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

📄 ctc.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifdef DEBUG        printk(KERN_DEBUG "%s: bh routine - state-%02x\n" ,dev->name, ctc->state);#endif         while (ctc->proc_anchor != NULL) {                 lp = &ctc->proc_anchor->block->data;                while ((__u8 *) lp < (__u8 *) &ctc->proc_anchor->block->length + ctc->proc_anchor->block->length) {                        data_len = lp->length - PACKET_HEADER_LENGTH;                        skb = dev_alloc_skb(data_len);                         if (skb) {                                 memcpy(skb_put(skb, data_len),&lp->data, data_len);                                skb->mac.raw = skb->data;                                skb->dev = dev;                                skb->protocol = htons(ETH_P_IP);                                skb->ip_summed = CHECKSUM_UNNECESSARY; /* no UC happened!!! */                                netif_rx(skb);                                privptr->stats.rx_packets++;                        } else {                                privptr->stats.rx_dropped++;                                 printk(KERN_WARNING "%s: is low on memory\n",dev->name);                        }                        (__u8 *)lp += lp->length;                }                s390irq_spin_lock_irqsave(ctc->irq, saveflags);                ctc_buffer_swap(&ctc->proc_anchor, &ctc->free_anchor);                if (test_and_set_bit(0, (void *)&ctc->IO_active) == 0) {#ifdef DEBUG                        printk(KERN_DEBUG "%s: HOT READ started in bh routine\n" ,dev->name);#endif                         ctc->ccw[1].cda  = (char *)virt_to_phys(ctc->free_anchor->block);                        parm = (__u32) ctc;                         rc = do_IO (ctc->irq, &ctc->ccw[0], parm, 0xff, flags );                        if (rc != 0)                                  ccw_check_return_code(dev, rc);                }                 s390irq_spin_unlock_irqrestore(ctc->irq, saveflags);         }        clear_bit(CTC_BH_ACTIVE, (void *)&ctc->flag_a);        return;}  static void ctc_read_retry (struct channel *ctc){        int                rc = 0;        __u32              parm;        __u8               flags = 0x00;        __u32              saveflags;        net_device  *dev;        dev = (net_device *) ctc->dev;    #ifdef DEBUG        printk(KERN_DEBUG "%s: read retry - state-%02x\n" ,dev->name, ctc->state);#endif         s390irq_spin_lock_irqsave(ctc->irq, saveflags);        ctc->ccw[1].cda  = (char *)virt_to_phys(ctc->free_anchor->block);        parm = (__u32) ctc;         rc = do_IO (ctc->irq, &ctc->ccw[0], parm, 0xff, flags );        s390irq_spin_unlock_irqrestore(ctc->irq, saveflags);        if (rc != 0)                 ccw_check_return_code(dev, rc);        return;}   static void ctc_write_retry (struct channel *ctc){        int                rc = 0;        __u32              parm;        __u8               flags = 0x00;        __u32              saveflags;        net_device  *dev;        dev = (net_device *) ctc->dev;    #ifdef DEBUG        printk(KERN_DEBUG "%s: write retry - state-%02x\n" ,dev->name, ctc->state);#endif         s390irq_spin_lock_irqsave(ctc->irq, saveflags);        ctc->ccw[1].count = 0;        ctc->ccw[1].cda  = (char *)virt_to_phys(ctc->proc_anchor->block);        parm = (__u32) ctc;         rc = do_IO (ctc->irq, &ctc->ccw[0], parm, 0xff, flags );        s390irq_spin_unlock_irqrestore(ctc->irq, saveflags);        if (rc != 0)                 ccw_check_return_code(dev, rc);        return;}  /* *   ctc_open * */static int ctc_open(net_device *dev){        int                rc;        int                i;        int                j;        __u8               flags = 0x00;        __u32              saveflags;        __u32              parm;        struct ctc_priv    *privptr;	DECLARE_WAITQUEUE(wait, current);        struct timer_list  timer;        ctc_set_busy(dev);        privptr = (struct ctc_priv *) (dev->priv);                privptr->channel[READ].flag  = 0x00;        privptr->channel[WRITE].flag = CTC_WRITE;        for (i = 0; i < 2;  i++) {                 for (j = 0; j < CTC_BLOCKS;  j++) {                         rc = ctc_buffer_alloc(&privptr->channel[i]);                        if (rc != 0)                                return -ENOMEM;                }                init_waitqueue_head(&privptr->channel[i].wait);                INIT_LIST_HEAD(&privptr->channel[i].tq.list);                privptr->channel[i].tq.sync = 0;                privptr->channel[i].tq.routine = (void *)(void *)ctc_irq_bh;                privptr->channel[i].tq.data = &privptr->channel[i];                 privptr->channel[i].dev = dev;                                privptr->channel[i].flag_a = 0;                privptr->channel[i].IO_active = 0;                privptr->channel[i].ccw[0].cmd_code  = CCW_CMD_PREPARE;                privptr->channel[i].ccw[0].flags     = CCW_FLAG_SLI | CCW_FLAG_CC;                privptr->channel[i].ccw[0].count     = 0;                privptr->channel[i].ccw[0].cda       = NULL;                if (i == READ) {                          privptr->channel[i].ccw[1].cmd_code  = CCW_CMD_READ;                        privptr->channel[i].ccw[1].flags     = CCW_FLAG_SLI;                        privptr->channel[i].ccw[1].count     = 0xffff;   /* MAX size */                        privptr->channel[i].ccw[1].cda       = NULL;                } else {                        privptr->channel[i].ccw[1].cmd_code = CCW_CMD_WRITE;                        privptr->channel[i].ccw[1].flags    = CCW_FLAG_SLI | CCW_FLAG_CC;                        privptr->channel[i].ccw[1].count    = 0;                        privptr->channel[i].ccw[1].cda      = NULL;                }                privptr->channel[i].ccw[2].cmd_code = CCW_CMD_NOOP;      /* jointed CE+DE */                privptr->channel[i].ccw[2].flags    = CCW_FLAG_SLI;                privptr->channel[i].ccw[2].count    = 0;                privptr->channel[i].ccw[2].cda      = NULL;                                privptr->channel[i].flag  &= ~CTC_TIMER;                init_timer(&timer);                timer.function = (void *)ctc_timer;                 timer.data = (__u32)&privptr->channel[i];                timer.expires = jiffies + 150*HZ;                        /* time to connect with the remote side */                add_timer(&timer);                s390irq_spin_lock_irqsave(privptr->channel[i].irq, saveflags);                parm = (unsigned long) &privptr->channel[i];                 privptr->channel[i].state = CTC_START_HALT_IO;                rc = halt_IO(privptr->channel[i].irq, parm, flags);                add_wait_queue(&privptr->channel[i].wait, &wait);                current->state = TASK_INTERRUPTIBLE;                s390irq_spin_unlock_irqrestore(privptr->channel[i].irq, saveflags);                schedule();                remove_wait_queue(&privptr->channel[i].wait, &wait);                if(rc != 0)                        ccw_check_return_code(dev, rc);                if((privptr->channel[i].flag & CTC_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) & CTC_TIMER) != 0x00)) {#ifdef DEBUG                printk(KERN_DEBUG "%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 currently not ready\n", dev->name);                                for (i = 0; i < 2;  i++) {                        s390irq_spin_lock_irqsave(privptr->channel[i].irq, saveflags);                        parm = (unsigned long) &privptr->channel[i];                        privptr->channel[i].state = CTC_STOP;                        rc = halt_IO(privptr->channel[i].irq, parm, flags);                        s390irq_spin_unlock_irqrestore(privptr->channel[i].irq, saveflags);                        if (rc != 0)                                ccw_check_return_code(dev, rc);                        for (j = 0; j < CTC_BLOCKS;  j++)                                 ctc_buffer_free(&privptr->channel[i]);                }                return -EIO;        }        printk(KERN_INFO "%s: connected with remote side\n",dev->name);        ctc_clear_busy(dev);        return 0;}static void ctc_timer (struct channel *ctc){#ifdef DEBUG        net_device  *dev;        dev = (net_device *) ctc->dev;         printk(KERN_DEBUG "%s: timer return\n" ,dev->name);#endif        ctc->flag |= CTC_TIMER;        wake_up(&ctc->wait);          return;}  /* *   ctc_release  * */static int ctc_release(net_device *dev){           int                rc;        int                i;        int                j;        __u8               flags = 0x00;        __u32              saveflags;        __u32              parm;        struct ctc_priv    *privptr;	DECLARE_WAITQUEUE(wait, current);        privptr = (struct ctc_priv *) dev->priv;     	ctc_protect_busy_irqsave(dev,saveflags);        ctc_setbit_busy(TB_STOP,dev);    	ctc_unprotect_busy_irqrestore(dev,flags);        for (i = 0; i < 2;  i++) {                s390irq_spin_lock_irqsave(privptr->channel[i].irq, saveflags);                privptr->channel[i].state = CTC_STOP;                parm = (__u32) &privptr->channel[i];                 rc = halt_IO (privptr->channel[i].irq, parm, flags );                add_wait_queue(&privptr->channel[i].wait, &wait);                current->state = TASK_INTERRUPTIBLE;                s390irq_spin_unlock_irqrestore(privptr->channel[i].irq, saveflags);                 schedule();                remove_wait_queue(&privptr->channel[i].wait, &wait);                if (rc != 0) {                        ccw_check_return_code(dev, rc);                }                                 for (j = 0; j < CTC_BLOCKS;  j++) {                          ctc_buffer_swap(&privptr->channel[i].proc_anchor, &privptr->channel[i].free_anchor);                        ctc_buffer_free(&privptr->channel[i]);                 }        }        if (((privptr->channel[READ].last_dstat | privptr->channel[WRITE].last_dstat) &            ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) != 0x00) {                printk(KERN_WARNING "%s: channel problems during close - read: %02x -  write: %02x\n",                    dev->name, privptr->channel[READ].last_dstat, privptr->channel[WRITE].last_dstat);                return -EIO;        }        return 0;}  /* *   ctc_tx  * * */static int ctc_tx(struct sk_buff *skb, net_device *dev){        int                rc=0,rc2;        __u32              parm;        __u8               flags = 0x00;        __u32              saveflags;        struct ctc_priv    *privptr;        struct packet      *lp;           privptr = (struct ctc_priv *) (dev->priv);        if (skb == NULL) {                 printk(KERN_WARNING "%s: NULL pointer as sk_buffer passed\n", dev->name);                privptr->stats.tx_dropped++;                return -EIO;        }                s390irq_spin_lock_irqsave(privptr->channel[WRITE].irq, saveflags);        if (ctc_check_busy(dev)) {                rc=-EBUSY;		goto Done;        }         if (ctc_test_and_setbit_busy(TB_TX,dev)) {                /* set transmission to busy */                rc=-EBUSY;		goto Done;        }         if (65535 - privptr->channel[WRITE].free_anchor->block->length - PACKET_HEADER_LENGTH <= skb->len + PACKET_HEADER_LENGTH + 2) {#ifdef DEBUG                printk(KERN_DEBUG "%s: early swap\n", dev->name);#endif                               ctc_buffer_swap(&privptr->channel[WRITE].free_anchor, &privptr->channel[WRITE].proc_anchor);                if (privptr->channel[WRITE].free_anchor == NULL){                        ctc_setbit_busy(TB_NOBUFFER,dev);                        rc=-EBUSY;			goto Done2;                }        }                if (privptr->channel[WRITE].free_anchor->block->length == 0) {                privptr->channel[WRITE].free_anchor->block->length = BLOCK_HEADER_LENGTH;                 privptr->channel[WRITE].free_anchor->packets = 0;        }         (__u8 *)lp = (__u8 *) &privptr->channel[WRITE].free_anchor->block->length + privptr->channel[WRITE].free_anchor->block->length;        privptr->channel[WRITE].free_anchor->block->length += skb->len + PACKET_HEADER_LENGTH;        lp->length = skb->len + PACKET_HEADER_LENGTH;         lp->type = 0x0800;         lp->unused = 0;        memcpy(&lp->data, skb->data, skb->len);         (__u8 *) lp += lp->length;         lp->length = 0;        dev_kfree_skb(skb);        privptr->channel[WRITE].free_anchor->packets++;        if (test_and_set_bit(0, (void *)&privptr->channel[WRITE].IO_active) == 0) {	       ctc_buffer_swap(&privptr->channel[WRITE].free_anchor,&privptr->channel[WRITE].proc_anchor);                 privptr->channel[WRITE].ccw[1].count = privptr->channel[WRITE].proc_anchor->block->length;                privptr->channel[WRITE].ccw[1].cda   = (char *)virt_to_phys(privptr->channel[WRITE].proc_anchor->block);                parm = (__u32) &privptr->channel[WRITE];                  rc2 = do_IO (privptr->channel[WRITE].irq, &privptr->channel[WRITE].ccw[0], parm, 0xff, flags );                if (rc2 != 0)                         ccw_check_return_code(dev, rc2);                dev->trans_start = jiffies;        }        if (privptr->channel[WRITE].free_anchor == NULL)                ctc_setbit_busy(TB_NOBUFFER,dev);Done2:        ctc_clearbit_busy(TB_TX,dev);Done:	s390irq_spin_unlock_irqrestore(privptr->channel[WRITE].irq, saveflags);        return(rc);} /* *   ctc_change_mtu  * *   S/390 can handle MTU sizes from 576 to 32760 for VM, VSE *                                   576 to 65527 for OS/390 * */static int ctc_change_mtu(net_device *dev, int new_mtu){        if ((new_mtu < 576) || (new_mtu > 65528))                return -EINVAL;        dev->mtu = new_mtu;        return 0;}/* *   ctc_stats * */struct net_device_stats *ctc_stats(net_device *dev){         struct ctc_priv *privptr;            privptr = dev->priv;         return &privptr->stats;}  /* Module code goes here *//*                free_irq(privptr->channel[i].irq, privptr->channel[i].devstat);                kfree(privptr->channel[i].devstat); *//* --- This is the END my friend --- */

⌨️ 快捷键说明

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