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