All of the changes requested are included in the attached diff.

Signed-off-by: Nick Sillik <[EMAIL PROTECTED]>

---- Original message ----
>Date: Fri, 11 Mar 2005 16:11:06 -0500
>From: Dmitry Torokhov <[EMAIL PROTECTED]>  
>Subject: Re: [linux-usb-devel] [PATCH] To add usabillity for
the Maxtor Onetouch button on External Hard-drives  
>To: Alan Stern <[EMAIL PROTECTED]>
>Cc: Nick Sillik <[EMAIL PROTECTED]>,
linux-usb-devel@lists.sourceforge.net
>
>On Fri, 11 Mar 2005 15:20:30 -0500 (EST), Alan Stern
><[EMAIL PROTECTED]> wrote:
>> On Fri, 11 Mar 2005, Nick Sillik wrote:
>> 
>> > I'm resubmitting the patch with the wrap removed and the
list in the onetouch
>> > struct. I also changed usb_unlink_urb usb_kill_urb.
>> 
>> > +int onetouch_release_input(struct us_data *ss)
>> <...>
>> > +             usb_unlink_urb(onetouch->irq);
>> 
>> Should be usb_kill_urb again.
>> 
>> > +             input_unregister_device(&onetouch->dev);
>> > +             usb_free_urb(onetouch->irq);
>> > +             usb_buffer_free(onetouch->udev,
ONETOUCH_PKT_LEN,
>> > +                             onetouch->data,
onetouch->data_dma);
>> > +             kfree(onetouch);
>> 
>> I'm not too familiar with the input layer.  Can't this code
run while a
>> user still has the input device file open?  If it does,
what will happen
>> when the user later closes the device file and
onetouch_close tries to
>> dereference a pointer to deallocated memory?
>
>It is OK, input layer will not try to call close on a device
taht is
>marked dead.
>
>> In usb.c:usb_stor_release_resources():
>> > +        /* Attempt to connect the onetouch urb to the
device         */
>> > +     /* Note: If the CONFIG_USB_STORAGE_ONETOUCH is not
set  */
>> > +     /* onetouch_connect_input(us) will always return 0
     */
>> > +     switch (onetouch_connect_input(us)) {
>> > +     case 0:
>> > +             break;
>> > +     default:
>> > +             printk(KERN_WARNING USB_STORAGE
>> > +                     "Unable to allocate onetouch urb\n");
>> > +     }
>> > +
>> >       /* Kill the control thread.  The SCSI host must
already have been
>> >        * removed so it won't try to queue any more commands.
>> >        */
>> 
>> Looks like you cut & pasted instead of writing the correct
code here.
>>
>
>May we have it converted to "if", pretty please? I don't
think it will
>ever act on return code from onetouch_connect_input.
>
>-- 
>Dmitry
>
>
>-------------------------------------------------------
>SF email is sponsored by - The IT Product Guide
>Read honest & candid reviews on hundreds of IT Products from
real users.
>Discover which products truly live up to the hype. Start
reading now.
>http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
>_______________________________________________
>linux-usb-devel@lists.sourceforge.net
>To unsubscribe, use the last form field at:
>https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
diff -urN -X dontdiff linux-2.6.11/drivers/usb/storage/Kconfig 
linux-2.6.11mod/drivers/usb/storage/Kconfig
--- linux-2.6.11/drivers/usb/storage/Kconfig    2005-03-02 02:38:26.000000000 
-0500
+++ linux-2.6.11mod/drivers/usb/storage/Kconfig 2005-03-07 18:18:27.000000000 
-0500
@@ -118,3 +118,10 @@
          Say Y here to include additional code to support the Lexar Jumpshot
          USB CompactFlash reader.
 
+config USB_STORAGE_ONETOUCH
+       bool "Support OneTouch Button on Maxtor Hard Drives (EXPERIMENTAL)"
+       depends on USB_STORAGE && INPUT_EVDEV && EXPERIMENTAL
+       help
+         Say Y here to include additional code to support the Maxtor OneTouch
+         USB hard drive's onetouch button.
+
diff -urN -X dontdiff linux-2.6.11/drivers/usb/storage/Makefile 
linux-2.6.11mod/drivers/usb/storage/Makefile
--- linux-2.6.11/drivers/usb/storage/Makefile   2005-03-02 02:38:13.000000000 
-0500
+++ linux-2.6.11mod/drivers/usb/storage/Makefile        2005-03-07 
23:45:30.000000000 -0500
@@ -18,6 +18,7 @@
 usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200)   += isd200.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB)  += datafab.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o
+usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o
 
 usb-storage-objs :=    scsiglue.o protocol.o transport.o usb.o \
                        initializers.o $(usb-storage-obj-y)
diff -urN -X dontdiff linux-2.6.11/drivers/usb/storage/onetouch.c 
linux-2.6.11mod/drivers/usb/storage/onetouch.c
--- linux-2.6.11/drivers/usb/storage/onetouch.c 1969-12-31 19:00:00.000000000 
-0500
+++ linux-2.6.11mod/drivers/usb/storage/onetouch.c      2005-03-11 
14:23:43.000000000 -0500
@@ -0,0 +1,253 @@
+/*
+ * Support for the Maxtor OneTouch USB hard drive's button
+ *
+ * Current development and maintenance by:
+ *     Copyright (c) 2005 Nick Sillik <[EMAIL PROTECTED]>
+ *
+ * Initial work by:
+ *     Copyright (c) 2003 Erik Thyrén <[EMAIL PROTECTED]>
+ *
+ * Based on usbmouse.c (Vojtech Pavlik) and xpad.c (Marko Friedemann)
+ *
+ */
+
+/*
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/input.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/smp_lock.h>
+#include <linux/spinlock.h>
+#include <linux/usb.h>
+#include "onetouch.h"
+#include "debug.h"
+
+
+spinlock_t onetouch_list_lock = SPIN_LOCK_UNLOCKED;
+struct usb_onetouch {
+       char name[128];
+       char phys[64];
+       struct input_dev dev;   /* input device interface */
+       struct usb_device *udev;        /* usb device */
+
+       struct urb *irq;        /* urb for interrupt in report */
+       unsigned char *data;    /* input data */
+       dma_addr_t data_dma;
+
+       int open_count;         /* reference count */
+        
+        struct list_head list;
+       struct usb_onetouch *onetouch;
+};
+
+
+
+
+/*
+struct usb_onetouch_wrap {
+       struct list_head list;
+       struct usb_onetouch *onetouch;
+};
+*/
+static LIST_HEAD(onetouch_list);
+
+static void onetouch_irq(struct urb *urb, struct pt_regs *regs)
+{
+       struct usb_onetouch *onetouch = urb->context;
+       int retval;
+
+       switch (urb->status) {
+       case 0:
+               /* success */
+               break;
+       case -ECONNRESET:
+       case -ENOENT:
+       case -ESHUTDOWN:
+               /* this urb is terminated, clean up */
+               dbg("%s - urb shutting down with status: %d", __FUNCTION__,
+                   urb->status);
+               return;
+       default:
+               dbg("%s - nonzero urb status received: %d", __FUNCTION__,
+                   urb->status);
+               goto resubmit;
+       }
+
+       input_regs(&onetouch->dev, regs);
+       /*printk(KERN_INFO "input: %02x %02x\n", onetouch->data[0], 
onetouch->data[1]); */
+       input_report_key(&onetouch->dev, ONETOUCH_BUTTON,
+                        onetouch->data[0] & 0x02);
+
+       input_sync(&onetouch->dev);
+
+      resubmit:
+       retval = usb_submit_urb(urb, GFP_ATOMIC);
+       if (retval)
+               err("%s - usb_submit_urb failed with result %d",
+                   __FUNCTION__, retval);
+}
+
+static int onetouch_open(struct input_dev *dev)
+{
+       struct usb_onetouch *onetouch = dev->private;
+
+       if (onetouch->open_count++)
+               return 0;
+
+       onetouch->irq->dev = onetouch->udev;
+       if (usb_submit_urb(onetouch->irq, GFP_KERNEL)) {
+               onetouch->open_count--;
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static void onetouch_close(struct input_dev *dev)
+{
+       struct usb_onetouch *onetouch = dev->private;
+
+       if (!--onetouch->open_count)
+               usb_kill_urb(onetouch->irq);
+}
+
+int onetouch_connect_input(struct us_data *ss)
+{
+       struct usb_device *udev = ss->pusb_dev;
+       struct usb_onetouch *onetouch;
+       char path[64];
+
+       if (udev->descriptor.idVendor != VENDOR_MAXTOR
+           || udev->descriptor.idProduct != PRODUCT_ONETOUCH) {
+               return 0;       /* Not a onetouch device, nothing to see here */
+       }
+
+
+
+       US_DEBUGP("Connecting OneTouch device\n");
+
+       onetouch = kmalloc(sizeof(struct usb_onetouch), GFP_KERNEL);
+
+       if ((onetouch) == NULL) {
+               err("cannot allocate memory for new onetouch");
+               return -1;
+       }
+       memset(onetouch, 0, sizeof(struct usb_onetouch));
+
+       onetouch->data = usb_buffer_alloc(udev, ONETOUCH_PKT_LEN,
+                                         SLAB_ATOMIC,
+                                         &onetouch->data_dma);
+       if (!onetouch->data) {
+               kfree(onetouch);
+               return -8;
+       }
+
+       onetouch->irq = usb_alloc_urb(0, GFP_KERNEL);
+       if (!onetouch->irq) {
+               err("cannot allocate memory for new onetouch interrupt urb");
+               usb_buffer_free(udev, ONETOUCH_PKT_LEN, onetouch->data,
+                               onetouch->data_dma);
+               kfree(onetouch);
+               return -6;
+       }
+
+       usb_fill_int_urb(onetouch->irq, udev,
+                        ss->recv_intr_pipe,
+                        onetouch->data, ONETOUCH_PKT_LEN, onetouch_irq,
+                        onetouch, ss->ep_bInterval);
+       onetouch->irq->transfer_dma = onetouch->data_dma;
+       onetouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+       onetouch->udev = udev;
+
+       onetouch->dev.id.bustype = BUS_USB;
+       onetouch->dev.id.vendor = udev->descriptor.idVendor;
+       onetouch->dev.id.product = udev->descriptor.idProduct;
+       onetouch->dev.id.version = udev->descriptor.bcdDevice;
+       onetouch->dev.private = onetouch;
+       onetouch->dev.name = onetouch->name;
+       onetouch->dev.phys = onetouch->phys;
+       onetouch->dev.open = onetouch_open;
+       onetouch->dev.close = onetouch_close;
+
+       usb_make_path(udev, path, 64);
+       snprintf(onetouch->phys, 64, "%s/input0", path);
+       snprintf(onetouch->name, 128, "%s %s", ss->vendor, ss->product);
+       if (!strlen(onetouch->name))
+               snprintf(onetouch->name, 128, "Maxtor OneTouch");
+
+       set_bit(EV_KEY, onetouch->dev.evbit);
+       set_bit(ONETOUCH_BUTTON, onetouch->dev.keybit);
+       clear_bit(0, onetouch->dev.keybit);
+
+       input_register_device(&onetouch->dev);
+
+       printk(KERN_INFO "input: %s on %s\n", onetouch->dev.name, path);
+
+       spin_lock(&onetouch_list_lock);
+       list_add(&onetouch->list, &onetouch_list);
+       spin_unlock(&onetouch_list_lock);
+
+
+       return 0;
+}
+
+int onetouch_release_input(struct us_data *ss)
+{
+       struct usb_device *udev = ss->pusb_dev;
+       struct usb_onetouch *onetouch;
+        struct usb_onetouch *entry;
+
+       if (udev->descriptor.idVendor != VENDOR_MAXTOR ||
+           udev->descriptor.idProduct != PRODUCT_ONETOUCH) {
+               return 0;       /* Not a onetouch device, nothing to see here */
+       }
+
+       US_DEBUGP("Trying to release OneTouch device...");
+
+       onetouch = NULL;
+       spin_lock(&onetouch_list_lock);
+       list_for_each_entry(entry, &onetouch_list, list) {
+               if (entry->udev == udev) {
+                       onetouch = entry;
+                       list_del(&onetouch->list);
+                       break;
+               }
+       }
+       spin_unlock(&onetouch_list_lock);
+
+       if (onetouch) {
+                US_DEBUGP("device found: %s. Releasing\n",
+                          onetouch->phys);
+               usb_unlink_urb(onetouch->irq);
+               input_unregister_device(&onetouch->dev);
+               usb_free_urb(onetouch->irq);
+               usb_buffer_free(onetouch->udev, ONETOUCH_PKT_LEN,
+                               onetouch->data, onetouch->data_dma);
+               kfree(onetouch);
+       }
+
+
+       return 0;               /* Should not return anything else (yet)        
                */
+       /* FIXME: In the future this should return something like EBUSY */
+       /* If the things being freed here are being used currently      */
+}
diff -urN -X dontdiff linux-2.6.11/drivers/usb/storage/onetouch.h 
linux-2.6.11mod/drivers/usb/storage/onetouch.h
--- linux-2.6.11/drivers/usb/storage/onetouch.h 1969-12-31 19:00:00.000000000 
-0500
+++ linux-2.6.11mod/drivers/usb/storage/onetouch.h      2005-03-11 
14:00:01.000000000 -0500
@@ -0,0 +1,16 @@
+#ifndef _ONETOUCH_H_
+#define _ONETOUCH_H_
+
+#include <linux/config.h>
+#include <linux/input.h>
+#include "usb.h"
+
+#define ONETOUCH_PKT_LEN        0x02
+#define ONETOUCH_BUTTON         KEY_PROG1
+#define VENDOR_MAXTOR           0x0d49
+#define PRODUCT_ONETOUCH        0x7010
+
+int onetouch_connect_input(struct us_data *ss);
+int onetouch_release_input(struct us_data *ss);
+
+#endif
diff -urN -X dontdiff linux-2.6.11/drivers/usb/storage/usb.c 
linux-2.6.11mod/drivers/usb/storage/usb.c
--- linux-2.6.11/drivers/usb/storage/usb.c      2005-03-02 02:37:50.000000000 
-0500
+++ linux-2.6.11mod/drivers/usb/storage/usb.c   2005-03-11 18:22:11.000000000 
-0500
@@ -87,7 +87,13 @@
 #ifdef CONFIG_USB_STORAGE_JUMPSHOT
 #include "jumpshot.h"
 #endif
-
+#ifdef CONFIG_USB_STORAGE_ONETOUCH
+#include "onetouch.h"
+#endif
+#ifndef CONFIG_USB_STORAGE_ONETOUCH
+static inline int onetouch_connect_input (struct us_data *ss) { return 0; }
+static inline int onetouch_release_input (struct us_data *ss) { return 0; }
+#endif
 
 #include <linux/module.h>
 #include <linux/init.h>
@@ -799,6 +805,14 @@
        /* Set the hostdata to prepare for scanning */
        us->host->hostdata[0] = (unsigned long) us;
 
+        /* Attempt to connect the onetouch urb to the device   */
+       /* Note: If the CONFIG_USB_STORAGE_ONETOUCH is not set  */
+       /* onetouch_connect_input(us) will always return 0      */
+       if (onetouch_connect_input(us) != 0) {
+               printk(KERN_WARNING USB_STORAGE
+                       "Unable to allocate onetouch urb\n");
+       }
+        
        /* Start up our control thread */
        p = kernel_thread(usb_stor_control_thread, us, CLONE_VM);
        if (p < 0) {
@@ -819,6 +833,14 @@
 {
        US_DEBUGP("-- %s\n", __FUNCTION__);
 
+        /* Attempt to connect the onetouch urb to the device   */
+       /* Note: If the CONFIG_USB_STORAGE_ONETOUCH is not set  */
+       /* onetouch_connect_input(us) will always return 0      */
+       if (onetouch_realese_input(us) != 0) {
+               printk(KERN_WARNING USB_STORAGE
+                       "Unable to allocate onetouch urb\n");
+       }
+        
        /* Kill the control thread.  The SCSI host must already have been
         * removed so it won't try to queue any more commands.
         */

Reply via email to