aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/storage
diff options
context:
space:
mode:
authorMatthew Dharm <mdharm-usb@one-eyed-alien.net>2005-07-28 17:49:01 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-09-08 19:22:55 -0400
commit34008dbfe8c00eca67f97bad484eb5cb03bafe66 (patch)
tree72b7a8dc823dc1f1e77041025c7572499e65db64 /drivers/usb/storage
parent26186ba77b493204ae0fadc3c88a67b14f22168f (diff)
[PATCH] USB Storage: add support for Maxtor One-Touch button
This patch is originally from Nick Sillik, and has been rediffed against the latest tree. This patch adds usability to the OneTouch Button on Maxtor External USB Hard Drives. Using an unusual device entry it declares an extra init function which claims the interrupt endpoint associated with this button. The button is connected to the input system. Signed-off-by: Nick Sillik <n.sillik@temple.edu> Signed-off-by: Matthew Dharm <mdharm-usb@one-eyed-alien.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/storage')
-rw-r--r--drivers/usb/storage/Kconfig12
-rw-r--r--drivers/usb/storage/Makefile1
-rw-r--r--drivers/usb/storage/onetouch.c205
-rw-r--r--drivers/usb/storage/onetouch.h9
-rw-r--r--drivers/usb/storage/unusual_devs.h12
-rw-r--r--drivers/usb/storage/usb.c4
6 files changed, 242 insertions, 1 deletions
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
index f1f1c0608c22..bb9819cc8826 100644
--- a/drivers/usb/storage/Kconfig
+++ b/drivers/usb/storage/Kconfig
@@ -111,3 +111,15 @@ config USB_STORAGE_JUMPSHOT
111 Say Y here to include additional code to support the Lexar Jumpshot 111 Say Y here to include additional code to support the Lexar Jumpshot
112 USB CompactFlash reader. 112 USB CompactFlash reader.
113 113
114
115config USB_STORAGE_ONETOUCH
116 bool "Support OneTouch Button on Maxtor Hard Drives (EXPERIMENTAL)"
117 depends on USB_STORAGE && INPUT_EVDEV && EXPERIMENTAL
118 help
119 Say Y here to include additional code to support the Maxtor OneTouch
120 USB hard drive's onetouch button.
121
122 This code registers the button on the front of Maxtor OneTouch USB
123 hard drive's as an input device. An action can be associated with
124 this input in any keybinding software. (e.g. gnome's keyboard short-
125 cuts)
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile
index 56652ccc2881..44ab8f9978fe 100644
--- a/drivers/usb/storage/Makefile
+++ b/drivers/usb/storage/Makefile
@@ -18,6 +18,7 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_DPCM) += dpcm.o
18usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200) += isd200.o 18usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200) += isd200.o
19usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB) += datafab.o 19usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB) += datafab.o
20usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o 20usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o
21usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o
21 22
22usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ 23usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \
23 initializers.o $(usb-storage-obj-y) 24 initializers.o $(usb-storage-obj-y)
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c
new file mode 100644
index 000000000000..07fd29ceb347
--- /dev/null
+++ b/drivers/usb/storage/onetouch.c
@@ -0,0 +1,205 @@
1/*
2 * Support for the Maxtor OneTouch USB hard drive's button
3 *
4 * Current development and maintenance by:
5 * Copyright (c) 2005 Nick Sillik <n.sillik@temple.edu>
6 *
7 * Initial work by:
8 * Copyright (c) 2003 Erik Thyrén <erth7411@student.uu.se>
9 *
10 * Based on usbmouse.c (Vojtech Pavlik) and xpad.c (Marko Friedemann)
11 *
12 */
13
14/*
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 *
29 */
30
31#include <linux/config.h>
32#include <linux/kernel.h>
33#include <linux/input.h>
34#include <linux/init.h>
35#include <linux/slab.h>
36#include <linux/module.h>
37#include <linux/usb.h>
38#include "usb.h"
39#include "onetouch.h"
40#include "debug.h"
41
42void onetouch_release_input(void *onetouch_);
43
44struct usb_onetouch {
45 char name[128];
46 char phys[64];
47 struct input_dev dev; /* input device interface */
48 struct usb_device *udev; /* usb device */
49
50 struct urb *irq; /* urb for interrupt in report */
51 unsigned char *data; /* input data */
52 dma_addr_t data_dma;
53};
54
55static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs)
56{
57 struct usb_onetouch *onetouch = urb->context;
58 signed char *data = onetouch->data;
59 struct input_dev *dev = &onetouch->dev;
60 int status;
61
62 switch (urb->status) {
63 case 0: /* success */
64 break;
65 case -ECONNRESET: /* unlink */
66 case -ENOENT:
67 case -ESHUTDOWN:
68 return;
69 /* -EPIPE: should clear the halt */
70 default: /* error */
71 goto resubmit;
72 }
73
74 input_regs(dev, regs);
75
76 input_report_key(&onetouch->dev, ONETOUCH_BUTTON,
77 data[0] & 0x02);
78
79 input_sync(dev);
80resubmit:
81 status = usb_submit_urb (urb, SLAB_ATOMIC);
82 if (status)
83 err ("can't resubmit intr, %s-%s/input0, status %d",
84 onetouch->udev->bus->bus_name,
85 onetouch->udev->devpath, status);
86}
87
88static int usb_onetouch_open(struct input_dev *dev)
89{
90 struct usb_onetouch *onetouch = dev->private;
91
92 onetouch->irq->dev = onetouch->udev;
93 if (usb_submit_urb(onetouch->irq, GFP_KERNEL)) {
94 err("usb_submit_urb failed");
95 return -EIO;
96 }
97
98 return 0;
99}
100
101static void usb_onetouch_close(struct input_dev *dev)
102{
103 struct usb_onetouch *onetouch = dev->private;
104
105 usb_kill_urb(onetouch->irq);
106}
107
108int onetouch_connect_input(struct us_data *ss)
109{
110 struct usb_device *udev = ss->pusb_dev;
111 struct usb_host_interface *interface;
112 struct usb_endpoint_descriptor *endpoint;
113 struct usb_onetouch *onetouch;
114 int pipe, maxp;
115 char path[64];
116
117 interface = ss->pusb_intf->cur_altsetting;
118
119 endpoint = &interface->endpoint[2].desc;
120 if(!(endpoint->bEndpointAddress & 0x80))
121 return -ENODEV;
122 if((endpoint->bmAttributes & 3) != 3)
123 return -ENODEV;
124
125 pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
126 maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
127
128 if (!(onetouch = kcalloc(1, sizeof(struct usb_onetouch), GFP_KERNEL)))
129 return -ENOMEM;
130
131 onetouch->data = usb_buffer_alloc(udev, ONETOUCH_PKT_LEN, SLAB_ATOMIC, &onetouch->data_dma);
132 if (!onetouch->data){
133 kfree(onetouch);
134 return -ENOMEM;
135 }
136
137 onetouch->irq = usb_alloc_urb(0, GFP_KERNEL);
138 if (!onetouch->irq){
139 kfree(onetouch);
140 usb_buffer_free(udev, ONETOUCH_PKT_LEN, onetouch->data, onetouch->data_dma);
141 return -ENODEV;
142 }
143
144
145 onetouch->udev = udev;
146
147 set_bit(EV_KEY, onetouch->dev.evbit);
148 set_bit(ONETOUCH_BUTTON, onetouch->dev.keybit);
149 clear_bit(0, onetouch->dev.keybit);
150
151 onetouch->dev.private = onetouch;
152 onetouch->dev.open = usb_onetouch_open;
153 onetouch->dev.close = usb_onetouch_close;
154
155 usb_make_path(udev, path, 64);
156 sprintf(onetouch->phys, "%s/input0", path);
157
158 onetouch->dev.name = onetouch->name;
159 onetouch->dev.phys = onetouch->phys;
160
161 onetouch->dev.id.bustype = BUS_USB;
162 onetouch->dev.id.vendor = le16_to_cpu(udev->descriptor.idVendor);
163 onetouch->dev.id.product = le16_to_cpu(udev->descriptor.idProduct);
164 onetouch->dev.id.version = le16_to_cpu(udev->descriptor.bcdDevice);
165
166 onetouch->dev.dev = &udev->dev;
167
168 if (udev->manufacturer)
169 strcat(onetouch->name, udev->manufacturer);
170 if (udev->product)
171 sprintf(onetouch->name, "%s %s", onetouch->name,
172 udev->product);
173 if (!strlen(onetouch->name))
174 sprintf(onetouch->name, "Maxtor Onetouch %04x:%04x",
175 onetouch->dev.id.vendor, onetouch->dev.id.product);
176
177 usb_fill_int_urb(onetouch->irq, udev, pipe, onetouch->data,
178 (maxp > 8 ? 8 : maxp),
179 usb_onetouch_irq, onetouch, endpoint->bInterval);
180 onetouch->irq->transfer_dma = onetouch->data_dma;
181 onetouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
182
183 ss->extra_destructor = onetouch_release_input;
184 ss->extra = onetouch;
185
186 input_register_device(&onetouch->dev);
187 printk(KERN_INFO "usb-input: %s on %s\n", onetouch->dev.name, path);
188
189 return 0;
190}
191
192void onetouch_release_input(void *onetouch_)
193{
194 struct usb_onetouch *onetouch = (struct usb_onetouch *) onetouch_;
195
196 if (onetouch) {
197 usb_kill_urb(onetouch->irq);
198 input_unregister_device(&onetouch->dev);
199 usb_free_urb(onetouch->irq);
200 usb_buffer_free(onetouch->udev, ONETOUCH_PKT_LEN,
201 onetouch->data, onetouch->data_dma);
202 printk(KERN_INFO "Maxtor Onetouch %04x:%04x Deregistered\n",
203 onetouch->dev.id.vendor, onetouch->dev.id.product);
204 }
205}
diff --git a/drivers/usb/storage/onetouch.h b/drivers/usb/storage/onetouch.h
new file mode 100644
index 000000000000..41c7aa8f0446
--- /dev/null
+++ b/drivers/usb/storage/onetouch.h
@@ -0,0 +1,9 @@
1#ifndef _ONETOUCH_H_
2#define _ONETOUCH_H_
3
4#define ONETOUCH_PKT_LEN 0x02
5#define ONETOUCH_BUTTON KEY_PROG1
6
7int onetouch_connect_input(struct us_data *ss);
8
9#endif
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index e7ed8351f6ea..ad0cfd7a782f 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -936,6 +936,18 @@ UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
936 US_FL_SINGLE_LUN ), 936 US_FL_SINGLE_LUN ),
937#endif 937#endif
938 938
939/* Submitted by: Nick Sillik <n.sillik@temple.edu>
940 * Needed for OneTouch extension to usb-storage
941 *
942 */
943#ifdef CONFIG_USB_STORAGE_ONETOUCH
944 UNUSUAL_DEV( 0x0d49, 0x7010, 0x0000, 0x9999,
945 "Maxtor",
946 "OneTouch External Harddrive",
947 US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input,
948 0),
949#endif
950
939/* Submitted by Joris Struyve <joris@struyve.be> */ 951/* Submitted by Joris Struyve <joris@struyve.be> */
940UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff, 952UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff,
941 "Medion", 953 "Medion",
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 97b9ebb8a082..cb4c770baf32 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -90,7 +90,9 @@
90#ifdef CONFIG_USB_STORAGE_JUMPSHOT 90#ifdef CONFIG_USB_STORAGE_JUMPSHOT
91#include "jumpshot.h" 91#include "jumpshot.h"
92#endif 92#endif
93 93#ifdef CONFIG_USB_STORAGE_ONETOUCH
94#include "onetouch.h"
95#endif
94 96
95/* Some informational data */ 97/* Some informational data */
96MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); 98MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>");