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

📄 comx-hw-munich.c

📁 该文件是rt_linux
💻 C
📖 第 1 页 / 共 5 页
字号:
	    writeb(0x00, lbi + XPM2);	    writeb(0xf0, lbi + FMR0);	    writeb(0x80, lbi + PCD);	    writeb(0x80, lbi + PCR);	    writeb(0x00, lbi + LIM2);	    writeb(0x07, lbi + XC0);	    writeb(0x3d, lbi + XC1);	    writeb(0x05, lbi + RC0);	    writeb(0x00, lbi + RC1);	    writeb(0x83, lbi + FMR2);	    writeb(0x9f, lbi + XSW);	    writeb(0x0f, lbi + XSP);	    writeb(0x00, lbi + TSWM);	    writeb(0xe0, lbi + MODE);	    writeb(0xff, lbi + IDLE);	/* Idle Code to send in unused timeslots        */	    writeb(0x83, lbi + IPC);	/* interrupt query line mode: Push/pull output, active high     */	    writeb(0xbf, lbi + IMR3);	/* send an interrupt every second               */	    slicecom_set_framing(hw->boardnum, board->framing);	    slicecom_set_linecode(hw->boardnum, board->linecode);	    slicecom_set_clock_source(hw->boardnum, board->clock_source);	    slicecom_set_loopback(hw->boardnum, board->loopback);	    memset((void *)board->intervals, 0, sizeof(board->intervals));	    board->current_interval = 0;	    board->elapsed_seconds = 0;	    board->ses_seconds = 0;	    board->is_unavailable = 0;	    board->no_ses_seconds = 0;	    board->deg_elapsed_seconds = 0;	    board->deg_cumulated_errors = 0;	}	/* Enable the interrupts last                                                   */	/* These interrupts will be enabled. We do not need the others. */	writel(readl(MUNICH_VIRT(IMASK)) & ~(STAT_PTI | STAT_PRI | STAT_LBII | STAT_TSPA | STAT_RSPA), MUNICH_VIRT(IMASK));    }    spin_unlock_irqrestore(&mister_lock, flags);    dev->irq = board->irq;	/* hogy szep legyen az ifconfig outputja */    ccb = board->ccb;		/* TODO: ez igy csunya egy kicsit hogy benn is meg kinn is beletoltom :( */    spin_lock_irqsave(&mister_lock, flags);    set_current_state(TASK_UNINTERRUPTIBLE);    schedule_timeout(1);    /* Check if the selected timeslots aren't used already */    for (i = 0; i < 32; i++)	if (((1 << i) & timeslots) && !ccb->timeslot_spec[i].tti)	{	    printk("MUNICH_open: %s: timeslot %d already used by %s\n",		   dev->name, i, board->twins[ccb->timeslot_spec[i].txchannel]->name);	    spin_unlock_irqrestore(&mister_lock, flags);	    return -EBUSY;	/* TODO: lehet hogy valami mas errno kellene? */	}    /* find a free channel: */    /* TODO: ugly, rewrite it  */    for (channel = 0; channel <= 32; channel++)    {	if (channel == 32)	{			/* not found a free one */	    printk		("MUNICH_open: %s: FATAL: can not find a free channel - this should not happen!\n",		 dev->name);	    spin_unlock_irqrestore(&mister_lock, flags);	    return -ENODEV;	}	if (board->twins[channel] == NULL)	    break;		/* found the first free one */    }    board->lastcheck = jiffies;	/* avoid checking uninitialized hardware channel */    /* Open the channel. If fails, calls MUNICH_close() to properly free resources and stop the HW */    hw->channel = channel;    board->twins[channel] = dev;    board->use_count++;		/* meg nem nyitottuk meg a csatornat, de a twins-ben				   mar elfoglaltunk egyet, es ha a _close-t akarjuk hivni, akkor ez kell. */    for (i = 0; i < 32; i++)	if ((1 << i) & timeslots)	{	    ccb->timeslot_spec[i].tti = 0;	    ccb->timeslot_spec[i].txchannel = channel;	    ccb->timeslot_spec[i].txfillmask = ~0;	    ccb->timeslot_spec[i].rti = 0;	    ccb->timeslot_spec[i].rxchannel = channel;	    ccb->timeslot_spec[i].rxfillmask = ~0;	}    if (!board->isx21) rework_idle_channels(dev);    memset((void *)&(hw->tx_desc), 0, TX_DESC_MAX * sizeof(tx_desc_t));    memset((void *)&(hw->rx_desc), 0, RX_DESC_MAX * sizeof(rx_desc_t));    for (i = 0; i < TX_DESC_MAX; i++)    {	hw->tx_desc[i].fe = 1;	hw->tx_desc[i].fnum = 2;                hw->tx_desc[i].data     = virt_to_phys( & (hw->tx_data[i][0]) );                hw->tx_desc[i].next     = virt_to_phys( & (hw->tx_desc[ (i+1) % TX_DESC_MAX ]) );    }    hw->tx_desc_ptr = 0;	/* we will send an initial packet so it is correct: "oda irtunk utoljara" */    hw->busy = 0;    hw->tx_desc[hw->tx_desc_ptr].hold = 1;    hw->tx_desc[hw->tx_desc_ptr].no = 1;	/* TOD: inkabb csak 0 hosszut kuldjunk ki az initkor? */    for (i = 0; i < RX_DESC_MAX; i++)    {	hw->rx_desc[i].no = RXBUFFER_SIZE;	hw->rx_desc[i].data = virt_to_phys(&(hw->rx_data[i][0]));	hw->rx_desc[i].next = virt_to_phys(&(hw->rx_desc[(i+1) % RX_DESC_MAX]));	hw->rx_desc[i].status = 0xFF;    }    hw->rx_desc_ptr = 0;    hw->rx_desc[(hw->rx_desc_ptr + RX_DESC_MAX - 2) % RX_DESC_MAX].hold = 1;    memset((void *)&ccb->channel_spec[channel], 0, sizeof(channel_spec_t));    ccb->channel_spec[channel].ti = 0;	/* Transmit off */    ccb->channel_spec[channel].to = 1;    ccb->channel_spec[channel].ta = 0;    ccb->channel_spec[channel].th = 1;	/* Transmit hold        */    ccb->channel_spec[channel].ri = 0;	/* Receive off  */    ccb->channel_spec[channel].ro = 1;    ccb->channel_spec[channel].ra = 0;    ccb->channel_spec[channel].mode = 3;	/* HDLC */    ccb->action_spec = CCB_ACTIONSPEC_IN | (channel << 8);    writel(CMD_ARPCM, MUNICH_VIRT(CMD));    set_current_state(TASK_UNINTERRUPTIBLE);    schedule_timeout(1);    spin_unlock_irqrestore(&mister_lock, flags);    stat = 0;    jiffs = jiffies;    while (!((stat = readl(MUNICH_VIRT(STAT))) & (STAT_PCMA | STAT_PCMF)) && time_before(jiffies, jiffs + HZ))    {	set_current_state(TASK_UNINTERRUPTIBLE);	schedule_timeout(1);    }    if (stat & STAT_PCMF)    {	printk(KERN_ERR "MUNICH_open: %s: %s channel %d off failed\n",	       dev->name, board->devname, channel);	writel(readl(MUNICH_VIRT(STAT)) & STAT_PCMF, MUNICH_VIRT(STAT));	MUNICH_close(dev);	return -EAGAIN;    }    else if (!(stat & STAT_PCMA))    {	printk(KERN_ERR "MUNICH_open: %s: %s channel %d off timeout\n",	       dev->name, board->devname, channel);	MUNICH_close(dev);	return -EIO;    }    writel(readl(MUNICH_VIRT(STAT)) & STAT_PCMA, MUNICH_VIRT(STAT));    //      printk("MUNICH_open: %s: succesful channel off took %ld jiffies\n", board->devname, jiffies-jiffs);    spin_lock_irqsave(&mister_lock, flags);    set_current_state(TASK_UNINTERRUPTIBLE);    schedule_timeout(1);    ccb->channel_spec[channel].ifc = 1;	/* 1 .. 'Idle/Flag change' interrupt letiltva   */    ccb->channel_spec[channel].fit = 1;    ccb->channel_spec[channel].nitbs = 1;    ccb->channel_spec[channel].itbs = 2;    /* TODOO: lehet hogy jo lenne igy, de utana kellene nezni hogy nem okoz-e fragmentaciot */    //      ccb->channel_spec[channel].itbs = 2 * number_of_timeslots;    //      printk("open: %s: number_of_timeslots: %d\n", dev->name, number_of_timeslots);    ccb->channel_spec[channel].mode = 3;	/* HDLC */    ccb->channel_spec[channel].ftda = virt_to_phys(&(hw->tx_desc));    ccb->channel_spec[channel].frda = virt_to_phys(&(hw->rx_desc[0]));    ccb->channel_spec[channel].ti = 1;	/* Transmit init        */    ccb->channel_spec[channel].to = 0;    ccb->channel_spec[channel].ta = 1;    ccb->channel_spec[channel].th = 0;    ccb->channel_spec[channel].ri = 1;	/* Receive init */    ccb->channel_spec[channel].ro = 0;    ccb->channel_spec[channel].ra = 1;    ccb->action_spec = CCB_ACTIONSPEC_ICO | (channel << 8);    writel(CMD_ARPCM, MUNICH_VIRT(CMD));	/* Start the channel init */    set_current_state(TASK_UNINTERRUPTIBLE);    schedule_timeout(1);    spin_unlock_irqrestore(&mister_lock, flags);    stat = 0;			/* Wait for the action to complete max. 1 second */    jiffs = jiffies;    while (!((stat = readl(MUNICH_VIRT(STAT))) & (STAT_PCMA | STAT_PCMF)) && time_before(jiffies, jiffs + HZ))    {	set_current_state(TASK_UNINTERRUPTIBLE);        schedule_timeout(1);    }    if (stat & STAT_PCMF)    {	printk(KERN_ERR "MUNICH_open: %s: channel open ARPCM failed\n",	       board->devname);	writel(readl(MUNICH_VIRT(STAT)) & STAT_PCMF, MUNICH_VIRT(STAT));	MUNICH_close(dev);	return -EAGAIN;    }    else if (!(stat & STAT_PCMA))    {	printk(KERN_ERR "MUNICH_open: %s: channel open ARPCM timeout\n",	       board->devname);	MUNICH_close(dev);	return -EIO;    }    writel(readl(MUNICH_VIRT(STAT)) & STAT_PCMA, MUNICH_VIRT(STAT));    //      printk("MUNICH_open: %s: succesful channel open took %ld jiffies\n", board->devname, jiffies-jiffs);    spin_lock_irqsave(&mister_lock, flags);    ccb->channel_spec[channel].nitbs = 0;	/* once ITBS defined, these must be 0   */    ccb->channel_spec[channel].itbs = 0;    if (board->isx21)    {	board->modemline_timer.data = (unsigned long)board;	board->modemline_timer.function = pcicom_modemline;	board->modemline_timer.expires = jiffies + HZ;	add_timer((struct timer_list *)&board->modemline_timer);    }    /* It is done. Declare that we're open: */    hw->busy = 0;		/* It may be 1 if the frame at Tx init already ended, but it is not     */    /* a real problem: we compute hw->busy on every interrupt                       */    hw->rafutott = 0;    ch->init_status |= HW_OPEN;    /* Initialize line state: */    if (board->lineup)	ch->line_status |= LINE_UP;    else	ch->line_status &= ~LINE_UP;    /* Remove w attribute from /proc files associated to hw parameters:       no write when the device is open */    for (; procfile; procfile = procfile->next)	if (strcmp(procfile->name, FILENAME_BOARDNUM) == 0 ||	    strcmp(procfile->name, FILENAME_TIMESLOTS) == 0)	    procfile->mode = S_IFREG | 0444;    spin_unlock_irqrestore(&mister_lock, flags);    return 0;}/* * Hardware close routine. * Called by comx (upper) layer when the user wants to bring down the interface * with ifconfig. * We also call it from MUNICH_open, if the open fails. * Brings down hardware, frees resources, stops receiver * Returns 0 on OK, or standard error value on error. */static int MUNICH_close(struct net_device *dev){    struct comx_channel *ch = dev->priv;    struct slicecom_privdata *hw = ch->HW_privdata;    struct proc_dir_entry *procfile = ch->procdir->subdir;    munich_board_t *board;    munich_ccb_t *ccb;    u32 *bar1;    u32 timeslots = hw->timeslots;    int stat, i, channel = hw->channel;    unsigned long jiffs;    board = hw->boardnum + (ch->hardware == &pcicomhw ? pcicom_boards : slicecom_boards);    ccb = board->ccb;    bar1 = board->bar1;    if (board->isx21)	del_timer((struct timer_list *)&board->modemline_timer);    spin_lock_irqsave(&mister_lock, flags);    set_current_state(TASK_UNINTERRUPTIBLE);    schedule_timeout(1);    /* Disable receiver for the channel: */    for (i = 0; i < 32; i++)	if ((1 << i) & timeslots)	{	    ccb->timeslot_spec[i].tti = 1;	    ccb->timeslot_spec[i].txfillmask = 0;	/* just to be double-sure :) */	    ccb->timeslot_spec[i].rti = 1;	    ccb->timeslot_spec[i].rxfillmask = 0;	}    if (!board->isx21) rework_idle_channels(dev);    ccb->channel_spec[channel].ti = 0;	/* Receive off, Transmit off */    ccb->channel_spec[channel].to = 1;    ccb->channel_spec[channel].ta = 0;    ccb->channel_spec[channel].th = 1;    ccb->channel_spec[channel].ri = 0;    ccb->channel_spec[channel].ro = 1;    ccb->channel_spec[channel].ra = 0;    board->twins[channel] = NULL;    ccb->action_spec = CCB_ACTIONSPEC_IN | (channel << 8);    writel(CMD_ARPCM, MUNICH_VIRT(CMD));    set_current_state(TASK_UNINTERRUPTIBLE);    schedule_timeout(1);    spin_unlock_irqrestore(&mister_lock, flags);    stat = 0;    jiffs = jiffies;    while (!((stat = readl(MUNICH_VIRT(STAT))) & (STAT_PCMA | STAT_PCMF)) && time_before(jiffies, jiffs + HZ))    {	set_current_state(TASK_UNINTERRUPTIBLE);	schedule_timeout(1);    }    if (stat & STAT_PCMF)    {	printk(KERN_ERR	       "MUNICH_close: %s: FATAL: channel off ARPCM failed, not closing!\n",	       dev->name);	writel(readl(MUNICH_VIRT(STAT)) & STAT_PCMF, MUNICH_VIRT(STAT));	/* If we return success, the privdata (and the descriptor list) will be freed */	return -EIO;    }    else if (!(stat & STAT_PCMA))	printk(KERN_ERR "MUNICH_close: %s: channel off ARPCM timeout\n",	       board->devname);    writel(readl(MUNICH_VIRT(STAT)) & STAT_PCMA, MUNICH_VIRT(STAT));    //      printk("MUNICH_close: %s: channel off took %ld jiffies\n", board->devname, jiffies-jiffs);    spin_lock_irqsave(&mister_lock, flags);    if (board->use_count) board->use_count--;    if (!board->use_count)	/* we were the last user of the board */    {	printk("MUNICH_close: bringing down board %s\n", board->devname);	/* program down the board: */	writel(0x0000FF7F, MUNICH_VIRT(IMASK));	/* do not send any interrupts */	writel(0, MUNICH_VIRT(CMD));	/* stop the timer if someone started it */	writel(~0U, MUNICH_VIRT(STAT));	/* if an interrupt came between the cli()-sti(), quiet it */	if (ch->hardware == &pcicomhw)	    writel(0x1400, MUNICH_VIRT(GPDATA));	/* Put the board into 'reset' state: */	pci_write_config_dword(board->pci, MUNICH_PCI_PCIRES, 0xe0000);	/* Free irq and other resources: */	if (board->irq)	    free_irq(board->irq, (void *)board);	/* Ha nem inicializalta magat, akkor meg nincs irq */	board->irq = 0;	/* Free CCB and the interrupt queues */	if (board->ccb) kfree((void *)board->ccb);	if (board->tiq) kfree((void *)board->tiq);	if (board->riq) kfree((void *)board->riq);	if (board->piq) kfree((void *)board->piq);	board->ccb = NULL;	board->tiq = board->riq = board->piq = NULL;    }    /* Enable setting of hw parameters */    for (; procfile; procfile = procfile->next)	if (strcmp(procfile->name, FILENAME_BOARDNUM) == 0 ||	    strcmp(procfile->name, FILENAME_TIMESLOTS) 

⌨️ 快捷键说明

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