⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 icn.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
 *        0 if successfully loaded */#ifdef BOOT_DEBUG#define SLEEP(sec) { \int slsec = sec; \  printk(KERN_DEBUG "SLEEP(%d)\n",slsec); \  while (slsec) { \    current->state = TASK_INTERRUPTIBLE; \    current->timeout = jiffies + HZ; \    schedule(); \    slsec--; \  } \}#else#define SLEEP(sec)#endifstatic inticn_loadboot(u_char * buffer, icn_card * card){	int ret;	ulong flags;	u_char *codebuf;#ifdef BOOT_DEBUG	printk(KERN_DEBUG "icn_loadboot called, buffaddr=%08lx\n", (ulong) buffer);#endif	if (!(codebuf = kmalloc(ICN_CODE_STAGE1, GFP_KERNEL))) {		printk(KERN_WARNING "icn: Could not allocate code buffer\n");		return -ENOMEM;	}	if ((ret = copy_from_user(codebuf, buffer, ICN_CODE_STAGE1))) {		kfree(codebuf);		return ret;	}	save_flags(flags);	cli();	if (!card->rvalid) {		if (check_region(card->port, ICN_PORTLEN)) {			printk(KERN_WARNING			       "icn: (%s) ports 0x%03x-0x%03x in use.\n",			       CID,			       card->port,			       card->port + ICN_PORTLEN);			restore_flags(flags);			kfree(codebuf);			return -EBUSY;		}		request_region(card->port, ICN_PORTLEN, card->regname);		card->rvalid = 1;		if (card->doubleS0)			card->other->rvalid = 1;	}	if (!dev.mvalid) {		if (check_shmem((ulong) dev.shmem, 0x4000)) {			printk(KERN_WARNING			       "icn: memory at 0x%08lx in use.\n",			       (ulong) dev.shmem);			restore_flags(flags);			return -EBUSY;		}		request_shmem((ulong) dev.shmem, 0x4000, "icn");		dev.mvalid = 1;	}	restore_flags(flags);	OUTB_P(0, ICN_RUN);     /* Reset Controller */	OUTB_P(0, ICN_MAPRAM);  /* Disable RAM      */	icn_shiftout(ICN_CFG, 0x0f, 3, 4);	/* Windowsize= 16k  */	icn_shiftout(ICN_CFG, (unsigned long) dev.shmem, 23, 10);	/* Set RAM-Addr.    */#ifdef BOOT_DEBUG	printk(KERN_DEBUG "shmem=%08lx\n", (ulong) dev.shmem);#endif	SLEEP(1);#ifdef BOOT_DEBUG	printk(KERN_DEBUG "Map Bank 0\n");#endif	save_flags(flags);	cli();	icn_map_channel(card, 0);	/* Select Bank 0    */	icn_lock_channel(card, 0);	/* Lock Bank 0      */	restore_flags(flags);	SLEEP(1);	memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1);	/* Copy code        */#ifdef BOOT_DEBUG	printk(KERN_DEBUG "Bootloader transfered\n");#endif	if (card->doubleS0) {		SLEEP(1);#ifdef BOOT_DEBUG		printk(KERN_DEBUG "Map Bank 8\n");#endif		save_flags(flags);		cli();		icn_release_channel();		icn_map_channel(card, 2);	/* Select Bank 8   */		icn_lock_channel(card, 2);	/* Lock Bank 8     */		restore_flags(flags);		SLEEP(1);		memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1);	/* Copy code        */#ifdef BOOT_DEBUG		printk(KERN_DEBUG "Bootloader transfered\n");#endif	}	kfree(codebuf);	SLEEP(1);	OUTB_P(0xff, ICN_RUN);  /* Start Boot-Code */	if ((ret = icn_check_loader(card->doubleS0 ? 2 : 1)))		return ret;	if (!card->doubleS0)		return 0;	/* reached only, if we have a Double-S0-Card */#ifdef BOOT_DEBUG	printk(KERN_DEBUG "Map Bank 0\n");#endif	save_flags(flags);	cli();	icn_map_channel(card, 0);	/* Select Bank 0   */	icn_lock_channel(card, 0);	/* Lock Bank 0     */	restore_flags(flags);	SLEEP(1);	return (icn_check_loader(1));}static inticn_loadproto(u_char * buffer, icn_card * card){	register u_char *p = buffer;	u_char codebuf[256];	uint left = ICN_CODE_STAGE2;	uint cnt;	int timer;	int ret;	unsigned long flags;#ifdef BOOT_DEBUG	printk(KERN_DEBUG "icn_loadproto called\n");#endif	if ((ret = verify_area(VERIFY_READ, (void *) buffer, ICN_CODE_STAGE2)))		return ret;	timer = 0;	save_flags(flags);	cli();	if (card->secondhalf) {		icn_map_channel(card, 2);		icn_lock_channel(card, 2);	} else {		icn_map_channel(card, 0);		icn_lock_channel(card, 0);	}	restore_flags(flags);	while (left) {		if (sbfree) {   /* If there is a free buffer...  */			cnt = MIN(256, left);			if (copy_from_user(codebuf, p, cnt)) {				icn_maprelease_channel(card, 0);				return -EFAULT;			}			memcpy_toio(&sbuf_l, codebuf, cnt);	/* copy data                     */			sbnext; /* switch to next buffer         */			p += cnt;			left -= cnt;			timer = 0;		} else {#ifdef BOOT_DEBUG			printk(KERN_DEBUG "boot 2 !sbfree\n");#endif			if (timer++ > 5) {				icn_maprelease_channel(card, 0);				return -EIO;			}			current->state = TASK_INTERRUPTIBLE;			current->timeout = jiffies + 10;			schedule();		}	}	writeb(0x20, &sbuf_n);	timer = 0;	while (1) {		if (readb(&cmd_o) || readb(&cmd_i)) {#ifdef BOOT_DEBUG			printk(KERN_DEBUG "Proto?\n");#endif			if (timer++ > 5) {				printk(KERN_WARNING				       "icn: (%s) Protocol timed out.\n",				       CID);#ifdef BOOT_DEBUG				printk(KERN_DEBUG "Proto TO!\n");#endif				icn_maprelease_channel(card, 0);				return -EIO;			}#ifdef BOOT_DEBUG			printk(KERN_DEBUG "Proto TO?\n");#endif			current->state = TASK_INTERRUPTIBLE;			current->timeout = jiffies + ICN_BOOT_TIMEOUT1;			schedule();		} else {			if ((card->secondhalf) || (!card->doubleS0)) {#ifdef BOOT_DEBUG				printk(KERN_DEBUG "Proto loaded, install poll-timer %d\n",				       card->secondhalf);#endif				save_flags(flags);				cli();				init_timer(&card->st_timer);				card->st_timer.expires = jiffies + ICN_TIMER_DCREAD;				card->st_timer.function = icn_polldchan;				card->st_timer.data = (unsigned long) card;				add_timer(&card->st_timer);				card->flags |= ICN_FLAGS_RUNNING;				if (card->doubleS0) {					init_timer(&card->other->st_timer);					card->other->st_timer.expires = jiffies + ICN_TIMER_DCREAD;					card->other->st_timer.function = icn_polldchan;					card->other->st_timer.data = (unsigned long) card->other;					add_timer(&card->other->st_timer);					card->other->flags |= ICN_FLAGS_RUNNING;				}				restore_flags(flags);			}			icn_maprelease_channel(card, 0);			return 0;		}	}}/* Read the Status-replies from the Interface */static inticn_readstatus(u_char * buf, int len, int user, icn_card * card){	int count;	u_char *p;	for (p = buf, count = 0; count < len; p++, count++) {		if (card->msg_buf_read == card->msg_buf_write)			return count;		if (user)			put_user(*card->msg_buf_read++, p);		else			*p = *card->msg_buf_read++;		if (card->msg_buf_read > card->msg_buf_end)			card->msg_buf_read = card->msg_buf;	}	return count;}/* Put command-strings into the command-queue of the Interface */static inticn_writecmd(const u_char * buf, int len, int user, icn_card * card){	int mch = card->secondhalf ? 2 : 0;	int avail;	int pp;	int i;	int count;	int xcount;	int ocount;	int loop;	unsigned long flags;	int lastmap_channel;	struct icn_card *lastmap_card;	u_char *p;	isdn_ctrl cmd;	u_char msg[0x100];	ocount = 1;	xcount = loop = 0;	while (len) {		save_flags(flags);		cli();		lastmap_card = dev.mcard;		lastmap_channel = dev.channel;		icn_map_channel(card, mch);		avail = cmd_free;		count = MIN(avail, len);		if (user)			copy_from_user(msg, buf, count);		else			memcpy(msg, buf, count);		icn_putmsg(card, '>');		for (p = msg, pp = readb(&cmd_i), i = count; i > 0; i--, p++, pp		     ++) {			writeb((*p == '\n') ? 0xff : *p,			   &dev.shmem->comm_buffers.pcio_buf[pp & 0xff]);			len--;			xcount++;			icn_putmsg(card, *p);			if ((*p == '\n') && (i > 1)) {				icn_putmsg(card, '>');				ocount++;			}			ocount++;		}		writeb((readb(&cmd_i) + count) & 0xff, &cmd_i);		if (lastmap_card)			icn_map_channel(lastmap_card, lastmap_channel);		restore_flags(flags);		if (len) {			udelay(1000);			if (loop++ > 20)				break;		} else			break;	}	if (len && (!user))		printk(KERN_WARNING "icn: writemsg incomplete!\n");	cmd.command = ISDN_STAT_STAVAIL;	cmd.driver = card->myid;	cmd.arg = ocount;	card->interface.statcallb(&cmd);	return xcount;}/* * Delete card's pending timers, send STOP to linklevel */static voidicn_stopcard(icn_card * card){	unsigned long flags;	isdn_ctrl cmd;	save_flags(flags);	cli();	if (card->flags & ICN_FLAGS_RUNNING) {		card->flags &= ~ICN_FLAGS_RUNNING;		del_timer(&card->st_timer);		del_timer(&card->rb_timer);		cmd.command = ISDN_STAT_STOP;		cmd.driver = card->myid;		card->interface.statcallb(&cmd);		if (card->doubleS0)			icn_stopcard(card->other);	}	restore_flags(flags);}static voidicn_stopallcards(void){	icn_card *p = cards;	while (p) {		icn_stopcard(p);		p = p->next;	}}/* * Unmap all cards, because some of them may be mapped accidetly during * autoprobing of some network drivers (SMC-driver?) */static voidicn_disable_cards(void){	icn_card *card = cards;	unsigned long flags;	save_flags(flags);	cli();	while (card) {		if (check_region(card->port, ICN_PORTLEN)) {			printk(KERN_WARNING			       "icn: (%s) ports 0x%03x-0x%03x in use.\n",			       CID,			       card->port,			       card->port + ICN_PORTLEN);			cli();		} else {			OUTB_P(0, ICN_RUN);	/* Reset Controller     */			OUTB_P(0, ICN_MAPRAM);	/* Disable RAM          */		}		card = card->next;	}	restore_flags(flags);}static inticn_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 ((unsigned long) dev.shmem != (a & 0x0ffc000)) {						if (check_shmem((ulong) (a & 0x0ffc000), 0x4000)) {							printk(KERN_WARNING							       "icn: memory at 0x%08lx in use.\n",							       (ulong) (a & 0x0ffc000));							return -EINVAL;						}						icn_stopallcards();						save_flags(flags);						cli();						if (dev.mvalid)							release_shmem((ulong) dev.shmem, 0x4000);						dev.mvalid = 0;						dev.shmem = (icn_shmem *) (a & 0x0ffc000);						restore_flags(flags);						printk(KERN_INFO						       "icn: (%s) mmio set to 0x%08lx\n",						       CID,						       (unsigned long) dev.shmem);					}					break;				case ICN_IOCTL_GETMMIO:					return (long) dev.shmem;				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)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -