public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
From: James Bottomley <James.Bottomley@steeleye.com>
To: Matthew Dharm <mdharm-scsi@one-eyed-alien.net>
Cc: Linus Torvalds <torvalds@transmeta.com>,
	USB Developers <linux-usb-devel@lists.sourceforge.net>,
	USB Storage List <usb-storage@one-eyed-alien.net>,
	Linux SCSI list <linux-scsi@vger.kernel.org>,
	Greg KH <greg@kroah.com>
Subject: Re: PATCH: exclude certain commands from emulated SCSI hosts
Date: 21 Apr 2003 11:28:48 -0500	[thread overview]
Message-ID: <1050942530.1772.12.camel@mulgrave> (raw)
In-Reply-To: <20030420143351.C20891@one-eyed-alien.net>

[-- Attachment #1: Type: text/plain, Size: 816 bytes --]

On Sun, 2003-04-20 at 16:33, Matthew Dharm wrote:
> How about this patch?  It is based on James' work, but I cleaned up the
> comments a bit and eliminated a structure which was used to only hold two
> elements.  I also added a filter type and fixed the symbol problems when
> modules were used.
> 
> I've tested this, and it works well.  Linus, if you'll take this I've got
> several more patches -- ones to make usb-storage use this to cut some
> undesireable commands, and one to fix up the INQUIRY probing in scsi_scan.c
> to be compatible with the filter code.
> 
> Linus, please apply this to 2.5.

Actually, you havn't folded any of the list feedback into your version. 
I've done the merger and collapsed the EVPD inquiry filter into a
qualifier of the inquiry filter (which seems more appropriate).

James


[-- Attachment #2: tmp.diff --]
[-- Type: text/plain, Size: 7626 bytes --]

# 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.1131  -> 1.1134 
#	 drivers/scsi/scsi.h	1.73    -> 1.76   
#	drivers/scsi/scsi_syms.c	1.30    -> 1.31   
#	drivers/scsi/scsi_lib.c	1.83    -> 1.86   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/04/21	jejb@raven.il.steeleye.com	1.1132
# Add a command filter to scsi_lib.c
# 
# To facilitate emulated hosts rejecting commands they do not
# wish to process
# --------------------------------------------
# 03/04/21	mdharm-scsi@one-eyed-alien.net	1.1131.1.1
# [PATCH] Re: PATCH: exclude certain commands from emulated SCSI hosts
# 
# --=-ubLHM6H8VjG+svJp0RLA
# Content-Disposition: inline
# Content-Type: text/plain; charset=us-ascii
# Content-Transfer-Encoding: 8bit
# 
# How about this patch?  It is based on James' work, but I cleaned up the
# comments a bit and eliminated a structure which was used to only hold two
# elements.  I also added a filter type and fixed the symbol problems when
# modules were used.
# 
# I've tested this, and it works well.  Linus, if you'll take this I've got
# several more patches -- ones to make usb-storage use this to cut some
# undesireable commands, and one to fix up the INQUIRY probing in scsi_scan.c
# to be compatible with the filter code.
# 
# Linus, please apply this to 2.5.
# 
# Matt
# 
# # This is a BitKeeper generated patch for the following project:
# # Project Name: greg k-h's linux 2.5 USB kernel tree
# # This patch format is intended for GNU patch command version 2.5 or higher.
# # This patch includes the following deltas:
# #	           ChangeSet	1.670   -> 1.671
# #	drivers/scsi/scsi_syms.c	1.20    -> 1.21
# #	 drivers/scsi/scsi.h	1.31    -> 1.32
# #	drivers/scsi/scsi_lib.c	1.34    -> 1.35
# #
# # The following is the BitKeeper ChangeSet Log
# # --------------------------------------------
# # 03/04/19	mdharm@zen.san.one-eyed-alien.net	1.671
# # Added SCSI command filter.
# # --------------------------------------------
# #
# --------------------------------------------
# 03/04/21	jejb@raven.il.steeleye.com	1.1133
# Merge jejb/mdharm
# --------------------------------------------
# 03/04/21	jejb@raven.il.steeleye.com	1.1134
# Complete jejb/mdharm Merger in scsi_filter_list
# --------------------------------------------
#
diff -Nru a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h
--- a/drivers/scsi/scsi.h	Mon Apr 21 11:26:23 2003
+++ b/drivers/scsi/scsi.h	Mon Apr 21 11:26:23 2003
@@ -971,4 +971,49 @@
 extern int scsi_sysfs_register(void);
 extern void scsi_sysfs_unregister(void);
 
+struct scsi_cmd_filter {
+	enum {
+		SCSI_FILTER_WHITELIST,
+		SCSI_FILTER_BLACKLIST
+	} type;
+	/* normal scsi commands are bytes, exceptions are longer.  The format
+	 * of the exceptions is:
+	 *
+	 * bit 15: invert the specific condition
+	 * bits 14-12: Reserved
+	 * bits 11-8: command opcode (must be > 0)
+	 * bits 7-0: Command specific */
+	unsigned short commands[];
+};
+
+extern int scsi_filter_cmd(struct scsi_cmnd *, struct scsi_cmd_filter *);
+
+/* exception definitions for the filter */
+#define SCSI_FILTER_INVERT		0x8000
+
+/* opcodes for the filter */
+#define SCSI_FILTER_INQUIRY		0x0100
+
+/* useful filter commands */
+
+/* of the FILTER_INQUIRY opcode, < 128 is a length bits above are inquiry
+ * type */
+#define SCSI_FILTER_QUALIFIER		0x80
+#define SCSI_FILTER_QUALIFIER_EVPD	0x01
+#define SCSI_FILTER_INQUIRY_EVPD	(SCSI_FILTER_INQUIRY | SCSI_FILTER_QUALIFIER | SCSI_FILTER_QUALIFIER_EVPD)
+#define SCSI_FILTER_INQUIRY_36		(SCSI_FILTER_INQUIRY | 36)
+#define SCSI_FILTER_INQUIRY_NOT36	(SCSI_FILTER_INVERT | SCSI_FILTER_INQUIRY | 36)
+#define SCSI_FILTER_INQUIRY_NOT_EVPD	(SCSI_FILTER_INVERT | SCSI_FILTER_INQUIRY_EVPD)
+
+/* marker for end of filter list */
+#define SCSI_FILTER_LIST_END		0xFFFF
+
+static inline unsigned short scsi_filter_opcode(unsigned short command) {
+	return command & 0x7f00;
+}
+
+static inline unsigned char scsi_filter_data(unsigned short command) {
+	return (unsigned char)(command & 0x00ff);
+}
+
 #endif /* _SCSI_H */
diff -Nru a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
--- a/drivers/scsi/scsi_lib.c	Mon Apr 21 11:26:23 2003
+++ b/drivers/scsi/scsi_lib.c	Mon Apr 21 11:26:23 2003
@@ -1423,3 +1423,88 @@
 		kmem_cache_destroy(sgp->slab);
 	}
 }
+
+static inline int scsi_filter_exceptions(struct scsi_cmnd *cmd,
+					 unsigned short command)
+{
+	int found = 0;
+
+	/* specials begin at 0x100 */
+	if(command < 0x100)
+		return 0;
+
+	/* we check for inversion in each switch so that we can define each
+	 * test to act only on a specific subset of commands
+	 */
+	switch (scsi_filter_opcode(command)) {
+
+	case SCSI_FILTER_INQUIRY:
+		if (cmd->cmnd[0] != INQUIRY)
+			break;
+
+		/* is it a special filter */
+		if (command & SCSI_FILTER_QUALIFIER) {
+			if (command & SCSI_FILTER_QUALIFIER_EVPD)
+				/* is EVPD bit set? */
+				found += (cmd->cmnd[1] & 0x1) ? 1 : 0;
+		} else {
+			/* does the transfer length match the data */
+			found = (cmd->cmnd[4] == scsi_filter_data(command));
+		}
+		/* now check for inversion */
+		if (command & SCSI_FILTER_INVERT)
+			found = !found;
+		break;
+	default:
+		/* unrecognized filter */
+		break;
+	}
+
+	return found;
+}
+
+/**
+ * scsi_filter_cmd - Filter a given command against a list
+ * @cmd: command to be filtered.
+ * @filter: pointer to the filter containing the type (black/white list) and
+ * zero terminated list of commands to filter against (first byte only).  See
+ * scsi.h for details on the filter structure.
+ *
+ * Returns 0 if the filter passed successfully and the driver can continue
+ * processing the command or 1 if the filter failed and the command should
+ * be finished (via ->scsi_done).  In the latter case, the command will have
+ * the sense fields filled in indicating the correct sense for an illegal
+ * request.
+ **/
+int scsi_filter_cmd(struct scsi_cmnd *cmd, struct scsi_cmd_filter *filter)
+{
+	int found = 0;
+	unsigned short *command;
+
+	/* search command list for a match */
+	for (command = filter->commands ; *command != SCSI_FILTER_LIST_END;
+	     command++) {
+		found = scsi_filter_exceptions(cmd, *command);
+		found += (cmd->cmnd[0] == *command);
+		if(found)
+			break;
+	}
+
+	/* pass behavior -- found on a whitelist or not found on a blacklist */
+	if ((found && filter->type == SCSI_FILTER_WHITELIST) ||
+	    (!found && filter->type == SCSI_FILTER_BLACKLIST))
+		return 0;
+
+	/* fill in the Check Condition/Illegal request */
+	cmd->result = SAM_STAT_CHECK_CONDITION;
+	memset(cmd->sense_buffer, '\0', sizeof(cmd->sense_buffer));
+	cmd->sense_buffer[0] = 0xF0; /* valid, response code 0x70 */
+	cmd->sense_buffer[2] = ILLEGAL_REQUEST;
+
+	/* ASC 0x20, ASCQ 0x00: Invalid command operation code */
+	cmd->sense_buffer[12] = 0x20;
+	cmd->sense_buffer[13] = 0x00;
+
+	return 1;
+}
+	
diff -Nru a/drivers/scsi/scsi_syms.c b/drivers/scsi/scsi_syms.c
--- a/drivers/scsi/scsi_syms.c	Mon Apr 21 11:26:23 2003
+++ b/drivers/scsi/scsi_syms.c	Mon Apr 21 11:26:23 2003
@@ -55,6 +55,7 @@
 #if defined(CONFIG_SCSI_LOGGING)	/* { */
 EXPORT_SYMBOL(scsi_logging_level);
 #endif
+EXPORT_SYMBOL(scsi_filter_cmd);
 
 EXPORT_SYMBOL(scsi_allocate_request);
 EXPORT_SYMBOL(scsi_release_request);

  parent reply	other threads:[~2003-04-21 16:17 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20030322193046.A17056@one-eyed-alien.net>
     [not found] ` <20030322193149.B17056@one-eyed-alien.net>
2003-03-23  3:37   ` PATCH: exclude certain commands from emulated SCSI hosts Matthew Dharm
2003-03-23  4:09     ` Linus Torvalds
2003-03-23  7:31       ` Matthew Dharm
2003-03-23  7:39         ` Linus Torvalds
2003-03-23 18:13           ` [usb-storage] " Matthew Dharm
2003-03-24  1:05             ` Douglas Gilbert
2003-03-24  1:26         ` James Bottomley
2003-03-24  1:37           ` Matthew Dharm
2003-03-24  1:39             ` James Bottomley
2003-03-24  7:04               ` Matthew Dharm
2003-03-24 15:15                 ` James Bottomley
2003-03-24 16:29                   ` Linus Torvalds
2003-03-24 16:43                     ` James Bottomley
2003-03-24 16:52                     ` Jens Axboe
2003-03-24 16:56                       ` James Bottomley
2003-03-24 17:30                   ` Matthew Dharm
2003-04-05 15:30                     ` James Bottomley
2003-04-05 19:27                       ` Matthew Dharm
2003-04-05 19:45                         ` James Bottomley
2003-04-05 19:55                           ` Matthew Dharm
2003-04-05 20:08                             ` James Bottomley
2003-04-06  0:20                               ` Matthew Dharm
2003-04-06  0:22                           ` Matthew Dharm
2003-04-06 15:39                             ` James Bottomley
2003-04-07 22:33                       ` Patrick Mansfield
2003-04-07 23:14                         ` James Bottomley
2003-04-08  0:51                           ` Patrick Mansfield
2003-04-20 21:33                       ` Matthew Dharm
2003-04-20 21:35                         ` Matthew Dharm
2003-04-21 16:20                           ` James Bottomley
2003-04-21 17:02                             ` Matthew Dharm
2003-04-21 16:28                         ` James Bottomley [this message]
2003-04-21 17:01                           ` Matthew Dharm
2003-04-21 19:23                             ` James Bottomley
2003-04-21 19:35                               ` Matthew Dharm
2003-04-21 21:27                                 ` James Bottomley
2003-04-21 23:37                                   ` Matthew Dharm
2003-04-21 21:28                                 ` Patrick Mansfield
2003-04-21 23:45                                   ` Matthew Dharm
2003-03-24  1:58             ` Linus Torvalds
2003-03-24  6:58               ` Matthew Dharm
2003-04-22 17:37 [usb-storage] " James Bottomley
2003-04-22 18:13 ` Alan Stern
  -- strict thread matches above, loose matches on Subject: below --
2003-04-22 19:30 Andries.Brouwer
2003-04-22 19:41 ` James Bottomley
2003-04-22 19:50 Andries.Brouwer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1050942530.1772.12.camel@mulgrave \
    --to=james.bottomley@steeleye.com \
    --cc=greg@kroah.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=linux-usb-devel@lists.sourceforge.net \
    --cc=mdharm-scsi@one-eyed-alien.net \
    --cc=torvalds@transmeta.com \
    --cc=usb-storage@one-eyed-alien.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox