patch-2.3.31 linux/drivers/usb/usb_scsi.c

Next file: linux/fs/Config.in
Previous file: linux/drivers/usb/usb-core.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.30/linux/drivers/usb/usb_scsi.c linux/drivers/usb/usb_scsi.c
@@ -1,11 +1,12 @@
-
 /* Driver for USB SCSI-like devices
  *
- * (C) Michael Gee (michael@linuxspecific.com) 1999
+ * (c) 1999 Michael Gee (michael@linuxspecific.com)
+ * (c) 1999 Matthew Dharm (mdharm@one-eyed-alien.net)
  *
- * This driver is schizoid  - it makes a USB device appear as both a SCSI device
- * and a character device. The latter is only available if the device has an
- * interrupt endpoint, and is used specifically to receive interrupt events.
+ * This driver is schizoid  - it makes a USB device appear as both a SCSI
+ * device and a character device. The latter is only available if the device
+ * has an interrupt endpoint, and is used specifically to receive interrupt
+ * events.
  *
  * In order to support various 'strange' devices, this module supports plug-in
  * device-specific filter modules, which can do their own thing when required.
@@ -58,7 +59,7 @@
 #ifdef REWRITE_PROJECT
 #define IRQ_PERIOD		255
 #else
-#define IRQ_PERIOD		0	/* single IRQ transfer then remove it */
+#define IRQ_PERIOD		0    /* single IRQ transfer then remove it */
 #endif
 
 /*
@@ -70,38 +71,37 @@
 int usbscsi_debug = 1;
 
 struct us_data {
-	struct us_data		*next;			/* next device */
-	struct usb_device 	*pusb_dev;
-	struct usb_scsi_filter  *filter;		/* filter driver */
-	void 			*fdata;			/* filter data */
-	unsigned int		flags;			/* from filter initially */
-	__u8			ifnum;			/* interface number */
-	__u8			ep_in;			/* in endpoint */
-	__u8			ep_out;			/* out ....... */
-	__u8			ep_int;			/* interrupt . */
-	__u8			subclass;		/* as in overview */
-	__u8			protocol;		/* .............. */
-	__u8			attention_done;		/* force attention on first command */
-	int (*pop)(Scsi_Cmnd *);			/* protocol specific do cmd */
-	int (*pop_reset)(struct us_data *);		/* ................. device reset */
-	GUID(guid);					/* unique dev id */
-	struct Scsi_Host	*host;			/* our dummy host data */
-	Scsi_Host_Template	*htmplt;		/* own host template */
-	int			host_number;		/* to find us */
-	int			host_no;		/* allocated by scsi */
-	int			fixedlength;		/* expand commands */
-	Scsi_Cmnd		*srb;			/* current srb */
-	int			action;			/* what to do */
-	wait_queue_head_t	waitq;			/* thread waits */
-	wait_queue_head_t	ip_waitq;		/* for CBI interrupts */
-	__u16			ip_data;		/* interrupt data */
-	int			ip_wanted;		/* needed */
-	int			pid;			/* control thread */
-	struct semaphore	*notify; 		/* wait for thread to begin */
-	void			*irq_handle;		/* for USB interrupt requests */
-	unsigned int		irqpipe;		/* remember pipe for release_irq */
-	int			mode_xlate;		/* if current SCSI command is MODE_6 */
-							/* but is translated to MODE_10 for UFI */
+	struct us_data		*next;		/* next device */
+	struct usb_device	*pusb_dev;
+	struct usb_scsi_filter	*filter;	/* filter driver */
+	void			*fdata;		/* filter data */
+	unsigned int		flags;		/* from filter initially */
+	__u8			ifnum;		/* interface number */
+	__u8			ep_in;		/* in endpoint */
+	__u8			ep_out;		/* out ....... */
+	__u8			ep_int;		/* interrupt . */
+	__u8			subclass;	/* as in overview */
+	__u8			protocol;	/* .............. */
+	__u8			attention_done; /* force attn on first cmd */
+	int (*pop)(Scsi_Cmnd *);		/* protocol specific do cmd */
+	int (*pop_reset)(struct us_data *);	/* ........... device reset */
+	GUID(guid);				/* unique dev id */
+	struct Scsi_Host	*host;		/* our dummy host data */
+	Scsi_Host_Template	*htmplt;	/* own host template */
+	int			host_number;	/* to find us */
+	int			host_no;	/* allocated by scsi */
+	int			fixedlength;	/* expand commands */
+	Scsi_Cmnd		*srb;		/* current srb */
+	int			action;		/* what to do */
+	wait_queue_head_t	waitq;		/* thread waits */
+	wait_queue_head_t	ip_waitq;	/* for CBI interrupts */
+	__u16			ip_data;	/* interrupt data */
+	int			ip_wanted;	/* needed */
+	int			pid;		/* control thread */
+	struct semaphore	*notify;	/* wait for thread to begin */
+	void			*irq_handle;	/* for USB int requests */
+	unsigned int		irqpipe;	/* pipe for release_irq */
+	int			mode_xlate;	/* trans MODE_6 to _10? */
 };
 
 /*
@@ -131,230 +131,230 @@
 
 static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length)
 {
-    int max_size = usb_maxpacket(us->pusb_dev, pipe, usb_pipeout(pipe)) * 16;
-    int this_xfer;
-    int result;
-    unsigned long partial;
-    int maxtry = 100;
-    while (length) {
-	this_xfer = length > max_size ? max_size : length;
-	length -= this_xfer;
-	do {
-	    /* US_DEBUGP("Bulk xfer %x(%d)\n", (unsigned int)buf, this_xfer); */
-	    result = usb_bulk_msg(us->pusb_dev, pipe, buf,
-				this_xfer, &partial, HZ*5);
-
-	    if (result != 0 || partial != this_xfer)
-		US_DEBUGP("bulk_msg returned %d xferred %lu/%d\n",
-			  result, partial, this_xfer);
-
-	    if (result == USB_ST_STALL) {
-		US_DEBUGP("clearing endpoint halt for pipe %x\n", pipe);
-		usb_clear_halt(us->pusb_dev,
-			usb_pipeendpoint(pipe) | (pipe & USB_DIR_IN));
-	    }
-
-	    /* we want to retry if the device reported NAK */
-	    if (result == USB_ST_TIMEOUT) {
-		if (partial != this_xfer) {
-		    return 0;	/* I do not like this */
-		}
-		if (!maxtry--)
-		    break;
-		this_xfer -= partial;
-		buf += partial;
-	    } else if (!result && partial != this_xfer) {
-		/* short data - assume end */
-		result = USB_ST_DATAUNDERRUN;
-		break;
-	    } else if (result == USB_ST_STALL && us->protocol == US_PR_CB) {
-		if (!maxtry--)
-		    break;
-		this_xfer -= partial;
-		buf += partial;
-	    } else
-		break;
-	} while ( this_xfer );
-	if (result)
-	    return result;
-	buf += this_xfer;
-    }
+	int max_size = usb_maxpacket(us->pusb_dev, pipe, usb_pipeout(pipe)) * 16;
+	int this_xfer;
+	int result;
+	unsigned long partial;
+	int maxtry = 100;
+	while (length) {
+		this_xfer = length > max_size ? max_size : length;
+		length -= this_xfer;
+		do {
+			US_DEBUGP("Bulk xfer %x(%d)\n", (unsigned int)buf, this_xfer);
+			result = usb_bulk_msg(us->pusb_dev, pipe, buf,
+					      this_xfer, &partial, HZ*5);
+
+			if (result != 0 || partial != this_xfer)
+				US_DEBUGP("bulk_msg returned %d xferred %lu/%d\n",
+					  result, partial, this_xfer);
+
+			if (result == USB_ST_STALL) {
+				US_DEBUGP("clearing endpoint halt for pipe %x\n", pipe);
+				usb_clear_halt(us->pusb_dev,
+					       usb_pipeendpoint(pipe) | (pipe & USB_DIR_IN));
+			}
 
-    return 0;
+			/* we want to retry if the device reported NAK */
+			if (result == USB_ST_TIMEOUT) {
+				if (partial != this_xfer) {
+					return 0;	/* I do not like this */
+				}
+				if (!maxtry--)
+					break;
+				this_xfer -= partial;
+				buf += partial;
+			} else if (!result && partial != this_xfer) {
+				/* short data - assume end */
+				result = USB_ST_DATAUNDERRUN;
+				break;
+			} else if (result == USB_ST_STALL && us->protocol == US_PR_CB) {
+				if (!maxtry--)
+					break;
+				this_xfer -= partial;
+				buf += partial;
+			} else
+				break;
+		} while ( this_xfer );
+		if (result)
+			return result;
+		buf += this_xfer;
+	}
+
+	return 0;
 }
 
 static int us_transfer(Scsi_Cmnd *srb, int dir_in)
 {
-    struct us_data *us = (struct us_data *)srb->host_scribble;
-    int i;
-    int result = -1;
-    unsigned int pipe = dir_in ? usb_rcvbulkpipe(us->pusb_dev, us->ep_in) :
-	    usb_sndbulkpipe(us->pusb_dev, us->ep_out);
-
-    if (srb->use_sg) {
-	struct scatterlist *sg = (struct scatterlist *) srb->request_buffer;
-
-	for (i = 0; i < srb->use_sg; i++) {
-	    result = us_one_transfer(us, pipe, sg[i].address, sg[i].length);
-	    if (result)
-		break;
+	struct us_data *us = (struct us_data *)srb->host_scribble;
+	int i;
+	int result = -1;
+	unsigned int pipe = dir_in ? usb_rcvbulkpipe(us->pusb_dev, us->ep_in) :
+		usb_sndbulkpipe(us->pusb_dev, us->ep_out);
+
+	if (srb->use_sg) {
+		struct scatterlist *sg = (struct scatterlist *) srb->request_buffer;
+
+		for (i = 0; i < srb->use_sg; i++) {
+			result = us_one_transfer(us, pipe, sg[i].address, sg[i].length);
+			if (result)
+				break;
+		}
 	}
-    }
-    else
-	result = us_one_transfer(us, pipe,
-				 srb->request_buffer, srb->request_bufflen);
-
-    if (result)
-	US_DEBUGP("us_transfer returning error %d\n", result);
-    return result;
+	else
+		result = us_one_transfer(us, pipe,
+					 srb->request_buffer, srb->request_bufflen);
+
+	if (result)
+		US_DEBUGP("us_transfer returning error %d\n", result);
+	return result;
 }
 
 static unsigned int us_transfer_length(Scsi_Cmnd *srb)
 {
-    int i;
-    unsigned int total = 0;
+	int i;
+	unsigned int total = 0;
 
-    /* always zero for some commands */
-    switch (srb->cmnd[0]) {
-    case SEEK_6:
-    case SEEK_10:
-    case REZERO_UNIT:
-    case ALLOW_MEDIUM_REMOVAL:
-    case START_STOP:
-    case TEST_UNIT_READY:
-	return 0;
+	/* always zero for some commands */
+	switch (srb->cmnd[0]) {
+	case SEEK_6:
+	case SEEK_10:
+	case REZERO_UNIT:
+	case ALLOW_MEDIUM_REMOVAL:
+	case START_STOP:
+	case TEST_UNIT_READY:
+		return 0;
+
+	default:
+		break;
+	}
+
+	if (srb->use_sg) {
+		struct scatterlist *sg = (struct scatterlist *) srb->request_buffer;
 
-    default:
-	break;
-    }
-
-    if (srb->use_sg) {
-	struct scatterlist *sg = (struct scatterlist *) srb->request_buffer;
-
-	for (i = 0; i < srb->use_sg; i++) {
-	    total += sg[i].length;
-	}
-	return total;
-    }
-    else
-	return srb->request_bufflen;
+		for (i = 0; i < srb->use_sg; i++) {
+			total += sg[i].length;
+		}
+		return total;
+	}
+	else
+		return srb->request_bufflen;
 }
 
 static int pop_CBI_irq(int state, void *buffer, int len, void *dev_id)
 {
-    struct us_data *us = (struct us_data *)dev_id;
+	struct us_data *us = (struct us_data *)dev_id;
 
-    if (state != USB_ST_REMOVED) {
-	us->ip_data = le16_to_cpup((__u16 *)buffer);
-	/* US_DEBUGP("Interrupt Status %x\n", us->ip_data); */
-    }
-    if (us->ip_wanted) {
-	us->ip_wanted = 0;
-	wake_up(&us->ip_waitq);
-    }
+	if (state != USB_ST_REMOVED) {
+		us->ip_data = le16_to_cpup((__u16 *)buffer);
+		/* US_DEBUGP("Interrupt Status %x\n", us->ip_data); */
+	}
+	if (us->ip_wanted) {
+		us->ip_wanted = 0;
+		wake_up(&us->ip_waitq);
+	}
 
-    /* we don't want another interrupt */
-    return 0;
+	/* we don't want another interrupt */
+	return 0;
 }
 
 static int pop_CB_reset(struct us_data *us)
 {
-    unsigned char cmd[12];
-    int result;
+	unsigned char cmd[12];
+	int result;
 
-    US_DEBUGP("pop_CB_reset\n");
+	US_DEBUGP("pop_CB_reset\n");
 
-    memset(cmd, -1, sizeof(cmd));
-    cmd[0] = SEND_DIAGNOSTIC;
-    cmd[1] = 4;
-    result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
-			US_CBI_ADSC, USB_TYPE_CLASS | USB_RT_INTERFACE,
-			0, us->ifnum, cmd, sizeof(cmd), HZ*5);
+	memset(cmd, -1, sizeof(cmd));
+	cmd[0] = SEND_DIAGNOSTIC;
+	cmd[1] = 4;
+	result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
+				 US_CBI_ADSC, USB_TYPE_CLASS | USB_RT_INTERFACE,
+				 0, us->ifnum, cmd, sizeof(cmd), HZ*5);
 
-    /* long wait for reset */
+	/* long wait for reset */
 
-    schedule_timeout(HZ*6);
+	schedule_timeout(HZ*6);
 
-    US_DEBUGP("pop_CB_reset: clearing endpoint halt\n");
-    usb_clear_halt(us->pusb_dev, us->ep_in | USB_DIR_IN);
-    usb_clear_halt(us->pusb_dev, us->ep_out | USB_DIR_OUT);
+	US_DEBUGP("pop_CB_reset: clearing endpoint halt\n");
+	usb_clear_halt(us->pusb_dev, us->ep_in | USB_DIR_IN);
+	usb_clear_halt(us->pusb_dev, us->ep_out | USB_DIR_OUT);
 
-    US_DEBUGP("pop_CB_reset done\n");
-    return 0;
+	US_DEBUGP("pop_CB_reset done\n");
+	return 0;
 }
 
 static int pop_CB_command(Scsi_Cmnd *srb)
 {
-    struct us_data *us = (struct us_data *)srb->host_scribble;
-    unsigned char cmd[16];
-    int result;
-    int retry = 5;
-    int done_start = 0;
+	struct us_data *us = (struct us_data *)srb->host_scribble;
+	unsigned char cmd[16];
+	int result;
+	int retry = 5;
+	int done_start = 0;
 
-    while (retry--) {
+	while (retry--) {
 
-	if (us->flags & US_FL_FIXED_COMMAND) {
-	    memset(cmd, 0, us->fixedlength);
+		if (us->flags & US_FL_FIXED_COMMAND) {
+			memset(cmd, 0, us->fixedlength);
 
-	    /* fix some commands */
+			/* fix some commands */
 
-	    switch (srb->cmnd[0]) {
-	    case WRITE_6:
-	    case READ_6:
-		cmd[0] = srb->cmnd[0] | 0x20;
-		cmd[1] = srb->cmnd[1] & 0xE0;
-		cmd[2] = 0;
-		cmd[3] = srb->cmnd[1] & 0x1F;
-		cmd[4] = srb->cmnd[2];
-		cmd[5] = srb->cmnd[3];
-		cmd[8] = srb->cmnd[4];
-		break;
+			switch (srb->cmnd[0]) {
+			case WRITE_6:
+			case READ_6:
+				cmd[0] = srb->cmnd[0] | 0x20;
+				cmd[1] = srb->cmnd[1] & 0xE0;
+				cmd[2] = 0;
+				cmd[3] = srb->cmnd[1] & 0x1F;
+				cmd[4] = srb->cmnd[2];
+				cmd[5] = srb->cmnd[3];
+				cmd[8] = srb->cmnd[4];
+				break;
 
-	    case MODE_SENSE:
-	    case MODE_SELECT:
-		us->mode_xlate = (srb->cmnd[0] == MODE_SENSE);
-		cmd[0] = srb->cmnd[0] | 0x40;
-		cmd[1] = srb->cmnd[1];
-		cmd[2] = srb->cmnd[2];
-		cmd[8] = srb->cmnd[4];
-		break;
+			case MODE_SENSE:
+			case MODE_SELECT:
+				us->mode_xlate = (srb->cmnd[0] == MODE_SENSE);
+				cmd[0] = srb->cmnd[0] | 0x40;
+				cmd[1] = srb->cmnd[1];
+				cmd[2] = srb->cmnd[2];
+				cmd[8] = srb->cmnd[4];
+				break;
 
-	    default:
-		us->mode_xlate = 0;
-		memcpy(cmd, srb->cmnd, srb->cmd_len);
-		break;
-	    }
-	    result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
-				US_CBI_ADSC, USB_TYPE_CLASS | USB_RT_INTERFACE,
-				0, us->ifnum,
-				cmd, us->fixedlength, HZ*5);
-	    if (!done_start && (us->subclass == US_SC_UFI /*|| us->subclass == US_SC_8070*/)
-		 && cmd[0] == TEST_UNIT_READY && result) {
-		/* as per spec try a start command, wait and retry */
-
-		done_start++;
-		memset(cmd, 0, sizeof(cmd));
-		cmd[0] = START_STOP;
-		cmd[4] = 1;		/* start */
-		result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
-				US_CBI_ADSC, USB_TYPE_CLASS | USB_RT_INTERFACE,
-				0, us->ifnum,
-				cmd, us->fixedlength, HZ*5);
-		wait_ms(100);
-		retry++;
-		continue;
-	    }
-	} else {
-	    result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
-				US_CBI_ADSC, USB_TYPE_CLASS | USB_RT_INTERFACE,
-				0, us->ifnum,
-	    			srb->cmnd, srb->cmd_len, HZ*5);
-	}
-	if (/*result != USB_ST_STALL &&*/ result != USB_ST_TIMEOUT)
-	    return result;
-    }
+			default:
+				us->mode_xlate = 0;
+				memcpy(cmd, srb->cmnd, srb->cmd_len);
+				break;
+			}
+			result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
+						 US_CBI_ADSC, USB_TYPE_CLASS | USB_RT_INTERFACE,
+						 0, us->ifnum,
+						 cmd, us->fixedlength, HZ*5);
+			if (!done_start && (us->subclass == US_SC_UFI /*|| us->subclass == US_SC_8070*/)
+			    && cmd[0] == TEST_UNIT_READY && result) {
+				/* as per spec try a start command, wait and retry */
+
+				done_start++;
+				memset(cmd, 0, sizeof(cmd));
+				cmd[0] = START_STOP;
+				cmd[4] = 1;		/* start */
+				result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
+							 US_CBI_ADSC, USB_TYPE_CLASS | USB_RT_INTERFACE,
+							 0, us->ifnum,
+							 cmd, us->fixedlength, HZ*5);
+				wait_ms(100);
+				retry++;
+				continue;
+			}
+		} else {
+			result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
+						 US_CBI_ADSC, USB_TYPE_CLASS | USB_RT_INTERFACE,
+						 0, us->ifnum,
+						 srb->cmnd, srb->cmd_len, HZ*5);
+		}
+		if (/*result != USB_ST_STALL &&*/ result != USB_ST_TIMEOUT)
+			return result;
+	}
 
-    return result;
+	return result;
 }
 
 /*
@@ -363,237 +363,237 @@
 
 static int pop_CB_status(Scsi_Cmnd *srb)
 {
-    struct us_data *us = (struct us_data *)srb->host_scribble;
-    int result;
-    __u8 status[2];
-    int retry = 5;
-
-    US_DEBUGP("pop_CB_status, proto=%x\n", us->protocol);
-    switch (us->protocol) {
-    case US_PR_CB:
-	/* get from control */
-
-	while (retry--) {
-	    result = usb_control_msg(us->pusb_dev, usb_rcvctrlpipe(us->pusb_dev,0),
-	    			USB_REQ_GET_STATUS, USB_DIR_IN | USB_TYPE_STANDARD | USB_RT_DEVICE,
-				0, us->ifnum,
-				status, sizeof(status), HZ*5);
-	    if (result != USB_ST_TIMEOUT)
+	struct us_data *us = (struct us_data *)srb->host_scribble;
+	int result;
+	__u8 status[2];
+	int retry = 5;
+
+	US_DEBUGP("pop_CB_status, proto=%x\n", us->protocol);
+	switch (us->protocol) {
+	case US_PR_CB:
+		/* get from control */
+
+		while (retry--) {
+			result = usb_control_msg(us->pusb_dev, usb_rcvctrlpipe(us->pusb_dev,0),
+						 USB_REQ_GET_STATUS, USB_DIR_IN | USB_TYPE_STANDARD | USB_RT_DEVICE,
+						 0, us->ifnum,
+						 status, sizeof(status), HZ*5);
+			if (result != USB_ST_TIMEOUT)
+				break;
+		}
+		if (result) {
+			US_DEBUGP("Bad AP status request %d\n", result);
+			return DID_ABORT << 16;
+		}
+		US_DEBUGP("Got AP status %x %x\n", status[0], status[1]);
+		if (srb->cmnd[0] != REQUEST_SENSE && srb->cmnd[0] != INQUIRY &&
+		    ( (status[0] & ~3) || status[1]))
+			return (DID_OK << 16) | 2;
+		else
+			return DID_OK << 16;
 		break;
-	}
-	if (result) {
-	    US_DEBUGP("Bad AP status request %d\n", result);
-	    return DID_ABORT << 16;
-	}
-	US_DEBUGP("Got AP status %x %x\n", status[0], status[1]);
-	if (srb->cmnd[0] != REQUEST_SENSE && srb->cmnd[0] != INQUIRY &&
-	    ( (status[0] & ~3) || status[1]))
-	    return (DID_OK << 16) | 2;
-	else
-	    return DID_OK << 16;
-	break;
 
-    case US_PR_CBI:
-	/* get from interrupt pipe */
+	case US_PR_CBI:
+		/* get from interrupt pipe */
 
-	/* add interrupt transfer, marked for removal */
-	us->ip_wanted = 1;
-	us->irqpipe = usb_rcvintpipe(us->pusb_dev, us->ep_int);
-	result = usb_request_irq(us->pusb_dev, us->irqpipe, pop_CBI_irq,
-				IRQ_PERIOD, (void *)us, &us->irq_handle);
-	if (result) {
-	    US_DEBUGP("usb_request_irq failed (0x%x), No interrupt for CBI\n",
-		result);
-	    return DID_ABORT << 16;
-	}
+		/* add interrupt transfer, marked for removal */
+		us->ip_wanted = 1;
+		us->irqpipe = usb_rcvintpipe(us->pusb_dev, us->ep_int);
+		result = usb_request_irq(us->pusb_dev, us->irqpipe, pop_CBI_irq,
+					 IRQ_PERIOD, (void *)us, &us->irq_handle);
+		if (result) {
+			US_DEBUGP("usb_request_irq failed (0x%x), No interrupt for CBI\n",
+				  result);
+			return DID_ABORT << 16;
+		}
 
-	sleep_on(&us->ip_waitq);
+		sleep_on(&us->ip_waitq);
 #ifdef REWRITE_PROJECT
-    	usb_release_irq(us->pusb_dev, us->irq_handle, us->irqpipe);
-	us->irq_handle = NULL;
+		usb_release_irq(us->pusb_dev, us->irq_handle, us->irqpipe);
+		us->irq_handle = NULL;
 #endif
 
-	if (us->ip_wanted) {
-	    US_DEBUGP("Did not get interrupt on CBI\n");
-	    us->ip_wanted = 0;
-	    return DID_ABORT << 16;
-	}
+		if (us->ip_wanted) {
+			US_DEBUGP("Did not get interrupt on CBI\n");
+			us->ip_wanted = 0;
+			return DID_ABORT << 16;
+		}
 
-	US_DEBUGP("Got interrupt data %x\n", us->ip_data);
+		US_DEBUGP("Got interrupt data %x\n", us->ip_data);
 
-	/* sort out what it means */
+		/* sort out what it means */
 
-	if (us->subclass == US_SC_UFI) {
-	    /* gives us asc and ascq, as per request sense */
+		if (us->subclass == US_SC_UFI) {
+			/* gives us asc and ascq, as per request sense */
 
-	    if (srb->cmnd[0] == REQUEST_SENSE ||
-		srb->cmnd[0] == INQUIRY)
-		return DID_OK << 16;
-	    else
-		return (DID_OK << 16) + ((us->ip_data & 0xff) ? 2 : 0);
+			if (srb->cmnd[0] == REQUEST_SENSE ||
+			    srb->cmnd[0] == INQUIRY)
+				return DID_OK << 16;
+			else
+				return (DID_OK << 16) + ((us->ip_data & 0xff) ? 2 : 0);
+		}
+		if (us->ip_data & 0xff) {
+			US_DEBUGP("Bad CBI interrupt data %x\n", us->ip_data);
+			return DID_ABORT << 16;
+		}
+		return (DID_OK << 16) + ((us->ip_data & 0x300) ? 2 : 0);
 	}
-	if (us->ip_data & 0xff) {
-	    US_DEBUGP("Bad CBI interrupt data %x\n", us->ip_data);
-	    return DID_ABORT << 16;
-	}
-	return (DID_OK << 16) + ((us->ip_data & 0x300) ? 2 : 0);
-    }
-    return DID_ERROR << 16;
+	return DID_ERROR << 16;
 }
 
 /* Protocol command handlers */
 
 static int pop_CBI(Scsi_Cmnd *srb)
 {
-    int result;
+	int result;
 
-    /* run the command */
+	/* run the command */
 
-    if ((result = pop_CB_command(srb))) {
-	US_DEBUGP("CBI command %x\n", result);
-	if (result == USB_ST_STALL || result == USB_ST_TIMEOUT)	{
-	    return (DID_OK << 16) | 2;
+	if ((result = pop_CB_command(srb))) {
+		US_DEBUGP("CBI command %x\n", result);
+		if (result == USB_ST_STALL || result == USB_ST_TIMEOUT) {
+			return (DID_OK << 16) | 2;
+		}
+		return DID_ERROR << 16;
 	}
-	return DID_ERROR << 16;
-    }
 
-    /* transfer the data */
+	/* transfer the data */
 
-    if (us_transfer_length(srb)) {
-	result = us_transfer(srb, US_DIRECTION(srb->cmnd[0]));
-	if (result && result != USB_ST_DATAUNDERRUN && result != USB_ST_STALL) {
-	    US_DEBUGP("CBI transfer %x\n", result);
-	    return DID_ERROR << 16;
-	}
+	if (us_transfer_length(srb)) {
+		result = us_transfer(srb, US_DIRECTION(srb->cmnd[0]));
+		if (result && result != USB_ST_DATAUNDERRUN && result != USB_ST_STALL) {
+			US_DEBUGP("CBI transfer %x\n", result);
+			return DID_ERROR << 16;
+		}
 #if 0
-	else if (result == USB_ST_DATAUNDERRUN) {
-	    return DID_OK << 16;
-	}
-    } else {
-	if (!result) {
-	    return DID_OK << 16;
-	}
+		else if (result == USB_ST_DATAUNDERRUN) {
+			return DID_OK << 16;
+		}
+	} else {
+		if (!result) {
+			return DID_OK << 16;
+		}
 #endif
-    }
+	}
 
-    /* get status */
-    return pop_CB_status(srb);
+	/* get status */
+	return pop_CB_status(srb);
 }
 
 static int pop_Bulk_reset(struct us_data *us)
 {
-    int result;
+	int result;
 
-    result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
-			US_BULK_RESET, USB_TYPE_CLASS | USB_RT_INTERFACE,
-			US_BULK_RESET_HARD, us->ifnum,
-			NULL, 0, HZ*5);
-    if (result)
-	US_DEBUGP("Bulk hard reset failed %d\n", result);
-    usb_clear_halt(us->pusb_dev, us->ep_in | USB_DIR_IN);
-    usb_clear_halt(us->pusb_dev, us->ep_out | USB_DIR_OUT);
+	result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
+				 US_BULK_RESET, USB_TYPE_CLASS | USB_RT_INTERFACE,
+				 US_BULK_RESET_HARD, us->ifnum,
+				 NULL, 0, HZ*5);
+	if (result)
+		US_DEBUGP("Bulk hard reset failed %d\n", result);
+	usb_clear_halt(us->pusb_dev, us->ep_in | USB_DIR_IN);
+	usb_clear_halt(us->pusb_dev, us->ep_out | USB_DIR_OUT);
 
-    /* long wait for reset */
+	/* long wait for reset */
 
-    schedule_timeout(HZ*6);
+	schedule_timeout(HZ*6);
 
-    return result;
+	return result;
 }
 
 /*
  * The bulk only protocol handler.
- * 	Uses the in and out endpoints to transfer commands and data (nasty)
+ *	Uses the in and out endpoints to transfer commands and data (nasty)
  */
 static int pop_Bulk(Scsi_Cmnd *srb)
 {
-    struct us_data *us = (struct us_data *)srb->host_scribble;
-    struct bulk_cb_wrap bcb;
-    struct bulk_cs_wrap bcs;
-    int result;
-    unsigned long partial;
-    int stall;
-
-    /* set up the command wrapper */
-
-    bcb.Signature = US_BULK_CB_SIGN;
-    bcb.DataTransferLength = us_transfer_length(srb);;
-    bcb.Flags = US_DIRECTION(srb->cmnd[0]) << 7;
-    bcb.Tag = srb->serial_number;
-    bcb.Lun = 0;
-    memset(bcb.CDB, 0, sizeof(bcb.CDB));
-    memcpy(bcb.CDB, srb->cmnd, srb->cmd_len);
-    if (us->flags & US_FL_FIXED_COMMAND) {
-	bcb.Length = us->fixedlength;
-    } else {
-	bcb.Length = srb->cmd_len;
-    }
-
-    /* send it to out endpoint */
-
-    US_DEBUGP("Bulk command S %x T %x L %d F %d CL %d\n",
-		bcb.Signature, bcb.Tag, bcb.DataTransferLength,
-		bcb.Flags, bcb.Length);
-    result = usb_bulk_msg(us->pusb_dev,
-			usb_sndbulkpipe(us->pusb_dev, us->ep_out), &bcb,
-			US_BULK_CB_WRAP_LEN, &partial, HZ*5);
-    if (result) {
-	US_DEBUGP("Bulk command result %x\n", result);
-	return DID_ABORT << 16;
-    }
-
-    //return DID_BAD_TARGET << 16;
-    /* send/receive data */
-
-    if (bcb.DataTransferLength) {
-	result = us_transfer(srb, bcb.Flags);
-	if (result && result != USB_ST_DATAUNDERRUN && result != USB_ST_STALL) {
-	    US_DEBUGP("Bulk transfer result %x\n", result);
-	    return DID_ABORT << 16;
+	struct us_data *us = (struct us_data *)srb->host_scribble;
+	struct bulk_cb_wrap bcb;
+	struct bulk_cs_wrap bcs;
+	int result;
+	unsigned long partial;
+	int stall;
+
+	/* set up the command wrapper */
+
+	bcb.Signature = US_BULK_CB_SIGN;
+	bcb.DataTransferLength = us_transfer_length(srb);;
+	bcb.Flags = US_DIRECTION(srb->cmnd[0]) << 7;
+	bcb.Tag = srb->serial_number;
+	bcb.Lun = 0;
+	memset(bcb.CDB, 0, sizeof(bcb.CDB));
+	memcpy(bcb.CDB, srb->cmnd, srb->cmd_len);
+	if (us->flags & US_FL_FIXED_COMMAND) {
+		bcb.Length = us->fixedlength;
+	} else {
+		bcb.Length = srb->cmd_len;
 	}
-    }
 
-    /* get status */
+	/* send it to out endpoint */
 
-    stall = 0;
-    do {
+	US_DEBUGP("Bulk command S %x T %x L %d F %d CL %d\n",
+		  bcb.Signature, bcb.Tag, bcb.DataTransferLength,
+		  bcb.Flags, bcb.Length);
 	result = usb_bulk_msg(us->pusb_dev,
-			usb_rcvbulkpipe(us->pusb_dev, us->ep_in), &bcs,
-			US_BULK_CS_WRAP_LEN, &partial, HZ*5);
-	if (result == USB_ST_STALL || result == USB_ST_TIMEOUT)
-	    stall++;
-	else
-	    break;
-    } while ( stall < 3);
-    if (result && result != USB_ST_DATAUNDERRUN) {
-	US_DEBUGP("Bulk status result = %x\n", result);
-	return DID_ABORT << 16;
-    }
-
-    /* check bulk status */
-
-    US_DEBUGP("Bulk status S %x T %x R %d V %x\n",
-		bcs.Signature, bcs.Tag, bcs.Residue, bcs.Status);
-    if (bcs.Signature != US_BULK_CS_SIGN || bcs.Tag != bcb.Tag ||
-	bcs.Status > US_BULK_STAT_PHASE) {
-	US_DEBUGP("Bulk logical error\n");
-	return DID_ABORT << 16;
-    }
-    switch (bcs.Status) {
-    case US_BULK_STAT_OK:
-	return DID_OK << 16;
-
-    case US_BULK_STAT_FAIL:
-	/* check for underrun - dont report */
-	if (bcs.Residue)
-	    return DID_OK << 16;
-	//pop_Bulk_reset(us);
-	break;
+			      usb_sndbulkpipe(us->pusb_dev, us->ep_out), &bcb,
+			      US_BULK_CB_WRAP_LEN, &partial, HZ*5);
+	if (result) {
+		US_DEBUGP("Bulk command result %x\n", result);
+		return DID_ABORT << 16;
+	}
 
-    case US_BULK_STAT_PHASE:
-	return DID_ERROR << 16;
-    }
+	//return DID_BAD_TARGET << 16;
+	/* send/receive data */
+
+	if (bcb.DataTransferLength) {
+		result = us_transfer(srb, bcb.Flags);
+		if (result && result != USB_ST_DATAUNDERRUN && result != USB_ST_STALL) {
+			US_DEBUGP("Bulk transfer result %x\n", result);
+			return DID_ABORT << 16;
+		}
+	}
+
+	/* get status */
+
+	stall = 0;
+	do {
+		result = usb_bulk_msg(us->pusb_dev,
+				      usb_rcvbulkpipe(us->pusb_dev, us->ep_in), &bcs,
+				      US_BULK_CS_WRAP_LEN, &partial, HZ*5);
+		if (result == USB_ST_STALL || result == USB_ST_TIMEOUT)
+			stall++;
+		else
+			break;
+	} while ( stall < 3);
+	if (result && result != USB_ST_DATAUNDERRUN) {
+		US_DEBUGP("Bulk status result = %x\n", result);
+		return DID_ABORT << 16;
+	}
+
+	/* check bulk status */
+
+	US_DEBUGP("Bulk status S %x T %x R %d V %x\n",
+		  bcs.Signature, bcs.Tag, bcs.Residue, bcs.Status);
+	if (bcs.Signature != US_BULK_CS_SIGN || bcs.Tag != bcb.Tag ||
+	    bcs.Status > US_BULK_STAT_PHASE) {
+		US_DEBUGP("Bulk logical error\n");
+		return DID_ABORT << 16;
+	}
+	switch (bcs.Status) {
+	case US_BULK_STAT_OK:
+		return DID_OK << 16;
+
+	case US_BULK_STAT_FAIL:
+		/* check for underrun - dont report */
+		if (bcs.Residue)
+			return DID_OK << 16;
+		//pop_Bulk_reset(us);
+		break;
+
+	case US_BULK_STAT_PHASE:
+		return DID_ERROR << 16;
+	}
 
-    return (DID_OK << 16) | 2;		/* check sense required */
+	return (DID_OK << 16) | 2;		/* check sense required */
 }
 
 /* Host functions */
@@ -601,25 +601,25 @@
 /* detect adapter (always true ) */
 static int us_detect(struct SHT *sht)
 {
-    /* FIXME - not nice at all, but how else ? */
-    struct us_data *us = (struct us_data *)sht->proc_dir;
-    char name[32];
-
-    sprintf(name, "usbscsi%d", us->host_number);
-    sht->name = sht->proc_name = kmalloc(strlen(name)+1, GFP_KERNEL);
-    if (!sht->proc_name)
+	/* FIXME - not nice at all, but how else ? */
+	struct us_data *us = (struct us_data *)sht->proc_dir;
+	char name[32];
+
+	sprintf(name, "usbscsi%d", us->host_number);
+	sht->name = sht->proc_name = kmalloc(strlen(name)+1, GFP_KERNEL);
+	if (!sht->proc_name)
+		return 0;
+	strcpy(sht->proc_name, name);
+	sht->proc_dir = NULL;
+	us->host = scsi_register(sht, sizeof(us));
+	if (us->host) {
+		us->host->hostdata[0] = (unsigned long)us;
+		us->host_no = us->host->host_no;
+		return 1;
+	}
+	kfree(sht->proc_name);
+	sht->proc_name = sht->name = NULL;
 	return 0;
-    strcpy(sht->proc_name, name);
-    sht->proc_dir = NULL;
-    us->host = scsi_register(sht, sizeof(us));
-    if (us->host) {
-	us->host->hostdata[0] = (unsigned long)us;
-	us->host_no = us->host->host_no;
-	return 1;
-    }
-    kfree(sht->proc_name);
-    sht->proc_name = sht->name = NULL;
-    return 0;
 }
 
 /* release - must be here to stop scsi
@@ -628,71 +628,71 @@
  */
 static int us_release(struct Scsi_Host *psh)
 {
-    struct us_data *us = (struct us_data *)psh->hostdata[0];
-    struct us_data *prev = (struct us_data *)&us_list;
+	struct us_data *us = (struct us_data *)psh->hostdata[0];
+	struct us_data *prev = (struct us_data *)&us_list;
 
-    if (us->irq_handle) {
-    	usb_release_irq(us->pusb_dev, us->irq_handle, us->irqpipe);
-	us->irq_handle = NULL;
-    }
-    if (us->filter)
-	us->filter->release(us->fdata);
-    if (us->pusb_dev)
-	usb_deregister(&scsi_driver);
-
-    /* FIXME - leaves hanging host template copy */
-    /* (because scsi layer uses it after removal !!!) */
-    while (prev->next != us)
-	prev = prev->next;
-    prev->next = us->next;
-    return 0;
+	if (us->irq_handle) {
+		usb_release_irq(us->pusb_dev, us->irq_handle, us->irqpipe);
+		us->irq_handle = NULL;
+	}
+	if (us->filter)
+		us->filter->release(us->fdata);
+	if (us->pusb_dev)
+		usb_deregister(&scsi_driver);
+
+	/* FIXME - leaves hanging host template copy */
+	/* (because scsi layer uses it after removal !!!) */
+	while (prev->next != us)
+		prev = prev->next;
+	prev->next = us->next;
+	return 0;
 }
 
 /* run command */
 static int us_command( Scsi_Cmnd *srb )
 {
-    US_DEBUGP("Bad use of us_command\n");
+	US_DEBUGP("Bad use of us_command\n");
 
-    return DID_BAD_TARGET << 16;
+	return DID_BAD_TARGET << 16;
 }
 
 /* run command */
 static int us_queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *))
 {
-    struct us_data *us = (struct us_data *)srb->host->hostdata[0];
+	struct us_data *us = (struct us_data *)srb->host->hostdata[0];
 
-    US_DEBUGP("Command wakeup\n");
-    if (us->srb) {
-	/* busy */
-    }
-    srb->host_scribble = (unsigned char *)us;
-    us->srb = srb;
-    srb->scsi_done = done;
-    us->action = US_ACT_COMMAND;
+	US_DEBUGP("Command wakeup\n");
+	if (us->srb) {
+		/* busy */
+	}
+	srb->host_scribble = (unsigned char *)us;
+	us->srb = srb;
+	srb->scsi_done = done;
+	us->action = US_ACT_COMMAND;
 
-    /* wake up the process task */
+	/* wake up the process task */
 
-    wake_up_interruptible(&us->waitq);
+	wake_up_interruptible(&us->waitq);
 
-    return 0;
+	return 0;
 }
 
 static int us_abort( Scsi_Cmnd *srb )
 {
-    return 0;
+	return 0;
 }
 
 static int us_bus_reset( Scsi_Cmnd *srb )
 {
-    struct us_data *us = (struct us_data *)srb->host->hostdata[0];
+	struct us_data *us = (struct us_data *)srb->host->hostdata[0];
 
-    us->pop_reset(us);
-    return SUCCESS;
+	us->pop_reset(us);
+	return SUCCESS;
 }
 
 static int us_host_reset( Scsi_Cmnd *srb )
 {
-    return 0;
+	return 0;
 }
 
 #undef SPRINTF
@@ -700,62 +700,62 @@
 
 int usb_scsi_proc_info (char *buffer, char **start, off_t offset, int length, int hostno, int inout)
 {
-    struct us_data *us = us_list;
-    char *pos = buffer;
-    char *vendor;
-    char *product;
-    char *style = "";
-
-    /* find our data from hostno */
-
-    while (us) {
-	if (us->host_no == hostno)
-	    break;
-	us = us->next;
-    }
-
-    if (!us)
-	return -ESRCH;
-
-    /* null on outward */
-
-    if (inout)
-	return length;
-
-    if (!us->pusb_dev || !(vendor = usb_string(us->pusb_dev, us->pusb_dev->descriptor.iManufacturer)))
-	vendor = "?";
-    if (!us->pusb_dev || !(product = usb_string(us->pusb_dev, us->pusb_dev->descriptor.iProduct)))
-	product = "?";
-
-    switch (us->protocol) {
-    case US_PR_CB:
-	style = "Control/Bulk";
-	break;
-
-    case US_PR_CBI:
-	style = "Control/Bulk/Interrupt";
-	break;
-
-    case US_PR_ZIP:
-	style = "Bulk only";
-	break;
-
-    }
-    SPRINTF ("Host scsi%d: usb-scsi\n", hostno);
-    SPRINTF ("Device: %s %s - GUID " GUID_FORMAT "\n", vendor, product, GUID_ARGS(us->guid) );
-    SPRINTF ("Style: %s\n", style);
-
-    /*
-     * Calculate start of next buffer, and return value.
-     */
-    *start = buffer + offset;
-
-    if ((pos - buffer) < offset)
-	return (0);
-    else if ((pos - buffer - offset) < length)
-	return (pos - buffer - offset);
-    else
-	return (length);
+	struct us_data *us = us_list;
+	char *pos = buffer;
+	char *vendor;
+	char *product;
+	char *style = "";
+
+	/* find our data from hostno */
+
+	while (us) {
+		if (us->host_no == hostno)
+			break;
+		us = us->next;
+	}
+
+	if (!us)
+		return -ESRCH;
+
+	/* null on outward */
+
+	if (inout)
+		return length;
+
+	if (!us->pusb_dev || !(vendor = usb_string(us->pusb_dev, us->pusb_dev->descriptor.iManufacturer)))
+		vendor = "?";
+	if (!us->pusb_dev || !(product = usb_string(us->pusb_dev, us->pusb_dev->descriptor.iProduct)))
+		product = "?";
+
+	switch (us->protocol) {
+	case US_PR_CB:
+		style = "Control/Bulk";
+		break;
+
+	case US_PR_CBI:
+		style = "Control/Bulk/Interrupt";
+		break;
+
+	case US_PR_ZIP:
+		style = "Bulk only";
+		break;
+
+	}
+	SPRINTF ("Host scsi%d: usb-scsi\n", hostno);
+	SPRINTF ("Device: %s %s - GUID " GUID_FORMAT "\n", vendor, product, GUID_ARGS(us->guid) );
+	SPRINTF ("Style: %s\n", style);
+
+	/*
+	 * Calculate start of next buffer, and return value.
+	 */
+	*start = buffer + offset;
+
+	if ((pos - buffer) < offset)
+		return (0);
+	else if ((pos - buffer - offset) < length)
+		return (pos - buffer - offset);
+	else
+		return (length);
 }
 
 /*
@@ -763,599 +763,599 @@
  */
 
 static Scsi_Host_Template my_host_template = {
-    NULL,			/* next */
-    NULL,			/* module */
-    NULL,			/* proc_dir */
-    usb_scsi_proc_info,
-    NULL,			/* name - points to unique */
-    us_detect,
-    us_release,
-    NULL,			/* info */
-    NULL,			/* ioctl */
-    us_command,
-    us_queuecommand,
-    NULL,			/* eh_strategy */
-    us_abort,
-    us_bus_reset,
-    us_bus_reset,
-    us_host_reset,
-    NULL,			/* abort */
-    NULL,			/* reset */
-    NULL,			/* slave_attach */
-    NULL,			/* bios_param */
-    1,				/* can_queue */
-    -1,				/* this_id */
-    SG_ALL,			/* sg_tablesize */
-    1,				/* cmd_per_lun */
-    0,				/* present */
-    FALSE,			/* unchecked_isa_dma */
-    FALSE,			/* use_clustering */
-    TRUE,			/* use_new_eh_code */
-    TRUE			/* emulated */
+	NULL,			/* next */
+	NULL,			/* module */
+	NULL,			/* proc_dir */
+	usb_scsi_proc_info,
+	NULL,			/* name - points to unique */
+	us_detect,
+	us_release,
+	NULL,			/* info */
+	NULL,			/* ioctl */
+	us_command,
+	us_queuecommand,
+	NULL,			/* eh_strategy */
+	us_abort,
+	us_bus_reset,
+	us_bus_reset,
+	us_host_reset,
+	NULL,			/* abort */
+	NULL,			/* reset */
+	NULL,			/* slave_attach */
+	NULL,			/* bios_param */
+	1,				/* can_queue */
+	-1,				/* this_id */
+	SG_ALL,			/* sg_tablesize */
+	1,				/* cmd_per_lun */
+	0,				/* present */
+	FALSE,			/* unchecked_isa_dma */
+	FALSE,			/* use_clustering */
+	TRUE,			/* use_new_eh_code */
+	TRUE			/* emulated */
 };
 
 static unsigned char sense_notready[] = {
-    0x70,			/* current error */
-    0x00,
-    0x02,			/* not ready */
-    0x00,
-    0x00,
-    10,				/* additional length */
-    0x00,
-    0x00,
-    0x00,
-    0x00,
-    0x04,			/* not ready */
-    0x03,			/* manual intervention */
-    0x00,
-    0x00,
-    0x00,
-    0x00
+	0x70,			/* current error */
+	0x00,
+	0x02,			/* not ready */
+	0x00,
+	0x00,
+	10,				/* additional length */
+	0x00,
+	0x00,
+	0x00,
+	0x00,
+	0x04,			/* not ready */
+	0x03,			/* manual intervention */
+	0x00,
+	0x00,
+	0x00,
+	0x00
 };
 
 static int usbscsi_control_thread(void * __us)
 {
-    struct us_data *us = (struct us_data *)__us;
-    int action;
+	struct us_data *us = (struct us_data *)__us;
+	int action;
 
-    lock_kernel();
+	lock_kernel();
 
-    /*
-     * This thread doesn't need any user-level access,
-     * so get rid of all our resources..
-     */
-    exit_mm(current);
-    exit_files(current);
-    //exit_fs(current);
-
-    sprintf(current->comm, "usbscsi%d", us->host_number);
-
-    unlock_kernel();
-
-    up(us->notify);
-
-    for(;;) {
-	    siginfo_t info;
-	    int unsigned long signr;
-
-	    interruptible_sleep_on(&us->waitq);
-
-	    action = us->action;
-	    us->action = 0;
-
-	    switch (action) {
-	    case US_ACT_COMMAND:
-		if (us->srb->target || us->srb->lun) {
-		    /* bad device */
-		    US_DEBUGP( "Bad device number (%d/%d) or dev %x\n",
-			us->srb->target, us->srb->lun, (unsigned int)us->pusb_dev);
-		    us->srb->result = DID_BAD_TARGET << 16;
-		} else if (!us->pusb_dev) {
-
-		    /* our device has gone - pretend not ready */
-
-		    if (us->srb->cmnd[0] == REQUEST_SENSE) {
-			memcpy(us->srb->request_buffer, sense_notready, sizeof(sense_notready));
-			us->srb->result = DID_OK << 16;
-		    } else {
-			us->srb->result = (DID_OK << 16) | 2;
-		    }
-		} else {
-		    US_DEBUG(us_show_command(us->srb));
+	/*
+	 * This thread doesn't need any user-level access,
+	 * so get rid of all our resources..
+	 */
+	exit_mm(current);
+	exit_files(current);
+	//exit_fs(current);
+
+	sprintf(current->comm, "usbscsi%d", us->host_number);
+
+	unlock_kernel();
+
+	up(us->notify);
+
+	for(;;) {
+		siginfo_t info;
+		int unsigned long signr;
+
+		interruptible_sleep_on(&us->waitq);
+
+		action = us->action;
+		us->action = 0;
+
+		switch (action) {
+		case US_ACT_COMMAND:
+			if (us->srb->target || us->srb->lun) {
+				/* bad device */
+				US_DEBUGP( "Bad device number (%d/%d) or dev %x\n",
+					   us->srb->target, us->srb->lun, (unsigned int)us->pusb_dev);
+				us->srb->result = DID_BAD_TARGET << 16;
+			} else if (!us->pusb_dev) {
+
+				/* our device has gone - pretend not ready */
+
+				if (us->srb->cmnd[0] == REQUEST_SENSE) {
+					memcpy(us->srb->request_buffer, sense_notready, sizeof(sense_notready));
+					us->srb->result = DID_OK << 16;
+				} else {
+					us->srb->result = (DID_OK << 16) | 2;
+				}
+			} else {
+				US_DEBUG(us_show_command(us->srb));
 
-		    /* check for variable length - do properly if so */
+				/* check for variable length - do properly if so */
 
-		    if (us->filter && us->filter->command)
-			us->srb->result = us->filter->command(us->fdata, us->srb);
-		    else if (us->srb->cmnd[0] == START_STOP &&
-			     us->pusb_dev->descriptor.idProduct == 0x0001 &&
-			     us->pusb_dev->descriptor.idVendor == 0x04e6)
-			us->srb->result = DID_OK << 16;
-		    else {
-			unsigned int savelen = us->srb->request_bufflen;
-			unsigned int saveallocation = 0;
-
-			switch (us->srb->cmnd[0]) {
-			case REQUEST_SENSE:
-			    if (us->srb->request_bufflen > 18)
-				us->srb->request_bufflen = 18;
-			    else
-				break;
-			    saveallocation = us->srb->cmnd[4];
-			    us->srb->cmnd[4] = 18;
-			    break;
-
-			case INQUIRY:
-			    if (us->srb->request_bufflen > 36)
-				us->srb->request_bufflen = 36;
-			    else
-				break;
-			    saveallocation = us->srb->cmnd[4];
-			    us->srb->cmnd[4] = 36;
-			    break;
+				if (us->filter && us->filter->command)
+					us->srb->result = us->filter->command(us->fdata, us->srb);
+				else if (us->srb->cmnd[0] == START_STOP &&
+					 us->pusb_dev->descriptor.idProduct == 0x0001 &&
+					 us->pusb_dev->descriptor.idVendor == 0x04e6)
+					us->srb->result = DID_OK << 16;
+				else {
+					unsigned int savelen = us->srb->request_bufflen;
+					unsigned int saveallocation = 0;
+
+					switch (us->srb->cmnd[0]) {
+					case REQUEST_SENSE:
+						if (us->srb->request_bufflen > 18)
+							us->srb->request_bufflen = 18;
+						else
+							break;
+						saveallocation = us->srb->cmnd[4];
+						us->srb->cmnd[4] = 18;
+						break;
+
+					case INQUIRY:
+						if (us->srb->request_bufflen > 36)
+							us->srb->request_bufflen = 36;
+						else
+							break;
+						saveallocation = us->srb->cmnd[4];
+						us->srb->cmnd[4] = 36;
+						break;
+
+					case MODE_SENSE:
+						if (us->srb->request_bufflen > 4)
+							us->srb->request_bufflen = 4;
+						else
+							break;
+						saveallocation = us->srb->cmnd[4];
+						us->srb->cmnd[4] = 4;
+						break;
+
+					case LOG_SENSE:
+					case MODE_SENSE_10:
+						if (us->srb->request_bufflen > 8)
+							us->srb->request_bufflen = 8;
+						else
+							break;
+						saveallocation = (us->srb->cmnd[7] << 8) | us->srb->cmnd[8];
+						us->srb->cmnd[7] = 0;
+						us->srb->cmnd[8] = 8;
+						break;
+
+					default:
+						break;
+					} /* end switch on cmnd[0] */
+					us->srb->result = us->pop(us->srb);
+
+					if (savelen != us->srb->request_bufflen &&
+					    us->srb->result == (DID_OK << 16)) {
+						unsigned char *p = (unsigned char *)us->srb->request_buffer;
+						unsigned int length = 0;
+
+						/* set correct length and retry */
+						switch (us->srb->cmnd[0]) {
+						case REQUEST_SENSE:
+				/* simply return 18 bytes */
+							p[7] = 10;
+							length = us->srb->request_bufflen;;
+							break;
+
+						case INQUIRY:
+							length = p[4] + 5 > savelen ? savelen : p[4] + 5;
+							us->srb->cmnd[4] = length;
+							break;
+
+						case MODE_SENSE:
+							length = p[0] + 4 > savelen ? savelen : p[0] + 4;
+							us->srb->cmnd[4] = 4;
+							break;
+
+						case LOG_SENSE:
+							length = ((p[2] << 8) + p[3]) + 4 > savelen ? savelen : ((p[2] << 8) + p[3]) + 4;
+							us->srb->cmnd[7] = length >> 8;
+							us->srb->cmnd[8] = length;
+							break;
+
+						case MODE_SENSE_10:
+							length = ((p[0] << 8) + p[1]) + 8 > savelen ? savelen : ((p[0] << 8) + p[1]) + 8;
+							us->srb->cmnd[7] = length >> 8;
+							us->srb->cmnd[8] = length;
+							break;
+						} /* end switch on cmnd[0] */
+
+						US_DEBUGP("Old/New length = %d/%d\n",
+							  savelen, length);
+
+						if (us->srb->request_bufflen != length) {
+							US_DEBUGP("redoing cmd with len=%d\n", length);
+							us->srb->request_bufflen = length;
+							us->srb->result = us->pop(us->srb);
+						}
+						/* reset back to original values */
+
+						us->srb->request_bufflen = savelen;
+						switch (us->srb->cmnd[0]) {
+						case REQUEST_SENSE:
+						case INQUIRY:
+						case MODE_SENSE:
+							if (us->srb->use_sg == 0 && length > 0) {
+								int i;
+								printk(KERN_DEBUG "Data is");
+								for (i = 0; i < 32 && i < length; ++i)
+									printk(" %.2x", ((unsigned char *)us->srb->request_buffer)[i]);
+								if (i < length)
+									printk(" ...");
+								printk("\n");
+							}
+							us->srb->cmnd[4] = saveallocation;
+							if (us->mode_xlate) {
+								/* convert MODE_SENSE_10 return data
+								 * format to MODE_SENSE_6 format */
+								unsigned char *dta = (unsigned char *)us->srb->request_buffer;
+								dta[0] = dta[1];	/* data len */
+								dta[1] = dta[2];	/* med type */
+								dta[2] = dta[3];	/* dev-spec prm */
+								dta[3] = dta[7];	/* block desc len */
+								printk (KERN_DEBUG USB_SCSI "new MODE_SENSE_6 data = %.2X %.2X %.2X %.2X\n",
+									dta[0], dta[1], dta[2], dta[3]);
+							}
+							break;
+
+						case LOG_SENSE:
+						case MODE_SENSE_10:
+							us->srb->cmnd[7] = saveallocation >> 8;
+							us->srb->cmnd[8] = saveallocation;
+							break;
+						} /* end switch on cmnd[0] */
+					}
+					/* force attention on first command */
+					if (!us->attention_done) {
+						US_DEBUGP("forcing unit attention\n");
+						if (us->srb->cmnd[0] == REQUEST_SENSE) {
+							if (us->srb->result == (DID_OK << 16)) {
+								unsigned char *p = (unsigned char *)us->srb->request_buffer;
+
+								us->attention_done = 1;
+								if ((p[2] & 0x0f) != UNIT_ATTENTION) {
+									p[2] = UNIT_ATTENTION;
+									p[12] = 0x29;	/* power on, reset or bus-reset */
+									p[13] = 0;
+								}
+							}
+						} else if (us->srb->cmnd[0] != INQUIRY &&
+							   us->srb->result == (DID_OK << 16)) {
+							us->srb->result |= 2;	/* force check condition */
+						}
+					}
+				}
+			}
+			US_DEBUGP("scsi cmd done, result=%x\n", us->srb->result);
+			us->srb->scsi_done(us->srb);
+			us->srb = NULL;
+			break;
+
+		case US_ACT_ABORT:
+			break;
+
+		case US_ACT_DEVICE_RESET:
+			break;
+
+		case US_ACT_BUS_RESET:
+			break;
+
+		case US_ACT_HOST_RESET:
+			break;
+
+		} /* end switch on action */
+
+		if (signal_pending(current)) {
+			/* sending SIGUSR1 makes us print out some info */
+			spin_lock_irq(&current->sigmask_lock);
+			signr = dequeue_signal(&current->blocked, &info);
+			spin_unlock_irq(&current->sigmask_lock);
+
+			if (signr == SIGUSR2) {
+				usbscsi_debug = !usbscsi_debug;
+				printk(USB_SCSI "debug toggle = %d\n", usbscsi_debug);
+			} else {
+				break;	/* exit the loop on any other signal */
+			}
+		}
+	}
 
-			case MODE_SENSE:
-			    if (us->srb->request_bufflen > 4)
-				us->srb->request_bufflen = 4;
-			    else
-				break;
-			    saveallocation = us->srb->cmnd[4];
-			    us->srb->cmnd[4] = 4;
-			    break;
-
-			case LOG_SENSE:
-			case MODE_SENSE_10:
-			    if (us->srb->request_bufflen > 8)
-				us->srb->request_bufflen = 8;
-			    else
-				break;
-			    saveallocation = (us->srb->cmnd[7] << 8) | us->srb->cmnd[8];
-			    us->srb->cmnd[7] = 0;
-			    us->srb->cmnd[8] = 8;
-			    break;
+	MOD_DEC_USE_COUNT;
 
-			default:
-			    break;
-			} /* end switch on cmnd[0] */
-			us->srb->result = us->pop(us->srb);
-
-			if (savelen != us->srb->request_bufflen &&
-			    us->srb->result == (DID_OK << 16)) {
-			    unsigned char *p = (unsigned char *)us->srb->request_buffer;
-			    unsigned int length = 0;
-
-			    /* set correct length and retry */
-			    switch (us->srb->cmnd[0]) {
-			    case REQUEST_SENSE:
-				/* simply return 18 bytes */
-				p[7] = 10;
-				length = us->srb->request_bufflen;;
-				break;
+	printk("usbscsi_control_thread exiting\n");
 
-			    case INQUIRY:
-				length = p[4] + 5 > savelen ? savelen : p[4] + 5;
-				us->srb->cmnd[4] = length;
-				break;
+	return 0;
+}	
 
-			    case MODE_SENSE:
-				length = p[0] + 4 > savelen ? savelen : p[0] + 4;
-				us->srb->cmnd[4] = 4;
+static void * scsi_probe(struct usb_device *dev, unsigned int ifnum)
+{
+	struct usb_interface_descriptor *interface;
+	int i;
+	char *mf;		/* manufacturer */
+	char *prod;		/* product */
+	char *serial;		/* serial number */
+	struct us_data *ss = NULL;
+	struct usb_scsi_filter *filter = filters;
+	void *fdata = NULL;
+	unsigned int flags = 0;
+	GUID(guid);
+	struct us_data *prev;
+	Scsi_Host_Template *htmplt;
+	int protocol = 0;
+	int subclass = 0;
+
+	GUID_CLEAR(guid);
+	mf = usb_string(dev, dev->descriptor.iManufacturer);
+	prod = usb_string(dev, dev->descriptor.iProduct);
+	serial = usb_string(dev, dev->descriptor.iSerialNumber);
+
+	/* probe with filters first */
+
+	if (mf && prod) {
+		while (filter) {
+			if ((fdata = filter->probe(dev, mf, prod, serial)) != NULL) {
+				flags = filter->flags;
+				printk(KERN_INFO "USB Scsi filter %s\n", filter->name);
 				break;
+			}
+			filter = filter->next;
+		}
+	}
 
-			    case LOG_SENSE:
-				length = ((p[2] << 8) + p[3]) + 4 > savelen ? savelen : ((p[2] << 8) + p[3]) + 4;
-				us->srb->cmnd[7] = length >> 8;
-				us->srb->cmnd[8] = length;
-				break;
+	/* generic devices next */
 
-			    case MODE_SENSE_10:
-				length = ((p[0] << 8) + p[1]) + 8 > savelen ? savelen : ((p[0] << 8) + p[1]) + 8;
-				us->srb->cmnd[7] = length >> 8;
-				us->srb->cmnd[8] = length;
-				break;
-			    } /* end switch on cmnd[0] */
+	if (fdata == NULL) {
 
-			    US_DEBUGP("Old/New length = %d/%d\n",
-				savelen, length);
+		/* some exceptions */
+		if (dev->descriptor.idVendor == 0x04e6 &&
+		    dev->descriptor.idProduct == 0x0001) {
+			/* shuttle E-USB */
+			protocol = US_PR_CB;
+			subclass = US_SC_8070;	/* an assumption */
+		} else if (dev->descriptor.bDeviceClass != 0 ||
+			   dev->actconfig->interface[ifnum].altsetting[0].bInterfaceClass !=
+			   USB_CLASS_MASS_STORAGE ||
+			   dev->actconfig->interface[ifnum].altsetting[0].bInterfaceSubClass < US_SC_MIN ||
+			   dev->actconfig->interface[ifnum].altsetting[0].bInterfaceSubClass > US_SC_MAX) {
+			return NULL;
+		}
 
-			    if (us->srb->request_bufflen != length) {
-				US_DEBUGP("redoing cmd with len=%d\n", length);
-				us->srb->request_bufflen = length;
-				us->srb->result = us->pop(us->srb);
-			    }
-			    /* reset back to original values */
-
-			    us->srb->request_bufflen = savelen;
-			    switch (us->srb->cmnd[0]) {
-			    case REQUEST_SENSE:
-			    case INQUIRY:
-			    case MODE_SENSE:
-				if (us->srb->use_sg == 0 && length > 0) {
-				    int i;
-				    printk(KERN_DEBUG "Data is");
-				    for (i = 0; i < 32 && i < length; ++i)
-					printk(" %.2x", ((unsigned char *)us->srb->request_buffer)[i]);
-				    if (i < length)
-					printk(" ...");
-				    printk("\n");
-				}
-				us->srb->cmnd[4] = saveallocation;
-				if (us->mode_xlate) {
-					/* convert MODE_SENSE_10 return data
-					 * format to MODE_SENSE_6 format */
-					unsigned char *dta = (unsigned char *)us->srb->request_buffer;
-					dta[0] = dta[1];	/* data len */
-					dta[1] = dta[2];	/* med type */
-					dta[2] = dta[3];	/* dev-spec prm */
-					dta[3] = dta[7];	/* block desc len */
-					printk (KERN_DEBUG USB_SCSI "new MODE_SENSE_6 data = %.2X %.2X %.2X %.2X\n",
-						dta[0], dta[1], dta[2], dta[3]);
-				}
-				break;
+		/* now check if we have seen it before */
 
-			    case LOG_SENSE:
-			    case MODE_SENSE_10:
-				us->srb->cmnd[7] = saveallocation >> 8;
-				us->srb->cmnd[8] = saveallocation;
+		if (dev->descriptor.iSerialNumber &&
+		    usb_string(dev, dev->descriptor.iSerialNumber) ) {
+			make_guid(guid, dev->descriptor.idVendor, dev->descriptor.idProduct,
+				  usb_string(dev, dev->descriptor.iSerialNumber));
+		} else {
+			make_guid(guid, dev->descriptor.idVendor, dev->descriptor.idProduct,
+				  "0");
+		}
+		for (ss = us_list; ss; ss = ss->next) {
+			if (!ss->pusb_dev && GUID_EQUAL(guid, ss->guid))	{
+				US_DEBUGP("Found existing GUID " GUID_FORMAT "\n",
+					  GUID_ARGS(guid));
+				flags = ss->flags;
 				break;
-			    } /* end switch on cmnd[0] */
 			}
-			/* force attention on first command */
-			if (!us->attention_done) {
-			    US_DEBUGP("forcing unit attention\n");
-			    if (us->srb->cmnd[0] == REQUEST_SENSE) {
-				if (us->srb->result == (DID_OK << 16)) {
-				    unsigned char *p = (unsigned char *)us->srb->request_buffer;
-
-				    us->attention_done = 1;
-				    if ((p[2] & 0x0f) != UNIT_ATTENTION) {
-					p[2] = UNIT_ATTENTION;
-					p[12] = 0x29;	/* power on, reset or bus-reset */
-					p[13] = 0;
-				    }
-				}
-			    } else if (us->srb->cmnd[0] != INQUIRY &&
-				    us->srb->result == (DID_OK << 16)) {
-				us->srb->result |= 2;	/* force check condition */
-			    }
-			}
-		    }
 		}
-		US_DEBUGP("scsi cmd done, result=%x\n", us->srb->result);
-		us->srb->scsi_done(us->srb);
-		us->srb = NULL;
-		break;
+	}
 
-	    case US_ACT_ABORT:
-		break;
+	if (!ss) {
+		if ((ss = (struct us_data *)kmalloc(sizeof(*ss), GFP_KERNEL)) == NULL) {
+			printk(KERN_WARNING USB_SCSI "Out of memory\n");
+			if (filter)
+				filter->release(fdata);
+			return NULL;
+		}
+		memset(ss, 0, sizeof(struct us_data));
+	}
+
+	interface = &dev->actconfig->interface[ifnum].altsetting[0];
+	ss->filter = filter;
+	ss->fdata = fdata;
+	ss->flags = flags;
+	if (subclass) {
+		ss->subclass = subclass;
+		ss->protocol = protocol;
+	} else {
+		ss->subclass = interface->bInterfaceSubClass;
+		ss->protocol = interface->bInterfaceProtocol;
+	}
+	ss->attention_done = 0;
+
+	/* set the protocol op */
 
-	    case US_ACT_DEVICE_RESET:
+	US_DEBUGP("Protocol ");
+	switch (ss->protocol) {
+	case US_PR_CB:
+		US_DEBUGPX("Control/Bulk\n");
+		ss->pop = pop_CBI;
+		ss->pop_reset = pop_CB_reset;
 		break;
 
-	    case US_ACT_BUS_RESET:
+	case US_PR_CBI:
+		US_DEBUGPX("Control/Bulk/Interrupt\n");
+		ss->pop = pop_CBI;
+		ss->pop_reset = pop_CB_reset;
 		break;
 
-	    case US_ACT_HOST_RESET:
+	default:
+		US_DEBUGPX("Bulk\n");
+		ss->pop = pop_Bulk;
+		ss->pop_reset = pop_Bulk_reset;
 		break;
+	}
 
-	    } /* end switch on action */
+	/*
+	 * We are expecting a minimum of 2 endpoints - in and out (bulk).
+	 * An optional interrupt is OK (necessary for CBI protocol).
+	 * We will ignore any others.
+	 */
+
+	for (i = 0; i < interface->bNumEndpoints; i++) {
+		if ((interface->endpoint[i].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+		    == USB_ENDPOINT_XFER_BULK) {
+			if (interface->endpoint[i].bEndpointAddress & USB_DIR_IN)
+				ss->ep_in = interface->endpoint[i].bEndpointAddress &
+					USB_ENDPOINT_NUMBER_MASK;
+			else
+				ss->ep_out = interface->endpoint[i].bEndpointAddress &
+					USB_ENDPOINT_NUMBER_MASK;
+		} else if ((interface->endpoint[i].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+			   == USB_ENDPOINT_XFER_INT) {
+			ss->ep_int = interface->endpoint[i].bEndpointAddress &
+				USB_ENDPOINT_NUMBER_MASK;
+		}
+	}
+	US_DEBUGP("Endpoints In %d Out %d Int %d\n",
+		  ss->ep_in, ss->ep_out, ss->ep_int);
 
-	    if (signal_pending(current)) {
-		    /* sending SIGUSR1 makes us print out some info */
-		    spin_lock_irq(&current->sigmask_lock);
-		    signr = dequeue_signal(&current->blocked, &info);
-		    spin_unlock_irq(&current->sigmask_lock);
-
-		    if (signr == SIGUSR2) {
-			    usbscsi_debug = !usbscsi_debug;
-			    printk(USB_SCSI "debug toggle = %d\n", usbscsi_debug);
-		    } else {
-			    break;	/* exit the loop on any other signal */
-		    }
-	    }
-    }
+	/* save the interface number */
+	ss->ifnum = ifnum;
 
-    MOD_DEC_USE_COUNT;
+	/* exit if strange looking */
 
-    printk("usbscsi_control_thread exiting\n");
+	if (usb_set_interface(dev, interface->bInterfaceNumber, 0) ||
+	    !ss->ep_in || !ss->ep_out || (ss->protocol == US_PR_CBI && ss->ep_int == 0)) {
+		US_DEBUGP("Problems with device\n");
+		if (ss->host) {
+			scsi_unregister_module(MODULE_SCSI_HA, ss->htmplt);
+			kfree(ss->htmplt->name);
+			kfree(ss->htmplt);
+		}
+		if (filter)
+			filter->release(fdata);
+		kfree(ss);
+		return NULL;			/* no endpoints */
+	}
 
-    return 0;
-}	
+	if (dev->actconfig->iConfiguration && usb_string(dev, dev->actconfig->iConfiguration))
+		US_DEBUGP("Configuration %s\n",
+			  usb_string(dev, dev->actconfig->iConfiguration));
+	if (interface->iInterface && usb_string(dev, interface->iInterface))
+		US_DEBUGP("Interface %s\n",
+			  usb_string(dev, interface->iInterface));
+
+	ss->pusb_dev = dev;
+
+	/* Now generate a scsi host definition, and register with scsi above us */
+
+	if (!ss->host) {
+
+		/* make unique id if possible */
+
+		US_DEBUGP("New GUID " GUID_FORMAT "\n", GUID_ARGS(guid));
+		memcpy(ss->guid, guid, sizeof(guid));
+
+		/* set class specific stuff */
+
+		US_DEBUGP("SubClass ");
+		switch (ss->subclass) {
+		case US_SC_RBC:
+			US_DEBUGPX("Reduced Block Commands\n");
+			break;
+		case US_SC_8020:
+			US_DEBUGPX("8020\n");
+			break;
+		case US_SC_QIC:
+			US_DEBUGPX("QIC157\n");
+			break;
+		case US_SC_8070:
+			US_DEBUGPX("8070\n");
+			ss->flags |= US_FL_FIXED_COMMAND;
+			ss->fixedlength = 12;
+			break;
+		case US_SC_SCSI:
+			US_DEBUGPX("Transparent SCSI\n");
+			break;
+		case US_SC_UFI:
+			US_DEBUGPX(" UFF\n");
+			ss->flags |= US_FL_FIXED_COMMAND;
+			ss->fixedlength = 12;
+			break;
 
-static void * scsi_probe(struct usb_device *dev, unsigned int ifnum)
-{
-    struct usb_interface_descriptor *interface;
-    int i;
-    char *mf;		/* manufacturer */
-    char *prod;		/* product */
-    char *serial;		/* serial number */
-    struct us_data *ss = NULL;
-    struct usb_scsi_filter *filter = filters;
-    void *fdata = NULL;
-    unsigned int flags = 0;
-    GUID(guid);
-    struct us_data *prev;
-    Scsi_Host_Template *htmplt;
-    int protocol = 0;
-    int subclass = 0;
-
-    GUID_CLEAR(guid);
-    mf = usb_string(dev, dev->descriptor.iManufacturer);
-    prod = usb_string(dev, dev->descriptor.iProduct);
-    serial = usb_string(dev, dev->descriptor.iSerialNumber);
-
-    /* probe with filters first */
-
-    if (mf && prod)	{
-	    while (filter) {
-		    if ((fdata = filter->probe(dev, mf, prod, serial)) != NULL) {
-			    flags = filter->flags;
-			    printk(KERN_INFO "USB Scsi filter %s\n", filter->name);
-			    break;
-		    }
-		    filter = filter->next;
-	    }
-    }
-
-    /* generic devices next */
-
-    if (fdata == NULL) {
-
-	/* some exceptions */
-	if (dev->descriptor.idVendor == 0x04e6 &&
-	    dev->descriptor.idProduct == 0x0001) {
-	    /* shuttle E-USB */
-	    protocol = US_PR_CB;
-	    subclass = US_SC_8070;	/* an assumption */
-	} else if (dev->descriptor.bDeviceClass != 0 ||
-	    dev->actconfig->interface[ifnum].altsetting[0].bInterfaceClass !=
-		USB_CLASS_MASS_STORAGE ||
-	    dev->actconfig->interface[ifnum].altsetting[0].bInterfaceSubClass < US_SC_MIN ||
-	    dev->actconfig->interface[ifnum].altsetting[0].bInterfaceSubClass > US_SC_MAX) {
-	    return NULL;
-	}
-
-	/* now check if we have seen it before */
-
-	if (dev->descriptor.iSerialNumber &&
-	    usb_string(dev, dev->descriptor.iSerialNumber) ) {
-	    make_guid(guid, dev->descriptor.idVendor, dev->descriptor.idProduct,
-		usb_string(dev, dev->descriptor.iSerialNumber));
-	} else {
-	    make_guid(guid, dev->descriptor.idVendor, dev->descriptor.idProduct,
-		"0");
-	}
-	for (ss = us_list; ss; ss = ss->next) {
-	    if (!ss->pusb_dev && GUID_EQUAL(guid, ss->guid))	{
-		US_DEBUGP("Found existing GUID " GUID_FORMAT "\n",
-			GUID_ARGS(guid));
-		flags = ss->flags;
-		break;
-	    }
-	}
-    }
+		default:
+			break;
+		}
 
-    if (!ss) {
-	if ((ss = (struct us_data *)kmalloc(sizeof(*ss), GFP_KERNEL)) == NULL) {
-	    printk(KERN_WARNING USB_SCSI "Out of memory\n");
-	    if (filter)
-		    filter->release(fdata);
-	    return NULL;
-	}
-	memset(ss, 0, sizeof(struct us_data));
-    }
-
-    interface = &dev->actconfig->interface[ifnum].altsetting[0];
-    ss->filter = filter;
-    ss->fdata = fdata;
-    ss->flags = flags;
-    if (subclass) {
-	ss->subclass = subclass;
-	ss->protocol = protocol;
-    } else {
-	ss->subclass = interface->bInterfaceSubClass;
-	ss->protocol = interface->bInterfaceProtocol;
-    }
-    ss->attention_done = 0;
-
-    /* set the protocol op */
-
-    US_DEBUGP("Protocol ");
-    switch (ss->protocol) {
-    case US_PR_CB:
-	US_DEBUGPX("Control/Bulk\n");
-	ss->pop = pop_CBI;
-	ss->pop_reset = pop_CB_reset;
-	break;
-
-    case US_PR_CBI:
-	US_DEBUGPX("Control/Bulk/Interrupt\n");
-	ss->pop = pop_CBI;
-	ss->pop_reset = pop_CB_reset;
-	break;
-
-    default:
-	US_DEBUGPX("Bulk\n");
-	ss->pop = pop_Bulk;
-	ss->pop_reset = pop_Bulk_reset;
-	break;
-    }
-
-    /*
-     * We are expecting a minimum of 2 endpoints - in and out (bulk).
-     * An optional interrupt is OK (necessary for CBI protocol).
-     * We will ignore any others.
-     */
-
-    for (i = 0; i < interface->bNumEndpoints; i++) {
-	    if ((interface->endpoint[i].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-			== USB_ENDPOINT_XFER_BULK) {
-		    if (interface->endpoint[i].bEndpointAddress & USB_DIR_IN)
-			    ss->ep_in = interface->endpoint[i].bEndpointAddress &
-				USB_ENDPOINT_NUMBER_MASK;
-		    else
-			    ss->ep_out = interface->endpoint[i].bEndpointAddress &
-				USB_ENDPOINT_NUMBER_MASK;
-	    } else if ((interface->endpoint[i].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-			== USB_ENDPOINT_XFER_INT) {
-		    ss->ep_int = interface->endpoint[i].bEndpointAddress &
-				USB_ENDPOINT_NUMBER_MASK;
-	    }
-    }
-    US_DEBUGP("Endpoints In %d Out %d Int %d\n",
-		ss->ep_in, ss->ep_out, ss->ep_int);
-
-    /* save the interface number */
-    ss->ifnum = ifnum;
-
-    /* exit if strange looking */
-
-    if (usb_set_interface(dev, interface->bInterfaceNumber, 0) ||
-	!ss->ep_in || !ss->ep_out || (ss->protocol == US_PR_CBI && ss->ep_int == 0)) {
-	US_DEBUGP("Problems with device\n");
-	if (ss->host) {
-	    scsi_unregister_module(MODULE_SCSI_HA, ss->htmplt);
-	    kfree(ss->htmplt->name);
-	    kfree(ss->htmplt);
-	}
-	if (filter)
-		filter->release(fdata);
-	kfree(ss);
-	return NULL;			/* no endpoints */
-    }
-
-    if (dev->actconfig->iConfiguration && usb_string(dev, dev->actconfig->iConfiguration))
-	US_DEBUGP("Configuration %s\n",
-		usb_string(dev, dev->actconfig->iConfiguration));
-    if (interface->iInterface && usb_string(dev, interface->iInterface))
-	US_DEBUGP("Interface %s\n",
-		usb_string(dev, interface->iInterface));
-
-    ss->pusb_dev = dev;
-
-    /* Now generate a scsi host definition, and register with scsi above us */
-
-    if (!ss->host) {
-
-	/* make unique id if possible */
-
-	US_DEBUGP("New GUID " GUID_FORMAT "\n", GUID_ARGS(guid));
-	memcpy(ss->guid, guid, sizeof(guid));
-
-	/* set class specific stuff */
-
-	US_DEBUGP("SubClass ");
-	switch (ss->subclass) {
-	case US_SC_RBC:
-	    US_DEBUGPX("Reduced Block Commands\n");
-	    break;
-	case US_SC_8020:
-	    US_DEBUGPX("8020\n");
-	    break;
-	case US_SC_QIC:
-	    US_DEBUGPX("QIC157\n");
-	    break;
-	case US_SC_8070:
-	    US_DEBUGPX("8070\n");
-	    ss->flags |= US_FL_FIXED_COMMAND;
-	    ss->fixedlength = 12;
-	    break;
-	case US_SC_SCSI:
-	    US_DEBUGPX("Transparent SCSI\n");
-	    break;
-	case US_SC_UFI:
-	    US_DEBUGPX(" UFF\n");
-	    ss->flags |= US_FL_FIXED_COMMAND;
-	    ss->fixedlength = 12;
-	    break;
+		/* create unique host template */
 
-	default:
-	    break;
-	}
+		if ((htmplt = (Scsi_Host_Template *)kmalloc(sizeof(*ss->htmplt), GFP_KERNEL)) == NULL ) {
+			printk(KERN_WARNING USB_SCSI "Out of memory\n");
+			if (filter)
+				filter->release(fdata);
+			kfree(ss);
+			return NULL;
+		}
+		memcpy(htmplt, &my_host_template, sizeof(my_host_template));
+		ss->host_number = my_host_number++;
 
-	/* create unique host template */
+		(struct us_data *)htmplt->proc_dir = ss;
 
-	if ((htmplt = (Scsi_Host_Template *)kmalloc(sizeof(*ss->htmplt), GFP_KERNEL)) == NULL ) {
-	    printk(KERN_WARNING USB_SCSI "Out of memory\n");
-	    if (filter)
-		    filter->release(fdata);
-	    kfree(ss);
-	    return NULL;
-	}
-	memcpy(htmplt, &my_host_template, sizeof(my_host_template));
-	ss->host_number = my_host_number++;
-
-	(struct us_data *)htmplt->proc_dir = ss;
-
-	if (dev->descriptor.idVendor == 0x04e6 &&
-	    dev->descriptor.idProduct == 0x0001) {
-	    __u8 qstat[2];
-	    int result;
-
-	    /* shuttle E-USB */
-	    result = usb_control_msg(ss->pusb_dev, usb_rcvctrlpipe(dev,0),
-			1, 0xC0,
-			0, ss->ifnum,
-			qstat, 2, HZ*5);
-	    US_DEBUGP("C0 status %x %x\n", qstat[0], qstat[1]);
-	    init_waitqueue_head(&ss->ip_waitq);
-	    ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int);
-	    result = usb_request_irq(ss->pusb_dev, ss->irqpipe, pop_CBI_irq,
-				IRQ_PERIOD, (void *)ss, &ss->irq_handle);
-	    if (result)
-	    	return NULL;
+		if (dev->descriptor.idVendor == 0x04e6 &&
+		    dev->descriptor.idProduct == 0x0001) {
+			__u8 qstat[2];
+			int result;
+
+			/* shuttle E-USB */
+			result = usb_control_msg(ss->pusb_dev, usb_rcvctrlpipe(dev,0),
+						 1, 0xC0,
+						 0, ss->ifnum,
+						 qstat, 2, HZ*5);
+			US_DEBUGP("C0 status %x %x\n", qstat[0], qstat[1]);
+			init_waitqueue_head(&ss->ip_waitq);
+			ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int);
+			result = usb_request_irq(ss->pusb_dev, ss->irqpipe, pop_CBI_irq,
+						 IRQ_PERIOD, (void *)ss, &ss->irq_handle);
+			if (result)
+				return NULL;
 
-	    interruptible_sleep_on_timeout(&ss->ip_waitq, HZ*6);
+			interruptible_sleep_on_timeout(&ss->ip_waitq, HZ*6);
 #ifdef REWRITE_PROJECT
-	    /* FIXME: Don't know if this release_irq() call is at the
-		right place/time. */
-    	    usb_release_irq(ss->pusb_dev, ss->irq_handle, ss->irqpipe);
-	    ss->irq_handle = NULL;
+			/* FIXME: Don't know if this release_irq() call is at the
+			   right place/time. */
+			usb_release_irq(ss->pusb_dev, ss->irq_handle, ss->irqpipe);
+			ss->irq_handle = NULL;
 #endif
 
-	} else if (ss->protocol == US_PR_CBI)
-	    init_waitqueue_head(&ss->ip_waitq);
+		} else if (ss->protocol == US_PR_CBI)
+			init_waitqueue_head(&ss->ip_waitq);
 
-	/* start up our thread */
+		/* start up our thread */
 
-	{
-	    DECLARE_MUTEX_LOCKED(sem);
+		{
+			DECLARE_MUTEX_LOCKED(sem);
 
-	    init_waitqueue_head(&ss->waitq);
-
-	    ss->notify = &sem;
-	    ss->pid = kernel_thread(usbscsi_control_thread, ss,
-		    CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
-	    if (ss->pid < 0) {
-		printk(KERN_WARNING USB_SCSI "Unable to start control thread\n");
-		kfree(htmplt);
-		if (filter)
-			filter->release(fdata);
-		kfree(ss);
-		return NULL;
-	    }
+			init_waitqueue_head(&ss->waitq);
+
+			ss->notify = &sem;
+			ss->pid = kernel_thread(usbscsi_control_thread, ss,
+						CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+			if (ss->pid < 0) {
+				printk(KERN_WARNING USB_SCSI "Unable to start control thread\n");
+				kfree(htmplt);
+				if (filter)
+					filter->release(fdata);
+				kfree(ss);
+				return NULL;
+			}
 
-	    /* wait for it to start */
+			/* wait for it to start */
 
-	    down(&sem);
-	}
+			down(&sem);
+		}
 
-	/* now register - our detect function will be called */
+		/* now register - our detect function will be called */
 
-	scsi_register_module(MODULE_SCSI_HA, htmplt);
+		scsi_register_module(MODULE_SCSI_HA, htmplt);
 
-	/* put us in the list */
+		/* put us in the list */
 
-	prev = (struct us_data *)&us_list;
-	while (prev->next)
-	    prev = prev->next;
-	prev->next = ss;
-    }
+		prev = (struct us_data *)&us_list;
+		while (prev->next)
+			prev = prev->next;
+		prev->next = ss;
+	}
 
-    printk(KERN_WARNING "DANGEROUS: USB SCSI driver data integrity not assured !!!\n");
-    printk(KERN_INFO "USB SCSI device found at address %d\n", dev->devnum);
+	printk(KERN_WARNING "DANGEROUS: USB SCSI driver data integrity not assured !!!\n");
+	printk(KERN_INFO "USB SCSI device found at address %d\n", dev->devnum);
 
-    return ss;
+	return ss;
 }
 
 static void scsi_disconnect(struct usb_device *dev, void *ptr)
@@ -1363,7 +1363,7 @@
 	struct us_data *ss = ptr;
 
 	if (!ss)
-	    return;
+		return;
 	if (ss->filter)
 		ss->filter->release(ss->fdata);
 	ss->pusb_dev = NULL;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)