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

📄 ctcmain.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
	DEV_STATE_STOPPED,	DEV_STATE_STARTWAIT_RXTX,	DEV_STATE_STARTWAIT_RX,	DEV_STATE_STARTWAIT_TX,	DEV_STATE_STOPWAIT_RXTX,	DEV_STATE_STOPWAIT_RX,	DEV_STATE_STOPWAIT_TX,	DEV_STATE_RUNNING,	/**	 * MUST be always the last element!!	 */	NR_DEV_STATES};static const char *dev_state_names[] = {	"Stopped",	"StartWait RXTX",	"StartWait RX",	"StartWait TX",	"StopWait RXTX",	"StopWait RX",	"StopWait TX",	"Running",};/** * Events of the interface statemachine. */enum dev_events {	DEV_EVENT_START,	DEV_EVENT_STOP,	DEV_EVENT_RXUP,	DEV_EVENT_TXUP,	DEV_EVENT_RXDOWN,	DEV_EVENT_TXDOWN,	/**	 * MUST be always the last element!!	 */	NR_DEV_EVENTS};static const char *dev_event_names[] = {	"Start",	"Stop",	"RX up",	"TX up",	"RX down",	"TX down",};/** * Events of the channel statemachine */enum ch_events {	/**	 * Events, representing return code of	 * I/O operations (do_IO, halt_IO et al.)	 */	CH_EVENT_IO_SUCCESS,	CH_EVENT_IO_EBUSY,	CH_EVENT_IO_ENODEV,	CH_EVENT_IO_EIO,	CH_EVENT_IO_UNKNOWN,	CH_EVENT_ATTNBUSY,	CH_EVENT_ATTN,	CH_EVENT_BUSY,	/**	 * Events, representing unit-check	 */	CH_EVENT_UC_RCRESET,	CH_EVENT_UC_RSRESET,	CH_EVENT_UC_TXTIMEOUT,	CH_EVENT_UC_TXPARITY,	CH_EVENT_UC_HWFAIL,	CH_EVENT_UC_RXPARITY,	CH_EVENT_UC_ZERO,	CH_EVENT_UC_UNKNOWN,	/**	 * Events, representing subchannel-check	 */	CH_EVENT_SC_UNKNOWN,	/**	 * Events, representing machine checks	 */	CH_EVENT_MC_FAIL,	CH_EVENT_MC_GOOD,	/**	 * Event, representing normal IRQ	 */	CH_EVENT_IRQ,	CH_EVENT_FINSTAT,	/**	 * Event, representing timer expiry.	 */	CH_EVENT_TIMER,	/**	 * Events, representing commands from upper levels.	 */	CH_EVENT_START,	CH_EVENT_STOP,	/**	 * MUST be always the last element!!	 */	NR_CH_EVENTS,};static const char *ch_event_names[] = {	"do_IO success",	"do_IO busy",	"do_IO enodev",	"do_IO ioerr",	"do_IO unknown",	"Status ATTN & BUSY",	"Status ATTN",	"Status BUSY",	"Unit check remote reset",	"Unit check remote system reset",	"Unit check TX timeout",	"Unit check TX parity",	"Unit check Hardware failure",	"Unit check RX parity",	"Unit check ZERO",	"Unit check Unknown",	"SubChannel check Unknown",	"Machine check failure",	"Machine check operational",	"IRQ normal",	"IRQ final",	"Timer",	"Start",	"Stop",};/** * States of the channel statemachine. */enum ch_states {	/**	 * Channel not assigned to any device,	 * initial state, direction invalid	 */	CH_STATE_IDLE,	/**	 * Channel assigned but not operating	 */	CH_STATE_STOPPED,	CH_STATE_STARTWAIT,	CH_STATE_STARTRETRY,	CH_STATE_SETUPWAIT,	CH_STATE_RXINIT,	CH_STATE_TXINIT,	CH_STATE_RX,	CH_STATE_TX,	CH_STATE_RXIDLE,	CH_STATE_TXIDLE,	CH_STATE_RXERR,	CH_STATE_TXERR,	CH_STATE_TERM,	CH_STATE_DTERM,	CH_STATE_NOTOP,	/**	 * MUST be always the last element!!	 */	NR_CH_STATES,};static const char *ch_state_names[] = {	"Idle",	"Stopped",	"StartWait",	"StartRetry",	"SetupWait",	"RX init",	"TX init",	"RX",	"TX",	"RX idle",	"TX idle",	"RX error",	"TX error",	"Terminating",	"Restarting",	"Not operational",};#ifdef DEBUG/** * Dump header and first 16 bytes of an sk_buff for debugging purposes. * * @param skb    The sk_buff to dump. * @param offset Offset relative to skb-data, where to start the dump. */static void ctc_dump_skb(struct sk_buff *skb, int offset){	unsigned char *p = skb->data;	__u16 bl;	ll_header *header;	int i;	p += offset;	bl = *((__u16*)p);	p += 2;	header = (ll_header *)p;	p -= 2;		printk(KERN_DEBUG "dump:\n");	printk(KERN_DEBUG "blocklen=%d %04x\n", bl, bl);	printk(KERN_DEBUG "h->length=%d %04x\n", header->length,	       header->length); 	printk(KERN_DEBUG "h->type=%04x\n", header->type); 	printk(KERN_DEBUG "h->unused=%04x\n", header->unused);	if (bl > 16)		bl = 16;	printk(KERN_DEBUG "data: ");	for (i = 0; i < bl; i++)		printk("%02x%s", *p++, (i % 16) ? " " : "\n<7>");	printk("\n");}#endif/** * Unpack a just received skb and hand it over to * upper layers. * * @param ch The channel where this skb has been received. * @param pskb The received skb. */static __inline__ void ctc_unpack_skb(channel *ch, struct sk_buff *pskb){	net_device     *dev = ch->netdev;	ctc_priv       *privptr = (ctc_priv *)dev->priv;	__u16 len = *((__u16*)pskb->data);	skb_put(pskb, 2 + LL_HEADER_LENGTH);	skb_pull(pskb, 2);	pskb->dev = dev;	pskb->ip_summed = CHECKSUM_UNNECESSARY;	while (len > 0) {		struct sk_buff *skb;		ll_header *header = (ll_header *)pskb->data;		skb_pull(pskb, LL_HEADER_LENGTH);		if ((ch->protocol == CTC_PROTO_S390) &&		    (header->type != ETH_P_IP)) {			/**			 * Check packet type only if we stick strictly			 * to S/390's protocol of OS390. This only			 * supports IP. Otherwise allow any packet			 * type.			 */			printk(KERN_WARNING			       "%s Illegal packet type 0x%04x "			       "received, dropping\n",			       dev->name, header->type);#ifdef DEBUG			ctc_dump_skb(pskb, -6);#endif			privptr->stats.rx_dropped++;			privptr->stats.rx_frame_errors++;			return;		}		pskb->protocol = ntohs(header->type);		header->length -= LL_HEADER_LENGTH;		if ((header->length == 0) ||		    (header->length > skb_tailroom(pskb)) ||		    (header->length > len)) {			printk(KERN_WARNING			       "%s Illegal packet size %d "			       "received (MTU=%d blocklen=%d), "			       "dropping\n", dev->name, header->length,			       dev->mtu, len);#ifdef DEBUG			ctc_dump_skb(pskb, -6);#endif			privptr->stats.rx_dropped++;			privptr->stats.rx_length_errors++;			return;		}		if (header->length > skb_tailroom(pskb)) {			printk(KERN_WARNING			       "%s Illegal packet size %d "			       "(beyond the end of received data), "			       "dropping\n", dev->name, header->length);#ifdef DEBUG			ctc_dump_skb(pskb, -6);#endif			privptr->stats.rx_dropped++;			privptr->stats.rx_length_errors++;			return;		}		skb_put(pskb, header->length);		pskb->mac.raw = pskb->data;		len -= (LL_HEADER_LENGTH + header->length);		skb = dev_alloc_skb(pskb->len);		if (!skb) {			printk(KERN_WARNING			       "%s Out of memory in ctc_unpack_skb\n",			       dev->name);			privptr->stats.rx_dropped++;			return;		}		memcpy(skb_put(skb, pskb->len), pskb->data, pskb->len);		skb->mac.raw = skb->data;		skb->dev = pskb->dev;		skb->protocol = pskb->protocol;		pskb->ip_summed = CHECKSUM_UNNECESSARY;		if (ch->protocol == CTC_PROTO_LINUX_TTY)			ctc_tty_netif_rx(skb);		else			netif_rx(skb);		privptr->stats.rx_packets++;		privptr->stats.rx_bytes += skb->len;		if (len > 0) {			skb_pull(pskb, header->length);			skb_put(pskb, LL_HEADER_LENGTH);		}	}}/** * Bottom half routine. * * @param ch The channel to work on. */static void ctc_bh(channel *ch){	struct sk_buff *skb;	while ((skb = skb_dequeue(&ch->io_queue)))		ctc_unpack_skb(ch, skb);}/** * Check return code of a preceeding do_IO, halt_IO etc... * * @param ch          The channel, the error belongs to. * @param return_code The error code to inspect. */static void inline ccw_check_return_code (channel *ch, int return_code){	switch (return_code) {		case 0:			fsm_event(ch->fsm, CH_EVENT_IO_SUCCESS, ch);			break;		case -EBUSY:			printk(KERN_INFO "ch-%04x: Busy !\n", ch->devno);			fsm_event(ch->fsm, CH_EVENT_IO_EBUSY, ch);			break;		case -ENODEV:			printk(KERN_EMERG			       "ch-%04x: Invalid device called for IO\n",			       ch->devno);			fsm_event(ch->fsm, CH_EVENT_IO_ENODEV, ch);			break;		case -EIO:			printk(KERN_EMERG			       "ch-%04x: Status pending... \n", ch->devno);			fsm_event(ch->fsm, CH_EVENT_IO_EIO, ch);			break;		default:			printk(KERN_EMERG			       "ch-%04x: Unknown error in do_IO %04x\n",			       ch->devno, return_code);			fsm_event(ch->fsm, CH_EVENT_IO_UNKNOWN, ch);	}}/** * Check sense of a unit check. * * @param ch    The channel, the sense code belongs to. * @param sense The sense code to inspect. */static void inline ccw_unit_check (channel *ch, unsigned char sense) {	if (sense & SNS0_INTERVENTION_REQ) {		if (sense & 0x01)  {			if (ch->protocol != CTC_PROTO_LINUX_TTY)				printk(KERN_DEBUG				       "ch-%04x: Interface disc. or Sel. reset "				       "(remote)\n", ch->devno);			fsm_event(ch->fsm, CH_EVENT_UC_RCRESET, ch);		} else {			printk(KERN_DEBUG "ch-%04x: System reset (remote)\n",			       ch->devno);			fsm_event(ch->fsm, CH_EVENT_UC_RSRESET, ch);		}	} else if (sense & SNS0_EQUIPMENT_CHECK) {		if (sense & SNS0_BUS_OUT_CHECK) {			printk(KERN_WARNING			       "ch-%04x: Hardware malfunction (remote)\n",			       ch->devno);			fsm_event(ch->fsm, CH_EVENT_UC_HWFAIL, ch);		} else {			printk(KERN_WARNING			       "ch-%04x: Read-data parity error (remote)\n",			       ch->devno);			fsm_event(ch->fsm, CH_EVENT_UC_RXPARITY, ch);		}	} else if (sense & SNS0_BUS_OUT_CHECK) {		if (sense & 0x04) {			printk(KERN_WARNING			       "ch-%04x: Data-streaming timeout)\n",			       ch->devno);			fsm_event(ch->fsm, CH_EVENT_UC_TXTIMEOUT, ch);		} else {			printk(KERN_WARNING			       "ch-%04x: Data-transfer parity error\n",			       ch->devno);			fsm_event(ch->fsm, CH_EVENT_UC_TXPARITY, ch);		}	} else if (sense & SNS0_CMD_REJECT) {			printk(KERN_WARNING "ch-%04x: Command reject\n",			       ch->devno);	} else if (sense == 0) {		printk(KERN_DEBUG "ch-%04x: Unit check ZERO\n", ch->devno);		fsm_event(ch->fsm, CH_EVENT_UC_ZERO, ch);	} else {		printk(KERN_WARNING		       "ch-%04x: Unit Check with sense code: %02x\n",		       ch->devno, sense);		fsm_event(ch->fsm, CH_EVENT_UC_UNKNOWN, ch);	}}static void ctc_purge_skb_queue(struct sk_buff_head *q){	struct sk_buff *skb;	while ((skb = skb_dequeue(q))) {		atomic_dec(&skb->users);		dev_kfree_skb_irq(skb);	}}static __inline__ int ctc_checkalloc_buffer(channel *ch, int warn) {	if ((ch->trans_skb == NULL) ||	    (ch->flags & CHANNEL_FLAGS_BUFSIZE_CHANGED)) {		if (ch->trans_skb != NULL)			dev_kfree_skb(ch->trans_skb);		clear_normalized_cda(&ch->ccw[1]);		ch->trans_skb = __dev_alloc_skb(ch->max_bufsize,						GFP_ATOMIC|GFP_DMA);		if (ch->trans_skb == NULL) {			if (warn)				printk(KERN_WARNING				       "ch-%04x: Couldn't alloc %s trans_skb\n",				       ch->devno,				       (CHANNEL_DIRECTION(ch->flags) == READ) ?				       "RX" : "TX");			return -ENOMEM;		}		ch->ccw[1].count = ch->max_bufsize;		if (set_normalized_cda(&ch->ccw[1],				       virt_to_phys(ch->trans_skb->data))) {			dev_kfree_skb(ch->trans_skb);			ch->trans_skb = NULL;			if (warn)				printk(KERN_WARNING				       "ch-%04x: set_normalized_cda for %s "				       "trans_skb failed, dropping packets\n",				       ch->devno,				       (CHANNEL_DIRECTION(ch->flags) == READ) ?				       "RX" : "TX");			return -ENOMEM;		}

⌨️ 快捷键说明

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