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

📄 ctc.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        dev_info_t temp;                for (m = 0; m < CHANNEL_MEDIA;  m++) {                 for (c = 0; c < MAX_CHANNEL_DEVICES; c++){                        channel[m].list[c].devno = -ENODEV;                }        }                for (irq = 0; irq < NR_IRQS; irq++) {                /* CTC/A */                if (channel[CTC].count < MAX_CHANNEL_DEVICES ) {                        if (get_dev_info(irq, &temp) == 0 &&                             channel_check_for_type(&temp.sid_data) == channel_type_ctca) {                                channel[CTC].list[channel[CTC].count].devno = temp.devno;                                 channel[CTC].count++;                         }                }                /* ESCON */                if (channel[ESCON].count < MAX_CHANNEL_DEVICES ) {                        if (get_dev_info(irq, &temp) == 0 &&                             channel_check_for_type(&temp.sid_data) == channel_type_escon) {                                channel[ESCON].list[channel[ESCON].count].devno = temp.devno;                                 channel[ESCON].count++;                         }                }        }}  /* * free specific channel from the channel[].list  */  static int channel_free(int media, int devno){        int     i;        for (i = 0; i < channel[media].count; i++) {                       if ((devno == channel[media].list[i].devno) &&                    ((channel[media].list[i].flag & CHANNEL_IN_USE) != 0x00)) {                        channel[media].list[i].flag &= ~CHANNEL_IN_USE;                        return 0;                }        }        printk(KERN_WARNING "channel: dev %04x is not a channel or in use\n", devno);        return -ENODEV; }/* * get specific channel from the channel[].list  */  static int channel_get(int media, int devno){        int     i;        for (i = 0; i < channel[media].count; i++) {                       if ((devno == channel[media].list[i].devno) &&                    ((channel[media].list[i].flag & CHANNEL_IN_USE) == 0x00)) {                        channel[media].list[i].flag |= CHANNEL_IN_USE;                        return channel[media].list[i].devno;                             }        }        printk(KERN_WARNING "channel: dev %04x is not a channel or in use\n", devno);        return -ENODEV; }/* * get the next free channel from the channel[].list  */  static int channel_get_next(int media){        int     i;        for (i = 0; i < channel[media].count; i++) {                if ((channel[media].list[i].flag & CHANNEL_IN_USE) == 0x00) {#ifdef DEBUG                        printk(KERN_DEBUG "channel: picked=%04x\n", channel[media].list[i].devno);#endif                        channel[media].list[i].flag |= CHANNEL_IN_USE;                        return channel[media].list[i].devno;                        }        }        return -ENODEV; } /* * picks the next free channel from the channel[].list  */  static int channel_left(int media){        return channel[media].left; }/* * defines all devices which are channels */static channel_type_t channel_check_for_type (senseid_t *id) {        channel_type_t type;        switch (id->cu_type) {                case 0x3088:                         switch (id->cu_model) {                                case 0x08:                                            type = channel_type_ctca;  /* 3088-08  ==> CTCA */                                        break;                                 case 0x1F:                                           type = channel_type_escon; /* 3088-1F  ==> ESCON channel */                                        break;                                 case 0x01:                         /* 3088-01  ==> P390 OSA emulation */                                case 0x60:                         /* 3088-60  ==> OSA/2 adapter */                                case 0x61:                         /* 3088-61  ==> CISCO 7206 CLAW protocol ESCON connected */                                case 0x62:                         /* 3088-62  ==> OSA/D device */                                         type = channel_type_unsupported;                                         break;                                 default:                                        type = channel_type_undefined;                                        printk(KERN_INFO "channel: Unknown model found 3088-%02x\n",id->cu_model);                        }                        break;                default:                        type = channel_type_none;        }        return type;}/* *  sort the channel[].list */static void channel_sort(struct devicelist list[], int n){        int               i;        int               sorted = 0;        struct devicelist tmp;        while (!sorted) {                 sorted = 1;                for (i = 0; i < n-1; i++) {                          if (list[i].devno > list[i+1].devno) {                                  tmp = list[i];                                list[i] = list[i+1];                                list[i+1] = tmp;                                sorted = 0;                        }                }        }} /* *   General routines  * */static int inline extract_channel_id(char *name){        if (name[0] == 'c')                 return (name[3]-'0');        else                return (name[5]-'0');}static int inline extract_channel_media(char *name){        if (name[0] == 'c')                 return CTC;        else                return ESCON;}static void ctc_tab_init(void){                                            int          m;        int          i;        static int   t;        if (t == 0){                for (m = 0; m < CHANNEL_MEDIA;  m++) {                        for (i = 0; i < MAX_ADAPTERS;  i++) {                                ctc_adapter[m][i].devno[WRITE] = -ENODEV;                                ctc_adapter[m][i].devno[READ] = -ENODEV;                        }                }                t = 1;         }} static int ctc_buffer_alloc(struct channel *ctc) {                struct buffer    *p;        struct buffer    *q;        p = kmalloc(sizeof(p), GFP_KERNEL);        if (p == NULL)                 return -ENOMEM;        else {                  p->next = NULL;                  p->packets = 0;                p->block = (struct block *) __get_free_pages(GFP_KERNEL+GFP_DMA, 4);                if (p->block == NULL) {                        kfree(p);                        return -ENOMEM;                }        }           if (ctc->free_anchor == NULL)                 ctc->free_anchor = p;          else {                   q = ctc->free_anchor;                 while (q->next != NULL)                         q = q->next;                 q->next = p;        }        ctc->buffer_count++;      return 0;}static int ctc_buffer_free(struct channel *ctc) {                struct buffer    *p;                   if (ctc->free_anchor == NULL)                return -ENOMEM;                p = ctc->free_anchor;         ctc->free_anchor = p->next;        free_pages((__u32)p->block, 4);        kfree(p);        return 0;}static int inline ctc_buffer_swap(struct buffer **from, struct buffer **to) {                struct buffer    *p = NULL;        struct buffer    *q = NULL;         if (*from == NULL)                return -ENOMEM;         p = *from;        *from = p->next;        p->next = NULL;        if (*to == NULL)                *to = p;        else {                q = *to;                while (q->next != NULL)                        q = q->next;                q->next = p;        }        return 0;}/* *   ctc_setup function  *     this function is called for each ctc= keyword passed into the kernel  * *     valid parameter are: ctc=n,0xnnnn,0xnnnn,ctcx  *     where n      is the channel protocol always 0  *           0xnnnn is the cu number  read  *           0xnnnn is the cu number  write  *           ctcx can be ctc0 to ctc7 or escon0 to escon7  */#if LINUX_VERSION_CODE>=0x020300static int __init ctc_setup(char *dev_name)#else__initfunc(void ctc_setup(char *dev_name,int *ints))#endif{        struct adapterlist tmp;#if  LINUX_VERSION_CODE>=0x020300	#define CTC_MAX_PARMS 4	int ints[CTC_MAX_PARMS+1];		get_options(dev_name,CTC_MAX_PARMS,ints);	#define ctc_setup_return return(1)#else	#define ctc_setup_return return#endif        ctc_tab_init();                ctc_no_auto = 1;        if (!strcmp(dev_name,"noauto")) {                 printk(KERN_INFO "ctc: automatic channel selection deactivated\n");                 ctc_setup_return;        }        tmp.devno[WRITE] = -ENODEV;        tmp.devno[READ] = -ENODEV;         switch (ints[0]) {                              case 3: /* write channel passed */                        tmp.devno[WRITE] = ints[3];                                         case 2: /* read channel passed */                        tmp.devno[READ] = ints[2];                        if (tmp.devno[WRITE] == -ENODEV)                                tmp.devno[WRITE] = tmp.devno[READ] + 1;                 case 1: /* protocol type passed */                        tmp.protocol    = ints[1];                        if (tmp.protocol == 0) {                                break;                            } else {                                printk(KERN_WARNING "%s: wrong Channel protocol type passed\n", dev_name);                                ctc_setup_return;                        }			break;                default:                         printk(KERN_WARNING "ctc: wrong number of parameter passed\n");                        ctc_setup_return;        }        ctc_adapter[extract_channel_media(dev_name)][extract_channel_id(dev_name)] = tmp; #ifdef DEBUG        printk(DEBUG "%s: protocol=%x read=%04x write=%04x\n",             dev_name, tmp.protocol, tmp.devno[READ], tmp.devno[WRITE]);#endif          ctc_setup_return;        }#if LINUX_VERSION_CODE>=0x020300__setup("ctc=", ctc_setup);#endif/* *   ctc_probe  *      this function is called for each channel network device,  *      which is defined in the /init/main.c  */int ctc_probe(net_device *dev){               int                rc;        int                c;        int                i;        int                m;        struct ctc_priv    *privptr;        /* Only the first time the ctc_probe gets control */        if (channel_tab_initialized == 0) {                  channel_init();          }                ctc_tab_init();        m = extract_channel_media(dev->name);        i = extract_channel_id(dev->name);                if (channel_left(m) <=1)                 return -ENODEV;        if (ctc_no_auto == 1 && (ctc_adapter[m][i].devno[READ] == -ENODEV || ctc_adapter[m][i].devno[WRITE] == -ENODEV))                return -ENODEV;        dev->priv = kmalloc(sizeof(struct ctc_priv), GFP_KERNEL);        if (dev->priv == NULL)                return -ENOMEM;        memset(dev->priv, 0, sizeof(struct ctc_priv));          privptr = (struct ctc_priv *) (dev->priv);                for (c = 0; c < 2; c++) {                privptr->channel[c].devstat = kmalloc(sizeof(devstat_t), GFP_KERNEL);                if (privptr->channel[c].devstat == NULL){                        if (i == WRITE)                                kfree(privptr->channel[READ].devstat);                        return -ENOMEM;  

⌨️ 快捷键说明

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