[2.6 patch] remove drivers/usb/image/hpusbscsi.c

From: Adrian Bunk
Date: Thu Mar 03 2005 - 08:44:06 EST


USB_HPUSBSCSI was marked as BROKEN in 2.6.11 since libsane is the
preferred way to access these devices.

Unless someone plans to resurrect this driver, I'm therefore proposing
this patch to completely remove it.

Signed-off-by: Adrian Bunk <bunk@xxxxxxxxx>

---

drivers/usb/Makefile | 1
drivers/usb/image/Kconfig | 11
drivers/usb/image/Makefile | 1
drivers/usb/image/hpusbscsi.c | 523 ----------------------------------
drivers/usb/image/hpusbscsi.h | 73 ----
5 files changed, 609 deletions(-)

--- linux-2.6.11-rc5-mm1-full/drivers/usb/image/Kconfig.old 2005-03-02 15:59:34.000000000 +0100
+++ linux-2.6.11-rc5-mm1-full/drivers/usb/image/Kconfig 2005-03-03 14:24:33.000000000 +0100
@@ -28,14 +28,3 @@
The scanner will appear as a scsi generic device to the rest
of the system. Scsi support is required.
This driver can be compiled as a module, called microtek.
-
-config USB_HPUSBSCSI
- tristate "HP53xx USB scanner support"
- depends on USB && SCSI && BROKEN
- help
- Say Y here if you want support for the HP 53xx series of scanners
- and the Minolta Scan Dual.
- The scanner will be accessible as a SCSI device.
- Please note that recent versions of SANE use usbfs, not this driver.
- This can be compiled as a module, called hpusbscsi.
-
--- linux-2.6.11-rc5-mm1-full/drivers/usb/Makefile.old 2005-03-02 16:02:10.000000000 +0100
+++ linux-2.6.11-rc5-mm1-full/drivers/usb/Makefile 2005-03-02 16:02:18.000000000 +0100
@@ -51,7 +51,6 @@
obj-$(CONFIG_USB_RTL8150) += net/
obj-$(CONFIG_USB_USBNET) += net/

-obj-$(CONFIG_USB_HPUSBSCSI) += image/
obj-$(CONFIG_USB_MDC800) += image/
obj-$(CONFIG_USB_MICROTEK) += image/

--- linux-2.6.11-rc5-mm1-full/drivers/usb/image/Makefile.old 2005-03-02 16:02:26.000000000 +0100
+++ linux-2.6.11-rc5-mm1-full/drivers/usb/image/Makefile 2005-03-02 16:02:30.000000000 +0100
@@ -3,5 +3,4 @@
#

obj-$(CONFIG_USB_MDC800) += mdc800.o
-obj-$(CONFIG_USB_HPUSBSCSI) += hpusbscsi.o
obj-$(CONFIG_USB_MICROTEK) += microtek.o
--- linux-2.6.11-rc5-mm1-full/drivers/usb/image/hpusbscsi.h 2004-12-24 22:33:59.000000000 +0100
+++ /dev/null 2004-11-25 03:16:25.000000000 +0100
@@ -1,73 +0,0 @@
-/* Header file for the hpusbscsi driver */
-/* (C) Copyright 2001 Oliver Neukum */
-/* sponsored by the Linux Usb Project */
-/* large parts based on or taken from code by John Fremlin and Matt Dharm */
-/* this file is licensed under the GPL */
-
-/* A big thanks to Jose for untiring testing */
-
-typedef void (*scsi_callback)(Scsi_Cmnd *);
-
-#define SENSE_COMMAND_SIZE 6
-#define HPUSBSCSI_SENSE_LENGTH 0x16
-
-struct hpusbscsi
-{
- struct usb_device *dev; /* NULL indicates unplugged device */
- int ep_out;
- int ep_in;
- int ep_int;
- int interrupt_interval;
- int number;
- int fragment;
- struct Scsi_Host *host;
-
- scsi_callback scallback;
- Scsi_Cmnd *srb;
-
-
- wait_queue_head_t pending;
- wait_queue_head_t deathrow;
-
- struct urb *dataurb;
- struct urb *controlurb;
-
-
- int state;
- int current_data_pipe;
- u8 sense_command[SENSE_COMMAND_SIZE];
- u8 scsi_state_byte;
-};
-
-#define SCSI_ERR_MASK ~0x3fu
-
-static const unsigned char scsi_command_direction[256/8] = {
- 0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77,
- 0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-#define DIRECTION_IS_IN(x) ((scsi_command_direction[x>>3] >> (x & 7)) & 1)
-
-static void simple_command_callback(struct urb *u, struct pt_regs *regs);
-static void scatter_gather_callback(struct urb *u, struct pt_regs *regs);
-static void simple_payload_callback (struct urb *u, struct pt_regs *regs);
-static void request_sense_callback (struct urb *u, struct pt_regs *regs);
-static void control_interrupt_callback (struct urb *u, struct pt_regs *regs);
-static void simple_done (struct urb *u, struct pt_regs *regs);
-static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback);
-static int hpusbscsi_scsi_host_reset (Scsi_Cmnd *srb);
-static int hpusbscsi_scsi_abort (Scsi_Cmnd *srb);
-static void issue_request_sense (struct hpusbscsi *hpusbscsi);
-
-/* defines for internal driver state */
-#define HP_STATE_FREE 0 /*ready for next request */
-#define HP_STATE_BEGINNING 1 /*command being transferred */
-#define HP_STATE_WORKING 2 /* data transfer stage */
-#define HP_STATE_ERROR 3 /* error has been reported */
-#define HP_STATE_WAIT 4 /* waiting for status transfer */
-#define HP_STATE_PREMATURE 5 /* status prematurely reported */
-
-
-
--- linux-2.6.11-rc5-mm1-full/drivers/usb/image/hpusbscsi.c 2004-12-24 22:35:40.000000000 +0100
+++ /dev/null 2004-11-25 03:16:25.000000000 +0100
@@ -1,523 +0,0 @@
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/usb.h>
-#include <asm/atomic.h>
-#include <linux/blkdev.h>
-#include "../../scsi/scsi.h"
-#include <scsi/scsi_host.h>
-
-#include "hpusbscsi.h"
-
-#define DEBUG(x...) \
- printk( KERN_DEBUG x )
-
-static char *states[]={"FREE", "BEGINNING", "WORKING", "ERROR", "WAIT", "PREMATURE"};
-
-#define TRACE_STATE printk(KERN_DEBUG"hpusbscsi->state = %s at line %d\n", states[hpusbscsi->state], __LINE__)
-
-static Scsi_Host_Template hpusbscsi_scsi_host_template = {
- .module = THIS_MODULE,
- .name = "hpusbscsi",
- .proc_name = "hpusbscsi",
- .queuecommand = hpusbscsi_scsi_queuecommand,
- .eh_abort_handler = hpusbscsi_scsi_abort,
- .eh_host_reset_handler = hpusbscsi_scsi_host_reset,
- .sg_tablesize = SG_ALL,
- .can_queue = 1,
- .this_id = -1,
- .cmd_per_lun = 1,
- .use_clustering = 1,
- .emulated = 1,
-};
-
-static int
-hpusbscsi_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct usb_device *dev = interface_to_usbdev(intf);
- struct usb_host_interface *altsetting = intf->cur_altsetting;
- struct hpusbscsi *new;
- int error = -ENOMEM;
- int i;
-
- if (altsetting->desc.bNumEndpoints != 3) {
- printk (KERN_ERR "Wrong number of endpoints\n");
- return -ENODEV;
- }
-
- new = kmalloc(sizeof(struct hpusbscsi), GFP_KERNEL);
- if (!new)
- return -ENOMEM;
- memset(new, 0, sizeof(struct hpusbscsi));
- new->dataurb = usb_alloc_urb(0, GFP_KERNEL);
- if (!new->dataurb)
- goto out_kfree;
- new->controlurb = usb_alloc_urb(0, GFP_KERNEL);
- if (!new->controlurb)
- goto out_free_dataurb;
-
- new->dev = dev;
- init_waitqueue_head(&new->pending);
- init_waitqueue_head(&new->deathrow);
-
- error = -ENODEV;
- for (i = 0; i < altsetting->desc.bNumEndpoints; i++) {
- if ((altsetting->endpoint[i].desc.
- bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
- USB_ENDPOINT_XFER_BULK) {
- if (altsetting->endpoint[i].desc.
- bEndpointAddress & USB_DIR_IN) {
- new->ep_in =
- altsetting->endpoint[i].desc.
- bEndpointAddress &
- USB_ENDPOINT_NUMBER_MASK;
- } else {
- new->ep_out =
- altsetting->endpoint[i].desc.
- bEndpointAddress &
- USB_ENDPOINT_NUMBER_MASK;
- }
- } else {
- new->ep_int =
- altsetting->endpoint[i].desc.
- bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
- new->interrupt_interval= altsetting->endpoint[i].desc.
- bInterval;
- }
- }
-
- /* build and submit an interrupt URB for status byte handling */
- usb_fill_int_urb(new->controlurb, new->dev,
- usb_rcvintpipe(new->dev, new->ep_int),
- &new->scsi_state_byte, 1,
- control_interrupt_callback,new,
- new->interrupt_interval);
-
- if (usb_submit_urb(new->controlurb, GFP_KERNEL) < 0)
- goto out_free_controlurb;
-
- /* In host->hostdata we store a pointer to desc */
- new->host = scsi_host_alloc(&hpusbscsi_scsi_host_template, sizeof(new));
- if (!new->host)
- goto out_kill_controlurb;
-
- new->host->hostdata[0] = (unsigned long)new;
- scsi_add_host(new->host, &intf->dev); /* XXX handle failure */
- scsi_scan_host(new->host);
-
- new->sense_command[0] = REQUEST_SENSE;
- new->sense_command[4] = HPUSBSCSI_SENSE_LENGTH;
-
- usb_set_intfdata(intf, new);
- return 0;
-
- out_kill_controlurb:
- usb_kill_urb(new->controlurb);
- out_free_controlurb:
- usb_free_urb(new->controlurb);
- out_free_dataurb:
- usb_free_urb(new->dataurb);
- out_kfree:
- kfree(new);
- return error;
-}
-
-static void
-hpusbscsi_usb_disconnect(struct usb_interface *intf)
-{
- struct hpusbscsi *desc = usb_get_intfdata(intf);
-
- usb_set_intfdata(intf, NULL);
-
- scsi_remove_host(desc->host);
- usb_kill_urb(desc->controlurb);
- scsi_host_put(desc->host);
-
- usb_free_urb(desc->controlurb);
- usb_free_urb(desc->dataurb);
- kfree(desc);
-}
-
-static struct usb_device_id hpusbscsi_usb_ids[] = {
- {USB_DEVICE (0x03f0, 0x0701)}, /* HP 53xx */
- {USB_DEVICE (0x03f0, 0x0801)}, /* HP 7400 */
- {USB_DEVICE (0x0638, 0x0268)}, /*iVina 1200U */
- {USB_DEVICE (0x0638, 0x026a)}, /*Scan Dual II */
- {USB_DEVICE (0x0638, 0x0A13)}, /*Avision AV600U */
- {USB_DEVICE (0x0638, 0x0A16)}, /*Avision DS610CU Scancopier */
- {USB_DEVICE (0x0638, 0x0A18)}, /*Avision AV600U Plus */
- {USB_DEVICE (0x0638, 0x0A23)}, /*Avision AV220 */
- {USB_DEVICE (0x0638, 0x0A24)}, /*Avision AV210 */
- {USB_DEVICE (0x0686, 0x4004)}, /*Minolta Elite II */
- {} /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE (usb, hpusbscsi_usb_ids);
-MODULE_LICENSE("GPL");
-
-
-static struct usb_driver hpusbscsi_usb_driver = {
- .owner = THIS_MODULE,
- .name ="hpusbscsi",
- .probe =hpusbscsi_usb_probe,
- .disconnect =hpusbscsi_usb_disconnect,
- .id_table =hpusbscsi_usb_ids,
-};
-
-/* module initialisation */
-
-static int __init
-hpusbscsi_init (void)
-{
- return usb_register(&hpusbscsi_usb_driver);
-}
-
-static void __exit
-hpusbscsi_exit (void)
-{
- usb_deregister(&hpusbscsi_usb_driver);
-}
-
-module_init (hpusbscsi_init);
-module_exit (hpusbscsi_exit);
-
-static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback)
-{
- struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->device->host->hostdata[0]);
- usb_complete_t usb_callback;
- int res;
-
- /* we don't answer for anything but our single device on any faked host controller */
- if ( srb->device->lun || srb->device->id || srb->device->channel ) {
- if (callback) {
- srb->result = DID_BAD_TARGET;
- callback(srb);
- }
- goto out;
- }
-
- /* Now we need to decide which callback to give to the urb we send the command with */
-
- if (!srb->bufflen) {
- if (srb->cmnd[0] == REQUEST_SENSE){
- hpusbscsi->current_data_pipe = usb_rcvbulkpipe(hpusbscsi->dev, hpusbscsi->ep_in);
- usb_callback = request_sense_callback;
- } else {
- usb_callback = simple_command_callback;
- }
- } else {
- if (likely(srb->use_sg)) {
- usb_callback = scatter_gather_callback;
- hpusbscsi->fragment = 0;
- } else {
- usb_callback = simple_payload_callback;
- }
- /* Now we find out which direction data is to be transferred in */
- hpusbscsi->current_data_pipe = DIRECTION_IS_IN(srb->cmnd[0]) ?
- usb_rcvbulkpipe(hpusbscsi->dev, hpusbscsi->ep_in)
- :
- usb_sndbulkpipe(hpusbscsi->dev, hpusbscsi->ep_out)
- ;
- }
-
-
- TRACE_STATE;
-
- /* We zero the sense buffer to avoid confusing user space */
- memset(srb->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
-
- hpusbscsi->state = HP_STATE_BEGINNING;
- TRACE_STATE;
-
- /* We prepare the urb for writing out the scsi command */
- usb_fill_bulk_urb(
- hpusbscsi->dataurb,
- hpusbscsi->dev,
- usb_sndbulkpipe(hpusbscsi->dev,hpusbscsi->ep_out),
- srb->cmnd,
- srb->cmd_len,
- usb_callback,
- hpusbscsi
- );
- hpusbscsi->scallback = callback;
- hpusbscsi->srb = srb;
-
- res = usb_submit_urb(hpusbscsi->dataurb, GFP_ATOMIC);
- if (unlikely(res)) {
- hpusbscsi->state = HP_STATE_FREE;
- TRACE_STATE;
- if (likely(callback != NULL)) {
- srb->result = DID_ERROR;
- callback(srb);
- }
- }
-
-out:
- return 0;
-}
-
-static int hpusbscsi_scsi_host_reset (Scsi_Cmnd *srb)
-{
- struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->device->host->hostdata[0]);
-
- printk(KERN_DEBUG"SCSI reset requested.\n");
- //usb_reset_device(hpusbscsi->dev);
- //printk(KERN_DEBUG"SCSI reset completed.\n");
- hpusbscsi->state = HP_STATE_FREE;
-
- return 0;
-}
-
-static int hpusbscsi_scsi_abort (Scsi_Cmnd *srb)
-{
- struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->device->host->hostdata[0]);
- printk(KERN_DEBUG"Requested is canceled.\n");
-
- usb_kill_urb(hpusbscsi->dataurb);
- usb_kill_urb(hpusbscsi->controlurb);
- hpusbscsi->state = HP_STATE_FREE;
-
- return SCSI_ABORT_PENDING;
-}
-
-/* usb interrupt handlers - they are all running IN INTERRUPT ! */
-
-static void handle_usb_error (struct hpusbscsi *hpusbscsi)
-{
- if (likely(hpusbscsi->scallback != NULL)) {
- hpusbscsi->srb->result = DID_ERROR;
- hpusbscsi->scallback(hpusbscsi->srb);
- }
- hpusbscsi->state = HP_STATE_FREE;
-}
-
-static void control_interrupt_callback (struct urb *u, struct pt_regs *regs)
-{
- struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
- u8 scsi_state;
-
-DEBUG("Getting status byte %d \n",hpusbscsi->scsi_state_byte);
- if(unlikely(u->status < 0)) {
- if (likely(hpusbscsi->state != HP_STATE_FREE))
- handle_usb_error(hpusbscsi);
- if (u->status == -ECONNRESET || u->status == -ENOENT || u->status == -ESHUTDOWN)
- return;
- else
- goto resub;
- }
-
- scsi_state = hpusbscsi->scsi_state_byte;
- if (hpusbscsi->state != HP_STATE_ERROR) {
- hpusbscsi->srb->result &= SCSI_ERR_MASK;
- hpusbscsi->srb->result |= scsi_state;
- }
-
- if (scsi_state == CHECK_CONDITION << 1) {
- if (hpusbscsi->state == HP_STATE_WAIT) {
- issue_request_sense(hpusbscsi);
- } else {
- /* we request sense after an eventual data transfer */
- hpusbscsi->state = HP_STATE_ERROR;
- }
- }
-
- if (hpusbscsi->scallback != NULL && hpusbscsi->state == HP_STATE_WAIT && scsi_state != CHECK_CONDITION <<1 )
- /* we do a callback to the scsi layer if and only if all data has been transferred */
- hpusbscsi->scallback(hpusbscsi->srb);
-
- TRACE_STATE;
- switch (hpusbscsi->state) {
- case HP_STATE_WAIT:
- hpusbscsi->state = HP_STATE_FREE;
- TRACE_STATE;
- break;
- case HP_STATE_WORKING:
- case HP_STATE_BEGINNING:
- hpusbscsi->state = HP_STATE_PREMATURE;
- TRACE_STATE;
- break;
- case HP_STATE_ERROR:
- break;
- default:
- printk(KERN_ERR"hpusbscsi: Unexpected status report.\n");
- TRACE_STATE;
- hpusbscsi->state = HP_STATE_FREE;
- TRACE_STATE;
- break;
- }
-resub:
- usb_submit_urb(u, GFP_ATOMIC);
-}
-
-static void simple_command_callback(struct urb *u, struct pt_regs *regs)
-{
- struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
- if (unlikely(u->status<0)) {
- handle_usb_error(hpusbscsi);
- return;
- }
- TRACE_STATE;
- if (hpusbscsi->state != HP_STATE_PREMATURE) {
- TRACE_STATE;
- hpusbscsi->state = HP_STATE_WAIT;
- } else {
- if (likely(hpusbscsi->scallback != NULL))
- hpusbscsi->scallback(hpusbscsi->srb);
- hpusbscsi->state = HP_STATE_FREE;
- TRACE_STATE;
- }
-}
-
-static void scatter_gather_callback(struct urb *u, struct pt_regs *regs)
-{
- struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
- struct scatterlist *sg = hpusbscsi->srb->buffer;
- usb_complete_t callback;
- int res;
-
- DEBUG("Going through scatter/gather\n");
- if (unlikely(u->status < 0)) {
- handle_usb_error(hpusbscsi);
- return;
- }
-
- if (hpusbscsi->fragment + 1 != hpusbscsi->srb->use_sg)
- callback = scatter_gather_callback;
- else
- callback = simple_done;
-
- TRACE_STATE;
- if (hpusbscsi->state != HP_STATE_PREMATURE)
- hpusbscsi->state = HP_STATE_WORKING;
- TRACE_STATE;
-
- usb_fill_bulk_urb(
- u,
- hpusbscsi->dev,
- hpusbscsi->current_data_pipe,
- page_address(sg[hpusbscsi->fragment].page) +
- sg[hpusbscsi->fragment].offset,
- sg[hpusbscsi->fragment++].length,
- callback,
- hpusbscsi
- );
-
- res = usb_submit_urb(u, GFP_ATOMIC);
- if (unlikely(res))
- handle_usb_error(hpusbscsi);
- TRACE_STATE;
-}
-
-static void simple_done (struct urb *u, struct pt_regs *regs)
-{
- struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
-
- if (unlikely(u->status < 0)) {
- handle_usb_error(hpusbscsi);
- return;
- }
- DEBUG("Data transfer done\n");
- TRACE_STATE;
- if (hpusbscsi->state != HP_STATE_PREMATURE) {
- if (unlikely(u->status < 0)) {
- handle_usb_error(hpusbscsi);
- } else {
- if (hpusbscsi->state != HP_STATE_ERROR) {
- hpusbscsi->state = HP_STATE_WAIT;
- } else {
- issue_request_sense(hpusbscsi);
- }
- }
- } else {
- if (likely(hpusbscsi->scallback != NULL))
- hpusbscsi->scallback(hpusbscsi->srb);
- hpusbscsi->state = HP_STATE_FREE;
- }
-}
-
-static void simple_payload_callback (struct urb *u, struct pt_regs *regs)
-{
- struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
- int res;
-
- if (unlikely(u->status<0)) {
- handle_usb_error(hpusbscsi);
- return;
- }
-
- usb_fill_bulk_urb(
- u,
- hpusbscsi->dev,
- hpusbscsi->current_data_pipe,
- hpusbscsi->srb->buffer,
- hpusbscsi->srb->bufflen,
- simple_done,
- hpusbscsi
- );
-
- res = usb_submit_urb(u, GFP_ATOMIC);
- if (unlikely(res)) {
- handle_usb_error(hpusbscsi);
- return;
- }
- TRACE_STATE;
- if (hpusbscsi->state != HP_STATE_PREMATURE) {
- hpusbscsi->state = HP_STATE_WORKING;
- TRACE_STATE;
- }
-}
-
-static void request_sense_callback (struct urb *u, struct pt_regs *regs)
-{
- struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
-
- if (u->status<0) {
- handle_usb_error(hpusbscsi);
- return;
- }
-
- usb_fill_bulk_urb(
- u,
- hpusbscsi->dev,
- hpusbscsi->current_data_pipe,
- hpusbscsi->srb->sense_buffer,
- SCSI_SENSE_BUFFERSIZE,
- simple_done,
- hpusbscsi
- );
-
- if (0 > usb_submit_urb(u, GFP_ATOMIC)) {
- handle_usb_error(hpusbscsi);
- return;
- }
- if (hpusbscsi->state != HP_STATE_PREMATURE && hpusbscsi->state != HP_STATE_ERROR)
- hpusbscsi->state = HP_STATE_WORKING;
-}
-
-static void issue_request_sense (struct hpusbscsi *hpusbscsi)
-{
- usb_fill_bulk_urb(
- hpusbscsi->dataurb,
- hpusbscsi->dev,
- usb_sndbulkpipe(hpusbscsi->dev, hpusbscsi->ep_out),
- &hpusbscsi->sense_command,
- SENSE_COMMAND_SIZE,
- request_sense_callback,
- hpusbscsi
- );
-
- hpusbscsi->current_data_pipe = usb_rcvbulkpipe(hpusbscsi->dev, hpusbscsi->ep_in);
-
- if (0 > usb_submit_urb(hpusbscsi->dataurb, GFP_ATOMIC)) {
- handle_usb_error(hpusbscsi);
- }
-}
-
-

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/