cregit-Linux how code gets into the kernel

Release 4.7 drivers/usb/storage/onetouch.c

/*
 * Support for the Maxtor OneTouch USB hard drive's button
 *
 * Current development and maintenance by:
 *      Copyright (c) 2005 Nick Sillik <n.sillik@temple.edu>
 *
 * Initial work by:
 *      Copyright (c) 2003 Erik Thyren <erth7411@student.uu.se>
 *
 * 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/kernel.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/usb/input.h>
#include "usb.h"
#include "debug.h"
#include "scsiglue.h"


#define DRV_NAME "ums-onetouch"

MODULE_DESCRIPTION("Maxtor USB OneTouch hard drive button driver");
MODULE_AUTHOR("Nick Sillik <n.sillik@temple.edu>");
MODULE_LICENSE("GPL");


#define ONETOUCH_PKT_LEN        0x02

#define ONETOUCH_BUTTON         KEY_PROG1

static int onetouch_connect_input(struct us_data *ss);
static void onetouch_release_input(void *onetouch_);


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;
	
unsigned int is_open:1;
};


/*
 * The table of devices
 */

#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
		    vendorName, productName, useProtocol, useTransport, \
		    initFunction, flags) \
{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
  .driver_info = (flags) }


static struct usb_device_id onetouch_usb_ids[] = {
#	include "unusual_onetouch.h"
	{ }		/* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, onetouch_usb_ids);


#undef UNUSUAL_DEV

/*
 * The flags table
 */

#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
		    vendor_name, product_name, use_protocol, use_transport, \
		    init_function, Flags) \
{ \
        .vendorName = vendor_name,      \
        .productName = product_name,    \
        .useProtocol = use_protocol,    \
        .useTransport = use_transport,  \
        .initFunction = init_function,  \
}


static struct us_unusual_dev onetouch_unusual_dev_list[] = {
#	include "unusual_onetouch.h"
	{ }		/* Terminating entry */
};


#undef UNUSUAL_DEV



static void usb_onetouch_irq(struct urb *urb) { struct usb_onetouch *onetouch = urb->context; signed char *data = onetouch->data; struct input_dev *dev = onetouch->dev; int status = urb->status; int retval; switch (status) { case 0: /* success */ break; case -ECONNRESET: /* unlink */ case -ENOENT: case -ESHUTDOWN: return; /* -EPIPE: should clear the halt */ default: /* error */ goto resubmit; } input_report_key(dev, ONETOUCH_BUTTON, data[0] & 0x02); input_sync(dev); resubmit: retval = usb_submit_urb (urb, GFP_ATOMIC); if (retval) dev_err(&dev->dev, "can't resubmit intr, %s-%s/input0, " "retval %d\n", onetouch->udev->bus->bus_name, onetouch->udev->devpath, retval); }

Contributors

PersonTokensPropCommitsCommitProp
matthew dharmmatthew dharm12186.43%125.00%
greg kroah-hartmangreg kroah-hartman1812.86%250.00%
christoph lameterchristoph lameter10.71%125.00%
Total140100.00%4100.00%


static int usb_onetouch_open(struct input_dev *dev) { struct usb_onetouch *onetouch = input_get_drvdata(dev); onetouch->is_open = 1; onetouch->irq->dev = onetouch->udev; if (usb_submit_urb(onetouch->irq, GFP_KERNEL)) { dev_err(&dev->dev, "usb_submit_urb failed\n"); return -EIO; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
matthew dharmmatthew dharm5785.07%250.00%
greg kroah-hartmangreg kroah-hartman710.45%125.00%
dmitry torokhovdmitry torokhov34.48%125.00%
Total67100.00%4100.00%


static void usb_onetouch_close(struct input_dev *dev) { struct usb_onetouch *onetouch = input_get_drvdata(dev); usb_kill_urb(onetouch->irq); onetouch->is_open = 0; }

Contributors

PersonTokensPropCommitsCommitProp
matthew dharmmatthew dharm3191.18%266.67%
dmitry torokhovdmitry torokhov38.82%133.33%
Total34100.00%3100.00%

#ifdef CONFIG_PM
static void usb_onetouch_pm_hook(struct us_data *us, int action) { struct usb_onetouch *onetouch = (struct usb_onetouch *) us->extra; if (onetouch->is_open) { switch (action) { case US_SUSPEND: usb_kill_urb(onetouch->irq); break; case US_RESUME: if (usb_submit_urb(onetouch->irq, GFP_NOIO) != 0) dev_err(&onetouch->irq->dev->dev, "usb_submit_urb failed\n"); break; default: break; } } }

Contributors

PersonTokensPropCommitsCommitProp
matthew dharmmatthew dharm7486.05%250.00%
greg kroah-hartmangreg kroah-hartman1112.79%125.00%
oliver neukumoliver neukum11.16%125.00%
Total86100.00%4100.00%

#endif /* CONFIG_PM */
static int onetouch_connect_input(struct us_data *ss) { struct usb_device *udev = ss->pusb_dev; struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct usb_onetouch *onetouch; struct input_dev *input_dev; int pipe, maxp; int error = -ENOMEM; interface = ss->pusb_intf->cur_altsetting; if (interface->desc.bNumEndpoints != 3) return -ENODEV; endpoint = &interface->endpoint[2].desc; if (!usb_endpoint_is_int_in(endpoint)) return -ENODEV; pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress); maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); maxp = min(maxp, ONETOUCH_PKT_LEN); onetouch = kzalloc(sizeof(struct usb_onetouch), GFP_KERNEL); input_dev = input_allocate_device(); if (!onetouch || !input_dev) goto fail1; onetouch->data = usb_alloc_coherent(udev, ONETOUCH_PKT_LEN, GFP_KERNEL, &onetouch->data_dma); if (!onetouch->data) goto fail1; onetouch->irq = usb_alloc_urb(0, GFP_KERNEL); if (!onetouch->irq) goto fail2; onetouch->udev = udev; onetouch->dev = input_dev; if (udev->manufacturer) strlcpy(onetouch->name, udev->manufacturer, sizeof(onetouch->name)); if (udev->product) { if (udev->manufacturer) strlcat(onetouch->name, " ", sizeof(onetouch->name)); strlcat(onetouch->name, udev->product, sizeof(onetouch->name)); } if (!strlen(onetouch->name)) snprintf(onetouch->name, sizeof(onetouch->name), "Maxtor Onetouch %04x:%04x", le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct)); usb_make_path(udev, onetouch->phys, sizeof(onetouch->phys)); strlcat(onetouch->phys, "/input0", sizeof(onetouch->phys)); input_dev->name = onetouch->name; input_dev->phys = onetouch->phys; usb_to_input_id(udev, &input_dev->id); input_dev->dev.parent = &udev->dev; set_bit(EV_KEY, input_dev->evbit); set_bit(ONETOUCH_BUTTON, input_dev->keybit); clear_bit(0, input_dev->keybit); input_set_drvdata(input_dev, onetouch); input_dev->open = usb_onetouch_open; input_dev->close = usb_onetouch_close; usb_fill_int_urb(onetouch->irq, udev, pipe, onetouch->data, maxp, usb_onetouch_irq, onetouch, endpoint->bInterval); onetouch->irq->transfer_dma = onetouch->data_dma; onetouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; ss->extra_destructor = onetouch_release_input; ss->extra = onetouch; #ifdef CONFIG_PM ss->suspend_resume_hook = usb_onetouch_pm_hook; #endif error = input_register_device(onetouch->dev); if (error) goto fail3; return 0; fail3: usb_free_urb(onetouch->irq); fail2: usb_free_coherent(udev, ONETOUCH_PKT_LEN, onetouch->data, onetouch->data_dma); fail1: kfree(onetouch); input_free_device(input_dev); return error; }

Contributors

PersonTokensPropCommitsCommitProp
matthew dharmmatthew dharm32456.06%218.18%
dmitry torokhovdmitry torokhov21837.72%327.27%
nick silliknick sillik203.46%19.09%
dan carpenterdan carpenter91.56%19.09%
luiz fernando capitulinoluiz fernando capitulino30.52%19.09%
daniel mackdaniel mack20.35%19.09%
alan sternalan stern10.17%19.09%
oliver neukumoliver neukum10.17%19.09%
Total578100.00%11100.00%


static void onetouch_release_input(void *onetouch_) { struct usb_onetouch *onetouch = (struct usb_onetouch *) onetouch_; if (onetouch) { usb_kill_urb(onetouch->irq); input_unregister_device(onetouch->dev); usb_free_urb(onetouch->irq); usb_free_coherent(onetouch->udev, ONETOUCH_PKT_LEN, onetouch->data, onetouch->data_dma); } }

Contributors

PersonTokensPropCommitsCommitProp
matthew dharmmatthew dharm6496.97%133.33%
daniel mackdaniel mack11.52%133.33%
adrian bunkadrian bunk11.52%133.33%
Total66100.00%3100.00%

static struct scsi_host_template onetouch_host_template;
static int onetouch_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct us_data *us; int result; result = usb_stor_probe1(&us, intf, id, (id - onetouch_usb_ids) + onetouch_unusual_dev_list, &onetouch_host_template); if (result) return result; /* Use default transport and protocol */ result = usb_stor_probe2(us); return result; }

Contributors

PersonTokensPropCommitsCommitProp
alan sternalan stern6395.45%150.00%
akinobu mitaakinobu mita34.55%150.00%
Total66100.00%2100.00%

static struct usb_driver onetouch_driver = { .name = DRV_NAME, .probe = onetouch_probe, .disconnect = usb_stor_disconnect, .suspend = usb_stor_suspend, .resume = usb_stor_resume, .reset_resume = usb_stor_reset_resume, .pre_reset = usb_stor_pre_reset, .post_reset = usb_stor_post_reset, .id_table = onetouch_usb_ids, .soft_unbind = 1, .no_dynamic_id = 1, }; module_usb_stor_driver(onetouch_driver, onetouch_host_template, DRV_NAME);

Overall Contributors

PersonTokensPropCommitsCommitProp
matthew dharmmatthew dharm75356.36%28.70%
alan sternalan stern23417.51%14.35%
dmitry torokhovdmitry torokhov22616.92%313.04%
greg kroah-hartmangreg kroah-hartman372.77%313.04%
nick silliknick sillik221.65%14.35%
akinobu mitaakinobu mita211.57%14.35%
maciej grelamaciej grela151.12%14.35%
dan carpenterdan carpenter90.67%14.35%
huajun lihuajun li50.37%14.35%
daniel mackdaniel mack30.22%14.35%
luiz fernando capitulinoluiz fernando capitulino30.22%14.35%
oliver neukumoliver neukum20.15%28.70%
adrian bunkadrian bunk20.15%14.35%
sebastian andrzej siewiorsebastian andrzej siewior10.07%14.35%
david brownelldavid brownell10.07%14.35%
christoph lameterchristoph lameter10.07%14.35%
felipe balbifelipe balbi10.07%14.35%
Total1336100.00%23100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}