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

📄 st5481_usb.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
	DBG(1,"");	// Stop and free Control and Interrupt URBs	usb_kill_urb(ctrl->urb);	kfree(ctrl->urb->transfer_buffer);	usb_free_urb(ctrl->urb);	ctrl->urb = NULL;	usb_kill_urb(intr->urb);	kfree(intr->urb->transfer_buffer);	usb_free_urb(intr->urb);	ctrl->urb = NULL;}/* *  Initialize the adapter. */void st5481_start(struct st5481_adapter *adapter){	static const u8 init_cmd_table[]={		SET_DEFAULT,0,		STT,0,		SDA_MIN,0x0d,		SDA_MAX,0x29,		SDELAY_VALUE,0x14,		GPIO_DIR,0x01,				GPIO_OUT,RED_LED,//		FFCTRL_OUT_D,4,//		FFCTRH_OUT_D,12,		FFCTRL_OUT_B1,6,		FFCTRH_OUT_B1,20,		FFCTRL_OUT_B2,6,		FFCTRH_OUT_B2,20,		MPMSK,RXCI_INT+DEN_INT+DCOLL_INT,		0	};		struct st5481_intr *intr = &adapter->intr;	int i = 0;	u8 request,value;	DBG(8,"");	adapter->leds = RED_LED; 	// Start receiving on the interrupt endpoint	SUBMIT_URB(intr->urb, GFP_KERNEL); 	while ((request = init_cmd_table[i++])) {		value = init_cmd_table[i++];		st5481_usb_device_ctrl_msg(adapter, request, value, NULL, NULL);	}	st5481_ph_command(adapter, ST5481_CMD_PUP);}/* * Reset the adapter to default values. */void st5481_stop(struct st5481_adapter *adapter){	DBG(8,"");	st5481_usb_device_ctrl_msg(adapter, SET_DEFAULT, 0, NULL, NULL);}/* ====================================================================== * isochronous USB  helpers */static voidfill_isoc_urb(struct urb *urb, struct usb_device *dev,	      unsigned int pipe, void *buf, int num_packets, 	      int packet_size, usb_complete_t complete,	      void *context) {	int k;	spin_lock_init(&urb->lock);	urb->dev=dev;	urb->pipe=pipe;	urb->interval = 1;	urb->transfer_buffer=buf;	urb->number_of_packets = num_packets;	urb->transfer_buffer_length=num_packets*packet_size;	urb->actual_length = 0;	urb->complete=complete;	urb->context=context;	urb->transfer_flags=URB_ISO_ASAP;	for (k = 0; k < num_packets; k++) {		urb->iso_frame_desc[k].offset = packet_size * k;		urb->iso_frame_desc[k].length = packet_size;		urb->iso_frame_desc[k].actual_length = 0;	}}intst5481_setup_isocpipes(struct urb* urb[2], struct usb_device *dev, 			   unsigned int pipe, int num_packets,			   int packet_size, int buf_size,			   usb_complete_t complete, void *context){	int j, retval;	unsigned char *buf;	for (j = 0; j < 2; j++) {		retval = -ENOMEM;		urb[j] = usb_alloc_urb(num_packets, GFP_KERNEL);		if (!urb[j])			goto err;		// Allocate memory for 2000bytes/sec (16Kb/s)		buf = kmalloc(buf_size, GFP_KERNEL);		if (!buf)			goto err;					// Fill the isochronous URB		fill_isoc_urb(urb[j], dev, pipe, buf, 			      num_packets, packet_size, complete,			      context);	}	return 0; err:	for (j = 0; j < 2; j++) {		if (urb[j]) {			kfree(urb[j]->transfer_buffer);			urb[j]->transfer_buffer = NULL;			usb_free_urb(urb[j]);			urb[j] = NULL;		}	}	return retval;}void st5481_release_isocpipes(struct urb* urb[2]){	int j;	for (j = 0; j < 2; j++) {		usb_kill_urb(urb[j]);		kfree(urb[j]->transfer_buffer);		usb_free_urb(urb[j]);		urb[j] = NULL;	}}/* * Decode frames received on the B/D channel. * Note that this function will be called continously * with 64Kbit/s / 16Kbit/s of data and hence it will be  * called 50 times per second with 20 ISOC descriptors.  * Called at interrupt. */static void usb_in_complete(struct urb *urb, struct pt_regs *regs){	struct st5481_in *in = urb->context;	unsigned char *ptr;	struct sk_buff *skb;	int len, count, status;	if (unlikely(urb->status < 0)) {		switch (urb->status) {			case -ENOENT:			case -ESHUTDOWN:			case -ECONNRESET:				DBG(1,"urb killed status %d", urb->status);				return; // Give up			default: 				WARN("urb status %d",urb->status);				break;		}	}	DBG_ISO_PACKET(0x80,urb);	len = st5481_isoc_flatten(urb);	ptr = urb->transfer_buffer;	while (len > 0) {		if (in->mode == L1_MODE_TRANS) {			memcpy(in->rcvbuf, ptr, len);			status = len;			len = 0;		} else {			status = isdnhdlc_decode(&in->hdlc_state, ptr, len, &count,				in->rcvbuf, in->bufsize);			ptr += count;			len -= count;		}				if (status > 0) {			// Good frame received			DBG(4,"count=%d",status);			DBG_PACKET(0x400, in->rcvbuf, status);			if (!(skb = dev_alloc_skb(status))) {				WARN("receive out of memory\n");				break;			}			memcpy(skb_put(skb, status), in->rcvbuf, status);			in->hisax_if->l1l2(in->hisax_if, PH_DATA | INDICATION, skb);		} else if (status == -HDLC_CRC_ERROR) {			INFO("CRC error");		} else if (status == -HDLC_FRAMING_ERROR) {			INFO("framing error");		} else if (status == -HDLC_LENGTH_ERROR) {			INFO("length error");		}	}	// Prepare URB for next transfer	urb->dev = in->adapter->usb_dev;	urb->actual_length = 0;	SUBMIT_URB(urb, GFP_ATOMIC);}int st5481_setup_in(struct st5481_in *in){	struct usb_device *dev = in->adapter->usb_dev;	int retval;	DBG(4,"");	in->rcvbuf = kmalloc(in->bufsize, GFP_KERNEL);	retval = -ENOMEM;	if (!in->rcvbuf)		goto err;	retval = st5481_setup_isocpipes(in->urb, dev, 					usb_rcvisocpipe(dev, in->ep),					in->num_packets,  in->packet_size,					in->num_packets * in->packet_size,					usb_in_complete, in);	if (retval)		goto err_free;	return 0; err_free:	kfree(in->rcvbuf); err:	return retval;}void st5481_release_in(struct st5481_in *in){	DBG(2,"");	st5481_release_isocpipes(in->urb);}/* * Make the transfer_buffer contiguous by * copying from the iso descriptors if necessary.  */static int st5481_isoc_flatten(struct urb *urb){	struct usb_iso_packet_descriptor *pipd,*pend;	unsigned char *src,*dst;	unsigned int len;		if (urb->status < 0) {		return urb->status;	}	for (pipd = &urb->iso_frame_desc[0],		     pend = &urb->iso_frame_desc[urb->number_of_packets],		     dst = urb->transfer_buffer; 	     pipd < pend; 	     pipd++) {				if (pipd->status < 0) {			return (pipd->status);		}			len = pipd->actual_length;		pipd->actual_length = 0;		src = urb->transfer_buffer+pipd->offset;		if (src != dst) {			// Need to copy since isoc buffers not full			while (len--) {				*dst++ = *src++;			}					} else {			// No need to copy, just update destination buffer			dst += len;		}	}	// Return size of flattened buffer	return (dst - (unsigned char *)urb->transfer_buffer);}static void st5481_start_rcv(void *context){	struct st5481_in *in = context;	struct st5481_adapter *adapter = in->adapter;	DBG(4,"");	in->urb[0]->dev = adapter->usb_dev;	SUBMIT_URB(in->urb[0], GFP_KERNEL);	in->urb[1]->dev = adapter->usb_dev;	SUBMIT_URB(in->urb[1], GFP_KERNEL);}void st5481_in_mode(struct st5481_in *in, int mode){	if (in->mode == mode)		return;	in->mode = mode;	usb_unlink_urb(in->urb[0]);	usb_unlink_urb(in->urb[1]);	if (in->mode != L1_MODE_NULL) {		if (in->mode != L1_MODE_TRANS)			isdnhdlc_rcv_init(&in->hdlc_state,				in->mode == L1_MODE_HDLC_56K);				st5481_usb_pipe_reset(in->adapter, in->ep, NULL, NULL);		st5481_usb_device_ctrl_msg(in->adapter, in->counter,					   in->packet_size,					   NULL, NULL);		st5481_start_rcv(in);	} else {		st5481_usb_device_ctrl_msg(in->adapter, in->counter,					   0, NULL, NULL);	}}

⌨️ 快捷键说明

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