This is the first release of a driver we've been using internally at Intel
for a few weeks which is as low-latency as possible. It's designed to
let us find latency issues elsewhere in the storage stack (eg filesystem,
block layer, scsi layer)
There are a few different options, controlled through module parameters.
The sector size and disc capacity are load-time parameters, but the
parameters affecting performance are tweakable at runtime.
Arguably, this driver should be merged into scsi_debug. I didn't want to
trip over Doug's toes while developing this driver, and the two drivers
do have very different objectives. scsi_debug is obviously a lot more
fully-featured and implements lots of bits of the spec I simply haven't
bothered with. Like MODE SENSE ;-)
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index a5f0aaa..e8dd685 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1499,6 +1499,16 @@ config SCSI_DEBUG
information. This driver is primarily of use to those testing the
SCSI and block subsystems. If unsure, say N.
+config SCSI_RAM
+ tristate SCSI RAM-based host
+ depends on SCSI
+ help
+ This driver simulates a host adapter with one disc attached.
+ The primary purpose of this driver is for performance testing
+ of the fs/block/scsi stack; as such it attempts to simulate a
+ disc which is as fast as RAM. If you are unsure how to answer
+ this question, say N.
+
config SCSI_MESH
tristate MESH (Power Mac internal SCSI) support
depends on PPC32 PPC_PMAC SCSI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 925c26b..95466d8 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -133,6 +133,7 @@ obj-$(CONFIG_SCSI_ENCLOSURE)+= ses.o
# This goes last, so that real scsi devices probe earlier
obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o
+obj-$(CONFIG_SCSI_RAM) += scsi_ram.o
obj-$(CONFIG_SCSI_WAIT_SCAN) += scsi_wait_scan.o
diff --git a/drivers/scsi/scsi_ram.c b/drivers/scsi/scsi_ram.c
new file mode 100644
index 000..f097aee
--- /dev/null
+++ b/drivers/scsi/scsi_ram.c
@@ -0,0 +1,618 @@
+/*
+ * scsi_ram.c - A RAM-based SCSI driver for Linux.
+ *
+ * This driver is intended to run as fast as possible, hence the options
+ * to discard writes and reads.
+ * By default, it'll allocate half a gigabyte of RAM to use as a ramdisc;
+ * you can change this with the `capacity' module parameter.
+ *
+ * (C) Copyright 2007-2008 Intel Corporation
+ * Author: Matthew Wilcox [EMAIL PROTECTED]
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+#undef DEBUG
+
+#include linux/init.h
+#include linux/kernel.h
+#include linux/kthread.h
+#include linux/list.h
+#include linux/module.h
+#include linux/spinlock.h
+
+#include scsi/scsi.h
+#include scsi/scsi_cmnd.h
+#include scsi/scsi_device.h
+#include scsi/scsi_host.h
+#include scsi/scsi_dbg.h
+
+MODULE_LICENSE(GPL v2);
+MODULE_AUTHOR(Matthew Wilcox [EMAIL PROTECTED]);
+
+#define DRV_NAME scsi_ram
+
+static unsigned int sector_size = 512;
+module_param(sector_size, uint, 0444);
+MODULE_PARM_DESC(sector_size, Size of sectors);
+
+static unsigned int capacity = 1024 * 1024;
+module_param(capacity, uint, 0444);
+MODULE_PARM_DESC(capacity, Number of logical blocks in device);
+
+static int throw_away_writes;
+module_param(throw_away_writes, int, 0644);
+MODULE_PARM_DESC(throw_away_writes, Discard all writes to the device);
+
+static int throw_away_reads;
+module_param(throw_away_reads, int, 0644);
+MODULE_PARM_DESC(throw_away_reads, Don't actually read data from the device);
+
+static int use_thread = 1;
+module_param(use_thread, int, 0644);
+MODULE_PARM_DESC(use_thread, Use a separate thread to do data accesses);
+
+static void copy_buffer(struct scsi_cmnd *cmnd, char *buf, int len)
+{
+ char *p;
+ struct scatterlist *sg;
+ int i;
+
+ scsi_for_each_sg(cmnd, sg, scsi_sg_count(cmnd), i) {
+ int tocopy = sg-length;
+ if (tocopy len)
+ tocopy = len;
+
+ p = kmap_atomic(sg_page(sg), KM_USER0);
+ memcpy(p + sg-offset, buf, tocopy);
+ kunmap_atomic(p, KM_USER0);
+
+ len -= tocopy;
+ if (!len)
+ break;
+ buf += tocopy;
+ }
+
+ scsi_set_resid(cmnd, len);
+}
+
+static char inquiry[57] = {
+ 0, 0, 5, 0x22, 52, 0, 0, 0x0a, /* 0-7 */
+ 'L', 'i', 'n', 'u', 'x', ' ', ' ', ' ', /* 8-15 */
+ 'R', 'A', 'M', ' ', 'D', 'r', 'i', 'v', /* 16-23 */
+ 'e', ' ', ' ', ' ', ' ', ' ', ' ', ' ', /* 24-31 */
+ '0', '.', '0', '1', 0, 0, 0, 0, /* 32-39 */
+ 0, 0, 0, 0, 0, 0, 0, 0,