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

📄 c7000.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	c7000_clearbit_busy(TB_TX, dev);	s390irq_spin_unlock_irqrestore(cup->irq, saveflags);	CPrintk(1, "c7000: c7000_xmit: exits for unit 0x%x\n", cup->devno);	return(0);}/*	Handle an ioctl from a user process.*/static intc7000_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd){	CPrintk(1, "c7000: c7000_ioctl: entered for base unit 0x%lx with cmd %d\n", dev->base_addr, cmd);	return(0);}/*	Analyze the interrupt status and return a value	that identifies the type.*/static enum c7000_ruptc7000_check_csw(devstat_t *devstat){	/*		Check for channel detected conditions (except PCI).	*/	if ((devstat->cstat & ~SCHN_STAT_PCI) != 0) {		CPrintk(0, "c7000: c7000_check_csw: channel status 0x%x for unit 0x%x\n", devstat->cstat, devstat->devno);		return(C7000_CHANERR);	}	/*		Fast path the normal cases.	*/	if (devstat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))		return(C7000_NORMAL);	if (devstat->cstat == SCHN_STAT_PCI)		return(C7000_NORMAL);	/*		Check for exceptions.	*/	if (devstat->dstat & DEV_STAT_UNIT_CHECK) {		CPrintk(0, "c7000: c7000_check_csw: unit check for unit 0x%x, sense byte0 0x%2.2x\n", devstat->devno, devstat->ii.sense.data[0]);		if (devstat->ii.sense.data[0] == C7000_BOX_RESET)			return(C7000_UCK_RESET);		else			return(C7000_UCK);	} else if (devstat->dstat & DEV_STAT_UNIT_EXCEP) {		CPrintk(0, "c7000: c7000_check_csw: unit exception for unit 0x%x\n", devstat->devno);		return(C7000_UE);	} else if (devstat->dstat & DEV_STAT_ATTENTION) {		CPrintk(0, "c7000: c7000_check_csw: attention for unit 0x%x\n", devstat->devno);		return(C7000_ATTN);	} else if (devstat->dstat & DEV_STAT_BUSY) {		CPrintk(0, "c7000: c7000_check_csw: busy for unit 0x%x\n", devstat->devno);		return(C7000_BUSY);	} else {		CPrintk(0, "c7000: c7000_check_csw: channel status 0x%2.2x , device status 0x%2.2x, devstat flags 0x%8.8x for unit 0x%x\n",			devstat->cstat, devstat->dstat, devstat->flag, devstat->devno);		return(C7000_OTHER);	}	/* NOT REACHED */}/*	Retry the last CCW chain to the unit.*/static voidc7000_retry_io(struct c7000_unit *cup){	int	rc;	unsigned long	parm;	__u8	flags = 0x00;	ccw1_t	*ccwp;	if (++cup->retries > C7000_MAX_RETRIES) {		c7000_error(cup->cntlp);		CPrintk(0, "c7000: c7000_retry_io: retry IO for unit 0x%x exceeds maximum retry count\n", cup->devno);		return;	}	set_bit(0, (void *)&cup->IO_active);	parm = (unsigned long)cup;	if (cup->state == C7000_READ || cup->state == C7000_WRITE)		ccwp = &cup->proc_head->ccws[0];	else		ccwp = &cup->ccws[0];	if ((rc = do_IO(cup->irq, ccwp, parm, 0xff, flags)) != 0) {		CPrintk(0, "c7000: c7000_retry_io: can not retry IO for unit 0x%x, return code %d\n", cup->devno, rc);		clear_bit(0, (void *)&cup->IO_active);		c7000_error(cup->cntlp);	}	CPrintk(1, "c7000: c7000_retry_io: retry IO for unit 0x%x, retry count %d\n", cup->devno, cup->retries);	return;}/*	Process a read interrupt by scanning the list of buffers	for ones that have completed and queue them for the bottom	half to process.*/static voidc7000_proc_rintr(struct c7000_unit *cup){	struct	c7000_buffer	*buf;	struct	c7000_rd_header	*head;	int			num_read = 0;	while (cup->proc_head != NULL) {		head = (struct c7000_rd_header *)(cup->proc_head->data + C7000_DATAL);		/*			The flag byte in the read header will be set to			FLAG_FF when the buffer has been read.		*/		if (head->flag != FLAG_FF)			break;				/*			Dequeue the buffer from the proc chain			and enqueue it on the bh chain for			the bh routine to process.		*/		buf = c7000_dequeue_buffer(cup);		c7000_queue_bh_buffer(cup, buf);		num_read++;	}	CPrintk(1, "c7000: c7000_proc_rintr: %d buffers read for unit 0x%x\n", num_read, cup->devno);	return;}/*	Process all completed buffers on the proc chain.	A buffer is completed if it's READFF flag is FLAG_FF.*/static intc7000_proc_wintr(struct c7000_unit *cup){	struct	c7000_controller	*ccp = cup->cntlp;	struct	c7000_buffer		*buf;	int				num_write = 0;	if (cup->proc_head == NULL) {		CPrintk(0, "c7000: c7000_proc_wintr: unexpected NULL processing chain pointer for unit 0x%x\n", cup->devno);		return(num_write);	}	while (cup->proc_head != NULL) {		/*			Check if the buffer has completed.		*/		if (*(cup->proc_head->data + C7000_DATAL + C7000_READHDRL) != FLAG_FF)			break;		/*			Remove buffer from top of processing chain.			Place it on free list.		*/		buf = c7000_dequeue_buffer(cup);		ccp->stats.tx_bytes += buf->len;		ccp->stats.tx_packets++;		c7000_release_buffer(cup, buf);		num_write++;	}	CPrintk(1, "c7000: c7000_proc_wintr: %d buffers written for unit 0x%x\n", num_write, cup->devno);	return(num_write);}/*	Interrupt handler.*/static voidc7000_intr(int irq, void *initparm, struct pt_regs *regs){	devstat_t			*devstat = ((devstat_t *) initparm);	struct	c7000_unit		*cup = NULL;	struct	c7000_controller	*ccp = NULL;	struct	net_device		*dev = NULL;	unsigned long			parm;	__u8				flags = 0x00;	int				rc;	/*		Discard unsolicited interrupts	*/	if (devstat->intparm == 0) {		CPrintk(0, "c7000: c7000_intr: unsolicited interrupt for device 0x%x, cstat = 0x%2.2x, dstat = 0x%2.2x, flag = 0x%8.8x\n",			devstat->devno, devstat->cstat, devstat->dstat, devstat->flag);		return;	}	/*		Obtain the c7000_unit structure pointer.	*/	cup = (struct c7000_unit *)(devstat->intparm);	/*		Obtain the c7000_controller structure and device structure		pointers.	*/	if (cup == NULL) {		CPrintk(0, "c7000: c7000_intr: c7000_unit pointer is NULL in devstat\n");		return;	}	ccp = cup->cntlp;	if (ccp == NULL) {		CPrintk(0, "c7000: c7000_intr: c7000_cntlp pointer is NULL in c7000_unit structure %p for unit 0x%x\n", cup, cup->devno);		return;	}	dev = ccp->dev;	if (dev == NULL) {		CPrintk(0, "c7000: c7000_intr: device pointer is NULL in c7000_controller structure %p for unit 0x%x\n", ccp, cup->devno);		return;	}	/*		Finite state machine (fsm) handling.	*/	CPrintk(1, "c7000: c7000_intr: entered with state %d flag 0x%8.8x for unit 0x%x\n", cup->state, devstat->flag, cup->devno);	switch(cup->state) {		/*			Not expected to be here when in INIT state.		*/		case C7000_INIT:			break;		/*			Enter state C7000_SID and wakeup the sleeping			process in c7000_open.		*/		case C7000_HALT:			if ((devstat->flag & DEVSTAT_FINAL_STATUS) == 0)				break;			cup->state = C7000_SID;			wake_up(&cup->wait);			break;				/*			Enter state C7000_SYSVAL and wakeup the sleeping			process in c7000_open.		*/					case C7000_SID:			if ((devstat->flag & DEVSTAT_FINAL_STATUS) == 0)				break;			if (c7000_check_csw(devstat) != 0) {				c7000_retry_io(cup);				if (cup->state == C7000_ERROR)					wake_up(&cup->wait);				break;			}			cup->retries = 0;			cup->state = C7000_SYSVAL;			wake_up(&cup->wait);			break;		/*			Wakeup the sleeping process in c7000_open.		*/		case C7000_SYSVAL:			if ((devstat->flag & DEVSTAT_FINAL_STATUS) == 0)				break;			if (c7000_check_csw(devstat) != 0) {				c7000_retry_io(cup);				if (cup->state == C7000_ERROR)					wake_up(&cup->wait);				break;			}			cup->retries = 0;			wake_up(&cup->wait);			break;		/*			Wakeup the sleeping process in c7000_open.		*/		case C7000_CONNECT:			if ((devstat->flag & DEVSTAT_FINAL_STATUS) == 0)				break;			if (c7000_check_csw(devstat) != 0) {				c7000_retry_io(cup);				if (cup->state == C7000_ERROR)					wake_up(&cup->wait);				break;			}			cup->retries = 0;			wake_up(&cup->wait);			break;		/*			Not expected to be entered here.		*/		case C7000_READY:			break;		/*			Process the data that was just read.		*/		case C7000_READ:			if ((devstat->flag & (DEVSTAT_PCI | DEVSTAT_FINAL_STATUS)) == 0)				break;			CPrintk(1, "c7000: c7000_intr: process read interrupt for unit 0x%x , devstat flag = 0x%8.8x\n", cup->devno, devstat->flag);			/*				Check for serious errors.			*/			if (c7000_check_csw(devstat) != 0) {				ccp->stats.rx_errors++;				c7000_error(cup->cntlp);				break;			}			/*				Build the bottom half buffer list.			*/			c7000_proc_rintr(cup);			/*				When final status is received clear				the IO active bit.			*/			if (devstat->flag & DEVSTAT_FINAL_STATUS) {				clear_bit(0, (void *)&cup->IO_active);			}			/*				If there are free buffers redrive the IO.			*/			if ((devstat->flag & DEVSTAT_FINAL_STATUS) &&			    (cup->free != NULL)) {				c7000_bld_read_chain(cup);				parm = (unsigned long)cup;				set_bit(0, (void *)&cup->IO_active);				if ((rc = do_IO(cup->irq, &cup->proc_head->ccws[0], parm, 0xff, flags)) != 0) {					clear_bit(0, (void *)&cup->IO_active);					CPrintk(0, "c7000: c7000_intr: do_IO failed with return code %d for unit 0x%x\n", rc, cup->devno);					c7000_error(cup->cntlp);					break;				}				CPrintk(1, "c7000: c7000_intr: started read io for unit 0x%x\n", cup->devno);			}			/*				Initiate bottom half routine to process				data that was read.			*/			if (test_and_set_bit(C7000_BH_ACTIVE, (void *)&cup->flag_a) == 0) {				queue_task(&cup->tq, &tq_immediate);				mark_bh(IMMEDIATE_BH);			}			break;		/*			Free the transmitted buffers and restart the channel			process (if necessary).		*/		case C7000_WRITE:			if ((devstat->flag & DEVSTAT_FINAL_STATUS) == 0)				break;			if (c7000_check_csw(devstat) != 0) {				ccp->stats.tx_errors++;				c7000_error(cup->cntlp);				break;			}			/*				If at least one buffer was freed, clear				the NOBUFFER indication.			*/			if (c7000_proc_wintr(cup) != 0) {				c7000_clearbit_busy(TB_NOBUFFER, dev);			}			/*				Restart the channel program if there are more				buffers on the processing chain.			*/			if (cup->proc_head != NULL) {				c7000_bld_wrt_chain(cup);				parm = (unsigned long)cup;				set_bit(0, (void *)&cup->IO_active);				if ((rc = do_IO(cup->irq, &cup->proc_head->ccws[0], parm, 0xff, flags)) != 0) {					CPrintk(0, "c7000: c7000_intr: do_IO failed with return code %d for unit 0x%x\n", rc, cup->devno);					clear_bit(0, (void *)&cup->IO_active);					c7000_error(cup->cntlp);					break;				}				dev->trans_start = jiffies;			} else {				clear_bit(0, (void *)&cup->IO_active);				cup->state = C7000_READY;			}			break;		/*			Disconnect message completed.  Wakeup the			sleeping process in c7000_stop.		*/		case C7000_DISC:			if ((devstat->flag & DEVSTAT_FINAL_STATUS) == 0)				break;			if (c7000_check_csw(devstat) != 0) {				c7000_retry_io(cup);				if (cup->state == C7000_ERROR)					wake_up(&cup->wait);				break;			}			cup->retries = 0;			wake_up(&cup->wait);			break;		/*			Subchannel is now halted.  Wakeup the sleeping			process in c7000_stop.  Set the state to C7000_STOPPED.		*/		case C7000_STOP:			cup->state = C7000_STOPPED;			wake_up(&cup->wait);			break;		/*			When in error state, stay there until the			interface is recycled.		*/		case C7000_ERROR:			break;		/*			Should not reach here		*/		default:			CPrintk(0, "c7000: c7000_intr: entered default case for unit 0x%x, state %d\n", cup->devno, cup->state);			break;	}	CPrintk(1, "c7000: c7000_intr: exited with state %d for unit 0x%x\n", cup->state, cup->devno);	return;}/*	Fill in system validation name padding it with blanks.*/static voidc7000_fill_name(char *dst, char *src){	char	*tmp = dst;	int	i;	for (i = 0; i < NAMLEN; i++, tmp++) 		*tmp = ' ';	for (i = 0; i < NAMLEN && *src != '\0'; i++)		*dst++ = *src++;	return;}/*	Initialization routine called when the device is registered.*/static intc7000_init(struct net_device *dev){	struct	c7000_controller	*ccp;	int				i;	int				unitaddr;	int				irq;	/*		Find the position of base_addr in the bases array.	*/	for (i = 0; i < MAX_C7000; i++) 		if (bases[i] == dev->base_addr)			break;	if (i == MAX_C7000)		return(-ENODEV);	/*		Make sure it is a C7000 type of device.	*/	if (c7000_check_devices(dev->base_addr) != 0) {		CPrintk(0, "c7000: c7000_init: b

⌨️ 快捷键说明

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