You're going to need to rediff this against the latest patches that
re-organize how some of the internal data structures are allocated (which
gives us refcounting).

Also, could you use the unusual_devs.h init functions instead?  Or does
that not work out for some reason?  This may also be a good time for us to
introduce some sort of exit function along the same lines...

Matt

On Sat, Mar 19, 2005 at 07:27:25PM -0500, Nick Sillik wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Here is my final version of the patch to add usability for the onetouch button
> on Maxtor Onetouch External Drives. I have made fixes that Alan Stern, Greg 
> KH,
> and others have suggested.
> 
> This includes the following (partial) list of changes this list requested:
> - -Locking the onetouch device list
> - -Removing the wrap struct and putting it's members in the onetouch struct
> - -Removing the case from usb.c and replacing it with an if
> 
> Signed-off-by: Nick Sillik <[EMAIL PROTECTED]>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.2.5 (GNU/Linux)
> 
> iD8DBQFCPMNt2hKwjhIv2aMRArx1AJ4xaV8UWjWMwwkyZjjRQZAl25HAIgCgwji2
> ImxosBNBhMQmZWgRs5yxPjc=
> =mHIl
> -----END PGP SIGNATURE-----

> 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.
>        */
> 


-- 
Matthew Dharm                              Home: [EMAIL PROTECTED] 
Maintainer, Linux USB Mass Storage Driver

I'm just trying to think of a way to say "up yours" without getting fired.
                                        -- Stef
User Friendly, 10/8/1998

Attachment: pgpu2GPnc60VB.pgp
Description: PGP signature

Reply via email to