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

📄 garmin_gps.c

📁 LINUX 2.6.17.4的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
{	struct usb_serial *serial = port->serial;	struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);	struct urb *urb;	unsigned char *buffer;	int status;	dbg("%s - port %d, state %d", __FUNCTION__, port->number,		garmin_data_p->state);	garmin_data_p->flags &= ~FLAGS_DROP_DATA;	buffer = kmalloc (count, GFP_ATOMIC);	if (!buffer) {		dev_err(&port->dev, "out of memory\n");		return -ENOMEM;	}	urb = usb_alloc_urb(0, GFP_ATOMIC);	if (!urb) {		dev_err(&port->dev, "no more free urbs\n");		kfree (buffer);		return -ENOMEM;	}	memcpy (buffer, buf, count);	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, buffer);	usb_fill_bulk_urb (urb, serial->dev,			 	usb_sndbulkpipe (serial->dev,				port->bulk_out_endpointAddress),				buffer, count,				garmin_write_bulk_callback, port);	urb->transfer_flags |= URB_ZERO_PACKET;	if (GARMIN_LAYERID_APPL == getLayerId(buffer)) {		garmin_data_p->flags |= FLAGS_APP_REQ_SEEN;		if (garmin_data_p->mode == MODE_GARMIN_SERIAL)  {			pkt_clear(garmin_data_p);			garmin_data_p->state = STATE_GSP_WAIT_DATA;		}	}	/* send it down the pipe */	status = usb_submit_urb(urb, GFP_ATOMIC);	if (status) {		dev_err(&port->dev,		        "%s - usb_submit_urb(write bulk) "		        "failed with status = %d\n",				__FUNCTION__, status);		count = status;	} else {		if (GARMIN_LAYERID_APPL == getLayerId(buffer)		    && (garmin_data_p->mode == MODE_GARMIN_SERIAL))  {			gsp_send_ack(garmin_data_p, buffer[4]);		}	}	/* we are done with this urb, so let the host driver	 * really free it when it is finished with it */	usb_free_urb (urb);	return count;}static int garmin_write (struct usb_serial_port *port,                         const unsigned char *buf, int count){	int pktid, pktsiz, len;	struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);	__le32 *privpkt = (__le32 *)garmin_data_p->privpkt;	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, buf);	/* check for our private packets */	if (count >= GARMIN_PKTHDR_LENGTH) {		len = PRIVPKTSIZ;		if (count < len)			len = count;		memcpy(garmin_data_p->privpkt, buf, len);		pktsiz = getDataLength(garmin_data_p->privpkt);		pktid  = getPacketId(garmin_data_p->privpkt);		if (count == (GARMIN_PKTHDR_LENGTH+pktsiz)		    && GARMIN_LAYERID_PRIVATE == getLayerId(garmin_data_p->privpkt)) {			dbg("%s - processing private request %d",				__FUNCTION__, pktid);			// drop all unfinished transfers			garmin_clear(garmin_data_p);			switch(pktid) {			case PRIV_PKTID_SET_DEBUG:				if (pktsiz != 4)					return -EINVPKT;				debug = __le32_to_cpu(privpkt[3]);				dbg("%s - debug level set to 0x%X",					__FUNCTION__, debug);				break;			case PRIV_PKTID_SET_MODE:				if (pktsiz != 4)					return -EINVPKT;				garmin_data_p->mode = __le32_to_cpu(privpkt[3]);				dbg("%s - mode set to %d",					__FUNCTION__, garmin_data_p->mode);				break;			case PRIV_PKTID_INFO_REQ:				priv_status_resp(port);				break;			case PRIV_PKTID_RESET_REQ:				garmin_data_p->flags |= FLAGS_APP_REQ_SEEN;				break;			case PRIV_PKTID_SET_DEF_MODE:				if (pktsiz != 4)					return -EINVPKT;				initial_mode = __le32_to_cpu(privpkt[3]);				dbg("%s - initial_mode set to %d",					__FUNCTION__,					garmin_data_p->mode);				break;			}			return count;		}	}	if (garmin_data_p->mode == MODE_GARMIN_SERIAL) {		return gsp_receive(garmin_data_p, buf, count);	} else {	/* MODE_NATIVE */		return nat_receive(garmin_data_p, buf, count);	}}static int garmin_write_room (struct usb_serial_port *port){	/*	 * Report back the bytes currently available in the output buffer.	 */	struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);	return GPS_OUT_BUFSIZ-garmin_data_p->outsize;}static int garmin_chars_in_buffer (struct usb_serial_port *port){	/*	 * Report back the number of bytes currently in our input buffer.         * Will this lock up the driver - the buffer contains an incomplete         * package which will not be written to the device until it         * has been completed ?         */	//struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);	//return garmin_data_p->insize;	return 0;}static void garmin_read_process(struct garmin_data * garmin_data_p,				 unsigned char *data, unsigned data_length){	if (garmin_data_p->flags & FLAGS_DROP_DATA) {		/* abort-transfer cmd is actice */		dbg("%s - pkt dropped", __FUNCTION__);	} else if (garmin_data_p->state != STATE_DISCONNECTED &&	           garmin_data_p->state != STATE_RESET ) {		/* remember any appl.layer packets, so we know		   if a reset is required or not when closing		   the device */		if (0 == memcmp(data, GARMIN_APP_LAYER_REPLY,		                sizeof(GARMIN_APP_LAYER_REPLY)))			garmin_data_p->flags |= FLAGS_APP_RESP_SEEN;		/* if throttling is active or postprecessing is required		   put the received data in th input queue, otherwise		   send it directly to the tty port */		if (garmin_data_p->flags & FLAGS_QUEUING) {			pkt_add(garmin_data_p, data, data_length);		} else if (garmin_data_p->mode == MODE_GARMIN_SERIAL) {			if (getLayerId(data) == GARMIN_LAYERID_APPL) {				pkt_add(garmin_data_p, data, data_length);			}		} else {			send_to_tty(garmin_data_p->port, data, data_length);		}	}}static void garmin_read_bulk_callback (struct urb *urb, struct pt_regs *regs){	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;	struct usb_serial *serial =  port->serial;	struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);	unsigned char *data = urb->transfer_buffer;	int status;	dbg("%s - port %d", __FUNCTION__, port->number);	if (!serial) {		dbg("%s - bad serial pointer, exiting", __FUNCTION__);		return;	}	if (urb->status) {		dbg("%s - nonzero read bulk status received: %d",			__FUNCTION__, urb->status);		return;	}	usb_serial_debug_data(debug, &port->dev, 				__FUNCTION__, urb->actual_length, data);	garmin_read_process(garmin_data_p, data, urb->actual_length);	/* Continue trying to read until nothing more is received  */	if (urb->actual_length > 0) {		usb_fill_bulk_urb (port->read_urb, serial->dev,			   usb_rcvbulkpipe (serial->dev,					    port->bulk_in_endpointAddress),			   port->read_urb->transfer_buffer,			   port->read_urb->transfer_buffer_length,			   garmin_read_bulk_callback, port);		status = usb_submit_urb(port->read_urb, GFP_ATOMIC);		if (status)			dev_err(&port->dev,				"%s - failed resubmitting read urb, error %d\n",			        __FUNCTION__, status);	}	return;}static void garmin_read_int_callback (struct urb *urb, struct pt_regs *regs){	int status;	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;	struct usb_serial *serial = port->serial;	struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);	unsigned char *data = urb->transfer_buffer;	switch (urb->status) {	case 0:		/* success */		break;	case -ECONNRESET:	case -ENOENT:	case -ESHUTDOWN:		/* this urb is terminated, clean up */		dbg("%s - urb shutting down with status: %d",			__FUNCTION__, urb->status);		return;	default:		dbg("%s - nonzero urb status received: %d",			__FUNCTION__, urb->status);		return;	}	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, 				urb->actual_length, urb->transfer_buffer);	if (urb->actual_length == sizeof(GARMIN_BULK_IN_AVAIL_REPLY) &&	    0 == memcmp(data, GARMIN_BULK_IN_AVAIL_REPLY,		        sizeof(GARMIN_BULK_IN_AVAIL_REPLY))) {		dbg("%s - bulk data available.", __FUNCTION__);		/* bulk data available */		usb_fill_bulk_urb (port->read_urb, serial->dev,				usb_rcvbulkpipe (serial->dev,				port->bulk_in_endpointAddress),				port->read_urb->transfer_buffer,				port->read_urb->transfer_buffer_length,				garmin_read_bulk_callback, port);		status = usb_submit_urb(port->read_urb, GFP_KERNEL);		if (status) {			dev_err(&port->dev,				"%s - failed submitting read urb, error %d\n",			__FUNCTION__, status);		}	} else if (urb->actual_length == (4+sizeof(GARMIN_START_SESSION_REPLY))			 && 0 == memcmp(data, GARMIN_START_SESSION_REPLY,			                sizeof(GARMIN_START_SESSION_REPLY))) {		garmin_data_p->flags |= FLAGS_SESSION_REPLY1_SEEN;		/* save the serial number */		garmin_data_p->serial_num 			= __le32_to_cpup((__le32*)(data+GARMIN_PKTHDR_LENGTH));		dbg("%s - start-of-session reply seen - serial %u.",			__FUNCTION__, garmin_data_p->serial_num);	}	if (garmin_data_p->ignorePkts) {		/* this reply belongs to a request generated by the driver,		   ignore it. */		dbg("%s - pkt ignored (%d)",			__FUNCTION__, garmin_data_p->ignorePkts);		garmin_data_p->ignorePkts--;	} else {		garmin_read_process(garmin_data_p, data, urb->actual_length);	}	port->interrupt_in_urb->dev = port->serial->dev;	status = usb_submit_urb (urb, GFP_ATOMIC);	if (status)		dev_err(&urb->dev->dev,			"%s - Error %d submitting interrupt urb\n",			__FUNCTION__, status);}/* * Sends the next queued packt to the tty port (garmin native mode only) * and then sets a timer to call itself again until all queued data * is sent. */static int garmin_flush_queue(struct garmin_data * garmin_data_p){	struct garmin_packet *pkt;	if ((garmin_data_p->flags & FLAGS_THROTTLED) == 0) {		pkt = pkt_pop(garmin_data_p);		if (pkt != NULL) {			send_to_tty(garmin_data_p->port, pkt->data, pkt->size);			kfree(pkt);			mod_timer(&garmin_data_p->timer, (1)+jiffies);		} else {			garmin_data_p->flags &= ~FLAGS_QUEUING;		}	}	return 0;}static void garmin_throttle (struct usb_serial_port *port){	struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);	dbg("%s - port %d", __FUNCTION__, port->number);	/* set flag, data received will be put into a queue	   for later processing */	garmin_data_p->flags |= FLAGS_QUEUING|FLAGS_THROTTLED;}static void garmin_unthrottle (struct usb_serial_port *port){	struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);	dbg("%s - port %d", __FUNCTION__, port->number);	garmin_data_p->flags &= ~FLAGS_THROTTLED;	/* in native mode send queued data to tty, in	   serial mode nothing needs to be done here */	if (garmin_data_p->mode == MODE_NATIVE)		garmin_flush_queue(garmin_data_p);}/* * The timer is currently only used to send queued packets to * the tty in cases where the protocol provides no own handshaking * to initiate the transfer. */static void timeout_handler(unsigned long data){	struct garmin_data *garmin_data_p = (struct garmin_data *) data;	/* send the next queued packet to the tty port */	if (garmin_data_p->mode == MODE_NATIVE)		if (garmin_data_p->flags & FLAGS_QUEUING)			garmin_flush_queue(garmin_data_p);}static int garmin_attach (struct usb_serial *serial){	int status = 0;	struct usb_serial_port *port = serial->port[0];	struct garmin_data * garmin_data_p = NULL;	dbg("%s", __FUNCTION__);	garmin_data_p = kzalloc(sizeof(struct garmin_data), GFP_KERNEL);	if (garmin_data_p == NULL) {		dev_err(&port->dev, "%s - Out of memory\n", __FUNCTION__);		return -ENOMEM;	}	init_timer(&garmin_data_p->timer);	spin_lock_init(&garmin_data_p->lock);	INIT_LIST_HEAD(&garmin_data_p->pktlist);	//garmin_data_p->timer.expires = jiffies + session_timeout;	garmin_data_p->timer.data = (unsigned long)garmin_data_p;	garmin_data_p->timer.function = timeout_handler;	garmin_data_p->port = port;	garmin_data_p->state = 0;	garmin_data_p->count = 0;	usb_set_serial_port_data(port, garmin_data_p);	status = garmin_init_session(port);	return status;}static void garmin_shutdown (struct usb_serial *serial){	struct usb_serial_port *port = serial->port[0];	struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);	dbg("%s", __FUNCTION__);	usb_kill_urb (port->interrupt_in_urb);	del_timer_sync(&garmin_data_p->timer);	kfree (garmin_data_p);	usb_set_serial_port_data(port, NULL);}/* All of the device info needed */static struct usb_serial_driver garmin_device = {	.driver = {		.owner =	THIS_MODULE,		.name =		"garmin_gps",	},	.description =		"Garmin GPS usb/tty",	.id_table            = id_table,	.num_interrupt_in    = 1,	.num_bulk_in         = 1,	.num_bulk_out        = 1,	.num_ports           = 1,	.open                = garmin_open,	.close               = garmin_close,	.throttle            = garmin_throttle,	.unthrottle          = garmin_unthrottle,	.attach              = garmin_attach,	.shutdown            = garmin_shutdown,	.write               = garmin_write,	.write_room          = garmin_write_room,	.chars_in_buffer     = garmin_chars_in_buffer,	.write_bulk_callback = garmin_write_bulk_callback,	.read_bulk_callback  = garmin_read_bulk_callback,	.read_int_callback   = garmin_read_int_callback,};static int __init garmin_init (void){	int retval;	retval = usb_serial_register(&garmin_device);	if (retval)		goto failed_garmin_register;	retval = usb_register(&garmin_driver);	if (retval)		goto failed_usb_register;	info(DRIVER_DESC " " DRIVER_VERSION);	return 0;failed_usb_register:	usb_serial_deregister(&garmin_device);failed_garmin_register:	return retval;}static void __exit garmin_exit (void){	usb_deregister (&garmin_driver);	usb_serial_deregister (&garmin_device);}module_init(garmin_init);module_exit(garmin_exit);MODULE_AUTHOR( DRIVER_AUTHOR );MODULE_DESCRIPTION( DRIVER_DESC );MODULE_LICENSE("GPL");module_param(debug, bool, S_IWUSR | S_IRUGO);MODULE_PARM_DESC(debug, "Debug enabled or not");module_param(initial_mode, int, S_IRUGO);MODULE_PARM_DESC(initial_mode, "Initial mode");

⌨️ 快捷键说明

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