/* * Returns number of bytes to be dropped, 0 if packet is okay. */ static int vsxxxaa_check_packet (struct vsxxxaa *mouse, int packet_len) { int i; /* First byte must be a header byte */ if (!IS_HDR_BYTE (mouse->buf[0])) { DBG ("vsck: len=%d, 1st=0x%02x\n", packet_len, mouse->buf[0]); return 1; } /* Check all following bytes */ if (packet_len > 1) { for (i = 1; i < packet_len; i++) { if (IS_HDR_BYTE (mouse->buf[i])) { printk (KERN_ERR "Need to drop %d bytes " "of a broken packet.\n", i - 1); DBG (KERN_INFO "check: len=%d, b[%d]=0x%02x\n", packet_len, i, mouse->buf[i]); return i - 1; } } } return 0; }
static void vsxxxaa_parse_buffer(struct vsxxxaa *mouse) { unsigned char *buf = mouse->buf; int stray_bytes; /* * Parse buffer to death... */ do { /* * Out of sync? Throw away what we don't understand. Each * packet starts with a byte whose bit 7 is set. Unhandled * packets (ie. which we don't know about or simply b0rk3d * data...) will get shifted out of the buffer after some * activity on the mouse. */ while (mouse->count > 0 && !IS_HDR_BYTE(buf[0])) { printk(KERN_ERR "%s on %s: Dropping a byte to regain " "sync with mouse data stream...\n", mouse->name, mouse->phys); vsxxxaa_drop_bytes(mouse, 1); } /* * Check for packets we know about. */ if (vsxxxaa_smells_like_packet(mouse, VSXXXAA_PACKET_REL, 3)) { /* Check for broken packet */ stray_bytes = vsxxxaa_check_packet(mouse, 3); if (!stray_bytes) vsxxxaa_handle_REL_packet(mouse); } else if (vsxxxaa_smells_like_packet(mouse, VSXXXAA_PACKET_ABS, 5)) { /* Check for broken packet */ stray_bytes = vsxxxaa_check_packet(mouse, 5); if (!stray_bytes) vsxxxaa_handle_ABS_packet(mouse); } else if (vsxxxaa_smells_like_packet(mouse, VSXXXAA_PACKET_POR, 4)) { /* Check for broken packet */ stray_bytes = vsxxxaa_check_packet(mouse, 4); if (!stray_bytes) vsxxxaa_handle_POR_packet(mouse); } else { break; /* No REL, ABS or POR packet found */ } if (stray_bytes > 0) { printk(KERN_ERR "Dropping %d bytes now...\n", stray_bytes); vsxxxaa_drop_bytes(mouse, stray_bytes); } } while (1); }