struct ias_object *irias_new_object( char *name, int id)
{
    struct ias_object *obj;

    IRDA_DEBUG( 4, "%s()\n", __func__);

    obj = kzalloc(sizeof(struct ias_object), GFP_ATOMIC);
    if (obj == NULL) {
        IRDA_WARNING("%s(), Unable to allocate object!\n",
                     __func__);
        return NULL;
    }

    obj->magic = IAS_OBJECT_MAGIC;
    obj->name = kstrndup(name, IAS_MAX_CLASSNAME, GFP_ATOMIC);
    if (!obj->name) {
        IRDA_WARNING("%s(), Unable to allocate name!\n",
                     __func__);
        kfree(obj);
        return NULL;
    }
    obj->id = id;

    obj->attribs = hashbin_new(HB_LOCK);

    if (obj->attribs == NULL) {
        IRDA_WARNING("%s(), Unable to allocate attribs!\n",
                     __func__);
        kfree(obj->name);
        kfree(obj);
        return NULL;
    }

    return obj;
}
示例#2
0
/*
 * Send a command to change the speed of the dongle
 * Need to be called with spinlock on.
 */
static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self)
{
	__u8 *frame;
	struct urb *urb;
	int ret;

	IRDA_DEBUG(2, "%s(), speed=%d, xbofs=%d\n", __FUNCTION__,
		   self->new_speed, self->new_xbofs);

	/* Grab the speed URB */
	urb = self->speed_urb;
	if (urb->status != 0) {
		IRDA_WARNING("%s(), URB still in use!\n", __FUNCTION__);
		return;
	}

	/* Allocate the fake frame */
	frame = self->speed_buff;

	/* Set the new speed and xbofs in this fake frame */
	irda_usb_build_header(self, frame, 1);

	/* Submit the 0 length IrDA frame to trigger new speed settings */
        usb_fill_bulk_urb(urb, self->usbdev,
		      usb_sndbulkpipe(self->usbdev, self->bulk_out_ep),
                      frame, IRDA_USB_SPEED_MTU,
                      speed_bulk_callback, self);
	urb->transfer_buffer_length = USB_IRDA_HEADER;
	urb->transfer_flags = 0;

	/* Irq disabled -> GFP_ATOMIC */
	if ((ret = usb_submit_urb(urb, GFP_ATOMIC))) {
		IRDA_WARNING("%s(), failed Speed URB\n", __FUNCTION__);
	}
}
示例#3
0
/*
 * Function ias_new_object (name, id)
 *
 *    Create a new IAS object
 *
 */
struct ias_object *irias_new_object( char *name, int id)
{
        struct ias_object *obj;

	IRDA_DEBUG( 4, "%s()\n", __FUNCTION__);

	obj = kmalloc(sizeof(struct ias_object), GFP_ATOMIC);
	if (obj == NULL) {
		IRDA_WARNING("%s(), Unable to allocate object!\n",
			     __FUNCTION__);
		return NULL;
	}
	memset(obj, 0, sizeof( struct ias_object));

	obj->magic = IAS_OBJECT_MAGIC;
	obj->name = strndup(name, IAS_MAX_CLASSNAME);
	obj->id = id;

	/* Locking notes : the attrib spinlock has lower precendence
	 * than the objects spinlock. Never grap the objects spinlock
	 * while holding any attrib spinlock (risk of deadlock). Jean II */
	obj->attribs = hashbin_new(HB_LOCK);

	if (obj->attribs == NULL) {
		IRDA_WARNING("%s(), Unable to allocate attribs!\n",
			     __FUNCTION__);
		kfree(obj);
		return NULL;
	}

	return obj;
}
示例#4
0
文件: qos.c 项目: 274914765/C
/*
 * Function msb_index (word)
 *
 *    Returns index to most significant bit (MSB) in word
 *
 */
static int msb_index (__u16 word)
{
    __u16 msb = 0x8000;
    int index = 15;   /* Current MSB */

    /* Check for buggy peers.
     * Note : there is a small probability that it could be us, but I
     * would expect driver authors to catch that pretty early and be
     * able to check precisely what's going on. If a end user sees this,
     * it's very likely the peer. - Jean II */
    if (word == 0) {
        IRDA_WARNING("%s(), Detected buggy peer, adjust null PV to 0x1!\n",
             __func__);
        /* The only safe choice (we don't know the array size) */
        word = 0x1;
    }

    while (msb) {
        if (word & msb)
            break;   /* Found it! */
        msb >>=1;
        index--;
    }
    return index;
}
示例#5
0
/*
 * Function async_unwrap_ce(dev, byte)
 *
 *    Handle Character Escape character received within a frame
 *
 */
static inline void
async_unwrap_ce(struct net_device *dev,
		 struct net_device_stats *stats,
		 iobuff_t *rx_buff, __u8 byte)
{
	switch(rx_buff->state) {
	case OUTSIDE_FRAME:
		/* Activate carrier sense */











		break;

	case LINK_ESCAPE:
		IRDA_WARNING("%s: state not defined\n", __func__);
		break;

	case BEGIN_FRAME:
	case INSIDE_FRAME:
	default:
		/* Stuffed byte coming */
		rx_buff->state = LINK_ESCAPE;
		break;
	}
}
示例#6
0
/*
 * Function strndup (str, max)
 *
 *    My own kernel version of strndup!
 *
 * Faster, check boundary... Jean II
 */
static char *strndup(char *str, int max)
{
	char *new_str;
	int len;

	/* Check string */
	if (str == NULL)
		return NULL;
	/* Check length, truncate */
	len = strlen(str);
	if(len > max)
		len = max;

	/* Allocate new string */
        new_str = kmalloc(len + 1, GFP_ATOMIC);
        if (new_str == NULL) {
		IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
		return NULL;
	}

	/* Copy and truncate */
	memcpy(new_str, str, len);
	new_str[len] = '\0';

	return new_str;
}
示例#7
0
文件: sir_dev.c 项目: 03199618/linux
int sirdev_receive(struct sir_dev *dev, const unsigned char *cp, size_t count) 
{
	if (!dev || !dev->netdev) {
		IRDA_WARNING("%s(), not ready yet!\n", __func__);
		return -1;
	}

	if (!dev->irlap) {
		IRDA_WARNING("%s - too early: %p / %zd!\n",
			     __func__, cp, count);
		return -1;
	}

	if (cp==NULL) {
		/* error already at lower level receive
		 * just update stats and set media busy
		 */
		irda_device_set_media_busy(dev->netdev, TRUE);
		dev->netdev->stats.rx_dropped++;
		IRDA_DEBUG(0, "%s; rx-drop: %zd\n", __func__, count);
		return 0;
	}

	/* Read the characters into the buffer */
	if (likely(atomic_read(&dev->enable_rx))) {
		while (count--)
			/* Unwrap and destuff one byte */
			async_unwrap_char(dev->netdev, &dev->netdev->stats,
					  &dev->rx_buff, *cp++);
	} else {
		while (count--) {
			/* rx not enabled: save the raw bytes and never
			 * trigger any netif_rx. The received bytes are flushed
			 * later when we re-enable rx but might be read meanwhile
			 * by the dongle driver.
			 */
			dev->rx_buff.data[dev->rx_buff.len++] = *cp++;

			/* What should we do when the buffer is full? */
			if (unlikely(dev->rx_buff.len == dev->rx_buff.truesize))
				dev->rx_buff.len = 0;
		}
	}

	return 0;
}
示例#8
0
文件: iriap.c 项目: CSCLOG/beaglebone
/*
 * Function iriap_init (void)
 *
 *    Initializes the IrIAP layer, called by the module initialization code
 *    in irmod.c
 */
int __init iriap_init(void)
{
	struct ias_object *obj;
	struct iriap_cb *server;
	__u8 oct_seq[6];
	__u16 hints;

	/* Allocate master array */
	iriap = hashbin_new(HB_LOCK);
	if (!iriap)
		return -ENOMEM;

	/* Object repository - defined in irias_object.c */
	irias_objects = hashbin_new(HB_LOCK);
	if (!irias_objects) {
		IRDA_WARNING("%s: Can't allocate irias_objects hashbin!\n",
			     __func__);
		hashbin_delete(iriap, NULL);
		return -ENOMEM;
	}

	lockdep_set_class_and_name(&irias_objects->hb_spinlock, &irias_objects_key,
				   "irias_objects");

	/*
	 *  Register some default services for IrLMP
	 */
	hints  = irlmp_service_to_hint(S_COMPUTER);
	service_handle = irlmp_register_service(hints);

	/* Register the Device object with LM-IAS */
	obj = irias_new_object("Device", IAS_DEVICE_ID);
	irias_add_string_attrib(obj, "DeviceName", "Linux", IAS_KERNEL_ATTR);

	oct_seq[0] = 0x01;  /* Version 1 */
	oct_seq[1] = 0x00;  /* IAS support bits */
	oct_seq[2] = 0x00;  /* LM-MUX support bits */
#ifdef CONFIG_IRDA_ULTRA
	oct_seq[2] |= 0x04; /* Connectionless Data support */
#endif
	irias_add_octseq_attrib(obj, "IrLMPSupport", oct_seq, 3,
				IAS_KERNEL_ATTR);
	irias_insert_object(obj);

	/*
	 *  Register server support with IrLMP so we can accept incoming
	 *  connections
	 */
	server = iriap_open(LSAP_IAS, IAS_SERVER, NULL, NULL);
	if (!server) {
		IRDA_DEBUG(0, "%s(), unable to open server\n", __func__);
		return -1;
	}
	iriap_register_lsap(server, LSAP_IAS, IAS_SERVER);

	return 0;
}
示例#9
0
文件: irda_device.c 项目: 7799/linux
int __init irda_device_init( void)
{
	dongles = hashbin_new(HB_NOLOCK);
	if (dongles == NULL) {
		IRDA_WARNING("IrDA: Can't allocate dongles hashbin!\n");
		return -ENOMEM;
	}
	spin_lock_init(&dongles->hb_spinlock);

	tasks = hashbin_new(HB_LOCK);
	if (tasks == NULL) {
		IRDA_WARNING("IrDA: Can't allocate tasks hashbin!\n");
		hashbin_delete(dongles, NULL);
		return -ENOMEM;
	}

	/* We no longer initialise the driver ourselves here, we let
	 * the system do it for us... - Jean II */

	return 0;
}
示例#10
0
文件: ma600-sir.c 项目: E-LLP/n900
static int ma600_change_speed(struct sir_dev *dev, unsigned speed)
{
	u8	byte;
	
	IRDA_DEBUG(2, "%s(), speed=%d (was %d)\n", __func__,
		speed, dev->speed);

	/* dongle already reset, dongle and port at default speed (9600) */

	/* Set RTS low for 1 ms */
	sirdev_set_dtr_rts(dev, TRUE, FALSE);
	mdelay(1);

	/* Write control byte */
	byte = get_control_byte(speed);
	sirdev_raw_write(dev, &byte, sizeof(byte));

	/* Wait at least 10ms: fake wait_until_sent - 10 bits at 9600 baud*/
	msleep(15);					/* old ma600 uses 15ms */

#if 1
	/* read-back of the control byte. ma600 is the first dongle driver
	 * which uses this so there might be some unidentified issues.
	 * Disable this in case of problems with readback.
	 */

	sirdev_raw_read(dev, &byte, sizeof(byte));
	if (byte != get_control_byte(speed))  {
		IRDA_WARNING("%s(): bad control byte read-back %02x != %02x\n",
			     __func__, (unsigned) byte,
			     (unsigned) get_control_byte(speed));
		return -1;
	}
	else
		IRDA_DEBUG(2, "%s() control byte write read OK\n", __func__);
#endif

	/* Set DTR, Set RTS */
	sirdev_set_dtr_rts(dev, TRUE, TRUE);

	/* Wait at least 10ms */
	msleep(10);

	/* dongle is now switched to the new speed */
	dev->speed = speed;

	return 0;
}
示例#11
0
/*
 * Function iriap_open (void)
 *
 *    Opens an instance of the IrIAP layer, and registers with IrLMP
 */
struct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv,
			    CONFIRM_CALLBACK callback)
{
	struct iriap_cb *self;

	IRDA_DEBUG(2, "%s()\n", __func__);

	self = kzalloc(sizeof(*self), GFP_ATOMIC);
	if (!self) {
		IRDA_WARNING("%s: Unable to kmalloc!\n", __func__);
		return NULL;
	}

	/*
	 *  Initialize instance
	 */

	self->magic = IAS_MAGIC;
	self->mode = mode;
	if (mode == IAS_CLIENT) {
		if (iriap_register_lsap(self, slsap_sel, mode)) {
			kfree(self);
			return NULL;
		}
	}

	self->confirm = callback;
	self->priv = priv;

	/* iriap_getvaluebyclass_request() will construct packets before
	 * we connect, so this must have a sane value... Jean II */
	self->max_header_size = LMP_MAX_HEADER;

	init_timer(&self->watchdog_timer);

	hashbin_insert(iriap, (irda_queue_t *) self, (long) self, NULL);

	/* Initialize state machines */
	iriap_next_client_state(self, S_DISCONNECT);
	iriap_next_call_state(self, S_MAKE_CALL);
	iriap_next_server_state(self, R_DISCONNECT);
	iriap_next_r_connect_state(self, R_WAITING);

	return self;
}
示例#12
0
文件: irda_device.c 项目: 7799/linux
static void leftover_dongle(void *arg)
{
	struct dongle_reg *reg = arg;
	IRDA_WARNING("IrDA: Dongle type %x not unregistered\n",
		     reg->type);
}
示例#13
0
/*
 * Function ircomm_tty_change_speed (driver)
 *
 *    Change speed of the driver. If the remote device is a DCE, then this
 *    should make it change the speed of its serial port
 */
static void ircomm_tty_change_speed(struct ircomm_tty_cb *self)
{
	unsigned cflag, cval;
	int baud;

	IRDA_DEBUG(2, "%s()\n", __func__ );

	if (!self->tty || !self->tty->termios || !self->ircomm)
		return;

	cflag = self->tty->termios->c_cflag;

	/*  byte size and parity */
	switch (cflag & CSIZE) {
	case CS5: cval = IRCOMM_WSIZE_5; break;
	case CS6: cval = IRCOMM_WSIZE_6; break;
	case CS7: cval = IRCOMM_WSIZE_7; break;
	case CS8: cval = IRCOMM_WSIZE_8; break;
	default:  cval = IRCOMM_WSIZE_5; break;
	}
	if (cflag & CSTOPB)
		cval |= IRCOMM_2_STOP_BIT;

	if (cflag & PARENB)
		cval |= IRCOMM_PARITY_ENABLE;
	if (!(cflag & PARODD))
		cval |= IRCOMM_PARITY_EVEN;

	/* Determine divisor based on baud rate */
	baud = tty_get_baud_rate(self->tty);
	if (!baud)
		baud = 9600;	/* B0 transition handled in rs_set_termios */

	self->settings.data_rate = baud;
	ircomm_param_request(self, IRCOMM_DATA_RATE, FALSE);

	/* CTS flow control flag and modem status interrupts */
	if (cflag & CRTSCTS) {
		self->flags |= ASYNC_CTS_FLOW;
		self->settings.flow_control |= IRCOMM_RTS_CTS_IN;
		/* This got me. Bummer. Jean II */
		if (self->service_type == IRCOMM_3_WIRE_RAW)
			IRDA_WARNING("%s(), enabling RTS/CTS on link that doesn't support it (3-wire-raw)\n", __func__);
	} else {
		self->flags &= ~ASYNC_CTS_FLOW;
		self->settings.flow_control &= ~IRCOMM_RTS_CTS_IN;
	}
	if (cflag & CLOCAL)
		self->flags &= ~ASYNC_CHECK_CD;
	else
		self->flags |= ASYNC_CHECK_CD;
#if 0
	/*
	 * Set up parity check flag
	 */

	if (I_INPCK(self->tty))
		driver->read_status_mask |= LSR_FE | LSR_PE;
	if (I_BRKINT(driver->tty) || I_PARMRK(driver->tty))
		driver->read_status_mask |= LSR_BI;

	/*
	 * Characters to ignore
	 */
	driver->ignore_status_mask = 0;
	if (I_IGNPAR(driver->tty))
		driver->ignore_status_mask |= LSR_PE | LSR_FE;

	if (I_IGNBRK(self->tty)) {
		self->ignore_status_mask |= LSR_BI;
		/*
		 * If we're ignore parity and break indicators, ignore
		 * overruns too. (For real raw support).
		 */
		if (I_IGNPAR(self->tty))
			self->ignore_status_mask |= LSR_OE;
	}
#endif
	self->settings.data_format = cval;

	ircomm_param_request(self, IRCOMM_DATA_FORMAT, FALSE);
	ircomm_param_request(self, IRCOMM_FLOW_CONTROL, TRUE);
}
static int __init nsc_ircc_open(chipio_t *info)
{
	struct net_device *dev;
	struct nsc_ircc_cb *self;
	void *ret;
	int err, chip_index;

	IRDA_DEBUG(2, "%s()\n", __func__);


 	for (chip_index = 0; chip_index < ARRAY_SIZE(dev_self); chip_index++) {
		if (!dev_self[chip_index])
			break;
	}

	if (chip_index == ARRAY_SIZE(dev_self)) {
		IRDA_ERROR("%s(), maximum number of supported chips reached!\n", __func__);
		return -ENOMEM;
	}

	IRDA_MESSAGE("%s, Found chip at base=0x%03x\n", driver_name,
		     info->cfg_base);

	if ((nsc_ircc_setup(info)) == -1)
		return -1;

	IRDA_MESSAGE("%s, driver loaded (Dag Brattli)\n", driver_name);

	dev = alloc_irdadev(sizeof(struct nsc_ircc_cb));
	if (dev == NULL) {
		IRDA_ERROR("%s(), can't allocate memory for "
			   "control block!\n", __func__);
		return -ENOMEM;
	}

	self = netdev_priv(dev);
	self->netdev = dev;
	spin_lock_init(&self->lock);
   
	
	dev_self[chip_index] = self;
	self->index = chip_index;

	
	self->io.cfg_base  = info->cfg_base;
	self->io.fir_base  = info->fir_base;
        self->io.irq       = info->irq;
        self->io.fir_ext   = CHIP_IO_EXTENT;
        self->io.dma       = info->dma;
        self->io.fifo_size = 32;
	
	
	ret = request_region(self->io.fir_base, self->io.fir_ext, driver_name);
	if (!ret) {
		IRDA_WARNING("%s(), can't get iobase of 0x%03x\n",
			     __func__, self->io.fir_base);
		err = -ENODEV;
		goto out1;
	}

	
	irda_init_max_qos_capabilies(&self->qos);
	
	
	self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
		IR_115200|IR_576000|IR_1152000 |(IR_4000000 << 8);
	
	self->qos.min_turn_time.bits = qos_mtt_bits;
	irda_qos_bits_to_value(&self->qos);
	
	
	self->rx_buff.truesize = 14384; 
	self->tx_buff.truesize = 14384;

	
	self->rx_buff.head =
		dma_alloc_coherent(NULL, self->rx_buff.truesize,
				   &self->rx_buff_dma, GFP_KERNEL);
	if (self->rx_buff.head == NULL) {
		err = -ENOMEM;
		goto out2;

	}
	memset(self->rx_buff.head, 0, self->rx_buff.truesize);
	
	self->tx_buff.head =
		dma_alloc_coherent(NULL, self->tx_buff.truesize,
				   &self->tx_buff_dma, GFP_KERNEL);
	if (self->tx_buff.head == NULL) {
		err = -ENOMEM;
		goto out3;
	}
	memset(self->tx_buff.head, 0, self->tx_buff.truesize);

	self->rx_buff.in_frame = FALSE;
	self->rx_buff.state = OUTSIDE_FRAME;
	self->tx_buff.data = self->tx_buff.head;
	self->rx_buff.data = self->rx_buff.head;
	
	
	self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0;
	self->tx_fifo.tail = self->tx_buff.head;

	
	dev->netdev_ops = &nsc_ircc_sir_ops;

	err = register_netdev(dev);
	if (err) {
		IRDA_ERROR("%s(), register_netdev() failed!\n", __func__);
		goto out4;
	}
	IRDA_MESSAGE("IrDA: Registered device %s\n", dev->name);

	
	if ((dongle_id <= 0) ||
	    (dongle_id >= ARRAY_SIZE(dongle_types))) {
		dongle_id = nsc_ircc_read_dongle_id(self->io.fir_base);
		
		IRDA_MESSAGE("%s, Found dongle: %s\n", driver_name,
			     dongle_types[dongle_id]);
	} else {
		IRDA_MESSAGE("%s, Using dongle: %s\n", driver_name,
			     dongle_types[dongle_id]);
	}
	
	self->io.dongle_id = dongle_id;
	nsc_ircc_init_dongle_interface(self->io.fir_base, dongle_id);

 	self->pldev = platform_device_register_simple(NSC_IRCC_DRIVER_NAME,
 						      self->index, NULL, 0);
 	if (IS_ERR(self->pldev)) {
 		err = PTR_ERR(self->pldev);
 		goto out5;
 	}
 	platform_set_drvdata(self->pldev, self);

	return chip_index;

 out5:
 	unregister_netdev(dev);
 out4:
	dma_free_coherent(NULL, self->tx_buff.truesize,
			  self->tx_buff.head, self->tx_buff_dma);
 out3:
	dma_free_coherent(NULL, self->rx_buff.truesize,
			  self->rx_buff.head, self->rx_buff_dma);
 out2:
	release_region(self->io.fir_base, self->io.fir_ext);
 out1:
	free_netdev(dev);
	dev_self[chip_index] = NULL;
	return err;
}
示例#15
0
int sirdev_receive(struct sir_dev *dev, const unsigned char *cp, size_t count) 
{


	int i;
	unsigned char c[32];

	unsigned char *eofp, *ebufp;
	int	framelen;




	if (!dev || !dev->netdev) {
		IRDA_WARNING("%s(), not ready yet!\n", __func__);
		return -1;
	}

	if (!dev->irlap) {
		IRDA_WARNING("%s - too early: %p / %zd!\n",
			     __func__, cp, count);
		return -1;
	}

	if (cp==NULL) {
		/* error already at lower level receive
		 * just update stats and set media busy
		 */
		irda_device_set_media_busy(dev->netdev, TRUE);
		dev->netdev->stats.rx_dropped++;
		IRDA_DEBUG(0, "%s; rx-drop: %zd\n", __func__, count);
		return 0;
	}



	IRDA_DEBUG(3, "%s; get rx: %zd\n", __func__, count);



	/* Read the characters into the buffer */
	if (likely(atomic_read(&dev->enable_rx))) {

		
		rx_count_log = count;
		
		
		if (count >0){
			for(i= 0; i<32; i ++){
				if (i<count){
					c[i] = cp[i];
				}
				else {
					c[i] = 0x00;
				}
			}
			IRDA_DEBUG(3, "RcvData= %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", 
					 c[0], c[1], c[2], c[3], c[4], c[5],c[6], c[7], c[8], c[9], c[10], c[11], c[12], c[13],c[14],c[15],
					 c[16], c[17], c[18], c[19], c[20], c[21],c[22], c[23], c[24], c[25], c[26], c[27], c[28], c[29],c[30],c[31]
					 );
		}
		if (count >= 32){
			for(i= 0; i<32; i ++){
				if ( i < count-32){
					c[i] = cp[i+32];
				}
				else {
					c[i] = 0x00;
				}
			}
			IRDA_DEBUG(3, "RcvData= %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", 
					 c[0], c[1], c[2], c[3], c[4], c[5],c[6], c[7], c[8], c[9], c[10], c[11], c[12], c[13],c[14],c[15],
					 c[16], c[17], c[18], c[19], c[20], c[21],c[22], c[23], c[24], c[25], c[26], c[27], c[28], c[29],c[30],c[31]
					 );
		}
		if (count >= 64){
			for(i= 0; i< 32; i ++){
				if ( i < count-64){
					c[i] = cp[i+64];
				}
				else {
					c[i] = 0x00;
				}
			}
			IRDA_DEBUG(3, "RcvData= %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", 
					 c[0], c[1], c[2], c[3], c[4], c[5],c[6], c[7], c[8], c[9], c[10], c[11], c[12], c[13],c[14],c[15],
					 c[16], c[17], c[18], c[19], c[20], c[21],c[22], c[23], c[24], c[25], c[26], c[27], c[28], c[29],c[30],c[31]
					 );
		}
		if (count >=96){
			for(i= 0; i<32; i ++){
				if ( i < count-96){
					c[i] = cp[i+96];
				}
				else {
					c[i] = 0x00;
				}
			}
			IRDA_DEBUG(3, "RcvData= %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", 
					 c[0], c[1], c[2], c[3], c[4], c[5],c[6], c[7], c[8], c[9], c[10], c[11], c[12], c[13],c[14],c[15],
					 c[16], c[17], c[18], c[19], c[20], c[21],c[22], c[23], c[24], c[25], c[26], c[27], c[28], c[29],c[30],c[31]
					 );
		}
		



		ebufp = localechobuf;

		if ( ( count < 20) && localechodata > 0 && dev->rx_buff.state == OUTSIDE_FRAME){
			if ( count > localechodata){
				if (!memcmp(localechobuf, cp + count - localechodata, localechodata)){
					IRDA_DEBUG(4, "%s; data mutch trush %d byte!\n", __func__, count);
					localechodata = 0;
					cp += count;
					count = 0;
				}
			}
			else {
				if (!memcmp(localechobuf + localechodata - count, cp , count)){
					IRDA_DEBUG(4, "%s; data mutch trush %d byte!\n", __func__, count);
					localechodata = 0;
					cp += count;
					count = 0;
				}
			}
		}
		while (count--){
			
			if (localechodata > 0 && dev->rx_buff.state == OUTSIDE_FRAME){
				switch(*cp) {
				case BOF:

					if ( count > 1 && *(cp + 1) == BOF){
						ebufp ++;
						localechodata--;
						cp++;
						continue;
						break;
					}
					else {
						eofp = (unsigned char *)memchr( (void *)cp, (int)EOF, count);
						if ( eofp  == NULL){
							IRDA_DEBUG(4, "%s; not find eof, get start of next frame.\n", __func__);
							localechodata = 0;
							break;
						}
						else {
							framelen = eofp - cp +1 ;
							if ( framelen <= localechodata &&
								   !memcmp((void *)cp, ebufp + localechodata - framelen, framelen)){
								IRDA_DEBUG(4, "%s; find one frame, skip it\n", __func__);
								cp += framelen;
								count -= framelen;
								localechodata = 0;
								break;
							}
							else {
								IRDA_DEBUG(4, "%s; frame line =%d, localechodata = %d.\n", __func__, framelen, localechodata);
								IRDA_DEBUG(4, "%s; find start of next frame.\n", __func__);
								localechodata = 0;
								break;
							}
						}
					}





				case EOF:
					IRDA_DEBUG(4, "%s; find end of trush data!\n", __func__);
					ebufp ++;		
					localechodata = 0;
					cp++;
					continue;
					break;
				default:
					ebufp ++;		
					localechodata--;
					cp++;
					continue;
					break;
				}
			}
			async_unwrap_char(dev->netdev, &dev->netdev->stats,
					  &dev->rx_buff, *cp++);
		}







	} else {
		while (count--) {
			/* rx not enabled: save the raw bytes and never
			 * trigger any netif_rx. The received bytes are flushed
			 * later when we re-enable rx but might be read meanwhile
			 * by the dongle driver.
			 */
			dev->rx_buff.data[dev->rx_buff.len++] = *cp++;

			/* What should we do when the buffer is full? */
			if (unlikely(dev->rx_buff.len == dev->rx_buff.truesize))
				dev->rx_buff.len = 0;
		}
	}

	return 0;
}