patch-2.4.0-test5 linux/drivers/usb/storage/usb.c

Next file: linux/drivers/usb/storage/usb.h
Previous file: linux/drivers/usb/storage/transport.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test4/linux/drivers/usb/storage/usb.c linux/drivers/usb/storage/usb.c
@@ -1,6 +1,6 @@
 /* Driver for USB Mass Storage compliant devices
  *
- * $Id: usb.c,v 1.3 2000/06/27 10:20:39 mdharm Exp $
+ * $Id: usb.c,v 1.11 2000/07/24 20:37:24 mdharm Exp $
  *
  * Current development and maintainance by:
  *   (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -43,16 +43,18 @@
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/config.h>
+
 #include "usb.h"
 #include "scsiglue.h"
 #include "transport.h"
 #include "protocol.h"
 #include "debug.h"
+#if defined(CONFIG_USB_STORAGE_HP8200e) || defined(CONFIG_USB_STORAGE_SDDR09)
+#include "scm.h"
+#endif
 
 #include <linux/module.h>
- /*FIXME: note that this next include is needed for the new sleeping system
-  * which is not implemented yet
-  */
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/init.h>
@@ -88,6 +90,7 @@
 
 static int usb_stor_control_thread(void * __us)
 {
+	wait_queue_t wait;
 	struct us_data *us = (struct us_data *)__us;
 	int action;
 
@@ -97,6 +100,9 @@
 	 * This thread doesn't need any user-level access,
 	 * so get rid of all our resources..
 	 */
+	exit_files(current);
+	current->files = init_task.files;
+	atomic_inc(&current->files->count);
 	daemonize();
 
 	/* set our name for identification purposes */
@@ -104,15 +110,23 @@
 
 	unlock_kernel();
 
+	/* set up for wakeups by new commands */
+	init_waitqueue_entry(&wait, current);
+	init_waitqueue_head(&(us->wqh));
+	add_wait_queue(&(us->wqh), &wait);
+
 	/* signal that we've started the thread */
 	up(&(us->notify));
 
 	for(;;) {
+		set_current_state(TASK_INTERRUPTIBLE);
 		US_DEBUGP("*** thread sleeping.\n");
-		down(&(us->sleeper));
-		down(&(us->queue_exclusion));
+		schedule();
 		US_DEBUGP("*** thread awakened.\n");
 
+		/* lock access to the queue element */
+		down(&(us->queue_exclusion));
+
 		/* take the command off the queue */
 		action = us->action;
 		us->action = 0;
@@ -216,6 +230,11 @@
 static struct us_unusual_dev us_unusual_dev_list[] = {
 	{ 0x03f0, 0x0107, 0x0200, 0x0200, "HP USB CD-Writer Plus",
 		US_SC_8070, US_PR_CB, 0}, 
+#ifdef CONFIG_USB_STORAGE_HP8200e
+	{ 0x03f0, 0x0207, 0x0001, 0x0001, "HP USB CD-Writer Plus 8200e",
+		US_SC_8070, US_PR_SCM_ATAPI, 
+		US_FL_ALT_LENGTH | US_FL_NEED_INIT | US_FL_SINGLE_LUN}, 
+#endif
 	{ 0x04e6, 0x0001, 0x0200, 0x0200, "Matshita LS-120",
 		US_SC_8020, US_PR_CB, US_FL_SINGLE_LUN},
 	{ 0x04e6, 0x0002, 0x0100, 0x0100, "Shuttle eUSCSI Bridge",
@@ -236,6 +255,11 @@
 		US_SC_SCSI, US_PR_BULK, US_FL_ALT_LENGTH},
 	{ 0x0781, 0x0001, 0x0200, 0x0200, "Sandisk ImageMate (SDDR-01)",
 		US_SC_SCSI, US_PR_CB, US_FL_SINGLE_LUN | US_FL_START_STOP},
+#ifdef CONFIG_USB_STORAGE_SDDR09
+	{ 0x0781, 0x0200, 0x0100, 0x0100, "Sandisk ImageMate (SDDR-09)",
+		US_SC_SCSI, US_PR_SCM_SCSI,
+		US_FL_SINGLE_LUN | US_FL_START_STOP | US_FL_NEED_INIT},
+#endif
 	{ 0x0781, 0x0002, 0x0009, 0x0009, "Sandisk Imagemate (SDDR-31)",
 		US_SC_SCSI, US_PR_BULK, US_FL_IGNORE_SER},
 	{ 0x07af, 0x0004, 0x0100, 0x0100, "Microtech USB-SCSI-DB25",
@@ -422,7 +446,15 @@
 		  ep_in, ep_out, ep_int, ep_int ? ep_int->bInterval : 0);
 
 	/* set the interface -- STALL is an acceptable response here */
+#ifdef CONFIG_USB_STORAGE_SDDR09
+	if (protocol != US_PR_SCM_SCSI)
+		result = usb_set_interface(dev, 
+			altsetting->bInterfaceNumber, 0);
+	else
+		result = usb_set_configuration(dev, 1);
+#else
 	result = usb_set_interface(dev, altsetting->bInterfaceNumber, 0);
+#endif
 	US_DEBUGP("Result from usb_set_interface is %d\n", result);
 	if (result == -EPIPE) {
 		US_DEBUGP("-- clearing stall on control interface\n");
@@ -495,6 +527,12 @@
 				USB_ENDPOINT_NUMBER_MASK;
 		ss->ep_int = ep_int;
 
+                /* Reset the device's NEED_INIT flag if it needs to be
+                   initialized with a magic sequence */
+
+                if (flags & US_FL_NEED_INIT)
+                        ss->flags |= US_FL_NEED_INIT;
+
 		/* allocate an IRQ callback if one is needed */
 		if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss))
 			return NULL;
@@ -518,7 +556,6 @@
 		}
 
 		/* Initialize the mutexes only when the struct is new */
-		init_MUTEX_LOCKED(&(ss->sleeper));
 		init_MUTEX_LOCKED(&(ss->notify));
 		init_MUTEX_LOCKED(&(ss->ip_waitq));
 		init_MUTEX(&(ss->queue_exclusion));
@@ -584,6 +621,24 @@
 			ss->max_lun = usb_stor_Bulk_max_lun(ss);
 			break;
 			
+#ifdef CONFIG_USB_STORAGE_HP8200e
+		case US_PR_SCM_ATAPI:
+			ss->transport_name = "SCM/ATAPI";
+			ss->transport = hp8200e_transport;
+			ss->transport_reset = usb_stor_CB_reset;
+			ss->max_lun = 1;
+			break;
+#endif
+
+#ifdef CONFIG_USB_STORAGE_SDDR09
+		case US_PR_SCM_SCSI:
+			ss->transport_name = "SCM/SCSI";
+			ss->transport = sddr09_transport;
+			ss->transport_reset = usb_stor_CB_reset;
+			ss->max_lun = 1;
+			break;
+#endif
+			
 		default:
 			ss->transport_name = "Unknown";
 			up(&us_list_semaphore);
@@ -669,8 +724,7 @@
 		
 		/* start up our control thread */
 		ss->pid = kernel_thread(usb_stor_control_thread, ss,
-					CLONE_FS | CLONE_FILES |
-					CLONE_SIGHAND);
+					CLONE_VM);
 		if (ss->pid < 0) {
 			printk(KERN_WARNING USB_STORAGE 
 			       "Unable to start control thread\n");

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