# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.851 -> 1.852 # drivers/usb/hpusbscsi.c 1.5 -> 1.6 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/08/14 oliver@oenone.homelinux.org 1.852 # [PATCH] USB: hpusbscsi driver updates # # -------------------------------------------- # diff -Nru a/drivers/usb/hpusbscsi.c b/drivers/usb/hpusbscsi.c --- a/drivers/usb/hpusbscsi.c Wed Aug 14 23:17:35 2002 +++ b/drivers/usb/hpusbscsi.c Wed Aug 14 23:17:35 2002 @@ -1,3 +1,51 @@ +/* + * hpusbscsi + * (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 driver is known to work with the following scanners (VID, PID) + * (0x03f0, 0x0701) HP 53xx + * (0x03f0, 0x0801) HP 7400 + * (0x0638, 0x026a) Minolta Scan Dual II + * (0x0686, 0x4004) Minolta Elite II + * To load with full debugging load with "insmod hpusbscsi debug=2" + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Contributors: + * Oliver Neukum + * John Fremlin + * Matt Dharm + * . + * . + * Timothy Jedlicka + * + * History + * + * 22-Apr-2002 + * + * - Added Elite II scanner - bonzo + * - Cleaned up the debug statements and made them optional at load time - bonzo + * + * 20020618 + * + * - Confirm to stupid 2.4 rules on io_request_lock + * + */ + #include #include #include @@ -16,12 +64,28 @@ #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__) +/* DEBUG related parts */ +#define HPUSBSCSI_DEBUG + +#ifdef HPUSBSCSI_DEBUG +# define PDEBUG(level, fmt, args...) \ + if (debug >= (level)) info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , \ + ## args) +#else +# define PDEBUG(level, fmt, args...) do {} while(0) +#endif + + +/* 0=no debug messages + * 1=everything but trace states + * 2=trace states + */ +static int debug; /* = 0 */ + +MODULE_PARM(debug, "i"); +MODULE_PARM_DESC(debug, "Debug level: 0=none, 1=no trace states, 2=trace states"); /* global variables */ @@ -54,7 +118,7 @@ GFP_KERNEL); if (new == NULL) return NULL; - DEBUG ("Allocated memory\n"); + PDEBUG (1, "Allocated memory"); memset (new, 0, sizeof (struct hpusbscsi)); spin_lock_init (&new->dataurb.lock); spin_lock_init (&new->controlurb.lock); @@ -167,7 +231,8 @@ int result; INIT_LIST_HEAD (&hpusbscsi_devices); - + PDEBUG(0, "driver loaded, DebugLvel=%d", debug); + if ((result = usb_register (&hpusbscsi_usb_driver)) < 0) { printk (KERN_ERR "hpusbscsi: driver registration failed\n"); return -1; @@ -210,6 +275,7 @@ /* What a hideous hack! */ char local_name[48]; + spin_unlock_irq(&io_request_lock); /* set up the name of our subdirectory under /proc/scsi/ */ @@ -218,6 +284,7 @@ /* FIXME: where is this freed ? */ if (!sht->proc_name) { + spin_lock_irq(&io_request_lock); return 0; } @@ -238,6 +305,7 @@ if ( 0 > usb_submit_urb(&desc->controlurb)) { kfree(sht->proc_name); + spin_lock_irq(&io_request_lock); return 0; } @@ -246,10 +314,11 @@ if (desc->host == NULL) { kfree (sht->proc_name); usb_unlink_urb(&desc->controlurb); + spin_lock_irq(&io_request_lock); return 0; } desc->host->hostdata[0] = (unsigned long) desc; - + spin_lock_irq(&io_request_lock); return 1; } @@ -297,7 +366,7 @@ } - TRACE_STATE; + PDEBUG(2, "state= %s", states[hpusbscsi->state]); if (hpusbscsi->state != HP_STATE_FREE) { printk(KERN_CRIT"hpusbscsi - Ouch: queueing violation!\n"); return 1; /* This must not happen */ @@ -307,7 +376,7 @@ memset(srb->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); hpusbscsi->state = HP_STATE_BEGINNING; - TRACE_STATE; + PDEBUG(2, "state= %s", states[hpusbscsi->state]); /* We prepare the urb for writing out the scsi command */ FILL_BULK_URB( @@ -325,7 +394,7 @@ res = usb_submit_urb(&hpusbscsi->dataurb); if (res) { hpusbscsi->state = HP_STATE_FREE; - TRACE_STATE; + PDEBUG(2, "state= %s", states[hpusbscsi->state]); if (callback) { srb->result = DID_ERROR; callback(srb); @@ -341,9 +410,9 @@ { struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]); - printk(KERN_DEBUG"SCSI reset requested.\n"); + PDEBUG(1, "SCSI reset requested"); //usb_reset_device(hpusbscsi->dev); - //printk(KERN_DEBUG"SCSI reset completed.\n"); + //PDEBUG(1, "SCSI reset completed"); hpusbscsi->state = HP_STATE_FREE; return 0; @@ -352,10 +421,13 @@ static int hpusbscsi_scsi_abort (Scsi_Cmnd *srb) { struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]); - printk(KERN_DEBUG"Request is canceled.\n"); + PDEBUG(1, "Request is canceled"); + spin_unlock_irq(&io_request_lock); usb_unlink_urb(&hpusbscsi->dataurb); hpusbscsi->state = HP_STATE_FREE; + + spin_lock_irq(&io_request_lock); return SCSI_ABORT_PENDING; } @@ -376,7 +448,7 @@ struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context; u8 scsi_state; -DEBUG("Getting status byte %d \n",hpusbscsi->scsi_state_byte); + PDEBUG(1, "Getting status byte %d",hpusbscsi->scsi_state_byte); if(u->status < 0) { if (hpusbscsi->state != HP_STATE_FREE) handle_usb_error(hpusbscsi); @@ -402,24 +474,24 @@ /* we do a callback to the scsi layer if and only if all data has been transfered */ hpusbscsi->scallback(hpusbscsi->srb); - TRACE_STATE; + PDEBUG(2, "state= %s", states[hpusbscsi->state]); switch (hpusbscsi->state) { case HP_STATE_WAIT: hpusbscsi->state = HP_STATE_FREE; - TRACE_STATE; + PDEBUG(2, "state= %s", states[hpusbscsi->state]); break; case HP_STATE_WORKING: case HP_STATE_BEGINNING: hpusbscsi->state = HP_STATE_PREMATURE; - TRACE_STATE; + PDEBUG(2, "state= %s", states[hpusbscsi->state]); break; case HP_STATE_ERROR: break; default: printk(KERN_ERR"hpusbscsi: Unexpected status report.\n"); - TRACE_STATE; + PDEBUG(2, "state= %s", states[hpusbscsi->state]); hpusbscsi->state = HP_STATE_FREE; - TRACE_STATE; + PDEBUG(2, "state= %s", states[hpusbscsi->state]); break; } } @@ -431,15 +503,15 @@ handle_usb_error(hpusbscsi); return; } - TRACE_STATE; + PDEBUG(2, "state= %s", states[hpusbscsi->state]); if (hpusbscsi->state != HP_STATE_PREMATURE) { - TRACE_STATE; + PDEBUG(2, "state= %s", states[hpusbscsi->state]); hpusbscsi->state = HP_STATE_WAIT; } else { if (hpusbscsi->scallback != NULL) hpusbscsi->scallback(hpusbscsi->srb); hpusbscsi->state = HP_STATE_FREE; - TRACE_STATE; + PDEBUG(2, "state= %s", states[hpusbscsi->state]); } } @@ -450,7 +522,7 @@ usb_urb_callback callback; int res; - DEBUG("Going through scatter/gather\n"); + PDEBUG(1, "Going through scatter/gather"); // bonzo - this gets hit a lot - maybe make it a 2 if (u->status < 0) { handle_usb_error(hpusbscsi); return; @@ -461,10 +533,10 @@ else callback = simple_done; - TRACE_STATE; + PDEBUG(2, "state= %s", states[hpusbscsi->state]); if (hpusbscsi->state != HP_STATE_PREMATURE) hpusbscsi->state = HP_STATE_WORKING; - TRACE_STATE; + PDEBUG(2, "state= %s", states[hpusbscsi->state]); FILL_BULK_URB( u, @@ -479,7 +551,7 @@ res = usb_submit_urb(u); if (res) handle_usb_error(hpusbscsi); - TRACE_STATE; + PDEBUG(2, "state= %s", states[hpusbscsi->state]); } static void simple_done (struct urb *u) @@ -490,8 +562,8 @@ handle_usb_error(hpusbscsi); return; } - DEBUG("Data transfer done\n"); - TRACE_STATE; + PDEBUG(1, "Data transfer done"); + PDEBUG(2, "state= %s", states[hpusbscsi->state]); if (hpusbscsi->state != HP_STATE_PREMATURE) { if (u->status < 0) { handle_usb_error(hpusbscsi); @@ -501,7 +573,7 @@ } else { issue_request_sense(hpusbscsi); } - TRACE_STATE; + PDEBUG(2, "state= %s", states[hpusbscsi->state]); } } else { if (hpusbscsi->scallback != NULL) @@ -535,10 +607,10 @@ handle_usb_error(hpusbscsi); return; } - TRACE_STATE; + PDEBUG(2, "state= %s", states[hpusbscsi->state]); if (hpusbscsi->state != HP_STATE_PREMATURE) { hpusbscsi->state = HP_STATE_WORKING; - TRACE_STATE; + PDEBUG(2, "state= %s", states[hpusbscsi->state]); } }