From a7b664e3974318d1df4710a3fe73acd1967802ba Mon Sep 17 00:00:00 2001 From: carl Date: Wed, 7 Jun 2023 09:24:24 -0300 Subject: [PATCH] trying to get the driver test --- .../fjpalmvein-main/93-unicon-palmvene.rules | 7 +- modules/fjpalmvein/C/fjpalmvein-main/Makefile | 2 +- modules/fjpalmvein/C/fjpalmvein-main/ctl.sh | 9 +- .../fjpalmvein/C/fjpalmvein-main/fjveincam.c | 586 +++++++++++------- .../fjpalmvein/C/fjpalmvein-main/fjveincam.h | 4 + modules/fjpalmvein/README | 17 + 6 files changed, 394 insertions(+), 231 deletions(-) diff --git a/modules/fjpalmvein/C/fjpalmvein-main/93-unicon-palmvene.rules b/modules/fjpalmvein/C/fjpalmvein-main/93-unicon-palmvene.rules index b83172d9d..da1d0577e 100644 --- a/modules/fjpalmvein/C/fjpalmvein-main/93-unicon-palmvene.rules +++ b/modules/fjpalmvein/C/fjpalmvein-main/93-unicon-palmvene.rules @@ -1,6 +1,9 @@ ACTION!="add",\ + DRIVERS=="fjveincam",\ + MODE="0666", SUBSYSTEM=="usb",\ ATTRS{idVendor}=="04c5",\ ATTRS{idProduct}=="1526",\ - SYMLINK+="usb/fjveincam0",\ - RUN+="/bin/bash -c 'date >> /tmp/fjpv'" + SYMLINK+="usb/fjveincam%n",\ + RUN+="/bin/bash -c 'date >> /tmp/fjpv'",\ + RUN+="/bin/bash -c 'echo $kernel _ $devpath _ $number id=$id MM=$major:$minor $name $sys >> /tmp/fjpv'" diff --git a/modules/fjpalmvein/C/fjpalmvein-main/Makefile b/modules/fjpalmvein/C/fjpalmvein-main/Makefile index d43176bb4..c13c1d3b6 100644 --- a/modules/fjpalmvein/C/fjpalmvein-main/Makefile +++ b/modules/fjpalmvein/C/fjpalmvein-main/Makefile @@ -15,7 +15,7 @@ VERSION := $(shell uname -r) #KERNDIR = /usr/src/linux-headers-5.15.0-58 KERNDIR = /usr/src/linux-headers-$(VERSION) -INSTALLDIR = /lib/modules/$(VERSION)/drivers/usb/misc +INSTALLDIR = /lib/modules/$(VERSION)/kernel/drivers/usb/misc BUILD_DIR := $(shell pwd) VERBOSE = 0 TARGET = fjveincam diff --git a/modules/fjpalmvein/C/fjpalmvein-main/ctl.sh b/modules/fjpalmvein/C/fjpalmvein-main/ctl.sh index d5d242da9..81303d345 100755 --- a/modules/fjpalmvein/C/fjpalmvein-main/ctl.sh +++ b/modules/fjpalmvein/C/fjpalmvein-main/ctl.sh @@ -1,5 +1,8 @@ -sudo rmmod fjveincam.ko +rmmod fjveincam.ko make clean make -sudo cp fjveincam.ko /usr/lib/modules/5.15.0-72-generic/kernel/drivers/usb/misc/ -sudo insmod fjveincam.ko +make install +cp fjveincam.ko /usr/lib/modules/`uname -r`/kernel/drivers/usb/misc/ +cp 93-unicon-palmvene.rules /usr/lib/udev/rules.d/ +insmod fjveincam.ko +depmod diff --git a/modules/fjpalmvein/C/fjpalmvein-main/fjveincam.c b/modules/fjpalmvein/C/fjpalmvein-main/fjveincam.c index 5351576a8..ed31baabd 100644 --- a/modules/fjpalmvein/C/fjpalmvein-main/fjveincam.c +++ b/modules/fjpalmvein/C/fjpalmvein-main/fjveincam.c @@ -1,4 +1,4 @@ -/* +/** * USB PalmSecure Sensor driver (kernel-2.6) * * Copyright (C) 2012 FUJITSU FRONTECH LIMITED @@ -8,36 +8,90 @@ * 2 as published by the Free Software Foundation. * * Notes: + * Heavily based on usb_skeleton.c + * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) * * History: * * 2012-07-06 - V31L01 * - first version * + * Problems? Try... + * lsusb or lsusb -vd MANU:PROD // swap in the device values << FUJITSU PalmSecure-F Pro + * sudo udevadm info -a -n /dev/usb/fjveincam0 // get infor about the device << major=180 minor=0 + * cat /sys/class/usbmisc/fjveincam0/ * // + * ls -al /sys/class/usbmisc/fjveincam0/device/driver/module - coresize, + + */ #include #include -#include +#include //+ #include #include + // kref.h- #include -#include -#include +#include //+ +#include //+ #include + +/* Define these values to match your devices */ +#define VENDOR_ID 0x04C5 +#define PRODUCT_ID 0x1526 + +/* table of devices that work with this driver */ +static struct usb_device_id fjveincam_table [] = { + { USB_DEVICE(VENDOR_ID, PRODUCT_ID) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, fjveincam_table); + + +/* Get a minor range for your devices from the usb maintainer */ +#define USB_subminor_BASE 160 + + +/* Structure to hold all of our device specific stuff */ +struct fjveincam { + struct usb_device *udev; + unsigned char subminor; /* minor number - used in disconnect() */ + char confirmed; /* Not zero if the device is used (Not in phase of confirming) */ + int open_count; /* count the number of openers */ + char *obuf, *ibuf; /* transfer buffers */ + char bulk_in_ep; /* Endpoint assignments */ + char bulk_out_ep; /* Endpoint assignments */ + wait_queue_head_t wait_q; /* wait-queue for checking sensors */ + struct mutex io_mutex; /* lock to prevent concurrent reads or writes */ + int o_timeout; /* counter of open time out */ + int r_error; /* counter of read error */ + int r_lasterr; /* read last error */ + int w_error; /* counter of write error */ + int w_lasterr; /* write last error */ +}; +#define to_skel_dev(d) container_of(d, struct fjveincam, kref) + +static struct usb_driver usb_fjveincam_driver; +//skel static void fjveincam_draw_down(struct usb_fjveincam *dev); + + + +/* our private defines. if this grows any larger, use your own .h file */ #include "fjveincam.h" -#define CONFIG_FJVEINCAM_DEBUG -/* -#undef dbg -#ifdef CONFIG_FJVEINCAM_DEBUG -#define dbg(format, arg...) printk(KERN_DEBUG __FILE__":%d : " format "\n" , __LINE__, ## arg); -#else -#define dbg(format, arg...) -#endif -*/ +#define CONFIG_FJVEINCAM_DEBUGXXX + + +// +// # # ##### ###### ##### ## # #### +// # # # # # # # # # # +// # # # ##### # # # # # #### +// # # # # ##### ###### # # +// # # # # # # # # # # # +// ###### # # ###### # # # # ###### #### +// /* Endpoint direction check macros */ #define IS_EP_BULK(ep) ((ep)->bmAttributes == USB_ENDPOINT_XFER_BULK ? 1 : 0) @@ -52,22 +106,20 @@ /* minor number defines */ -#define USB_FJVEINCAM_MINOR_BASE 160 /* minor base number */ - /* Waiting time for sensor confirming. */ /* Change this value when the time-out happens before the sensor confirming ends. */ -#define SENSOR_CONFIRMED_WAIT_TIME 100 +#define SENSOR_CONFIRMED_WAIT_TIME 1 /* Read timeouts -- R_NAK_TIMEOUT * R_EXPIRE = Number of seconds */ -#define R_NAK_TIMEOUT (5000) /* Default number of X seconds to wait */ +#define R_NAK_TIMEOUT (50) /* Default number of X seconds to wait */ #define R_EXPIRE 1 /* Number of attempts to wait X seconds */ /* Write timeouts */ -#define W_NAK_TIMEOUT (5000) /* Default number of X seconds to wait */ +#define W_NAK_TIMEOUT (50) /* Default number of X seconds to wait */ /* Ioctl timeouts */ -#define C_NAK_TIMEOUT (10000) /* Default number of X seconds to wait */ +#define C_NAK_TIMEOUT (100) /* Default number of X seconds to wait */ /* Allocate buffer byte size */ #define IBUF_SIZE 32768 @@ -78,177 +130,174 @@ #define SENSOR_CONFIRMED 1 /* Sensor is now used */ -/* table of devices that work with this driver - - Carl add 1526 - */ -static struct usb_device_id fjveincam_device_ids [] = { - { USB_DEVICE(0x04C5, 0x1084) }, - { USB_DEVICE(0x04C5, 0x125a) }, - { USB_DEVICE(0x04C5, 0x1526) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, fjveincam_device_ids); static DEFINE_MUTEX(fjveincam_mutex); /* Initializes to unlocked */ -struct fjveincam_usb_data { - struct usb_device *udev; - unsigned char fjveincam_minor; /* minor number - used in disconnect() */ - char confirmed; /* Not zero if the device is used (Not in phase of confirming) */ - int open_count; /* count the number of openers */ - char *obuf, *ibuf; /* transfer buffers */ - char bulk_in_ep; /* Endpoint assignments */ - char bulk_out_ep; /* Endpoint assignments */ - wait_queue_head_t wait_q; /* wait-queue for checking sensors */ - struct mutex io_mutex; /* lock to prevent concurrent reads or writes */ - int o_timeout; /* counter of open time out */ - int r_error; /* counter of read error */ - int r_lasterr; /* read last error */ - int w_error; /* counter of write error */ - int w_lasterr; /* write last error */ -}; - -static struct usb_driver usb_fjveincam_driver; // static void dbg(int line, char * func, char * remark, unsigned long num){ - printk(">>>>>>>>>>>>>>.. USB Driver: %s @ %d (%s): %s = %lu", __FILE__, line, remark, func, num); + pr_notice(">>>>>>>>>>>>>>.. USB Driver: %s @ %d (%s): %s = %lu", __FILE__, line, remark, func, num); } + + + + + + + + + +// ####### ### # ####### +// # # # # +// # # # # +// ##### # # ##### +// # # # # +// # # # # +// # ### ####### ####### +// +// @func static int usb_fjveincam_open(struct inode *inode, struct file *file) { - struct fjveincam_usb_data *fjveincam; - struct usb_interface *intf; - - int fjveincam_minor; - - int errx = 0; + struct fjveincam *dev; + struct usb_interface *interface; + int subminor; + int retval = 0; long wait; - dbg(__LINE__, "usb_fjveincam_open", "init open", 0L); + // does this even run? + dbg(__LINE__, "usb_fjveincam_open", "********* fjveincam open", ENODEV); + pr_notice("**************81 FFFFFFFFFUCK"); + return -ENODEV; + mutex_lock(&fjveincam_mutex); - fjveincam_minor = iminor(inode); + subminor = iminor(inode); - dbg(__LINE__, "usb_fjveincam_open", "open", fjveincam_minor); + dbg(__LINE__, "usb_fjveincam_open", "open", subminor); - intf = usb_find_interface(&usb_fjveincam_driver, fjveincam_minor); - if (!intf) { - dbg(__LINE__, "usb_fjveincam_open", "unable to access minor", fjveincam_minor); - mutex_unlock(&fjveincam_mutex); - return -ENODEV; + interface = usb_find_interface(&usb_fjveincam_driver, subminor); + if (!interface) { + pr_err("%s - error, can't find device for minor %d\n", + __func__, subminor); + retval = -ENODEV; + goto exit; } - fjveincam = usb_get_intfdata(intf); - if ((!fjveincam) || (!fjveincam->udev)) { + dev = usb_get_intfdata(interface); + if ((!dev) || (!dev->udev)) { dbg(__LINE__, "usb_fjveincam_open", "device not present", 0L); - mutex_unlock(&fjveincam_mutex); - return -ENODEV; + retval = -ENODEV; + goto exit; } - mutex_lock(&(fjveincam->io_mutex)); + mutex_lock(&(dev->io_mutex)); - if (fjveincam->open_count) { + if (dev->open_count) { /* Another process has opened. */ - if (fjveincam->confirmed == SENSOR_CONFIRMED) { + if (dev->confirmed == SENSOR_CONFIRMED) { /* The sensor was confirmed. */ dbg(__LINE__, "usb_fjveincam_open", "device already open", 0L); - errx = -EBUSY; - goto out_error; + retval = -EBUSY; + goto exit; } - mutex_unlock(&(fjveincam->io_mutex)); + mutex_unlock(&(dev->io_mutex)); /* Wait until the sensor is confirmed or closed, because another process is open. */ /* Change SENSOR_CONFIRMED_WAIT_TIME value when the time-out happens before the sensor is confirmed. */ - wait = wait_event_interruptible_timeout(fjveincam->wait_q, - (!fjveincam->open_count)||(fjveincam->confirmed==SENSOR_CONFIRMED), + wait = wait_event_interruptible_timeout(dev->wait_q, + (!dev->open_count)||(dev->confirmed==SENSOR_CONFIRMED), SENSOR_CONFIRMED_WAIT_TIME); - mutex_lock(&(fjveincam->io_mutex)); + mutex_lock(&(dev->io_mutex)); if (wait == 0) { /* Time-out happens before the sensor is confirmed. */ dbg(__LINE__, "usb_fjveincam_open", "preconfirmation timeout", 0L); - fjveincam->o_timeout++; - fjveincam->confirmed=SENSOR_CONFIRMED; - errx = -EBUSY; - goto out_error; + dev->o_timeout++; + dev->confirmed=SENSOR_CONFIRMED; + retval = -EBUSY; + goto exit; } - else if (fjveincam->confirmed==SENSOR_CONFIRMED) { + else if (dev->confirmed==SENSOR_CONFIRMED) { /* Another process completed the sensor confirming, and started the use of the sensor. */ dbg(__LINE__, "usb_fjveincam_open", "device already open", 0L); - errx = -EBUSY; - goto out_error; + retval = -EBUSY; + goto exit; } else if(wait == -ERESTARTSYS) { - errx = -ERESTARTSYS; - goto out_error; + retval = -ERESTARTSYS; + goto exit; } /* else { // Another process closed the sensor. } */ } - init_waitqueue_head(&fjveincam->wait_q); - fjveincam->open_count = 1; - file->private_data = fjveincam; /* Used by the read and write methods */ - -out_error: - mutex_unlock(&(fjveincam->io_mutex)); + init_waitqueue_head(&dev->wait_q); + dev->open_count = 1; + file->private_data = dev; /* Used by the read and write methods */ +exit: + mutex_unlock(&(dev->io_mutex)); mutex_unlock(&fjveincam_mutex); - return errx; + return retval; } -static int usb_fjveincam_close(struct inode *inode, struct file *file) +// @func +static int usb_fjveincam_release(struct inode *inode, struct file *file) { - struct fjveincam_usb_data *fjveincam = file->private_data; - - mutex_lock(&(fjveincam->io_mutex)); - - fjveincam->confirmed = SENSOR_NOT_CONFIRMED; - - fjveincam->open_count = 0; + struct fjveincam *dev = file->private_data; + mutex_lock(&(dev->io_mutex)); + dev->confirmed = SENSOR_NOT_CONFIRMED; + dev->open_count = 0; file->private_data = NULL; - if (!fjveincam->udev) { + if (!dev->udev) { /* The device was unplugged while open - need to clean up */ dbg(__LINE__, "funczz", "device was unplugged while open .. tidying up", 0L); - mutex_unlock(&(fjveincam->io_mutex)); - - kfree(fjveincam->ibuf); - kfree(fjveincam->obuf); - kfree(fjveincam); + mutex_unlock(&(dev->io_mutex)); + kfree(dev->ibuf); + kfree(dev->obuf); + kfree(dev); return 0; } - wake_up_interruptible(&fjveincam->wait_q); /* Wake_up the process waiting in open() function. */ - - dbg(__LINE__, "usb_fjveincam_close", "closing...", 0L); - - mutex_unlock(&(fjveincam->io_mutex)); + wake_up_interruptible(&dev->wait_q); /* Wake_up the process waiting in open() function. */ + dbg(__LINE__, "usb_fjveincam_close", "closing...", 0L); + mutex_unlock(&(dev->io_mutex)); return 0; } + +// ### # ####### +// # # # # +// # # # # +// # # # # +// # # # # +// # # # # +// ### # ####### +// +// @func static ssize_t usb_fjveincam_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { - struct fjveincam_usb_data *fjveincam = file->private_data; - struct usb_device *dev; + struct fjveincam *dev = file->private_data; + struct usb_device *udev; ssize_t bytes_read = 0; /* Overall count of bytes_read */ ssize_t ret = 0; - int fjveincam_minor; + int subminor; int partial; /* Number of bytes successfully read */ int this_read; /* Max number of bytes to read */ int result; @@ -259,19 +308,19 @@ static ssize_t usb_fjveincam_read(struct file *file, char *buffer, ktime_get_ts64(&CURRENT_TIME); - mutex_lock(&(fjveincam->io_mutex)); + mutex_lock(&(dev->io_mutex)); - fjveincam_minor = fjveincam->fjveincam_minor; + subminor = dev->subminor; - dev = fjveincam->udev; - if (!dev) { + udev = dev->udev; + if (!udev) { /* The device was unplugged before the file was released */ dbg(__LINE__, "usb_fjveincam_read", "device was unplugged", 0L); ret = -ENODEV; goto out_error; } - ibuf = fjveincam->ibuf; + ibuf = dev->ibuf; file->f_path.dentry->d_inode->i_atime = CURRENT_TIME; while (count > 0) { @@ -283,13 +332,13 @@ static ssize_t usb_fjveincam_read(struct file *file, char *buffer, this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count; - result = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, fjveincam->bulk_in_ep), ibuf, this_read, &partial, R_NAK_TIMEOUT); - //dbg("%s: minor:%d result:%d this_read:%d partial:%d count:%d", "funczz", fjveincam_minor, result, this_read, partial, count); + result = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, dev->bulk_in_ep), ibuf, this_read, &partial, R_NAK_TIMEOUT); + //dbg("%s: minor:%d result:%d this_read:%d partial:%d count:%d", "funczz", subminor, result, this_read, partial, count); dbg(__LINE__, "usb_fjveincam_read", "partial read", 0L); - fjveincam->r_lasterr = result; + dev->r_lasterr = result; if (result == -ETIMEDOUT) { /* NAK */ - fjveincam->r_error++; + dev->r_error++; if (!partial) { /* No data */ if (--r_expire <= 0) { /* Give it up */ dbg(__LINE__, "usb_fjveincam_read", "excessive NAKs", 0L); @@ -305,14 +354,14 @@ static ssize_t usb_fjveincam_read(struct file *file, char *buffer, } if (result == -EPIPE) { /* No hope */ - fjveincam->r_error++; - if(usb_clear_halt(dev, fjveincam->bulk_in_ep)) { + dev->r_error++; + if(usb_clear_halt(udev, dev->bulk_in_ep)) { dbg(__LINE__, "usb_fjveincam_read", "failed to clear endpoint halt condition", 0L); } ret = result; break; } else if ((result < 0) && (result != EREMOTEIO)) { - fjveincam->r_error++; + dev->r_error++; dbg(__LINE__, "usb_fjveincam_read", "an error occurred", 0L); ret = -EIO; break; @@ -339,21 +388,23 @@ out_error: dbg(__LINE__, "usb_fjveincam_read", "bytes were read", 0L); - mutex_unlock(&(fjveincam->io_mutex)); + mutex_unlock(&(dev->io_mutex)); return ret ? ret : bytes_read; } + +// @func static ssize_t usb_fjveincam_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) { - struct fjveincam_usb_data *fjveincam = file->private_data; - struct usb_device *dev; + struct fjveincam *dev = file->private_data; + struct usb_device *udev; ssize_t bytes_written = 0; /* Overall count of bytes written */ ssize_t ret = 0; - int fjveincam_minor; + int subminor; int this_write; /* Number of bytes to write */ int partial; /* Number of bytes successfully written */ int result = 0; @@ -362,18 +413,18 @@ static ssize_t usb_fjveincam_write(struct file *file, const char *buffer, struct timespec64 CURRENT_TIME; ktime_get_ts64(&CURRENT_TIME); - mutex_lock(&(fjveincam->io_mutex)); + mutex_lock(&(dev->io_mutex)); - fjveincam_minor = fjveincam->fjveincam_minor; + subminor = dev->subminor; - dev = fjveincam->udev; - if (!dev) { + udev = dev->udev; + if (!udev) { dbg(__LINE__, "usb_fjveincam_write", "device was unplugged", 0L); ret = -ENODEV; goto out_error; } - obuf = fjveincam->obuf; + obuf = dev->obuf; file->f_path.dentry->d_inode->i_atime = CURRENT_TIME; while (count > 0) { @@ -384,29 +435,29 @@ static ssize_t usb_fjveincam_write(struct file *file, const char *buffer, this_write = (count >= OBUF_SIZE) ? OBUF_SIZE : count; - if (copy_from_user(fjveincam->obuf, buffer, this_write)) { + if (copy_from_user(dev->obuf, buffer, this_write)) { ret = -EFAULT; break; } - result = usb_bulk_msg(dev,usb_sndbulkpipe(dev, fjveincam->bulk_out_ep), obuf, this_write, &partial, W_NAK_TIMEOUT); + result = usb_bulk_msg(udev,usb_sndbulkpipe(udev, dev->bulk_out_ep), obuf, this_write, &partial, W_NAK_TIMEOUT); dbg(__LINE__, "usb_fjveincam_write", "bulk data sent", 0L); - fjveincam->w_lasterr = result; + dev->w_lasterr = result; if (result == -ETIMEDOUT) { /* NAK */ dbg(__LINE__, "usb_fjveincam_write", "excess NAKs", 0L); - fjveincam->w_error++; + dev->w_error++; ret = result; break; } else if (result < 0) { /* We should not get any I/O errors */ dbg(__LINE__, "usb_fjveincam_write", "error detected", 0L); - fjveincam->w_error++; + dev->w_error++; ret = -EIO; break; } if (partial != this_write) { /* Unable to write all contents of obuf */ - fjveincam->w_error++; + dev->w_error++; ret = -EIO; break; } @@ -423,27 +474,42 @@ static ssize_t usb_fjveincam_write(struct file *file, const char *buffer, out_error: - mutex_unlock(&(fjveincam->io_mutex)); + mutex_unlock(&(dev->io_mutex)); return ret ? ret : bytes_written; } + + + + +// ### ####### ##### ####### # +// # # # # # # # +// # # # # # # +// # # # # # # +// # # # # # # +// # # # # # # # +// ### ####### ##### # ####### +// +// @func static long usb_fjveincam_unlocked_ioctl(struct file *file, uint cmd, ulong arg) { - struct fjveincam_usb_data *fjveincam = file->private_data; - struct usb_device *dev; - - int fjveincam_minor; + struct fjveincam *dev = file->private_data; + struct usb_device *udev; + char obuf[256]; + int subminor; int retval = 0; + return -99; + memset(&obuf,0,sizeof(obuf)); printk(">>>>>>>>> IOCTL %d\n", cmd); - mutex_lock(&(fjveincam->io_mutex)); + mutex_lock(&(dev->io_mutex)); - fjveincam_minor = fjveincam->fjveincam_minor; + subminor = dev->subminor; dbg(__LINE__, "usb_fjveincam_ioctl", "ioctl", 0L); - if (!fjveincam->udev) { + if (!dev->udev) { dbg(__LINE__, "usb_fjveincam_ioctl", "device was unplugged", 0L); retval = -ENODEV; goto out_error; @@ -462,8 +528,8 @@ static long usb_fjveincam_unlocked_ioctl(struct file *file, uint cmd, ulong arg) } cmsg; int pipe, nb, ret; unsigned char buf[974]; - - dev = fjveincam->udev; + dbg(__LINE__, "usb_fjveincam_ioctl", "USB_FJVEINCAM_IOCTL_CTRLMSG", 0L); + udev = dev->udev; dbg(__LINE__, "usb_fjveincam_ioctl", "dealing with an ioctl", 0L); @@ -486,16 +552,16 @@ static long usb_fjveincam_unlocked_ioctl(struct file *file, uint cmd, ulong arg) } if ((cmsg.req.bRequestType & 0x80) == 0) { - pipe = usb_sndctrlpipe(dev, 0); + pipe = usb_sndctrlpipe(udev, 0); if (nb > 0 && copy_from_user(buf, cmsg.data, nb)) { retval = -EFAULT; break; } } else { - pipe = usb_rcvctrlpipe(dev, 0); + pipe = usb_rcvctrlpipe(udev, 0); } - ret = usb_control_msg(dev, pipe, + ret = usb_control_msg(udev, pipe, cmsg.req.bRequest, cmsg.req.bRequestType, cmsg.req.wValue, @@ -504,10 +570,12 @@ static long usb_fjveincam_unlocked_ioctl(struct file *file, uint cmd, ulong arg) dbg(__LINE__, "usb_fjveincam_ioctl", "request", 0L); - //dbg("%s: minor:%d request result:%d cmd[%02X:%04X:%04X:%04X] rsp[%02X:%02X:%02X:%02X]", - // "funczz", fjveincam_minor, ret, - // cmsg.req.bRequest, cmsg.req.wValue, cmsg.req.wIndex, cmsg.req.wLength, - // buf[0], buf[1], buf[2], buf[3]); + sprintf(obuf,"%s: minor:%d request result:%d cmd[%02X:%04X:%04X:%04X] rsp[%02X:%02X:%02X:%02X]", + "funczz", subminor, ret, + cmsg.req.bRequest, cmsg.req.wValue, cmsg.req.wIndex, cmsg.req.wLength, + buf[0], buf[1], buf[2], buf[3]); + dbg(__LINE__, "usb_fjveincam_ioctl", obuf, 0L); + if (ret < 0) { dbg(__LINE__, "usb_fjveincam_ioctl", "error detected", 0L); @@ -527,15 +595,16 @@ static long usb_fjveincam_unlocked_ioctl(struct file *file, uint cmd, ulong arg) case USB_FJVEINCAMV30_IOCTL_CHECK: case USB_FJVEINCAM_IOCTL_CHECK: - /* nop */ + dbg(__LINE__, "usb_fjveincam_ioctl", "USB_FJVEINCAM_IOCTL_CHECK", 0L); break; /* Notification of the end of sensor confirming. */ case USB_FJVEINCAMV30_IOCTL_CONFIRM: case USB_FJVEINCAM_IOCTL_CONFIRM: { - fjveincam->confirmed = SENSOR_CONFIRMED; /* Sensor confirming was completed, and started the use of the sensor. */ - wake_up_interruptible(&fjveincam->wait_q); /* Wake_up the process waiting in open() function. */ + dbg(__LINE__, "usb_fjveincam_ioctl", "USB_FJVEINCAM_IOCTL_CONFIRM", 0L); + dev->confirmed = SENSOR_CONFIRMED; /* Sensor confirming was completed, and started the use of the sensor. */ + wake_up_interruptible(&dev->wait_q); /* Wake_up the process waiting in open() function. */ dbg(__LINE__, "usb_fjveincam_ioctl", "sensor was checked", 0L); break; } @@ -544,14 +613,15 @@ static long usb_fjveincam_unlocked_ioctl(struct file *file, uint cmd, ulong arg) case USB_FJVEINCAM_IOCTL_INFO: { struct fjveincam_info info; + dbg(__LINE__, "usb_fjveincam_ioctl", "USB_FJVEINCAM_IOCTL_INFO", 0L); info.magic = FJPV_MAGIC; /* Magic number for indicating Fujitsu Palmsecure sensor driver. */ - info.minor = fjveincam_minor; - info.o_timeout = fjveincam->o_timeout; - info.r_error = fjveincam->r_error; - info.r_lasterr = fjveincam->r_lasterr; - info.w_error = fjveincam->w_error; - info.w_lasterr = fjveincam->w_lasterr; + info.minor = subminor; + info.o_timeout = dev->o_timeout; + info.r_error = dev->r_error; + info.r_lasterr = dev->r_lasterr; + info.w_error = dev->w_error; + info.w_lasterr = dev->w_lasterr; strncpy((char*)info.version, DRIVER_VERSION, sizeof(info.version)); if (copy_to_user((void *)arg, &info, sizeof(info))) retval = -EFAULT; @@ -567,37 +637,51 @@ static long usb_fjveincam_unlocked_ioctl(struct file *file, uint cmd, ulong arg) out_error: - mutex_unlock(&(fjveincam->io_mutex)); + mutex_unlock(&(dev->io_mutex)); dbg(__LINE__, "usb_fjveincam_ioctl", "OK...", 0L); return retval; } -/* Kernel VFS uses this to lookup actual driver functions to call on - open(fd, O_RD) -> open - close(fd) -> close -*/ + + +// @config static struct file_operations usb_fjveincam_fops = { .owner = THIS_MODULE, + .open = usb_fjveincam_open, + .release = usb_fjveincam_release, .read = usb_fjveincam_read, .write = usb_fjveincam_write, .unlocked_ioctl = usb_fjveincam_unlocked_ioctl, - .open = usb_fjveincam_open, - .release = usb_fjveincam_close, }; - + + +// @config static struct usb_class_driver fjveincam_class = { .name = "usb/fjveincam%d", .fops = &usb_fjveincam_fops, - .minor_base = USB_FJVEINCAM_MINOR_BASE, + .minor_base = USB_subminor_BASE, }; + + + +// +// ##### ##### #### ##### ###### +// # # # # # # # # # +// # # # # # # ##### ##### +// ##### ##### # # # # # +// # # # # # # # # +// # # # #### ##### ###### +// +// Runs when the *device* is plugged in +// @func static int usb_fjveincam_probe(struct usb_interface *intf, const struct usb_device_id *id) { - struct usb_device *dev = interface_to_usbdev(intf); - struct fjveincam_usb_data *fjveincam; + struct usb_device *udev = interface_to_usbdev(intf); + struct fjveincam *dev; struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; @@ -607,22 +691,38 @@ static int usb_fjveincam_probe(struct usb_interface *intf, char have_bulk_in, have_bulk_out; char name[20]; char buf[128]; + struct usb_class_driver *class_driver = intf->dev.driver_data; + + pr_info("Associated file name: %s\n", class_driver->name); + + // Dump usb_interface structure + pr_info("Dumping usb_interface structure:\n"); + pr_info(" Interface number: %d\n", intf->cur_altsetting->desc.bInterfaceNumber); + pr_info(" Interface class: 0x%02x\n", intf->cur_altsetting->desc.bInterfaceClass); + // Add more fields as needed + + // Dump usb_device_id structure + pr_info("Dumping usb_device_id structure:\n"); + pr_info(" Matched vendor ID: 0x%04x\n", id->idVendor); + pr_info(" Matched product ID: 0x%04x\n", id->idProduct); + // Add more fields as needed + memset(&buf,0,sizeof(buf)); dbg(__LINE__, "usb_fjveincam_probe", "probed; [device id]", 0L); - sprintf(buf, "vendor id 0x%x, device id 0x%x, portnum:%d", - dev->descriptor.idVendor, dev->descriptor.idProduct, - dev->portnum); + sprintf(buf, "vendor id 0x%x, device id 0x%x, portnum:%d minor_base:%d", + udev->descriptor.idVendor, udev->descriptor.idProduct, + udev->portnum, USB_subminor_BASE); dbg(__LINE__, "usb_fjveincam_probe", buf, 0L); - + /* * After this point we can be a little noisy about what we are trying to * configure. */ - if (dev->descriptor.bNumConfigurations != 1) { + if (udev->descriptor.bNumConfigurations != 1) { dbg(__LINE__, "funczz", "only one device configuration is supported", 0L); return -ENODEV; } @@ -633,7 +733,7 @@ static int usb_fjveincam_probe(struct usb_interface *intf, interface = &intf->altsetting[0]; - dbg(__LINE__, "usb_fjveincam_probe", "endpoints", 0L); + dbg(__LINE__, "usb_fjveincam_probe", "endpoints", 0L); if (interface->desc.bNumEndpoints != 2) { dbg(__LINE__, "usb_fjveincam_probe", "**ERROR** endpoint count", 0L); @@ -677,47 +777,47 @@ static int usb_fjveincam_probe(struct usb_interface *intf, * Determine a minor number and initialize the structure associated * with it. */ - if (!(fjveincam = kzalloc (sizeof (struct fjveincam_usb_data), GFP_KERNEL))) { + if (!(dev = kzalloc (sizeof (struct fjveincam), GFP_KERNEL))) { dbg(__LINE__, "usb_fjveincam_probe", "**ERROR** insufficient memory", 0L); return -ENOMEM; } - mutex_init(&(fjveincam->io_mutex)); /* Initializes to unlocked */ + mutex_init(&(dev->io_mutex)); /* Initializes to unlocked */ /* Ok, now initialize all the relevant values */ - if (!(fjveincam->obuf = (char *)kmalloc(OBUF_SIZE, GFP_KERNEL))) { + if (!(dev->obuf = (char *)kmalloc(OBUF_SIZE, GFP_KERNEL))) { dbg(__LINE__, "usb_fjveincam_probe", "**ERROR** insufficient output memory", 0L); - kfree(fjveincam); + kfree(dev); return -ENOMEM; } - if (!(fjveincam->ibuf = (char *)kmalloc(IBUF_SIZE, GFP_KERNEL))) { + if (!(dev->ibuf = (char *)kmalloc(IBUF_SIZE, GFP_KERNEL))) { dbg(__LINE__, "usb_fjveincam_probe", "**ERROR** insufficient input memory", 0L); - kfree(fjveincam->obuf); - kfree(fjveincam); + kfree(dev->obuf); + kfree(dev); return -ENOMEM; } - usb_get_dev(dev); - fjveincam->bulk_in_ep = have_bulk_in; - fjveincam->bulk_out_ep = have_bulk_out; - fjveincam->udev = dev; - fjveincam->open_count = 0; - fjveincam->confirmed = SENSOR_NOT_CONFIRMED; + usb_get_dev(udev); + dev->bulk_in_ep = have_bulk_in; + dev->bulk_out_ep = have_bulk_out; + dev->udev = udev; + dev->open_count = 0; + dev->confirmed = SENSOR_NOT_CONFIRMED; - usb_set_intfdata(intf, fjveincam); + usb_set_intfdata(intf, dev); retval = usb_register_dev(intf, &fjveincam_class); if (retval) { dbg(__LINE__, "usb_fjveincam_probe", "**ERROR** unable to get a minor number", 0L); usb_set_intfdata(intf, NULL); - kfree(fjveincam->ibuf); - kfree(fjveincam->obuf); - kfree(fjveincam); + kfree(dev->ibuf); + kfree(dev->obuf); + kfree(dev); return -ENOMEM; } dbg(__LINE__, "usb_fjveincam_probe", "have a minor", intf->minor); - fjveincam->fjveincam_minor = intf->minor; + dev->subminor = intf->minor; snprintf(name, sizeof(name), fjveincam_class.name, intf->minor - fjveincam_class.minor_base); @@ -728,10 +828,24 @@ static int usb_fjveincam_probe(struct usb_interface *intf, return 0; } + + + + +// ##### ####### # # # # +// # # # # ## # ## # +// # # # # # # # # # +// # # # # # # # # # +// # # # # # # # # # +// # # # # # ## # ## +// ##### ####### # # # # +// +// Runs when the *device* is disconnected, or the module is unloaded +// @func static void usb_fjveincam_disconnect(struct usb_interface *interface) { - struct fjveincam_usb_data *fjveincam = usb_get_intfdata(interface); - int fjveincam_minor = interface->minor; + struct fjveincam *dev = usb_get_intfdata(interface); + int subminor = interface->minor; usb_set_intfdata(interface, NULL); @@ -739,44 +853,50 @@ static void usb_fjveincam_disconnect(struct usb_interface *interface) usb_deregister_dev (interface, &fjveincam_class); mutex_lock(&fjveincam_mutex); /* If there is a process in open(), wait for return. */ - mutex_lock(&(fjveincam->io_mutex)); + mutex_lock(&(dev->io_mutex)); - dev_info(&interface->dev, "USB PalmVeinCam #%d now disconnected\n", (fjveincam_minor - fjveincam_class.minor_base)); + dev_info(&interface->dev, "USB PalmVeinCam #%d now disconnected\n", (subminor - fjveincam_class.minor_base)); usb_driver_release_interface(&usb_fjveincam_driver, - fjveincam->udev->actconfig->interface[0]); + dev->udev->actconfig->interface[0]); - if (fjveincam->open_count) { + if (dev->open_count) { /* The device is still open - cleanup must be delayed */ dbg(__LINE__, "usb_fjveincam_disconnect", "device was unplugged while open", 0L); - fjveincam->udev = 0; - mutex_unlock(&(fjveincam->io_mutex)); + dev->udev = 0; + mutex_unlock(&(dev->io_mutex)); mutex_unlock(&fjveincam_mutex); return; } dbg(__LINE__, "usb_fjveincam_disconnect", "deallocating...", 0L); - mutex_unlock(&(fjveincam->io_mutex)); + mutex_unlock(&(dev->io_mutex)); mutex_unlock(&fjveincam_mutex); - kfree(fjveincam->ibuf); - kfree(fjveincam->obuf); - kfree(fjveincam); + kfree(dev->ibuf); + kfree(dev->obuf); + kfree(dev); } -static struct usb_driver usb_fjveincam_driver = { - .name = "fjveincam", - .probe = usb_fjveincam_probe, - .disconnect = usb_fjveincam_disconnect, - .id_table = fjveincam_device_ids, - .no_dynamic_id = 1 -}; + + + +// ###### ####### ##### ### ##### ####### ### ###### # # +// # # # # # # # # # ### # # ## # +// # # # # # # # # # # # # # +// ###### ##### # #### # ##### # # ###### # # # +// # # # # # # # # # # # # # +// # # # # # # # # # # # # ## +// # # ####### ##### ### ##### # # # # # +// +// Runs when the *module* is loaded +// @func static int __init usb_fjveincam_init(void){ int result; - /* register this driver with the USB subsystem - fires on driver module insmod */ + // register this driver with the USB subsystem - fires on driver module insmod dbg(__LINE__, "usb_fjveincam_init", "USB registration with ioctl %lu", USB_FJVEINCAM_IOCTL_INFO); result = usb_register(&usb_fjveincam_driver); if (result){ @@ -785,18 +905,34 @@ static int __init usb_fjveincam_init(void){ dbg(__LINE__, "usb_fjveincam_init", "registration complete", result); return result; } - +// This runs when the *module* is unloaded +// @func static void __exit usb_fjveincam_exit(void) { - /* deregister this driver with the USB subsystem - fires on driver module rmmod */ - dbg(__LINE__, "usb_fjveincam_init", "USB de-registration with ioctl %lu", USB_FJVEINCAM_IOCTL_INFO); + // deregister this driver with the USB subsystem - fires on driver module rmmod + dbg(__LINE__, "usb_fjveincam_exit", "USB de-registration with ioctl %lu", USB_FJVEINCAM_IOCTL_INFO); usb_deregister(&usb_fjveincam_driver); dbg(__LINE__, "usb_fjveincam_exit", "removing the driver", 0L); } - module_init(usb_fjveincam_init); module_exit(usb_fjveincam_exit); + + + + +// @config +static struct usb_driver usb_fjveincam_driver = { + .name = "fjveincam", + .probe = usb_fjveincam_probe, + .disconnect = usb_fjveincam_disconnect, + .id_table = fjveincam_table, + .no_dynamic_id = 1 +}; + + + + MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL v2"); diff --git a/modules/fjpalmvein/C/fjpalmvein-main/fjveincam.h b/modules/fjpalmvein/C/fjpalmvein-main/fjveincam.h index 9b51e1dbc..309cea6f8 100644 --- a/modules/fjpalmvein/C/fjpalmvein-main/fjveincam.h +++ b/modules/fjpalmvein/C/fjpalmvein-main/fjveincam.h @@ -18,6 +18,8 @@ #ifndef _FJVEINCAM_ #define _FJVEINCAM_ +//#define CONFIG_FJVEINCAM_DEBUG + /*----------------------------------------------------------------------*/ /* ioctl */ /*----------------------------------------------------------------------*/ @@ -65,4 +67,6 @@ struct fjveincam_info { unsigned char version[8]; /* device driver version string */ }; + + #endif /* _FJVEINCAM_ */ diff --git a/modules/fjpalmvein/README b/modules/fjpalmvein/README index 7511b5f2b..04dc4c646 100644 --- a/modules/fjpalmvein/README +++ b/modules/fjpalmvein/README @@ -44,6 +44,23 @@ make +Jun 01 11:27:08 virgil kernel: >>>>>>>>>>>>>>.. USB Driver: /t200/yoloserv/modules/fjpalmvein/C/fjpalmvein-main/fjveincam.c @ 750 (deallocating...): usb_fjveincam_disconnect = 0 +Jun 01 11:27:09 virgil kernel: usb 4-6.1: new high-speed USB device number 38 using xhci_hcd +Jun 01 11:27:10 virgil kernel: usb 4-6.1: New USB device found, idVendor=04c5, idProduct=1526, bcdDevice= 2.00 +Jun 01 11:27:10 virgil kernel: usb 4-6.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 +Jun 01 11:27:10 virgil kernel: usb 4-6.1: Product: FUJITSU PalmSecure-F Pro +Jun 01 11:27:10 virgil kernel: usb 4-6.1: Manufacturer: FUJITSU +Jun 01 11:27:10 virgil kernel: >>>>>>>>>>>>>>.. USB Driver: /t200/yoloserv/modules/fjpalmvein/C/fjpalmvein-main/fjveincam.c @ 606 (probed; [device id]): usb_fjveincam_probe = 0 +Jun 01 11:27:10 virgil kernel: >>>>>>>>>>>>>>.. USB Driver: /t200/yoloserv/modules/fjpalmvein/C/fjpalmvein-main/fjveincam.c @ 611 (vendor id 0x4c5, device id 0x1526, portnum:1): usb_fjveincam_probe = 0 +Jun 01 11:27:10 virgil kernel: >>>>>>>>>>>>>>.. USB Driver: /t200/yoloserv/modules/fjpalmvein/C/fjpalmvein-main/fjveincam.c @ 630 (endpoints): usb_fjveincam_probe = 0 +Jun 01 11:27:10 virgil kernel: >>>>>>>>>>>>>>.. USB Driver: /t200/yoloserv/modules/fjpalmvein/C/fjpalmvein-main/fjveincam.c @ 645 (bulk in): usb_fjveincam_probe = 0 +Jun 01 11:27:10 virgil kernel: >>>>>>>>>>>>>>.. USB Driver: /t200/yoloserv/modules/fjpalmvein/C/fjpalmvein-main/fjveincam.c @ 652 (bulk out): usb_fjveincam_probe = 0 +Jun 01 11:27:10 virgil kernel: >>>>>>>>>>>>>>.. USB Driver: /t200/yoloserv/modules/fjpalmvein/C/fjpalmvein-main/fjveincam.c @ 713 (have a minor): usb_fjveincam_probe = 0 +Jun 01 11:27:10 virgil kernel: fjveincam 4-6.1:1.0: USB PalmVeinCam device now attached to usb/fjveincam-160 +Jun 01 11:27:10 virgil mtp-probe[306997]: checking bus 4, device 38: "/sys/devices/pci0000:00/0000:00:02.4/0000:05:00.0/usb4/4-6/4-6.1" +Jun 01 11:27:10 virgil mtp-probe[306997]: bus: 4, device: 38 was not an MTP device +Jun 01 11:27:10 virgil systemd-udevd[306996]: 4-6.1:1.0: Process '/usr/lib/snapd/snap-device-helper bind snap_arduino_arduino /devices/pci0000:00/0000:00:02.4/0000:05:00.0/usb4/4-6/4-6.1/4-6.1:1.0 0:0' failed with exit code 1. +Jun 01 11:27:10 virgil systemd-udevd[306996]: 4-6.1:1.0: Process '/usr/lib/snapd/snap-device-helper bind snap_cups_cupsd /devices/pci0000:00/0000:00:02.4/0000:05:00.0/usb4/4-6/4-6.1/4-6.1:1.0 0:0' failed with exit code 1.