Several cleanups. Still a lot to do though. Signed-off-by: Felipe Balbi <me at felipebalbi.com> --- ...add-usb-test-and-measurement-class-driver.patch | 1872 +++++++++----------- 1 files changed, 852 insertions(+), 1020 deletions(-) diff --git a/usb-add-usb-test-and-measurement-class-driver.patch b/usb-add-usb-test-and-measurement-class-driver.patch index c176f36..b6e33ca 100644 --- a/usb-add-usb-test-and-measurement-class-driver.patch +++ b/usb-add-usb-test-and-measurement-class-driver.patch @@ -13,12 +13,13 @@ TODO: - remove unneeded ioctls (like the manufacturer string...) - get assigned minor number - linux-usb review for locking, etc. + - get rid of ifdefs + - move include file to include/linux/usb so it can be used by gadget framework Cc: Stefan Kopp <stefan_kopp at agilent.com> Cc: Marcel Janssen <korgull at home.nl> Not-Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de> - --- drivers/usb/class/Kconfig | 10 drivers/usb/class/Makefile | 1 @@ -26,9 +27,11 @@ Not-Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de> drivers/usb/class/usbtmc.h | 143 +++ 4 files changed, 1910 insertions(+) ---- a/drivers/usb/class/Kconfig -+++ b/drivers/usb/class/Kconfig -@@ -40,3 +40,13 @@ config USB_WDM +Index: linux-2.6/drivers/usb/class/Kconfig +=================================================================== +--- linux-2.6.orig/drivers/usb/class/Kconfig 2008-06-11 16:38:51.000000000 +0300 ++++ linux-2.6/drivers/usb/class/Kconfig 2008-06-18 00:06:46.000000000 +0300 +@@ -40,3 +40,13 @@ To compile this driver as a module, choose M here: the module will be called cdc-wdm. @@ -42,39 +45,44 @@ Not-Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de> + + To compile this driver as a module, choose M here: the + module will be called usbtmc. ---- a/drivers/usb/class/Makefile -+++ b/drivers/usb/class/Makefile +Index: linux-2.6/drivers/usb/class/Makefile +=================================================================== +--- linux-2.6.orig/drivers/usb/class/Makefile 2008-06-11 16:38:51.000000000 +0300 ++++ linux-2.6/drivers/usb/class/Makefile 2008-06-18 00:06:46.000000000 +0300 @@ -6,3 +6,4 @@ obj-$(CONFIG_USB_ACM) += cdc-acm.o obj-$(CONFIG_USB_PRINTER) += usblp.o obj-$(CONFIG_USB_WDM) += cdc-wdm.o +obj-$(CONFIG_USB_TMC) += usbtmc.o ---- /dev/null -+++ b/drivers/usb/class/usbtmc.c -@@ -0,0 +1,1756 @@ -+// usbtmc.c -+// Linux kernel module for USBTMC (USB Test and Measurement Class) devices -+// Copyright (C) 2007 Stefan Kopp, Gechingen, Germany -+// See revision history at the end of this file -+// -+// This program is free software; you can redistribute it and/or -+// modify it under the terms of the GNU General Public License -+// as published by the Free Software Foundation; either version 2 -+// of the License, or (at your option) any later version. -+// -+// This program is distributed in the hope that it will be useful, -+// but WITHOUT ANY WARRANTY; without even the implied warranty of -+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+// GNU General Public License for more details. -+// -+// The GNU General Public License is available at -+// http://www.gnu.org/copyleft/gpl.html. -+ -+// #define USBTMC_DEBUG -+// If defined: causes the driver to log status messages in the kernel log +Index: linux-2.6/drivers/usb/class/usbtmc.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6/drivers/usb/class/usbtmc.c 2008-06-18 00:54:14.000000000 +0300 +@@ -0,0 +1,1578 @@ ++/* usbtmc.c ++ * Linux kernel module for USBTMC (USB Test and Measurement Class) devices ++ * Copyright (C) 2007 Stefan Kopp, Gechingen, Germany ++ * See revision history at the end of this file ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * The GNU General Public License is available at ++ * http://www.gnu.org/copyleft/gpl.html. ++ */ + ++/* If defined: causes the driver to log status messages in the kernel log */ ++/* #define USBTMC_DEBUG */ ++ ++/* Integer representation of version code (1.1) */ +#define USBTMC_VERSION 110 -+// Integer representation of version code (1.1) + +#include <linux/init.h> +#include <linux/module.h> @@ -87,37 +95,36 @@ Not-Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de> +#include "usbtmc.h" + +static struct usb_device_id usbtmc_devices[] = { -+ {.match_flags=USB_DEVICE_ID_MATCH_INT_CLASS | -+ USB_DEVICE_ID_MATCH_INT_SUBCLASS, -+ // Device class and sub class need to match for notification by the -+ // usb core layer. -+ .bInterfaceClass=254, // 254 = application specific -+ .bInterfaceSubClass=3}, // 3 = test and measurement class (USBTMC) -+ { } // Empty (terminating) entry ++ { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 0), }, ++ { } /* terminating entry */ +}; -+// This list defines which devices are serviced by this driver. This driver -+// handles USBTMC devices, so we look for the corresponding class (application -+// specific) and subclass (USBTMC). + ++/* Will hold base (first) major/minor number to be used. ++ * The major number used is allocated dynamically in usbtmc_init. ++ */ +static dev_t dev; -+// Will hold base (first) major/minor number to be used. -+// The major number used is allocated dynamically in usbtmc_init. + ++/* Character device structure for minor number 0 (for communication with ++ * the driver itself, not an instrument. ++ */ +static struct cdev cdev; -+// Character device structure for minor number 0 (for communication with -+// the driver itself, not an instrument. + ++/* This array is used to track the status of the minor numbers allocated by ++ * the driver (used or unused). ++ * 0 = unused; 1 = used. ++ * Minor number 0 is reserved for communication with the driver itself. ++ */ +static u8 usbtmc_minors[USBTMC_MINOR_NUMBERS]; -+// This array is used to track the status of the minor numbers allocated by -+// the driver (used or unused). -+// 0=unused; 1=used. -+// Minor number 0 is reserved for communication with the driver itself. + ++/* This array will hold the private data pointers of the instruments. It is ++ * used by the minor 0 driver to get access to the USB sessions to retrieve ++ * instrument information. ++ */ +static struct usbtmc_device_data *usbtmc_devs[USBTMC_MINOR_NUMBERS]; -+// This array will hold the private data pointers of the instruments. It is -+// used by the minor 0 driver to get access to the USB sessions to retrieve -+// instrument information. + ++/* This structure holds private data for each USBTMC device. One copy is ++ * allocated for each USBTMC device in the driver's probe function. ++ */ +struct usbtmc_device_data { + struct cdev cdev; + int devno; @@ -138,146 +145,142 @@ Not-Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de> + int add_nl_on_read; + int rem_nl_on_write; +}; -+// This structure holds private data for each USBTMC device. One copy is -+// allocated for each USBTMC device in the driver's probe function. -+ -+static struct usb_driver usbtmc_driver; -+// This structure contains registration information for the driver. The -+// information is passed to the system through usb_register(), called in the -+// driver's init function. + +/* Pointer to buffer for I/O data (allocated in usbtmc_init) */ +static u8 *usbtmc_buffer; + -+ +/* Last bTag values (needed for abort) */ +static u8 usbtmc_last_write_bTag; +static u8 usbtmc_last_read_bTag; + -+/* "Completion" for driver initialization.... */ -+// static struct completion usbtmc_init_done; -+ +/* Forward declarations */ +static int usbtmc_ioctl_abort_bulk_in(struct inode *, struct file *, + unsigned int, unsigned long); +static int usbtmc_ioctl_abort_bulk_out(struct inode *, struct file *, + unsigned int, unsigned long); + -+static int usbtmc_open(struct inode *inode,struct file *filp) -+// This function is called when opening an instrument device file. It looks for -+// the device's USB endpoints for later access. ++/** ++ * usbtmc_open ++ * This function is called when opening an instrument device file. It looks for ++ * the device's USB endpoints for later access. ++ */ ++static int usbtmc_open(struct inode *inode, struct file *filp) +{ + struct usbtmc_device_data *p_device_data; + u8 n; -+ u8 bulk_in,bulk_out; ++ u8 bulk_in = 0; ++ u8 bulk_out = 0; + struct usb_host_interface *curr_setting; + struct usb_endpoint_descriptor *end_point; + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: usbtmc_open called\n"); -+ #endif ++#endif + -+ if(!iminor(inode)) goto minor_null; // Driver communication ++ if (!iminor(inode)) ++ goto minor_null; + -+ // Get pointer to instrument's private data -+ p_device_data = container_of(inode->i_cdev,struct usbtmc_device_data,cdev); ++ /* Get pointer to instrument's private data */ ++ p_device_data = container_of(inode->i_cdev, ++ struct usbtmc_device_data, cdev); + -+ // Store pointer in file structure's private data field -+ filp->private_data=p_device_data; ++ /* Store pointer in file structure's private data field */ ++ filp->private_data = p_device_data; + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: Number of USB settings is %u\n", -+ p_device_data->intf->num_altsetting); -+ #endif ++ p_device_data->intf->num_altsetting); ++#endif + -+ // USBTMC devices have only one setting, so use that (current setting) ++ /* USBTMC devices have only one setting, ++ * so use that (current setting) ++ */ + curr_setting=p_device_data->intf->cur_altsetting; + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: Number of endpoints is %u\n", -+ curr_setting->desc.bNumEndpoints); -+ #endif -+ -+ // Find bulk in endpoint -+ bulk_in=0; -+ for(n=0;n<(curr_setting->desc.bNumEndpoints);n++) { -+ end_point=&(curr_setting->endpoint[n].desc); -+ if((end_point->bEndpointAddress & USB_DIR_IN) && -+ ((end_point->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)== -+ USB_ENDPOINT_XFER_BULK)) { -+ bulk_in=end_point->bEndpointAddress; -+ #ifdef USBTMC_DEBUG ++ curr_setting->desc.bNumEndpoints); ++#endif ++ ++ /* Find bulk in endpoint */ ++ for (n = 0; n < curr_setting->desc.bNumEndpoints; n++) { ++ end_point = &curr_setting->endpoint[n].desc; ++ ++ if ((end_point->bEndpointAddress & USB_DIR_IN) && ++ ((end_point->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == ++ USB_ENDPOINT_XFER_BULK)) { ++ ++ bulk_in = end_point->bEndpointAddress; ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: Found bulk in endpoint at %u\n", -+ bulk_in); -+ #endif -+ n=curr_setting->desc.bNumEndpoints; // Exit loop ++ bulk_in); ++#endif ++ n = curr_setting->desc.bNumEndpoints; + } + } -+ p_device_data->bulk_in=bulk_in; ++ p_device_data->bulk_in = bulk_in; + -+ // Find bulk out endpoint -+ bulk_out=0; -+ for(n=0;n<(curr_setting->desc.bNumEndpoints);n++) { -+ end_point=&(curr_setting->endpoint[n].desc); -+ if(!(end_point->bEndpointAddress & USB_DIR_IN) && ++ /* Find bulk out endpoint */ ++ for (n = 0; n < curr_setting->desc.bNumEndpoints; n++) { ++ end_point = &curr_setting->endpoint[n].desc; ++ ++ if (!(end_point->bEndpointAddress & USB_DIR_IN) && + ((end_point->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)== + USB_ENDPOINT_XFER_BULK)) { -+ bulk_out=end_point->bEndpointAddress; -+ #ifdef USBTMC_DEBUG ++ ++ bulk_out = end_point->bEndpointAddress; ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: Found Bulk out endpoint at %u\n", -+ bulk_out); -+ #endif -+ n=curr_setting->desc.bNumEndpoints; // Exit loop ++ bulk_out); ++#endif ++ n = curr_setting->desc.bNumEndpoints; + } + } -+ p_device_data->bulk_out=bulk_out; ++ p_device_data->bulk_out = bulk_out; + + return 0; + +minor_null: -+ // Minor number 0 is reserved for communication with driver ++ /* Minor number 0 is reserved for communication with driver */ + -+ // Allocate memory for private data -+ if(!(p_device_data=kmalloc(sizeof(struct usbtmc_device_data),GFP_KERNEL))) { ++ p_device_data = kmalloc(sizeof(*p_device_data), GFP_KERNEL); ++ if(!p_device_data) { + printk(KERN_ALERT "USBTMC: Unable to allocate kernel memory\n"); + return -ENOMEM; + } + -+ // Set major/minor to 0 -+ p_device_data->devno=0; ++ /* Set major/minor to 0 */ ++ p_device_data->devno = 0; + -+ // Store pointer in file structure's private data field -+ filp->private_data=p_device_data; ++ /* Store pointer in file structure's private data field */ ++ filp->private_data = p_device_data; + + return 0; +} + +static int usbtmc_release(struct inode *inode,struct file *filp) -+// This function is called when closing the instrument device file. +{ -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_ALERT "USBTMC: usbtmc_release called\n"); -+ #endif ++#endif + -+ if(!iminor(inode)) goto minor_null; // Driver communication ++ if (!iminor(inode)) ++ goto minor_null; + + return 0; + +minor_null: -+ // Minor number 0 is reserved for communication with driver -+ -+ // Free buffer allocated in usbtmc_init ++ /* Minor number 0 is reserved for communication with driver */ + kfree(filp->private_data); + + return 0; +} + +static int usbtmc_buffer_append(char *dest,char *src,int *count) -+// Helper function for usbtmc_read. +{ + int n=0; -+ while(*src!=0){ // Continue to the end of source string -+ *dest=*src; ++ while(*src != 0){ ++ *dest = *src; + dest++; + src++; + n++; @@ -290,8 +293,6 @@ Not-Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de> + char __user *buf, + size_t count, + loff_t *f_pos) -+// This function reads the instrument's output buffer through a -+// USMTMC DEV_DEP_MSG_IN message. +{ + struct usbtmc_device_data *p_device_data; + unsigned int pipe; @@ -307,179 +308,176 @@ Not-Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de> + int done; + int this_part; + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: usbtmc_read called\n"); + printk(KERN_NOTICE "USBTMC: Count is %u\n",count); -+ #endif ++#endif + -+ // Get pointer to private data structure -+ p_device_data=filp->private_data; ++ /* Get pointer to private data structure */ ++ p_device_data = filp->private_data; + -+ if(!p_device_data->devno) goto minor_null; // Driver communication ++ if (!p_device_data->devno) ++ goto minor_null; + -+ if((p_device_data->fread)&&(p_device_data->eof)) { -+ // Zero will tell fread that the EOF was reached. It will keep fread -+ // from retrying to read up to the max number of characters. -+ p_device_data->eof=0; ++ if (p_device_data->fread && p_device_data->eof) { ++ /* Zero will tell fread that the EOF was reached. It will keep fread ++ * from retrying to read up to the max number of characters. ++ */ ++ p_device_data->eof = 0; + return 0; + } + -+ remaining=count; -+ done=0; ++ remaining = count; ++ done = 0; + -+ while(remaining>0) ++ while (remaining > 0) + { -+ if(remaining>USBTMC_SIZE_IOBUFFER-12-3) { -+ this_part=USBTMC_SIZE_IOBUFFER-12-3; -+ } -+ else { -+ this_part=remaining; -+ } -+ -+ // Setup IO buffer for DEV_DEP_MSG_IN message -+ usbtmc_buffer[0]=2; // REQUEST_DEV_DEP_MSG_IN -+ usbtmc_buffer[1]=p_device_data->bTag; // Transfer ID (bTag) -+ usbtmc_buffer[2]=~(p_device_data->bTag); // Inverse of bTag -+ usbtmc_buffer[3]=0; // Reserved -+ usbtmc_buffer[4]=(this_part-12-3)&255; // Max transfer (first byte) -+ usbtmc_buffer[5]=((this_part-12-3)>>8)&255; // Second byte -+ usbtmc_buffer[6]=((this_part-12-3)>>16)&255; // Third byte -+ usbtmc_buffer[7]=((this_part-12-3)>>24)&255; // Fourth byte -+ usbtmc_buffer[8]=p_device_data->term_char_enabled*2; -+ // Use term character? -+ usbtmc_buffer[9]=p_device_data->term_char; // Term character -+ usbtmc_buffer[10]=0; // Reserved -+ usbtmc_buffer[11]=0; // Reserved -+ -+ // Create pipe for bulk out transfer -+ pipe=usb_sndbulkpipe(p_device_data->usb_dev,p_device_data->bulk_out); -+ -+ // Send bulk URB -+ retval=usb_bulk_msg(p_device_data->usb_dev,pipe,usbtmc_buffer,12, -+ &actual,p_device_data->timeout); -+ -+ // Store bTag (in case we need to abort) -+ usbtmc_last_write_bTag=p_device_data->bTag; -+ -+ // Increment bTag -- and increment again if zero -+ (p_device_data->bTag)++; -+ if(!(p_device_data->bTag)) (p_device_data->bTag)++; -+ -+ if(retval<0) { ++ if (remaining > USBTMC_SIZE_IOBUFFER - 12 - 3) ++ this_part = USBTMC_SIZE_IOBUFFER - 12 - 3; ++ else ++ this_part = remaining; ++ ++ /* Setup IO buffer for DEV_DEP_MSG_IN message ++ * Refer to class specs for details ++ */ ++ usbtmc_buffer[0] = 2; ++ usbtmc_buffer[1] = p_device_data->bTag; ++ usbtmc_buffer[2] = ~(p_device_data->bTag); ++ usbtmc_buffer[3] = 0; /* Reserved */ ++ usbtmc_buffer[4] = (this_part - 12 - 3) & 255; ++ usbtmc_buffer[5] = ((this_part - 12 - 3) >> 8) & 255; ++ usbtmc_buffer[6] = ((this_part - 12 - 3) >> 16) & 255; ++ usbtmc_buffer[7] = ((this_part - 12 - 3) >> 24) & 255; ++ usbtmc_buffer[8] = p_device_data->term_char_enabled * 2; ++ /* Use term character? */ ++ usbtmc_buffer[9] = p_device_data->term_char; ++ usbtmc_buffer[10] = 0; /* Reserved */ ++ usbtmc_buffer[11] = 0; /* Reserved */ ++ ++ /* Create pipe for bulk out transfer */ ++ pipe = usb_sndbulkpipe(p_device_data->usb_dev, ++ p_device_data->bulk_out); ++ ++ /* Send bulk URB */ ++ retval = usb_bulk_msg(p_device_data->usb_dev, ++ pipe, usbtmc_buffer, 12, ++ &actual,p_device_data->timeout); ++ ++ /* Store bTag (in case we need to abort) */ ++ usbtmc_last_write_bTag = p_device_data->bTag; ++ ++ /* Increment bTag -- and increment again if zero */ ++ p_device_data->bTag++; ++ if (!p_device_data->bTag) ++ (p_device_data->bTag)++; ++ ++ if (retval < 0) { + printk(KERN_NOTICE "USBTMC: usb_bulk_msg returned %d\n", -+ retval); -+ if(p_device_data->auto_abort) -+ usbtmc_ioctl_abort_bulk_out(NULL,filp,USBTMC_IOCTL_ABORT_BULK_OUT, -+ 0); ++ retval); ++ if (p_device_data->auto_abort) ++ usbtmc_ioctl_abort_bulk_out(NULL, filp, ++ USBTMC_IOCTL_ABORT_BULK_OUT, 0); + return retval; + } + -+ // Create pipe for bulk in transfer -+ pipe=usb_rcvbulkpipe(p_device_data->usb_dev,p_device_data->bulk_in); ++ /* Create pipe for bulk in transfer */ ++ pipe = usb_rcvbulkpipe(p_device_data->usb_dev, ++ p_device_data->bulk_in); + -+ // Send bulk URB -+ retval=usb_bulk_msg(p_device_data->usb_dev,pipe,usbtmc_buffer, -+ USBTMC_SIZE_IOBUFFER,&actual,p_device_data->timeout); ++ /* Send bulk URB */ ++ retval = usb_bulk_msg(p_device_data->usb_dev, pipe, ++ usbtmc_buffer, USBTMC_SIZE_IOBUFFER, ++ &actual, p_device_data->timeout); + -+ // Store bTag (in case we need to abort) ++ /* Store bTag (in case we need to abort) */ + usbtmc_last_read_bTag=p_device_data->bTag; + -+ if(retval<0) { ++ if (retval < 0) { + printk(KERN_NOTICE "USBTMC: Unable to read data, error %d\n", -+ retval); -+ if(p_device_data->auto_abort) -+ usbtmc_ioctl_abort_bulk_in(NULL,filp,USBTMC_IOCTL_ABORT_BULK_IN,0); ++ retval); ++ if (p_device_data->auto_abort) ++ usbtmc_ioctl_abort_bulk_in(NULL, filp, ++ USBTMC_IOCTL_ABORT_BULK_IN, 0); + return retval; + } + -+ // How many characters did the instrument send? -+ n_characters=usbtmc_buffer[4]+ -+ (usbtmc_buffer[5]<<8)+ -+ (usbtmc_buffer[6]<<16)+ -+ (usbtmc_buffer[7]<<24); ++ /* How many characters did the instrument send? */ ++ n_characters = usbtmc_buffer[4] + ++ (usbtmc_buffer[5] << 8) + ++ (usbtmc_buffer[6] << 16) + ++ (usbtmc_buffer[7] << 24); + -+ // Copy buffer to user space -+ if(copy_to_user(buf+done,&usbtmc_buffer[12],n_characters)) { -+ // There must have been an addressing problem ++ /* Copy buffer to user space */ ++ if (copy_to_user(buf + done, &usbtmc_buffer[12], ++ n_characters)) ++ /* There must have been an addressing problem */ + return -EFAULT; -+ } + -+ done+=n_characters; -+ if(n_characters<USBTMC_SIZE_IOBUFFER) remaining=0; ++ done += n_characters; ++ if (n_characters < USBTMC_SIZE_IOBUFFER) ++ remaining=0; + } + -+ if(p_device_data->add_nl_on_read==USBTMC_ATTRIB_VAL_ON) { -+ // Add newline character -+ if(done<count) { // Still space in user buffer? -+ usbtmc_buffer[0]='\n'; -+ if(copy_to_user(buf+done,&usbtmc_buffer[0],1)) { -+ // There must have been an addressing problem ++ if (p_device_data->add_nl_on_read == USBTMC_ATTRIB_VAL_ON) { ++ /* Add newline character */ ++ if (done < count) { ++ usbtmc_buffer[0] = '\n'; ++ if (copy_to_user(buf + done, &usbtmc_buffer[0], 1)) + return -EFAULT; -+ } -+ done+=1; ++ done += 1; + } + } + -+ // Update file position value -+ *f_pos=*f_pos+done; ++ /* Update file position value */ ++ *f_pos = *f_pos + done; + -+ // If less bytes than the requested number are returned, fread will -+ // retry. Make sure the next read (retry) returns 0 -- this will cause -+ // fread to give up (EOF). -+ if(done<count) p_device_data->eof=1; ++ /* If less bytes than the requested number are returned, fread will ++ * retry. Make sure the next read (retry) returns 0 -- this will cause ++ * fread to give up (EOF). ++ */ ++ if (done < count) ++ p_device_data->eof = 1; + -+ return done; // Number of bytes read (total) ++ return done; + +minor_null: -+ // Minor number 0 is reserved for communication with this driver. -+ // Reading from this minor number returns a list of the devices currently -+ // registered. This allows you to identify the minor number to use for a -+ // given device. -+ -+ // Return 0 (end of file) if not reading from beginning (f_pos==0). -+ // This will keep fread from trying to read the full number of requested -+ // bytes. You must read the whole data with the initial call because -+ // subsequent calls will return "end of file". -+ if(*f_pos>0) return 0; -+ -+ p=(char *)usbtmc_buffer; -+ t=0; -+ -+ // Add header line to buffer -+ p=p+usbtmc_buffer_append(p, ++ if(*f_pos > 0) ++ return 0; ++ ++ p = (char *)usbtmc_buffer; ++ t = 0; ++ ++ /* Add header line to buffer */ ++ p = p + usbtmc_buffer_append(p, + "Minor Number\tManufacturer\tProduct\tSerial Number\n",&t); + -+ // Find out which minor numbers are used -+ for(n=1;n<USBTMC_MINOR_NUMBERS;n++) -+ if(usbtmc_minors[n]) { -+ // Add entry for this device -+ p_device=interface_to_usbdev(usbtmc_devs[n]->intf); -+ sprintf(p,"%03d\t",n); p=p+4; t=t+4; -+ s=p_device->manufacturer; -+ p=p+usbtmc_buffer_append(p,s,&t); -+ p=p+usbtmc_buffer_append(p,"\t",&t); -+ s=p_device->product; -+ p=p+usbtmc_buffer_append(p,s,&t); -+ p=p+usbtmc_buffer_append(p,"\t",&t); -+ s=p_device->serial; -+ p=p+usbtmc_buffer_append(p,s,&t); -+ p=p+usbtmc_buffer_append(p,"\n",&t); ++ /* Find out which minor numbers are used */ ++ for(n = 1; n < USBTMC_MINOR_NUMBERS; n++) ++ if (usbtmc_minors[n]) { ++ /* Add entry for this device */ ++ p_device = interface_to_usbdev(usbtmc_devs[n]->intf); ++ sprintf(p, "%03d\t", n); ++ p = p + 4; ++ t = t + 4; ++ s = p_device->manufacturer; ++ p = p + usbtmc_buffer_append(p, s, &t); ++ p = p + usbtmc_buffer_append(p, "\t", &t); ++ s = p_device->product; ++ p = p + usbtmc_buffer_append(p, s, &t); ++ p = p + usbtmc_buffer_append(p, "\t", &t); ++ s = p_device->serial; ++ p = p + usbtmc_buffer_append(p, s, &t); ++ p = p + usbtmc_buffer_append(p, "\n", &t); + } + -+ // Copy buffer to user space -+ if(copy_to_user(buf,usbtmc_buffer,t)) { -+ // There must have been an addressing problem ++ if(copy_to_user(buf, usbtmc_buffer, t)) { + return -EFAULT; + } ++ *f_pos = *f_pos+t; + -+ // Update file position value -+ *f_pos=*f_pos+t; -+ -+ return t; // Number of bytes read ++ return t; +} + -+// This function sends a command to an instrument by wrapping it into a -+// USMTMC DEV_DEP_MSG_OUT message. +static ssize_t usbtmc_write(struct file *filp, + const char __user *buf, + size_t count, @@ -495,112 +493,94 @@ Not-Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de> + int done; + int this_part; + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: usbtmc_write called\n"); -+ #endif ++#endif + -+ // Get pointer to private data structure -+ p_device_data=filp->private_data; ++ p_device_data = filp->private_data; + -+ if(!p_device_data->devno) goto minor_null; // Driver communication ++ if(!p_device_data->devno) ++ goto minor_null; + -+ p_device_data->eof=0; ++ p_device_data->eof = 0; + -+ remaining=count; -+ done=0; ++ remaining = count; ++ done = 0; + -+ while(remaining>0) // Still bytes to send -+ { -+ if(remaining>USBTMC_SIZE_IOBUFFER-12) { -+ // Use maximum size (limited by driver internal buffer size) -+ this_part=USBTMC_SIZE_IOBUFFER-12; // Use maximum size -+ usbtmc_buffer[8]=0; // This is not the last transfer -- see below -+ } -+ else { -+ // Can send remaining bytes in a single transaction -+ this_part=remaining; -+ usbtmc_buffer[8]=1; // Message ends with this transfer -- see below ++ while (remaining > 0) { ++ if (remaining > USBTMC_SIZE_IOBUFFER - 12) { ++ this_part = USBTMC_SIZE_IOBUFFER - 12; ++ usbtmc_buffer[8] = 0; ++ } else { ++ this_part = remaining; ++ usbtmc_buffer[8] = 1; + } + -+ // Setup IO buffer for DEV_DEP_MSG_OUT message -+ usbtmc_buffer[0]=1; // DEV_DEP_MSG_OUT -+ usbtmc_buffer[1]=p_device_data->bTag; // Transfer ID (bTag) -+ usbtmc_buffer[2]=~(p_device_data->bTag); // Inverse of bTag -+ usbtmc_buffer[3]=0; // Reserved -+ usbtmc_buffer[4]=this_part&255; // Transfer size (first byte) -+ usbtmc_buffer[5]=(this_part>>8)&255; // Transfer size (second byte) -+ usbtmc_buffer[6]=(this_part>>16)&255; // Transfer size (third byte) -+ usbtmc_buffer[7]=(this_part>>24)&255; // Transfer size (fourth byte) -+ // usbtmc_buffer[8] is set above... -+ usbtmc_buffer[9]=0; // Reserved -+ usbtmc_buffer[10]=0; // Reserved -+ usbtmc_buffer[11]=0; // Reserved -+ -+ // Append write buffer (instrument command) to USBTMC message -+ if(copy_from_user(&(usbtmc_buffer[12]),buf+done,this_part)) { -+ // There must have been an addressing problem ++ /* Setup IO buffer for DEV_DEP_MSG_OUT message */ ++ usbtmc_buffer[0] = 1; ++ usbtmc_buffer[1] = p_device_data->bTag; ++ usbtmc_buffer[2] = ~(p_device_data->bTag); ++ usbtmc_buffer[3] = 0; /* Reserved */ ++ usbtmc_buffer[4] = this_part & 255; ++ usbtmc_buffer[5] = (this_part >> 8) & 255; ++ usbtmc_buffer[6] = (this_part >> 16) & 255; ++ usbtmc_buffer[7] = (this_part >> 24) & 255; ++ /* usbtmc_buffer[8] is set above... */ ++ usbtmc_buffer[9] = 0; /* Reserved */ ++ usbtmc_buffer[10] = 0; /* Reserved */ ++ usbtmc_buffer[11] = 0; /* Reserved */ ++ ++ if (copy_from_user(&usbtmc_buffer[12], buf + done, this_part)) + return -EFAULT; -+ } + -+ if(this_part==remaining) { // If this is the last transfer... -+ if(p_device_data->rem_nl_on_write==USBTMC_ATTRIB_VAL_ON) { -+ // See if last byte to send is a '\n'... -+ if(usbtmc_buffer[12+this_part-1]=='\n') { -+ // Remove it! ++ if (this_part == remaining) ++ if (p_device_data->rem_nl_on_write == ++ USBTMC_ATTRIB_VAL_ON) ++ if(usbtmc_buffer[12 + this_part - 1] == '\n') + this_part--; -+ } -+ } -+ } + -+ // Add zero bytes to achieve 4-byte alignment -+ n_bytes=12+this_part; -+ if(this_part%4) { -+ n_bytes+=4-this_part%4; -+ for(n=12+this_part;n<n_bytes;n++) usbtmc_buffer[n]=0; -+ } ++ n_bytes = 12 + this_part; ++ if (this_part % 4) ++ n_bytes += 4 - this_part % 4; ++ for (n = 12 + this_part; n < n_bytes; n++) ++ usbtmc_buffer[n] = 0; + -+ // Create pipe for bulk out transfer -+ pipe=usb_sndbulkpipe(p_device_data->usb_dev,p_device_data->bulk_out); ++ pipe = usb_sndbulkpipe(p_device_data->usb_dev, ++ p_device_data->bulk_out); ++ retval = usb_bulk_msg(p_device_data->usb_dev, pipe, ++ usbtmc_buffer, n_bytes, ++ &actual, p_device_data->timeout); + -+ // Send bulk URB -+ retval=usb_bulk_msg(p_device_data->usb_dev,pipe,usbtmc_buffer,n_bytes, -+ &actual,p_device_data->timeout); ++ usbtmc_last_write_bTag = p_device_data->bTag; ++ p_device_data->bTag++; + -+ // Store bTag (in case we need to abort) -+ usbtmc_last_write_bTag=p_device_data->bTag; ++ if (!p_device_data->bTag) ++ p_device_data->bTag++; + -+ // Increment bTag -- and increment again if zero -+ (p_device_data->bTag)++; -+ if(!(p_device_data->bTag)) (p_device_data->bTag)++; -+ -+ if(retval<0) { ++ if (retval < 0) { + printk(KERN_NOTICE "USBTMC: Unable to send data, error %d\n", + retval); -+ if(p_device_data->auto_abort) -+ usbtmc_ioctl_abort_bulk_out(NULL,filp,USBTMC_IOCTL_ABORT_BULK_OUT, -+ 0); ++ if (p_device_data->auto_abort) ++ usbtmc_ioctl_abort_bulk_out(NULL, filp, ++ USBTMC_IOCTL_ABORT_BULK_OUT, ++ 0); + return retval; + } + -+ remaining-=this_part; -+ done+=this_part; ++ remaining -= this_part; ++ done += this_part; + } + + return count; + +minor_null: -+ // Minor number 0 is reserved for communication with driver -+ + return -EPERM; +} + -+static int usbtmc_ioctl_abort_bulk_in (struct inode *inode, ++static int usbtmc_ioctl_abort_bulk_in(struct inode *inode, + struct file *filp, + unsigned int cmd, + unsigned long arg) -+// Abort the last bulk in transfer and restore synchronization. -+// See section 4.2.1.4 of the USBTMC specifcation for details. -+// Called by usbtmc_ioctl... See below! +{ + struct usbtmc_device_data *p_device_data; + int rv; @@ -609,166 +589,155 @@ Not-Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de> + struct usb_host_interface *current_setting; + int max_size; + -+ // Get pointer to private data structure -+ p_device_data=filp->private_data; ++ p_device_data = filp->private_data; + -+ // INITIATE_ABORT_BULK_IN request -+ rv=usb_control_msg( -+ p_device_data->usb_dev, // USB device structure -+ usb_rcvctrlpipe(p_device_data->usb_dev,0), // Control in pipe -+ USBTMC_REQUEST_INITIATE_ABORT_BULK_IN, // INITIATE_ABORT -+ USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_ENDPOINT, // Request type -+ usbtmc_last_read_bTag, // Last transaction's bTag value -+ p_device_data->bulk_in, // Endpoint -+ usbtmc_buffer, // Target buffer -+ 2, // Number of characters to read -+ p_device_data->timeout); // Timeout (jiffies) -+ -+ if(rv<0) { // I/O error ++ rv = usb_control_msg( ++ p_device_data->usb_dev, ++ usb_rcvctrlpipe(p_device_data->usb_dev, 0), ++ USBTMC_REQUEST_INITIATE_ABORT_BULK_IN, ++ USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_ENDPOINT, ++ usbtmc_last_read_bTag, ++ p_device_data->bulk_in, ++ usbtmc_buffer, ++ 2, ++ p_device_data->timeout); ++ ++ if (rv < 0) { + printk(KERN_NOTICE "USBTMC: usb_control_msg returned %d\n",rv); + return rv; + } + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: INITIATE_ABORT_BULK_IN returned %x\n", -+ usbtmc_buffer[0]); -+ #endif ++ usbtmc_buffer[0]); ++#endif + -+ if(usbtmc_buffer[0]==USBTMC_STATUS_FAILED) { -+ // No transfer in progress and bulk in fifo is empty. ++ if (usbtmc_buffer[0] == USBTMC_STATUS_FAILED) + return 0; -+ } + -+ if(usbtmc_buffer[0]!=USBTMC_STATUS_SUCCESS) -+ { ++ if (usbtmc_buffer[0] != USBTMC_STATUS_SUCCESS) { + printk(KERN_NOTICE + "USBTMC: INITIATE_ABORT_BULK_IN returned %x\n", + usbtmc_buffer[0]); + return -EPERM; + } + -+ // Get wMaxPacketSize -+ max_size=0; -+ current_setting=p_device_data->intf->cur_altsetting; -+ // Find data structure for bulk in endpoint -+ for(n=0;n<current_setting->desc.bNumEndpoints;n++) -+ if(current_setting->endpoint[n].desc.bEndpointAddress== ++ max_size = 0; ++ current_setting = p_device_data->intf->cur_altsetting; ++ for (n = 0; n < current_setting->desc.bNumEndpoints; n++) ++ if (current_setting->endpoint[n].desc.bEndpointAddress == + p_device_data->bulk_in) -+ // Now get that endpoint's wMaxPacketSize -+ max_size=current_setting->endpoint[n].desc.wMaxPacketSize; -+ if(max_size==0) { ++ max_size = ++ current_setting->endpoint[n].desc.wMaxPacketSize; ++ ++ if (max_size == 0) { + printk(KERN_NOTICE "USBTMC: Couldn't get wMaxPacketSize\n"); + return -EPERM; + } + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: wMaxPacketSize is %d\n",max_size); -+ #endif ++#endif + -+ n=0; // To keep track of the number of read operations (see below) ++ n = 0; + + do { -+ // Read a chunk of data from bulk in endpoint -+ -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: Reading from bulk in EP\n"); -+ #endif ++#endif + -+ // Read from bulk in EP -+ rv=usb_bulk_msg(p_device_data->usb_dev, -+ usb_rcvbulkpipe(p_device_data->usb_dev, -+ p_device_data->bulk_in), // Bulk in pipe -+ usbtmc_buffer, // Target buffer -+ USBTMC_SIZE_IOBUFFER, // Max characters to read -+ &actual, // Actual characters read -+ p_device_data->timeout); // Timeout (jiffies) ++ rv = usb_bulk_msg(p_device_data->usb_dev, ++ usb_rcvbulkpipe(p_device_data->usb_dev, ++ p_device_data->bulk_in), ++ usbtmc_buffer, ++ USBTMC_SIZE_IOBUFFER, ++ &actual, ++ p_device_data->timeout); + + n++; + -+ if(rv<0) { // I/O error ++ if(rv < 0) { + printk(KERN_NOTICE "USBTMC: usb_bulk_msg returned %d\n", + rv); + return rv; + } -+ } while ((actual==max_size)&&(n<USBTMC_MAX_READS_TO_CLEAR_BULK_IN)); ++ } while ((actual == max_size) && ++ (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN)); + -+ if(actual==max_size) { // Couldn't clear device buffer ++ if(actual == max_size) { + printk(KERN_NOTICE + "USBTMC: Couldn't clear device buffer within %d cycles\n", + USBTMC_MAX_READS_TO_CLEAR_BULK_IN); + return -EPERM; + } + -+ n=0; // To keep track of the number of read operations (see below) ++ n = 0; + +usbtmc_abort_bulk_in_status: + -+ // CHECK_ABORT_BULK_IN_STATUS request -+ rv=usb_control_msg( -+ p_device_data->usb_dev, // USB device structure -+ usb_rcvctrlpipe(p_device_data->usb_dev,0), // Control in pipe -+ USBTMC_REQUEST_CHECK_ABORT_BULK_IN_STATUS, // CHECK_STATUS -+ USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_ENDPOINT, // Request type -+ 0, // Reserved -+ p_device_data->bulk_in, // Endpoint -+ usbtmc_buffer, // Target buffer -+ 0x08, // Number of characters to read -+ p_device_data->timeout); // Timeout (jiffies) -+ -+ if(rv<0) { // I/O error ++ rv = usb_control_msg( ++ p_device_data->usb_dev, ++ usb_rcvctrlpipe(p_device_data->usb_dev,0), ++ USBTMC_REQUEST_CHECK_ABORT_BULK_IN_STATUS, ++ USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_ENDPOINT, ++ 0, ++ p_device_data->bulk_in, ++ usbtmc_buffer, ++ 0x08, ++ p_device_data->timeout); ++ ++ if (rv < 0) { + printk(KERN_NOTICE "USBTMC: usb_control_msg returned %d\n",rv); + return rv; + } + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: INITIATE_ABORT_BULK_IN returned %x\n", -+ usbtmc_buffer[0]); -+ #endif ++ usbtmc_buffer[0]); ++#endif + + if(usbtmc_buffer[0]==USBTMC_STATUS_SUCCESS) + return 0; + + if(usbtmc_buffer[0]!=USBTMC_STATUS_PENDING) { + printk(KERN_NOTICE -+ "USBTMC: INITIATE_ABORT_BULK_IN returned %x\n", -+ usbtmc_buffer[0]); ++ "USBTMC: INITIATE_ABORT_BULK_IN returned %x\n", ++ usbtmc_buffer[0]); + return -EPERM; + } + -+ // Is there data to read off the device? -+ if(usbtmc_buffer[1]==1) do { -+ // Read a chunk of data from bulk in endpoint ++ if (usbtmc_buffer[1] == 1) ++ do { + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: Reading from bulk in EP\n"); -+ #endif ++#endif + -+ // Read from bulk in EP -+ rv=usb_bulk_msg(p_device_data->usb_dev, -+ usb_rcvbulkpipe(p_device_data->usb_dev, -+ p_device_data->bulk_in), // Bulk in pipe -+ usbtmc_buffer, // Target buffer -+ USBTMC_SIZE_IOBUFFER, // Max characters to read -+ &actual, // Actual characters read -+ p_device_data->timeout); // Timeout (jiffies) ++ rv = usb_bulk_msg(p_device_data->usb_dev, ++ usb_rcvbulkpipe(p_device_data->usb_dev, ++ p_device_data->bulk_in), ++ usbtmc_buffer, ++ USBTMC_SIZE_IOBUFFER, ++ &actual, ++ p_device_data->timeout); + + n++; + -+ if(rv<0) { // I/O error ++ if (rv < 0) { + printk(KERN_NOTICE "USBTMC: usb_bulk_msg returned %d\n", -+ rv); ++ rv); + return rv; + } -+ } while ((actual=max_size)&&(n<USBTMC_MAX_READS_TO_CLEAR_BULK_IN)); ++ } while ((actual = max_size) && ++ (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN)); + -+ if(actual==max_size) { // Couldn't clear device buffer ++ if(actual == max_size) { + printk(KERN_NOTICE + "USBTMC: Couldn't clear device buffer within %d cycles\n", + USBTMC_MAX_READS_TO_CLEAR_BULK_IN); + return -EPERM; + } + -+ // Device should be clear at this point. Now check status again! + goto usbtmc_abort_bulk_in_status; +} + @@ -776,80 +745,73 @@ Not-Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de> + struct file *filp, + unsigned int cmd, + unsigned long arg) -+// Abort the last bulk out transfer and restore synchronization. -+// See section 4.2.1.2 of the USBTMC specifcation for details. -+// Called by usbtmc_ioctl... See below! +{ + struct usbtmc_device_data *p_device_data; + int rv; + int n; + -+ // Get pointer to private data structure -+ p_device_data=filp->private_data; ++ p_device_data = filp->private_data; + -+ // INITIATE_ABORT_BULK_OUT request -+ rv=usb_control_msg( -+ p_device_data->usb_dev, // USB device structure -+ usb_rcvctrlpipe(p_device_data->usb_dev,0), // Control in pipe -+ USBTMC_REQUEST_INITIATE_ABORT_BULK_OUT, // INITIATE_ABORT -+ USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_ENDPOINT, // Request type -+ usbtmc_last_write_bTag, // Last transaction's bTag value -+ p_device_data->bulk_out, // Endpoint -+ usbtmc_buffer, // Target buffer -+ 2, // Number of characters to read -+ p_device_data->timeout); // Timeout (jiffies) -+ -+ if(rv<0) { // I/O error ++ rv = usb_control_msg( ++ p_device_data->usb_dev, ++ usb_rcvctrlpipe(p_device_data->usb_dev,0), ++ USBTMC_REQUEST_INITIATE_ABORT_BULK_OUT, ++ USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_ENDPOINT, ++ usbtmc_last_write_bTag, ++ p_device_data->bulk_out, ++ usbtmc_buffer, ++ 2, ++ p_device_data->timeout); ++ ++ if (rv < 0) { + printk(KERN_NOTICE "USBTMC: usb_control_msg returned %d\n",rv); + return rv; + } + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: INITIATE_ABORT_BULK_OUT returned %x\n", -+ usbtmc_buffer[0]); -+ #endif ++ usbtmc_buffer[0]); ++#endif + -+ if(usbtmc_buffer[0]!=USBTMC_STATUS_SUCCESS) -+ { ++ if (usbtmc_buffer[0]!=USBTMC_STATUS_SUCCESS) { + printk(KERN_NOTICE + "USBTMC: INITIATE_ABORT_BULK_OUT returned %x\n", + usbtmc_buffer[0]); + return -EPERM; + } + -+ n=0; // To keep track of the number of turns (see below) ++ n = 0; + +usbtmc_abort_bulk_out_check_status: + -+ // CHECK_ABORT_BULK_OUT request -+ rv=usb_control_msg( -+ p_device_data->usb_dev, // USB device structure -+ usb_rcvctrlpipe(p_device_data->usb_dev,0), // Control in pipe -+ USBTMC_REQUEST_CHECK_ABORT_BULK_OUT_STATUS, // CHECK_STATUS -+ USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_ENDPOINT, // Request type -+ 0, // Reserved -+ p_device_data->bulk_out, // Endpoint -+ usbtmc_buffer, // Target buffer -+ 0x08, // Number of characters to read -+ p_device_data->timeout); // Timeout (jiffies) ++ rv = usb_control_msg( ++ p_device_data->usb_dev, ++ usb_rcvctrlpipe(p_device_data->usb_dev,0), ++ USBTMC_REQUEST_CHECK_ABORT_BULK_OUT_STATUS, ++ USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_ENDPOINT, ++ 0, ++ p_device_data->bulk_out, ++ usbtmc_buffer, ++ 0x08, ++ p_device_data->timeout); + + n++; + -+ if(rv<0) { // I/O error ++ if (rv < 0) { + printk(KERN_NOTICE "USBTMC: usb_control_msg returned %d\n",rv); + return rv; + } + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: CHECK_ABORT_BULK_OUT returned %x\n", -+ usbtmc_buffer[0]); -+ #endif ++ usbtmc_buffer[0]); ++#endif + -+ if(usbtmc_buffer[0]==USBTMC_STATUS_SUCCESS) ++ if (usbtmc_buffer[0] == USBTMC_STATUS_SUCCESS) + goto usbtmc_abort_bulk_out_clear_halt; + -+ if((usbtmc_buffer[0]==USBTMC_STATUS_PENDING)&& -+ (n<USBTMC_MAX_READS_TO_CLEAR_BULK_IN)) ++ if ((usbtmc_buffer[0] == USBTMC_STATUS_PENDING)&& ++ (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN)) + goto usbtmc_abort_bulk_out_check_status; + + printk(KERN_NOTICE "USBTMC: CHECK_ABORT_BULK_OUT returned %x\n", @@ -858,19 +820,18 @@ Not-Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de> + +usbtmc_abort_bulk_out_clear_halt: + -+ // CLEAR_FEATURE request to clear bulk out halt -+ rv=usb_control_msg( -+ p_device_data->usb_dev, // USB device structure -+ usb_sndctrlpipe(p_device_data->usb_dev,0), // Control out pipe -+ USB_REQ_CLEAR_FEATURE, // Clear feature request -+ USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT, // To EP -+ USB_ENDPOINT_HALT, // Feature ENDPOINT_HALT ++ rv = usb_control_msg( ++ p_device_data->usb_dev, ++ usb_sndctrlpipe(p_device_data->usb_dev,0), ++ USB_REQ_CLEAR_FEATURE, ++ USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT, ++ USB_ENDPOINT_HALT, + p_device_data->bulk_out, -+ usbtmc_buffer, // Target buffer -+ 0, // Although we don't really want data this time ++ usbtmc_buffer, ++ 0, + p_device_data->timeout); + -+ if(rv<0) { // I/O error ++ if (rv < 0) { + printk(KERN_NOTICE "USBTMC: usb_control_msg returned %d\n",rv); + return rv; + } @@ -878,13 +839,10 @@ Not-Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de> + return 0; +} + -+static int usbtmc_ioctl_clear (struct inode *inode, ++static int usbtmc_ioctl_clear(struct inode *inode, + struct file *filp, + unsigned int cmd, + unsigned long arg) -+// Clear the device's input and output buffers. -+// See section 4.2.1.6 of the USBTMC specification for details. -+// Called by usbtmc_ioctl... See below! +{ + struct usbtmc_device_data *p_device_data; + int rv; @@ -893,241 +851,224 @@ Not-Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de> + struct usb_host_interface *current_setting; + int max_size; + -+ // Get pointer to private data structure -+ p_device_data=filp->private_data; -+ ++ p_device_data = filp->private_data; + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: Sending INITIATE_CLEAR request\n"); -+ #endif -+ -+ // INITIATE_CLEAR request -+ rv=usb_control_msg( -+ p_device_data->usb_dev, // USB device structure -+ usb_rcvctrlpipe(p_device_data->usb_dev,0), // Control in pipe -+ USBTMC_REQUEST_INITIATE_CLEAR, // INITIATE_CLEAR -+ USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE, // Request type -+ 0, // Interface number (always zero for USBTMC) -+ 0, // Reserved -+ usbtmc_buffer, // Target buffer -+ 1, // Number of characters to read -+ p_device_data->timeout); // Timeout (jiffies) -+ -+ if(rv<0) { // I/O error -+ printk(KERN_NOTICE "USBTMC: usb_control_msg returned %d\n",rv); ++#endif ++ ++ rv = usb_control_msg( ++ p_device_data->usb_dev, ++ usb_rcvctrlpipe(p_device_data->usb_dev, 0), ++ USBTMC_REQUEST_INITIATE_CLEAR, ++ USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE, ++ 0, ++ 0, ++ usbtmc_buffer, ++ 1, ++ p_device_data->timeout); ++ ++ if(rv < 0) { ++ printk(KERN_NOTICE "USBTMC: usb_control_msg returned %d\n", rv); + return rv; + } + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: INITIATE_CLEAR returned %x\n", -+ usbtmc_buffer[0]); -+ #endif ++ usbtmc_buffer[0]); ++#endif + -+ if(usbtmc_buffer[0]!=USBTMC_STATUS_SUCCESS) { ++ if (usbtmc_buffer[0] != USBTMC_STATUS_SUCCESS) { + printk(KERN_NOTICE "USBTMC: INITIATE_CLEAR returned %x\n", -+ usbtmc_buffer[0]); ++ usbtmc_buffer[0]); + return -EPERM; + } + -+ // Get wMaxPacketSize -+ max_size=0; -+ current_setting=p_device_data->intf->cur_altsetting; -+ // Find data structure for bulk in endpoint -+ for(n=0;n<current_setting->desc.bNumEndpoints;n++) -+ if(current_setting->endpoint[n].desc.bEndpointAddress== -+ p_device_data->bulk_in) -+ // Now get that endpoint's wMaxPacketSize -+ max_size=current_setting->endpoint[n].desc.wMaxPacketSize; -+ if(max_size==0) { ++ max_size = 0; ++ current_setting = p_device_data->intf->cur_altsetting; ++ for (n = 0; n < current_setting->desc.bNumEndpoints; n++) ++ if (current_setting->endpoint[n].desc.bEndpointAddress == ++ p_device_data->bulk_in) ++ max_size = current_setting->endpoint[n].desc.wMaxPacketSize; ++ if (max_size == 0) { + printk(KERN_NOTICE "USBTMC: Couldn't get wMaxPacketSize\n"); + return -EPERM; + } + -+ #ifdef USBTMC_DEBUG -+ printk(KERN_NOTICE "USBTMC: wMaxPacketSize is %d\n",max_size); -+ #endif ++#ifdef USBTMC_DEBUG ++ printk(KERN_NOTICE "USBTMC: wMaxPacketSize is %d\n", max_size); ++#endif + -+ n=0; // To keep track of the number of read operations (see below) ++ n = 0; + +usbtmc_clear_check_status: + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: Sending CHECK_CLEAR_STATUS request\n"); -+ #endif -+ -+ // CHECK_CLEAR_STATUS request -+ rv=usb_control_msg( -+ p_device_data->usb_dev, // USB device structure -+ usb_rcvctrlpipe(p_device_data->usb_dev,0), // Control in pipe -+ USBTMC_REQUEST_CHECK_CLEAR_STATUS, // INITIATE_CLEAR -+ USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE, // Request type -+ 0, // Interface number (always zero for USBTMC) -+ 0, // Reserved -+ usbtmc_buffer, // Target buffer -+ 2, // Number of characters to read -+ p_device_data->timeout); // Timeout (jiffies) -+ -+ if(rv<0) { // I/O error -+ printk(KERN_NOTICE "USBTMC: usb_control_msg returned %d\n",rv); ++#endif ++ ++ rv = usb_control_msg( ++ p_device_data->usb_dev, ++ usb_rcvctrlpipe(p_device_data->usb_dev, 0), ++ USBTMC_REQUEST_CHECK_CLEAR_STATUS, ++ USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE, ++ 0, ++ 0, ++ usbtmc_buffer, ++ 2, ++ p_device_data->timeout); ++ ++ if (rv < 0) { ++ printk(KERN_NOTICE "USBTMC: usb_control_msg returned %d\n", rv); + return rv; + } + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: CHECK_CLEAR_STATUS returned %x\n", -+ usbtmc_buffer[0]); -+ #endif ++ usbtmc_buffer[0]); ++#endif + -+ if(usbtmc_buffer[0]==USBTMC_STATUS_SUCCESS) { -+ // Done. No data to read off the device. ++ if (usbtmc_buffer[0] == USBTMC_STATUS_SUCCESS) { + goto usbtmc_clear_bulk_out_halt; + } + -+ if(usbtmc_buffer[0]!=USBTMC_STATUS_PENDING) { ++ if (usbtmc_buffer[0] != USBTMC_STATUS_PENDING) { + printk(KERN_NOTICE "USBTMC: CHECK_CLEAR_STATUS returned %x\n", -+ usbtmc_buffer[0]); ++ usbtmc_buffer[0]); + return -EPERM; + } + -+ // Check bmClear field to see if data needs to be read off -+ // the device. -+ -+ if(usbtmc_buffer[1]==1) do { -+ // Read a chunk of data from bulk in endpoint ++ if (usbtmc_buffer[1] == 1) ++ do { + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: Reading from bulk in EP\n"); -+ #endif ++#endif + -+ // Read from bulk in EP -+ rv=usb_bulk_msg(p_device_data->usb_dev, -+ usb_rcvbulkpipe(p_device_data->usb_dev, -+ p_device_data->bulk_in), // Bulk in pipe -+ usbtmc_buffer, // Target buffer -+ USBTMC_SIZE_IOBUFFER, // Max characters to read -+ &actual, // Actual characters read -+ p_device_data->timeout); // Timeout (jiffies) ++ rv = usb_bulk_msg(p_device_data->usb_dev, ++ usb_rcvbulkpipe(p_device_data->usb_dev, ++ p_device_data->bulk_in), ++ usbtmc_buffer, ++ USBTMC_SIZE_IOBUFFER, ++ &actual, ++ p_device_data->timeout); + + n++; + -+ if(rv<0) { // I/O error ++ if (rv < 0) { + printk(KERN_NOTICE "USBTMC: usb_control_msg returned %d\n", -+ rv); ++ rv); + return rv; + } -+ } while ((actual==max_size)&&(n<USBTMC_MAX_READS_TO_CLEAR_BULK_IN)); ++ } while ((actual == max_size) && ++ (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN)); + -+ if(actual==max_size) { // Couldn't clear device buffer ++ if (actual == max_size) { + printk(KERN_NOTICE -+ "USBTMC: Couldn't clear device buffer within %d cycles\n", -+ USBTMC_MAX_READS_TO_CLEAR_BULK_IN); ++ "USBTMC: Couldn't clear device buffer within %d cycles\n", ++ USBTMC_MAX_READS_TO_CLEAR_BULK_IN); + return -EPERM; + } + -+ // Device should be clear at this point. Now check status again! + goto usbtmc_clear_check_status; + +usbtmc_clear_bulk_out_halt: + -+ // Finally, clear bulk out halt -+ rv=usb_control_msg( -+ p_device_data->usb_dev, // USB device structure -+ usb_sndctrlpipe(p_device_data->usb_dev,0), // Control out pipe -+ USB_REQ_CLEAR_FEATURE, // Clear feature request -+ USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT, // To EP -+ USB_ENDPOINT_HALT, // Feature ENDPOINT_HALT -+ p_device_data->bulk_out, -+ usbtmc_buffer, // Target buffer -+ 0, // Although we don't really want data this time -+ p_device_data->timeout); -+ -+ if(rv<0) { // I/O error -+ printk(KERN_NOTICE "USBTMC: usb_control_msg returned %d\n",rv); ++ rv = usb_control_msg( ++ p_device_data->usb_dev, ++ usb_sndctrlpipe(p_device_data->usb_dev, 0), ++ USB_REQ_CLEAR_FEATURE, ++ USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT, ++ USB_ENDPOINT_HALT, ++ p_device_data->bulk_out, ++ usbtmc_buffer, ++ 0, ++ p_device_data->timeout); ++ ++ if (rv < 0) { ++ printk(KERN_NOTICE "USBTMC: usb_control_msg returned %d\n", rv); + return rv; + } + + return 0; +} + -+static int usbtmc_ioctl_set_attribute (struct inode *inode, ++static int usbtmc_ioctl_set_attribute(struct inode *inode, + struct file *filp, + unsigned int cmd, + unsigned long arg) -+// Set driver attribute. -+// Called by usbtmc_ioctl... See below! +{ + struct usbtmc_device_data *p_device_data; + -+ // Get pointer to private data structure -+ p_device_data=filp->private_data; ++ p_device_data = filp->private_data; + + switch(((struct usbtmc_attribute *)arg)->attribute) + { -+ case USBTMC_ATTRIB_AUTO_ABORT_ON_ERROR: -+ if((((struct usbtmc_attribute *)arg)->value!= -+ USBTMC_ATTRIB_VAL_ON)&& ++ case USBTMC_ATTRIB_AUTO_ABORT_ON_ERROR: ++ if((((struct usbtmc_attribute *)arg)->value!= ++ USBTMC_ATTRIB_VAL_ON)&& + (((struct usbtmc_attribute *)arg)->value!= -+ USBTMC_ATTRIB_VAL_OFF)) -+ return -EINVAL; -+ p_device_data->auto_abort=((struct usbtmc_attribute *)arg)->value; -+ break; -+ -+ case USBTMC_ATTRIB_READ_MODE: -+ if((((struct usbtmc_attribute *)arg)->value!= -+ USBTMC_ATTRIB_VAL_FREAD)&& ++ USBTMC_ATTRIB_VAL_OFF)) ++ return -EINVAL; ++ p_device_data->auto_abort=((struct usbtmc_attribute *)arg)->value; ++ break; ++ ++ case USBTMC_ATTRIB_READ_MODE: ++ if((((struct usbtmc_attribute *)arg)->value!= ++ USBTMC_ATTRIB_VAL_FREAD)&& + (((struct usbtmc_attribute *)arg)->value!= -+ USBTMC_ATTRIB_VAL_READ)) -+ return -EINVAL; -+ p_device_data->fread=((struct usbtmc_attribute *)arg)->value; -+ break; -+ -+ case USBTMC_ATTRIB_TIMEOUT: -+ if(((struct usbtmc_attribute *)arg)->value<0) -+ return -EINVAL; -+ p_device_data->timeout= -+ ((struct usbtmc_attribute *)arg)->value/1000*HZ; -+ break; -+ -+ case USBTMC_ATTRIB_TERM_CHAR_ENABLED: -+ if((((struct usbtmc_attribute *)arg)->value!= -+ USBTMC_ATTRIB_VAL_ON)&& ++ USBTMC_ATTRIB_VAL_READ)) ++ return -EINVAL; ++ p_device_data->fread=((struct usbtmc_attribute *)arg)->value; ++ break; ++ ++ case USBTMC_ATTRIB_TIMEOUT: ++ if(((struct usbtmc_attribute *)arg)->value<0) ++ return -EINVAL; ++ p_device_data->timeout= ++ ((struct usbtmc_attribute *)arg)->value/1000*HZ; ++ break; ++ ++ case USBTMC_ATTRIB_TERM_CHAR_ENABLED: ++ if((((struct usbtmc_attribute *)arg)->value!= ++ USBTMC_ATTRIB_VAL_ON)&& + (((struct usbtmc_attribute *)arg)->value!= -+ USBTMC_ATTRIB_VAL_OFF)) -+ return -EINVAL; -+ p_device_data->term_char_enabled= -+ ((struct usbtmc_attribute *)arg)->value; -+ break; -+ -+ case USBTMC_ATTRIB_TERM_CHAR: -+ if((((struct usbtmc_attribute *)arg)->value<0)|| ++ USBTMC_ATTRIB_VAL_OFF)) ++ return -EINVAL; ++ p_device_data->term_char_enabled= ++ ((struct usbtmc_attribute *)arg)->value; ++ break; ++ ++ case USBTMC_ATTRIB_TERM_CHAR: ++ if((((struct usbtmc_attribute *)arg)->value<0)|| + (((struct usbtmc_attribute *)arg)->value>255)) -+ return -EINVAL; -+ p_device_data->term_char= -+ ((struct usbtmc_attribute *)arg)->value; -+ break; -+ -+ case USBTMC_ATTRIB_ADD_NL_ON_READ: -+ if((((struct usbtmc_attribute *)arg)->value!= -+ USBTMC_ATTRIB_VAL_ON)&& -+ (((struct usbtmc_attribute *)arg)->value!= -+ USBTMC_ATTRIB_VAL_OFF)) -+ return -EINVAL; -+ p_device_data->add_nl_on_read= -+ ((struct usbtmc_attribute *)arg)->value; -+ break; -+ -+ case USBTMC_ATTRIB_REM_NL_ON_WRITE: -+ if((((struct usbtmc_attribute *)arg)->value!= -+ USBTMC_ATTRIB_VAL_ON)&& ++ return -EINVAL; ++ p_device_data->term_char= ++ ((struct usbtmc_attribute *)arg)->value; ++ break; ++ ++ case USBTMC_ATTRIB_ADD_NL_ON_READ: ++ if((((struct usbtmc_attribute *)arg)->value!= ++ USBTMC_ATTRIB_VAL_ON)&& + (((struct usbtmc_attribute *)arg)->value!= -+ USBTMC_ATTRIB_VAL_OFF)) -+ return -EINVAL; -+ p_device_data->rem_nl_on_write= -+ ((struct usbtmc_attribute *)arg)->value; -+ break; ++ USBTMC_ATTRIB_VAL_OFF)) ++ return -EINVAL; ++ p_device_data->add_nl_on_read= ++ ((struct usbtmc_attribute *)arg)->value; ++ break; + -+ default: -+ // Bad attribute or read-only ++ case USBTMC_ATTRIB_REM_NL_ON_WRITE: ++ if((((struct usbtmc_attribute *)arg)->value!= ++ USBTMC_ATTRIB_VAL_ON)&& ++ (((struct usbtmc_attribute *)arg)->value!= ++ USBTMC_ATTRIB_VAL_OFF)) + return -EINVAL; ++ p_device_data->rem_nl_on_write= ++ ((struct usbtmc_attribute *)arg)->value; ++ break; ++ ++ default: ++ return -EINVAL; + } + + return 0; @@ -1137,154 +1078,139 @@ Not-Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de> + struct file *filp, + unsigned int cmd, + unsigned long arg) -+// Read driver attribute. -+// Called by usbtmc_ioctl... See below! +{ + struct usbtmc_device_data *p_device_data; + int n; + int count; + -+ // Get pointer to private data structure -+ p_device_data=filp->private_data; ++ p_device_data = filp->private_data; + + switch(((struct usbtmc_attribute *)arg)->attribute) + { -+ case USBTMC_ATTRIB_AUTO_ABORT_ON_ERROR: -+ ((struct usbtmc_attribute *)arg)->value=p_device_data->auto_abort; -+ break; -+ -+ case USBTMC_ATTRIB_READ_MODE: -+ ((struct usbtmc_attribute *)arg)->value=p_device_data->fread; -+ break; -+ -+ case USBTMC_ATTRIB_TIMEOUT: -+ ((struct usbtmc_attribute *)arg)->value= -+ p_device_data->timeout/HZ*1000; -+ break; -+ -+ case USBTMC_ATTRIB_NUM_INSTRUMENTS: -+ count=0; -+ for(n=1;n<USBTMC_MINOR_NUMBERS;n++) -+ if(usbtmc_minors[n]) count++; -+ ((struct usbtmc_attribute *)arg)->value=count; -+ break; -+ -+ case USBTMC_ATTRIB_MINOR_NUMBERS: -+ ((struct usbtmc_attribute *)arg)->value= -+ USBTMC_MINOR_NUMBERS; // defined in usbtmc.h -+ break; -+ -+ case USBTMC_ATTRIB_SIZE_IO_BUFFER: -+ ((struct usbtmc_attribute *)arg)->value= -+ USBTMC_SIZE_IOBUFFER; // defined in usbtmc.h -+ break; -+ -+ case USBTMC_ATTRIB_DEFAULT_TIMEOUT: -+ ((struct usbtmc_attribute *)arg)->value= -+ USBTMC_DEFAULT_TIMEOUT/HZ*1000; -+ // defined in usbtmc.h (in jiffies) -+ break; -+ -+ case USBTMC_ATTRIB_DEBUG_MODE: -+ ((struct usbtmc_attribute *)arg)->value=0; -+ #ifdef USBTMC_DEBUG -+ ((struct usbtmc_attribute *)arg)->value=1; -+ #endif -+ // defined at the beginning of this file -+ break; -+ -+ case USBTMC_ATTRIB_VERSION: -+ ((struct usbtmc_attribute *)arg)->value=USBTMC_VERSION; -+ // defined at the beginning of this file -+ break; -+ -+ case USBTMC_ATTRIB_TERM_CHAR_ENABLED: -+ ((struct usbtmc_attribute *)arg)->value= -+ p_device_data->term_char_enabled; -+ break; -+ -+ case USBTMC_ATTRIB_TERM_CHAR: -+ ((struct usbtmc_attribute *)arg)->value= -+ p_device_data->term_char; -+ break; -+ -+ case USBTMC_ATTRIB_ADD_NL_ON_READ: -+ ((struct usbtmc_attribute *)arg)->value= -+ p_device_data->add_nl_on_read; -+ break; -+ -+ case USBTMC_ATTRIB_REM_NL_ON_WRITE: -+ ((struct usbtmc_attribute *)arg)->value= -+ p_device_data->rem_nl_on_write; -+ break; -+ -+ default: -+ return -EINVAL; ++ case USBTMC_ATTRIB_AUTO_ABORT_ON_ERROR: ++ ((struct usbtmc_attribute *)arg)->value=p_device_data->auto_abort; ++ break; ++ ++ case USBTMC_ATTRIB_READ_MODE: ++ ((struct usbtmc_attribute *)arg)->value=p_device_data->fread; ++ break; ++ ++ case USBTMC_ATTRIB_TIMEOUT: ++ ((struct usbtmc_attribute *)arg)->value= ++ p_device_data->timeout/HZ*1000; ++ break; ++ ++ case USBTMC_ATTRIB_NUM_INSTRUMENTS: ++ count=0; ++ for(n=1;n<USBTMC_MINOR_NUMBERS;n++) ++ if(usbtmc_minors[n]) count++; ++ ((struct usbtmc_attribute *)arg)->value=count; ++ break; ++ ++ case USBTMC_ATTRIB_MINOR_NUMBERS: ++ ((struct usbtmc_attribute *)arg)->value= ++ USBTMC_MINOR_NUMBERS; ++ break; ++ ++ case USBTMC_ATTRIB_SIZE_IO_BUFFER: ++ ((struct usbtmc_attribute *)arg)->value= ++ USBTMC_SIZE_IOBUFFER; ++ break; ++ ++ case USBTMC_ATTRIB_DEFAULT_TIMEOUT: ++ ((struct usbtmc_attribute *)arg)->value= ++ USBTMC_DEFAULT_TIMEOUT/HZ*1000; ++ break; ++ ++ case USBTMC_ATTRIB_DEBUG_MODE: ++ ((struct usbtmc_attribute *)arg)->value=0; ++#ifdef USBTMC_DEBUG ++ ((struct usbtmc_attribute *)arg)->value=1; ++#endif ++ break; ++ ++ case USBTMC_ATTRIB_VERSION: ++ ((struct usbtmc_attribute *)arg)->value=USBTMC_VERSION; ++ break; ++ ++ case USBTMC_ATTRIB_TERM_CHAR_ENABLED: ++ ((struct usbtmc_attribute *)arg)->value= ++ p_device_data->term_char_enabled; ++ break; ++ ++ case USBTMC_ATTRIB_TERM_CHAR: ++ ((struct usbtmc_attribute *)arg)->value= ++ p_device_data->term_char; ++ break; ++ ++ case USBTMC_ATTRIB_ADD_NL_ON_READ: ++ ((struct usbtmc_attribute *)arg)->value= ++ p_device_data->add_nl_on_read; ++ break; ++ ++ case USBTMC_ATTRIB_REM_NL_ON_WRITE: ++ ((struct usbtmc_attribute *)arg)->value= ++ p_device_data->rem_nl_on_write; ++ break; ++ ++ default: ++ return -EINVAL; + } + + return 0; +} + -+static int usbtmc_ioctl_clear_out_halt (struct inode *inode, ++static int usbtmc_ioctl_clear_out_halt(struct inode *inode, + struct file *filp, + unsigned int cmd, + unsigned long arg) -+// Send CLEAR_FEATURE request to clear bulk out endpoint halt. -+// Called by usbtmc_ioctl... See below! +{ + struct usbtmc_device_data *p_device_data; + int rv; + -+ // Get pointer to private data structure -+ p_device_data=filp->private_data; ++ p_device_data = filp->private_data; + -+ rv=usb_control_msg( -+ p_device_data->usb_dev, // USB device structure -+ usb_sndctrlpipe(p_device_data->usb_dev,0), // Control out pipe -+ USB_REQ_CLEAR_FEATURE, // Clear feature request -+ USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT, // To EP -+ USB_ENDPOINT_HALT, // Feature ENDPOINT_HALT ++ rv = usb_control_msg( ++ p_device_data->usb_dev, ++ usb_sndctrlpipe(p_device_data->usb_dev, 0), ++ USB_REQ_CLEAR_FEATURE, ++ USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT, ++ USB_ENDPOINT_HALT, + p_device_data->bulk_out, -+ usbtmc_buffer, // Target buffer -+ 0, // Although we don't really want data this time ++ usbtmc_buffer, ++ 0, + p_device_data->timeout); + -+ if(rv<0) { // I/O error -+ printk(KERN_NOTICE "USBTMC: usb_control_msg returned %d\n",rv); ++ if (rv < 0) { ++ printk(KERN_NOTICE "USBTMC: usb_control_msg returned %d\n", rv); + return rv; + } + + return 0; +} + -+static int usbtmc_ioctl_clear_in_halt (struct inode *inode, ++static int usbtmc_ioctl_clear_in_halt(struct inode *inode, + struct file *filp, + unsigned int cmd, + unsigned long arg) -+// Send CLEAR_FEATURE request to clear bulk in endpoint halt. -+// Normally, you should not need this function. If a read transaction is -+// not processed properly (e.g. if a timeout occurs), ABORT_BULK_IN is usually -+// a better choice. -+// Called by usbtmc_ioctl... See below! +{ + struct usbtmc_device_data *p_device_data; + int rv; + -+ // Get pointer to private data structure -+ p_device_data=filp->private_data; ++ p_device_data = filp->private_data; + + rv=usb_control_msg( -+ p_device_data->usb_dev, // USB device structure -+ usb_sndctrlpipe(p_device_data->usb_dev,0), // Control out pipe -+ USB_REQ_CLEAR_FEATURE, // Clear feature request -+ USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT, // To EP -+ USB_ENDPOINT_HALT, // Feature ENDPOINT_HALT ++ p_device_data->usb_dev, ++ usb_sndctrlpipe(p_device_data->usb_dev,0), ++ USB_REQ_CLEAR_FEATURE, ++ USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT, ++ USB_ENDPOINT_HALT, + p_device_data->bulk_in, -+ usbtmc_buffer, // Target buffer -+ 0, // Although we don't really want data this time ++ usbtmc_buffer, ++ 0, + p_device_data->timeout); + -+ if(rv<0) { // I/O error ++ if (rv < 0) { + printk(KERN_NOTICE "USBTMC: usb_control_msg returned %d\n",rv); + return rv; + } @@ -1292,49 +1218,44 @@ Not-Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de> + return 0; +} + -+static int usbtmc_ioctl_get_capabilities (struct inode *inode, ++static int usbtmc_ioctl_get_capabilities(struct inode *inode, + struct file *filp, + unsigned int cmd, + unsigned long arg) -+// Returns information about the device's optional capabilities. -+// See section 4.2.1.8 of the USBTMC specifcation for details. -+// Called by usbtmc_ioctl... See below! +{ + struct usbtmc_device_data *p_device_data; + int rv; + -+ // Get pointer to private data structure -+ p_device_data=filp->private_data; ++ p_device_data = filp->private_data; ++ ++ rv = usb_control_msg( ++ p_device_data->usb_dev, ++ usb_rcvctrlpipe(p_device_data->usb_dev,0), ++ USBTMC_REQUEST_GET_CAPABILITIES, ++ USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE, ++ 0, ++ 0, ++ usbtmc_buffer, ++ 0x18, ++ p_device_data->timeout); + -+ // GET_CAPABILITIES request -+ rv=usb_control_msg( -+ p_device_data->usb_dev, // USB device structure -+ usb_rcvctrlpipe(p_device_data->usb_dev,0), // Control in pipe -+ USBTMC_REQUEST_GET_CAPABILITIES, // GET_CAPABILITIES -+ USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE, // Request type -+ 0, // Interface number (always zero for USBTMC) -+ 0, // Reserved -+ usbtmc_buffer, // Target buffer -+ 0x18, // Number of characters to read -+ p_device_data->timeout); // Timeout (jiffies) -+ -+ if(rv<0) { // I/O error ++ if (rv < 0) { + printk(KERN_NOTICE "USBTMC: usb_control_msg returned %d\n",rv); + return rv; + } + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: GET_CAPABILITIES returned %x\n", -+ usbtmc_buffer[0]); ++ usbtmc_buffer[0]); + printk(KERN_NOTICE "USBTMC: Interface capabilities are %x\n", -+ usbtmc_buffer[4]); ++ usbtmc_buffer[4]); + printk(KERN_NOTICE "USBTMC: Device capabilities are %x\n", -+ usbtmc_buffer[5]); ++ usbtmc_buffer[5]); + printk(KERN_NOTICE "USBTMC: USB488 interface capabilities are %x\n", -+ usbtmc_buffer[14]); ++ usbtmc_buffer[14]); + printk(KERN_NOTICE "USBTMC: USB488 device capabilities are %x\n", -+ usbtmc_buffer[15]); -+ #endif ++ usbtmc_buffer[15]); ++#endif + + if(usbtmc_buffer[0]!=USBTMC_STATUS_SUCCESS) { + printk(KERN_NOTICE "USBTMC: GET_CAPABILITIES returned %x\n", @@ -1358,41 +1279,34 @@ Not-Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de> + struct file *filp, + unsigned int cmd, + unsigned long arg) -+// Turns on the device's activity indicator for identification. -+// This capability is optional. When in doubt, use GET_CAPABILITIES to check -+// for support. -+// Called by usbtmc_ioctl... See below! +{ + struct usbtmc_device_data *p_device_data; + int rv; + -+ // Get pointer to private data structure -+ p_device_data=filp->private_data; ++ p_device_data = filp->private_data; ++ ++ rv = usb_control_msg( ++ p_device_data->usb_dev, ++ usb_rcvctrlpipe(p_device_data->usb_dev,0), ++ USBTMC_REQUEST_INDICATOR_PULSE, ++ USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE, ++ 0, ++ 0, ++ usbtmc_buffer, ++ 0x01, ++ p_device_data->timeout); + -+ // INDICATOR_PULSE request -+ rv=usb_control_msg( -+ p_device_data->usb_dev, // USB device structure -+ usb_rcvctrlpipe(p_device_data->usb_dev,0), // Control in pipe -+ USBTMC_REQUEST_INDICATOR_PULSE, // INDICATOR_PULSE -+ USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE, // Request type -+ 0, // Interface number (always zero for USBTMC) -+ 0, // Reserved -+ usbtmc_buffer, // Target buffer -+ 0x01, // Number of characters to read -+ p_device_data->timeout); // Timeout (jiffies) -+ -+ if(rv<0) { // I/O error ++ if (rv < 0) { + printk(KERN_NOTICE "USBTMC: usb_control_msg returned %d\n",rv); + return rv; + } + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: INDICATOR_PULSE returned %x\n", -+ usbtmc_buffer[0]); -+ #endif ++ usbtmc_buffer[0]); ++#endif + -+ if(usbtmc_buffer[0]!=USBTMC_STATUS_SUCCESS) -+ { ++ if (usbtmc_buffer[0] != USBTMC_STATUS_SUCCESS) { + printk(KERN_NOTICE "USBTMC: INDICATOR_PULSE returned %x\n", + usbtmc_buffer[0]); + return -EPERM; @@ -1405,71 +1319,62 @@ Not-Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de> + struct file *filp, + unsigned int cmd, + unsigned long arg) -+// Fills usbtmc_instrument data structure. -+// Called by usbtmc_ioctl... See below! +{ + struct usbtmc_device_data *p_device_data; + struct usb_device *p_device; + int n; + -+ // Get pointer to private data structure -+ p_device_data=filp->private_data; ++ p_device_data = filp->private_data; + -+ // See if minor number is OK -+ if(!usbtmc_minors[((struct usbtmc_instrument *)arg)->minor_number]) -+ // This minor number is not in use! ++ if (!usbtmc_minors[((struct usbtmc_instrument *)arg)->minor_number]) + return -EINVAL; + -+ // Now fill the data structure -+ p_device=interface_to_usbdev( ++ p_device = interface_to_usbdev( + usbtmc_devs[((struct usbtmc_instrument *)arg)->minor_number]->intf); -+ // Manufacturer -+ n=strlen(p_device->manufacturer); -+ if(n>199) n=199; -+ if(copy_to_user(((struct usbtmc_instrument *)arg)->manufacturer, -+ p_device->manufacturer,n)) { -+ // There must have been an addressing problem ++ n = strlen(p_device->manufacturer); ++ if (n > 199) ++ n = 199; ++ ++ if (copy_to_user(((struct usbtmc_instrument *)arg)->manufacturer, ++ p_device->manufacturer, n)) + return -EFAULT; -+ } -+ ((struct usbtmc_instrument *)arg)->manufacturer[n]=0; -+ // Product -+ n=strlen(p_device->product); -+ if(n>199) n=199; -+ if(copy_to_user(((struct usbtmc_instrument *)arg)->product, -+ p_device->product,n)) { -+ // There must have been an addressing problem ++ ++ ((struct usbtmc_instrument *)arg)->manufacturer[n] = 0; ++ n = strlen(p_device->product); ++ ++ if (n > 199) ++ n = 199; ++ ++ if (copy_to_user(((struct usbtmc_instrument *)arg)->product, ++ p_device->product, n)) + return -EFAULT; -+ } ++ + ((struct usbtmc_instrument *)arg)->product[n]=0; -+ // Serial number -+ n=strlen(p_device->product); -+ if(n>199) n=199; -+ if(copy_to_user(((struct usbtmc_instrument *)arg)->serial_number, -+ p_device->serial,n)) { -+ // There must have been an addressing problem ++ n = strlen(p_device->product); ++ ++ if (n > 199) ++ n = 199; ++ if (copy_to_user(((struct usbtmc_instrument *)arg)->serial_number, ++ p_device->serial,n)) + return -EFAULT; -+ } ++ + ((struct usbtmc_instrument *)arg)->serial_number[n]=0; ++ + return 0; +} + -+static int usbtmc_ioctl_reset_conf (struct inode *inode, ++static int usbtmc_ioctl_reset_conf(struct inode *inode, + struct file *filp, + unsigned int cmd, + unsigned long arg) -+// Reinitialize current USB configuration and its interfaces. -+// Called by usbtmc_ioctl... See below! +{ + struct usbtmc_device_data *p_device_data; + int rv; + -+ // Get pointer to private data structure -+ p_device_data=filp->private_data; -+ -+ // Reset configuration -+ rv=usb_reset_configuration(p_device_data->usb_dev); ++ p_device_data = filp->private_data; ++ rv = usb_reset_configuration(p_device_data->usb_dev); + -+ if(rv<0) { // I/O error ++ if (rv < 0) { + printk(KERN_NOTICE "USBTMC: usb_reset_configuration returned %d\n",rv); + return rv; + } @@ -1481,165 +1386,145 @@ Not-Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de> + struct file *filp, + unsigned int cmd, + unsigned long arg) -+// ioctl is used for special operations (other than message-based I/O), such -+// as device clear. +{ -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: Ioctl function called\n"); -+ #endif ++#endif + + switch(cmd) + { + case USBTMC_IOCTL_SET_ATTRIBUTE: -+ return usbtmc_ioctl_set_attribute(inode,filp,cmd,arg); ++ return usbtmc_ioctl_set_attribute(inode, filp, cmd, arg); + + case USBTMC_IOCTL_GET_ATTRIBUTE: -+ return usbtmc_ioctl_get_attribute(inode,filp,cmd,arg); ++ return usbtmc_ioctl_get_attribute(inode, filp, cmd, arg); + + case USBTMC_IOCTL_CLEAR_OUT_HALT: -+ return usbtmc_ioctl_clear_out_halt(inode,filp,cmd,arg); ++ return usbtmc_ioctl_clear_out_halt(inode, filp, cmd, arg); + + case USBTMC_IOCTL_CLEAR_IN_HALT: -+ return usbtmc_ioctl_clear_in_halt(inode,filp,cmd,arg); ++ return usbtmc_ioctl_clear_in_halt(inode, filp, cmd, arg); + + case USBTMC_IOCTL_GET_CAPABILITIES: -+ return usbtmc_ioctl_get_capabilities(inode,filp,cmd,arg); ++ return usbtmc_ioctl_get_capabilities(inode, filp, cmd, arg); + + case USBTMC_IOCTL_INDICATOR_PULSE: -+ return usbtmc_ioctl_indicator_pulse(inode,filp,cmd,arg); ++ return usbtmc_ioctl_indicator_pulse(inode, filp, cmd, arg); + + case USBTMC_IOCTL_CLEAR: -+ return usbtmc_ioctl_clear(inode,filp,cmd,arg); ++ return usbtmc_ioctl_clear(inode, filp, cmd, arg); + + case USBTMC_IOCTL_ABORT_BULK_OUT: -+ return usbtmc_ioctl_abort_bulk_out(inode,filp,cmd,arg); ++ return usbtmc_ioctl_abort_bulk_out(inode, filp, cmd, arg); + + case USBTMC_IOCTL_ABORT_BULK_IN: -+ return usbtmc_ioctl_abort_bulk_in(inode,filp,cmd,arg); ++ return usbtmc_ioctl_abort_bulk_in(inode, filp, cmd, arg); + + case USBTMC_IOCTL_INSTRUMENT_DATA: -+ return usbtmc_ioctl_instrument_data(inode,filp,cmd,arg); ++ return usbtmc_ioctl_instrument_data(inode, filp, cmd, arg); + + case USBTMC_IOCTL_RESET_CONF: -+ return usbtmc_ioctl_reset_conf(inode,filp,cmd,arg); ++ return usbtmc_ioctl_reset_conf(inode, filp, cmd, arg); + + default: -+ return -EBADRQC; // Invalid request code ++ return -EBADRQC; + } +} + ++/* REVISIT Do we need this after all ? */ +static loff_t usbtmc_llseek(struct file *filp,loff_t position,int x) -+// Seek (random access) doesn't make sense with test instruments, so this -+// function returns an error. +{ -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: usbtmc_llseek called\n"); -+ #endif ++#endif + -+ return -EPERM; // Operation not permitted ++ return -EPERM; +} + -+// This structure is used to publish the char device driver entry points +static struct file_operations fops = { -+ .owner=THIS_MODULE, -+ .read=usbtmc_read, -+ .write=usbtmc_write, -+ .open=usbtmc_open, -+ .release=usbtmc_release, -+ .ioctl=usbtmc_ioctl, -+ .llseek=usbtmc_llseek, ++ .owner = THIS_MODULE, ++ .read = usbtmc_read, ++ .write = usbtmc_write, ++ .open = usbtmc_open, ++ .release = usbtmc_release, ++ .ioctl = usbtmc_ioctl, ++ .llseek = usbtmc_llseek, +}; + +static int usbtmc_probe(struct usb_interface *intf, + const struct usb_device_id *id) -+// The probe function is called whenever a device is connected which is serviced -+// by this driver (USBTMC device). +{ + int retcode; + struct usbtmc_device_data *p_device_data; + struct usb_device *p_device; + int n; + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: usbtmc_probe called\n"); -+ #endif -+ -+ // Wait for completion of driver initialization -+ // wait_for_completion(&usbtmc_init_done); ++#endif + -+ // Allocate memory for device specific data -+ if(!(p_device_data=kmalloc(sizeof(struct usbtmc_device_data),GFP_KERNEL))) { ++ p_device_data = kmalloc(sizeof(struct usbtmc_device_data),GFP_KERNEL); ++ if(!p_device_data) { + printk(KERN_ALERT "USBTMC: Unable to allocate kernel memory\n"); + goto exit_kmalloc; + } + -+ // Find the first free minor number -+ n=1; -+ while(n<USBTMC_MINOR_NUMBERS && usbtmc_minors[n]!=0) n++; -+ if(n==USBTMC_MINOR_NUMBERS) { ++ n = 1; ++ while (n < USBTMC_MINOR_NUMBERS && usbtmc_minors[n] != 0) ++ n++; ++ if (n == USBTMC_MINOR_NUMBERS) { + printk(KERN_ALERT "USBTMC: No free minor number found\n"); -+ retcode=-ENOMEM; ++ retcode = -ENOMEM; + goto exit_cdev_add; + } + -+ // Now in use -+ usbtmc_minors[n]=1; -+ usbtmc_devs[n]=p_device_data; ++ usbtmc_minors[n] = 1; ++ usbtmc_devs[n] = p_device_data; + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: Using minor number %d\n",n); -+ #endif -+ -+ // Initialize cdev structure for this character device -+ // Set cdev structure to zero before calling cdev_init -+ memset(&p_device_data->cdev,0,sizeof(struct cdev)); -+ cdev_init(&p_device_data->cdev,&fops); -+ p_device_data->cdev.owner=THIS_MODULE; -+ p_device_data->cdev.ops=&fops; -+ -+ // Identify this instrument -+ p_device=interface_to_usbdev(intf); -+ #ifdef USBTMC_DEBUG ++#endif ++ ++ memset(&p_device_data->cdev, 0, sizeof(struct cdev)); ++ cdev_init(&p_device_data->cdev, &fops); ++ p_device_data->cdev.owner = THIS_MODULE; ++ p_device_data->cdev.ops = &fops; ++ ++ /* Identify this instrument */ ++ p_device = interface_to_usbdev(intf); ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: New device attached:\n"); + printk(KERN_NOTICE "USBTMC: Product: %s\n",p_device->product); + printk(KERN_NOTICE "USBTMC: Manufacturer: %s\n",p_device->manufacturer); + printk(KERN_NOTICE "USBTMC: Serial number: %s\n",p_device->serial); -+ #endif ++#endif + -+ // Combine major and minor numbers -+ printk(KERN_NOTICE "USBTMC: MKDEV\n"); -+ p_device_data->devno=MKDEV(MAJOR(dev),n); ++ p_device_data->devno = MKDEV(MAJOR(dev), n); + -+ // Add character device to kernel list -+ printk(KERN_NOTICE "USBTMC: CDEV_ADD\n"); -+ if((retcode=cdev_add(&p_device_data->cdev,p_device_data->devno,1))) { ++ retcode = cdev_add(&p_device_data->cdev,p_device_data->devno,1); ++ if(retcode) { + printk(KERN_ALERT "USBTMC: Unable to add character device\n"); + goto exit_cdev_add; + } + -+ // Store info about USB interface in private data structure -+ p_device_data->intf=intf; -+ p_device_data->id=id; -+ -+ // Store pointer to usb device -+ p_device_data->usb_dev=usb_get_dev(interface_to_usbdev(intf)); -+ -+ // Associate pointer to private data with this interface -+ usb_set_intfdata(intf,p_device_data); -+ -+ // Initialize USBTMC bTag and other fields -+ p_device_data->bTag=1; -+ p_device_data->eof=0; -+ p_device_data->fread=1; -+ p_device_data->timeout=USBTMC_DEFAULT_TIMEOUT; -+ p_device_data->term_char_enabled=0; -+ p_device_data->term_char='\n'; -+ p_device_data->add_nl_on_read=0; -+ p_device_data->rem_nl_on_write=0; ++ p_device_data->intf = intf; ++ p_device_data->id = id; ++ p_device_data->usb_dev = usb_get_dev(interface_to_usbdev(intf)); ++ usb_set_intfdata(intf, p_device_data); ++ ++ /* Initialize USBTMC bTag and other fields */ ++ p_device_data->bTag = 1; ++ p_device_data->eof = 0; ++ p_device_data->fread = 1; ++ p_device_data->timeout = USBTMC_DEFAULT_TIMEOUT; ++ p_device_data->term_char_enabled = 0; ++ p_device_data->term_char = '\n'; ++ p_device_data->add_nl_on_read = 0; ++ p_device_data->rem_nl_on_write = 0; ++ + return 0; + +exit_cdev_add: -+ // Free memory for device specific data + kfree(p_device_data); + return retcode; + @@ -1648,169 +1533,115 @@ Not-Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de> +} + +static void usbtmc_disconnect(struct usb_interface *intf) -+// The disconnect function is called whenever a device serviced by the driver is -+// disconnected. +{ + struct usbtmc_device_data *p_device_data; + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: usbtmc_disconnect called\n"); -+ #endif ++#endif + -+ // Get pointer to private data -+ p_device_data=usb_get_intfdata(intf); -+ -+ // Update array for minor number usage -+ usbtmc_minors[MINOR(p_device_data->devno)]=0; -+ -+ // Remove character device from kernel list ++ p_device_data = usb_get_intfdata(intf); ++ usbtmc_minors[MINOR(p_device_data->devno)] = 0; + cdev_del(&p_device_data->cdev); -+ -+ // Decrease use count + usb_get_dev(p_device_data->usb_dev); -+ -+ // Free memory allocated for private data + kfree(p_device_data); -+ -+ return; +} + -+// This structure is used to pass information about this USB driver to the -+// USB core (via usb_register) +static struct usb_driver usbtmc_driver = { -+ //.owner=THIS_MODULE, -+ .name="USBTMC", // Driver name -+ .id_table=usbtmc_devices, // Devices serviced by the driver -+ .probe=usbtmc_probe, // Probe function (called when device is connected) -+ .disconnect=usbtmc_disconnect // Disconnect function ++ .name = "usbtmc", ++ .id_table = usbtmc_devices, ++ .probe = usbtmc_probe, ++ .disconnect = usbtmc_disconnect +}; + -+static int usbtmc_init(void) -+// This function is called when the driver is inserted into the kernel. It -+// initializes and registers the driver. ++static int __init usbtmc_init(void) +{ + int retcode; + int n; + int devno; + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: usbtmc_init called\n"); -+ #endif ++#endif + -+ // Reset usbtmc_minors array -+ for(n=0;n<USBTMC_MINOR_NUMBERS;n++) usbtmc_minors[n]=0; ++ for ( n = 0; n < USBTMC_MINOR_NUMBERS; n++) ++ usbtmc_minors[n]=0; + -+ // Dynamically allocate char driver major/minor numbers -+ if((retcode=alloc_chrdev_region(&dev, // First major/minor number to use -+ 0, // First minor number -+ USBTMC_MINOR_NUMBERS, // Number of minor numbers to reserve -+ "USBTMCCHR" // Char device driver name -+ ))) { ++ if ((retcode = alloc_chrdev_region(&dev, ++ 0, ++ USBTMC_MINOR_NUMBERS, ++ "USBTMCCHR" ++ ))) { + printk(KERN_ALERT "USBTMC: Unable to allocate major/minor numbers\n"); + goto exit_alloc_chrdev_region; + } + -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: Major number is %d\n", MAJOR(dev)); -+ #endif ++#endif + -+ // Allocate I/O buffer -+ if(!(usbtmc_buffer=kmalloc(USBTMC_SIZE_IOBUFFER,GFP_KERNEL))) { ++ usbtmc_buffer = kmalloc(USBTMC_SIZE_IOBUFFER,GFP_KERNEL); ++ if(!usbtmc_buffer) { + printk(KERN_ALERT "USBTMC: Unable to allocate kernel memory\n"); -+ retcode=-ENOMEM; ++ retcode = -ENOMEM; + goto exit_kmalloc; + } + -+ // Initialize cdev structure for driver communication character device -+ // Set cdev structure to zero before calling cdev_init -+ memset(&cdev,0,sizeof(struct cdev)); -+ cdev_init(&cdev,&fops); -+ cdev.owner=THIS_MODULE; -+ cdev.ops=&fops; -+ devno=MKDEV(MAJOR(dev),0); ++ memset(&cdev, 0, sizeof(struct cdev)); ++ cdev_init(&cdev, &fops); ++ cdev.owner = THIS_MODULE; ++ cdev.ops = &fops; ++ devno = MKDEV(MAJOR(dev), 0); + -+ // Add character device to kernel list -+ if((retcode=cdev_add(&cdev,devno,1))) { ++ if((retcode = cdev_add(&cdev, devno, 1))) { + printk(KERN_ALERT "USBTMC: Unable to add character device\n"); -+ retcode=-ENODEV; ++ retcode = -ENODEV; + goto exit_cdev_add; + } + -+ // Initialize completion for driver initialization -+ // init_completion(&usbtmc_init_done); -+ -+ #ifdef USBTMC_DEBUG ++#ifdef USBTMC_DEBUG + printk(KERN_NOTICE "USBTMC: Registering USB driver\n"); -+ #endif ++#endif + -+ // Register USB driver with USB core -+ retcode=usb_register(&usbtmc_driver); -+ // complete(&usbtmc_init_done); -+ if(retcode) { ++ retcode = usb_register(&usbtmc_driver); ++ ++ if (retcode) { + printk(KERN_ALERT "USBTMC: Unable to register driver\n"); + goto exit_usb_register; + } + -+ return 0; // So far so good ++ return 0; + +exit_usb_register: -+ // Remove character device from kernel list + cdev_del(&cdev); + +exit_cdev_add: -+ // Free driver buffers + kfree(usbtmc_buffer); + +exit_kmalloc: -+ // Unregister char driver major/minor numbers -+ unregister_chrdev_region(dev,USBTMC_MINOR_NUMBERS); ++ unregister_chrdev_region(dev, USBTMC_MINOR_NUMBERS); + +exit_alloc_chrdev_region: + return retcode; +} ++module_init(usbtmc_init); + -+static void usbtmc_exit(void) -+// The exit function is called before the driver is unloaded from the kernel. -+// It is supposed to clean up and free any resources allocated by the driver. ++static void __exit usbtmc_exit(void) +{ -+ #ifdef USBTMC_DEBUG -+ printk(KERN_NOTICE "USBTMC: usbtmc_exit called\n"); -+ printk(KERN_NOTICE "USBTMC: Unregistering major/minor numbers\n"); -+ #endif -+ -+ // Unregister char driver major/minor numbers -+ unregister_chrdev_region(dev,USBTMC_MINOR_NUMBERS); -+ -+ // Release IO buffer allocated in usbtmc_init ++ unregister_chrdev_region(dev, USBTMC_MINOR_NUMBERS); + kfree(usbtmc_buffer); -+ -+ #ifdef USBTMC_DEBUG -+ printk(KERN_NOTICE "USBTMC: Deregistering driver\n"); -+ #endif -+ -+ // Unregister USB driver with USB core + usb_deregister(&usbtmc_driver); +} ++module_exit(usbtmc_exit); + -+module_init(usbtmc_init); // Inititialization function -+module_exit(usbtmc_exit); // Shutdown function -+ ++MODULE_ALIAS("usb:usbtmc"); +MODULE_LICENSE("GPL"); + -+// Revision history -+// -+// 1.0 05.11.2007 Initial version. -+// 1.0.1 07.11.2007 Set cdev struct to zero prior to calling cdev_init(). -+// 1.0.2 09.11.2007 Bug fixes related to control requests. -+// 1.0.3 13.11.2007 Automatic ABORT on error capability. -+// 1.0.4 21.11.2007 Updated ioctl functions. -+// Added GET_ATTRIBUTE and SET_ATTRIBUTE functions. -+// Added usbtmc_ioctl command line utility. -+// 1.1 08.12.2007 Added several new attributes. -+// Wrote HTML documentation. ---- /dev/null -+++ b/drivers/usb/class/usbtmc.h -@@ -0,0 +1,143 @@ +Index: linux-2.6/drivers/usb/class/usbtmc.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6/drivers/usb/class/usbtmc.h 2008-06-18 00:06:46.000000000 +0300 +@@ -0,0 +1,144 @@ +/* + * usbtmc.h + * This file is part of a Linux kernel module for USBTMC (USB Test and @@ -1826,17 +1657,18 @@ Not-Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de> +/* Driver parameters that you might want to tune... */ + +/* Maximum number of USBTMC devices to be concurrently serviced -+ * by this module */ -+#define USBTMC_MINOR_NUMBERS 16 ++ * by this module ++ */ ++#define USBTMC_MINOR_NUMBERS 16 + +/* + * Size of driver internal IO buffer. Must be multiple of 4 and at least as + * large as wMaxPacketSize (which is usually 512 bytes). + */ -+#define USBTMC_SIZE_IOBUFFER 4096 ++#define USBTMC_SIZE_IOBUFFER 4096 + +/* Default USB timeout (in jiffies) */ -+#define USBTMC_DEFAULT_TIMEOUT (10*HZ) ++#define USBTMC_DEFAULT_TIMEOUT (10*HZ) + +/* + * Maximum number of read cycles to empty bulk in endpoint during CLEAR and -- 1.5.6.rc1