/* structure to hold all of our device specific stuff */ struct usb_idmouse {
struct usb_device *udev; /* save off the usb device pointer */ struct usb_interface *interface; /* the interface for this device */
unsignedchar *bulk_in_buffer; /* the buffer to receive data */
size_t bulk_in_size; /* the maximum bulk packet size */
size_t orig_bi_size; /* same as above, but reported by the device */
__u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */
int open; /* if the port is open or not */ int present; /* if the device is not disconnected */ struct mutex lock; /* locks this structure */
};
/* local function prototypes */ static ssize_t idmouse_read(struct file *file, char __user *buffer,
size_t count, loff_t * ppos);
/* reset the device and set a fast blink rate */
result = ftip_command(dev, FTIP_RELEASE, 0, 0); if (result < 0) goto reset;
result = ftip_command(dev, FTIP_BLINK, 1, 0); if (result < 0) goto reset;
/* initialize the sensor - sending this command twice */ /* significantly reduces the rate of failed reads */
result = ftip_command(dev, FTIP_ACQUIRE, 0, 0); if (result < 0) goto reset;
result = ftip_command(dev, FTIP_ACQUIRE, 0, 0); if (result < 0) goto reset;
/* start the readout - sending this command twice */ /* presumably enables the high dynamic range mode */
result = ftip_command(dev, FTIP_RESET, 0, 0); if (result < 0) goto reset;
result = ftip_command(dev, FTIP_RESET, 0, 0); if (result < 0) goto reset;
/* loop over a blocking bulk read to get data from the device */ while (bytes_read < IMGSIZE) {
result = usb_bulk_msg(dev->udev,
usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr),
dev->bulk_in_buffer + bytes_read,
dev->bulk_in_size, &bulk_read, 5000); if (result < 0) { /* Maybe this error was caused by the increased packet size? */ /* Reset to the original value and tell userspace to retry. */ if (dev->bulk_in_size != dev->orig_bi_size) {
dev->bulk_in_size = dev->orig_bi_size;
result = -EAGAIN;
} break;
} if (signal_pending(current)) {
result = -EINTR; break;
}
bytes_read += bulk_read;
}
/* check for valid image */ /* right border should be black (0x00) */ for (bytes_read = sizeof(HEADER)-1 + WIDTH-1; bytes_read < IMGSIZE; bytes_read += WIDTH) if (dev->bulk_in_buffer[bytes_read] != 0x00) return -EAGAIN;
/* lower border should be white (0xFF) */ for (bytes_read = IMGSIZE-WIDTH; bytes_read < IMGSIZE-1; bytes_read++) if (dev->bulk_in_buffer[bytes_read] != 0xFF) return -EAGAIN;
/* reset the device */
reset:
ftip_command(dev, FTIP_RELEASE, 0, 0);
/* should be IMGSIZE == 65040 */
dev_dbg(&dev->interface->dev, "read %d bytes fingerprint data\n",
bytes_read); return result;
}
/* PM operations are nops as this driver does IO only during open() */ staticint idmouse_suspend(struct usb_interface *intf, pm_message_t message)
{ return 0;
}
/* get the interface from minor number and driver information */
interface = usb_find_interface(&idmouse_driver, iminor(inode)); if (!interface) return -ENODEV;
/* get the device information block from the interface */
dev = usb_get_intfdata(interface); if (!dev) return -ENODEV;
/* lock this device */
mutex_lock(&dev->lock);
/* check if already open */ if (dev->open) {
/* already open, so fail */
result = -EBUSY;
} else {
/* create a new image and check for success */
result = usb_autopm_get_interface(interface); if (result) goto error;
result = idmouse_create_image(dev);
usb_autopm_put_interface(interface); if (result) goto error;
/* increment our usage count for the driver */
++dev->open;
/* save our object in the file's private structure */
file->private_data = dev;
}
error:
/* unlock this device */
mutex_unlock(&dev->lock); return result;
}
if (!dev->present) { /* the device was unplugged before the file was released */
mutex_unlock(&dev->lock);
idmouse_delete(dev);
} else {
mutex_unlock(&dev->lock);
} return 0;
}
/* check if we have gotten the data or the hid interface */
iface_desc = interface->cur_altsetting; if (iface_desc->desc.bInterfaceClass != 0x0A) return -ENODEV;
if (iface_desc->desc.bNumEndpoints < 1) return -ENODEV;
/* allocate memory for our device state and initialize it */
dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (dev == NULL) return -ENOMEM;
/* set up the endpoint information - use only the first bulk-in endpoint */
result = usb_find_bulk_in_endpoint(iface_desc, &endpoint); if (result) {
dev_err(&interface->dev, "Unable to find bulk-in endpoint.\n");
idmouse_delete(dev); return result;
}
/* we can register the device now, as it is ready */
usb_set_intfdata(interface, dev);
result = usb_register_dev(interface, &idmouse_class); if (result) { /* something prevented us from registering this device */
dev_err(&interface->dev, "Unable to allocate minor number.\n");
idmouse_delete(dev); return result;
}
/* be noisy */
dev_info(&interface->dev,"%s now attached\n",DRIVER_DESC);
/* if the device is opened, idmouse_release will clean this up */ if (!dev->open) {
mutex_unlock(&dev->lock);
idmouse_delete(dev);
} else { /* unlock */
mutex_unlock(&dev->lock);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.