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

📄 claw.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
 *   claw_tx                                                         * *-------------------------------------------------------------------*/static intclaw_tx(struct sk_buff *skb, struct net_device *dev){        int             rc;        struct claw_privbk *privptr=dev->priv;	unsigned long saveflags;        struct chbk *p_ch;#ifdef FUNCTRACE        printk(KERN_INFO "%s:%s enter\n",dev->name,__FUNCTION__);#endif	CLAW_DBF_TEXT(4,trace,"claw_tx");        p_ch=&privptr->channel[WRITE];        if (skb == NULL) {                printk(KERN_WARNING "%s: null pointer passed as sk_buffer\n",			dev->name);                privptr->stats.tx_dropped++;#ifdef FUNCTRACE                printk(KERN_INFO "%s: %s() exit on line %d, rc = EIO\n",			dev->name,__FUNCTION__, __LINE__);#endif		CLAW_DBF_TEXT_(2,trace,"clawtx%d",-EIO);                return -EIO;        }#ifdef IOTRACE        printk(KERN_INFO "%s: variable sk_buff=\n",dev->name);        dumpit((char *) skb, sizeof(struct sk_buff));        printk(KERN_INFO "%s: variable dev=\n",dev->name);        dumpit((char *) dev, sizeof(struct net_device));#endif        spin_lock_irqsave(get_ccwdev_lock(p_ch->cdev), saveflags);        rc=claw_hw_tx( skb, dev, 1 );        spin_unlock_irqrestore(get_ccwdev_lock(p_ch->cdev), saveflags);#ifdef FUNCTRACE        printk(KERN_INFO "%s:%s exit on line %d, rc = %d\n",		dev->name, __FUNCTION__, __LINE__, rc);#endif	CLAW_DBF_TEXT_(4,trace,"clawtx%d",rc);        return rc;}   /*  end of claw_tx *//*------------------------------------------------------------------* *  pack the collect queue into an skb and return it                * *   If not packing just return the top skb from the queue          * *------------------------------------------------------------------*/static struct sk_buff *claw_pack_skb(struct claw_privbk *privptr){	struct sk_buff *new_skb,*held_skb;	struct chbk *p_ch = &privptr->channel[WRITE];	struct claw_env  *p_env = privptr->p_env;	int	pkt_cnt,pk_ind,so_far;	new_skb = NULL;		/* assume no dice */	pkt_cnt = 0;	CLAW_DBF_TEXT(4,trace,"PackSKBe");	if (!skb_queue_empty(&p_ch->collect_queue)) {	/* some data */		held_skb = skb_dequeue(&p_ch->collect_queue);		if (held_skb)			dev_kfree_skb_any(held_skb);		else			return NULL;		if (p_env->packing != DO_PACKED)			return held_skb;		/* get a new SKB we will pack at least one */		new_skb = dev_alloc_skb(p_env->write_size);		if (new_skb == NULL) {			atomic_inc(&held_skb->users);			skb_queue_head(&p_ch->collect_queue,held_skb);			return NULL;		}		/* we have packed packet and a place to put it  */		pk_ind = 1;		so_far = 0;		new_skb->cb[1] = 'P'; /* every skb on queue has pack header */		while ((pk_ind) && (held_skb != NULL)) {			if (held_skb->len+so_far <= p_env->write_size-8) {				memcpy(skb_put(new_skb,held_skb->len),					held_skb->data,held_skb->len);				privptr->stats.tx_packets++;				so_far += held_skb->len;				pkt_cnt++;				dev_kfree_skb_any(held_skb);				held_skb = skb_dequeue(&p_ch->collect_queue);				if (held_skb)					atomic_dec(&held_skb->users);			} else {				pk_ind = 0;				atomic_inc(&held_skb->users);				skb_queue_head(&p_ch->collect_queue,held_skb);			}		}#ifdef IOTRACE		printk(KERN_INFO "%s: %s() Packed %d len %d\n",			p_env->ndev->name,			__FUNCTION__,pkt_cnt,new_skb->len);#endif	}	CLAW_DBF_TEXT(4,trace,"PackSKBx");	return new_skb;}/*-------------------------------------------------------------------* *   claw_change_mtu                                                 * *                                                                   * *-------------------------------------------------------------------*/static intclaw_change_mtu(struct net_device *dev, int new_mtu){	struct claw_privbk  *privptr=dev->priv;	int buff_size;#ifdef FUNCTRACE        printk(KERN_INFO "%s:%s Enter  \n",dev->name,__FUNCTION__);#endif#ifdef DEBUGMSG        printk(KERN_INFO "variable dev =\n");        dumpit((char *) dev, sizeof(struct net_device));        printk(KERN_INFO "variable new_mtu = %d\n", new_mtu);#endif	CLAW_DBF_TEXT(4,trace,"setmtu");	buff_size = privptr->p_env->write_size;        if ((new_mtu < 60) || (new_mtu > buff_size)) {#ifdef FUNCTRACE                printk(KERN_INFO "%s:%s Exit on line %d, rc=EINVAL\n",		dev->name,		__FUNCTION__, __LINE__);#endif                return -EINVAL;        }        dev->mtu = new_mtu;#ifdef FUNCTRACE        printk(KERN_INFO "%s:%s Exit on line %d\n",dev->name,	__FUNCTION__, __LINE__);#endif        return 0;}  /*   end of claw_change_mtu *//*-------------------------------------------------------------------* *   claw_open                                                       * *                                                                   * *-------------------------------------------------------------------*/static intclaw_open(struct net_device *dev){        int     rc;        int     i;        unsigned long       saveflags=0;        unsigned long       parm;        struct claw_privbk  *privptr;	DECLARE_WAITQUEUE(wait, current);        struct timer_list  timer;        struct ccwbk *p_buf;#ifdef FUNCTRACE        printk(KERN_INFO "%s:%s Enter  \n",dev->name,__FUNCTION__);#endif	CLAW_DBF_TEXT(4,trace,"open");	if (!dev | (dev->name[0] == 0x00)) {		CLAW_DBF_TEXT(2,trace,"BadDev");	 	printk(KERN_WARNING "claw: Bad device at open failing \n");		return -ENODEV;	}	privptr = (struct claw_privbk *)dev->priv;        /*   allocate and initialize CCW blocks */	if (privptr->buffs_alloc == 0) {	        rc=init_ccw_bk(dev);        	if (rc) {                	printk(KERN_INFO "%s:%s Exit on line %d, rc=ENOMEM\n",			dev->name,			__FUNCTION__, __LINE__);			CLAW_DBF_TEXT(2,trace,"openmem");                	return -ENOMEM;        	}	}        privptr->system_validate_comp=0;        privptr->release_pend=0;	if(strncmp(privptr->p_env->api_type,WS_APPL_NAME_PACKED,6) == 0) {		privptr->p_env->read_size=DEF_PACK_BUFSIZE;		privptr->p_env->write_size=DEF_PACK_BUFSIZE;		privptr->p_env->packing=PACKING_ASK;	} else {		privptr->p_env->packing=0;		privptr->p_env->read_size=CLAW_FRAME_SIZE;		privptr->p_env->write_size=CLAW_FRAME_SIZE;	}        claw_set_busy(dev);	tasklet_init(&privptr->channel[READ].tasklet, claw_irq_tasklet,        	(unsigned long) &privptr->channel[READ]);        for ( i = 0; i < 2;  i++) {		CLAW_DBF_TEXT_(2,trace,"opn_ch%d",i);                init_waitqueue_head(&privptr->channel[i].wait);		/* skb_queue_head_init(&p_ch->io_queue); */		if (i == WRITE)			skb_queue_head_init(				&privptr->channel[WRITE].collect_queue);                privptr->channel[i].flag_a = 0;                privptr->channel[i].IO_active = 0;                privptr->channel[i].flag  &= ~CLAW_TIMER;                init_timer(&timer);                timer.function = (void *)claw_timer;                timer.data = (unsigned long)(&privptr->channel[i]);                timer.expires = jiffies + 15*HZ;                add_timer(&timer);                spin_lock_irqsave(get_ccwdev_lock(			privptr->channel[i].cdev), saveflags);                parm = (unsigned long) &privptr->channel[i];                privptr->channel[i].claw_state = CLAW_START_HALT_IO;		rc = 0;		add_wait_queue(&privptr->channel[i].wait, &wait);                rc = ccw_device_halt(			(struct ccw_device *)privptr->channel[i].cdev,parm);                set_current_state(TASK_INTERRUPTIBLE);                spin_unlock_irqrestore(			get_ccwdev_lock(privptr->channel[i].cdev), saveflags);                schedule();		set_current_state(TASK_RUNNING);                remove_wait_queue(&privptr->channel[i].wait, &wait);                if(rc != 0)                        ccw_check_return_code(privptr->channel[i].cdev, rc);                if((privptr->channel[i].flag & CLAW_TIMER) == 0x00)                        del_timer(&timer);        }        if ((((privptr->channel[READ].last_dstat |		privptr->channel[WRITE].last_dstat) &           ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) != 0x00) ||           (((privptr->channel[READ].flag |	   	privptr->channel[WRITE].flag) & CLAW_TIMER) != 0x00)) {#ifdef DEBUGMSG                printk(KERN_INFO "%s: channel problems during open - read:"			" %02x -  write: %02x\n",                        dev->name,			privptr->channel[READ].last_dstat,			privptr->channel[WRITE].last_dstat);#endif                printk(KERN_INFO "%s: remote side is not ready\n", dev->name);		CLAW_DBF_TEXT(2,trace,"notrdy");                for ( i = 0; i < 2;  i++) {                        spin_lock_irqsave(				get_ccwdev_lock(privptr->channel[i].cdev),				saveflags);                        parm = (unsigned long) &privptr->channel[i];                        privptr->channel[i].claw_state = CLAW_STOP;                        rc = ccw_device_halt(				(struct ccw_device *)&privptr->channel[i].cdev,				parm);                        spin_unlock_irqrestore(				get_ccwdev_lock(privptr->channel[i].cdev),				saveflags);                        if (rc != 0) {                                ccw_check_return_code(					privptr->channel[i].cdev, rc);                        }                }                free_pages((unsigned long)privptr->p_buff_ccw,			(int)pages_to_order_of_mag(privptr->p_buff_ccw_num));                if (privptr->p_env->read_size < PAGE_SIZE) {                        free_pages((unsigned long)privptr->p_buff_read,			       (int)pages_to_order_of_mag(			       		privptr->p_buff_read_num));                }                else {                        p_buf=privptr->p_read_active_first;                        while (p_buf!=NULL) {                                free_pages((unsigned long)p_buf->p_buffer,				      (int)pages_to_order_of_mag(				      	privptr->p_buff_pages_perread ));                                p_buf=p_buf->next;                        }                }                if (privptr->p_env->write_size < PAGE_SIZE ) {                        free_pages((unsigned long)privptr->p_buff_write,			     (int)pages_to_order_of_mag(			     	privptr->p_buff_write_num));                }                else {                        p_buf=privptr->p_write_active_first;                        while (p_buf!=NULL) {                                free_pages((unsigned long)p_buf->p_buffer,				     (int)pages_to_order_of_mag(				     	privptr->p_buff_pages_perwrite ));                                p_buf=p_buf->next;                        }                }		privptr->buffs_alloc = 0;		privptr->channel[READ].flag= 0x00;		privptr->channel[WRITE].flag = 0x00;                privptr->p_buff_ccw=NULL;                privptr->p_buff_read=NULL;                privptr->p_buff_write=NULL;                claw_clear_busy(dev);#ifdef FUNCTRACE                printk(KERN_INFO "%s:%s Exit on line %d, rc=EIO\n",		dev->name,__FUNCTION__,__LINE__);#endif		CLAW_DBF_TEXT(2,trace,"open EIO");                return -EIO;        }        /*   Send SystemValidate command */        claw_clear_busy(dev);#ifdef FUNCTRACE        printk(KERN_INFO "%s:%s Exit on line %d, rc=0\n",		dev->name,__FUNCTION__,__LINE__);#endif	CLAW_DBF_TEXT(4,trace,"openok");        return 0;}    /*     end of claw_open    *//*-------------------------------------------------------------------**                                                                    **       claw_irq_handler                                             **                                                                    **--------------------------------------------------------------------*/static voidclaw_irq_handler(struct ccw_device *cdev,	unsigned long intparm, struct irb *irb){        struct chbk *p_ch = NULL;        struct claw_privbk *privptr = NULL;        struct net_device *dev = NULL;        struct claw_env  *p_env;        struct chbk *p_ch_r=NULL;#ifdef FUNCTRACE        printk(KERN_INFO "%s enter  \n",__FUNCTION__);#endif	CLAW_DBF_TEXT(4,trace,"clawirq");        /* Bypass all 'unsolicited interrupts' */	if (!cdev->dev.driver_data) {                printk(KERN_WARNING "claw: unsolicited interrupt for device:"		 	"%s received c-%02x d-%02x\n",                        cdev->dev.bus_id,irb->scsw.cstat, irb->scsw.dstat);#ifdef FUNCTRACE                printk(KERN_INFO "claw: %s() "			"exit on line %d\n",__FUNCTION__,__LINE__);#endif		CLAW_DBF_TEXT(2,trace,"badirq");                return;        }	privptr = (struct claw_privbk *)cdev->dev.driver_data;	/* Try to extract channel from driver data. */	if (privptr->channel[READ].cdev == cdev)		p_ch = &privptr->channel[READ];	else if (privptr->channel[WRITE].cdev == cdev)		p_ch = &privptr->channel[WRITE];	else {		printk(KERN_WARNING "claw: Can't determine channel for "			"interrupt, device %s\n", cdev->dev.bus_id);		CLAW_DBF_TEXT(2,trace,"badchan");		return;	}	CLAW_DBF_TEXT_(4,trace,"IRQCH=%d",p_ch->flag);	dev = (struct net_device *) (p_ch->ndev);

⌨️ 快捷键说明

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