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);
next prev 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.