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

📄 farsync.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	}}static voiddo_bottom_half_rx(struct fst_card_info *card){	struct fst_port_info *port;	int pi;	int rx_count = 0;	/* Check for rx completions on all ports on this card */	dbg(DBG_RX, "do_bottom_half_rx\n");	for (pi = 0, port = card->ports; pi < card->nports; pi++, port++) {		if (!port->run)			continue;		while (!(FST_RDB(card, rxDescrRing[pi][port->rxpos].bits)			 & DMA_OWN) && !(card->dmarx_in_progress)) {			if (rx_count > fst_max_reads) {				/*				 * Don't spend forever in receive processing				 * Schedule another event				 */				fst_q_work_item(&fst_work_intq, card->card_no);				tasklet_schedule(&fst_int_task);				break;	/* Leave the loop */			}			fst_intr_rx(card, port);			rx_count++;		}	}}/* *      The interrupt service routine *      Dev_id is our fst_card_info pointer */irqreturn_tfst_intr(int irq, void *dev_id, struct pt_regs *regs){	struct fst_card_info *card;	struct fst_port_info *port;	int rdidx;		/* Event buffer indices */	int wridx;	int event;		/* Actual event for processing */	unsigned int dma_intcsr = 0;	unsigned int do_card_interrupt;	unsigned int int_retry_count;	if ((card = dev_id) == NULL) {		dbg(DBG_INTR, "intr: spurious %d\n", irq);		return IRQ_NONE;	}	/*	 * Check to see if the interrupt was for this card	 * return if not	 * Note that the call to clear the interrupt is important	 */	dbg(DBG_INTR, "intr: %d %p\n", irq, card);	if (card->state != FST_RUNNING) {		printk_err		    ("Interrupt received for card %d in a non running state (%d)\n",		     card->card_no, card->state);		/* 		 * It is possible to really be running, i.e. we have re-loaded		 * a running card		 * Clear and reprime the interrupt source 		 */		fst_clear_intr(card);		return IRQ_HANDLED;	}	/* Clear and reprime the interrupt source */	fst_clear_intr(card);	/*	 * Is the interrupt for this card (handshake == 1)	 */	do_card_interrupt = 0;	if (FST_RDB(card, interruptHandshake) == 1) {		do_card_interrupt += FST_CARD_INT;		/* Set the software acknowledge */		FST_WRB(card, interruptHandshake, 0xEE);	}	if (card->family == FST_FAMILY_TXU) {		/*		 * Is it a DMA Interrupt		 */		dma_intcsr = inl(card->pci_conf + INTCSR_9054);		if (dma_intcsr & 0x00200000) {			/*			 * DMA Channel 0 (Rx transfer complete)			 */			dbg(DBG_RX, "DMA Rx xfer complete\n");			outb(0x8, card->pci_conf + DMACSR0);			fst_rx_dma_complete(card, card->dma_port_rx,					    card->dma_len_rx, card->dma_skb_rx,					    card->dma_rxpos);			card->dmarx_in_progress = 0;			do_card_interrupt += FST_RX_DMA_INT;		}		if (dma_intcsr & 0x00400000) {			/*			 * DMA Channel 1 (Tx transfer complete)			 */			dbg(DBG_TX, "DMA Tx xfer complete\n");			outb(0x8, card->pci_conf + DMACSR1);			fst_tx_dma_complete(card, card->dma_port_tx,					    card->dma_len_tx, card->dma_txpos);			card->dmatx_in_progress = 0;			do_card_interrupt += FST_TX_DMA_INT;		}	}	/*	 * Have we been missing Interrupts	 */	int_retry_count = FST_RDL(card, interruptRetryCount);	if (int_retry_count) {		dbg(DBG_ASS, "Card %d int_retry_count is  %d\n",		    card->card_no, int_retry_count);		FST_WRL(card, interruptRetryCount, 0);	}	if (!do_card_interrupt) {		return IRQ_HANDLED;	}	/* Scehdule the bottom half of the ISR */	fst_q_work_item(&fst_work_intq, card->card_no);	tasklet_schedule(&fst_int_task);	/* Drain the event queue */	rdidx = FST_RDB(card, interruptEvent.rdindex) & 0x1f;	wridx = FST_RDB(card, interruptEvent.wrindex) & 0x1f;	while (rdidx != wridx) {		event = FST_RDB(card, interruptEvent.evntbuff[rdidx]);		port = &card->ports[event & 0x03];		dbg(DBG_INTR, "Processing Interrupt event: %x\n", event);		switch (event) {		case TE1_ALMA:			dbg(DBG_INTR, "TE1 Alarm intr\n");			if (port->run)				fst_intr_te1_alarm(card, port);			break;		case CTLA_CHG:		case CTLB_CHG:		case CTLC_CHG:		case CTLD_CHG:			if (port->run)				fst_intr_ctlchg(card, port);			break;		case ABTA_SENT:		case ABTB_SENT:		case ABTC_SENT:		case ABTD_SENT:			dbg(DBG_TX, "Abort complete port %d\n", port->index);			break;		case TXA_UNDF:		case TXB_UNDF:		case TXC_UNDF:		case TXD_UNDF:			/* Difficult to see how we'd get this given that we			 * always load up the entire packet for DMA.			 */			dbg(DBG_TX, "Tx underflow port %d\n", port->index);                        hdlc_stats(port_to_dev(port))->tx_errors++;                        hdlc_stats(port_to_dev(port))->tx_fifo_errors++;			dbg(DBG_ASS, "Tx underflow on card %d port %d\n",			    card->card_no, port->index);			break;		case INIT_CPLT:			dbg(DBG_INIT, "Card init OK intr\n");			break;		case INIT_FAIL:			dbg(DBG_INIT, "Card init FAILED intr\n");			card->state = FST_IFAILED;			break;		default:			printk_err("intr: unknown card event %d. ignored\n",				   event);			break;		}		/* Bump and wrap the index */		if (++rdidx >= MAX_CIRBUFF)			rdidx = 0;	}	FST_WRB(card, interruptEvent.rdindex, rdidx);        return IRQ_HANDLED;}/*      Check that the shared memory configuration is one that we can handle *      and that some basic parameters are correct */static voidcheck_started_ok(struct fst_card_info *card){	int i;	/* Check structure version and end marker */	if (FST_RDW(card, smcVersion) != SMC_VERSION) {		printk_err("Bad shared memory version %d expected %d\n",			   FST_RDW(card, smcVersion), SMC_VERSION);		card->state = FST_BADVERSION;		return;	}	if (FST_RDL(card, endOfSmcSignature) != END_SIG) {		printk_err("Missing shared memory signature\n");		card->state = FST_BADVERSION;		return;	}	/* Firmware status flag, 0x00 = initialising, 0x01 = OK, 0xFF = fail */	if ((i = FST_RDB(card, taskStatus)) == 0x01) {		card->state = FST_RUNNING;	} else if (i == 0xFF) {		printk_err("Firmware initialisation failed. Card halted\n");		card->state = FST_HALTED;		return;	} else if (i != 0x00) {		printk_err("Unknown firmware status 0x%x\n", i);		card->state = FST_HALTED;		return;	}	/* Finally check the number of ports reported by firmware against the	 * number we assumed at card detection. Should never happen with	 * existing firmware etc so we just report it for the moment.	 */	if (FST_RDL(card, numberOfPorts) != card->nports) {		printk_warn("Port count mismatch on card %d."			    " Firmware thinks %d we say %d\n", card->card_no,			    FST_RDL(card, numberOfPorts), card->nports);	}}static intset_conf_from_info(struct fst_card_info *card, struct fst_port_info *port,		   struct fstioc_info *info){	int err;	unsigned char my_framing;	/* Set things according to the user set valid flags 	 * Several of the old options have been invalidated/replaced by the 	 * generic hdlc package.	 */	err = 0;	if (info->valid & FSTVAL_PROTO) {		if (info->proto == FST_RAW)			port->mode = FST_RAW;		else			port->mode = FST_GEN_HDLC;	}	if (info->valid & FSTVAL_CABLE)		err = -EINVAL;	if (info->valid & FSTVAL_SPEED)		err = -EINVAL;	if (info->valid & FSTVAL_PHASE)		FST_WRB(card, portConfig[port->index].invertClock,			info->invertClock);	if (info->valid & FSTVAL_MODE)		FST_WRW(card, cardMode, info->cardMode);	if (info->valid & FSTVAL_TE1) {		FST_WRL(card, suConfig.dataRate, info->lineSpeed);		FST_WRB(card, suConfig.clocking, info->clockSource);		my_framing = FRAMING_E1;		if (info->framing == E1)			my_framing = FRAMING_E1;		if (info->framing == T1)			my_framing = FRAMING_T1;		if (info->framing == J1)			my_framing = FRAMING_J1;		FST_WRB(card, suConfig.framing, my_framing);		FST_WRB(card, suConfig.structure, info->structure);		FST_WRB(card, suConfig.interface, info->interface);		FST_WRB(card, suConfig.coding, info->coding);		FST_WRB(card, suConfig.lineBuildOut, info->lineBuildOut);		FST_WRB(card, suConfig.equalizer, info->equalizer);		FST_WRB(card, suConfig.transparentMode, info->transparentMode);		FST_WRB(card, suConfig.loopMode, info->loopMode);		FST_WRB(card, suConfig.range, info->range);		FST_WRB(card, suConfig.txBufferMode, info->txBufferMode);		FST_WRB(card, suConfig.rxBufferMode, info->rxBufferMode);		FST_WRB(card, suConfig.startingSlot, info->startingSlot);		FST_WRB(card, suConfig.losThreshold, info->losThreshold);		if (info->idleCode)			FST_WRB(card, suConfig.enableIdleCode, 1);		else			FST_WRB(card, suConfig.enableIdleCode, 0);		FST_WRB(card, suConfig.idleCode, info->idleCode);#if FST_DEBUG		if (info->valid & FSTVAL_TE1) {			printk("Setting TE1 data\n");			printk("Line Speed = %d\n", info->lineSpeed);			printk("Start slot = %d\n", info->startingSlot);			printk("Clock source = %d\n", info->clockSource);			printk("Framing = %d\n", my_framing);			printk("Structure = %d\n", info->structure);			printk("interface = %d\n", info->interface);			printk("Coding = %d\n", info->coding);			printk("Line build out = %d\n", info->lineBuildOut);			printk("Equaliser = %d\n", info->equalizer);			printk("Transparent mode = %d\n",			       info->transparentMode);			printk("Loop mode = %d\n", info->loopMode);			printk("Range = %d\n", info->range);			printk("Tx Buffer mode = %d\n", info->txBufferMode);			printk("Rx Buffer mode = %d\n", info->rxBufferMode);			printk("LOS Threshold = %d\n", info->losThreshold);			printk("Idle Code = %d\n", info->idleCode);		}#endif	}#if FST_DEBUG	if (info->valid & FSTVAL_DEBUG) {		fst_debug_mask = info->debug;	}#endif	return err;}static voidgather_conf_info(struct fst_card_info *card, struct fst_port_info *port,		 struct fstioc_info *info){	int i;	memset(info, 0, sizeof (struct fstioc_info));	i = port->index;	info->kernelVersion = LINUX_VERSION_CODE;	info->nports = card->nports;	info->type = card->type;	info->state = card->state;	info->proto = FST_GEN_HDLC;	info->index = i;#if FST_DEBUG	info->debug = fst_debug_mask;#endif	/* Only mark information as valid if card is running.	 * Copy the data anyway in case it is useful for diagnostics	 */	info->valid = ((card->state == FST_RUNNING) ? FSTVAL_ALL : FSTVAL_CARD)#if FST_DEBUG	    | FSTVAL_DEBUG#endif	    ;	info->lineInterface = FST_RDW(card, portConfig[i].lineInterface);	info->internalClock = FST_RDB(card, portConfig[i].internalClock);	info->lineSpeed = FST_RDL(card, portConfig[i].lineSpeed);	info->invertClock = FST_RDB(card, portConfig[i].invertClock);	info->v24IpSts = FST_RDL(card, v24IpSts[i]);	info->v24OpSts = FST_RDL(card, v24OpSts[i]);	info->clockStatus = FST_RDW(card, clockStatus[i]);	info->cableStatus = FST_RDW(card, cableStatus);	info->cardMode = FST_RDW(card, cardMode);	info->smcFirmwareVersion = FST_RDL(card, smcFirmwareVersion);	/*	 * The T2U can report cable presence for both A or B	 * in bits 0 and 1 of cableStatus.  See which port we are and 	 * do the mapping.	 */	if (card->family == FST_FAMILY_TXU) {		if (port->index == 0) {			/*			 * Port A			 */			info->cableStatus = info->cableStatus & 1;		} else {			/*			 * Port B			 */			info->cableStatus = info->cableStatus >> 1;			info->cableStatus = info->cableStatus & 1;		}	}	/*	 * Some additional bits if we are TE1	 */	if (card->type == FST_TYPE_TE1) {		info->lineSpeed = FST_RDL(card, suConfig.dataRate);		info->clockSource = FST_RDB(card, suConfig.clocking);		info->framing = FST_RDB(card, suConfig.framing);		info->structure = FST_RDB(card, suConfig.structure);		info->interface = FST_RDB(card, suConfig.interface);		info->coding = FST_RDB(card, suConfig.coding);		info->lineBuildOut = FST_RDB(card, suConfig.lineBuildOut);		info->equalizer = FST_RDB(card, suConfig.equalizer);		info->loopMode = FST_RDB(card, suConfig.loopMode);		info->range = FST_RDB(card, suConfig.range);		info->txBufferMode = FST_RDB(card, suConfig.txBufferMode);		info->rxBufferMode = FST_RDB(card, suConfig.rxBufferMode);		info->startingSlot = FST_RDB(card, suConfig.startingSlot);		info->losThreshold = FST_RDB(card, suConfig.losThreshold);		if (FST_RDB(card, suConfig.enableIdleCode))			info->idleCode = FST_RDB(card, suConfig.idleCode);		else			info->idleCode = 0;		info->receiveBufferDelay =		    FST_RDL(card, suStatus.receiveBufferDelay);		info->framingErrorCount =		    FST_RDL(card, suStatus.framingErrorCount);		info->codeViolationCount =		    FST_RDL(card, suStatus.codeViolationCount);		info->crcErrorCount = FST_RDL(card, suStatus.crcErrorCount);		info->lineAttenuation = FST_RDL(card, suStatus.lineAttenuation);		info->lossOfSignal = FST_RDB(card, suStatus.lossOfSignal);		info->receiveRemoteAlarm =		    FST_RDB(card, suStatus.receiveRemoteAlarm);		info->alarmIndicationSignal =		    FST_RDB(card, suStatus.alarmIndicationSignal);	}}static intfst_set_iface(struct fst_card_info *card, struct fst_port_info *port,	      struct ifreq *ifr){	sync_serial_settings sync;	int i;	if (ifr->ifr_settings.size != sizeof (sync)) {		return -ENOMEM;	}	if (copy_from_user	    (&sync, ifr->ifr_settings.ifs_ifsu.sync, sizeof (sync))) {		return -EFAULT;	}	if (sync.loopback)		return -EINVAL;	i = port->index;	switch (ifr->ifr_settings.type) {	case IF_IFACE_V35:		FST_WRW(card, portConfig[i].lineInterface, V35);		port->hwif = V35;		break;	case IF_IFACE_V24:		FST_WRW(card, portConfig[i].lineInterface, V24);		port->hwif = V24;		break;	case IF_IFACE_X21:		FST_WRW(card, portConfig[i].lineInterface, X21);		port->hwif = X21;		break;	case IF_IFACE_X21D:		FST_WRW(card, portConfig[i].lineInterface, X21D);		port->hwif = X21D;		break;	case IF_IFACE_T1:		FST_WRW(card, portConfig[i].lineInterface, T1);		port->hwif = T1;		break;	case IF_IFACE_E1:		FST_WRW(card, portConfig[i].lineInterface, E1);		port->hwif = E1;		break;	case IF_IFACE_SYNC_SERIAL:		break;	default:

⌨️ 快捷键说明

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