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

📄 c7000.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
#define c7000_set_busy(dev) netif_stop_queue(dev)	/*	Clear the device structure transmission busy flag.*/#define c7000_clear_busy(dev) netif_wake_queue(dev)/*	Extract the device structure transmission busy flag.*/#define c7000_check_busy(dev) netif_queue_stopped(dev)/*	Set a bit in the device structure transmission busy flag.*/static __inline__ voidc7000_setbit_busy(int nr, struct net_device *dev){	netif_stop_queue(dev);	test_and_set_bit(nr, &((struct c7000_controller *)dev->priv)->tbusy);	return;}/*	Clear a bit in the device structure transmission busy flag.*/static __inline__ voidc7000_clearbit_busy(int nr, struct net_device *dev){	clear_bit(nr, &((struct c7000_controller *)dev->priv)->tbusy);	netif_wake_queue(dev);	return;}/*	Test and set a bit in the device structure transmission busy flag.*/static __inline__ intc7000_ts_busy(int nr, struct net_device *dev){	netif_stop_queue(dev);	return test_and_set_bit(nr, &((struct c7000_controller *)dev->priv)->tbusy);}/*	Set the C7000 controller in the error state.*/static voidc7000_error(struct c7000_controller *ccp){	int			i;	struct	c7000_unit	*cup;	struct net_device	*dev = ccp->dev;	for (i = 0; i < NUNITS; i++) {		cup = &ccp->cunits[i];		cup->state = C7000_ERROR;	}	if (dev != NULL)		/* RBH XXX Should we be doing this? */		dev->state &= ~__LINK_STATE_START;	CPrintk(0, "c7000: c7000_error: base unit 0x%x is down\n", ccp->base_addr);	return;}/*	Based on the SENSE ID information, fill in the	controller name.  Note that this is the SENSE ID	information saved by LINUX/390 at boot time.*/static intc7000_check_type(senseid_t *id){	switch (id->cu_type) {		case C7000_CU_TYPE:			if (id->cu_model == C7000_CU_MODEL) {				controller = "C7000  "; 				return(0);			}			break;                default:			break;	}	return(-1);}/*	Check the device information for the controller.*/static intc7000_check_devices(int devno){	int		i;	s390_dev_info_t	temp;	/*		Get the SENSE ID information for each device.	*/	for (i = devno; i < (devno + NUNITS); i++) {		if (get_dev_info_by_devno(devno, &temp) != 0)			return(-1);				if (c7000_check_type(&temp.sid_data) == -1)			return(-1);	}	CPrintk(1, "c7000: c7000_check_devices: device type is %s\n", controller);	return(0);}/*	Issue a halt I/O to device pointed to by cup.*/static intc7000_haltio(struct c7000_unit *cup){	unsigned long		parm;	__u8			flags = 0x00;	unsigned long		saveflags;	DECLARE_WAITQUEUE(wait, current);	int			rc;	s390irq_spin_lock_irqsave(cup->irq, saveflags);	parm = (unsigned long)cup;	if ((rc = halt_IO(cup->irq, parm, flags)) != 0) {		s390irq_spin_unlock_irqrestore(cup->irq, saveflags);		return(rc);	}	/*		Wait for the halt I/O to finish.	*/	add_wait_queue(&cup->wait, &wait);	current->state = TASK_UNINTERRUPTIBLE;	s390irq_spin_unlock_irqrestore(cup->irq, saveflags);	schedule();	remove_wait_queue(&cup->wait, &wait);	return(0);}/*	Issue a start I/O to device pointed to by cup.*/static intc7000_doio(struct c7000_unit *cup){	unsigned long		parm;	__u8			flags = 0x00;	unsigned long		saveflags;	DECLARE_WAITQUEUE(wait, current);	int			rc;	/*		Do no further I/O while the device is in the ERROR, STOP		or STOPPED state.	*/	if (cup->state == C7000_ERROR || cup->state == C7000_STOP || cup->state == C7000_STOPPED)		return(-1);	s390irq_spin_lock_irqsave(cup->irq, saveflags);	parm = (unsigned long)cup;	if ((rc = do_IO(cup->irq, &cup->ccws[0], parm, 0xff, flags)) != 0) {		s390irq_spin_unlock_irqrestore(cup->irq, saveflags);		return(rc);	}		/*		Wait for the I/O to complete.	*/	add_wait_queue(&cup->wait, &wait);	current->state = TASK_UNINTERRUPTIBLE;	s390irq_spin_unlock_irqrestore(cup->irq, saveflags);	schedule();	remove_wait_queue(&cup->wait, &wait);	/*		Interrupt handling may have marked the device in ERROR.	*/	if (cup->state == C7000_ERROR)		return(-1);	return(0);}/*	Build a channel program to do a sense id channel program.*/static voidc7000_bld_senseid_chpgm(struct c7000_unit *cup){	ccw1_t	*ccwp;	ccwp = &cup->ccws[0];	ccwp->cmd_code = C7000_SID_CCW;	ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC);	ccwp->cda = (__u32)virt_to_phys(&cup->senseid);	ccwp->count = SIDL;	ccwp++;	ccwp->cmd_code = C7000_NOOP_CCW;	ccwp->flags = CCW_FLAG_SLI;	ccwp->cda = (__u32)NULL;	ccwp->count = 1;	return;}/*	Build a channel program to write a control message.*/static voidc7000_bld_wrtctl_chpgm(struct c7000_unit *cup){	ccw1_t	*ccwp;	ccwp = &cup->ccws[0];	ccwp->cmd_code = C7000_WRITE_CCW;	ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC);	ccwp->cda = (__u32)virt_to_phys(&cup->control_blk);	ccwp->count = sizeof(struct c7000_control_blk);	ccwp++;	ccwp->cmd_code = C7000_READFF_CCW;	ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC);	ccwp->cda = (__u32)virt_to_phys(&cup->readff);	ccwp->count = C7000_READFFL;	ccwp++;	ccwp->cmd_code = C7000_TIC_CCW;	ccwp->flags = 0;	ccwp->cda = (__u32)virt_to_phys(ccwp + 1);	ccwp->count = 0;	ccwp++;	ccwp->cmd_code = C7000_NOOP_CCW;	ccwp->flags = CCW_FLAG_SLI;	ccwp->cda = (__u32)NULL;	ccwp->count = 1;	return;}/*	Build a write channel program to write the indicated buffer.*/static voidc7000_bld_wrt_chpgm(struct c7000_unit *cup, struct c7000_buffer *buf){	ccw1_t				*ccwp;	struct	c7000_controller	*ccp = cup->cntlp;	ccwp = &buf->ccws[0];	ccwp->cmd_code = C7000_WRITE_CCW | (ccp->linkid << 3);	ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC);	ccwp->cda = (__u32)virt_to_phys(buf->data);	ccwp->count = buf->len;	ccwp++;	ccwp->cmd_code = C7000_READFF_CCW;	ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC);	ccwp->cda = (__u32)virt_to_phys(buf->data + C7000_DATAL + C7000_READHDRL);	ccwp->count = C7000_READFFL;	ccwp++;	ccwp->cmd_code = C7000_TIC_CCW;	ccwp->flags = 0;	ccwp->cda = (__u32)virt_to_phys(ccwp + 1);	ccwp->count = 0;	ccwp++;	ccwp->cmd_code = C7000_NOOP_CCW;	ccwp->flags = (CCW_FLAG_SLI);	ccwp->cda = (__u32)NULL;	ccwp->count = 1;	return;}/*	Build a channel program to read a control message.*/static voidc7000_bld_readctl_chpgm(struct c7000_unit *cup){	ccw1_t	*ccwp;	ccwp = &cup->ccws[0];	ccwp->cmd_code = C7000_READ_CCW;	ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC);	ccwp->cda = (__u32)virt_to_phys(&cup->control_blk);	ccwp->count = sizeof(struct c7000_control_blk);	ccwp++;	ccwp->cmd_code = C7000_READHDR_CCW;	ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC);	ccwp->cda = (__u32)virt_to_phys(&cup->readhdr);	ccwp->count = C7000_READHDRL;	ccwp++;	ccwp->cmd_code = C7000_SIGSMOD_CCW;	ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC);	ccwp->cda = (__u32)virt_to_phys(&cup->sigsmod);	ccwp->count = C7000_SIGSMODL;	ccwp++;	ccwp->cmd_code = C7000_TIC_CCW;	ccwp->flags = 0;	ccwp->cda = (__u32)virt_to_phys(ccwp + 1);	ccwp->count = 0;	ccwp++;	ccwp->cmd_code = C7000_NOOP_CCW;	ccwp->flags = (CCW_FLAG_SLI);	ccwp->cda = (__u32)NULL;	ccwp->count = 1;	return;}/*	Build a channel program to read the indicated buffer.*/static voidc7000_bld_read_chpgm(struct c7000_unit *cup, struct c7000_buffer *buf){	ccw1_t	*ccwp;	ccwp = &buf->ccws[0];	ccwp->cmd_code = C7000_READ_CCW;	ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC);	ccwp->cda = (__u32)virt_to_phys(buf->data);	ccwp->count = C7000_DATAL;	ccwp++;	ccwp->cmd_code = C7000_READHDR_CCW;	ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC);	ccwp->cda = (__u32)virt_to_phys(buf->data + C7000_DATAL);	ccwp->count = C7000_READHDRL;	ccwp++;	ccwp->cmd_code = C7000_SIGSMOD_CCW;	ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC);	ccwp->cda = (__u32)virt_to_phys(&cup->sigsmod);	ccwp->count = C7000_SIGSMODL;	ccwp++;	ccwp->cmd_code = C7000_TIC_CCW;	ccwp->flags = 0;	ccwp->cda = (__u32)virt_to_phys(ccwp + 3);	ccwp->count = 0;	ccwp++;	ccwp->cmd_code = C7000_READFF_CCW;	ccwp->flags = (CCW_FLAG_SLI | CCW_FLAG_CC | CCW_FLAG_PCI);	ccwp->cda = (__u32)virt_to_phys(&cup->readff);	ccwp->count = C7000_READFFL;	ccwp++;	ccwp->cmd_code = C7000_TIC_CCW;	ccwp->flags = 0;	ccwp->cda = (__u32)virt_to_phys(ccwp + 1);	ccwp->count = 0;	ccwp++;	ccwp->cmd_code = C7000_NOOP_CCW;	ccwp->flags = (CCW_FLAG_SLI);	ccwp->cda = (__u32)NULL;	ccwp->count = 1;	return;}/*	Allocate buffer structure headers and buffers for all units	A return value of 0 means that all allocations worked.  A -1	means that an allocation failed.  It is expected that the caller	will call c7000_free_buffers when -1 is returned.*/static intc7000_alloc_buffers(struct net_device *dev){	int				i;	int				j;	char				*data;	struct	c7000_buffer		*bufptr;	struct	c7000_controller	*ccp = (struct c7000_controller *) dev->priv;	struct	c7000_unit		*cup;		for (i = 0; i < NUNITS; i++) {		cup = &ccp->cunits[i];		cup->free = NULL;		for (j = 0; j < C7000_MAXBUF; j++) {			bufptr = kmalloc(sizeof(struct c7000_buffer), GFP_KERNEL);			data = kmalloc(C7000_BUFSIZE, GFP_KERNEL);			if (bufptr == NULL || data == NULL) {				if (bufptr)					kfree(bufptr);				if (data)					kfree(data);				return(-1);			}			/*				Place filled in buffer header on free anchor.			*/			bufptr->next = cup->free;			bufptr->data = data;			bufptr->len = 0;			cup->free = bufptr;			if (data == NULL)				return(-1);			memset(data, '\0', C7000_BUFSIZE);		}	}	CPrintk(1, "c7000: c7000_alloc_buffers: allocated buffers for base unit 0x%lx\n", dev->base_addr);	return(0);}/*	Free buffers on a chain.*/static voidc7000_free_chain(struct c7000_buffer *buf){	char			*data;	struct	c7000_buffer	*bufptr = buf;	struct	c7000_buffer	*tmp;	while (bufptr != NULL) {		data = bufptr->data;		if (data != NULL)			kfree(data);		tmp = bufptr;		bufptr = bufptr->next;		kfree(tmp);	}	return;}/*	Free buffers on all possible chains for all units.*/static voidc7000_free_buffers(struct net_device *dev){	int				i;	struct	c7000_controller	*ccp = (struct c7000_controller *) dev->priv;	struct	c7000_unit	*cup;		for (i = 0; i < NUNITS; i++) {		cup = &ccp->cunits[i];		c7000_free_chain(cup->free);		cup->free = NULL;		c7000_free_chain(cup->proc_head);		cup->proc_head = cup->proc_tail = NULL;		c7000_free_chain(cup->bh_head);		cup->bh_head = cup->bh_tail = NULL;	}	CPrintk(1, "c7000: c7000_free_buffers: freed buffers for base unit 0x%lx\n", dev->base_addr);	return;}/*	Obtain a free buffer.  Return a pointer to the c7000_buffer	structure OR NULL.*/struct c7000_buffer *c7000_get_buffer(struct c7000_unit *cup) {	struct	c7000_buffer	*buf;	buf = cup->free;	if (buf == NULL)		return(NULL);	cup->free = buf->next;	buf->next = NULL;	return(buf);}/*	Release a buffer to the free list.*/voidc7000_release_buffer(struct c7000_unit *cup, struct c7000_buffer *buf){	struct	c7000_buffer	*tmp;	tmp = cup->free;	cup->free = buf;	buf->next = tmp;	return;}/*	Queue a buffer on the end of the processing (proc) chain.*/voidc7000_queue_buffer(struct c7000_unit *cup, struct c7000_buffer *buf){	buf->next = NULL;	if (cup->proc_head == NULL) {		cup->proc_head = cup->proc_tail = buf;		return;	}	cup->proc_tail->next = buf;	cup->proc_tail = buf;	return;}/*	Dequeue a buffer from the start of the processing (proc) chain.*/struct c7000_buffer *c7000_dequeue_buffer(struct c7000_unit *cup){	struct	c7000_buffer	*buf = cup->proc_head;	if (buf == NULL)		return(NULL);	cup->proc_head = buf->next;	if (cup->proc_head == NULL)		cup->proc_tail = NULL;	buf->next = NULL;	return(buf);}/*	Queue a buffer on the end of the bh routine chain.*/voidc7000_queue_bh_buffer(struct c7000_unit *cup, struct c7000_buffer *buf){	buf->next = NULL;	if (cup->bh_head == NULL) {		cup->bh_head = cup->bh_tail = buf;		return;	}	cup->bh_tail->next = buf;	cup->bh_tail = buf;	return;}

⌨️ 快捷键说明

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