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
pgpu2GPnc60VB.pgp
Description: PGP signature
