patch-2.4.0-test9 linux/drivers/scsi/st.c

Next file: linux/drivers/scsi/sun3_scsi.c
Previous file: linux/drivers/scsi/sr.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/st.c linux/drivers/scsi/st.c
@@ -155,7 +155,7 @@
 static int st_detect(Scsi_Device *);
 static void st_detach(Scsi_Device *);
 
-struct Scsi_Device_Template st_template =
+static struct Scsi_Device_Template st_template =
 {
 	name:"tape", 
 	tag:"st", 
@@ -173,6 +173,47 @@
 static int update_partition(Scsi_Tape *);
 
 static int st_int_ioctl(Scsi_Tape *, unsigned int, unsigned long);
+
+
+/* #include "osst_detect.h" */
+#ifndef SIGS_FROM_OSST
+#define SIGS_FROM_OSST \
+	{"OnStream", "SC-", "", "osst"}, \
+	{"OnStream", "DI-", "", "osst"}, \
+	{"OnStream", "DP-", "", "osst"}, \
+	{"OnStream", "USB", "", "osst"}, \
+	{"OnStream", "FW-", "", "osst"}
+#endif
+
+struct st_reject_data {
+	char *vendor;
+	char *model;
+	char *rev;
+	char *driver_hint; /* Name of the correct driver, NULL if unknown */
+};
+
+static struct st_reject_data reject_list[] = {
+	/* {"XXX", "Yy-", "", NULL},  example */
+	SIGS_FROM_OSST,
+	{NULL, }};
+
+/* If the device signature is on the list of incompatible drives, the
+   function returns a pointer to the name of the correct driver (if known) */
+static char * st_incompatible(Scsi_Device* SDp)
+{
+	struct st_reject_data *rp;
+
+	for (rp=&(reject_list[0]); rp->vendor != NULL; rp++)
+		if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
+		    !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
+		    !strncmp(rp->rev, SDp->rev, strlen(rp->rev))) {
+			if (rp->driver_hint)
+				return rp->driver_hint;
+			else
+				return "unknown";
+		}
+	return NULL;
+}
 
 
 /* Convert the result to success code */
@@ -3460,9 +3501,17 @@
 	ST_partstat *STps;
 	int i, mode, target_nbr;
 	unsigned long flags = 0;
+	char *stp;
 
 	if (SDp->type != TYPE_TAPE)
 		return 1;
+	if ((stp = st_incompatible(SDp))) {
+		printk(KERN_INFO
+		       "st: Found incompatible tape at scsi%d, channel %d, id %d, lun %d\n",
+		       SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
+		printk(KERN_INFO "st: The suggested driver is %s.\n", stp);
+		return 1;
+	}
 
 	write_lock_irqsave(&st_dev_arr_lock, flags);
 	if (st_template.nr_dev >= st_template.dev_max) {
@@ -3626,7 +3675,7 @@
 
 static int st_detect(Scsi_Device * SDp)
 {
-	if (SDp->type != TYPE_TAPE)
+	if (SDp->type != TYPE_TAPE || st_incompatible(SDp))
 		return 0;
 
 	printk(KERN_WARNING
@@ -3700,17 +3749,15 @@
 }
 
 
-#ifdef MODULE
-
-int __init init_module(void)
+static int __init init_st(void)
 {
 	validate_options();
 
-	st_template.module = &__this_module;
+	st_template.module = THIS_MODULE;
         return scsi_register_module(MODULE_SCSI_DEV, &st_template);
 }
 
-void cleanup_module(void)
+static void __exit exit_st(void)
 {
 	int i;
 
@@ -3736,4 +3783,6 @@
 	st_template.dev_max = 0;
 	printk(KERN_INFO "st: Unloaded.\n");
 }
-#endif				/* MODULE */
+
+module_init(init_st);
+module_exit(exit_st);

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