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

📄 keyspan.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 3 页
字号:
			 port, p_priv->inack_buffer, 1, cback->inack_callback);		/* outcont endpoint */		p_priv->outcont_urb = keyspan_setup_urb			(serial, d_details->outcont_endpoints[i], USB_DIR_OUT,			 port, p_priv->outcont_buffer, 64,			 cback->outcont_callback);	}	}/* usa19 function doesn't require prescaler */static int keyspan_usa19_calc_baud(u32 baud_rate, u32 baudclk,				   u8 *rate_hi, u8 *rate_low, u8 *prescaler){	u32 	b16,	/* baud rate times 16 (actual rate used internally) */		div,	/* divisor */			cnt;	/* inverse of divisor (programmed into 8051) */				/* prevent divide by zero...  */	if( (b16 = (baud_rate * 16L)) == 0) {		return (KEYSPAN_INVALID_BAUD_RATE);	}		/* Any "standard" rate over 57k6 is marginal on the USA-19		   as we run out of divisor resolution. */	if (baud_rate > 57600) {		return (KEYSPAN_INVALID_BAUD_RATE);	}		/* calculate the divisor and the counter (its inverse) */	if( (div = (baudclk / b16)) == 0) {		return (KEYSPAN_INVALID_BAUD_RATE);	}	else {		cnt = 0 - div;	}	if(div > 0xffff) {		return (KEYSPAN_INVALID_BAUD_RATE);	}		/* return the counter values if non-null */	if (rate_low) {		*rate_low = (u8) (cnt & 0xff);	}	if (rate_hi) {		*rate_hi = (u8) ((cnt >> 8) & 0xff);	}	if (rate_low && rate_hi) {		dbg (__FUNCTION__ " %d %02x %02x.", baud_rate, *rate_hi, *rate_low);	}		return (KEYSPAN_BAUD_RATE_OK);}static int keyspan_usa19w_calc_baud(u32 baud_rate, u32 baudclk,				    u8 *rate_hi, u8 *rate_low, u8 *prescaler){	u32 	b16,	/* baud rate times 16 (actual rate used internally) */		clk,	/* clock with 13/8 prescaler */		div,	/* divisor using 13/8 prescaler */			res,	/* resulting baud rate using 13/8 prescaler */		diff,	/* error using 13/8 prescaler */		smallest_diff;	u8	best_prescaler;	int	i;	/*  dbg (__FUNCTION__ " %d.", baud_rate); */		/* prevent divide by zero */	if( (b16 = baud_rate * 16L) == 0) {		return (KEYSPAN_INVALID_BAUD_RATE);	}		/* Calculate prescaler by trying them all and looking		   for best fit */				/* start with largest possible difference */	smallest_diff = 0xffffffff;		/* 0 is an invalid prescaler, used as a flag */	best_prescaler = 0;	for(i = 8; i <= 0xff; ++i)	{		clk = (baudclk * 8) / (u32) i;				if( (div = clk / b16) == 0) {			continue;		}		res = clk / div;		diff= (res > b16) ? (res-b16) : (b16-res);		if(diff < smallest_diff)		{			best_prescaler = i;			smallest_diff = diff;		}	}	if(best_prescaler == 0) {		return (KEYSPAN_INVALID_BAUD_RATE);	}	clk = (baudclk * 8) / (u32) best_prescaler;	div = clk / b16;		/* return the divisor and prescaler if non-null */	if (rate_low) {		*rate_low = (u8) (div & 0xff);	}	if (rate_hi) {		*rate_hi = (u8) ((div >> 8) & 0xff);	}	if (prescaler) {		*prescaler = best_prescaler;		/*  dbg(__FUNCTION__ " %d %d", *prescaler, div); */	}	return (KEYSPAN_BAUD_RATE_OK);}static int keyspan_usa26_send_setup(struct usb_serial *serial,				    struct usb_serial_port *port){	struct keyspan_usa26_portControlMessage	msg;			struct keyspan_serial_private 		*s_priv;	struct keyspan_port_private 		*p_priv;	const  keyspan_device_details		*d_details;	int 					outcont_urb;	urb_t *this_urb;	int err;	/*  dbg (__FUNCTION__); */	s_priv = (struct keyspan_serial_private *)(serial->private);	p_priv = (struct keyspan_port_private *)(port->private);	d_details = s_priv->device_details;	outcont_urb = d_details->outcont_endpoints[port->number];	this_urb = p_priv->outcont_urb;		/* Make sure we have an urb then send the message */	if (this_urb == NULL) {		dbg(__FUNCTION__ " oops no urb.");		return -1;	}	p_priv->resend_cont = 1;	if (this_urb->status == -EINPROGRESS) {		/*  dbg (__FUNCTION__ " already writing"); */		return(-1);	}	memset(&msg, 0, sizeof (struct keyspan_usa26_portControlMessage));			/* Only set baud rate if it's changed */		if (p_priv->old_baud != p_priv->baud) {		p_priv->old_baud = p_priv->baud;		msg.setClocking = 0xff;		if (d_details->calculate_baud_rate		    (p_priv->baud, d_details->baudclk, &msg.baudHi,		     &msg.baudLo, &msg.prescaler) == KEYSPAN_INVALID_BAUD_RATE ) {			dbg(__FUNCTION__ "Invalid baud rate %d requested, using 9600.",			    p_priv->baud);			msg.baudLo = 0;			msg.baudHi = 125;	/* Values for 9600 baud */			msg.prescaler = 10;		}		msg.setPrescaler = 0xff;	}	msg.lcr = USA_DATABITS_8 | STOPBITS_5678_1;	if (p_priv->cflag & PARENB) {		/* note USA_PARITY_NONE == 0 */		msg.lcr |= (p_priv->cflag & PARODD)?			USA_PARITY_ODD: USA_PARITY_EVEN;	}	msg.setLcr = 0xff;	msg.ctsFlowControl = (p_priv->flow_control == flow_cts);	msg.xonFlowControl = 0;	msg.setFlowControl = 0xff;		msg.forwardingLength = 1;	msg.xonChar = 17;	msg.xoffChar = 19;		msg._txOn = 1;	msg._txOff = 0;	msg.txFlush = 0;	msg.txBreak = 0;	msg.rxOn = 1;	msg.rxOff = 0;	msg.rxFlush = 0;	msg.rxForward = 0;	/*msg.returnStatus = 1;	msg.resetDataToggle = 0xff;*/		/* Do handshaking outputs */		msg.setTxTriState_setRts = 0xff;	msg.txTriState_rts = p_priv->rts_state;	msg.setHskoa_setDtr = 0xff;	msg.hskoa_dtr = p_priv->dtr_state;			p_priv->resend_cont = 0;	memcpy (this_urb->transfer_buffer, &msg, sizeof(msg));		/* send the data out the device on control endpoint */	this_urb->transfer_buffer_length = sizeof(msg);	this_urb->dev = serial->dev;	if ((err = usb_submit_urb(this_urb)) != 0) {		dbg(__FUNCTION__ " usb_submit_urb(setup) failed (%d)", err);	}#if 0	else {		dbg(__FUNCTION__ " usb_submit_urb(%d) OK %d bytes (end %d)",		    outcont_urb, this_urb->transfer_buffer_length,		    usb_pipeendpoint(this_urb->pipe));	}#endif	return (0);}static int keyspan_usa28_send_setup(struct usb_serial *serial,				    struct usb_serial_port *port){	struct keyspan_usa28_portControlMessage	msg;			struct keyspan_serial_private	 	*s_priv;	struct keyspan_port_private 		*p_priv;	const  keyspan_device_details		*d_details;	urb_t *this_urb;	int err;	s_priv = (struct keyspan_serial_private *)(serial->private);	p_priv = (struct keyspan_port_private *)(port->private);	d_details = s_priv->device_details;	/* only do something if we have a bulk out endpoint */	if ((this_urb = p_priv->outcont_urb) == NULL) {		dbg(__FUNCTION__ " oops no urb.");		return -1;	}	p_priv->resend_cont = 1;	if (this_urb->status == -EINPROGRESS) {		dbg (__FUNCTION__ " already writing");		return(-1);	}	memset(&msg, 0, sizeof (struct keyspan_usa28_portControlMessage));	msg.setBaudRate = 1;	if (keyspan_usa19_calc_baud(p_priv->baud, d_details->baudclk,		&msg.baudHi, &msg.baudLo, NULL) == KEYSPAN_INVALID_BAUD_RATE ) {		dbg(__FUNCTION__ "Invalid baud rate requested %d.", 9600);		msg.baudLo = 0xff;		msg.baudHi = 0xb2;	/* Values for 9600 baud */	}	/* If parity is enabled, we must calculate it ourselves. */	msg.parity = 0;		/* XXX for now */	msg.ctsFlowControl = (p_priv->flow_control == flow_cts);	msg.xonFlowControl = 0;	/* Do handshaking outputs, DTR is inverted relative to RTS */		msg.rts = p_priv->rts_state;	msg.dtr = p_priv->dtr_state;	msg.forwardingLength = 1;	msg.forwardMs = 10;	msg.breakThreshold = 45;	msg.xonChar = 17;	msg.xoffChar = 19;	msg._txOn = 1;	msg._txOff = 0;	msg.txFlush = 0;	msg.txForceXoff = 0;	msg.txBreak = 0;	msg.rxOn = 1;	msg.rxOff = 0;	msg.rxFlush = 0;	msg.rxForward = 0;	/*msg.returnStatus = 1;	msg.resetDataToggle = 0xff;*/	p_priv->resend_cont = 0;	memcpy (this_urb->transfer_buffer, &msg, sizeof(msg));	/* send the data out the device on control endpoint */	this_urb->transfer_buffer_length = sizeof(msg);	this_urb->dev = serial->dev;	if ((err = usb_submit_urb(this_urb)) != 0) {		dbg(__FUNCTION__ " usb_submit_urb(setup) failed");	}#if 0	else {		dbg(__FUNCTION__ " usb_submit_urb(setup) OK %d bytes",		    this_urb->transfer_buffer_length);	}#endif	return (0);}static int keyspan_usa49_send_setup(struct usb_serial *serial,				    struct usb_serial_port *port){	struct keyspan_usa49_portControlMessage	msg;			struct keyspan_serial_private 		*s_priv;	struct keyspan_port_private 		*p_priv;	const  keyspan_device_details		*d_details;	int 					glocont_urb;	urb_t *this_urb;	int err;	/*  dbg (__FUNCTION__); */	s_priv = (struct keyspan_serial_private *)(serial->private);	p_priv = (struct keyspan_port_private *)(port->private);	d_details = s_priv->device_details;	glocont_urb = d_details->glocont_endpoint;	this_urb = s_priv->glocont_urb;	/*  dbg(__FUNCTION__ " port %d\n", port->number); */		/* Make sure we have an urb then send the message */	if (this_urb == NULL) {		dbg(__FUNCTION__ " oops no urb for port %d.", port->number);		return -1;	}	p_priv->resend_cont = 1;	if (this_urb->status == -EINPROGRESS) {		/*  dbg (__FUNCTION__ " already writing"); */		return(-1);	}	memset(&msg, 0, sizeof (struct keyspan_usa49_portControlMessage));	msg.portNumber = port->number;			/* Only set baud rate if it's changed */		if (p_priv->old_baud != p_priv->baud) {		p_priv->old_baud = p_priv->baud;		msg.setClocking = 0xff;		if (d_details->calculate_baud_rate		    (p_priv->baud, d_details->baudclk, &msg.baudHi,		     &msg.baudLo, &msg.prescaler) == KEYSPAN_INVALID_BAUD_RATE ) {			dbg(__FUNCTION__ "Invalid baud rate %d requested, using 9600.",			    p_priv->baud);			msg.baudLo = 0;			msg.baudHi = 125;	/* Values for 9600 baud */			msg.prescaler = 10;		}		//msg.setPrescaler = 0xff;	}	msg.lcr = USA_DATABITS_8 | STOPBITS_5678_1;	if (p_priv->cflag & PARENB) {		/* note USA_PARITY_NONE == 0 */		msg.lcr |= (p_priv->cflag & PARODD)?			USA_PARITY_ODD: USA_PARITY_EVEN;	}	msg.setLcr = 0xff;	msg.ctsFlowControl = (p_priv->flow_control == flow_cts);	msg.xonFlowControl = 0;	msg.setFlowControl = 0xff;		msg.forwardingLength = 1;	msg.xonChar = 17;	msg.xoffChar = 19;		msg._txOn = 1;	msg._txOff = 0;	msg.txFlush = 0;	msg.txBreak = 0;	msg.rxOn = 1;	msg.rxOff = 0;	msg.rxFlush = 0;	msg.rxForward = 0;	msg.enablePort = 0xff;	msg.disablePort = 0;		/* Do handshaking outputs */		msg.setRts = 0xff;	msg.rts = p_priv->rts_state;	msg.setDtr = 0xff;	msg.dtr = p_priv->dtr_state;			p_priv->resend_cont = 0;	memcpy (this_urb->transfer_buffer, &msg, sizeof(msg));		/* send the data out the device on control endpoint */	this_urb->transfer_buffer_length = sizeof(msg);	this_urb->dev = serial->dev;	if ((err = usb_submit_urb(this_urb)) != 0) {		dbg(__FUNCTION__ " usb_submit_urb(setup) failed (%d)", err);	}#if 0	else {		dbg(__FUNCTION__ " usb_submit_urb(%d) OK %d bytes (end %d)",		    outcont_urb, this_urb->transfer_buffer_length,		    usb_pipeendpoint(this_urb->pipe));	}#endif	return (0);}static void keyspan_send_setup(struct usb_serial_port *port){	struct usb_serial *serial = port->serial;	struct keyspan_serial_private 	*s_priv;	const keyspan_device_details	*d_details;	s_priv = (struct keyspan_serial_private *)(serial->private);	d_details = s_priv->device_details;	switch (d_details->msg_format) {	case msg_usa26:		keyspan_usa26_send_setup(serial, port);		break;	case msg_usa28:		keyspan_usa28_send_setup(serial, port);		break;	case msg_usa49:		keyspan_usa49_send_setup(serial, port);		break;	}}/* Gets called by the "real" driver (ie once firmware is loaded   and renumeration has taken place. */static int keyspan_startup (struct usb_serial *serial){	int				i, err;	struct usb_serial_port		*port;	struct keyspan_serial_private 	*s_priv;	struct keyspan_port_private	*p_priv;	const keyspan_device_details	*d_details;	/*  dbg("keyspan_startup called."); */	for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i)		if (d_details->product_id == serial->dev->descriptor.idProduct)			break;	if (d_details == NULL) {		printk(KERN_ERR __FUNCTION__ ": unknown product id %x\n",		       serial->dev->descriptor.idProduct);		return 1;	}	/* Setup private data for serial driver */	serial->private = kmalloc(sizeof(struct keyspan_serial_private),				  GFP_KERNEL);	if (!serial->private) {		dbg(__FUNCTION__ "kmalloc for keyspan_serial_private failed.");		return (1);	}	memset(serial->private, 0, sizeof(struct keyspan_serial_private));	s_priv = (struct keyspan_serial_private *)(serial->private);	s_priv->device_details = d_details;			/* Now setup per port private data */	for (i = 0; i < serial->num_ports; i++) {		port = &serial->port[i];		port->private = kmalloc(sizeof(struct keyspan_port_private),					GFP_KERNEL);		if (!port->private) {			dbg(__FUNCTION__ "kmalloc for keyspan_port_private (%d) failed!.", i);			return (1);		}		memset(port->private, 0, sizeof(struct keyspan_port_private));		p_priv = (struct keyspan_port_private *)(port->private);		p_priv->device_details = d_details;	}	keyspan_setup_urbs(serial);	s_priv->instat_urb->dev = serial->dev;	if ((err = usb_submit_urb(s_priv->instat_urb)) != 0) {		dbg(__FUNCTION__ " submit instat urb failed %d", err);	}				return (0);}static void keyspan_shutdown (struct usb_serial *serial){	int				i, j;	struct usb_serial_port		*port;	struct keyspan_serial_private 	*s_priv;	struct keyspan_port_private	*p_priv;	/*  dbg("keyspan_shutdown called"); */	s_priv = (struct keyspan_serial_private *)(serial->private);	/* Stop reading/writing urbs */	stop_urb(s_priv->instat_urb);	stop_urb(s_priv->glocont_urb);	for (i = 0; i < serial->num_ports; ++i) {		port = &serial->port[i];		p_priv = (struct keyspan_port_private *)(port->private);		stop_urb(p_priv->inack_urb);		stop_urb(p_priv->outcont_urb);		for (j = 0; j < 2; j++) {			stop_urb(p_priv->in_urbs[j]);			stop_urb(p_priv->out_urbs[j]);		}	}	/* Now free them */	if (s_priv->instat_urb)		usb_free_urb(s_priv->instat_urb);	if (s_priv->glocont_urb)		usb_free_urb(s_priv->glocont_urb);	for (i = 0; i < serial->num_ports; ++i) {		port = &serial->port[i];		p_priv = (struct keyspan_port_private *)(port->private);		if (p_priv->inack_urb)			usb_free_urb(p_priv->inack_urb);		if (p_priv->outcont_urb)			usb_free_urb(p_priv->outcont_urb);		for (j = 0; j < 2; j++) {			if (p_priv->in_urbs[j])				usb_free_urb(p_priv->in_urbs[j]);			if (p_priv->out_urbs[j])				usb_free_urb(p_priv->out_urbs[j]);		}	}	/*  dbg("Freeing serial->private."); */	kfree(serial->private);	/*  dbg("Freeing port->private."); */	/* Now free per port private data */	for (i = 0; i < serial->num_ports; i++) {		port = &serial->port[i];		while (port->open_count > 0) {			--port->open_count;			MOD_DEC_USE_COUNT;		}		kfree(port->private);	}}

⌨️ 快捷键说明

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