From: <vl...@us...> - 2006-12-15 15:59:26
|
Revision: 62 http://svn.sourceforge.net/scst/?rev=62&view=rev Author: vlnb Date: 2006-12-15 07:59:21 -0800 (Fri, 15 Dec 2006) Log Message: ----------- Update to allow SCST built inside Linux kernel. Done together with Erik Habbinga. --This line, and below, will be ignored-- _M trunk/mpt _M trunk/mpt/in-tree M trunk/mpt/in-tree/Makefile.diff M trunk/mpt/mpt_scst.c M trunk/mpt/Makefile M trunk/qla2x00t/qla2x00-target/qla2x00t.c M trunk/scst/kernel/in-tree/Makefile.scsi_tgt D trunk/scst/include/scst_debug.c M trunk/scst/include/scst_debug.h M trunk/scst/src/scst_proc.c M trunk/scst/src/scst_priv.h A trunk/scst/src/scst_debug.c M trunk/scst/src/scst_targ.c M trunk/scst/src/scst_mem.c M trunk/scst/src/Makefile M trunk/scst/src/scst.c M trunk/scst/src/dev_handlers/scst_cdrom.c M trunk/scst/src/dev_handlers/scst_modisk.c M trunk/scst/src/dev_handlers/scst_changer.c M trunk/scst/src/dev_handlers/scst_fileio.c M trunk/scst/src/dev_handlers/scst_tape.c M trunk/scst/src/dev_handlers/scst_disk.c M trunk/scst/src/dev_handlers/scst_processor.c M trunk/scst/src/dev_handlers/scst_raid.c M trunk/scst/src/dev_handlers/Makefile M trunk/scst/src/dev_handlers/scst_dev_handler.h M trunk/scst/README Modified Paths: -------------- trunk/mpt/Makefile trunk/mpt/in-tree/Makefile.diff trunk/mpt/mpt_scst.c trunk/qla2x00t/qla2x00-target/qla2x00t.c trunk/scst/README trunk/scst/include/scst_debug.h trunk/scst/kernel/in-tree/Makefile.scsi_tgt trunk/scst/src/Makefile trunk/scst/src/dev_handlers/Makefile trunk/scst/src/dev_handlers/scst_cdrom.c trunk/scst/src/dev_handlers/scst_changer.c trunk/scst/src/dev_handlers/scst_dev_handler.h trunk/scst/src/dev_handlers/scst_disk.c trunk/scst/src/dev_handlers/scst_fileio.c trunk/scst/src/dev_handlers/scst_modisk.c trunk/scst/src/dev_handlers/scst_processor.c trunk/scst/src/dev_handlers/scst_raid.c trunk/scst/src/dev_handlers/scst_tape.c trunk/scst/src/scst.c trunk/scst/src/scst_mem.c trunk/scst/src/scst_priv.h trunk/scst/src/scst_proc.c trunk/scst/src/scst_targ.c Added Paths: ----------- trunk/scst/src/scst_debug.c Removed Paths: ------------- trunk/scst/include/scst_debug.c Property Changed: ---------------- trunk/mpt/ trunk/mpt/in-tree/ Property changes on: trunk/mpt ___________________________________________________________________ Name: svn:ignore + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers Modified: trunk/mpt/Makefile =================================================================== --- trunk/mpt/Makefile 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/mpt/Makefile 2006-12-15 15:59:21 UTC (rev 62) @@ -25,8 +25,10 @@ SCST_INC_DIR := $(SUBDIRS)/../scst/include SCST_DIR := $(shell pwd)/../scst/src -EXTRA_CFLAGS += -I$(SCST_INC_DIR) +FUSION_INC_DIR := drivers/message/fusion +EXTRA_CFLAGS += -I$(SCST_INC_DIR) -I$(FUSION_INC_DIR) -Iinclude/scsi + EXTRA_CFLAGS += -DEXTRACHECKS #EXTRA_CFLAGS += -DTRACING #EXTRA_CFLAGS += -DDEBUG @@ -44,7 +46,7 @@ EXTRA_CFLAGS += -I$(LSI_INC_DIR) ifneq ($(KERNELRELEASE),) -obj-m := mpt_scst.o +obj-$(CONFIG_FUSION_SCST) += mpt_scst.o else Property changes on: trunk/mpt/in-tree ___________________________________________________________________ Name: svn:ignore + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers Modified: trunk/mpt/in-tree/Makefile.diff =================================================================== --- trunk/mpt/in-tree/Makefile.diff 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/mpt/in-tree/Makefile.diff 2006-12-15 15:59:21 UTC (rev 62) @@ -1,21 +1,10 @@ ---- Makefile_orig 2006-03-05 22:07:54.000000000 +0300 -+++ Makefile 2006-12-13 14:50:36.000000000 +0300 -@@ -30,9 +30,18 @@ - #CFLAGS_mptctl.o += -DMPT_DEBUG_IOCTL - # - -+SCST_INC_DIR := /usr/local/include/scst -+ -+CFLAGS_mpt_scst.o += -I$(SCST_INC_DIR) -I$(src) -+CFLAGS_mpt_scst.o += -DEXTRACHECKS -+#CFLAGS_mpt_scst.o += -DTRACING -+#CFLAGS_mpt_scst.o += -DDEBUG -+#CFLAGS_mpt_scst.o += -DDEBUG_WORK_IN_THREAD -+ +--- Makefile.orig 2006-01-02 20:21:10.000000000 -0700 ++++ Makefile 2006-12-14 10:24:53.000000000 -0700 +@@ -33,6 +33,7 @@ #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC obj-$(CONFIG_FUSION_SPI) += mptbase.o mptscsih.o mptspi.o -+obj-$(CONFIG_FUSION_SCST) += mpt_scst/mpt_scst.o ++obj-$(CONFIG_FUSION_SCST) += mpt_scst/ obj-$(CONFIG_FUSION_FC) += mptbase.o mptscsih.o mptfc.o obj-$(CONFIG_FUSION_SAS) += mptbase.o mptscsih.o mptsas.o obj-$(CONFIG_FUSION_CTL) += mptctl.o Modified: trunk/mpt/mpt_scst.c =================================================================== --- trunk/mpt/mpt_scst.c 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/mpt/mpt_scst.c 2006-12-15 15:59:21 UTC (rev 62) @@ -29,6 +29,7 @@ #include <linux/blkdev.h> #include <linux/interrupt.h> #include <scsi/scsi.h> +#include <linux/seq_file.h> #include <scsi/scsi_host.h> #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) @@ -39,9 +40,6 @@ #include <scst_debug.h> -#include <scst_debug.c> -#include <linux/proc_fs.h> - #include "mpt_scst.h" #define MYNAM "mpt_scst" @@ -62,6 +60,17 @@ }; #endif +#ifdef DEBUG +#define SCST_DEFAULT_MPT_LOG_FLAGS (TRACE_FUNCTION | TRACE_PID | \ + TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MGMT_DEBUG | \ + TRACE_MINOR | TRACE_SPECIAL) +#else +# ifdef TRACING +#define SCST_DEFAULT_MPT_LOG_FLAGS (TRACE_FUNCTION | TRACE_PID | \ + TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MINOR | TRACE_SPECIAL) +# endif +#endif + static MPT_STM_PRIV *mpt_stm_priv[MPT_MAX_ADAPTERS+1]; static int set_aliases_in_fcportpage1 = 1; @@ -113,48 +122,45 @@ static void stmapp_srr_process(MPT_STM_PRIV *priv, int rx_id, int r_ctl, u32 offset, LinkServiceBufferPostReply_t *rep, int index); +#ifdef DEBUG +#define trace_flag mpt_trace_flag +unsigned long mpt_trace_flag = TRACE_FUNCTION | TRACE_OUT_OF_MEM | TRACE_SPECIAL; +#else +# ifdef TRACING +#define trace_flag mpt_trace_flag +unsigned long mpt_trace_flag = TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_SPECIAL; +# endif +#endif + static int -mpt_proc_read(char *buffer, char **start, off_t offset, int length, int *eof, - struct scst_tgt *scst_tgt) +mpt_target_show(struct seq_file *seq, void *v) { - struct mpt_tgt *tgt = scst_tgt_get_tgt_priv(scst_tgt); + struct mpt_tgt *tgt = (struct mpt_tgt *)seq->private; MPT_ADAPTER *ioc = tgt->priv->ioc; - int res = 0, len = 0; MPT_STM_PRIV *priv = tgt->priv; TRACE_ENTRY(); - TRACE_DBG("res %d, buffer %p, length %d, %d, priv %p, tgt %p", - res, buffer, length, len, priv, tgt); + TRACE_DBG("priv %p, tgt %p", priv, tgt); sBUG_ON(tgt == NULL); sBUG_ON(ioc == NULL); - len = snprintf(buffer, length, - "ProductID :0x%04x (%s)\n" + seq_printf(seq, "ProductID :0x%04x (%s)\n" "Target Enable :%s\n", ioc->facts.ProductID, ioc->prod_name, tgt->target_enable ? "True" : "False"); -#define LEN_CHECK(res, buffer, length) \ - TRACE_DBG("res %d, buffer %p, length %d, %d", res, buffer, length, len); \ - res += len; buffer += len; length -= len; \ - if (length <= 0) goto out; - LEN_CHECK(res, buffer, length) - if (ioc->bus_type == SCSI) { int i = 0; - len = snprintf(buffer, length, - "Target ID :%d\n" + seq_printf(seq, "Target ID :%d\n" "Capabilities :0x%x\n" "PhysicalInterface:0x%x\n", tgt->target_id, priv->SCSIPortPage0.Capabilities, priv->SCSIPortPage0.PhysicalInterface); - LEN_CHECK(res, buffer, length) - len = snprintf(buffer, length, - "Configuration :0x%x\n" + seq_printf(seq, "Configuration :0x%x\n" "OnBusTimerValue :0x%x\n" "TargetConfig :0x%x\n" "IDConfig :0x%x\n", @@ -162,63 +168,55 @@ priv->SCSIPortPage1.OnBusTimerValue, priv->SCSIPortPage1.TargetConfig, priv->SCSIPortPage1.IDConfig); - LEN_CHECK(res, buffer, length); - len = snprintf(buffer, length, - "PortFlags :0x%x\n" + seq_printf(seq, "PortFlags :0x%x\n" "PortSettings :0x%x\n", priv->SCSIPortPage2.PortFlags, priv->SCSIPortPage2.PortSettings); - LEN_CHECK(res, buffer, length); #if 0 for (i = 0; i < 16; i++) { - len = snprintf(buffer, length, - " DeviceSeting %02d: 0x%x 0x%x 0x%x\n", + seq_printf(seq, " DeviceSeting %02d: 0x%x 0x%x 0x%x\n", priv->SCSIPortPage2.DeviceSettings[i].Timeout, priv->SCSIPortPage2.DeviceSettings[i].SyncFactor, priv->SCSIPortPage2.DeviceSettings[i].DeviceFlags); - LEN_CHECK(res, buffer, length); } #endif for (i = 0; i < NUM_SCSI_DEVICES; i++) { - len = snprintf(buffer, length, - " Device %02d: 0x%x, 0x%x\n", + seq_printf(seq, " Device %02d: 0x%x, 0x%x\n", i, priv->SCSIDevicePage1[i].RequestedParameters, priv->SCSIDevicePage1[i].Configuration); - LEN_CHECK(res, buffer, length); } } if (ioc->bus_type == FC) { - len = snprintf(buffer, length, - "WWN :%08X%08X:%08X%08X\n", + seq_printf(seq, "WWN :%08X%08X:%08X%08X\n", ioc->fc_port_page0[0].WWNN.High, ioc->fc_port_page0[0].WWNN.Low, ioc->fc_port_page0[0].WWPN.High, ioc->fc_port_page0[0].WWPN.Low); - LEN_CHECK(res, buffer, length); } -#undef LEN_CHECK -out: - TRACE_EXIT_RES(res); - return res; + TRACE_EXIT(); + return 0; } static int -mpt_proc_write(struct file *file, const char *buf, unsigned long length, - struct scst_tgt *scst_tgt) +mpt_proc_target_write(struct file *file, const char __user *buf, + size_t length, loff_t *off) { - struct mpt_tgt *tgt = scst_tgt_get_tgt_priv(scst_tgt); + struct mpt_tgt *tgt = (struct mpt_tgt *)PDE(file->f_dentry->d_inode)->data; MPT_ADAPTER *ioc = tgt->priv->ioc; int res = 0; char tmp[32+1]; TRACE_ENTRY(); res = min(32, (int)length); - memcpy(tmp, buf, res); + if (copy_from_user(tmp, buf, res)) { + res = -EFAULT; + goto out; + } tmp[res] = 0; TRACE_DBG("buff '%s'", tmp); @@ -245,21 +243,17 @@ } #endif +out: TRACE_EXIT_RES(res); return length; } -static int mpt_proc_info(char *buffer, char **start, off_t offset, - int length, int *eof, struct scst_tgt *tgt, int inout) -{ - if (inout) { - return mpt_proc_write(NULL, buffer, length, tgt); - } - return mpt_proc_read(buffer, start, offset, length, eof, tgt); -} +static struct scst_proc_data mpt_target_proc_data = { + SCST_DEF_RW_SEQ_OP(mpt_proc_target_write) + .show = mpt_target_show, +}; - static int mpt_target_detect(struct scst_tgt_template *temp1); static int mpt_target_release(struct scst_tgt *scst_tgt); static int mpt_xmit_response(struct scst_cmd *scst_cmd); @@ -287,7 +281,6 @@ .rdy_to_xfer = mpt_rdy_to_xfer, .on_free_cmd = mpt_on_free_cmd, .task_mgmt_fn_done = mpt_task_mgmt_fn_done, -//ToDo: .proc_info = mpt_proc_info, }; static inline void @@ -339,6 +332,9 @@ MPT_ADAPTER *ioc = pci_get_drvdata(pdev); int ret = 0; struct mpt_tgt *tgt; + struct proc_dir_entry *p; + struct proc_dir_entry *root; + char name[4]; TRACE_ENTRY(); ret = mpt_stm_adapter_install(ioc); @@ -370,9 +366,23 @@ ret = -ENODEV; goto out; } + + root = scst_proc_get_tgt_root(&tgt_template); + scnprintf(name, sizeof(name), "%d", ioc->id); + mpt_target_proc_data.data = (void *)tgt; + p = scst_create_proc_entry(root, name, + &mpt_target_proc_data); + if (p == NULL) { + PRINT_ERROR("Not enough memory to register " + "target driver %s entry %s in /proc", + tgt_template.name, name); + scst_unregister(tgt->scst_tgt); + ret = -ENOMEM; + goto out; + } + scst_tgt_set_tgt_priv(tgt->scst_tgt, tgt); mpt_stm_priv[ioc->id]->tgt = tgt; - _mpt_ada_nums ++; out: @@ -5102,48 +5112,44 @@ TRACE_EXIT(); } +#if defined(DEBUG) || defined(TRACING) + #define MPT_PROC_LOG_ENTRY_NAME "trace_level" -#ifdef TRACING -static struct scst_proc_log mpt_spec_tbl[] = -{ - { TRACE_MPI, "mpt_mpi" }, - { 0, NULL } -}; -#endif -static int mpt_proc_log_entry_read(char *buffer, char **start, - off_t offset, int length, int *eof, - void *data) +#include <linux/proc_fs.h> + +static int mpt_log_info_show(struct seq_file *seq, void *v) { int res = 0; TRACE_ENTRY(); -#ifdef TRACING - res = scst_proc_log_entry_read(buffer, start, offset, length, eof, - data, trace_flag, mpt_spec_tbl); -#endif + res = scst_proc_log_entry_read(seq, trace_flag, NULL); + TRACE_EXIT_RES(res); return res; } -static int mpt_proc_log_entry_write(struct file *file, const char *buf, - unsigned long length, void *data) +static int mpt_proc_log_entry_write(struct file *file, const char __user *buf, + size_t length, loff_t *off) { int res = 0; TRACE_ENTRY(); -#ifdef TRACING - res = scst_proc_log_entry_write(file, buf, length, data, - &trace_flag, (TRACE_FUNCTION | TRACE_OUT_OF_MEM | TRACE_MGMT | \ - TRACE_MINOR | TRACE_SPECIAL), mpt_spec_tbl); -#endif + res = scst_proc_log_entry_write(file, buf, length, &trace_flag, + SCST_DEFAULT_MPT_LOG_FLAGS, NULL); TRACE_EXIT_RES(res); return res; } +static struct scst_proc_data mpt_log_proc_data = { + SCST_DEF_RW_SEQ_OP(mpt_proc_log_entry_write) + .show = mpt_log_info_show, +}; +#endif + static int mpt_proc_log_entry_build(struct scst_tgt_template *templ) { int res = 0; @@ -5153,10 +5159,10 @@ root = scst_proc_get_tgt_root(templ); if (root) { - p = create_proc_read_entry(MPT_PROC_LOG_ENTRY_NAME, - S_IFREG | S_IRUGO | S_IWUSR, root, - mpt_proc_log_entry_read, - (void *)templ->name); +#if defined(DEBUG) || defined(TRACING) + mpt_log_proc_data.data = (void *)templ->name; + p = scst_create_proc_entry(root, MPT_PROC_LOG_ENTRY_NAME, + &mpt_log_proc_data); if (p == NULL) { PRINT_ERROR("Not enough memory to register " "target driver %s entry %s in /proc", @@ -5164,7 +5170,7 @@ res = -ENOMEM; goto out; } - p->write_proc = mpt_proc_log_entry_write; +#endif } out: @@ -5175,16 +5181,18 @@ static void mpt_proc_log_entry_clean(struct scst_tgt_template *templ) { +#if defined(DEBUG) || defined(TRACING) struct proc_dir_entry *root; TRACE_ENTRY(); + root = scst_proc_get_tgt_root(templ); if (root) { remove_proc_entry(MPT_PROC_LOG_ENTRY_NAME, root); } - TRACE_EXIT(); +#endif } static int __init mpt_target_init(void) @@ -5225,14 +5233,6 @@ return; } -#ifdef DEBUG -unsigned long trace_flag = TRACE_FUNCTION | TRACE_OUT_OF_MEM | TRACE_SPECIAL; -#else -# ifdef TRACING -unsigned long trace_flag = TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_SPECIAL; -# endif -#endif - module_init(mpt_target_init); module_exit(mpt_target_exit); Modified: trunk/qla2x00t/qla2x00-target/qla2x00t.c =================================================================== --- trunk/qla2x00t/qla2x00-target/qla2x00t.c 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/qla2x00t/qla2x00-target/qla2x00t.c 2006-12-15 15:59:21 UTC (rev 62) @@ -43,8 +43,6 @@ #include "qla2x00t.h" -#include <scst_debug.c> - #ifndef FC_TARGET_SUPPORT #error "FC_TARGET_SUPPORT is NOT DEFINED" #endif @@ -59,12 +57,12 @@ #endif #ifdef DEBUG -#define SCST_DEFAULT_QLA_LOG_FLAGS (TRACE_FUNCTION | TRACE_PID | \ +#define Q2T_DEFAULT_LOG_FLAGS (TRACE_FUNCTION | TRACE_PID | \ TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MGMT_DEBUG | \ TRACE_MINOR | TRACE_SPECIAL) #else # ifdef TRACING -#define SCST_DEFAULT_QLA_LOG_FLAGS (TRACE_FUNCTION | TRACE_PID | \ +#define Q2T_DEFAULT_LOG_FLAGS (TRACE_FUNCTION | TRACE_PID | \ TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MINOR | TRACE_SPECIAL) # endif #endif @@ -93,7 +91,8 @@ */ #if defined(DEBUG) || defined(TRACING) -unsigned long trace_flag = SCST_DEFAULT_QLA_LOG_FLAGS; +#define trace_flag q2t_trace_flag +unsigned long q2t_trace_flag = Q2T_DEFAULT_LOG_FLAGS; #endif struct scst_tgt_template tgt_template = { @@ -2074,7 +2073,7 @@ TRACE_ENTRY(); res = scst_proc_log_entry_write(file, buf, length, &trace_flag, - SCST_DEFAULT_QLA_LOG_FLAGS, NULL); + Q2T_DEFAULT_LOG_FLAGS, NULL); TRACE_EXIT_RES(res); return res; Modified: trunk/scst/README =================================================================== --- trunk/scst/README 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/scst/README 2006-12-15 15:59:21 UTC (rev 62) @@ -40,10 +40,10 @@ To compile SCST type 'make'. It will build SCST itself and its device handlers. To install them type 'make install'. The driver modules will be installed in '/lib/modules/`you_kernel_version`/extra'. In addition, -scsi_tgt.h, scst_debug.h and scst_debug.c will be copied to -'/usr/local/include/scst'. The first file contains all SCST's public -data definition, which are used by target drivers. The other ones -support debug messages logging. +scsi_tgt.h, scst_debug.h as well as Module.symvers or Modules.symvers +will be copied to '/usr/local/include/scst'. The first file contains all +SCST's public data definition, which are used by target drivers. The +other ones support debug messages logging and build process. Then you can load any module by typing 'modprobe drive_name'. The names are: Deleted: trunk/scst/include/scst_debug.c =================================================================== --- trunk/scst/include/scst_debug.c 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/scst/include/scst_debug.c 2006-12-15 15:59:21 UTC (rev 62) @@ -1,108 +0,0 @@ -/* - * include/scst_debug.c - * - * Copyright (C) 2004-2006 Vladislav Bolkhovitin <vs...@vl...> - * and Leonid Stoljar - * - * Contains helper functions for execution tracing and error reporting. - * Intended to be included in main .c file. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#if defined(DEBUG) || defined(TRACING) - -unsigned long trace_flag; - -#define TRACE_BUF_SIZE 512 - -static char trace_buf[TRACE_BUF_SIZE]; -static spinlock_t trace_buf_lock = SPIN_LOCK_UNLOCKED; - -int debug_print_prefix(const char *func, int line) -{ - int i = 0; - unsigned long flags; - - spin_lock_irqsave(&trace_buf_lock, flags); - - if (trace_flag & TRACE_PID) - i += snprintf(&trace_buf[i], TRACE_BUF_SIZE, "[%d]: ", - current->pid); - if (trace_flag & TRACE_FUNCTION) - i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%s:", func); - if (trace_flag & TRACE_LINE) - i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%i:", line); - - if (i > 0) - PRINTN(LOG_FLAG, "%s", trace_buf); - - spin_unlock_irqrestore(&trace_buf_lock, flags); - - return i; -} - -void debug_print_buffer(const void *data, int len) -{ - int z, z1, i; - const unsigned char *buf = (const unsigned char *) data; - int f = 0; - unsigned long flags; - - if (buf == NULL) - return; - - spin_lock_irqsave(&trace_buf_lock, flags); - - PRINT(NO_FLAG, " (h)___0__1__2__3__4__5__6__7__8__9__A__B__C__D__E__F"); - for (z = 0, z1 = 0, i = 0; z < len; z++) { - if (z % 16 == 0) { - if (z != 0) { - i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, - " "); - for (; (z1 < z) && (i < TRACE_BUF_SIZE - 1); - z1++) { - if ((buf[z1] >= 0x20) && - (buf[z1] < 0x80)) - trace_buf[i++] = buf[z1]; - else - trace_buf[i++] = '.'; - } - trace_buf[i] = '\0'; - PRINT(NO_FLAG, "%s", trace_buf); - i = 0; - f = 1; - } - i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, - "%4x: ", z); - } - i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%02x ", - buf[z]); - } - i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, " "); - for (; (z1 < z) && (i < TRACE_BUF_SIZE - 1); z1++) { - if ((buf[z1] > 0x20) && (buf[z1] < 0x80)) - trace_buf[i++] = buf[z1]; - else - trace_buf[i++] = '.'; - } - trace_buf[i] = '\0'; - if (f) { - PRINT(LOG_FLAG, "%s", trace_buf) - } else { - PRINT(NO_FLAG, "%s", trace_buf); - } - - spin_unlock_irqrestore(&trace_buf_lock, flags); - return; -} - -#endif /* DEBUG || TRACING */ Modified: trunk/scst/include/scst_debug.h =================================================================== --- trunk/scst/include/scst_debug.h 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/scst/include/scst_debug.h 2006-12-15 15:59:21 UTC (rev 62) @@ -99,63 +99,61 @@ #if defined(DEBUG) || defined(TRACING) -extern unsigned long trace_flag; +extern int debug_print_prefix(unsigned long trace_flag, const char *func, int line); +extern void debug_print_buffer(unsigned long trace_flag, const void *data, int len); -extern int debug_print_prefix(const char *func, int line); -extern void debug_print_buffer(const void *data, int len); - -#define TRACE(trace, format, args...) \ -do { \ - if (trace_flag & (trace)) \ - { \ - char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(__FUNCTION__, __LINE__) > 0) \ - { \ - __tflag = NO_FLAG; \ - } \ - PRINT(NO_FLAG, "%s" format, __tflag, args); \ - } \ +#define TRACE(trace, format, args...) \ +do { \ + if (trace_flag & (trace)) \ + { \ + char *__tflag = LOG_FLAG; \ + if (debug_print_prefix(trace_flag, __FUNCTION__, __LINE__) > 0) \ + { \ + __tflag = NO_FLAG; \ + } \ + PRINT(NO_FLAG, "%s" format, __tflag, args); \ + } \ } while(0) -#define TRACE_LOG_FLAG(log_flag, trace, format, args...) \ -do { \ - char *__tflag = log_flag; \ - if (trace_flag & (trace)) \ - { \ - if (debug_print_prefix(__FUNCTION__, __LINE__) > 0) \ - { \ - __tflag = NO_FLAG; \ - } \ - } \ - PRINT(NO_FLAG, "%s" format, __tflag, args); \ +#define TRACE_LOG_FLAG(log_flag, trace, format, args...) \ +do { \ + char *__tflag = log_flag; \ + if (trace_flag & (trace)) \ + { \ + if (debug_print_prefix(trace_flag, __FUNCTION__, __LINE__) > 0) \ + { \ + __tflag = NO_FLAG; \ + } \ + } \ + PRINT(NO_FLAG, "%s" format, __tflag, args); \ } while(0) -#define TRACE_BUFFER(message, buff, len) \ -do { \ - if (trace_flag & TRACE_BUFF) \ - { \ - char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(__FUNCTION__, __LINE__) > 0) \ - { \ - __tflag = NO_FLAG; \ - } \ - PRINT(NO_FLAG, "%s%s:", __tflag, message); \ - debug_print_buffer(buff, len); \ - } \ +#define TRACE_BUFFER(message, buff, len) \ +do { \ + if (trace_flag & TRACE_BUFF) \ + { \ + char *__tflag = LOG_FLAG; \ + if (debug_print_prefix(trace_flag, __FUNCTION__, __LINE__) > 0) \ + { \ + __tflag = NO_FLAG; \ + } \ + PRINT(NO_FLAG, "%s%s:", __tflag, message); \ + debug_print_buffer(trace_flag, buff, len); \ + } \ } while(0) -#define TRACE_BUFF_FLAG(flag, message, buff, len) \ -do { \ - if (trace_flag & (flag)) \ - { \ - char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(__FUNCTION__, __LINE__) > 0) \ - { \ - __tflag = NO_FLAG; \ - } \ - PRINT(NO_FLAG, "%s%s:", __tflag, message); \ - debug_print_buffer(buff, len); \ - } \ +#define TRACE_BUFF_FLAG(flag, message, buff, len) \ +do { \ + if (trace_flag & (flag)) \ + { \ + char *__tflag = LOG_FLAG; \ + if (debug_print_prefix(trace_flag, __FUNCTION__, __LINE__) > 0) \ + { \ + __tflag = NO_FLAG; \ + } \ + PRINT(NO_FLAG, "%s%s:", __tflag, message); \ + debug_print_buffer(trace_flag, buff, len); \ + } \ } while(0) #else /* DEBUG || TRACING */ @@ -168,54 +166,54 @@ #ifdef DEBUG -#define TRACE_MEM(format, args...) \ -do { \ - if (trace_flag & TRACE_MEMORY) \ - { \ - char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(__FUNCTION__, __LINE__) > 0) \ - { \ - __tflag = NO_FLAG; \ - } \ - PRINT(NO_FLAG, "%s" format, __tflag, args); \ - } \ +#define TRACE_MEM(format, args...) \ +do { \ + if (trace_flag & TRACE_MEMORY) \ + { \ + char *__tflag = LOG_FLAG; \ + if (debug_print_prefix(trace_flag, __FUNCTION__, __LINE__) > 0) \ + { \ + __tflag = NO_FLAG; \ + } \ + PRINT(NO_FLAG, "%s" format, __tflag, args); \ + } \ } while(0) -#define TRACE_DBG(format, args...) \ -do { \ - if (trace_flag & TRACE_DEBUG) \ - { \ - char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(__FUNCTION__, __LINE__) > 0) \ - { \ - __tflag = NO_FLAG; \ - } \ - PRINT(NO_FLAG, "%s" format, __tflag, args); \ - } \ +#define TRACE_DBG(format, args...) \ +do { \ + if (trace_flag & TRACE_DEBUG) \ + { \ + char *__tflag = LOG_FLAG; \ + if (debug_print_prefix(trace_flag, __FUNCTION__, __LINE__) > 0) \ + { \ + __tflag = NO_FLAG; \ + } \ + PRINT(NO_FLAG, "%s" format, __tflag, args); \ + } \ } while(0) -#define TRACE_MGMT_DBG(format, args...) \ -do { \ - if (trace_flag & TRACE_MGMT_DEBUG) \ - { \ - char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(__FUNCTION__, __LINE__) > 0) \ - { \ - __tflag = NO_FLAG; \ - } \ - PRINT(NO_FLAG, "%s" format, __tflag, args); \ - } \ +#define TRACE_MGMT_DBG(format, args...) \ +do { \ + if (trace_flag & TRACE_MGMT_DEBUG) \ + { \ + char *__tflag = LOG_FLAG; \ + if (debug_print_prefix(trace_flag, __FUNCTION__, __LINE__) > 0) \ + { \ + __tflag = NO_FLAG; \ + } \ + PRINT(NO_FLAG, "%s" format, __tflag, args); \ + } \ } while(0) -#define PRINT_ERROR_PR(format, args...) \ -do { \ - if (ERROR_FLAG != LOG_FLAG) \ - { \ +#define PRINT_ERROR_PR(format, args...) \ +do { \ + if (ERROR_FLAG != LOG_FLAG) \ + { \ TRACE_LOG_FLAG(LOG_FLAG, trace_flag, "%s: ***ERROR*** " format, \ - LOG_PREFIX, args); \ - } \ + LOG_PREFIX, args); \ + } \ TRACE_LOG_FLAG(ERROR_FLAG, trace_flag, "%s: ***ERROR*** " format, \ - LOG_PREFIX, args); \ + LOG_PREFIX, args); \ } while(0) #define PRINT_INFO_PR(format, args...) \ @@ -229,86 +227,86 @@ format, LOG_PREFIX, args); \ } while(0) -#define PRINT_ERROR(format, args...) \ -do { \ - if (ERROR_FLAG != LOG_FLAG) \ - { \ +#define PRINT_ERROR(format, args...) \ +do { \ + if (ERROR_FLAG != LOG_FLAG) \ + { \ TRACE_LOG_FLAG(LOG_FLAG, trace_flag, "***ERROR*** " format, args); \ - } \ + } \ TRACE_LOG_FLAG(ERROR_FLAG, trace_flag, "***ERROR*** " format, args); \ } while(0) -#define PRINT_INFO(format, args...) \ -do { \ - if (INFO_FLAG != LOG_FLAG) \ - { \ +#define PRINT_INFO(format, args...) \ +do { \ + if (INFO_FLAG != LOG_FLAG) \ + { \ TRACE_LOG_FLAG(LOG_FLAG, trace_flag, format, args); \ - } \ - TRACE_LOG_FLAG(INFO_FLAG, trace_flag, format, args); \ + } \ + TRACE_LOG_FLAG(INFO_FLAG, trace_flag, format, args); \ } while(0) -#define TRACE_ENTRY() \ -do { \ - if (trace_flag & TRACE_ENTRYEXIT) \ - { \ - if (trace_flag & TRACE_PID) \ - { \ +#define TRACE_ENTRY() \ +do { \ + if (trace_flag & TRACE_ENTRYEXIT) \ + { \ + if (trace_flag & TRACE_PID) \ + { \ PRINT(LOG_FLAG, "[%d]: ENTRY %s", current->pid, \ - __FUNCTION__); \ - } \ - else \ - { \ - PRINT(LOG_FLAG, "ENTRY %s", __FUNCTION__); \ - } \ - } \ + __FUNCTION__); \ + } \ + else \ + { \ + PRINT(LOG_FLAG, "ENTRY %s", __FUNCTION__); \ + } \ + } \ } while(0) -#define TRACE_EXIT() \ -do { \ - if (trace_flag & TRACE_ENTRYEXIT) \ - { \ - if (trace_flag & TRACE_PID) \ - { \ +#define TRACE_EXIT() \ +do { \ + if (trace_flag & TRACE_ENTRYEXIT) \ + { \ + if (trace_flag & TRACE_PID) \ + { \ PRINT(LOG_FLAG, "[%d]: EXIT %s", current->pid, \ - __FUNCTION__); \ - } \ - else \ - { \ - PRINT(LOG_FLAG, "EXIT %s", __FUNCTION__); \ - } \ - } \ + __FUNCTION__); \ + } \ + else \ + { \ + PRINT(LOG_FLAG, "EXIT %s", __FUNCTION__); \ + } \ + } \ } while(0) -#define TRACE_EXIT_RES(res) \ -do { \ - if (trace_flag & TRACE_ENTRYEXIT) \ - { \ - if (trace_flag & TRACE_PID) \ - { \ - PRINT(LOG_FLAG, "[%d]: EXIT %s: %ld", current->pid, \ - __FUNCTION__, (long)(res)); \ - } \ - else \ - { \ +#define TRACE_EXIT_RES(res) \ +do { \ + if (trace_flag & TRACE_ENTRYEXIT) \ + { \ + if (trace_flag & TRACE_PID) \ + { \ + PRINT(LOG_FLAG, "[%d]: EXIT %s: %ld", current->pid, \ + __FUNCTION__, (long)(res)); \ + } \ + else \ + { \ PRINT(LOG_FLAG, "EXIT %s: %ld", __FUNCTION__, (long)(res)); \ - } \ - } \ + } \ + } \ } while(0) -#define TRACE_EXIT_HRES(res) \ -do { \ - if (trace_flag & TRACE_ENTRYEXIT) \ - { \ - if (trace_flag & TRACE_PID) \ - { \ - PRINT(LOG_FLAG, "[%d]: EXIT %s: 0x%lx", current->pid, \ - __FUNCTION__, (long)(res)); \ - } \ - else \ - { \ +#define TRACE_EXIT_HRES(res) \ +do { \ + if (trace_flag & TRACE_ENTRYEXIT) \ + { \ + if (trace_flag & TRACE_PID) \ + { \ + PRINT(LOG_FLAG, "[%d]: EXIT %s: 0x%lx", current->pid, \ + __FUNCTION__, (long)(res)); \ + } \ + else \ + { \ PRINT(LOG_FLAG, "EXIT %s: %lx", __FUNCTION__, (long)(res)); \ - } \ - } \ + } \ + } \ } while(0) #else /* DEBUG */ @@ -321,8 +319,8 @@ #define TRACE_EXIT_RES(res) {} #define TRACE_EXIT_HRES(res) {} -#define PRINT_INFO_PR(format, args...) \ -do { \ +#define PRINT_INFO_PR(format, args...) \ +do { \ PRINT(INFO_FLAG, "%s: " format, LOG_PREFIX, args); \ } while(0) Modified: trunk/scst/kernel/in-tree/Makefile.scsi_tgt =================================================================== --- trunk/scst/kernel/in-tree/Makefile.scsi_tgt 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/scst/kernel/in-tree/Makefile.scsi_tgt 2006-12-15 15:59:21 UTC (rev 62) @@ -5,6 +5,7 @@ scsi_tgt-y += scst_targ.o scsi_tgt-y += scst_lib.o scsi_tgt-y += scst_proc.o +scsi_tgt-y += scst_mem.o obj-$(CONFIG_SCSI_TARGET) += scsi_tgt.o obj-$(CONFIG_SCSI_TARGET_DISK) += scst_disk.o Modified: trunk/scst/src/Makefile =================================================================== --- trunk/scst/src/Makefile 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/scst/src/Makefile 2006-12-15 15:59:21 UTC (rev 62) @@ -29,9 +29,19 @@ DEV_HANDLERS_DIR = dev_handlers ifneq ($(KERNELRELEASE),) +SCST_INC_DIR := $(SUBDIRS)/../include + obj-m := scsi_tgt.o scsi_tgt-objs := scst.o scst_targ.o scst_lib.o scst_mem.o scst_proc.o +scsi_tgt-y += scst.o +scsi_tgt-y += scst_targ.o +scsi_tgt-y += scst_lib.o +scsi_tgt-y += scst_proc.o +scsi_tgt-y += scst_mem.o +scsi_tgt-y += scst_debug.o +obj-$(CONFIG_SCSI_TARGET) += scsi_tgt.o dev_handlers/ + obj-$(BUILD_DEV) += $(DEV_HANDLERS_DIR)/ else @@ -59,7 +69,6 @@ install -d $(INSTALL_DIR_H) install -m 644 ../include/scsi_tgt.h $(INSTALL_DIR_H) install -m 644 ../include/scst_debug.h $(INSTALL_DIR_H) - install -m 644 ../include/scst_debug.c $(INSTALL_DIR_H) ifneq ($(MODS_VERS),) rm -f $(INSTALL_DIR_H)/Module.symvers install -m 644 Modules.symvers $(INSTALL_DIR_H) @@ -81,10 +90,8 @@ INSTALL_DIR := /lib/modules/$(shell uname -r)/extra INSTALL_DIR_H := /usr/local/include/scst -INC_DIR := $(SUBDIRS)/../include +EXTRA_CFLAGS += -I$(SCST_INC_DIR) -EXTRA_CFLAGS += -I$(INC_DIR) - #EXTRA_CFLAGS += -DSTRICT_SERIALIZING EXTRA_CFLAGS += -DEXTRACHECKS Modified: trunk/scst/src/dev_handlers/Makefile =================================================================== --- trunk/scst/src/dev_handlers/Makefile 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/scst/src/dev_handlers/Makefile 2006-12-15 15:59:21 UTC (rev 62) @@ -27,8 +27,20 @@ # ifneq ($(KERNELRELEASE),) +SCST_INC_DIR := $(SUBDIRS)/../include + obj-m := scst_cdrom.o scst_changer.o scst_disk.o scst_modisk.o scst_tape.o \ scst_fileio.o scst_raid.o scst_processor.o + +obj-$(CONFIG_SCSI_TARGET_DISK) += scst_disk.o +obj-$(CONFIG_SCSI_TARGET_TAPE) += scst_tape.o +obj-$(CONFIG_SCSI_TARGET_CDROM) += scst_cdrom.o +obj-$(CONFIG_SCSI_TARGET_MODISK) += scst_modisk.o +obj-$(CONFIG_SCSI_TARGET_CHANGER) += scst_changer.o +obj-$(CONFIG_SCSI_TARGET_RAID) += scst_raid.o +obj-$(CONFIG_SCSI_TARGET_PROCESSOR) += scst_processor.o +obj-$(CONFIG_SCSI_TARGET_FILEIO) += scst_fileio.o + else ifeq ($(KDIR),) KDIR := /lib/modules/$(shell uname -r)/build @@ -48,11 +60,9 @@ INSTALL_DIR := /lib/modules/$(shell uname -r)/extra -EXTRA_CFLAGS += -I$(SUBDIRS) -I$(SUBDIRS)/../include -#EXTRA_CFLAGS += -I$(SUBDIRS) -I$(SUBDIRS)/../../include -I$(SUBDIRS)/.. +EXTRA_CFLAGS += -I$(SUBDIRS) -I$(SCST_INC_DIR) #EXTRA_CFLAGS += -DTRACING - EXTRA_CFLAGS += -DDEBUG clean: Modified: trunk/scst/src/dev_handlers/scst_cdrom.c =================================================================== --- trunk/scst/src/dev_handlers/scst_cdrom.c 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/scst/src/dev_handlers/scst_cdrom.c 2006-12-15 15:59:21 UTC (rev 62) @@ -20,12 +20,10 @@ #include <linux/cdrom.h> #define LOG_PREFIX "dev_cdrom" -#include "scst_debug.h" + #include "scsi_tgt.h" #include "scst_dev_handler.h" -#include "scst_debug.c" - #define CDROM_NAME "dev_cdrom" #define CDROM_TYPE { \ @@ -58,10 +56,6 @@ int cdrom_parse(struct scst_cmd *, const struct scst_info_cdb *); int cdrom_done(struct scst_cmd *); -#if defined(DEBUG) || defined(TRACING) -unsigned long trace_flag = SCST_DEFAULT_DEV_LOG_FLAGS; -#endif - static struct scst_dev_type cdrom_devtype = CDROM_TYPE; /************************************************************** Modified: trunk/scst/src/dev_handlers/scst_changer.c =================================================================== --- trunk/scst/src/dev_handlers/scst_changer.c 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/scst/src/dev_handlers/scst_changer.c 2006-12-15 15:59:21 UTC (rev 62) @@ -18,12 +18,10 @@ */ #define LOG_PREFIX "dev_changer" -#include "scst_debug.h" + #include "scsi_tgt.h" #include "scst_dev_handler.h" -#include "scst_debug.c" - #define CHANGER_NAME "dev_changer" #define CHANGER_TYPE { \ @@ -47,10 +45,6 @@ int changer_parse(struct scst_cmd *, const struct scst_info_cdb *); int changer_done(struct scst_cmd *); -#if defined(DEBUG) || defined(TRACING) -unsigned long trace_flag = SCST_DEFAULT_DEV_LOG_FLAGS; -#endif - static struct scst_dev_type changer_devtype = CHANGER_TYPE; /************************************************************** Modified: trunk/scst/src/dev_handlers/scst_dev_handler.h =================================================================== --- trunk/scst/src/dev_handlers/scst_dev_handler.h 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/scst/src/dev_handlers/scst_dev_handler.h 2006-12-15 15:59:21 UTC (rev 62) @@ -1,3 +1,6 @@ +#ifndef __SCST_DEV_HANDLER_H +#define __SCST_DEV_HANDLER_H + #include <scsi/scsi_eh.h> #define SCST_DEV_UA_RETRIES 5 @@ -10,6 +13,8 @@ #include <linux/proc_fs.h> #include <linux/seq_file.h> +#include "scst_debug.h" + #ifdef DEBUG #define SCST_DEFAULT_DEV_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_PID | \ TRACE_FUNCTION | TRACE_MGMT | TRACE_MINOR | TRACE_MGMT_DEBUG | \ @@ -18,6 +23,9 @@ #define SCST_DEFAULT_DEV_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MINOR) #endif +static unsigned long dh_trace_flag = SCST_DEFAULT_DEV_LOG_FLAGS; +#define trace_flag dh_trace_flag + static struct scst_proc_data dev_handler_log_proc_data; static int dev_handler_log_info_show(struct seq_file *seq, void *v) @@ -25,6 +33,7 @@ int res = 0; TRACE_ENTRY(); + res = scst_proc_log_entry_read(seq, trace_flag, NULL); TRACE_EXIT_RES(res); @@ -55,7 +64,6 @@ TRACE_ENTRY(); root = scst_proc_get_dev_type_root(dev_type); - if (root) { /* create the proc file entry for the device */ dev_handler_log_proc_data.data = (void *)dev_type->name; @@ -84,10 +92,10 @@ TRACE_ENTRY(); root = scst_proc_get_dev_type_root(dev_type); - if (root) { remove_proc_entry(DEV_HANDLER_LOG_ENTRY_NAME, root); } + TRACE_EXIT(); #endif } @@ -98,3 +106,5 @@ .show = dev_handler_log_info_show, }; #endif + +#endif /* __SCST_DEV_HANDLER_H */ Modified: trunk/scst/src/dev_handlers/scst_disk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_disk.c 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/scst/src/dev_handlers/scst_disk.c 2006-12-15 15:59:21 UTC (rev 62) @@ -24,12 +24,10 @@ #include <linux/init.h> #define LOG_PREFIX "dev_disk" -#include "scst_debug.h" + #include "scsi_tgt.h" #include "scst_dev_handler.h" -#include "scst_debug.c" - # define DISK_NAME "dev_disk" # define DISK_PERF_NAME "dev_disk_perf" @@ -78,10 +76,6 @@ int disk_done(struct scst_cmd *cmd); int disk_exec(struct scst_cmd *cmd); -#if defined(DEBUG) || defined(TRACING) -unsigned long trace_flag = SCST_DEFAULT_DEV_LOG_FLAGS; -#endif - static struct scst_dev_type disk_devtype = DISK_TYPE; static struct scst_dev_type disk_devtype_perf = DISK_PERF_TYPE; @@ -90,7 +84,7 @@ int res = 0; TRACE_ENTRY(); - + disk_devtype.module = THIS_MODULE; if (scst_register_dev_driver(&disk_devtype) < 0) { res = -ENODEV; Modified: trunk/scst/src/dev_handlers/scst_fileio.c =================================================================== --- trunk/scst/src/dev_handlers/scst_fileio.c 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/scst/src/dev_handlers/scst_fileio.c 2006-12-15 15:59:21 UTC (rev 62) @@ -37,12 +37,10 @@ #include <linux/kthread.h> #define LOG_PREFIX "dev_fileio" -#include "scst_debug.h" + #include "scsi_tgt.h" #include "scst_dev_handler.h" -#include "scst_debug.c" - /* 8 byte ASCII Vendor of the FILE IO target */ #define SCST_FIO_VENDOR "SCST_FIO" /* 4 byte ASCII Product Revision Level of the FILE IO target - left aligned */ @@ -81,10 +79,6 @@ #define FILEIO_PROC_HELP "help" -#if defined(DEBUG) || defined(TRACING) -unsigned long trace_flag = SCST_DEFAULT_DEV_LOG_FLAGS; -#endif - struct scst_fileio_dev { uint32_t block_size; uint64_t nblocks; @@ -3109,7 +3103,6 @@ TRACE_ENTRY(); devtype->module = THIS_MODULE; - res = scst_register_virtual_dev_driver(devtype); if (res < 0) goto out; Modified: trunk/scst/src/dev_handlers/scst_modisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_modisk.c 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/scst/src/dev_handlers/scst_modisk.c 2006-12-15 15:59:21 UTC (rev 62) @@ -24,12 +24,10 @@ #include <linux/init.h> #define LOG_PREFIX "dev_modisk" -#include "scst_debug.h" + #include "scsi_tgt.h" #include "scst_dev_handler.h" -#include "scst_debug.c" - # define MODISK_NAME "dev_modisk" # define MODISK_PERF_NAME "dev_modisk_perf" @@ -78,10 +76,6 @@ int modisk_done(struct scst_cmd *); int modisk_exec(struct scst_cmd *); -#if defined(DEBUG) || defined(TRACING) -unsigned long trace_flag = SCST_DEFAULT_DEV_LOG_FLAGS; -#endif - static struct scst_dev_type modisk_devtype = MODISK_TYPE; static struct scst_dev_type modisk_devtype_perf = MODISK_PERF_TYPE; Modified: trunk/scst/src/dev_handlers/scst_processor.c =================================================================== --- trunk/scst/src/dev_handlers/scst_processor.c 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/scst/src/dev_handlers/scst_processor.c 2006-12-15 15:59:21 UTC (rev 62) @@ -18,12 +18,10 @@ */ #define LOG_PREFIX "dev_processor" -#include "scst_debug.h" + #include "scsi_tgt.h" #include "scst_dev_handler.h" -#include "scst_debug.c" - #define PROCESSOR_NAME "dev_processor" #define PROCESSOR_TYPE { \ @@ -47,10 +45,6 @@ int processor_parse(struct scst_cmd *, const struct scst_info_cdb *); int processor_done(struct scst_cmd *); -#if defined(DEBUG) || defined(TRACING) -unsigned long trace_flag = SCST_DEFAULT_DEV_LOG_FLAGS; -#endif - static struct scst_dev_type processor_devtype = PROCESSOR_TYPE; /************************************************************** @@ -211,7 +205,7 @@ int res = 0; TRACE_ENTRY(); - + processor_devtype.module = THIS_MODULE; if (scst_register_dev_driver(&processor_devtype) < 0) { res = -ENODEV; Modified: trunk/scst/src/dev_handlers/scst_raid.c =================================================================== --- trunk/scst/src/dev_handlers/scst_raid.c 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/scst/src/dev_handlers/scst_raid.c 2006-12-15 15:59:21 UTC (rev 62) @@ -18,12 +18,10 @@ */ #define LOG_PREFIX "dev_raid" -#include "scst_debug.h" + #include "scsi_tgt.h" #include "scst_dev_handler.h" -#include "scst_debug.c" - #define RAID_NAME "dev_raid" #define RAID_TYPE { \ @@ -47,10 +45,6 @@ int raid_parse(struct scst_cmd *, const struct scst_info_cdb *); int raid_done(struct scst_cmd *); -#if defined(DEBUG) || defined(TRACING) -unsigned long trace_flag = SCST_DEFAULT_DEV_LOG_FLAGS; -#endif - static struct scst_dev_type raid_devtype = RAID_TYPE; /************************************************************** @@ -211,7 +205,7 @@ int res = 0; TRACE_ENTRY(); - + raid_devtype.module = THIS_MODULE; if (scst_register_dev_driver(&raid_devtype) < 0) { res = -ENODEV; Modified: trunk/scst/src/dev_handlers/scst_tape.c =================================================================== --- trunk/scst/src/dev_handlers/scst_tape.c 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/scst/src/dev_handlers/scst_tape.c 2006-12-15 15:59:21 UTC (rev 62) @@ -24,12 +24,10 @@ #include <linux/init.h> #define LOG_PREFIX "dev_tape" -#include "scst_debug.h" + #include "scsi_tgt.h" #include "scst_dev_handler.h" -#include "scst_debug.c" - # define TAPE_NAME "dev_tape" # define TAPE_PERF_NAME "dev_tape_perf" @@ -91,10 +89,6 @@ int tape_done(struct scst_cmd *); int tape_exec(struct scst_cmd *); -#if defined(DEBUG) || defined(TRACING) -unsigned long trace_flag = SCST_DEFAULT_DEV_LOG_FLAGS; -#endif - static struct scst_dev_type tape_devtype = TAPE_TYPE; static struct scst_dev_type tape_devtype_perf = TAPE_PERF_TYPE; @@ -103,7 +97,7 @@ int res = 0; TRACE_ENTRY(); - + tape_devtype.module = THIS_MODULE; if (scst_register_dev_driver(&tape_devtype) < 0) { res = -ENODEV; Modified: trunk/scst/src/scst.c =================================================================== --- trunk/scst/src/scst.c 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/scst/src/scst.c 2006-12-15 15:59:21 UTC (rev 62) @@ -28,12 +28,13 @@ #include <asm/string.h> #include <linux/kthread.h> -#include "scst_debug.h" #include "scsi_tgt.h" #include "scst_priv.h" #include "scst_mem.h" -#include "scst_debug.c" +#if defined(DEBUG) || defined(TRACING) +unsigned long scst_trace_flag = SCST_DEFAULT_LOG_FLAGS; +#endif /* * All targets, devices and dev_types management is done under @@ -70,10 +71,6 @@ LIST_HEAD(scst_cmd_list); DECLARE_WAIT_QUEUE_HEAD(scst_list_waitQ); -#if defined(DEBUG) || defined(TRACING) -unsigned long trace_flag = SCST_DEFAULT_LOG_FLAGS; -#endif - spinlock_t scst_cmd_mem_lock = SPIN_LOCK_UNLOCKED; unsigned long scst_cur_cmd_mem, scst_cur_max_cmd_mem; Added: trunk/scst/src/scst_debug.c =================================================================== --- trunk/scst/src/scst_debug.c (rev 0) +++ trunk/scst/src/scst_debug.c 2006-12-15 15:59:21 UTC (rev 62) @@ -0,0 +1,113 @@ +/* + * include/scst_debug.c + * + * Copyright (C) 2004-2006 Vladislav Bolkhovitin <vs...@vl...> + * and Leonid Stoljar + * + * Contains helper functions for execution tracing and error reporting. + * Intended to be included in main .c file. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "scst_debug.h" +#include "scsi_tgt.h" + +#if defined(DEBUG) || defined(TRACING) + +#define TRACE_BUF_SIZE 512 + +static char trace_buf[TRACE_BUF_SIZE]; +static spinlock_t trace_buf_lock = SPIN_LOCK_UNLOCKED; + +int debug_print_prefix(unsigned long trace_flag, const char *func, + int line) +{ + int i = 0; + unsigned long flags; + + spin_lock_irqsave(&trace_buf_lock, flags); + + if (trace_flag & TRACE_PID) + i += snprintf(&trace_buf[i], TRACE_BUF_SIZE, "[%d]: ", + current->pid); + if (trace_flag & TRACE_FUNCTION) + i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%s:", func); + if (trace_flag & TRACE_LINE) + i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%i:", line); + + if (i > 0) + PRINTN(LOG_FLAG, "%s", trace_buf); + + spin_unlock_irqrestore(&trace_buf_lock, flags); + + return i; +} + +void debug_print_buffer(unsigned long trace_flag, const void *data, + int len) +{ + int z, z1, i; + const unsigned char *buf = (const unsigned char *) data; + int f = 0; + unsigned long flags; + + if (buf == NULL) + return; + + spin_lock_irqsave(&trace_buf_lock, flags); + + PRINT(NO_FLAG, " (h)___0__1__2__3__4__5__6__7__8__9__A__B__C__D__E__F"); + for (z = 0, z1 = 0, i = 0; z < len; z++) { + if (z % 16 == 0) { + if (z != 0) { + i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, + " "); + for (; (z1 < z) && (i < TRACE_BUF_SIZE - 1); + z1++) { + if ((buf[z1] >= 0x20) && + (buf[z1] < 0x80)) + trace_buf[i++] = buf[z1]; + else + trace_buf[i++] = '.'; + } + trace_buf[i] = '\0'; + PRINT(NO_FLAG, "%s", trace_buf); + i = 0; + f = 1; + } + i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, + "%4x: ", z); + } + i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%02x ", + buf[z]); + } + i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, " "); + for (; (z1 < z) && (i < TRACE_BUF_SIZE - 1); z1++) { + if ((buf[z1] > 0x20) && (buf[z1] < 0x80)) + trace_buf[i++] = buf[z1]; + else + trace_buf[i++] = '.'; + } + trace_buf[i] = '\0'; + if (f) { + PRINT(LOG_FLAG, "%s", trace_buf) + } else { + PRINT(NO_FLAG, "%s", trace_buf); + } + + spin_unlock_irqrestore(&trace_buf_lock, flags); + return; +} + +EXPORT_SYMBOL(debug_print_prefix); +EXPORT_SYMBOL(debug_print_buffer); +#endif /* DEBUG || TRACING */ Modified: trunk/scst/src/scst_mem.c =================================================================== --- trunk/scst/src/scst_mem.c 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/scst/src/scst_mem.c 2006-12-15 15:59:21 UTC (rev 62) @@ -30,8 +30,8 @@ #endif #include "scsi_tgt.h" +#include "scst_priv.h" #include "scst_debug.h" -#include "scst_priv.h" #include "scst_mem.h" /* Modified: trunk/scst/src/scst_priv.h =================================================================== --- trunk/scst/src/scst_priv.h 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/scst/src/scst_priv.h 2006-12-15 15:59:21 UTC (rev 62) @@ -30,6 +30,8 @@ #include <scsi/scsi_request.h> #endif +#include "scst_debug.h" + #define SCST_MAJOR 177 #define TRACE_RETRY 0x80000000 @@ -41,6 +43,11 @@ #define LOG_PREFIX "scst" +#if defined(DEBUG) || defined(TRACING) +#define trace_flag scst_trace_flag +extern unsigned long scst_trace_flag; +#endif + #ifdef DEBUG /*#define SCST_DEFAULT_LOG_FLAGS (TRACE_ALL & ~TRACE_MEMORY & ~TRACE_BUFF \ & ~TRACE_FUNCTION) Modified: trunk/scst/src/scst_proc.c =================================================================== --- trunk/scst/src/scst_proc.c 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/scst/src/scst_proc.c 2006-12-15 15:59:21 UTC (rev 62) @@ -30,7 +30,6 @@ #include <linux/proc_fs.h> #include <linux/seq_file.h> -#include "scst_debug.h" #include "scsi_tgt.h" #include "scst_mem.h" #include "scst_priv.h" Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2006-12-15 11:45:24 UTC (rev 61) +++ trunk/scst/src/scst_targ.c 2006-12-15 15:59:21 UTC (rev 62) @@ -27,7 +27,6 @@ #include <asm/string.h> #include <linux/kthread.h> -#include "scst_debug.h" #include "scsi_tgt.h" #include "scst_priv.h" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2007-04-02 10:57:40
|
Revision: 103 http://svn.sourceforge.net/scst/?rev=103&view=rev Author: vlnb Date: 2007-04-02 03:55:55 -0700 (Mon, 02 Apr 2007) Log Message: ----------- Minor fixes Modified Paths: -------------- trunk/qla2x00t/qla2x00-target/qla2x00t.c trunk/scst/src/dev_handlers/scst_vdisk.c Modified: trunk/qla2x00t/qla2x00-target/qla2x00t.c =================================================================== --- trunk/qla2x00t/qla2x00-target/qla2x00t.c 2007-03-07 17:10:45 UTC (rev 102) +++ trunk/qla2x00t/qla2x00-target/qla2x00t.c 2007-04-02 10:55:55 UTC (rev 103) @@ -975,6 +975,7 @@ struct scst_cmd *scst_cmd; struct q2t_cmd *cmd; uint16_t loop_id = -1; + int err = 0; TRACE_ENTRY(); @@ -994,23 +995,24 @@ case CTIO_ABORTED: case CTIO_TIMEOUT: case CTIO_INVALID_RX_ID: + err = 1; /* they are OK */ -#if defined(DEBUG) || defined(TRACING) - PRINT_INFO("qla2x00tgt(%ld): CTIO with status %#x " + TRACE_MGMT_DBG("qla2x00tgt(%ld): CTIO with status %#x " "received (LIP_RESET=e, ABORTED=2, " "TARGET_RESET=17, TIMEOUT=b, " "INVALID_RX_ID=8)", ha->instance, status); -#endif break; case CTIO_PORT_LOGGED_OUT: case CTIO_PORT_UNAVAILABLE: + err = 1; PRINT_INFO("qla2x00tgt(%ld): CTIO with PORT LOGGED " "OUT (29) or PORT UNAVAILABLE (28) status %x " "received", ha->instance, status); break; default: + err = 1; PRINT_ERROR("qla2x00tgt(%ld): CTIO with error status " "0x%x received", ha->instance, status); break; @@ -1032,6 +1034,10 @@ ha->instance, handle); goto out; } + if (unlikely(err)) { + PRINT_INFO("Found by handle failed CTIO scst_cmd " + "%p (op %x)", scst_cmd, scst_cmd->cdb[0]); + } } else if (ctio != NULL) { uint32_t tag = le16_to_cpu(ctio->exchange_id); struct q2t_sess *sess = q2t_find_sess_by_lid(ha->tgt, loop_id); @@ -1051,12 +1057,19 @@ ha->instance, tag, loop_id); goto out; } + if (unlikely(err)) { + PRINT_INFO("Found by ctio failed CTIO scst_cmd %p " + "(op %x)", scst_cmd, scst_cmd->cdb[0]); + } TRACE_DBG("Found scst_cmd %p", scst_cmd); } else goto out; cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd); + if (unlikely(err)) { + PRINT_INFO("Failed CTIO state %d", cmd->state); + } if (cmd->state == Q2T_STATE_PROCESSED) { TRACE_DBG("Command %p finished", cmd); @@ -1103,6 +1116,9 @@ return; out_free: + if (unlikely(err)) { + TRACE_MGMT_DBG("%s", "Finishing failed CTIO"); + } scst_tgt_cmd_done(scst_cmd); goto out; } Modified: trunk/scst/src/dev_handlers/scst_vdisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_vdisk.c 2007-03-07 17:10:45 UTC (rev 102) +++ trunk/scst/src/dev_handlers/scst_vdisk.c 2007-04-02 10:55:55 UTC (rev 103) @@ -782,6 +782,8 @@ vdisk_exec_read_toc(cmd); break; case START_STOP: + vdisk_fsync(thr, 0, virt_dev->file_size, cmd); + break; case RESERVE: case RESERVE_10: case RELEASE: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2007-05-17 14:46:16
|
Revision: 115 http://svn.sourceforge.net/scst/?rev=115&view=rev Author: vlnb Date: 2007-05-17 07:45:18 -0700 (Thu, 17 May 2007) Log Message: ----------- Minor fixes, cleanups and updates Modified Paths: -------------- trunk/scst/README trunk/scst/src/dev_handlers/scst_vdisk.c trunk/scst/src/scst_targ.c trunk/www/scst_page.html Modified: trunk/scst/README =================================================================== --- trunk/scst/README 2007-05-08 09:26:48 UTC (rev 114) +++ trunk/scst/README 2007-05-17 14:45:18 UTC (rev 115) @@ -420,6 +420,31 @@ ========= them, if you try to use a device in both those modes simultaneously, you will almost instantly corrupt your data on that device. +Pass-through mode +----------------- + +As any other hardware, a local SCSI hardware for devices on target, +which are exported in the pass-through mode, can not handle commands +with amount of data and/or segments count in scatter-gather array +bigger, than some values. Therefore, when using the pass-through mode +you should note that the corresponding values on the corresponding +devices on initiators can not be bigger, than values, which the hardware +on the target can support. Otherwise you will see symptoms like small +transfers work well, but large ones stall and messages like: "Unable to +complete command due to SG IO count limitation" are printed in the +kernel logs. + +You can't control from the user space limit of the scatter-gather +segments, but for block devices usually it is sufficient if you set on +the initiator /sys/block/DEVICE_NAME/queue/max_sectors_kb in the same or +lower value as in /sys/block/DEVICE_NAME/queue/max_hw_sectors_kb for the +corresponding device on the target. + +For not-block devices SCSI commands are usually generated directly by +applications, so, if you experience large transfers stalls, you should +check documentation for your application how to limit the transfer +sizes. + Performance ----------- Modified: trunk/scst/src/dev_handlers/scst_vdisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_vdisk.c 2007-05-08 09:26:48 UTC (rev 114) +++ trunk/scst/src/dev_handlers/scst_vdisk.c 2007-05-17 14:45:18 UTC (rev 115) @@ -1669,8 +1669,8 @@ int res = 0; struct scst_vdisk_dev *virt_dev = thr->virt_dev; struct file *file = thr->fd; - struct inode *inode = file->f_dentry->d_inode; - struct address_space *mapping = file->f_mapping; + struct inode *inode; + struct address_space *mapping; TRACE_ENTRY(); @@ -1680,6 +1680,9 @@ virt_dev->nullio) goto out; + inode = file->f_dentry->d_inode; + mapping = file->f_mapping; + res = sync_page_range(inode, mapping, loff, len); if (unlikely(res != 0)) { PRINT_ERROR_PR("sync_page_range() failed (%d)", res); Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2007-05-08 09:26:48 UTC (rev 114) +++ trunk/scst/src/scst_targ.c 2007-05-17 14:45:18 UTC (rev 115) @@ -655,7 +655,7 @@ } if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))) { - TRACE_DBG("ABORTED set, returning ABORTED for " + TRACE_MGMT_DBG("ABORTED set, returning ABORTED for " "cmd %p", cmd); cmd->state = SCST_CMD_STATE_DEV_DONE; res = SCST_CMD_STATE_RES_CONT_SAME; @@ -822,7 +822,7 @@ TRACE_ENTRY(); if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))) { - TRACE_DBG("ABORTED set, aborting cmd %p", cmd); + TRACE_MGMT_DBG("ABORTED set, aborting cmd %p", cmd); goto out_dev_done; } @@ -1634,7 +1634,7 @@ smp_mb__after_set_bit(); if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))) { - TRACE_DBG("ABORTED set, aborting cmd %p", cmd); + TRACE_MGMT_DBG("ABORTED set, aborting cmd %p", cmd); goto out_aborted; } @@ -1769,7 +1769,7 @@ /* Optimized for lockless fast path */ - TRACE_SN("Slot %d, *cur_sn_slot %d", slot-tgt_dev->sn_slots, + TRACE_SN("Slot %d, *cur_sn_slot %d", slot - tgt_dev->sn_slots, atomic_read(slot)); if (!atomic_dec_and_test(slot)) @@ -2913,7 +2913,9 @@ TRACE_ENTRY(); +#if 0 set_user_nice(current, 10); +#endif current->flags |= PF_NOFREEZE; spin_lock_irq(&p_cmd_lists->cmd_list_lock); @@ -3694,7 +3696,7 @@ TRACE_DBG("Calling target %s task_mgmt_fn_done()", mcmd->sess->tgt->tgtt->name); mcmd->sess->tgt->tgtt->task_mgmt_fn_done(mcmd); - TRACE_MGMT_DBG("Dev handler %s task_mgmt_fn_done() returned", + TRACE_MGMT_DBG("Target's %s task_mgmt_fn_done() returned", mcmd->sess->tgt->tgtt->name); } Modified: trunk/www/scst_page.html =================================================================== --- trunk/www/scst_page.html 2007-05-08 09:26:48 UTC (rev 114) +++ trunk/www/scst_page.html 2007-05-17 14:45:18 UTC (rev 115) @@ -126,11 +126,11 @@ supported by Linux platform. More detail information you could find in the project's README file.<br> </p> -<p style="text-align: justify;">Starting from version 0.9.4 2.4 Linux +Starting from version 0.9.4 2.4 Linux kernels are not supported anymore, although there could be new SCST releases for those kernels with very important bug fixes. The latest stable -version of SCST with 2.4 kernels support is 0.9.3.1-24.</p> +version of SCST with 2.4 kernels support is 0.9.3.1-24. <p style="text-align: justify;">If you have any questions you can ask them on the SCST SF.net page either using forum, or scst-devel mailing list.<br> @@ -146,10 +146,13 @@ href="doc/scst_cmd_thread.png">scst_cmd_thread</a>, <a href="doc/scst_mgmt_cmd_thread.png">scst_mgmt_cmd_thread</a>, <a href="doc/scst_mgmt_thread.png">scst_mgmt_thread</a><br> -<p>The latest development versions of SCST and its drivers are +<p>The latest development version of SCST and target drivers is available directly from the -project's SVN. You can access it using either <a - href="http://svn.sourceforge.net/scst">web-based SVN +project's SVN. The SCST release policy is to make stable releases +twice a year, with the only exception if the current stable version +contains a critical bug. Therefore on practice the development version +is usually more stable, than the "stable" one. You can access it using +either <a href="http://svn.sourceforge.net/scst">web-based SVN repository viewer</a> or using anonymous access: </p> <p> <tt> svn co https://svn.sourceforge.net/svnroot/scst<br> </tt></p> @@ -210,6 +213,14 @@ above how to setup access to it.<br> <br> <hr style="width: 100%; height: 2px;"> +<h1><small>SCSI RDMA Protocol (SRP) Target driver</small></h1> +<p>SCSI RDMA Protocol (SRP) Target driver is developed +independently from SCST team. You can find instructions how to download +and install it on this page: <a + href="http://lists.openfabrics.org/pipermail/iwg/2007-March/000378.html">http://lists.openfabrics.org/pipermail/iwg/2007-March/000378.html</a><br> +<br> +</p> +<hr style="width: 100%; height: 2px;"> <h1><small>Old target driver for Qlogic 2200/2300 cards<br> </small></h1> <div style="text-align: justify;">Old target driver for Qlogic @@ -233,6 +244,9 @@ for details. Tested on i386 only, but should work on any other supported by Linux platform.<br> <br> +Currently it is not supported and listed here for historical reasons +only.<br> +<br> </div> <a href="http://sourceforge.net/project/showfiles.php?group_id=110471">Download</a><br> <a href="ChangeLog.qla">Change Log</a> @@ -270,6 +284,9 @@ Requires Linux kernel versions 2.4.20 or higher or 2.6.7 or higher and SCST version 0.9.2 or higher.<br> <br> +Currently it is not supported and listed here for historical reasons +only.<br> +<br> <a href="http://sourceforge.net/project/showfiles.php?group_id=110471">Download</a><br> <br> </body> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2007-06-01 11:11:21
|
Revision: 123 http://svn.sourceforge.net/scst/?rev=123&view=rev Author: vlnb Date: 2007-06-01 04:11:19 -0700 (Fri, 01 Jun 2007) Log Message: ----------- Docs update Modified Paths: -------------- trunk/scst/README trunk/www/scst_page.html Modified: trunk/scst/README =================================================================== --- trunk/scst/README 2007-05-31 17:13:27 UTC (rev 122) +++ trunk/scst/README 2007-06-01 11:11:19 UTC (rev 123) @@ -342,7 +342,7 @@ will go from the initiator. - BLOCKIO - enables block mode, which will perform direct block - IO with the device, bypassing page-cache for all operations. + IO with a block device, bypassing page-cache for all operations. This mode works ideally with high-end storage HBAs and for applications that either do not need caching between application and disk or need the large block throughput. See also below. Modified: trunk/www/scst_page.html =================================================================== --- trunk/www/scst_page.html 2007-05-31 17:13:27 UTC (rev 122) +++ trunk/www/scst_page.html 2007-06-01 11:11:19 UTC (rev 123) @@ -55,15 +55,19 @@ target T devices Da and Db read-writable, and initiator B from the same target T could see devices Db read-only and Dc read-writable.<br> </li> - <li> Complete SMP support.<br> - </li> <li> Emulates necessary functionality of SCSI host adapter, because -from a remote initiator's point of view SCST acts as a SCSI host with +from remote initiators point of view SCST acts as a SCSI host with its -own devices. Some of the emulated functions are the following: +own devices. This is especially important in pass-through mode with one +to many relationship, i.e. when +multiple initiators can connect to the exported pass-through devices. +You can find more deep elaboration why it is needed in <a + href="http://www.mail-archive.com/lin...@vg.../msg06911.html">this</a> +message in linux-scsi mailing list. Some of the emulated functions are +the following: <ul> <li> Generation of necessary UNIT ATTENTIONs, their storage and -delivery to all connected remote initiators (sessions). </li> +delivery to all connected remote initiators. </li> <li> RESERVE/RELEASE functionality. </li> <li> CA/ACA conditions (not implemented yet). </li> <li> All types of RESETs and other task management functions. </li> @@ -86,23 +90,24 @@ space for device emulation. Example of such plugin is FILEIO device handler (see below) .<br> </li> + <li> Complete SMP support.<br> + </li> + <li> </li> <li>Well documented.<br> </li> </ul> <div style="text-align: justify;"> </div> <p style="text-align: justify;">Interoperability between SCST and local -SCSI initiators (like sd, st) is +SCSI initiators (i.e. sd, st, etc.) is the additional issue that SCST is going to address (it is not implemented yet). It is necessary, because local SCSI initiators can change the state of the device, for example RESERVE the device, or some -of its parameters and that would be done behind SCST, which could lead -to various problems. Thus, RESERVE/RELEASE commands, locally generated +of its parameters and that could be done behind SCST, which could lead +to various problems, including data corruption. Thus, RESERVE/RELEASE +commands, locally generated UNIT ATTENTIONs, etc. should be intercepted and processed as if local -SCSI initiators act as remote SCSI initiators connected to SCST. This -feature requires some the kernel modification. Since in the current -version it is not implemented, SCST and target drivers are -able to work with any version of Linux 2.6 kernel.<br> +SCSI initiators act as remote SCSI initiators connected to SCST.<br> </p> <p style="text-align: justify;">Interface between SCST and target drivers is based on work, done by <a href="http://www.iol.unh.edu/">University @@ -111,26 +116,44 @@ project</a>, which is currently developed on <a href="http://unh-iscsi.sourceforge.net/">SourceForge.net</a>.<br> </p> -<p style="text-align: justify;">The latest stable version is 0.9.5. It -supports SCSI disks (type 0), tapes (type 1), processors (type +<p style="text-align: justify;">SCST supports the following I/O modes:<br> +</p> +<ul> + <li>Pass-through mode with one to many relationship, i.e. when +multiple initiators can connect to the exported pass-through devices, +for virtually all SCSI devices types: disks +(type 0), tapes (type 1), processors (type 3), CDROMs (type 5), MO disks (type 7), medium changers (type 8) and -RAID controllers (type 0xC). Also it supports FILEIO and "performance" -device handlers. FILEIO device handler allows to use files on file +RAID controllers (type 0xC)</li> + <li>FILEIO mode, which allows to use files on file systems or block devices as virtual remotely available SCSI disks or -CDROMs. "Performance" device handlers provide a way for direct +CDROMs with benefits of the Linux page cache<br> + </li> + <li>BLOCKIO mode, which performs direct block IO with a block device, +bypassing page-cache for all operations. This mode works ideally with +high-end storage HBAs and for applications that either do not need +caching between application and disk or need the large block throughput.</li> + <li>User space mode using scst_user device handler, which allows to +implement in the user space virtual SCSI devices in the SCST environment<br> + </li> + <li>"Performance" device handlers, which provide in pseudo +pass-through mode a way for direct performance measurements without overhead of actual data transferring -from/to underlying SCSI device. Requires Linux kernel 2.6.14 or higher. +from/to underlying SCSI device<br> + </li> +</ul> +<p style="text-align: justify;">The latest stable version is 0.9.5. +Requires Linux kernel 2.6.14 or higher. Tested mostly on i386 and x86_64, but should also work on any other supported by Linux platform. More detail information you could find in -the project's README file.<br> +the project's README file. </p> Starting from version 0.9.4 2.4 Linux -kernels are not supported anymore, although there could be new SCST -releases for those kernels with very important bug fixes. The latest +kernels are not supported anymore. The latest stable -version of SCST with 2.4 kernels support is 0.9.3.1-24. +version of SCST for 2.4 kernels is 0.9.3.1-24. <p style="text-align: justify;">If you have any questions you can ask them on the SCST SF.net page either using forum, or scst-devel mailing list.<br> @@ -140,7 +163,8 @@ page</a><br> <a href="ChangeLog.scst">Change Log</a><br> Documentation: <a href="doc/scst_pg.html">HTML</a>, <a - href="doc/scst_pg.pdf">PDF</a><br> + href="doc/scst_pg.pdf">PDF</a>, <a href="doc/scst_user_spec.txt">scst_user +interface description</a><br> Some nice SCST call graphs, created by Ming Zhang: <a href="doc/init_scst.png">init_scst</a>, <a href="doc/scst_cmd_thread.png">scst_cmd_thread</a>, <a @@ -151,6 +175,7 @@ project's SVN. The SCST release policy is to make stable releases twice a year, with the only exception if the current stable version contains a critical bug. Therefore on practice the development version +in the SVN is usually more stable, than the "stable" one. You can access it using either <a href="http://svn.sourceforge.net/scst">web-based SVN repository viewer</a> or using anonymous access: </p> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2007-06-08 10:25:59
|
Revision: 125 http://svn.sourceforge.net/scst/?rev=125&view=rev Author: vlnb Date: 2007-06-08 03:25:29 -0700 (Fri, 08 Jun 2007) Log Message: ----------- - Threads made per-device - Minor cleanups and fixes Modified Paths: -------------- trunk/Makefile trunk/doc/scst_user_spec.txt trunk/scst/include/scsi_tgt.h trunk/scst/include/scst_debug.h trunk/scst/include/scst_user.h trunk/scst/src/dev_handlers/scst_user.c trunk/scst/src/scst.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_mem.c trunk/scst/src/scst_priv.h trunk/scst/src/scst_targ.c trunk/usr/fileio/common.c Modified: trunk/Makefile =================================================================== --- trunk/Makefile 2007-06-01 15:05:54 UTC (rev 124) +++ trunk/Makefile 2007-06-08 10:25:29 UTC (rev 125) @@ -154,5 +154,5 @@ .PHONY: all install uninstall clean extraclean help \ qla qla_install qla_uninstall qla_clean qla_extraclean \ lsi lsi_install lsi_uninstall lsi_clean lsi_extraclean \ - scst scst_install scst_uninstall scst_clean scst_extraclean + scst scst_install scst_uninstall scst_clean scst_extraclean \ usr usr_install usr_uninstall usr_clean usr_extraclean Modified: trunk/doc/scst_user_spec.txt =================================================================== --- trunk/doc/scst_user_spec.txt 2007-06-01 15:05:54 UTC (rev 124) +++ trunk/doc/scst_user_spec.txt 2007-06-08 10:25:29 UTC (rev 125) @@ -251,6 +251,7 @@ { uint64_t sess_h; uint64_t lun; + uint16_t threads_num; uint8_t rd_only; char initiator_name[SCST_MAX_NAME]; }, @@ -260,7 +261,10 @@ - sess_h - session's handle, may not be 0 - lun - assigned LUN for this device in this session - + + - threads_num - specifies amount of additional threads, requested by + the corresponding target driver + - rd_only - if true, this device is read only in this session - initiator_name - name of the remote initiator, which initiated this Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2007-06-01 15:05:54 UTC (rev 124) +++ trunk/scst/include/scsi_tgt.h 2007-06-08 10:25:29 UTC (rev 125) @@ -619,9 +619,6 @@ /* The pointer to the /proc directory entry */ struct proc_dir_entry *proc_tgt_root; - /* Dedicated thread number */ - int thread_num; - /* Device number in /proc */ int proc_dev_num; }; @@ -1181,6 +1178,12 @@ { struct scst_dev_type *handler; /* corresponding dev handler */ + /* Pointer to lists of commands with the lock */ + struct scst_cmd_lists *p_cmd_lists; + + /* Lists of commands with the lock, if dedicated threads are used */ + struct scst_cmd_lists cmd_lists; + unsigned short type; /* SCSI type of the device */ /************************************************************* @@ -1250,6 +1253,9 @@ /* List of acg_dev's, one per acg, protected by scst_mutex */ struct list_head dev_acg_dev_list; + + /* List of dedicated threads. Doesn't need any protection. */ + struct list_head threads_list; }; /* @@ -1276,9 +1282,6 @@ struct scst_device *dev; /* to save extra dereferences */ lun_t lun; /* to save extra dereferences */ - /* Pointer to lists of commands with the lock */ - struct scst_cmd_lists *p_cmd_lists; - /* How many cmds alive on this dev in this session */ atomic_t cmd_count; @@ -1313,9 +1316,6 @@ atomic_t *cur_sn_slot; atomic_t sn_slots[10]; - /* Lists of commands with the lock, if dedicated threads are used */ - struct scst_cmd_lists cmd_lists; - /* Used for storage of dev handler private stuff */ void *dh_priv; @@ -1337,8 +1337,7 @@ /* internal tmp list entry */ struct list_head extra_tgt_dev_list_entry; - /* List of dedicated threads. Doesn't need any protection. */ - struct list_head threads_list; + }; /* Modified: trunk/scst/include/scst_debug.h =================================================================== --- trunk/scst/include/scst_debug.h 2007-06-01 15:05:54 UTC (rev 124) +++ trunk/scst/include/scst_debug.h 2007-06-08 10:25:29 UTC (rev 125) @@ -57,9 +57,13 @@ #endif #ifdef EXTRACHECKS -#define EXTRACHECKS_BUG_ON(a) sBUG_ON(a) +#define EXTRACHECKS_BUG_ON(a) sBUG_ON(a) +#define EXTRACHECKS_WARN_ON(a) WARN_ON(a) +#define EXTRACHECKS_WARN_ON_ONCE(a) WARN_ON_ONCE(a) #else #define EXTRACHECKS_BUG_ON(a) +#define EXTRACHECKS_WARN_ON(a) +#define EXTRACHECKS_WARN_ON_ONCE(a) #endif #ifdef DEBUG Modified: trunk/scst/include/scst_user.h =================================================================== --- trunk/scst/include/scst_user.h 2007-06-01 15:05:54 UTC (rev 124) +++ trunk/scst/include/scst_user.h 2007-06-08 10:25:29 UTC (rev 125) @@ -106,6 +106,7 @@ { aligned_u64 sess_h; aligned_u64 lun; + uint16_t threads_num; uint8_t rd_only; char initiator_name[SCST_MAX_NAME]; }; Modified: trunk/scst/src/dev_handlers/scst_user.c =================================================================== --- trunk/scst/src/dev_handlers/scst_user.c 2007-06-01 15:05:54 UTC (rev 124) +++ trunk/scst/src/dev_handlers/scst_user.c 2007-06-08 10:25:29 UTC (rev 125) @@ -2148,6 +2148,8 @@ goto out; } + sdev->p_cmd_lists = &dev->cmd_lists; + sdev->dh_priv = dev; PRINT_INFO_PR("Attached user space SCSI target virtual device \"%s\"", @@ -2219,8 +2221,6 @@ TRACE_ENTRY(); - tgt_dev->p_cmd_lists = &dev->cmd_lists; - ucmd = dev_user_alloc_ucmd(dev, GFP_KERNEL); if (ucmd == NULL) goto out_nomem; @@ -2235,6 +2235,7 @@ ucmd->user_cmd.subcode = SCST_USER_ATTACH_SESS; ucmd->user_cmd.sess.sess_h = (unsigned long)tgt_dev; ucmd->user_cmd.sess.lun = (uint64_t)tgt_dev->lun; + ucmd->user_cmd.sess.threads_num = tgt_dev->sess->tgt->tgtt->threads_num; ucmd->user_cmd.sess.rd_only = tgt_dev->acg_dev->rd_only_flag; strncpy(ucmd->user_cmd.sess.initiator_name, tgt_dev->sess->initiator_name, @@ -2243,9 +2244,10 @@ sizeof(ucmd->user_cmd.sess.initiator_name)-1] = '\0'; TRACE_MGMT_DBG("Preparing ATTACH_SESS %p (h %d, sess_h %Lx, LUN %Lx, " - "rd_only_flag %d, initiator %s)", ucmd, ucmd->h, + "threads_num %d, rd_only_flag %d, initiator %s)", ucmd, ucmd->h, ucmd->user_cmd.sess.sess_h, ucmd->user_cmd.sess.lun, - ucmd->user_cmd.sess.rd_only, ucmd->user_cmd.sess.initiator_name); + ucmd->user_cmd.sess.threads_num, ucmd->user_cmd.sess.rd_only, + ucmd->user_cmd.sess.initiator_name); ucmd->state = UCMD_STATE_ATTACH_SESS; Modified: trunk/scst/src/scst.c =================================================================== --- trunk/scst/src/scst.c 2007-06-01 15:05:54 UTC (rev 124) +++ trunk/scst/src/scst.c 2007-06-08 10:25:29 UTC (rev 125) @@ -156,6 +156,14 @@ goto out_err; } + if (vtt->threads_num < 0) { + PRINT_ERROR_PR("Wrong threads_num value %d for " + "target \"%s\"", vtt->threads_num, + vtt->name); + res = -EINVAL; + goto out_err; + } + if (!vtt->no_proc_entry) { res = scst_build_proc_target_dir_entries(vtt); if (res < 0) @@ -467,11 +475,9 @@ scst_suspend_activity(); down(&scst_mutex); - dev = scst_alloc_device(GFP_KERNEL); - if (dev == NULL) { - res = -ENOMEM; + res = scst_alloc_device(GFP_KERNEL, &dev); + if (res != 0) goto out_up; - } dev->type = scsidp->type; @@ -618,22 +624,19 @@ if (res != 0) goto out; - dev = scst_alloc_device(GFP_KERNEL); - if (dev == NULL) { - res = -ENOMEM; - goto out; + scst_suspend_activity(); + if (down_interruptible(&scst_mutex) != 0) { + res = -EINTR; + goto out_resume; } + res = scst_alloc_device(GFP_KERNEL, &dev); + if (res != 0) + goto out_up; + dev->type = dev_handler->type; dev->scsi_dev = NULL; dev->virt_name = dev_name; - - scst_suspend_activity(); - if (down_interruptible(&scst_mutex) != 0) { - res = -EINTR; - goto out_free_dev; - } - dev->virt_id = scst_virt_dev_last_id++; list_add_tail(&dev->dev_list_entry, &scst_dev_list); @@ -645,7 +648,8 @@ res = rc; goto out_free_del; } - + +out_up: up(&scst_mutex); out_resume: @@ -666,11 +670,8 @@ out_free_del: list_del(&dev->dev_list_entry); - up(&scst_mutex); - -out_free_dev: scst_free_device(dev); - goto out_resume; + goto out_up; } void scst_unregister_virtual_device(int id) @@ -893,6 +894,123 @@ return; } +/* Called under scst_mutex and suspended activity */ +int scst_add_dev_threads(struct scst_device *dev, int num) +{ + int i, res = 0; + static atomic_t major = ATOMIC_INIT(0); + int N, n = 0; + char nm[12]; + + TRACE_ENTRY(); + + N = atomic_inc_return(&major); + + for (i = 0; i < num; i++) { + struct scst_cmd_thread_t *thr; + + thr = kmalloc(sizeof(*thr), GFP_KERNEL); + if (!thr) { + res = -ENOMEM; + PRINT_ERROR_PR("Failed to allocate thr %d", res); + goto out; + } + strncpy(nm, dev->handler->name, ARRAY_SIZE(nm)-1); + nm[ARRAY_SIZE(nm)-1] = '\0'; + thr->cmd_thread = kthread_run(scst_cmd_thread, + &dev->cmd_lists, "%sd%d_%d", nm, N, n++); + if (IS_ERR(thr->cmd_thread)) { + res = PTR_ERR(thr->cmd_thread); + PRINT_ERROR_PR("kthread_create() failed: %d", res); + kfree(thr); + goto out; + } + list_add(&thr->thread_list_entry, &dev->threads_list); + } + +out: + TRACE_EXIT_RES(res); + return res; +} + +/* Called under scst_mutex and suspended activity */ +static int scst_create_dev_threads(struct scst_device *dev) +{ + int res = 0; + int threads_num; + + TRACE_ENTRY(); + + if (dev->handler->threads_num <= 0) + goto out; + + threads_num = dev->handler->threads_num; + + spin_lock_init(&dev->cmd_lists.cmd_list_lock); + INIT_LIST_HEAD(&dev->cmd_lists.active_cmd_list); + init_waitqueue_head(&dev->cmd_lists.cmd_list_waitQ); + + res = scst_add_dev_threads(dev, threads_num); + if (res != 0) + goto out; + + down(&scst_suspend_mutex); + list_add_tail(&dev->cmd_lists.lists_list_entry, + &scst_cmd_lists_list); + up(&scst_suspend_mutex); + + dev->p_cmd_lists = &dev->cmd_lists; + +out: + TRACE_EXIT_RES(res); + return res; +} + +/* Called under scst_mutex and suspended activity */ +void scst_del_dev_threads(struct scst_device *dev, int num) +{ + struct scst_cmd_thread_t *ct, *tmp; + int i = 0; + + TRACE_ENTRY(); + + list_for_each_entry_safe(ct, tmp, &dev->threads_list, + thread_list_entry) { + int rc = kthread_stop(ct->cmd_thread); + if (rc < 0) { + TRACE_MGMT_DBG("kthread_stop() failed: %d", rc); + } + list_del(&ct->thread_list_entry); + kfree(ct); + if ((num >0) && (++i >= num)) + break; + } + + TRACE_EXIT(); + return; +} + +/* Called under scst_mutex and suspended activity */ +static void scst_stop_dev_threads(struct scst_device *dev) +{ + TRACE_ENTRY(); + + if (list_empty(&dev->threads_list)) + goto out; + + scst_del_dev_threads(dev, -1); + + if (dev->p_cmd_lists == &dev->cmd_lists) { + down(&scst_suspend_mutex); + list_del(&dev->cmd_lists.lists_list_entry); + up(&scst_suspend_mutex); + } + +out: + TRACE_EXIT(); + return; +} + /* The activity supposed to be suspended and scst_mutex held */ int scst_assign_dev_handler(struct scst_device *dev, struct scst_dev_type *handler) @@ -908,8 +1026,7 @@ if (dev->handler && dev->handler->detach_tgt) { list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list, - dev_tgt_dev_list_entry) - { + dev_tgt_dev_list_entry) { TRACE_DBG("Calling dev handler's detach_tgt(%p)", tgt_dev); dev->handler->detach_tgt(tgt_dev); @@ -923,8 +1040,16 @@ TRACE_DBG("%s", "Old handler's detach() returned"); } + scst_stop_dev_threads(dev); + dev->handler = handler; + if (handler) { + res = scst_create_dev_threads(dev); + if (res != 0) + goto out_null; + } + if (handler && handler->attach) { TRACE_DBG("Calling new dev handler's attach(%p)", dev); res = handler->attach(dev); @@ -933,13 +1058,12 @@ PRINT_ERROR_PR("New device handler's %s attach() " "failed: %d", handler->name, res); } - goto out_null; + goto out_thr_null; } if (handler && handler->attach_tgt) { list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list, - dev_tgt_dev_list_entry) - { + dev_tgt_dev_list_entry) { TRACE_DBG("Calling dev handler's attach_tgt(%p)", tgt_dev); res = handler->attach_tgt(tgt_dev); @@ -953,7 +1077,11 @@ &attached_tgt_devs); } } - + +out_thr_null: + if (res != 0) + scst_stop_dev_threads(dev); + out_null: if (res != 0) dev->handler = NULL; Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2007-06-01 15:05:54 UTC (rev 124) +++ trunk/scst/src/scst_lib.c 2007-06-08 10:25:29 UTC (rev 125) @@ -145,33 +145,41 @@ return; } -struct scst_device *scst_alloc_device(int gfp_mask) +/* Called under scst_mutex and suspended activity */ +int scst_alloc_device(int gfp_mask, struct scst_device **out_dev) { struct scst_device *dev; + int res = 0; TRACE_ENTRY(); dev = kzalloc(sizeof(*dev), gfp_mask); if (dev == NULL) { TRACE(TRACE_OUT_OF_MEM, "%s", - "Allocation of scst_device failed"); + "Allocation of scst_device failed"); + res = -ENOMEM; goto out; } + dev->p_cmd_lists = &scst_main_cmd_lists; spin_lock_init(&dev->dev_lock); atomic_set(&dev->on_dev_count, 0); INIT_LIST_HEAD(&dev->blocked_cmd_list); INIT_LIST_HEAD(&dev->dev_tgt_dev_list); INIT_LIST_HEAD(&dev->dev_acg_dev_list); + INIT_LIST_HEAD(&dev->threads_list); init_waitqueue_head(&dev->on_dev_waitQ); dev->dev_double_ua_possible = 1; dev->dev_serialized = 1; + *out_dev = dev; + out: - TRACE_EXIT_HRES(dev); - return dev; + TRACE_EXIT_RES(res); + return res; } +/* Called under scst_mutex and suspended activity */ void scst_free_device(struct scst_device *dev) { TRACE_ENTRY(); @@ -312,96 +320,6 @@ return res; } -static int scst_create_tgt_threads(struct scst_tgt_dev *tgt_dev) -{ - int i, res = 0; - int threads_num = tgt_dev->dev->handler->threads_num + - tgt_dev->sess->tgt->tgtt->threads_num; - static atomic_t major = ATOMIC_INIT(0); - int N, n = 0; - char nm[12]; - - TRACE_ENTRY(); - - if (tgt_dev->dev->handler->threads_num < 0) - threads_num = 0; - - if (threads_num == 0) - goto out; - - spin_lock_init(&tgt_dev->cmd_lists.cmd_list_lock); - INIT_LIST_HEAD(&tgt_dev->cmd_lists.active_cmd_list); - init_waitqueue_head(&tgt_dev->cmd_lists.cmd_list_waitQ); - - if (tgt_dev->dev->handler->threads_num == 0) - threads_num += num_online_cpus(); - - N = atomic_inc_return(&major); - - for (i = 0; i < threads_num; i++) { - struct scst_cmd_thread_t *thr; - - thr = kmalloc(sizeof(*thr), GFP_KERNEL); - if (!thr) { - res = -ENOMEM; - PRINT_ERROR_PR("fail to allocate thr %d", res); - goto out; - } - strncpy(nm, tgt_dev->dev->handler->name, ARRAY_SIZE(nm)-1); - nm[ARRAY_SIZE(nm)-1] = '\0'; - thr->cmd_thread = kthread_run(scst_cmd_thread, - &tgt_dev->cmd_lists, "%sd%d_%d", nm, N, n++); - if (IS_ERR(thr->cmd_thread)) { - res = PTR_ERR(thr->cmd_thread); - PRINT_ERROR_PR("kthread_create() failed: %d", res); - kfree(thr); - goto out; - } - list_add(&thr->thread_list_entry, &tgt_dev->threads_list); - } - - down(&scst_suspend_mutex); - list_add_tail(&tgt_dev->cmd_lists.lists_list_entry, - &scst_cmd_lists_list); - up(&scst_suspend_mutex); - - tgt_dev->p_cmd_lists = &tgt_dev->cmd_lists; - -out: - TRACE_EXIT(); - return res; -} - -static void scst_stop_tgt_threads(struct scst_tgt_dev *tgt_dev) -{ - struct scst_cmd_thread_t *ct, *tmp; - - TRACE_ENTRY(); - - if (list_empty(&tgt_dev->threads_list)) - goto out; - - list_for_each_entry_safe(ct, tmp, &tgt_dev->threads_list, - thread_list_entry) { - int rc = kthread_stop(ct->cmd_thread); - if (rc < 0) { - TRACE_MGMT_DBG("kthread_stop() failed: %d", rc); - } - list_del(&ct->thread_list_entry); - kfree(ct); - } - - if (tgt_dev->p_cmd_lists == &tgt_dev->cmd_lists) { - down(&scst_suspend_mutex); - list_del(&tgt_dev->cmd_lists.lists_list_entry); - up(&scst_suspend_mutex); - } - -out: - TRACE_EXIT(); - return; -} - /* * No spin locks supposed to be held, scst_mutex - held. * The activity is suspended. @@ -413,6 +331,7 @@ struct scst_tgt_dev *tgt_dev; struct scst_device *dev = acg_dev->dev; struct list_head *sess_tgt_dev_list_head; + struct scst_tgt_template *vtt = sess->tgt->tgtt; int rc, i; TRACE_ENTRY(); @@ -431,7 +350,7 @@ memset(tgt_dev, 0, sizeof(*tgt_dev)); #endif - tgt_dev->dev = acg_dev->dev; + tgt_dev->dev = dev; tgt_dev->lun = acg_dev->lun; tgt_dev->acg_dev = acg_dev; tgt_dev->sess = sess; @@ -440,12 +359,10 @@ tgt_dev->gfp_mask = __GFP_NOWARN; tgt_dev->pool = &scst_sgv.norm; - if (tgt_dev->dev->scsi_dev != NULL) { - ini_sg = tgt_dev->dev->scsi_dev->host->sg_tablesize; - ini_unchecked_isa_dma = - tgt_dev->dev->scsi_dev->host->unchecked_isa_dma; - ini_use_clustering = - (tgt_dev->dev->scsi_dev->host->use_clustering == + if (dev->scsi_dev != NULL) { + ini_sg = dev->scsi_dev->host->sg_tablesize; + ini_unchecked_isa_dma = dev->scsi_dev->host->unchecked_isa_dma; + ini_use_clustering = (dev->scsi_dev->host->use_clustering == ENABLE_CLUSTERING); } else { ini_sg = (1 << 15) /* infinite */; @@ -471,8 +388,6 @@ #endif } - tgt_dev->p_cmd_lists = &scst_main_cmd_lists; - if (dev->scsi_dev != NULL) { TRACE_DBG("host=%d, channel=%d, id=%d, lun=%d, " "SCST lun=%Ld", dev->scsi_dev->host->host_no, @@ -497,7 +412,6 @@ tgt_dev->cur_sn_slot = &tgt_dev->sn_slots[0]; for(i = 0; i < (int)ARRAY_SIZE(tgt_dev->sn_slots); i++) atomic_set(&tgt_dev->sn_slots[i], 0); - INIT_LIST_HEAD(&tgt_dev->threads_list); if (dev->handler->parse_atomic && sess->tgt->tgtt->preprocessing_done_atomic) { @@ -531,9 +445,15 @@ tm_dbg_init_tgt_dev(tgt_dev, acg_dev); - rc = scst_create_tgt_threads(tgt_dev); - if (rc != 0) - goto out_free; + if (vtt->threads_num > 0) { + rc = 0; + if (dev->handler->threads_num > 0) + rc = scst_add_dev_threads(dev, vtt->threads_num); + else if (dev->handler->threads_num == 0) + rc = scst_add_cmd_threads(vtt->threads_num); + if (rc != 0) + goto out_free; + } if (dev->handler && dev->handler->attach_tgt) { TRACE_DBG("Calling dev handler's attach_tgt(%p)", @@ -543,7 +463,7 @@ if (rc != 0) { PRINT_ERROR_PR("Device handler's %s attach_tgt() " "failed: %d", dev->handler->name, rc); - goto out_stop_free; + goto out_thr_free; } } @@ -559,8 +479,13 @@ TRACE_EXIT(); return tgt_dev; -out_stop_free: - scst_stop_tgt_threads(tgt_dev); +out_thr_free: + if (vtt->threads_num > 0) { + if (dev->handler->threads_num > 0) + scst_del_dev_threads(dev, vtt->threads_num); + else if (dev->handler->threads_num == 0) + scst_del_cmd_threads(vtt->threads_num); + } out_free: kmem_cache_free(scst_tgtd_cachep, tgt_dev); @@ -613,6 +538,7 @@ static void scst_free_tgt_dev(struct scst_tgt_dev *tgt_dev) { struct scst_device *dev = tgt_dev->dev; + struct scst_tgt_template *vtt = tgt_dev->sess->tgt->tgtt; TRACE_ENTRY(); @@ -631,7 +557,12 @@ TRACE_DBG("%s", "Dev handler's detach_tgt() returned"); } - scst_stop_tgt_threads(tgt_dev); + if (vtt->threads_num > 0) { + if (dev->handler->threads_num > 0) + scst_del_dev_threads(dev, vtt->threads_num); + else if (dev->handler->threads_num == 0) + scst_del_cmd_threads(vtt->threads_num); + } kmem_cache_free(scst_tgtd_cachep, tgt_dev); @@ -2984,7 +2915,7 @@ if (!tm_dbg_flags.tm_dbg_active) { /* Do TM debugging only for LUN 0 */ tm_dbg_p_cmd_list_waitQ = - &tgt_dev->p_cmd_lists->cmd_list_waitQ; + &tgt_dev->dev->p_cmd_lists->cmd_list_waitQ; tm_dbg_state = INIT_TM_DBG_STATE; tm_dbg_on_state_passes = tm_dbg_on_state_num_passes[tm_dbg_state]; Modified: trunk/scst/src/scst_mem.c =================================================================== --- trunk/scst/src/scst_mem.c 2007-06-01 15:05:54 UTC (rev 124) +++ trunk/scst/src/scst_mem.c 2007-06-08 10:25:29 UTC (rev 125) @@ -352,7 +352,7 @@ (obj->sg_entries + pages_to_alloc); TRACE_MEM("trans_tbl %p", obj->trans_tbl); /* We want to have all the data on the same page */ - EXTRACHECKS_BUG_ON(((unsigned long)obj->sg_entries & PAGE_MASK) != + EXTRACHECKS_WARN_ON_ONCE(((unsigned long)obj->sg_entries & PAGE_MASK) != ((unsigned long)&obj->trans_tbl[pages_to_alloc-1] & PAGE_MASK)); /* * No need to clear trans_tbl, if needed, it will @@ -360,7 +360,7 @@ */ } else { /* We want to have all the data on the same page */ - EXTRACHECKS_BUG_ON(((unsigned long)obj->sg_entries & PAGE_MASK) != + EXTRACHECKS_WARN_ON_ONCE(((unsigned long)obj->sg_entries & PAGE_MASK) != ((unsigned long)&obj->sg_entries[pages_to_alloc-1] & PAGE_MASK)); } } else { Modified: trunk/scst/src/scst_priv.h =================================================================== --- trunk/scst/src/scst_priv.h 2007-06-01 15:05:54 UTC (rev 124) +++ trunk/scst/src/scst_priv.h 2007-06-08 10:25:29 UTC (rev 125) @@ -246,7 +246,10 @@ void scst_cmd_mem_work_fn(struct work_struct *work); #endif -struct scst_device *scst_alloc_device(int gfp_mask); +int scst_add_dev_threads(struct scst_device *dev, int num); +void scst_del_dev_threads(struct scst_device *dev, int num); + +int scst_alloc_device(int gfp_mask, struct scst_device **out_dev); void scst_free_device(struct scst_device *tgt_dev); struct scst_acg *scst_alloc_add_acg(const char *acg_name); Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2007-06-01 15:05:54 UTC (rev 124) +++ trunk/scst/src/scst_targ.c 2007-06-08 10:25:29 UTC (rev 125) @@ -2593,7 +2593,7 @@ break; } - cmd->cmd_lists = tgt_dev->p_cmd_lists; + cmd->cmd_lists = tgt_dev->dev->p_cmd_lists; cmd->tgt_dev = tgt_dev; cmd->dev = tgt_dev->dev; @@ -4156,8 +4156,7 @@ restart: list_for_each_entry(cmd, &sess->init_deferred_cmd_list, - cmd_list_entry) - { + cmd_list_entry) { TRACE_DBG("Deleting cmd %p from init deferred cmd list", cmd); list_del(&cmd->cmd_list_entry); sess->sess_cmd_count--; @@ -4170,8 +4169,7 @@ spin_lock(&scst_mcmd_lock); list_for_each_entry_safe(mcmd, tm, &sess->init_deferred_mcmd_list, - mgmt_cmd_list_entry) - { + mgmt_cmd_list_entry) { TRACE_DBG("Moving mgmt command %p from init deferred mcmd list", mcmd); list_move_tail(&mcmd->mgmt_cmd_list_entry, Modified: trunk/usr/fileio/common.c =================================================================== --- trunk/usr/fileio/common.c 2007-06-01 15:05:54 UTC (rev 124) +++ trunk/usr/fileio/common.c 2007-06-08 10:25:29 UTC (rev 125) @@ -594,8 +594,10 @@ tgt_dev->last_write_cmd_queue_type = SCST_CMD_QUEUE_SIMPLE; PRINT_INFO_PR("Session from initiator %s attached (LUN %Lx, " - "rd_only %d, sess_h %Lx)", cmd->sess.initiator_name, - cmd->sess.lun, cmd->sess.rd_only, cmd->sess.sess_h); + "threads_num %d, rd_only %d, sess_h %Lx)", + cmd->sess.initiator_name, cmd->sess.lun, + cmd->sess.threads_num, cmd->sess.rd_only, + cmd->sess.sess_h); } else { if (tgt_dev == NULL) { PRINT_ERROR_PR("Session %Lx not found)", cmd->sess.sess_h); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2007-06-25 16:32:57
|
Revision: 135 http://svn.sourceforge.net/scst/?rev=135&view=rev Author: vlnb Date: 2007-06-25 09:32:46 -0700 (Mon, 25 Jun 2007) Log Message: ----------- Patch from Stanislaw Gruszka <sta...@op...> This is SCST driver for ISP Qlogic chipsets commonly used in many SCSI and FC host bus adapters. Supported chipset are listed in README file, incomplete list of supported HBA's is in doc/Hardware.txt . It is based on Matthew Jacob's multiplatform driver for ISP chipsets, which can be download from ftp://ftp.feral.com/pub/isp/isp_dist.tgz Added Paths: ----------- trunk/qla_isp/ trunk/qla_isp/LICENSE trunk/qla_isp/Makefile trunk/qla_isp/README trunk/qla_isp/README.scst trunk/qla_isp/common/ trunk/qla_isp/common/isp.c trunk/qla_isp/common/isp_library.c trunk/qla_isp/common/isp_library.h trunk/qla_isp/common/isp_stds.h trunk/qla_isp/common/isp_target.c trunk/qla_isp/common/isp_target.h trunk/qla_isp/common/isp_tpublic.h trunk/qla_isp/common/ispmbox.h trunk/qla_isp/common/ispreg.h trunk/qla_isp/common/ispvar.h trunk/qla_isp/doc/ trunk/qla_isp/doc/DriverManual.txt trunk/qla_isp/doc/Hardware.txt trunk/qla_isp/firmware/ trunk/qla_isp/firmware/asm_1000.h trunk/qla_isp/firmware/asm_1040.h trunk/qla_isp/firmware/asm_1080.h trunk/qla_isp/firmware/asm_12160.h trunk/qla_isp/firmware/asm_2100.h trunk/qla_isp/firmware/asm_2200.h trunk/qla_isp/firmware/asm_2300.h trunk/qla_isp/firmware/asm_2322.h trunk/qla_isp/firmware/asm_2400.h trunk/qla_isp/linux/ trunk/qla_isp/linux/LINUX_BUILD_INSTRUCTIONS trunk/qla_isp/linux/LINUX_TARGET_MODE_HOWTO trunk/qla_isp/linux/Makefile trunk/qla_isp/linux/Makefile.alpha trunk/qla_isp/linux/Makefile.i386 trunk/qla_isp/linux/Makefile.ppc trunk/qla_isp/linux/Makefile.sparc trunk/qla_isp/linux/Makefile.sparc64 trunk/qla_isp/linux/Makefile.x86_64 trunk/qla_isp/linux/exioct.h trunk/qla_isp/linux/exioctln.h trunk/qla_isp/linux/isp_cb_ops.c trunk/qla_isp/linux/isp_ioctl.h trunk/qla_isp/linux/isp_linux.c trunk/qla_isp/linux/isp_linux.h trunk/qla_isp/linux/isp_pci.c trunk/qla_isp/linux/isp_scst.c trunk/qla_isp/linux/scsi_target.c trunk/qla_isp/linux/scsi_target.h trunk/qla_isp/linux/scsi_target_ctl.c trunk/qla_isp/linux-2.6/ trunk/qla_isp/linux-2.6/Makefile trunk/qla_isp/linux-2.6/build/ trunk/qla_isp/linux-2.6/build/Makefile Added: trunk/qla_isp/LICENSE =================================================================== --- trunk/qla_isp/LICENSE (rev 0) +++ trunk/qla_isp/LICENSE 2007-06-25 16:32:46 UTC (rev 135) @@ -0,0 +1,53 @@ +Copyright (c) 1997-2007 by Matthew Jacob +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + + +Alternatively, this software may be distributed under the terms of the +the GNU Public License ("GPL") with platforms where the prevalant license +is the GNU Public License: + + 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; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +Matthew Jacob +Feral Software +421 Laurel Avenue +Menlo Park, CA 94025 +USA + +gplbsd at feral com + Added: trunk/qla_isp/Makefile =================================================================== --- trunk/qla_isp/Makefile (rev 0) +++ trunk/qla_isp/Makefile 2007-06-25 16:32:46 UTC (rev 135) @@ -0,0 +1,15 @@ +ifndef KDIR +KDIR := /lib/modules/$(shell uname -r)/build +endif + +export KDIR + +all: + $(MAKE) -C linux-2.6 tgt + +clean: + $(MAKE) -C linux-2.6 clean + +install: + $(MAKE) -C linux-2.6 install + Added: trunk/qla_isp/README =================================================================== --- trunk/qla_isp/README (rev 0) +++ trunk/qla_isp/README 2007-06-25 16:32:46 UTC (rev 135) @@ -0,0 +1,30 @@ +$Id: README,v 1.30 2007/03/05 19:10:52 mjacob Exp $ +------------------------------------------------------------------------------ + +Supported Cards: + +SBus ISP1000 && ISP1000U +PCI SCSI ISP1020 +PCI Ultra SCSI ISP1040, ISP1240 (dual bus) +PCI Ultra2 SCSI ISP1080, ISP1280 (dual bus) +PCI Ultra3 SCSI ISP12160 (dual bus) +PCI Fibre Channel + 1-Gbit: + ISP2100, ISP2102 + ISP2200, ISP2202, ISP2204 + + 2-Gbit: + ISP2300, ISP2312, ISP2324, 2340, 2342 + ISP2322, ISP6322 + ISP200 + 4-Gbit: + ISP2422, ISP2432 + +You should note that some old non-Qlogic (or very old Qlogic) 2100 cards may +have trouble loading firmware. The newer f/w for 2100s is > 0x8000 words, +which PROM code on some cards has trouble loading- define the token +USE_SMALLER_2100_FIRMWARE to select 1.15.37 f/w for the 2100. + +For 23XX (but not 2322) 2K Login firmware is available and is recommended. + +------------------------------------------------------------------------------ Added: trunk/qla_isp/README.scst =================================================================== --- trunk/qla_isp/README.scst (rev 0) +++ trunk/qla_isp/README.scst 2007-06-25 16:32:46 UTC (rev 135) @@ -0,0 +1,48 @@ +WARNING: This driver is not finished, USE ONLY FOR TESTING. + +This is SCST driver for ISP Qlogic chipsets commonly used in many SCSI and FC +host bus adapters. Supported chipset are listed in README file, incomplete +list of supported HBA's is in doc/Hardware.txt . + +It is based on Matthew Jacob's multiplatform driver for ISP chipsets, +which can be download from ftp://ftp.feral.com/pub/isp/isp_dist.tgz. The +update for SCST was made and supported by Stanislaw Gruszka +<sta...@op...>. + +Driver operate same hardware as qla2x00tgt, but have one adventage over it: +support of 24xx series of Qlogic adapters. + +INSTALLATION: + +Build driver with command +$ make +Then install isp_mod, isp_scst modules +$ make install + +Other Qlogic drivers can not coexist in system, unload all other qla modules + +$ rmmod qla2x00tgt +$ rmmod qla2400 +$ rmmod qla2300 +$ rmmod qla2200 +$ rmmod qla2xxx + +Load isp modules + +$ modprobe isp_scst +$ modprobe isp_mod + +Enable all logical units to work in target mode + +$ echo 1 > /proc/scsi_tgt/qla_isp/0 + +(to unload isp_mod.ko module you must write 0 to this file). +This is not switching target/initiator role. If you have more then one device, +role of each you can set using isp_roles parameter, like in example: + +$ modprobe isp_mode isp_roles="b0300=initiator" + +Magic number "b0300" is DEVID value, which you can find in /proc/scsi/isp/X + +To attach logical units continue with normal SCST setup + Added: trunk/qla_isp/common/isp.c =================================================================== --- trunk/qla_isp/common/isp.c (rev 0) +++ trunk/qla_isp/common/isp.c 2007-06-25 16:32:46 UTC (rev 135) @@ -0,0 +1,8340 @@ +/* $Id: isp.c,v 1.166 2007/06/01 17:19:31 mjacob Exp $ */ +/*- + * Copyright (c) 1997-2007 by Matthew Jacob + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * + * Alternatively, this software may be distributed under the terms of the + * the GNU Public License ("GPL") with platforms where the prevalant license + * is the GNU Public License: + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * Matthew Jacob + * Feral Software + * 421 Laurel Avenue + * Menlo Park, CA 94025 + * USA + * + * gplbsd at feral com + */ + +/* + * Machine and OS Independent (well, as best as possible) + * code for the Qlogic ISP SCSI and FC-SCSI adapters. + */ + +/* + * Inspiration and ideas about this driver are from Erik Moe's Linux driver + * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c). Some + * ideas dredged from the Solaris driver. + */ + +/* + * Include header file appropriate for platform we're building on. + */ +#ifdef __NetBSD__ +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD$"); +#include <dev/ic/isp_netbsd.h> +#endif +#ifdef __FreeBSD__ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); +#include <dev/isp/isp_freebsd.h> +#endif +#ifdef __OpenBSD__ +#include <dev/ic/isp_openbsd.h> +#endif +#ifdef __linux__ +#include "isp_linux.h" +#endif +#ifdef __svr4__ +#include "isp_solaris.h" +#endif + +/* + * General defines + */ + +#define MBOX_DELAY_COUNT 1000000 / 100 +#define ISP_MARK_PORTDB(a, b, c) \ + isp_prt(isp, ISP_LOGSANCFG, "line %d: markportdb", __LINE__); \ + isp_mark_portdb(a, b, c) + +/* + * Local static data + */ +static const char fconf[] = + "PortDB[%d] changed:\n current =(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)\n" + " database=(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)"; +static const char notresp[] = + "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d"; +static const char xact1[] = + "HBA attempted queued transaction with disconnect not set for %d.%d.%d"; +static const char xact2[] = + "HBA attempted queued transaction to target routine %d on target %d bus %d"; +static const char xact3[] = + "HBA attempted queued cmd for %d.%d.%d when queueing disabled"; +static const char pskip[] = + "SCSI phase skipped for target %d.%d.%d"; +static const char topology[] = + "HBA PortID 0x%06x N-Port Handle %d, Connection Topology '%s'"; +static const char ourwwn[] = + "HBA WWNN 0x%08x%08x HBA WWPN 0x%08x%08x"; +static const char finmsg[] = + "%d.%d.%d: FIN dl%d resid %d STS 0x%x SKEY %c XS_ERR=0x%x"; +static const char sc0[] = + "%s CHAN %d FTHRSH %d IID %d RESETD %d RETRYC %d RETRYD %d ASD 0x%x"; +static const char sc1[] = + "%s RAAN 0x%x DLAN 0x%x DDMAB 0x%x CDMAB 0x%x SELTIME %d MQD %d"; +static const char sc2[] = "%s CHAN %d TGT %d FLAGS 0x%x 0x%x/0x%x"; +static const char sc3[] = "Generated"; +static const char sc4[] = "NVRAM"; +static const char bun[] = + "bad underrun for %d.%d (count %d, resid %d, status %s)"; + +/* + * Local function prototypes. + */ +static int isp_parse_async(ispsoftc_t *, uint16_t); +static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *, + uint32_t *); +static void +isp_parse_status(ispsoftc_t *, ispstatusreq_t *, XS_T *, long *); +static void +isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *, long *); +static void isp_fastpost_complete(ispsoftc_t *, uint16_t); +static int isp_mbox_continue(ispsoftc_t *); +static void isp_scsi_init(ispsoftc_t *); +static void isp_scsi_channel_init(ispsoftc_t *, int); +static void isp_fibre_init(ispsoftc_t *, int); +static void isp_fibre_init_2400(ispsoftc_t *, int); +static void isp_mark_portdb(ispsoftc_t *, int, int); +static int isp_plogx(ispsoftc_t *, int, uint16_t, uint32_t, int, int); +static int isp_port_login(ispsoftc_t *, uint16_t, uint32_t); +static int isp_port_logout(ispsoftc_t *, uint16_t, uint32_t); +static int isp_getpdb(ispsoftc_t *, int, uint16_t, isp_pdb_t *, int); +static uint64_t isp_get_portname(ispsoftc_t *, int, int, int); +static int isp_fclink_test(ispsoftc_t *, int, int); +static const char *ispfc_fw_statename(int); +static int isp_pdb_sync(ispsoftc_t *, int); +static int isp_scan_loop(ispsoftc_t *, int); +static int isp_gid_ft_sns(ispsoftc_t *, int); +static int isp_gid_ft_ct_passthru(ispsoftc_t *, int); +static int isp_scan_fabric(ispsoftc_t *, int); +static int isp_login_device(ispsoftc_t *, int, uint32_t, isp_pdb_t *, uint16_t *); +static int isp_register_fc4_type(ispsoftc_t *, int); +static int isp_register_fc4_type_24xx(ispsoftc_t *, int); +static uint16_t isp_nxt_handle(ispsoftc_t *, int, uint16_t); +static void isp_fw_state(ispsoftc_t *, int); +static void isp_mboxcmd_qnw(ispsoftc_t *, mbreg_t *, int); +static void isp_mboxcmd(ispsoftc_t *, mbreg_t *); + +static void isp_update(ispsoftc_t *); +static void isp_update_bus(ispsoftc_t *, int); +static void isp_setdfltparm(ispsoftc_t *, int); +static void isp_setdfltfcparm(ispsoftc_t *, int); +static int isp_read_nvram(ispsoftc_t *); +static int isp_read_nvram_2400(ispsoftc_t *, uint8_t *); +static void isp_rdnvram_word(ispsoftc_t *, int, uint16_t *); +static void isp_rd_2400_nvram(ispsoftc_t *, uint32_t, uint32_t *); +static void isp_parse_nvram_1020(ispsoftc_t *, uint8_t *); +static void isp_parse_nvram_1080(ispsoftc_t *, int, uint8_t *); +static void isp_parse_nvram_12160(ispsoftc_t *, int, uint8_t *); +static void isp_fix_nvram_wwns(ispsoftc_t *, int); +static void isp_parse_nvram_2100(ispsoftc_t *, uint8_t *); +static void isp_parse_nvram_2400(ispsoftc_t *, uint8_t *); + +/* + * Reset Hardware. + * + * Hit the chip over the head, download new f/w if available and set it running. + * + * Locking done elsewhere. + */ + +void +isp_reset(ispsoftc_t *isp) +{ + mbreg_t mbs; + uint32_t code_org, val; + int loops, i, dodnld = 1; + static const char *btype = "????"; + static const char dcrc[] = "Downloaded RISC Code Checksum Failure"; + + isp->isp_state = ISP_NILSTATE; + + /* + * Basic types (SCSI, FibreChannel and PCI or SBus) + * have been set in the MD code. We figure out more + * here. Possibly more refined types based upon PCI + * identification. Chip revision has been gathered. + * + * After we've fired this chip up, zero out the conf1 register + * for SCSI adapters and do other settings for the 2100. + */ + + /* + * Get the current running firmware revision out of the + * chip before we hit it over the head (if this is our + * first time through). Note that we store this as the + * 'ROM' firmware revision- which it may not be. In any + * case, we don't really use this yet, but we may in + * the future. + */ + if (isp->isp_touched == 0) { + /* + * First see whether or not we're sitting in the ISP PROM. + * If we've just been reset, we'll have the string "ISP " + * spread through outgoing mailbox registers 1-3. We do + * this for PCI cards because otherwise we really don't + * know what state the card is in and we could hang if + * we try this command otherwise. + * + * For SBus cards, we just do this because they almost + * certainly will be running firmware by now. + */ + if (ISP_READ(isp, OUTMAILBOX1) != 0x4953 || + ISP_READ(isp, OUTMAILBOX2) != 0x5020 || + ISP_READ(isp, OUTMAILBOX3) != 0x2020) { + /* + * Just in case it was paused... + */ + if (IS_24XX(isp)) { + ISP_WRITE(isp, BIU2400_HCCR, + HCCR_2400_CMD_RELEASE); + } else { + ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); + } + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_ABOUT_FIRMWARE; + mbs.logval = MBLOGNONE; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { + isp->isp_romfw_rev[0] = mbs.param[1]; + isp->isp_romfw_rev[1] = mbs.param[2]; + isp->isp_romfw_rev[2] = mbs.param[3]; + } + } + isp->isp_touched = 1; + } + + ISP_DISABLE_INTS(isp); + + /* + * Pick an initial maxcmds value which will be used + * to allocate xflist pointer space. It may be changed + * later by the firmware. + */ + if (IS_24XX(isp)) { + isp->isp_maxcmds = 4096; + } else if (IS_2322(isp)) { + isp->isp_maxcmds = 2048; + } else if (IS_23XX(isp) || IS_2200(isp)) { + isp->isp_maxcmds = 1024; + } else { + isp->isp_maxcmds = 512; + } + + /* + * Set up DMA for the request and result queues. + * + * We do this now so we can use the request queue + * for a dma + */ + if (ISP_MBOXDMASETUP(isp) != 0) { + isp_prt(isp, ISP_LOGERR, "Cannot setup DMA"); + return; + } + + + /* + * Set up default request/response queue in-pointer/out-pointer + * register indices. + */ + if (IS_24XX(isp)) { + isp->isp_rqstinrp = BIU2400_REQINP; + isp->isp_rqstoutrp = BIU2400_REQOUTP; + isp->isp_respinrp = BIU2400_RSPINP; + isp->isp_respoutrp = BIU2400_RSPOUTP; + isp->isp_atioinrp = BIU2400_ATIO_RSPINP; + isp->isp_atiooutrp = BIU2400_ATIO_REQINP; + } else if (IS_23XX(isp)) { + isp->isp_rqstinrp = BIU_REQINP; + isp->isp_rqstoutrp = BIU_REQOUTP; + isp->isp_respinrp = BIU_RSPINP; + isp->isp_respoutrp = BIU_RSPOUTP; + } else { + isp->isp_rqstinrp = INMAILBOX4; + isp->isp_rqstoutrp = OUTMAILBOX4; + isp->isp_respinrp = OUTMAILBOX5; + isp->isp_respoutrp = INMAILBOX5; + } + + /* + * Put the board into PAUSE mode (so we can read the SXP registers + * or write FPM/FBM registers). + */ + if (IS_24XX(isp)) { + ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_HOST_INT); + ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT); + ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE); + } else { + ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE); + } + + if (IS_FC(isp)) { + switch (isp->isp_type) { + case ISP_HA_FC_2100: + btype = "2100"; + break; + case ISP_HA_FC_2200: + btype = "2200"; + break; + case ISP_HA_FC_2300: + btype = "2300"; + break; + case ISP_HA_FC_2312: + btype = "2312"; + break; + case ISP_HA_FC_2322: + btype = "2322"; + break; + case ISP_HA_FC_2400: + btype = "2422"; + break; + default: + break; + } + + if (!IS_24XX(isp)) { + /* + * While we're paused, reset the FPM module and FBM + * fifos. + */ + ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS); + ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET); + ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS); + ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL); + ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS); + } + } else if (IS_1240(isp)) { + sdparam *sdp; + + btype = "1240"; + isp->isp_clock = 60; + sdp = SDPARAM(isp, 0); + sdp->isp_ultramode = 1; + sdp = SDPARAM(isp, 1); + sdp->isp_ultramode = 1; + /* + * XXX: Should probably do some bus sensing. + */ + } else if (IS_ULTRA2(isp)) { + static const char m[] = "bus %d is in %s Mode"; + uint16_t l; + sdparam *sdp = SDPARAM(isp, 0); + + isp->isp_clock = 100; + + if (IS_1280(isp)) + btype = "1280"; + else if (IS_1080(isp)) + btype = "1080"; + else if (IS_10160(isp)) + btype = "10160"; + else if (IS_12160(isp)) + btype = "12160"; + else + btype = "<UNKLVD>"; + + l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK; + switch (l) { + case ISP1080_LVD_MODE: + sdp->isp_lvdmode = 1; + isp_prt(isp, ISP_LOGCONFIG, m, 0, "LVD"); + break; + case ISP1080_HVD_MODE: + sdp->isp_diffmode = 1; + isp_prt(isp, ISP_LOGCONFIG, m, 0, "Differential"); + break; + case ISP1080_SE_MODE: + sdp->isp_ultramode = 1; + isp_prt(isp, ISP_LOGCONFIG, m, 0, "Single-Ended"); + break; + default: + isp_prt(isp, ISP_LOGERR, + "unknown mode on bus %d (0x%x)", 0, l); + break; + } + + if (IS_DUALBUS(isp)) { + sdp = SDPARAM(isp, 1); + l = ISP_READ(isp, SXP_PINS_DIFF|SXP_BANK1_SELECT); + l &= ISP1080_MODE_MASK; + switch(l) { + case ISP1080_LVD_MODE: + sdp->isp_lvdmode = 1; + isp_prt(isp, ISP_LOGCONFIG, m, 1, "LVD"); + break; + case ISP1080_HVD_MODE: + sdp->isp_diffmode = 1; + isp_prt(isp, ISP_LOGCONFIG, + m, 1, "Differential"); + break; + case ISP1080_SE_MODE: + sdp->isp_ultramode = 1; + isp_prt(isp, ISP_LOGCONFIG, + m, 1, "Single-Ended"); + break; + default: + isp_prt(isp, ISP_LOGERR, + "unknown mode on bus %d (0x%x)", 1, l); + break; + } + } + } else { + sdparam *sdp = SDPARAM(isp, 0); + i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK; + switch (i) { + default: + isp_prt(isp, ISP_LOGALL, "Unknown Chip Type 0x%x", i); + /* FALLTHROUGH */ + case 1: + btype = "1020"; + isp->isp_type = ISP_HA_SCSI_1020; + isp->isp_clock = 40; + break; + case 2: + /* + * Some 1020A chips are Ultra Capable, but don't + * run the clock rate up for that unless told to + * do so by the Ultra Capable bits being set. + */ + btype = "1020A"; + isp->isp_type = ISP_HA_SCSI_1020A; + isp->isp_clock = 40; + break; + case 3: + btype = "1040"; + isp->isp_type = ISP_HA_SCSI_1040; + isp->isp_clock = 60; + break; + case 4: + btype = "1040A"; + isp->isp_type = ISP_HA_SCSI_1040A; + isp->isp_clock = 60; + break; + case 5: + btype = "1040B"; + isp->isp_type = ISP_HA_SCSI_1040B; + isp->isp_clock = 60; + break; + case 6: + btype = "1040C"; + isp->isp_type = ISP_HA_SCSI_1040C; + isp->isp_clock = 60; + break; + } + /* + * Now, while we're at it, gather info about ultra + * and/or differential mode. + */ + if (ISP_READ(isp, SXP_PINS_DIFF) & SXP_PINS_DIFF_MODE) { + isp_prt(isp, ISP_LOGCONFIG, "Differential Mode"); + sdp->isp_diffmode = 1; + } else { + sdp->isp_diffmode = 0; + } + i = ISP_READ(isp, RISC_PSR); + if (isp->isp_bustype == ISP_BT_SBUS) { + i &= RISC_PSR_SBUS_ULTRA; + } else { + i &= RISC_PSR_PCI_ULTRA; + } + if (i != 0) { + isp_prt(isp, ISP_LOGCONFIG, "Ultra Mode Capable"); + sdp->isp_ultramode = 1; + /* + * If we're in Ultra Mode, we have to be 60MHz clock- + * even for the SBus version. + */ + isp->isp_clock = 60; + } else { + sdp->isp_ultramode = 0; + /* + * Clock is known. Gronk. + */ + } + + /* + * Machine dependent clock (if set) overrides + * our generic determinations. + */ + if (isp->isp_mdvec->dv_clock) { + if (isp->isp_mdvec->dv_clock < isp->isp_clock) { + isp->isp_clock = isp->isp_mdvec->dv_clock; + } + } + + } + + /* + * Clear instrumentation + */ + isp->isp_intcnt = isp->isp_intbogus = 0; + + /* + * Do MD specific pre initialization + */ + ISP_RESET0(isp); + + /* + * Hit the chip over the head with hammer, + * and give the ISP a chance to recover. + */ + + if (IS_SCSI(isp)) { + ISP_WRITE(isp, BIU_ICR, BIU_ICR_SOFT_RESET); + /* + * A slight delay... + */ + USEC_DELAY(100); + + /* + * Clear data && control DMA engines. + */ + ISP_WRITE(isp, CDMA_CONTROL, + DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT); + ISP_WRITE(isp, DDMA_CONTROL, + DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT); + + + } else if (IS_24XX(isp)) { + /* + * Stop DMA and wait for it to stop. + */ + ISP_WRITE(isp, BIU2400_CSR, BIU2400_DMA_STOP|(3 << 4)); + for (val = loops = 0; loops < 30000; loops++) { + USEC_DELAY(10); + val = ISP_READ(isp, BIU2400_CSR); + if ((val & BIU2400_DMA_ACTIVE) == 0) { + break; + } + } + if (val & BIU2400_DMA_ACTIVE) { + ISP_RESET0(isp); + isp_prt(isp, ISP_LOGERR, "DMA Failed to Stop on Reset"); + return; + } + /* + * Hold it in SOFT_RESET and STOP state for 100us. + */ + ISP_WRITE(isp, BIU2400_CSR, + BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4)); + USEC_DELAY(100); + for (loops = 0; loops < 10000; loops++) { + USEC_DELAY(5); + val = ISP_READ(isp, OUTMAILBOX0); + } + for (val = loops = 0; loops < 500000; loops ++) { + val = ISP_READ(isp, BIU2400_CSR); + if ((val & BIU2400_SOFT_RESET) == 0) { + break; + } + } + if (val & BIU2400_SOFT_RESET) { + ISP_RESET0(isp); + isp_prt(isp, ISP_LOGERR, "Failed to come out of reset"); + return; + } + } else { + ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET); + /* + * A slight delay... + */ + USEC_DELAY(100); + + /* + * Clear data && control DMA engines. + */ + ISP_WRITE(isp, CDMA2100_CONTROL, + DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT); + ISP_WRITE(isp, TDMA2100_CONTROL, + DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT); + ISP_WRITE(isp, RDMA2100_CONTROL, + DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT); + } + + /* + * Wait for ISP to be ready to go... + */ + loops = MBOX_DELAY_COUNT; + for (;;) { + if (IS_SCSI(isp)) { + if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET)) { + break; + } + } else if (IS_24XX(isp)) { + if (ISP_READ(isp, OUTMAILBOX0) == 0) { + break; + } + } else { + if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET)) + break; + } + USEC_DELAY(100); + if (--loops < 0) { + ISP_DUMPREGS(isp, "chip reset timed out"); + ISP_RESET0(isp); + return; + } + } + + /* + * After we've fired this chip up, zero out the conf1 register + * for SCSI adapters and other settings for the 2100. + */ + + if (IS_SCSI(isp)) { + ISP_WRITE(isp, BIU_CONF1, 0); + } else if (!IS_24XX(isp)) { + ISP_WRITE(isp, BIU2100_CSR, 0); + } + + /* + * Reset RISC Processor + */ + if (IS_24XX(isp)) { + ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET); + ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RELEASE); + ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RESET); + } else { + ISP_WRITE(isp, HCCR, HCCR_CMD_RESET); + USEC_DELAY(100); + ISP_WRITE(isp, BIU_SEMA, 0); + } + + + /* + * Post-RISC Reset stuff. + */ + if (IS_24XX(isp)) { + for (val = loops = 0; loops < 5000000; loops++) { + USEC_DELAY(5); + val = ISP_READ(isp, OUTMAILBOX0); + if (val == 0) { + break; + } + } + if (val != 0) { + ISP_RESET0(isp); + isp_prt(isp, ISP_LOGERR, "reset didn't clear"); + return; + } + } else if (IS_SCSI(isp)) { + uint16_t tmp = isp->isp_mdvec->dv_conf1; + /* + * Busted FIFO. Turn off all but burst enables. + */ + if (isp->isp_type == ISP_HA_SCSI_1040A) { + tmp &= BIU_BURST_ENABLE; + } + ISP_SETBITS(isp, BIU_CONF1, tmp); + if (tmp & BIU_BURST_ENABLE) { + ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST); + ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST); + } + if (SDPARAM(isp, 0)->isp_ptisp) { + if (SDPARAM(isp, 0)->isp_ultramode) { + while (ISP_READ(isp, RISC_MTR) != 0x1313) { + ISP_WRITE(isp, RISC_MTR, 0x1313); + ISP_WRITE(isp, HCCR, HCCR_CMD_STEP); + } + } else { + ISP_WRITE(isp, RISC_MTR, 0x1212); + } + /* + * PTI specific register + */ + ISP_WRITE(isp, RISC_EMB, DUAL_BANK); + } else { + ISP_WRITE(isp, RISC_MTR, 0x1212); + } + ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); + } else { + ISP_WRITE(isp, RISC_MTR2100, 0x1212); + if (IS_2200(isp) || IS_23XX(isp)) { + ISP_WRITE(isp, HCCR, HCCR_2X00_DISABLE_PARITY_PAUSE); + } + ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); + } + + ISP_WRITE(isp, isp->isp_rqstinrp, 0); + ISP_WRITE(isp, isp->isp_rqstoutrp, 0); + ISP_WRITE(isp, isp->isp_respinrp, 0); + ISP_WRITE(isp, isp->isp_respoutrp, 0); + + + /* + * Do MD specific post initialization + */ + ISP_RESET1(isp); + + /* + * Wait for everything to finish firing up. + * + * Avoid doing this on the 2312 because you can generate a PCI + * parity error (chip breakage). + */ + if (IS_2312(isp)) { + USEC_DELAY(100); + } else { + loops = MBOX_DELAY_COUNT; + while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) { + USEC_DELAY(100); + if (--loops < 0) { + ISP_RESET0(isp); + isp_prt(isp, ISP_LOGERR, + "MBOX_BUSY never cleared on reset"); + return; + } + } + } + + /* + * Up until this point we've done everything by just reading or + * setting registers. From this point on we rely on at least *some* + * kind of firmware running in the card. + */ + + /* + * Do some sanity checking. + */ + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_NO_OP; + mbs.logval = MBLOGALL; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + ISP_RESET0(isp); + return; + } + + if (IS_SCSI(isp) || IS_24XX(isp)) { + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_MAILBOX_REG_TEST; + mbs.param[1] = 0xdead; + mbs.param[2] = 0xbeef; + mbs.param[3] = 0xffff; + mbs.param[4] = 0x1111; + mbs.param[5] = 0xa5a5; + mbs.param[6] = 0x0000; + mbs.param[7] = 0x0000; + mbs.logval = MBLOGALL; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + ISP_RESET0(isp); + return; + } + if (mbs.param[1] != 0xdead || mbs.param[2] != 0xbeef || + mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 || + mbs.param[5] != 0xa5a5) { + ISP_RESET0(isp); + isp_prt(isp, ISP_LOGERR, + "Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)", + mbs.param[1], mbs.param[2], mbs.param[3], + mbs.param[4], mbs.param[5]); + return; + } + + } + + /* + * Download new Firmware, unless requested not to do so. + * This is made slightly trickier in some cases where the + * firmware of the ROM revision is newer than the revision + * compiled into the driver. So, where we used to compare + * versions of our f/w and the ROM f/w, now we just see + * whether we have f/w at all and whether a config flag + * has disabled our download. + */ + if ((isp->isp_mdvec->dv_ispfw == NULL) || + (isp->isp_confopts & ISP_CFG_NORELOAD)) { + dodnld = 0; + } + + if (IS_24XX(isp)) { + code_org = ISP_CODE_ORG_2400; + } else if (IS_23XX(isp)) { + code_org = ISP_CODE_ORG_2300; + } else { + code_org = ISP_CODE_ORG; + } + + if (dodnld && IS_24XX(isp)) { + const uint32_t *ptr = isp->isp_mdvec->dv_ispfw; + + /* + * NB: Whatever you do do, do *not* issue the VERIFY FIRMWARE + * NB: command to the 2400 while loading new firmware. This + * NB: causes the new f/w to start and immediately crash back + * NB: to the ROM. + */ + + /* + * Keep loading until we run out of f/w. + */ + code_org = ptr[2]; /* 1st load address is our start addr */ + + for (;;) { + uint32_t la, wi, wl; + + isp_prt(isp, ISP_LOGDEBUG0, + "load 0x%x words of code at load address 0x%x", + ptr[3], ptr[2]); + + wi = 0; + la = ptr[2]; + wl = ptr[3]; + + while (wi < ptr[3]) { + uint32_t *cp; + uint32_t nw; + + nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 2; + if (nw > wl) { + nw = wl; + } + cp = isp->isp_rquest; + for (i = 0; i < nw; i++) { + cp[i] = ptr[wi++]; + wl--; + } + MEMORYBARRIER(isp, SYNC_REQUEST, + 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp))); + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_LOAD_RISC_RAM; + mbs.param[1] = la; + mbs.param[2] = DMA_WD1(isp->isp_rquest_dma); + mbs.param[3] = DMA_WD0(isp->isp_rquest_dma); + mbs.param[4] = nw >> 16; + mbs.param[5] = nw; + mbs.param[6] = DMA_WD3(isp->isp_rquest_dma); + mbs.param[7] = DMA_WD2(isp->isp_rquest_dma); + mbs.param[8] = la >> 16; + mbs.logval = MBLOGALL; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + isp_prt(isp, ISP_LOGERR, + "F/W Risc Ram Load Failed"); + ISP_RESET0(isp); + return; + } + la += nw; + } + + if (ptr[1] == 0) { + break; + } + ptr += ptr[3]; + } + isp->isp_loaded_fw = 1; + } else if (dodnld && IS_23XX(isp)) { + const uint16_t *ptr = isp->isp_mdvec->dv_ispfw; + uint16_t wi, wl, segno; + uint32_t la; + + la = code_org; + segno = 0; + + for (;;) { + uint32_t nxtaddr; + + isp_prt(isp, ISP_LOGDEBUG0, + "load 0x%x words of code at load address 0x%x", + ptr[3], la); + + wi = 0; + wl = ptr[3]; + + while (wi < ptr[3]) { + uint16_t *cp; + uint32_t nw; + + nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 1; + if (nw > wl) { + nw = wl; + } + if (nw > (1 << 15)) { + nw = 1 << 15; + } + cp = isp->isp_rquest; + for (i = 0; i < nw; i++) { + cp[i] = ptr[wi++]; + wl--; + } + MEMORYBARRIER(isp, SYNC_REQUEST, + 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp))); + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_LOAD_RISC_RAM; + mbs.param[1] = la; + mbs.param[2] = DMA_WD1(isp->isp_rquest_dma); + mbs.param[3] = DMA_WD0(isp->isp_rquest_dma); + mbs.param[4] = nw; + mbs.param[6] = DMA_WD3(isp->isp_rquest_dma); + mbs.param[7] = DMA_WD2(isp->isp_rquest_dma); + mbs.param[8] = la >> 16; + mbs.logval = MBLOGALL; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + isp_prt(isp, ISP_LOGERR, + "F/W Risc Ram Load Failed"); + ISP_RESET0(isp); + return; + } + la += nw; + } + + if (!IS_2322(isp)) { + /* + * Verify that it downloaded correctly. + */ + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_VERIFY_CHECKSUM; + mbs.param[1] = code_org; + mbs.logval = MBLOGNONE; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + isp_prt(isp, ISP_LOGERR, dcrc); + ISP_RESET0(isp); + return; + } + break; + } + + if (++segno == 3) { + break; + } + + /* + * If we're a 2322, the firmware actually comes in + * three chunks. We loaded the first at the code_org + * address. The other two chunks, which follow right + * after each other in memory here, get loaded at + * addresses specfied at offset 0x9..0xB. + */ + + nxtaddr = ptr[3]; + ptr = &ptr[nxtaddr]; + la = ptr[5] | ((ptr[4] & 0x3f) << 16); + } + isp->isp_loaded_fw = 1; + } else if (dodnld) { + union { + const uint16_t *cp; + uint16_t *np; + } u; + u.cp = isp->isp_mdvec->dv_ispfw; + isp->isp_mbxworkp = &u.np[1]; + isp->isp_mbxwrk0 = u.np[3] - 1; + isp->isp_mbxwrk1 = code_org + 1; + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_WRITE_RAM_WORD; + mbs.param[1] = code_org; + mbs.param[2] = u.np[0]; + mbs.logval = MBLOGNONE; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + isp_prt(isp, ISP_LOGERR, + "F/W download failed at word %d", + isp->isp_mbxwrk1 - code_org); + ISP_RESET0(isp); + return; + } + /* + * Verify that it downloaded correctly. + */ + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_VERIFY_CHECKSUM; + mbs.param[1] = code_org; + mbs.logval = MBLOGNONE; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + isp_prt(isp, ISP_LOGERR, dcrc); + ISP_RESET0(isp); + return; + } + isp->isp_loaded_fw = 1; + } else { + isp->isp_loaded_fw = 0; + isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download"); + } + + /* + * Now start it rolling. + * + * If we didn't actually download f/w, + * we still need to (re)start it. + */ + + + MEMZERO(&mbs, sizeof (mbs)); + mbs.timeout = 1000000; + mbs.param[0] = MBOX_EXEC_FIRMWARE; + if (IS_24XX(isp)) { + mbs.param[1] = code_org >> 16; + mbs.param[2] = code_org; + if (isp->isp_loaded_fw) { + mbs.param[3] = 0; + } else { + mbs.param[3] = 1; + } + } else if (IS_2322(isp)) { + mbs.param[1] = code_org; + if (isp->isp_loaded_fw) { + mbs.param[2] = 0; + } else { + mbs.param[2] = 1; + } + } else { + mbs.param[1] = code_org; + } + + mbs.logval = MBLOGALL; + isp_mboxcmd(isp, &mbs); + if (IS_2322(isp) || IS_24XX(isp)) { + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + ISP_RESET0(isp); + return; + } + } + + /* + * Give it a chance to finish starting up. + */ + USEC_DELAY(250000); + + if (IS_SCSI(isp)) { + /* + * Set CLOCK RATE, but only if asked to. + */ + if (isp->isp_clock) { + mbs.param[0] = MBOX_SET_CLOCK_RATE; + mbs.param[1] = isp->isp_clock; + mbs.logval = MBLOGNONE; + isp_mboxcmd(isp, &mbs); + /* we will try not to care if this fails */ + } + } + + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_ABOUT_FIRMWARE; + mbs.logval = MBLOGALL; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + ISP_RESET0(isp); + return; + } + + if (IS_24XX(isp) && mbs.param[1] == 0xdead) { + isp_prt(isp, ISP_LOGERR, "f/w didn't *really* start"); + ISP_RESET0(isp); + return; + } + + /* + * The SBus firmware that we are using apparently does not return + * major, minor, micro revisions in the mailbox registers, which + * is really, really, annoying. + */ + if (ISP_SBUS_SUPPORTED && isp->isp_bustype == ISP_BT_SBUS) { + if (dodnld) { +#ifdef ISP_TARGET_MODE + isp->isp_fwrev[0] = 7; + isp->isp_fwrev[1] = 55; +#else + isp->isp_fwrev[0] = 1; + isp->isp_fwrev[1] = 37; +#endif + isp->isp_fwrev[2] = 0; + } + } else { + isp->isp_fwrev[0] = mbs.param[1]; + isp->isp_fwrev[1] = mbs.param[2]; + isp->isp_fwrev[2] = mbs.param[3]; + } + + isp_prt(isp, ISP_LOGALL, + "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d", + btype, isp->isp_revision, dodnld? "loaded" : "resident", + isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]); + + if (IS_FC(isp)) { + /* + * We do not believe firmware attributes for 2100 code less + * than 1.17.0, unless it's the firmware we specifically + * are loading. + * + * Note that all 22XX and later f/w is greater than 1.X.0. + */ + if ((ISP_FW_OLDER_THAN(isp, 1, 17, 1))) { +#ifdef USE_SMALLER_2100_FIRMWARE + isp->isp_fwattr = ISP_FW_ATTR_SCCLUN; +#else + isp->isp_fwattr = 0; +#endif + } else { + isp->isp_fwattr = mbs.param[6]; + isp_prt(isp, ISP_LOGDEBUG0, + "Firmware Attributes = 0x%x", mbs.param[6]); + } + } else { +#ifndef ISP_TARGET_MODE + isp->isp_fwattr = ISP_FW_ATTR_TMODE; +#else + isp->isp_fwattr = 0; +#endif + } + + if (isp->isp_romfw_rev[0] || isp->isp_romfw_rev[1] || + isp->isp_romfw_rev[2]) { + isp_prt(isp, ISP_LOGCONFIG, "Last F/W revision was %d.%d.%d", + isp->isp_romfw_rev[0], isp->isp_romfw_rev[1], + isp->isp_romfw_rev[2]); + } + + if (!IS_24XX(isp)) { + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_GET_FIRMWARE_STATUS; + mbs.logval = MBLOGALL; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + ISP_RESET0(isp); + return; + } + if (isp->isp_maxcmds >= mbs.param[2]) { + isp->isp_maxcmds = mbs.param[2]; + } + } + isp_prt(isp, ISP_LOGCONFIG, + "%d max I/O command limit set", isp->isp_maxcmds); + for (i = 0; i < isp->isp_nchan; i++) { + isp_fw_state(isp, i); + } + + isp->isp_state = ISP_RESETSTATE; + + /* + * Okay- now that we have new firmware running, we now (re)set our + * notion of how many luns we support. This is somewhat tricky because + * if we haven't loaded firmware, we sometimes do not have an easy way + * of knowing how many luns we support. + * + * Expanded lun firmware gives you 32 luns for SCSI cards and + * 16384 luns for Fibre Channel cards. + * + * It turns out that even for QLogic 2100s with ROM 1.10 and above + * we do get a firmware attributes word returned in mailbox register 6. + * + * Because the lun is in a different position in the Request Queue + * Entry structure for Fibre Channel with expanded lun firmware, we + * can only support one lun (lun zero) when we don't know what kind + * of firmware we're running. + */ + if (IS_SCSI(isp)) { + if (dodnld) { + if (IS_ULTRA2(isp) || IS_ULTRA3(isp)) { + isp->isp_maxluns = 32; + } else { + isp->isp_maxluns = 8; + } + } else { + isp->isp_maxluns = 8; + } + } else { + if (ISP_CAP_SCCFW(isp)) { + isp->isp_maxluns = 16384; + } else { + isp->isp_maxluns = 16; + } + } + /* + * Must do this first to get defaults established. + */ + if (IS_SCSI(isp)) { + for (i = 0; i < isp->isp_nchan; i++) { + isp_setdfltparm(isp, i); + } + } else { + for (i = 0; i < isp->isp_nchan; i++) { + isp_setdfltfcparm(isp, i); + } + } + +} + +/* + * Initialize Parameters of Hardware to a known state. + * + * Locks are held before coming here. + */ + +void +isp_init(ispsoftc_t *isp) +{ + if (IS_FC(isp)) { + int i; + for (i = 0; i < isp->isp_nchan; i++) { + ISP_MARK_PORTDB(isp, i, 0); + FCPARAM(isp, i)->isp_fwstate = FW_CONFIG_WAIT; + FCPARAM(isp, i)->isp_loopstate = LOOP_NIL; + if (isp->isp_role != ISP_ROLE_NONE) { + if (IS_24XX(isp)) { + isp_fibre_init_2400(isp, i); + } else { + isp_fibre_init(isp, i); + } + } + } + } else { + isp_scsi_init(isp); + } +} + +static void +isp_scsi_init(ispsoftc_t *isp) +{ + sdparam *sdp_chan0, *sdp_chan1; + mbreg_t mbs; + + sdp_chan0 = SDPARAM(isp, 0); + sdp_chan1 = sdp_chan0; + if (IS_DUALBUS(isp)) { + sdp_chan1 = SDPARAM(isp, 1); + } + + /* + * If we have no role (neither target nor initiator), return. + */ + if (isp->isp_role == ISP_ROLE_NONE) { + return; + } + + /* First do overall per-card settings. */ + + /* + * If we have fast memory timing enabled, turn it on. + */ + if (sdp_chan0->isp_fast_mttr) { + ISP_WRITE(isp, RISC_MTR, 0x1313); + } + + /* + * Set Retry Delay and Count. + * You set both channels at the same time. + */ + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_SET_RETRY_COUNT; + mbs.param[1] = sdp_chan0->isp_retry_count; + mbs.param[2] = sdp_chan0->isp_retry_delay; + mbs.param[6] = sdp_chan1->isp_retry_count; + mbs.param[7] = sdp_chan1->isp_retry_delay; + mbs.logval = MBLOGALL; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + return; + } + + /* + * Set ASYNC DATA SETUP time. This is very important. + */ + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME; + mbs.param[1] = sdp_chan0->isp_async_data_setup; + mbs.param[2] = sdp_chan1->isp_async_data_setup; + mbs.logval = MBLOGALL; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + return; + } + + /* + * Set ACTIVE Negation State. + */ + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_SET_ACT_NEG_STATE; + mbs.param[1] = + (sdp_chan0->isp_req_ack_active_neg << 4) | + (sdp_chan0->isp_data_line_active_neg << 5); + mbs.param[2] = + (sdp_chan1->isp_req_ack_active_neg << 4) | + (sdp_chan1->isp_data_line_active_neg << 5); + mbs.logval = MBLOGNONE; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + isp_prt(isp, ISP_LOGERR, + "failed to set active negation state (%d,%d), (%d,%d)", + sdp_chan0->isp_req_ack_active_neg, + sdp_chan0->isp_data_line_active_neg, + sdp_chan1->isp_req_ack_active_neg, + sdp_chan1->isp_data_line_active_neg); + /* + * But don't return. + */ + } + + /* + * Set the Tag Aging limit + */ + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_SET_TAG_AGE_LIMIT; + mbs.param[1] = sdp_chan0->isp_tag_aging; + mbs.param[2] = sdp_chan1->isp_tag_aging; + mbs.logval = MBLOGALL; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + isp_prt(isp, ISP_LOGERR, "failed to set tag age limit (%d,%d)", + sdp_chan0->isp_tag_aging, sdp_chan1->isp_tag_aging); + return; + } + + /* + * Set selection timeout. + */ + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_SET_SELECT_TIMEOUT; + mbs.param[1] = sdp_chan0->isp_selection_timeout; + mbs.param[2] = sdp_chan1->isp_selection_timeout; + mbs.logval = MBLOGALL; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + return; + } + + /* now do per-channel settings */ + isp_scsi_channel_init(isp, 0); + if (IS_DUALBUS(isp)) + isp_scsi_channel_init(isp, 1); + + /* + * Now enable request/response queues + */ + + if (IS_ULTRA2(isp) || IS_1240(isp)) { + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_INIT_RES_QUEUE_A64; + mbs.param[1] = RESULT_QUEUE_LEN(isp); + mbs.param[2] = DMA_WD1(isp->isp_result_dma); + mbs.param[3] = DMA_WD0(isp->isp_result_dma); + mbs.param[4] = 0; + mbs.param[6] = DMA_WD3(isp->isp_result_dma); + mbs.param[7] = DMA_WD2(isp->isp_result_dma); + mbs.logval = MBLOGALL; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + return; + } + isp->isp_residx = mbs.param[5]; + + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_INIT_REQ_QUEUE_A64; + mbs.param[1] = RQUEST_QUEUE_LEN(isp); + mbs.param[2] = DMA_WD1(isp->isp_rquest_dma); + mbs.param[3] = DMA_WD0(isp->isp_rquest_dma); + mbs.param[5] = 0; + mbs.param[6] = DMA_WD3(isp->isp_result_dma); + mbs.param[7] = DMA_WD2(isp->isp_result_dma); + mbs.logval = MBLOGALL; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + return; + } + isp->isp_reqidx = isp->isp_reqodx = mbs.param[4]; + } else { + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_INIT_RES_QUEUE; + mbs.param[1] = RESULT_QUEUE_LEN(isp); + mbs.param[2] = DMA_WD1(isp->isp_result_dma); + mbs.param[3] = DMA_WD0(isp->isp_result_dma); + mbs.param[4] = 0; + mbs.logval = MBLOGALL; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + return; + } + isp->isp_residx = mbs.param[5]; + + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_INIT_REQ_QUEUE; + mbs.param[1] = RQUEST_QUEUE_LEN(isp); + mbs.param[2] = DMA_WD1(isp->isp_rquest_dma); + mbs.param[3] = DMA_WD0(isp->isp_rquest_dma); + mbs.param[5] = 0; + mbs.logval = MBLOGALL; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + return; + } + isp->isp_reqidx = isp->isp_reqodx = mbs.param[4]; + } + + /* + * Turn on Fast Posting, LVD transitions + * + * Ultra2 F/W always has had fast posting (and LVD transitions) + * + * Ultra and older (i.e., SBus) cards may not. It's just safer + * to assume not for them. + */ + + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_SET_FW_FEATURES; + mbs.param[1] = 0; + if (IS_ULTRA2(isp)) + mbs.param[1] |= FW_FEATURE_LVD_NOTIFY; +#ifndef ISP_NO_RIO + if (IS_ULTRA2(isp) || IS_1240(isp)) + mbs.param[1] |= FW_FEATURE_RIO_16BIT; +#else + if (IS_ULTRA2(isp) || IS_1240(isp)) + mbs.param[1] |= FW_FEATURE_FAST_POST; +#endif + if (mbs.param[1] != 0) { + uint16_t sfeat = mbs.param[1]; + mbs.logval = MBLOGALL; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { + isp_prt(isp, ISP_LOGINFO, + "Enabled FW features (0x%x)", sfeat); + } + } + + /* + * Let the outer layers decide whether to issue a SCSI bus reset. + */ + isp->isp_state = ISP_INITSTATE; +} + +static void +isp_scsi_channel_init(ispsoftc_t *isp, int channel) +{ + sdparam *sdp; + mbreg_t mbs; + int tgt; + + sdp = SDPARAM(isp, channel); + + /* + * Set (possibly new) Initiator ID. + */ + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_SET_INIT_SCSI_ID; + mbs.param[1] = (channel << 7) | sdp->isp_initiator_id; + mbs.logval = MBLOGALL; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + return; + } + isp_prt(isp, ISP_LOGINFO, "Initiator ID is %d on Channel %d", + sdp->isp_initiator_id, channel); + + + /* + * Set current per-target parameters to an initial safe minimum. + */ + for (tgt = 0; tgt < MAX_TARGETS; tgt++) { + int lun; + uint16_t sdf; + + if (sdp->isp_devparam[tgt].dev_enable == 0) { + continue; + } +#ifndef ISP_TARGET_MODE + sdf = sdp->isp_devparam[tgt].goal_flags; + sdf &= DPARM_SAFE_DFLT; + /* + * It is not quite clear when this changed over so that + * we could force narrow and async for 1000/1020 cards, + * but assume that this is only the case for loaded + * firmware. + */ + if (isp->isp_loaded_fw) { + sdf |= DPARM_NARROW | DPARM_ASYNC; + } +#else + /* + * The !$*!)$!$)* f/w uses the same index into some + * internal table to decide how to respond to negotiations, + * so if we've said "let's be safe" for ID X, and ID X + * selects *us*, the negotiations will back to 'safe' + * (as in narrow/async). What the f/w *should* do is + * use the initiator id settings to decide how to respond. + */ + sdp->isp_devparam[tgt].goal_flags = sdf = DPARM_DEFAULT; +#endif + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_SET_TARGET_PARAMS; + mbs.param[1] = (channel << 15) | (tgt << 8); + mbs.param[2] = sdf; + if ((sdf & DPARM_SYNC) == 0) { + mbs.param[3] = 0; + } else { + mbs.param[3] = + (sdp->isp_devparam[tgt].goal_offset << 8) | + (sdp->isp_devparam[tgt].goal_period); + } + isp_prt(isp, ISP_LOGDEBUG0, + "Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x", + channel, tgt, mbs.param[2], mbs.param[3] >> 8, + mbs.param[3] & 0xff); + mbs.logval = MBLOGNONE; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + sdf = DPARM_SAFE_DFLT; + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_SET_TARGET_PARAMS; + mbs.param[1] = (tgt << 8) | (channel << 15); + mbs.param[2] = sdf; + mbs.param[3] = 0; + mbs.logval = MBLOGALL; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + continue; + } + } + + /* + * We don't update any information directly from the f/w + * because we need to run at least one command to cause a + * new state to be latched up. So, we just assume that we + * converge to the values we just had set. + * + * Ensure that we don't believe tagged queuing is enabled yet. + * It turns out that sometimes the ISP just ignores our + * attempts to set parameters for devices that it hasn't + * seen yet. + */ + sdp->isp_devparam[tgt].actv_flags = sdf & ~DPARM_TQING; + for (lun = 0; lun < (int) isp->isp_maxluns; lun++) { + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_SET_DEV_QUEUE_PARAMS; + mbs.param[1] = (channel << 15) | (tgt << 8) | lun; + mbs.param[2] = sdp->isp_max_queue_depth; + mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle; + mbs.logval = MBLOGALL; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + break; + } + } + } + for (tgt = 0; tgt < MAX_TARGETS; tgt++) { + if (sdp->isp_devparam[tgt].dev_refresh) { + isp->isp_sendmarker |= (1 << channel); + isp->isp_update |= (1 << channel); + break; + } + } +} + +/* + * Fibre Channel specific initialization. + */ +static void +isp_fibre_init(ispsoftc_t *isp, int chan) +{ + fcparam *fcp; + isp_icb_t local, *icbp = &local; + mbreg_t mbs; + int ownloopid; + uint64_t nwwn, pwwn; + + fcp = FCPARAM(isp, chan); + + MEMZERO(icbp, sizeof (*icbp)); + icbp->icb_version = ICB_VERSION1; + icbp->icb_fwoptions = fcp->isp_fwoptions; + + /* + * Firmware Options are either retrieved from NVRAM or + * are patched elsewhere. We check them for sanity here + * and make changes based on board revision, but otherwise + * let others decide policy. + */ + + /* + * If this is a 2100 < revision 5, we have to turn off FAIRNESS. + */ + if (IS_2100(isp) && isp->isp_revision < 5) { + icbp->icb_fwoptions &= ~ICBOPT_FAIRNESS; + } + + /* + * We have to use FULL LOGIN even though it resets the loop too much + * because otherwise port database entries don't get updated after + * a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0. + */ + if (!ISP_FW_NEWER_THAN(isp, 1, 17, 0)) { + icbp->icb_fwoptions |= ICBOPT_FULL_LOGIN; + } + + /* + * Insist on Port Database Update Async notifications + */ + icbp->icb_fwoptions |= ICBOPT_PDBCHANGE_AE; + + /* + * Make sure that target role reflects into fwoptions. + */ + if (isp->isp_role & ISP_ROLE_TARGET) { + icbp->icb_fwoptions |= ICBOPT_TGT_ENABLE; + } else { + icbp->icb_fwoptions &= ~ICBOPT_TGT_ENABLE; + } + + if (isp->isp_role & ISP_ROLE_INITIATOR) { + icbp->icb_fwoptions &= ~ICBOPT_INI_DISABLE; + } else { + icbp->icb_fwoptions |= ICBOPT_INI_DISABLE; + } + + icbp->icb_maxfrmlen = fcp->isp_maxfrmlen; + if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || + icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) { + isp_prt(isp, ISP_LOGERR, + "bad frame length (%d) from NVRAM- using %d", + fcp->isp_maxfrmlen, ICB_DFLT_FRMLEN); + icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN; + } + icbp->icb_maxalloc = fcp->isp_maxalloc; + if (icbp->icb_maxalloc < 1) { + isp_prt(isp, ISP_LOGERR, + "bad maximum allocation (%d)- using 16", fcp->isp_maxalloc); + icbp->icb_maxalloc = 16; + } + icbp->icb_execthrottle = fcp->isp_execthrottle; + if (icbp->icb_execthrottle < 1) { + isp_prt(isp, ISP_LOGERR, + "bad execution throttle of %d- using 16", + fcp->isp_execthrottle); + icbp->icb_execthrottle = ICB_DFLT_THROTTLE; + } + icbp->icb_retry_delay = fcp->isp_retry_delay; + icbp->icb_retry_count = fcp->isp_retry_count; + icbp->icb_hardaddr = fcp->isp_loopid; + ownloopid = (isp->isp_confopts & ISP_CFG_OWNLOOPID) != 0; + if (icbp->icb_hardaddr > 125) { + icbp->icb_hardaddr = 0; + ownloopid = 0; + } + + /* + * Our life seems so much better with 2200s and later with + * the latest f/w if we set Hard Address. + */ + if (ownloopid || ISP_FW_NEWER_THAN(isp, 2, 2, 5)) { + icbp->icb_fwoptions |= ICBOPT_HARD_ADDRESS; + } + + /* + * Right now we just set extended options to prefer point-to-point + * over loop based upon some soft config options. + * + * NB: for the 2300, ICBOPT_EXTENDED is required. + */ + if (IS_2200(isp) || IS_23XX(isp)) { + icbp->icb_fwoptions |= ICBOPT_EXTENDED; + /* + * Prefer or force Point-To-Point instead Loop? + */ + switch(isp->isp_confopts & ISP_CFG_PORT_PREF) { + case ISP_CFG_NPORT: + icbp->icb_xfwoptions |= ICBXOPT_PTP_2_LOOP; + break; + case ISP_CFG_NPORT_ONLY: + icbp->icb_xfwoptions |= ICBXOPT_PTP_ONLY; + break; + case ISP_CFG_LPORT_ONLY: + icbp->icb_xfwoptions |= ICBXOPT_LOOP_ONLY; + break; + default: + icbp->icb_xfwoptions |= ICBXOPT_LOOP_2_PTP; + break; + } + if (IS_2200(isp)) { + if (ISP_FW_NEWER_THAN(isp, 1, 17, 0)) { + icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT; + icbp->icb_racctimer = 4; + icbp->icb_idelaytimer = 8; + } + icbp->icb_fwoptions |= ICBOPT_FAST_POST; + } else { + /* + * QLogic recommends that FAST Posting be turned + * off for 23XX cards and instead allow the HBA + * to write response queue entries and interrupt + * after a delay (ZIO). + */ + icbp->icb_fwoptions &= ~ICBOPT_FAST_POST; + if ((fcp->isp_xfwoptions & ICBXOPT_TIMER_MASK) == + ICBXOPT_ZIO) { + icbp->icb_xfwoptions |= ICBXOPT_ZIO; + icbp->icb_idelaytimer = 10; + } + if (isp->isp_confopts & ISP_CFG_ONEGB) { + icbp->icb_zfwoptions |= ICBZOPT_RATE_ONEGB; + } else if (isp->isp_confopts & ISP_CFG_TWOGB) { + icbp->icb_zfwoptions |= ICBZOPT_RATE_TWOGB; + } else { + icbp->icb_zfwoptions |= ICBZOPT_RATE_AUTO; + } + if (fcp->isp_zfwoptions & ICBZOPT_50_OHM) { + icbp->icb_zfwoptions |= ICBZOPT_50_OHM; + } + } + } + + + /* + * For 22XX > 2.1.26 && 23XX, set some options. + * XXX: Probably okay for newer 2100 f/w too. + */ + if (ISP_FW_NEWER_THAN(isp, 2, 26, 0)) { + /* + * Turn on LIP F8 async event (1) + * Turn on generate AE 8013 on all LIP Resets (2) + * Disable LIP F7 switching (8) + */ + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_SET_FIRMWARE_OPTIONS; + mbs.param[1] = 0xb; + mbs.param[2] = 0; + mbs.param[3] = 0; + mbs.logval = MBLOGALL; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + return; + } + } + icbp->icb_logintime = ICB_LOGIN_TOV; + icbp->icb_lunetimeout = ICB_LUN_ENABLE_TOV; + + nwwn = ISP_NODEWWN(isp); + pwwn = ISP_PORTWWN(isp); + if (nwwn && pwwn) { + icbp->icb_fwoptions |= ICBOPT_BOTH_WWNS; + MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, nwwn); + MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn); + isp_prt(isp, ISP_LOGDEBUG1, + "Setting ICB Node 0x%08x%08x Port 0x%08x%08x", + ((uint32_t) (nwwn >> 32)), + ((uint32_t) (nwwn & 0xffffffff)), + ((uint32_t) (pwwn >> 32)), + ((uint32_t) (pwwn & 0xffffffff))); + } else if (pwwn) { + icbp->icb_fwoptions &= ~ICBOPT_BOTH_WWNS; + MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn); + isp_prt(isp, ISP_LOGDEBUG1, + "Setting ICB Port 0x%08x%08x", + ((uint32_t) (pwwn >> 32)), + ((uint32_t) (pwwn & 0xffffffff))); + } else { + isp_prt(isp, ISP_LOGERR, "No valid WWNs to use"); + return; + } + icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp); + if (icbp->icb_rqstqlen < 1) { + isp_prt(isp, ISP_LOGERR, "bad request queue length"); + } + icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp); + if (icbp->icb_rsltqlen < 1) { + isp_prt(isp, ISP_LOGERR, "bad result queue length"); + } + icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma); + icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma); + icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma); + icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma); + icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma); + icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma); + icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma); + icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma); + + isp_prt(isp, ISP_LOGDEBUG0, + "isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x", + icbp->icb_fwoptions, icbp->icb_xfwoptions, icbp->icb_zfwoptions); + + FC_SCRATCH_ACQUIRE(isp, chan); + isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch); + + /* + * Init the firmware + */ + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_INIT_FIRMWARE; + mbs.param[2] = DMA_WD1(fcp->isp_scdma); + mbs.param[3] = DMA_WD0(fcp->isp_scdma); + mbs.param[6] = DMA_WD3(fcp->isp_scdma); + mbs.param[7] = DMA_WD2(fcp->isp_scdma); + mbs.logval = MBLOGALL; + mbs.timeout = 30 * 1000000; + isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %p (%08x%08x)", + fcp->isp_scratch, (uint32_t) ((uint64_t)fcp->isp_scdma >> 32), + (uint32_t) fcp->isp_scdma); + MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp)); + isp_mboxcmd(isp, &mbs); + FC_SCRATCH_RELEASE(isp, chan); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + isp_print_bytes(isp, "isp_fibre_init", sizeof (*icbp), icbp); + return; + } + isp->isp_reqidx = 0; + isp->isp_reqodx = 0; + isp->isp_residx = 0; + + /* + * Whatever happens, we're now committed to being here. + */ + isp->isp_state = ISP_INITSTATE; +} + +static void +isp_fibre_init_2400(ispsoftc_t *isp, int chan) +{ + fcparam *fcp; + isp_icb_2400_t local, *icbp = &local; + mbreg_t mbs; + int ownloopid; + uint64_t nwwn, pwwn; + + fcp = FCPARAM(isp, chan); + + /* + * Turn on LIP F8 async event (1) + */ + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_SET_FIRMWARE_OPTIONS; + mbs.param[1] = 1; + mbs.logval = MBLOGALL; + isp_mboxcmd(isp, &mbs); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + return; + } + + /* + * XXX: This should be applied to icb- not fwoptions + */ + if (isp->isp_role & ISP_ROLE_TARGET) { + fcp->isp_fwoptions |= ICB2400_OPT1_TGT_ENABLE; + } else { + fcp->isp_fwoptions &= ~ICB2400_OPT1_TGT_ENABLE; + } + + if (isp-... [truncated message content] |
From: <vl...@us...> - 2007-07-23 11:51:22
|
Revision: 152 http://svn.sourceforge.net/scst/?rev=152&view=rev Author: vlnb Date: 2007-07-23 04:51:05 -0700 (Mon, 23 Jul 2007) Log Message: ----------- Partial update for 2.6.22 Modified Paths: -------------- trunk/qla2x00t/ql2100.c trunk/qla2x00t/ql2200.c trunk/qla2x00t/ql2300.c trunk/qla2x00t/ql2322.c trunk/qla2x00t/ql2400.c trunk/qla2x00t/qla_def.h trunk/qla2x00t/qla_os.c trunk/scst/src/scst_mem.c trunk/scst/src/scst_proc.c Added Paths: ----------- trunk/scst/kernel/scst_exec_req_fifo-2.6.22.patch Modified: trunk/qla2x00t/ql2100.c =================================================================== --- trunk/qla2x00t/ql2100.c 2007-07-18 08:50:50 UTC (rev 151) +++ trunk/qla2x00t/ql2100.c 2007-07-23 11:51:05 UTC (rev 152) @@ -73,7 +73,7 @@ static int __init qla2100_init(void) { - return pci_module_init(&qla2100_pci_driver); + return pci_register_driver(&qla2100_pci_driver); } static void __exit Modified: trunk/qla2x00t/ql2200.c =================================================================== --- trunk/qla2x00t/ql2200.c 2007-07-18 08:50:50 UTC (rev 151) +++ trunk/qla2x00t/ql2200.c 2007-07-23 11:51:05 UTC (rev 152) @@ -73,7 +73,7 @@ static int __init qla2200_init(void) { - return pci_module_init(&qla2200_pci_driver); + return pci_register_driver(&qla2200_pci_driver); } static void __exit Modified: trunk/qla2x00t/ql2300.c =================================================================== --- trunk/qla2x00t/ql2300.c 2007-07-18 08:50:50 UTC (rev 151) +++ trunk/qla2x00t/ql2300.c 2007-07-23 11:51:05 UTC (rev 152) @@ -96,7 +96,7 @@ static int __init qla2300_init(void) { - return pci_module_init(&qla2300_pci_driver); + return pci_register_driver(&qla2300_pci_driver); } static void __exit Modified: trunk/qla2x00t/ql2322.c =================================================================== --- trunk/qla2x00t/ql2322.c 2007-07-18 08:50:50 UTC (rev 151) +++ trunk/qla2x00t/ql2322.c 2007-07-23 11:51:05 UTC (rev 152) @@ -101,7 +101,7 @@ static int __init qla2322_init(void) { - return pci_module_init(&qla2322_pci_driver); + return pci_register_driver(&qla2322_pci_driver); } static void __exit Modified: trunk/qla2x00t/ql2400.c =================================================================== --- trunk/qla2x00t/ql2400.c 2007-07-18 08:50:50 UTC (rev 151) +++ trunk/qla2x00t/ql2400.c 2007-07-23 11:51:05 UTC (rev 152) @@ -121,7 +121,7 @@ static int __init qla24xx_init(void) { - return pci_module_init(&qla24xx_pci_driver); + return pci_register_driver(&qla24xx_pci_driver); } static void __exit Modified: trunk/qla2x00t/qla_def.h =================================================================== --- trunk/qla2x00t/qla_def.h 2007-07-18 08:50:50 UTC (rev 151) +++ trunk/qla2x00t/qla_def.h 2007-07-23 11:51:05 UTC (rev 152) @@ -98,7 +98,14 @@ #define LSD(x) ((uint32_t)((uint64_t)(x))) #define MSD(x) ((uint32_t)((((uint64_t)(x)) >> 16) >> 16)) +#ifndef IRQF_DISABLED +#define IRQF_DISABLED SA_INTERRUPT +#endif +#ifndef IRQF_SHARED +#define IRQF_SHARED SA_SHIRQ +#endif + /* * I/O register */ Modified: trunk/qla2x00t/qla_os.c =================================================================== --- trunk/qla2x00t/qla_os.c 2007-07-18 08:50:50 UTC (rev 151) +++ trunk/qla2x00t/qla_os.c 2007-07-23 11:51:05 UTC (rev 152) @@ -1557,7 +1557,7 @@ host->transportt = qla2xxx_transport_template; ret = request_irq(pdev->irq, ha->isp_ops.intr_handler, - SA_INTERRUPT|SA_SHIRQ, ha->brd_info->drv_name, ha); + IRQF_DISABLED|IRQF_SHARED, ha->brd_info->drv_name, ha); if (ret) { qla_printk(KERN_WARNING, ha, "Failed to reserve interrupt %d already in use.\n", @@ -2744,7 +2744,7 @@ static inline int qla2x00_pci_module_init(void) { - return pci_module_init(&qla2xxx_pci_driver); + return pci_register_driver(&qla2xxx_pci_driver); } static inline void Added: trunk/scst/kernel/scst_exec_req_fifo-2.6.22.patch =================================================================== --- trunk/scst/kernel/scst_exec_req_fifo-2.6.22.patch (rev 0) +++ trunk/scst/kernel/scst_exec_req_fifo-2.6.22.patch 2007-07-23 11:51:05 UTC (rev 152) @@ -0,0 +1,109 @@ +diff -upr linux-2.6.22/drivers/scsi/scsi_lib.c linux-2.6.22/drivers/scsi/scsi_lib.c +--- linux-2.6.22/drivers/scsi/scsi_lib.c 2007-07-09 03:32:17.000000000 +0400 ++++ linux-2.6.22/drivers/scsi/scsi_lib.c 2007-07-18 13:34:54.000000000 +0400 +@@ -366,7 +366,7 @@ free_bios: + } + + /** +- * scsi_execute_async - insert request ++ * __scsi_execute_async - insert request + * @sdev: scsi device + * @cmd: scsi command + * @cmd_len: length of scsi cdb +@@ -377,11 +377,14 @@ free_bios: + * @timeout: request timeout in seconds + * @retries: number of times to retry request + * @flags: or into request flags ++ * @at_head: insert request at head or tail of queue + **/ +-int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, ++static inline int __scsi_execute_async(struct scsi_device *sdev, ++ const unsigned char *cmd, + int cmd_len, int data_direction, void *buffer, unsigned bufflen, + int use_sg, int timeout, int retries, void *privdata, +- void (*done)(void *, char *, int, int), gfp_t gfp) ++ void (*done)(void *, char *, int, int), gfp_t gfp, ++ int at_head) + { + struct request *req; + struct scsi_io_context *sioc; +@@ -418,7 +421,7 @@ int scsi_execute_async(struct scsi_devic + sioc->data = privdata; + sioc->done = done; + +- blk_execute_rq_nowait(req->q, NULL, req, 1, scsi_end_async); ++ blk_execute_rq_nowait(req->q, NULL, req, at_head, scsi_end_async); + return 0; + + free_req: +@@ -427,8 +430,53 @@ free_sense: + kmem_cache_free(scsi_io_context_cache, sioc); + return DRIVER_ERROR << 24; + } ++ ++/** ++ * scsi_execute_async - insert request ++ * @sdev: scsi device ++ * @cmd: scsi command ++ * @cmd_len: length of scsi cdb ++ * @data_direction: data direction ++ * @buffer: data buffer (this can be a kernel buffer or scatterlist) ++ * @bufflen: len of buffer ++ * @use_sg: if buffer is a scatterlist this is the number of elements ++ * @timeout: request timeout in seconds ++ * @retries: number of times to retry request ++ * @flags: or into request flags ++ **/ ++int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, ++ int cmd_len, int data_direction, void *buffer, unsigned bufflen, ++ int use_sg, int timeout, int retries, void *privdata, ++ void (*done)(void *, char *, int, int), gfp_t gfp) ++{ ++ return __scsi_execute_async(sdev, cmd, cmd_len, data_direction, buffer, ++ bufflen, use_sg, timeout, retries, privdata, done, gfp, 1); ++} + EXPORT_SYMBOL_GPL(scsi_execute_async); + ++/** ++ * scsi_execute_async_fifo - insert request at tail, in FIFO order ++ * @sdev: scsi device ++ * @cmd: scsi command ++ * @cmd_len: length of scsi cdb ++ * @data_direction: data direction ++ * @buffer: data buffer (this can be a kernel buffer or scatterlist) ++ * @bufflen: len of buffer ++ * @use_sg: if buffer is a scatterlist this is the number of elements ++ * @timeout: request timeout in seconds ++ * @retries: number of times to retry request ++ * @flags: or into request flags ++ **/ ++int scsi_execute_async_fifo(struct scsi_device *sdev, const unsigned char *cmd, ++ int cmd_len, int data_direction, void *buffer, unsigned bufflen, ++ int use_sg, int timeout, int retries, void *privdata, ++ void (*done)(void *, char *, int, int), gfp_t gfp) ++{ ++ return __scsi_execute_async(sdev, cmd, cmd_len, data_direction, buffer, ++ bufflen, use_sg, timeout, retries, privdata, done, gfp, 0); ++} ++EXPORT_SYMBOL_GPL(scsi_execute_async_fifo); ++ + /* + * Function: scsi_init_cmd_errh() + * +diff -upr linux-2.6.22/include/scsi/scsi_device.h linux-2.6.22/include/scsi/scsi_device.h +--- linux-2.6.22/include/scsi/scsi_device.h 2007-07-09 03:32:17.000000000 +0400 ++++ linux-2.6.22/include/scsi/scsi_device.h 2007-07-18 13:34:54.000000000 +0400 +@@ -303,6 +303,13 @@ extern int scsi_execute_async(struct scs + int timeout, int retries, void *privdata, + void (*done)(void *, char *, int, int), + gfp_t gfp); ++#define SCSI_EXEC_REQ_FIFO_DEFINED ++extern int scsi_execute_async_fifo(struct scsi_device *sdev, ++ const unsigned char *cmd, int cmd_len, int data_direction, ++ void *buffer, unsigned bufflen, int use_sg, ++ int timeout, int retries, void *privdata, ++ void (*done)(void *, char *, int, int), ++ gfp_t gfp); + + static inline int __must_check scsi_device_reprobe(struct scsi_device *sdev) + { Modified: trunk/scst/src/scst_mem.c =================================================================== --- trunk/scst/src/scst_mem.c 2007-07-18 08:50:50 UTC (rev 151) +++ trunk/scst/src/scst_mem.c 2007-07-23 11:51:05 UTC (rev 152) @@ -41,6 +41,19 @@ * of the existing SLAB code. */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)) +#error 2.6.22+ kernels are not supported yet, because some oversmart nerd \ +has deleted support for destructors from SLABs in those kernels and was \ +unresponsible enough to made that without even set it in the deprecated \ +status for some time to allow depending on it projects fix it without \ +disturbing their users. Blame him for that! So, now to be usable on \ +2.6.22+ kernels SCST requires a complete rewrite of one of its major low \ +level parts: all kmem_cache_*() functions in this file should be replaced \ +with new ones with similar functionality. I'm not sure I will have time for \ +that in the near future, therefore you are welcome to implement that. \ +Don't hesitate to ask me how to do it most effectively. VLNB. +#endif + /* Chosen to have one page per slab for all orders */ #ifdef CONFIG_DEBUG_SLAB #define SGV_MAX_LOCAL_SLAB_ORDER 4 @@ -505,9 +518,11 @@ { struct sgv_pool_obj *obj = data; +#ifdef SLAB_CTOR_VERIFY if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) != SLAB_CTOR_CONSTRUCTOR) return; +#endif TRACE_MEM("Constructor for sgv_obj %p", obj); memset(obj, 0, sizeof(*obj)); Modified: trunk/scst/src/scst_proc.c =================================================================== --- trunk/scst/src/scst_proc.c 2007-07-18 08:50:50 UTC (rev 151) +++ trunk/scst/src/scst_proc.c 2007-07-23 11:51:05 UTC (rev 152) @@ -167,7 +167,7 @@ #include <linux/ctype.h> -#if !defined(CONFIG_PPC) +#if !defined(CONFIG_PPC) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) #if defined(DEBUG) || defined(TRACING) static int strcasecmp(const char *s1, const char *s2) @@ -191,7 +191,7 @@ return c1 - c2; } -#endif /* CONFIG_PPC */ +#endif /* !CONFIG_PPC && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) */ #if defined(DEBUG) || defined(TRACING) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2007-08-14 17:03:44
|
Revision: 160 http://scst.svn.sourceforge.net/scst/?rev=160&view=rev Author: vlnb Date: 2007-08-14 10:03:42 -0700 (Tue, 14 Aug 2007) Log Message: ----------- - Version changed in scst_user_spec.txt - Minor fixes Modified Paths: -------------- trunk/doc/scst_user_spec.txt trunk/usr/fileio/common.c trunk/usr/fileio/debug.h trunk/usr/fileio/fileio.c Modified: trunk/doc/scst_user_spec.txt =================================================================== --- trunk/doc/scst_user_spec.txt 2007-08-14 16:54:54 UTC (rev 159) +++ trunk/doc/scst_user_spec.txt 2007-08-14 17:03:42 UTC (rev 160) @@ -2,7 +2,7 @@ USER SPACE INTERFACE DESCRIPTION. - Version 0.9.6 + Version 0.9.6/1 I. Description. @@ -570,6 +570,7 @@ uint64_t pbuf; int32_t resp_data_len; uint8_t buffer_cached; + uint8_t aborted; uint8_t status; }, @@ -582,6 +583,8 @@ - buffer_cached - true, if memory reusage is enabled for this command + - aborted - true, if command was aborted + - status - SAM status of the commands execution The user space handler should reply using the corresponding reply Modified: trunk/usr/fileio/common.c =================================================================== --- trunk/usr/fileio/common.c 2007-08-14 16:54:54 UTC (rev 159) +++ trunk/usr/fileio/common.c 2007-08-14 17:03:42 UTC (rev 160) @@ -800,7 +800,7 @@ close(vcmd.fd); out: - PRINT_INFO_PR("Thread %d exited (res=%d)", gettid(), res); + PRINT_INFO_PR("Thread %d exiting (res=%d)", gettid(), res); TRACE_EXIT_RES(res); return (void*)res; Modified: trunk/usr/fileio/debug.h =================================================================== --- trunk/usr/fileio/debug.h 2007-08-14 16:54:54 UTC (rev 159) +++ trunk/usr/fileio/debug.h 2007-08-14 17:03:42 UTC (rev 160) @@ -105,6 +105,9 @@ #define TRACE_BUFFER(message, buff, len) {} #define TRACE_BUFF_FLAG(flag, message, buff, len) {} +static inline int debug_init(void) { return 0; } +static inline void debug_done(void) {} + #endif /* DEBUG || TRACING */ #ifdef DEBUG Modified: trunk/usr/fileio/fileio.c =================================================================== --- trunk/usr/fileio/fileio.c 2007-08-14 16:54:54 UTC (rev 159) +++ trunk/usr/fileio/fileio.c 2007-08-14 17:03:42 UTC (rev 160) @@ -396,7 +396,7 @@ goto out_close; } -#if 0 +#if 1 { /* Not needed, added here only as a test */ struct scst_user_opt opt; @@ -464,8 +464,11 @@ res = errno; PRINT_ERROR_PR("pthread_join() failed: %s", strerror(res)); - } else if (rc1 != NULL) + } else if (rc1 != NULL) { res = (int)rc1; + PRINT_INFO("Thread %d exited, res %x", i, res); + } else + PRINT_INFO("Thread %d exited", i); } if (dev.prio_thr) { rc = pthread_join(prio, &rc1); @@ -473,8 +476,11 @@ res = errno; PRINT_ERROR_PR("Prio pthread_join() failed: %s", strerror(res)); - } else if (rc1 != NULL) + } else if (rc1 != NULL) { res = (int)rc1; + PRINT_INFO("Prio thread %d exited, res %x", i, res); + } else + PRINT_INFO("Prio thread %d exited", i); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2007-08-15 10:34:56
|
Revision: 162 http://scst.svn.sourceforge.net/scst/?rev=162&view=rev Author: vlnb Date: 2007-08-15 02:28:54 -0700 (Wed, 15 Aug 2007) Log Message: ----------- The initial commit of iSCSI-SCST Modified Paths: -------------- trunk/Makefile Added Paths: ----------- trunk/iscsi-scst/ trunk/iscsi-scst/COPYING trunk/iscsi-scst/ChangeLog trunk/iscsi-scst/ChangeLog-IET trunk/iscsi-scst/Makefile trunk/iscsi-scst/README trunk/iscsi-scst/README-IET trunk/iscsi-scst/ToDo trunk/iscsi-scst/doc/ trunk/iscsi-scst/doc/manpages/ trunk/iscsi-scst/doc/manpages/iscsi-scst-adm.8 trunk/iscsi-scst/doc/manpages/iscsi-scstd.8 trunk/iscsi-scst/doc/manpages/iscsi-scstd.conf.5 trunk/iscsi-scst/etc/ trunk/iscsi-scst/etc/initd/ trunk/iscsi-scst/etc/initd/initd trunk/iscsi-scst/etc/initd/initd.debian trunk/iscsi-scst/etc/initd/initd.gentoo trunk/iscsi-scst/etc/initd/initd.redhat trunk/iscsi-scst/etc/initiators.allow trunk/iscsi-scst/etc/initiators.deny trunk/iscsi-scst/etc/iscsi-scstd.conf trunk/iscsi-scst/include/ trunk/iscsi-scst/include/iscsi_u.h trunk/iscsi-scst/kernel/ trunk/iscsi-scst/kernel/Makefile trunk/iscsi-scst/kernel/config.c trunk/iscsi-scst/kernel/conn.c trunk/iscsi-scst/kernel/digest.c trunk/iscsi-scst/kernel/digest.h trunk/iscsi-scst/kernel/event.c trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/kernel/iscsi.h trunk/iscsi-scst/kernel/iscsi_dbg.h trunk/iscsi-scst/kernel/iscsi_hdr.h trunk/iscsi-scst/kernel/nthread.c trunk/iscsi-scst/kernel/param.c trunk/iscsi-scst/kernel/patches/ trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.16.patch trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.18.patch trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.21.patch trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.22.patch trunk/iscsi-scst/kernel/session.c trunk/iscsi-scst/kernel/target.c trunk/iscsi-scst/usr/ trunk/iscsi-scst/usr/Makefile trunk/iscsi-scst/usr/chap.c trunk/iscsi-scst/usr/config.h trunk/iscsi-scst/usr/conn.c trunk/iscsi-scst/usr/ctldev.c trunk/iscsi-scst/usr/event.c trunk/iscsi-scst/usr/iscsi_adm.c trunk/iscsi-scst/usr/iscsi_adm.h trunk/iscsi-scst/usr/iscsi_hdr.h trunk/iscsi-scst/usr/iscsi_scstd.c trunk/iscsi-scst/usr/iscsid.c trunk/iscsi-scst/usr/iscsid.h trunk/iscsi-scst/usr/isns.c trunk/iscsi-scst/usr/isns_proto.h trunk/iscsi-scst/usr/log.c trunk/iscsi-scst/usr/message.c trunk/iscsi-scst/usr/misc.h trunk/iscsi-scst/usr/param.c trunk/iscsi-scst/usr/param.h trunk/iscsi-scst/usr/plain.c trunk/iscsi-scst/usr/session.c trunk/iscsi-scst/usr/target.c trunk/iscsi-scst/usr/types.h Modified: trunk/Makefile =================================================================== --- trunk/Makefile 2007-08-14 17:08:43 UTC (rev 161) +++ trunk/Makefile 2007-08-15 09:28:54 UTC (rev 162) @@ -24,22 +24,28 @@ LSI_DIR=mpt USR_DIR=usr/fileio +ISCSI_DIR=iscsi-scst +#ISCSI_DISTDIR=../../../../iscsi_scst_inst + all: cd $(SCST_DIR) && $(MAKE) $@ @if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; fi # @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi + @if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi @if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi install: cd $(SCST_DIR) && $(MAKE) $@ @if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; fi # @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi + @if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) DISTDIR=$(ISCSI_DISTDIR) $@; fi @if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi uninstall: cd $(SCST_DIR) && $(MAKE) $@ @if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; fi @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi + @if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi @if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi clean: @@ -47,6 +53,7 @@ @if [ -d $(QLA_INI_DIR) ]; then cd $(QLA_INI_DIR) && $(MAKE) $@; fi @if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; fi @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi + @if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi @if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi extraclean: @@ -54,6 +61,7 @@ @if [ -d $(QLA_INI_DIR) ]; then cd $(QLA_INI_DIR) && $(MAKE) $@; fi @if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; fi @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi + @if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi @if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi scst: @@ -88,6 +96,21 @@ cd $(QLA_INI_DIR)/.. && $(MAKE) extraclean cd $(QLA_DIR) && $(MAKE) extraclean +iscsi: + cd $(ISCSI_DIR) && $(MAKE) + +iscsi_install: + cd $(ISCSI_DIR) && $(MAKE) install + +iscsi_uninstall: + cd $(ISCSI_DIR) && $(MAKE) uninstall + +iscsi_clean: + cd $(ISCSI_DIR) && $(MAKE) clean + +iscsi_extraclean: + cd $(ISCSI_DIR) && $(MAKE) extraclean + lsi: cd $(LSI_DIR) && $(MAKE) @@ -137,6 +160,12 @@ @echo " qla_install : 2.6 qla target: install" @echo " qla_uninstall : 2.6 qla target: uninstall" @echo "" + @echo " iscsi : make new ISCSI target" + @echo " iscsi_clean : ISCSI target: clean " + @echo " iscsi_extraclean : ISCSI target: clean + clean dependencies" + @echo " iscsi_install : ISCSI target: install" + @echo " iscsi_uninstall : ISCSI target: uninstall" + @echo "" @echo " lsi : make lsi target" @echo " lsi_clean : lsi target: clean " @echo " lsi_extraclean : lsi target: clean + clean dependencies" @@ -154,5 +183,6 @@ .PHONY: all install uninstall clean extraclean help \ qla qla_install qla_uninstall qla_clean qla_extraclean \ lsi lsi_install lsi_uninstall lsi_clean lsi_extraclean \ + iscsi iscsi_install iscsi_uninstall iscsi_clean iscsi_extraclean \ scst scst_install scst_uninstall scst_clean scst_extraclean \ usr usr_install usr_uninstall usr_clean usr_extraclean Added: trunk/iscsi-scst/COPYING =================================================================== --- trunk/iscsi-scst/COPYING (rev 0) +++ trunk/iscsi-scst/COPYING 2007-08-15 09:28:54 UTC (rev 162) @@ -0,0 +1,341 @@ + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. Added: trunk/iscsi-scst/ChangeLog =================================================================== --- trunk/iscsi-scst/ChangeLog (rev 0) +++ trunk/iscsi-scst/ChangeLog 2007-08-15 09:28:54 UTC (rev 162) @@ -0,0 +1,38 @@ +Summary of changes in iSCSI-SCST since it was IET +------------------------------------------------- + + - Commands processing flow changed to work with SCST. Significant + cleanup was done. Modules and config files were renamed to allow to + run with IET on the same host. + + - In IET the iSCSI negotiation isn't fully iSCSI RFC confirmed: it doesn't + support ranges of values and, more important, violates RFC in case + when in the IET config file some value for some parameter is set and + a remote initiator doesn't initiate the negotiation for this + parameter or declare its value. According to RFC, in this case IET + shall use the RFC-specified default value, but it uses config file + specified one instead. Looks like the implementation confuses IET + config file default values and iSCSI RFC ones. The default values + handling was fixed. But support for ranges remains unfixed (see ToDo + file). + + - All shutdown/restart problems (resource leaks, hangups, etc.), especially + under load, were fixed. + + - Full duplex network IO implemented. + + - Threading model reimplemented. + + - Digests calculation made multi-threaded. + + - TX data digest errors handling iSCSI RFC violation was fixed. Another one + (SNACK handling) remains unfixed. + + - Ability to send data with sense in a single response added. + + - Ability to handle initiators misbehavior a bit improved: several BUG()'s + were relaced by the proper handling. Hovewer, there is a plenty of work in + this area left, IET is known to have a lot of weaknesses here. + + - A lot of other bugfixes and code cleanups. + Added: trunk/iscsi-scst/ChangeLog-IET =================================================================== --- trunk/iscsi-scst/ChangeLog-IET (rev 0) +++ trunk/iscsi-scst/ChangeLog-IET 2007-08-15 09:28:54 UTC (rev 162) @@ -0,0 +1,435 @@ +Summary of changes from v0.4.14 to v0.4.15 +================================= + +Juhani Rautiainen + o Add RELEASE/RESERVE support + +Ross S. W. Walker + o Improve the build system to support several kernel versions + o Add block-io support + + +Summary of changes from v0.4.13 to v0.4.14 +================================= + +Arne Redlich + o Kill unused "state" in struct iscsi_cmnd. + o Fixed fileio_sync() to propagate error to the caller (and initiator). + o Don't attempt to show target/session params if communication with ietd + fails. + o Fixes to ietadm parameters handling. + +FUJITA Tomonori + o rewritten iSNS code, many iSNS fixes. + o added iSNS SCN support. + o IPv6 fixes to userspace. + +Ming Zhang + o Fix the READ_* commands error handling bug. + o fix the mode sense response. + o wrong #endif sequence in misc.h + +Richard Bollinger + o add a patch to ietd.c that allows defunct sessions to go away. + o add write-back cache and read-only support. + +Frederic Temporelli + o Fix for the combination of 32-bit userland and 64-bit kernel on mips. + +Henry Liu + o corrected many task management functions, prevent crashing on + LUN RESET, TARGET WARM RESET. + +K Chapman + o Fixed a typo in check_segment_length(). + +Emmanuel Florac + o Add ietadm manpage. + + +Summary of changes from v0.4.12 to v0.4.13 +================================= +Arne Redlich + o patch to avoid digest calculation for PDUs whose data has been skipped + already for various reasons. + o Correct a bug managing non-default MaxRxDSL. + o added to ietadm ability to show target parameters. + o add on the workaround to AIX initiator MaxCmdSN bug. + +FUJITA Tomonori + o added to ietadm ability to show the iSCSI parameters for an established + session. + +Ming Zhang + o Fixed this bug : ietd should manage the iscsi name in a case insensitive + way to conform to the RFC. + o workaround to AIX initiator MaxCmdSN bug. + o Fixed socket() return value judgment. + +Bastiaan Bakker + o add 'condrestart' command to the RedHat initscript. + +Robert Whitehead + o correct the bug that prevents iet to start if there isn't + an /etc/ietd.conf file. + +Summary of changes from v0.4.11 to v0.4.12 +================================= + +Arne Redlich + o Fix MaxRecvDataSegmentLength handling. + o Fix login parameter handling. + o Update man pages. + +Bastiaan Bakker + o Add features to specify the listen address and port. + o Fix setuid and setgid bugs in ietd daemon. + +FUJITA Tomonori + o Add IPv6 support. + +Junjiro Okajima + o Fix a bug about getting parameters from kernel space. + +Krzysztof Blaszkowski + o Fix for requests with unaligned to 4 length. + + +Summary of changes from v0.4.10 to v0.4.11 +================================= + +FUJITA Tomonori + o Fix Task Management Function bugs. + +Ming Zhang + o Update man pages. + + +Summary of changes from v0.4.9 to v0.4.10 +================================= + +Arne Redlich + o Fix 0x83 inquiry output. + o Fix iSCSI parameter handling bugs. + +FUJITA Tomonori + o Add the access control based on initiator address + and target name patterns. + +Junjiro Okajima + o Fix parameter checking bugs. + +Ming Zhang + o Add the nullio mode (only useful for performance evaluation). + + +Summary of changes from v0.4.8 to v0.4.9 +================================= + +FUJITA Tomonori + o Fix parameter negotiation handling bugs. + +Wang Zhenyu + o Fix digest negotiation handling bugs. + + +Summary of changes from v0.4.7 to v0.4.8 +================================= + +FUJITA Tomonori + o Fix unsolicited data handling bugs. + o Rewrite parameter handling code. + o Rewrite ietadm tool. + o Improve dynamic configuration support. + o Cleanups on the kernel-user interface. + o Improve wrong PDU handling. + o Implement a framework to handle multiple configuration methods. + o Implement basic access control support. + + +Summary of changes from v0.4.6 to v0.4.7 +================================= + +Florian Zierer + o Add the startup script for Gentoo. + +FUJITA Tomonori + o Rewrite parameter handling code. + o Fix task management code bug. + o Fix 0x83 inquiry output (Thanks to Christophe Varoqui). + +Ming Zhang + o Acquire T10 ID. + o Fix parameter handling bugs. + o Some user-space cleanups. + +Philipp Hug + o Fix ietd.8 man typo. + + +Summary of changes from v0.4.5 to v0.4.6 +================================= + +FUJITA Tomonori + o Replace the makeshift event notification code with netlink. + o Add task management code except for ACA and reassign stuff. + o Fix r2t lun bug (Thanks to Ming Zhang). + + +Summary of changes from v0.4.4 to v0.4.5 +================================= + +FUJITA Tomonori + o Rewrite the iSCSI command handling code. + o Rewrite the I/O data handling code. + o Fix worker thread. + o Several cleanups. + + +Summary of changes from v0.4.3 to v0.4.4 +================================= + +Krzysztof Blaszkowski + o Fix an out-of-memory bug. + + +Summary of changes from v0.4.2 to v0.4.3 +================================= + +Arne Redlich + o Fix header digest bug. + o Fix unexpected closed connection bug. + o Fix iSCSI parameter bug. + +FUJITA Tomonori + o Fix network thread. + + +Summary of changes from v0.4.1 to v0.4.2 +================================= + +FUJITA Tomonori + o Fix network thread. + o Fix MaxOutstandingR2T handling. + +Ming Zhang + o Add large volume support (over 2TB). + + +Summary of changes from v0.4.0 to v0.4.1 +================================= + +Arne Redlich + o Add mutual CHAP support. Note that you need to replace "User" + with "IncomingUser" in ietd.conf. + +FUJITA Tomonori + o Fix InitialR2T=No support. + o Fix INQUIRY command handling. + o Fix network and worker thread. + o Start to split SCSI stuff. + o Rewrite the R2T handling code. + o Several cleanups. + + +Summary of changes from v0.3.8 to v0.4.0 +================================= + +Arne Redlich + o iSNS bug fix. + +FUJITA Tomonori + o Move to 2.6 kernels. + o Rewrite the kernel thread performing network I/O. + o Add header and data digests (Thanks to Arne Redlich). + +Ming Zhang + o Add mode sense page 0x3 and 0x4 support (Thanks to K Chapman). + o iSNS bug fix. + + +Summary of changes from v0.3.7 to v0.3.8 +================================= + +Arne Redlich + o Fix ietadm global option bug. + +FUJITA Tomonori + o Fix TCP option bugs (Thanks to Chuck Berg). + o Fix REPORT LUN (handling lots of LUs). + + +Summary of changes from v0.3.6 to v0.3.7 +================================= + +Arne Redlich + o Fix target_alloc_pages(). + +FUJITA Tomonori + o Fix REPORT LUN bug. + + +Summary of changes from v0.3.5 to v0.3.6 +================================= + +Arne Redlich + o Fix bugs about rejecting PDUs. + +FUJITA Tomonori + o Cleanups on target_cmnd structure. + o Kill highmem stuff. + o Fix REPORT LUN (handling lots of LUs). + + +Summary of changes from v0.3.4 to v0.3.5 +================================= + +Arne Redlich + o Fix ietd security hole. + o Fix REPORT LUN bug. + o FIX NOOP_OUT padding bug. + +FUJITA Tomonori + o Rewrite event notification code. + +Libor Vanek + o Add max_sessions option. + o Fix command parsing bug. + +Ming Zhang + o Cleanups for 64-bit architectures. + + +Summary of changes from v0.3.3 to v0.3.4 +================================= + +FUJITA Tomonori + o Improve dynamic configuration support (adding targets and users). + + +Summary of changes from v0.3.2 to v0.3.3 +================================= + +FUJITA Tomonori + o Fix Makefile for the startup script. + + +Summary of changes from v0.3.1 to v0.3.2 +================================= + +Ali Lehmann + o Add a new startup script for Debian. + +FUJITA Tomonori + o Fix the istd's handling of connections in out-of-memory situations. + o Fix bugs in regular file support. + o Fix `ietadm --mode del all`. + +Libor Vanek + o Add a new startup script for RedHat. + +Ming Zhang + o Add uid/gid option to ietd daemon. + o Fix a access freed-memory bug in kernel/daemon.c. + + +Summary of changes from v0.3.0 to v0.3.1 +================================= + +FUJITA Tomonori + o Fix memory leaks in ietd daemon (Thanks to Ming). + o Fix bugs about REPORT_LUNS commands (Thanks to Ming). + o Fix a bug about Target Task Tag. + o Add regular file support to fileio mode. + + +Summary of changes from v0.2.6 to v0.3.0 +================================= + +Ali Lehmann + o Update ietd.8 man page. + +FUJITA Tomonori + o Fix shutdown code. + o Fix istd kernel thread bugs. + o Replace procfs interface with ioctl. + o Add dynamic configuration support. + o Update README and the boot script. + +Ming Zhang + o Add config option to ietd daemon. + + +Summary of changes from v0.2.5 to v0.2.6 +================================= + +Ali Lehmann + o Add ietd.8 and ietd.conf.5 man pages. + +FUJITA Tomonori + o Update README, Makefile, and the boot script. + + +Summary of changes from v0.2.4 to v0.2.5 +================================= + +FUJITA Tomonori + o Update README. + + +Summary of changes from v0.2.3 to v0.2.4 +================================= + +Ming Zhang + o Add a preliminary iSNS support. + o Fix merge mistakes that I made at the previous release. + + +Summary of changes from v0.2.2 to v0.2.3 +================================= + +Ming Zhang + o Improve INQUIRY, REQUEST_SENSE, and MODE_SENSE command supports + o Add fake RESERVE* and RELEASE* command supports + + +Summary of changes from v0.2.1 to v0.2.2 +================================= + +FUJITA Tomonori + o Improve the write performance of the file IO mode + +Ming Zhang + o Fix unupdated pg_cnt when allocating a new tcmnd + o Several cleanups + + +Summary of changes from v0.2.0 to v0.2.1 +================================= + +FUJITA Tomonori + o Fix a bug that makes the target use CPU unnecessarily + o Add a feature that enable you to pass options to an IO mode + + +Summary of changes from v0.1.0 to v0.2.0 +================================= + +FUJITA Tomonori + o Rewrite read and write kernel threads which perform network IO + o Fix race issues in the proc interface + o Fix shutdown code + +Ming Zhang + o Fix memory leaks in file and block IO modes + + +Summary of changes from the ardis v20040211 to v0.1.0 +================================= + +FUJITA Tomonori + o Remove a kernel patch. Multiple threads execute I/O operations + o Replace IO functions with the kernel starndard functions + o Add multiple IO modes feature + o Fix several race issues + o Fix several out-of-memory situation bugs Added: trunk/iscsi-scst/Makefile =================================================================== --- trunk/iscsi-scst/Makefile (rev 0) +++ trunk/iscsi-scst/Makefile 2007-08-15 09:28:54 UTC (rev 162) @@ -0,0 +1,76 @@ +# +# Makefile for the Linux kernel device drivers. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (not a .c file). +# +# Note 2! The CFLAGS definitions are now in the main makefile. + +SCST_DIR := $(shell pwd)/../scst/src +SUBDIRS := $(shell pwd) + +ifeq ($(KVER),) + ifeq ($(KDIR),) + KVER = $(shell uname -r) + KDIR ?= /lib/modules/$(KVER)/build + else + KVER = $$KERNELRELEASE + endif +else + KDIR ?= /lib/modules/$(KVER)/build +endif + +all: progs mods + +mods: Modules.symvers Module.symvers + $(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd)/kernel modules + +progs: + $(MAKE) -C usr + +install: all kernel/iscsi-scst.ko usr/iscsi-scstd usr/iscsi-scst-adm + @install -vD usr/iscsi-scstd $(DISTDIR)/usr/local/sbin/iscsi-scstd + @install -vD usr/iscsi-scst-adm $(DISTDIR)/usr/local/sbin/iscsi-scst-adm + if [ -f /etc/debian_version ]; then \ + install -vD -m 755 etc/initd/initd.debian $(DISTDIR)/etc/init.d/iscsi-scst; \ + elif [ -f /etc/redhat-release ]; then \ + install -vD -m 755 etc/initd/initd.redhat $(DISTDIR)/etc/init.d/iscsi-scst; \ + elif [ -f /etc/gentoo-release ]; then \ + install -vD -m 755 etc/initd/initd.gentoo $(DISTDIR)/etc/init.d/iscsi-scst; \ + elif [ -f /etc/slackware-version ]; then \ + install -vD -m 755 etc/initd/initd $(DISTDIR)/etc/rc.d/iscsi-scst; \ + else \ + install -vD -m 755 etc/initd/initd $(DISTDIR)/etc/init.d/iscsi-scst; \ + fi + @eval `sed -n 's/#define UTS_RELEASE /KERNELRELEASE=/p' $(KDIR)/include/linux/version.h $(KDIR)/include/linux/utsrelease.h 2>/dev/null`; \ + install -vD -m 644 kernel/iscsi-scst.ko \ + $(DISTDIR)$(INSTALL_MOD_PATH)/lib/modules/$(KVER)/extra/iscsi-scst.ko + -/sbin/depmod -aq $(KVER) + +SCST_MOD_VERS := $(shell ls $(SCST_DIR)/Modules.symvers 2>/dev/null) +ifneq ($(SCST_MOD_VERS),) +Modules.symvers: $(SCST_DIR)/Modules.symvers + echo $(SCST_MOD_VERS) + cp $(SCST_DIR)/Modules.symvers kernel/ +else +.PHONY: Modules.symvers +endif + +# It's renamed in 2.6.18 +SCST_MOD_VERS := $(shell ls $(SCST_DIR)/Module.symvers 2>/dev/null) +ifneq ($(SCST_MOD_VERS),) +Module.symvers: $(SCST_DIR)/Module.symvers + cp $(SCST_DIR)/Module.symvers kernel/ +else +.PHONY: Module.symvers +endif + +clean: + $(MAKE) -C usr clean + $(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd)/kernel clean + rm -f kernel/Modules.symvers kernel/Module.symvers + +extraclean: clean + +.PHONY: all mods progs install clean extraclean Added: trunk/iscsi-scst/README =================================================================== --- trunk/iscsi-scst/README (rev 0) +++ trunk/iscsi-scst/README 2007-08-15 09:28:54 UTC (rev 162) @@ -0,0 +1,115 @@ +iSCSI SCST target driver +======================== + +Version 0.9.6/XXXX, XX XXX 200X +------------------------------- + +This driver is a forked with all respects version of iSCSI Enterprise +Target (IET) (http://iscsitarget.sourceforge.net/) with updates to work +over SCST as well as with many improvements and bugfixes (see ChangeLog +file). The reason of fork is that the necessary changes are intrusive +and with the current IET merge policy, where only simple bugfix-like +patches, which doesn't touch the core code, could be merged, it is very +unlikely that they will be merged in the main IET trunk. + +To let it be installed and work at the same host together with IET +simultaneously all the driver's modules and files were renamed: + + * ietd.conf -> iscsi-scstd.conf + * ietadm -> iscsi-scst-adm + * ietd -> iscsi-scstd + * iscsi-target -> iscsi-scst + * iscsi-target.ko -> iscsi-scst.ko + +This version is compatible with SCST version 0.9.6 and higher. + +Tested on 2.6.21.1 kernel, but it should also work on other versions, +starting from 2.6.16.x. + +Installation +------------ + +Basically as in README-IET, where file names are changed as specified +above. + +To use full power of TCP zero-copy transmit functions, especially +dealing with user space supplied via scst_user module memory, iSCSI-SCST +needs to be notified when Linux networking finished data transmission. +Patch put_page_callback.patch provides such functionality. The +corresponding version of it should be applied on your kernel. This is +highly recommended, but not required. If it isn't applied, iSCSI-SCST +will work in the performance degraded mode, when for data transmission: + + - For in-kernel allocated memory (scst_vdisk and pass-through + handlers) usage of SGV cache on transmit path (READ-type commands) + will be disabled. The performance hit will be not big, performance + will still remain better, than for IET, because SGV cache will remain + used on receive path and IET doesn't have such feature. + + - For user space allocated memory (scst_user handler) all transmitted + data will be additionally copied into temporary TCP buffers. The + performance hit will be quite noticiable. + +If you need your own version of put_page_callback.patch for your custom +kernel, for which there is no prepared version, you can create it +yourself. For that it is only necessary: + +1. Apply the closest version of put_page_callback.patch on your kernel. +Resolve only failed hanks from include/ and net/core/utils.c, ignore +other failures. + +2. Grep net/ and replace everywhere, except in net/sunrpc/svc.c and +net/core/pktgen.c, put_page() by net_put_page() and get_page() by +net_get_page(). + +That's all. + +Usage +----- + +ISCSI parameters like iSNS, CHAP and target parameters are configured in +iscsi-scstd.conf. All LUN information is configured using the regular +SCST interface. The LUN information in iscsi-scstd.conf will be ignored. +This is because now responsibilities are divided (as it should be) +between the target driver (iSCSI-SCST) and the SCST core. The target +driver is responsible for handling targets and their parameters, SCST +core is responsible for handling backstorage. + +If you need to configure different LUs for different targets you should +create for each target group "Default_target_name", where target name +means name of the target, for example: +"Default_iqn.2007-05.com.example:storage.disk1.sys1.xyz", and add there +all necessary LUNs. Check SCST README file for details. + +Compilation options +------------------- + +There are the following compilation options, that could be commented +in/out in the kernel's module Makefile: + + - DEBUG - turns on some debugging code, including some logging. Makes + the driver considerably bigger and slower, producing large amount of + log data. + + - TRACING - turns on ability to log events. Makes the driver considerably + bigger and lead to some performance loss. + + - EXTRACHECKS - adds extra validity checks in the various places. + + - DEBUG_DIGEST_FAILURES - simulates digest failures in random places. + +Credits +------- + +Thanks to: + + * IET developers for IET + + * Ming Zhang <bla...@gm...> for fixes + + * Krzysztof Blaszkowski <kb...@sy...> for many fixes + + * Alexey Kuznetsov <ku...@ms...> for comments and help in + debugging + +Vladislav Bolkhovitin <vs...@vl...>, http://scst.sourceforge.net Added: trunk/iscsi-scst/README-IET =================================================================== --- trunk/iscsi-scst/README-IET (rev 0) +++ trunk/iscsi-scst/README-IET 2007-08-15 09:28:54 UTC (rev 162) @@ -0,0 +1,105 @@ +Introduction +------------- +iSCSI Enterprise Target is for building an iSCSI storage system on +Linux. It is aimed at developing an iSCSI target satisfying enterprise +requirements. + +We borrow code from an Ardis iSCSI target (with respect to the GPL). + + +Installation +------------- +The iSCSI target requires a host running the Linux operating system +with a kernel version of 2.6.19 (2.6.14 - 2.6.18 kernels using +backward compatibility patches, see below) or newer. You need to +enable "Cryptographic API" under "Cryptographic options" in the kernel +config. You also need to enable "CRC32c CRC algorithm" if you use +header or data digests. They are the kernel options, CONFIG_CRYPTO and +CONFIG_CRYPTO_CRC32C, respectively. The user-space code requires +OpenSSL library (http://www.openssl.org/). + +The iSCSI target consists of kernel modules and a daemon. Since IET +is generally targetted at the latest stable mainline kernel, you might +need to apply a backward compatibility patch to compile it against +older kernel versions: + + patch -p0 < patches/compat-2.6.14-2.6.18.patch + +Compilation of the kernel modules require the path to the kernel +sources: + + make KSRC=<kernel-src> + +The path can also be set by editing the main Makefile. If KSRC is +omitted, make program will try to locate the kernel sources for +current running kernel. Be sure to check whether it finds the right +kernel sources. + +This will build the modules, the daemon, and the control tool. To +install both, use: + + make KSRC=<kernel-src> install + +The kernel modules will be install in the module directory of the +kernel. The daemon and the control tool will be installed as ietd and +ietadm under /usr/sbin. The boot script will be installed as +iscsi-targt under /etc/init.d. + +If you use Linux distribution that does not have /etc/init.d, the +boot script will not be installed. So you need to install it to an +appropriate directory manually. + + +Configuration +------------- +The daemon is configured via the configuration file /etc/ietd.conf. +See the man page and the example file for the current syntax. + +The ietadm utility is for managing IET software dynamically. You can +change the configurations of running targets. See the help message. + +The access control based on initiator address and target name patterns +is configured via two configuration files (/etc/initiators.allow and +/etc/initiators.deny). These files work like tcpd files +(/etc/hosts.allow and /etc/hosts.deny). This feature enables you to +hide a particular targets from some initiators. See the example files +for the supported expressions. You can change the configuration +dynamically. The modifications to the files become effective +immediately. + + +Starting +------------- +The target is not started automatically. So execute: + + /etc/init.d/iscsi-target start + +Note that you must edit the configuration file before starting the +target. + + +Stopping +------------- +Execute: + + /etc/init.d/iscsi-target stop + +Contact +------------- +Please send bug reports, comments, feature requests etc. to our +mailing list <isc...@li...>. + + +Developer Notes +---------------- +The central resource for IET development is the +<isc...@li...> mailing list. + +Our subversion repository can be found at: svn://svn.berlios.de/iscsitarget + +When submitting patches, please diff against the code in our repository's +trunk and adhere otherwise to the same rules that apply to Linux kernel +development, in particular the Linux kernel coding style +($KSRC/Documentation/CodingStyle) and the rules for submitting patches +($KSRC/Documentation/SubmittingPatches), i.e. please send patches inline as +plain text. Added: trunk/iscsi-scst/ToDo =================================================================== --- trunk/iscsi-scst/ToDo (rev 0) +++ trunk/iscsi-scst/ToDo 2007-08-15 09:28:54 UTC (rev 162) @@ -0,0 +1,32 @@ + - Reimplement sessions parameters negotiation and storage. In IET + the negotiation isn't iSCSI RFC confirmed: it doesn't support ranges + of values and, more important, violates RFC in case when in the IET + config file some value for some parameter is set and a remote + initiator doesn't initiate the negotiation for this parameter or + declare its value. According to RFC, in this case IET shall use the + RFC-specified default value, but it will use config file specified + one instead. Looks like the implementation confuses IET config file + default values and iSCSI ones. The default values handling was fixed + in very dirty and hackish way, but ranges support remains unfixed. + Storage of set by user parameters should be reimplemented, so they + will be kept in iscsi-scstd, not in the kernel, as it is currently + done in IET's code. Using kernel to *only* store parameters is quite + questionable decision, especially considering that it leads to some + code duplication between kernel and user space, so remove all + parameters storage code from kernel. Remove target_param, leave only + one type of parameters, but separate processing of iSCSI RFC + parameters from local ones (currently they are mixed up). Also mixing + up conceptions of "key" and "param" in param_*() and struct + iscsi_key_ops functions makes the code hardly manageable, particularly + for adding support for ranges in the negotiation keys, so it needs to + be fixed as well. + + - Fix SNACK command handling. Currently it violates iSCSI RFC. + + - Consider better integration with TCP internals on receive path to + improve performance. + + - The target shouldn't crash/hang/etc. on initiators' misbehavior as + IET likes to do. + + - Minor "ToDo"'s spread in the code. Added: trunk/iscsi-scst/doc/manpages/iscsi-scst-adm.8 =================================================================== --- trunk/iscsi-scst/doc/manpages/iscsi-scst-adm.8 (rev 0) +++ trunk/iscsi-scst/doc/manpages/iscsi-scst-adm.8 2007-08-15 09:28:54 UTC (rev 162) @@ -0,0 +1,240 @@ +.\" Automatically generated by Pod::Man 2.09 (Pod::Simple 3.04) +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sh \" Subsection heading +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. | will give a +.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to +.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' +.\" expand to `' in nroff, nothing in troff, for use with C<>. +.tr \(*W-|\(bv\*(Tr +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.ie n \{\ +. ds -- \(*W- +. ds PI pi +. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +. ds L" "" +. ds R" "" +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +'br\} +.\" +.\" If the F register is turned on, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.if \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. nr % 0 +. rr F +.\} +.\" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.hy 0 +.if n .na +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds / +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +.\} +.rm #[ #] #H #V #F C +.\" ======================================================================== +.\" +.IX Title "ISCSI_SCST_ADM 1" +.TH ISCSI_SCST_ADM 8 "2007-05" "iSCSI SCST Target admin" "User Manuals" +.SH "NAME" +iscsi-scst-adm \- iSCSI SCST Target Administration Utility. +.SH "SYNOPSIS" +.IX Header "SYNOPSIS" +\&\fBiscsi-scst-adm \-\-op [operation] \-\-tid=[id] [\-\-sid [id]] [\-\-params [key=value,...]]\fR +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +iscsi-scst-adm is used to monitor and modify in real-time the iSCSI SCST Target +targets. +.SH "USAGE" +.IX Header "USAGE" +You'll have to get target and sessions ids from /proc/scsi_tgt/iscsi. +Some usage examples can be : +.PP +\&\fBiscsi-scst-adm \-\-op show \-\-tid=1\fR +.PP +display status of target 1 (see /proc/scsi_tgt/iscsi to get the matching target name) +.PP +\&\fBiscsi-scst-adm \-\-op new \-\-tid=2\fR +.PP +create dynamically a new target, numbered 2. \s-1CAUTION\s0 : the target will disappear if you restart iscsi-scstd, you'll have to edit /etc/iscsi-scstd.conf to make it permanent! +.SH "ERROR MESSAGES" +.IX Header "ERROR MESSAGES" +iscsi-scst-adm misses error messages. Look carefully the \s-1STDERR\s0 output : in case of error +it will send a 3 number error code, ending with \-1, for instance : +.PP +iscsi-scstd_request 203 3 \-1 +.SH "OPTIONS" +.IX Header "OPTIONS" +\&\fB\-\-op new \-\-tid=[id] \-\-params Name=[name]\fR +.PP +add a new target with [id]. [id] must not be zero. +.PP +\&\fB\-\-op delete \-\-tid=[id]\fR +.PP +delete specific target with [id]. The target must +have no active sessions. +.PP +\&\fB\-\-op show \-\-tid=[id]\fR +.PP +show target parameters of target with [id]. +.PP +\&\fB\-\-op show \-\-tid=[id] \-\-sid=[sid]\fR +.PP +show iSCSI parameters in effect for session [sid]. If +[sid] is \*(L"0\*(R" (zero), the configured parameters +will be displayed. +.PP +\&\fB\-\-op delete \-\-tid=[id] \-\-sid=[sid] \-\-cid=[cid]\fR +.PP +delete specific connection with [cid] in a session +with [sid] that the target with [id] has. +If the session has no connections after +the operation, the session will be deleted +automatically. +.PP +\&\fB\-\-op delete\fR +.PP +stop all activity. +.PP +\&\fB\-\-op update \-\-tid=[id] \-\-params=key1=value1,key2=value2,...\fR +.PP +change iSCSI \s-1SCST\s0 target parameters of specific +target with [id]. You can use parameters in iscsi-scstd.conf +as a key. +.PP +\&\fB\-\-op new \-\-tid=[id] \-\-user \-\-params=[user]=[name],Password=[pass]\fR +.PP +add a new account with [pass] for specific target. +[user] could be [IncomingUser] or [OutgoingUser]. +If you don't specify a target (omit \-\-tid option), +you add a new account for discovery sessions. +.PP +\&\fB\-\-op delete \-\-tid=[id] \-\-user \-\-params=[user]=[name]\fR +.PP +delete specific account having [name] of specific +target. [user] could be [IncomingUser] or +[OutgoingUser]. +If you don't specify a target (omit \-\-tid option), +you delete the account for discovery sessions. +.PP +\&\fB\-\-version\fR +.PP +display version and exit +.PP +\&\fB\-\-help\fR +.PP +display a list of available options and exits +.SH "KNOWN ISSUES" +.IX Header "KNOWN ISSUES" +.IP "\(bu" 4 +iscsi-scst-adm doesn't return any human-readable error message, only error codes. +.IP "\(bu" 4 +iscsi-scst-adm doesn't modify or read the /etc/iscsi-scstd.conf iscsi-scstd configuration file. +.IP "\(bu" 4 +iscsi-scst-adm can't use target names or aliases, only the tid found in /proc/scsi_tgt/iscsi. +.IP "\(bu" 4 +/proc/scsi_tgt/iscsi may list inactive sessions if the initiator doesn't logout properly. +.PP +Report bugs to <iscsitarget\-d...@so...>. +.SH "FILES" +.IX Header "FILES" +/proc/scsi_tgt/iscsi +.SH "SEE ALSO" +.IX Header "SEE ALSO" +\&\fIiscsi-scstd\fR\|(8),\fIiscsi-scstd.conf\fR\|(5) +.\"man page written by Emmanuel Florac <ef...@in..." +.\"distributed under GPL v2 licence" Added: trunk/iscsi-scst/doc/manpages/iscsi-scstd.8 =================================================================== --- trunk/iscsi-scst/doc/manpages/iscsi-scstd.8 (rev 0) +++ trunk/iscsi-scst/doc/manpages/iscsi-scstd.8 2007-08-15 09:28:54 UTC (rev 162) @@ -0,0 +1,308 @@ +.\" Process this file with +.\" groff -man -Tascii iscsi-scstd.8 +.\" +.TH "iSCSI SCST Target Daemon" 8 "May 2007" Linux "User Manuals" +.SH NAME +iscsi-scstd \- iSCSI SCST Target Daemon +.SH SYNOPSIS +.B iscsi-scstd +.RB [\| \-c +.IR configfile \|] +.RB [\| \-d +.IR debuglevel \|] +.RB [\| \-f \|] +.RB [\| \-g +.IR GID \|] +.RB [\| \-h \|] +.RB [\| \-a +.IR address \|] +.RB [\| \-p +.IR port \|] +.RB [\| \-s +.IR IP \|] +.RB [\| \-u +.IR UID \|] +.SH DESCRIPTION +The +.B iscsi-scstd +program implements the user level part of iSCSI SCST Target software for building an iSCSI storage system on Linux. +.SH OPTIONS +.TP +.BI \-c\ filename ,\ \-\-config= filename +Specify configuration file, default is +.I /etc/iscsi-scstd.conf +.TP +.BI \-d\ debuglevel ,\ \-\-debug= debuglevel +Turns on debugging. Logging goes to +.I /var/log/syslog +via +.BR syslog (1). +.TP +.BI \-f,\ \-\-foreground +Act as a normal application which uses a console. +.TP +.BI \-g\ GID ,\ \-\-gid= GID +Specify running group id, default is current gid. +.TP +.BI \-a\ address ,\ \-\-address= address +Specify on which local address the server should listen, default is any. +.TP +.BI \-p\ port ,\ \-\-port= port +Specify on which port the server should listen, default is 3260. +.TP +.BI \-h,\ \-\-help +Display help message on command line options. +.TP +.BI \-s\ IP ,\ \-\-isns= IP +isns server's IP address +.TP +.BI \-u\ UID ,\ \-\-uid= UID +Specify running user id, default is current uid. +.SH FILES +.I /etc/iscsi... [truncated message content] |
From: <vl...@us...> - 2007-08-28 17:32:34
|
Revision: 173 http://scst.svn.sourceforge.net/scst/?rev=173&view=rev Author: vlnb Date: 2007-08-28 10:32:31 -0700 (Tue, 28 Aug 2007) Log Message: ----------- - Fixed several iSCSI RFC violations in TM area, added necessary support in the SCST core - Some minor TM handling improvements - Some cleanups Modified Paths: -------------- trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/kernel/iscsi.h trunk/iscsi-scst/kernel/iscsi_hdr.h trunk/scst/include/scsi_tgt.h trunk/scst/src/scst_main.c trunk/scst/src/scst_priv.h trunk/scst/src/scst_targ.c Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2007-08-27 10:49:04 UTC (rev 172) +++ trunk/iscsi-scst/kernel/iscsi.c 2007-08-28 17:32:31 UTC (rev 173) @@ -937,7 +937,7 @@ rsp_hdr = (struct iscsi_r2t_hdr *)&rsp->pdu.bhs; rsp_hdr->opcode = ISCSI_OP_R2T; rsp_hdr->flags = ISCSI_FLG_FINAL; - memcpy(rsp_hdr->lun, cmnd_hdr(req)->lun, 8); + rsp_hdr->lun = cmnd_hdr(req)->lun; rsp_hdr->itt = cmnd_hdr(req)->itt; rsp_hdr->r2t_sn = cpu_to_be32(req->r2t_sn++); rsp_hdr->buffer_offset = cpu_to_be32(offset); @@ -1130,7 +1130,7 @@ TRACE_DBG("scsi command: %02x", req_hdr->scb[0]); scst_cmd = scst_rx_cmd(session->scst_sess, - (uint8_t*)req_hdr->lun, sizeof(req_hdr->lun), + (uint8_t*)&req_hdr->lun, sizeof(req_hdr->lun), req_hdr->scb, sizeof(req_hdr->scb), SCST_NON_ATOMIC); if (scst_cmd == NULL) { create_status_rsp(req, SAM_STAT_BUSY, NULL, 0); @@ -1176,6 +1176,9 @@ break; } + /* cmd_sn is already in CPU format converted in check_cmd_sn() */ + scst_cmd_set_tgt_sn(scst_cmd, req_hdr->cmd_sn); + TRACE_DBG("START Command (tag %d, queue_type %d)", req_hdr->itt, scst_cmd->queue_type); req->scst_state = ISCSI_CMD_STATE_RX_CMD; @@ -1411,27 +1414,57 @@ return res; } -static int cmnd_abort(struct iscsi_session *session, u32 itt) +static int cmnd_abort(struct iscsi_cmnd *req) { + struct iscsi_session *session = req->conn->session; + struct iscsi_task_mgt_hdr *req_hdr = + (struct iscsi_task_mgt_hdr *)&req->pdu.bhs; struct iscsi_cmnd *cmnd; int err; - if ((cmnd = cmnd_find_hash_get(session, itt, ISCSI_RESERVED_TAG))) { + if ((cmnd = cmnd_find_hash_get(session, req_hdr->rtt, ISCSI_RESERVED_TAG))) { struct iscsi_conn *conn = cmnd->conn; + struct iscsi_scsi_cmd_hdr *hdr = cmnd_hdr(cmnd); + + if (req_hdr->lun != hdr->lun) { + PRINT_ERROR_PR("ABORT TASK: LUN mismatch: req LUN " + "%Lx, cmd LUN %Lx, rtt %u", req_hdr->lun, + hdr->lun, req_hdr->rtt); + err = ISCSI_RESPONSE_FUNCTION_REJECTED; + goto out_put; + } + + if (before(req_hdr->cmd_sn, hdr->cmd_sn) || + (req_hdr->cmd_sn == hdr->cmd_sn)) { + PRINT_ERROR_PR("ABORT TASK: SN mismatch: req SN %x, " + "cmd SN %x, rtt %u", req_hdr->cmd_sn, + hdr->cmd_sn, req_hdr->rtt); + err = ISCSI_RESPONSE_FUNCTION_REJECTED; + goto out_put; + } + spin_lock_bh(&conn->cmd_list_lock); __cmnd_abort(cmnd); spin_unlock_bh(&conn->cmd_list_lock); + cmnd_put(cmnd); err = 0; } else err = ISCSI_RESPONSE_UNKNOWN_TASK; +out: return err; + +out_put: + cmnd_put(cmnd); + goto out; } -static int target_abort(struct iscsi_cmnd *req, u16 *lun, int all) +static int target_abort(struct iscsi_cmnd *req, int all) { struct iscsi_target *target = req->conn->session->target; + struct iscsi_task_mgt_hdr *req_hdr = + (struct iscsi_task_mgt_hdr *)&req->pdu.bhs; struct iscsi_session *session; struct iscsi_conn *conn; struct iscsi_cmnd *cmnd; @@ -1448,8 +1481,7 @@ continue; if (all) again = __cmnd_abort(cmnd); - else if (memcmp(lun, &cmnd_hdr(cmnd)->lun, - sizeof(cmnd_hdr(cmnd)->lun)) == 0) + else if (req_hdr->lun == cmnd_hdr(cmnd)->lun) again = __cmnd_abort(cmnd); if (again) goto again; @@ -1465,6 +1497,8 @@ static void task_set_abort(struct iscsi_cmnd *req) { struct iscsi_session *session = req->conn->session; + struct iscsi_task_mgt_hdr *req_hdr = + (struct iscsi_task_mgt_hdr *)&req->pdu.bhs; struct iscsi_target *target = session->target; struct iscsi_conn *conn; struct iscsi_cmnd *cmnd; @@ -1475,9 +1509,16 @@ spin_lock_bh(&conn->cmd_list_lock); again: list_for_each_entry(cmnd, &conn->cmd_list, cmd_list_entry) { - if (cmnd != req) - if (__cmnd_abort(cmnd)) - goto again; + struct iscsi_scsi_cmd_hdr *hdr = cmnd_hdr(cmnd); + if (cmnd == req) + continue; + if (req_hdr->lun != hdr->lun) + continue; + if (before(req_hdr->cmd_sn, hdr->cmd_sn) || + req_hdr->cmd_sn == hdr->cmd_sn) + continue; + if (__cmnd_abort(cmnd)) + goto again; } spin_unlock_bh(&conn->cmd_list_lock); } @@ -1504,61 +1545,91 @@ static void execute_task_management(struct iscsi_cmnd *req) { struct iscsi_conn *conn = req->conn; - struct iscsi_task_mgt_hdr *req_hdr = (struct iscsi_task_mgt_hdr *)&req->pdu.bhs; + struct iscsi_task_mgt_hdr *req_hdr = + (struct iscsi_task_mgt_hdr *)&req->pdu.bhs; int err = 0, function = req_hdr->function & ISCSI_FUNCTION_MASK; + struct scst_rx_mgmt_params params; TRACE(TRACE_MGMT, "TM cmd: req %p, itt %x, fn %d, rtt %x", req, cmnd_itt(req), function, req_hdr->rtt); - /* - * ToDo: relevant TM functions shall affect only commands with - * CmdSN lower req_hdr->cmd_sn (see RFC 3720 section 10.5). - * - * I suppose, iscsi_session_push_cmnd() should be updated to keep - * commands with higher CmdSN in the session->pending_list until - * executing TM command finished. Although, if higher CmdSN commands - * might be already sent to SCST for execution, it could get much more - * complicated and should be implemented on SCST level. - */ + memset(¶ms, 0, sizeof(params)); + params.atomic = SCST_NON_ATOMIC; + params.tgt_priv = req; + + if ((function != ISCSI_FUNCTION_ABORT_TASK) && + (req_hdr->rtt != ISCSI_RESERVED_TAG)) { + PRINT_ERROR_PR("Invalid RTT %x (TM fn %x)", req_hdr->rtt, + function); + err = -1; + goto reject; + } + /* cmd_sn is already in CPU format converted in check_cmd_sn() */ + switch (function) { case ISCSI_FUNCTION_ABORT_TASK: - err = cmnd_abort(conn->session, req_hdr->rtt); + err = cmnd_abort(req); if (err == 0) { - err = scst_rx_mgmt_fn_tag(conn->session->scst_sess, - SCST_ABORT_TASK, req_hdr->rtt, SCST_NON_ATOMIC, - req); + params.fn = SCST_ABORT_TASK; + params.tag = req_hdr->rtt; + params.tag_set = 1; + params.lun = (uint8_t *)&req_hdr->lun; + params.lun_len = sizeof(req_hdr->lun); + params.lun_set = 1; + params.cmd_sn = req_hdr->cmd_sn; + params.cmd_sn_set = 1; + err = scst_rx_mgmt_fn(conn->session->scst_sess, + ¶ms); } break; case ISCSI_FUNCTION_ABORT_TASK_SET: task_set_abort(req); - err = scst_rx_mgmt_fn_lun(conn->session->scst_sess, - SCST_ABORT_TASK_SET, (uint8_t *)req_hdr->lun, - sizeof(req_hdr->lun), SCST_NON_ATOMIC, req); + params.fn = SCST_ABORT_TASK_SET; + params.lun = (uint8_t *)&req_hdr->lun; + params.lun_len = sizeof(req_hdr->lun); + params.lun_set = 1; + params.cmd_sn = req_hdr->cmd_sn; + params.cmd_sn_set = 1; + err = scst_rx_mgmt_fn(conn->session->scst_sess, + ¶ms); break; case ISCSI_FUNCTION_CLEAR_TASK_SET: task_set_abort(req); - err = scst_rx_mgmt_fn_lun(conn->session->scst_sess, - SCST_CLEAR_TASK_SET, (uint8_t *)req_hdr->lun, - sizeof(req_hdr->lun), SCST_NON_ATOMIC, req); + params.fn = SCST_CLEAR_TASK_SET; + params.lun = (uint8_t *)&req_hdr->lun; + params.lun_len = sizeof(req_hdr->lun); + params.lun_set = 1; + params.cmd_sn = req_hdr->cmd_sn; + params.cmd_sn_set = 1; + err = scst_rx_mgmt_fn(conn->session->scst_sess, + ¶ms); break; case ISCSI_FUNCTION_CLEAR_ACA: - err = scst_rx_mgmt_fn_lun(conn->session->scst_sess, - SCST_CLEAR_ACA, (uint8_t *)req_hdr->lun, - sizeof(req_hdr->lun), SCST_NON_ATOMIC, req); + params.fn = SCST_CLEAR_ACA; + params.lun = (uint8_t *)&req_hdr->lun; + params.lun_len = sizeof(req_hdr->lun); + params.lun_set = 1; + params.cmd_sn = req_hdr->cmd_sn; + params.cmd_sn_set = 1; + err = scst_rx_mgmt_fn(conn->session->scst_sess, + ¶ms); break; case ISCSI_FUNCTION_TARGET_COLD_RESET: case ISCSI_FUNCTION_TARGET_WARM_RESET: - target_abort(req, 0, 1); - err = scst_rx_mgmt_fn_lun(conn->session->scst_sess, - SCST_TARGET_RESET, (uint8_t *)req_hdr->lun, - sizeof(req_hdr->lun), SCST_NON_ATOMIC, req); + target_abort(req, 1); + params.fn = SCST_TARGET_RESET; + err = scst_rx_mgmt_fn(conn->session->scst_sess, + ¶ms); break; case ISCSI_FUNCTION_LOGICAL_UNIT_RESET: - target_abort(req, req_hdr->lun, 0); - err = scst_rx_mgmt_fn_lun(conn->session->scst_sess, - SCST_LUN_RESET, (uint8_t *)req_hdr->lun, - sizeof(req_hdr->lun), SCST_NON_ATOMIC, req); + target_abort(req, 0); + params.fn = SCST_LUN_RESET; + params.lun = (uint8_t *)&req_hdr->lun; + params.lun_len = sizeof(req_hdr->lun); + params.lun_set = 1; + err = scst_rx_mgmt_fn(conn->session->scst_sess, + ¶ms); break; case ISCSI_FUNCTION_TASK_REASSIGN: iscsi_send_task_mgmt_resp(req, @@ -1570,6 +1641,7 @@ break; } +reject: if (err != 0) { iscsi_send_task_mgmt_resp(req, ISCSI_RESPONSE_FUNCTION_REJECTED); Modified: trunk/iscsi-scst/kernel/iscsi.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi.h 2007-08-27 10:49:04 UTC (rev 172) +++ trunk/iscsi-scst/kernel/iscsi.h 2007-08-28 17:32:31 UTC (rev 173) @@ -407,12 +407,6 @@ #endif } -#define cmnd_hdr(cmnd) ((struct iscsi_scsi_cmd_hdr *) (&((cmnd)->pdu.bhs))) -#define cmnd_ttt(cmnd) cpu_to_be32((cmnd)->pdu.bhs.ttt) -#define cmnd_itt(cmnd) cpu_to_be32((cmnd)->pdu.bhs.itt) -#define cmnd_opcode(cmnd) ((cmnd)->pdu.bhs.opcode & ISCSI_OPCODE_MASK) -#define cmnd_scsicode(cmnd) cmnd_hdr(cmnd)->scb[0] - extern struct scst_tgt_template iscsi_template; static inline void cmnd_get(struct iscsi_cmnd *cmnd) Modified: trunk/iscsi-scst/kernel/iscsi_hdr.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi_hdr.h 2007-08-27 10:49:04 UTC (rev 172) +++ trunk/iscsi-scst/kernel/iscsi_hdr.h 2007-08-28 17:32:31 UTC (rev 173) @@ -38,7 +38,7 @@ #elif defined(__LITTLE_ENDIAN_BITFIELD) u32 length; /* 4 */ #endif - u16 lun[4]; /* 8 */ + u64 lun; /* 8 */ u32 itt; /* 16 */ u32 ttt; /* 20 */ u32 sn; /* 24 */ @@ -101,7 +101,7 @@ u16 rsvd1; u8 ahslength; u8 datalength[3]; - u16 lun[4]; + u64 lun; u32 itt; u32 data_length; u32 cmd_sn; @@ -170,7 +170,7 @@ u16 rsvd1; u8 ahslength; u8 datalength[3]; - u16 lun[4]; + u64 lun; u32 itt; u32 rtt; u32 cmd_sn; @@ -222,7 +222,7 @@ u16 rsvd1; u8 ahslength; u8 datalength[3]; - u16 lun[4]; + u64 lun; u32 itt; u32 ttt; u32 rsvd2; @@ -259,7 +259,7 @@ u16 rsvd1; u8 ahslength; u8 datalength[3]; - u16 lun[4]; + u64 lun; u32 itt; u32 ttt; u32 stat_sn; @@ -276,7 +276,7 @@ u16 rsvd1; u8 ahslength; u8 datalength[3]; - u16 lun[4]; + u64 lun; u32 ffffffff; u32 rsvd2; u32 stat_sn; @@ -491,7 +491,7 @@ u16 rsvd1; u8 ahslength; u8 datalength[3]; - u16 lun[4]; + u64 lun; u32 itt; u32 ttt; u32 cmd_sn; @@ -505,7 +505,7 @@ u16 rsvd1; u8 ahslength; u8 datalength[3]; - u16 lun[4]; + u64 lun; u32 itt; u32 ttt; u32 stat_sn; @@ -516,4 +516,11 @@ #define ISCSI_RESERVED_TAG (0xffffffffU) +#define cmnd_hdr(cmnd) ((struct iscsi_scsi_cmd_hdr *) (&((cmnd)->pdu.bhs))) +#define cmnd_ttt(cmnd) cpu_to_be32((cmnd)->pdu.bhs.ttt) +#define cmnd_itt(cmnd) cpu_to_be32((cmnd)->pdu.bhs.itt) +#define cmnd_opcode(cmnd) ((cmnd)->pdu.bhs.opcode & ISCSI_OPCODE_MASK) +#define cmnd_scsicode(cmnd) cmnd_hdr(cmnd)->scb[0] + + #endif /* __ISCSI_HDR_H__ */ Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2007-08-27 10:49:04 UTC (rev 172) +++ trunk/scst/include/scsi_tgt.h 2007-08-28 17:32:31 UTC (rev 173) @@ -1056,8 +1056,11 @@ * Set if inc expected_sn in cmd->scst_cmd_done() (to * save extra dereferences) */ - unsigned inc_expected_sn_on_done:1; + unsigned int inc_expected_sn_on_done:1; + /* Set if tgt_sn field is valid */ + unsigned int tgt_sn_set:1; + /**************************************************************/ unsigned long cmd_flags; /* cmd's async flags */ @@ -1095,6 +1098,8 @@ */ uint64_t tag; + uint32_t tgt_sn; /* SN set by target driver (for TM purposes) */ + /* CDB and its len */ uint8_t cdb[SCST_MAX_CDB_SIZE]; int cdb_len; @@ -1167,6 +1172,20 @@ struct scst_cmd *orig_cmd; /* Used to issue REQUEST SENSE */ }; +struct scst_rx_mgmt_params +{ + int fn; + uint64_t tag; + const uint8_t *lun; + int lun_len; + uint32_t cmd_sn; + int atomic; + void *tgt_priv; + unsigned char tag_set; + unsigned char lun_set; + unsigned char cmd_sn_set; +}; + struct scst_mgmt_cmd { /* List entry for *_mgmt_cmd_list */ @@ -1181,6 +1200,10 @@ unsigned int completed:1; /* set, if the mcmd is completed */ unsigned int active:1; /* set, if the mcmd is active */ + /* Set if device(s) should be unblocked after mcmd's finish */ + unsigned int needs_unblocking:1; + unsigned int lun_set:1; /* set, if lun field is valid */ + unsigned int cmd_sn_set:1; /* set, if cmd_sn field is valid */ /* * Number of commands to complete before sending response, @@ -1192,9 +1215,11 @@ int completed_cmd_count; lun_t lun; /* LUN for this mgmt cmd */ - /* or */ + /* or (and for iSCSI) */ uint64_t tag; /* tag of the corresponding cmd */ + uint32_t cmd_sn; /* affected command's highest SN */ + /* corresponding cmd (to be aborted, found by tag) */ struct scst_cmd *cmd_to_abort; @@ -1590,7 +1615,7 @@ /* * Creates and sends new command to SCST. - * Must not been called in parallel with scst_unregister_session() for the + * Must not be called in parallel with scst_unregister_session() for the * same sess. Returns the command on success or NULL otherwise */ struct scst_cmd *scst_rx_cmd(struct scst_session *sess, @@ -1662,24 +1687,62 @@ void scst_tgt_cmd_done(struct scst_cmd *cmd); /* + * Creates new management command sends it for execution. + * Must not be called in parallel with scst_unregister_session() for the + * same sess. Returns 0 for success, error code otherwise. + */ +int scst_rx_mgmt_fn(struct scst_session *sess, + const struct scst_rx_mgmt_params *params); + +/* * Creates new management command using tag and sends it for execution. * Can be used for SCST_ABORT_TASK only. - * Must not been called in parallel with scst_unregister_session() for the + * Must not be called in parallel with scst_unregister_session() for the * same sess. Returns 0 for success, error code otherwise. + * + * Obsolete in favor of scst_rx_mgmt_fn() */ -int scst_rx_mgmt_fn_tag(struct scst_session *sess, int fn, uint64_t tag, - int atomic, void *tgt_priv); +static inline int scst_rx_mgmt_fn_tag(struct scst_session *sess, int fn, + uint64_t tag, int atomic, void *tgt_priv) +{ + struct scst_rx_mgmt_params params; + BUG_ON(fn != SCST_ABORT_TASK); + + memset(¶ms, 0, sizeof(params)); + params.fn = fn; + params.tag = tag; + params.tag_set = 1; + params.atomic = atomic; + params.tgt_priv = tgt_priv; + return scst_rx_mgmt_fn(sess, ¶ms); +} + /* * Creates new management command using LUN and sends it for execution. * Currently can be used for any fn, except SCST_ABORT_TASK. - * Must not been called in parallel with scst_unregister_session() for the + * Must not be called in parallel with scst_unregister_session() for the * same sess. Returns 0 for success, error code otherwise. + * + * Obsolete in favor of scst_rx_mgmt_fn() */ -int scst_rx_mgmt_fn_lun(struct scst_session *sess, int fn, - const uint8_t *lun, int lun_len, - int atomic, void *tgt_priv); +static inline int scst_rx_mgmt_fn_lun(struct scst_session *sess, int fn, + const uint8_t *lun, int lun_len, int atomic, void *tgt_priv) +{ + struct scst_rx_mgmt_params params; + BUG_ON(fn == SCST_ABORT_TASK); + + memset(¶ms, 0, sizeof(params)); + params.fn = fn; + params.lun = lun; + params.lun_len = lun_len; + params.lun_set = 1; + params.atomic = atomic; + params.tgt_priv = tgt_priv; + return scst_rx_mgmt_fn(sess, ¶ms); +} + /* * Provides various CDB info * Parameters: @@ -1992,6 +2055,22 @@ } /* + * Get/Set functions for tgt_sn + */ +static inline int scst_cmd_get_tgt_sn(struct scst_cmd *cmd) +{ + BUG_ON(!cmd->tgt_sn_set); + return cmd->tgt_sn; +} + +static inline void scst_cmd_set_tgt_sn(struct scst_cmd *cmd, uint32_t tgt_sn) +{ + cmd->tgt_sn_set = 1; + cmd->tgt_sn = tgt_sn; +} + + +/* * Returns 1 if the cmd was aborted, so its status is invalid and no * reply shall be sent to the remote initiator. A target driver should * only clear internal resources, associated with cmd. Modified: trunk/scst/src/scst_main.c =================================================================== --- trunk/scst/src/scst_main.c 2007-08-27 10:49:04 UTC (rev 172) +++ trunk/scst/src/scst_main.c 2007-08-28 17:32:31 UTC (rev 173) @@ -1633,8 +1633,7 @@ EXPORT_SYMBOL(scst_restart_cmd); EXPORT_SYMBOL(scst_rx_cmd); EXPORT_SYMBOL(scst_rx_data); -EXPORT_SYMBOL(scst_rx_mgmt_fn_tag); -EXPORT_SYMBOL(scst_rx_mgmt_fn_lun); +EXPORT_SYMBOL(scst_rx_mgmt_fn); EXPORT_SYMBOL(scst_find_cmd); EXPORT_SYMBOL(scst_find_cmd_by_tag); Modified: trunk/scst/src/scst_priv.h =================================================================== --- trunk/scst/src/scst_priv.h 2007-08-27 10:49:04 UTC (rev 172) +++ trunk/scst/src/scst_priv.h 2007-08-28 17:32:31 UTC (rev 173) @@ -558,4 +558,13 @@ static inline void scst_check_debug_sn(struct scst_cmd *cmd) {} #endif +/* + * It deals with comparing 32 bit unsigned ints and worry about wraparound + * (automatic with unsigned arithmetic). Borrowed from net/tcp.h. + */ +static inline int scst_sn_before(__u32 seq1, __u32 seq2) +{ + return (__s32)(seq1-seq2) < 0; +} + #endif /* __SCST_PRIV_H */ Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2007-08-27 10:49:04 UTC (rev 172) +++ trunk/scst/src/scst_targ.c 2007-08-28 17:32:31 UTC (rev 173) @@ -49,7 +49,7 @@ } /* - * Must not been called in parallel with scst_unregister_session() for the + * Must not be called in parallel with scst_unregister_session() for the * same sess */ struct scst_cmd *scst_rx_cmd(struct scst_session *sess, @@ -3397,8 +3397,15 @@ search_cmd_list_entry) { if ((cmd->tgt_dev == tgt_dev) || ((cmd->tgt_dev == NULL) && - (cmd->lun == tgt_dev->lun))) + (cmd->lun == tgt_dev->lun))) { + if (mcmd->cmd_sn_set) { + sBUG_ON(!cmd->tgt_sn_set); + if (scst_sn_before(mcmd->cmd_sn, cmd->tgt_sn) || + (mcmd->cmd_sn == cmd->tgt_sn)) + continue; + } scst_abort_cmd(cmd, mcmd, other_ini, 0); + } } spin_unlock_irq(&sess->sess_list_lock); @@ -3418,6 +3425,8 @@ TRACE(TRACE_MGMT, "Aborting task set (lun=%Ld, mcmd=%p)", tgt_dev->lun, mcmd); + mcmd->needs_unblocking = 1; + spin_lock_bh(&dev->dev_lock); __scst_block_dev(dev); spin_unlock_bh(&dev->dev_lock); @@ -3452,7 +3461,7 @@ * >0, if it should be requeued, <0 otherwise */ static int scst_mgmt_cmd_init(struct scst_mgmt_cmd *mcmd) { - int res = 0; + int res = 0, rc; TRACE_ENTRY(); @@ -3460,7 +3469,11 @@ if (res != 0) goto out; - if (mcmd->fn == SCST_ABORT_TASK) { + mcmd->state = SCST_MGMT_CMD_STATE_READY; + + switch (mcmd->fn) { + case SCST_ABORT_TASK: + { struct scst_session *sess = mcmd->sess; struct scst_cmd *cmd; @@ -3479,23 +3492,43 @@ TRACE(TRACE_MGMT, "Cmd %p for tag %llu (sn %ld) found, " "aborting it", cmd, mcmd->tag, cmd->sn); mcmd->cmd_to_abort = cmd; - scst_abort_cmd(cmd, mcmd, 0, 1); - scst_unblock_aborted_cmds(0); + if (mcmd->lun_set && (mcmd->lun != cmd->lun)) { + PRINT_ERROR_PR("ABORT TASK: LUN mismatch: mcmd LUN %Lx, " + "cmd LUN %Lx, cmd tag %Lu", mcmd->lun, cmd->lun, + mcmd->tag); + mcmd->status = SCST_MGMT_STATUS_REJECTED; + } else if (mcmd->cmd_sn_set && + (scst_sn_before(mcmd->cmd_sn, cmd->tgt_sn) || + (mcmd->cmd_sn == cmd->tgt_sn))) { + PRINT_ERROR_PR("ABORT TASK: SN mismatch: mcmd SN %x, " + "cmd SN %x, cmd tag %Lu", mcmd->cmd_sn, + cmd->tgt_sn, mcmd->tag); + mcmd->status = SCST_MGMT_STATUS_REJECTED; + } else { + scst_abort_cmd(cmd, mcmd, 0, 1); + scst_unblock_aborted_cmds(0); + } res = scst_set_mcmd_next_state(mcmd); mcmd->cmd_to_abort = NULL; /* just in case */ scst_cmd_put(cmd); - } else { - int rc; + break; + } + + case SCST_TARGET_RESET: + case SCST_ABORT_ALL_TASKS: + case SCST_NEXUS_LOSS: + break; + + default: rc = scst_mgmt_translate_lun(mcmd); if (rc < 0) { PRINT_ERROR_PR("Corresponding device for lun %Ld not " "found", (uint64_t)mcmd->lun); mcmd->status = SCST_MGMT_STATUS_LUN_NOT_EXIST; mcmd->state = SCST_MGMT_CMD_STATE_DONE; - } else if (rc == 0) - mcmd->state = SCST_MGMT_CMD_STATE_READY; - else + } else if (rc != 0) res = rc; + break; } out: @@ -3517,6 +3550,8 @@ TRACE(TRACE_MGMT, "Target reset (mcmd %p, cmd count %d)", mcmd, atomic_read(&mcmd->sess->sess_cmd_count)); + mcmd->needs_unblocking = 1; + mutex_lock(&scst_mutex); list_for_each_entry(dev, &scst_dev_list, dev_list_entry) { @@ -3603,6 +3638,8 @@ TRACE(TRACE_MGMT, "Resetting lun %Ld (mcmd %p)", tgt_dev->lun, mcmd); + mcmd->needs_unblocking = 1; + spin_lock_bh(&dev->dev_lock); __scst_block_dev(dev); scst_process_reset(dev, mcmd->sess, NULL, mcmd); @@ -3648,6 +3685,8 @@ mcmd); } + mcmd->needs_unblocking = 1; + mutex_lock(&scst_mutex); for(i = 0; i < TGT_DEV_HASH_SIZE; i++) { struct list_head *sess_tgt_dev_list_head = @@ -3699,6 +3738,8 @@ mcmd); } + mcmd->needs_unblocking = 1; + mutex_lock(&scst_mutex); list_for_each_entry(dev, &scst_dev_list, dev_list_entry) { @@ -3828,7 +3869,7 @@ mcmd->sess->tgt->tgtt->name); } - if (mcmd->mcmd_tgt_dev != NULL) { + if (mcmd->needs_unblocking) { switch (mcmd->fn) { case SCST_ABORT_TASK_SET: case SCST_CLEAR_TASK_SET: @@ -3864,8 +3905,8 @@ break; } - case SCST_CLEAR_ACA: default: + sBUG(); break; } } @@ -4085,74 +4126,51 @@ } /* - * Must not been called in parallel with scst_unregister_session() for the + * Must not be called in parallel with scst_unregister_session() for the * same sess */ -int scst_rx_mgmt_fn_lun(struct scst_session *sess, int fn, - const uint8_t *lun, int lun_len, int atomic, - void *tgt_priv) +int scst_rx_mgmt_fn(struct scst_session *sess, + const struct scst_rx_mgmt_params *params) { int res = -EFAULT; struct scst_mgmt_cmd *mcmd = NULL; TRACE_ENTRY(); - if (unlikely(fn == SCST_ABORT_TASK)) { - PRINT_ERROR_PR("%s() for ABORT TASK called", __FUNCTION__); - res = -EINVAL; - goto out; + switch (params->fn) { + case SCST_ABORT_TASK: + sBUG_ON(!params->tag_set); + break; + case SCST_TARGET_RESET: + case SCST_ABORT_ALL_TASKS: + case SCST_NEXUS_LOSS: + break; + default: + sBUG_ON(!params->lun_set); } - mcmd = scst_pre_rx_mgmt_cmd(sess, fn, atomic, tgt_priv); + mcmd = scst_pre_rx_mgmt_cmd(sess, params->fn, params->atomic, + params->tgt_priv); if (mcmd == NULL) goto out; - mcmd->lun = scst_unpack_lun(lun, lun_len); - if (mcmd->lun == (lun_t)-1) - goto out_free; - - TRACE(TRACE_MGMT, "sess=%p, lun=%Ld", sess, (uint64_t)mcmd->lun); - - if (scst_post_rx_mgmt_cmd(sess, mcmd) != 0) - goto out_free; - - res = 0; - -out: - TRACE_EXIT_RES(res); - return res; - -out_free: - scst_free_mgmt_cmd(mcmd); - mcmd = NULL; - goto out; -} - -/* - * Must not been called in parallel with scst_unregister_session() for the - * same sess - */ -int scst_rx_mgmt_fn_tag(struct scst_session *sess, int fn, uint64_t tag, - int atomic, void *tgt_priv) -{ - int res = -EFAULT; - struct scst_mgmt_cmd *mcmd = NULL; - - TRACE_ENTRY(); - - if (unlikely(fn != SCST_ABORT_TASK)) { - PRINT_ERROR_PR("%s(%d) called", __FUNCTION__, fn); - res = -EINVAL; - goto out; + if (params->lun_set) { + mcmd->lun = scst_unpack_lun(params->lun, params->lun_len); + if (mcmd->lun == (lun_t)-1) + goto out_free; + mcmd->lun_set = 1; } - mcmd = scst_pre_rx_mgmt_cmd(sess, fn, atomic, tgt_priv); - if (mcmd == NULL) - goto out; + if (params->tag_set) + mcmd->tag = params->tag; - mcmd->tag = tag; + mcmd->cmd_sn_set = params->cmd_sn_set; + mcmd->cmd_sn = params->cmd_sn; - TRACE(TRACE_MGMT, "sess=%p, tag=%llu", sess, mcmd->tag); + TRACE(TRACE_MGMT, "sess=%p, fn %x, tag_set %d, tag %Ld, lun_set %d, " + "lun=%Ld, cmd_sn_set %d, cmd_sn %x", sess, params->fn, + params->tag_set, params->tag, params->lun_set, + (uint64_t)mcmd->lun, params->cmd_sn_set, params->cmd_sn); if (scst_post_rx_mgmt_cmd(sess, mcmd) != 0) goto out_free; @@ -4354,7 +4372,7 @@ } /* - * Must not been called in parallel with scst_rx_cmd() or + * Must not be called in parallel with scst_rx_cmd() or * scst_rx_mgmt_fn_*() for the same sess */ void scst_unregister_session(struct scst_session *sess, int wait, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2007-09-25 09:21:11
|
Revision: 193 http://scst.svn.sourceforge.net/scst/?rev=193&view=rev Author: vlnb Date: 2007-09-25 02:20:30 -0700 (Tue, 25 Sep 2007) Log Message: ----------- - Patch from Krzysztof Blaszkowski <kb...@sy...>: fixes possible active_pages_total corruption in scst_free() if use_clustering was enabled in scst_alloc(). - Now scst_alloc() always doesn't use clustering. Modified Paths: -------------- trunk/iscsi-scst/kernel/iscsi.c trunk/scst/include/scsi_tgt.h trunk/scst/src/scst_mem.c Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2007-09-25 09:17:16 UTC (rev 192) +++ trunk/iscsi-scst/kernel/iscsi.c 2007-09-25 09:20:30 UTC (rev 193) @@ -542,7 +542,7 @@ if (status == SAM_STAT_CHECK_CONDITION) { TRACE_DBG("%s", "CHECK_CONDITION"); /* ToDo: __GFP_NOFAIL ?? */ - sg = rsp->sg = scst_alloc(PAGE_SIZE, GFP_KERNEL|__GFP_NOFAIL, 0, + sg = rsp->sg = scst_alloc(PAGE_SIZE, GFP_KERNEL|__GFP_NOFAIL, &rsp->sg_cnt); if (sg == NULL) { /* ToDo(); */ @@ -601,7 +601,7 @@ rsp_hdr->reason = reason; /* ToDo: __GFP_NOFAIL ?? */ - sg = rsp->sg = scst_alloc(PAGE_SIZE, GFP_KERNEL|__GFP_NOFAIL, 0, + sg = rsp->sg = scst_alloc(PAGE_SIZE, GFP_KERNEL|__GFP_NOFAIL, &rsp->sg_cnt); if (sg == NULL) { /* ToDo(); */ @@ -791,7 +791,7 @@ if (sg == NULL) { /* ToDo: __GFP_NOFAIL ?? */ sg = cmnd->sg = scst_alloc(PAGE_SIZE, GFP_KERNEL|__GFP_NOFAIL, - 0, &cmnd->sg_cnt); + &cmnd->sg_cnt); if (sg == NULL) { /* ToDo(); */ } @@ -1061,7 +1061,7 @@ /* ToDo: __GFP_NOFAIL ?? */ cmnd->sg = sg = scst_alloc(size, - GFP_KERNEL|__GFP_NOFAIL, 0, &cmnd->sg_cnt); + GFP_KERNEL|__GFP_NOFAIL, &cmnd->sg_cnt); if (sg == NULL) { /* ToDo(); */ } Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2007-09-25 09:17:16 UTC (rev 192) +++ trunk/scst/include/scsi_tgt.h 2007-09-25 09:20:30 UTC (rev 193) @@ -2339,12 +2339,10 @@ /* * Allocates and returns pointer to SG vector with data size "size". - * If use_clustering is not 0, segments in the vector will be merged, - * when possible. In *count returned the count of entries in the vector. + * In *count returned the count of entries in the vector. * Returns NULL for failure. */ -struct scatterlist *scst_alloc(int size, unsigned long gfp_mask, - int use_clustering, int *count); +struct scatterlist *scst_alloc(int size, unsigned long gfp_mask, int *count); /* Frees SG vector returned by scst_alloc() */ void scst_free(struct scatterlist *sg, int count); Modified: trunk/scst/src/scst_mem.c =================================================================== --- trunk/scst/src/scst_mem.c 2007-09-25 09:17:16 UTC (rev 192) +++ trunk/scst/src/scst_mem.c 2007-09-25 09:20:30 UTC (rev 193) @@ -735,8 +735,7 @@ return; } -struct scatterlist *scst_alloc(int size, unsigned long gfp_mask, - int use_clustering, int *count) +struct scatterlist *scst_alloc(int size, unsigned long gfp_mask, int *count) { struct scatterlist *res; int pages = (size >> PAGE_SHIFT) + ((size & ~PAGE_MASK) != 0); @@ -757,8 +756,13 @@ if (res == NULL) goto out; - *count = scst_alloc_sg_entries(res, pages, gfp_mask, use_clustering, - NULL, &sys_alloc_fns, NULL); + /* + * If we allow use clustering here, we will have troubles in + * scst_free() to figure out how many pages are in the SG vector. + * So, always don't use clustering. + */ + *count = scst_alloc_sg_entries(res, pages, gfp_mask, 0, NULL, + &sys_alloc_fns, NULL); if (*count <= 0) goto out_free; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2007-09-25 09:30:17
|
Revision: 194 http://scst.svn.sourceforge.net/scst/?rev=194&view=rev Author: vlnb Date: 2007-09-25 02:30:12 -0700 (Tue, 25 Sep 2007) Log Message: ----------- - Docs updated - Switches debug<->performance<->release builds added - Cosmetics A trunk/usr-full_perf.patch M trunk/iscsi-scst/README A trunk/iscsi-full_perf.patch A trunk/debug2perf A trunk/perf2debug A trunk/usr-release.patch A trunk/qla2x00t-full_perf.patch A trunk/iscsi-release.patch A trunk/scst-full_perf.patch A trunk/qla2x00t-release.patch A trunk/scst-release.patch A trunk/README A trunk/usr/fileio/README A trunk/debug2release A trunk/release2debug M trunk/scst/src/scst_lib.c M trunk/scst/src/scst_mem.c M trunk/scst/README M trunk/Makefile Modified Paths: -------------- trunk/Makefile trunk/iscsi-scst/README trunk/scst/README trunk/scst/src/scst_lib.c trunk/scst/src/scst_mem.c Added Paths: ----------- trunk/README trunk/debug2perf trunk/debug2release trunk/iscsi-full_perf.patch trunk/iscsi-release.patch trunk/perf2debug trunk/qla2x00t-full_perf.patch trunk/qla2x00t-release.patch trunk/release2debug trunk/scst-full_perf.patch trunk/scst-release.patch trunk/usr/fileio/README trunk/usr-full_perf.patch trunk/usr-release.patch Modified: trunk/Makefile =================================================================== --- trunk/Makefile 2007-09-25 09:20:30 UTC (rev 193) +++ trunk/Makefile 2007-09-25 09:30:12 UTC (rev 194) @@ -63,7 +63,7 @@ @echo " usr_extraclean : usr target: clean + clean dependencies" @echo " usr_install : usr target: install" @echo " usr_uninstall : usr target: uninstall" - + @echo "" @echo " Note:" @echo " - install and uninstall may need root privileges" Added: trunk/README =================================================================== --- trunk/README (rev 0) +++ trunk/README 2007-09-25 09:30:12 UTC (rev 194) @@ -0,0 +1,25 @@ +This is the SCST development repository. It contains not a single +project SCST as one can think, but a number of them, which are divided +as the following: + +1. SCST core in scst/ subdirectory + +2. Target drivers in own subdirectories qla2x00t/, iscsi-scst/, etc. + +3. User space programs in usr/ subdirectory, like fileio_tgt. + +4. Some various docs in doc/ subdirectory. + +Those subprojects are in most cases independent from each other, +although some of them depend from the SCST core. They put in the single +repository only to simplify their development, they are released +independently. + +Thus, use "make all" only if you really need to build everything. +Otherwise build only what you need, like for iSCSI-SCST: + +make scst scst_install iscsi iscsi_install + +For more information about each subproject see their README files. + +Vladislav Bolkhovitin <vs...@vl...>, http://scst.sourceforge.net Added: trunk/debug2perf =================================================================== --- trunk/debug2perf (rev 0) +++ trunk/debug2perf 2007-09-25 09:30:12 UTC (rev 194) @@ -0,0 +1,8 @@ +#!/bin/bash + +echo "Changing current debug state from full debug to full performance" + +patch -p0 <scst-full_perf.patch && \ +patch -p0 <usr-full_perf.patch && \ +patch -p0 <qla2x00t-full_perf.patch && \ +patch -p0 <iscsi-full_perf.patch Added: trunk/debug2release =================================================================== --- trunk/debug2release (rev 0) +++ trunk/debug2release 2007-09-25 09:30:12 UTC (rev 194) @@ -0,0 +1,8 @@ +#!/bin/bash + +echo "Changing current debug state from full debug to release" + +patch -p0 <scst-release.patch && \ +patch -p0 <usr-release.patch && \ +patch -p0 <qla2x00t-release.patch && \ +patch -p0 <iscsi-release.patch Added: trunk/iscsi-full_perf.patch =================================================================== --- trunk/iscsi-full_perf.patch (rev 0) +++ trunk/iscsi-full_perf.patch 2007-09-25 09:30:12 UTC (rev 194) @@ -0,0 +1,16 @@ +Index: iscsi-scst/kernel/Makefile +=================================================================== +--- iscsi-scst/kernel/Makefile (revision 324) ++++ iscsi-scst/kernel/Makefile (working copy) +@@ -26,9 +26,9 @@ SCST_INC_DIR := $(SUBDIRS)/../../scst/in + EXTRA_CFLAGS += -I$(src)/../include -I$(SCST_INC_DIR) + # -Wextra -Wno-unused-parameter + +-EXTRA_CFLAGS += -DEXTRACHECKS ++#EXTRA_CFLAGS += -DEXTRACHECKS + #EXTRA_CFLAGS += -DTRACING +-EXTRA_CFLAGS += -DDEBUG -g ++#EXTRA_CFLAGS += -DDEBUG -g + + #EXTRA_CFLAGS += -DDEBUG_DIGEST_FAILURES + Added: trunk/iscsi-release.patch =================================================================== --- trunk/iscsi-release.patch (rev 0) +++ trunk/iscsi-release.patch 2007-09-25 09:30:12 UTC (rev 194) @@ -0,0 +1,17 @@ +Index: iscsi-scst/kernel/Makefile +=================================================================== +--- iscsi-scst/kernel/Makefile (revision 324) ++++ iscsi-scst/kernel/Makefile (working copy) +@@ -26,9 +26,9 @@ SCST_INC_DIR := $(SUBDIRS)/../../scst/in + EXTRA_CFLAGS += -I$(src)/../include -I$(SCST_INC_DIR) + # -Wextra -Wno-unused-parameter + +-EXTRA_CFLAGS += -DEXTRACHECKS +-#EXTRA_CFLAGS += -DTRACING +-EXTRA_CFLAGS += -DDEBUG -g ++#EXTRA_CFLAGS += -DEXTRACHECKS ++EXTRA_CFLAGS += -DTRACING ++#EXTRA_CFLAGS += -DDEBUG -g + + #EXTRA_CFLAGS += -DDEBUG_DIGEST_FAILURES + Modified: trunk/iscsi-scst/README =================================================================== --- trunk/iscsi-scst/README 2007-09-25 09:20:30 UTC (rev 193) +++ trunk/iscsi-scst/README 2007-09-25 09:30:12 UTC (rev 194) @@ -35,35 +35,49 @@ To use full power of TCP zero-copy transmit functions, especially dealing with user space supplied via scst_user module memory, iSCSI-SCST needs to be notified when Linux networking finished data transmission. -Patch put_page_callback.patch provides such functionality. The -corresponding version of it should be applied on your kernel. This is -highly recommended, but not required. If it isn't applied, iSCSI-SCST -will work in the performance degraded mode, when for data transmission: +Patch put_page_callback-<kernel-version>.patch provides such +functionality. The corresponding version of it should be applied on your +kernel. This is highly recommended, but not required. Basically, you +should consider using of this patch as some optimization, which IET +doesn't have, so if you don't use it, you will just revert to the +original IET behavior, when for data transmission: - For in-kernel allocated memory (scst_vdisk and pass-through handlers) usage of SGV cache on transmit path (READ-type commands) - will be disabled. The performance hit will be not big, performance + will be disabled. The performance hit will be not big, but performance will still remain better, than for IET, because SGV cache will remain used on receive path and IET doesn't have such feature. - For user space allocated memory (scst_user handler) all transmitted data will be additionally copied into temporary TCP buffers. The - performance hit will be quite noticiable. - -If you need your own version of put_page_callback.patch for your custom -kernel, for which there is no prepared version, you can create it -yourself. For that it is only necessary: + performance hit will be quite noticeable. -1. Apply the closest version of put_page_callback.patch on your kernel. -Resolve only failed hanks from include/ and net/core/utils.c, ignore -other failures. +If you have error messages like: -2. Grep net/ and replace everywhere, except in net/sunrpc/svc.c and -net/core/pktgen.c, put_page() by net_put_page() and get_page() by -net_get_page(). +iscsi-scst: ***ERROR*** net_priv isn't NULL and != ref_cmd -That's all. +with the corresponding kernel BUG dump, then put_page_callback patch you +use isn't sufficient for your kernel. This might be because the kernel +you use has some additional patches applied, which affect the +functionality, which put_page_callback patch provides. For example, +Fedora or Gentoo use kernels, which, although have version number like +2.6.18, are greatly differ from the "vanilla" kernel 2.6.18, +maintained by Linus Torvalds for that the put_page_callback patch was +created. In this case I would recommend you either: + - Search net/ in your kernel source for "put_page" and "get_page" functions. + If you find any in some place, except in net/sunrpc/svc.c and + net/core/pktgen.c, then, most likely, you found the reason of your + problem. Replace them by "net_put_page" and "net_get_page" + correspondingly and try again. If the problem is solved, then please + prepare a new put_page_callback patch and send it to the SCST mailing + list scs...@li.... + +or + + - Unapply this patch and use iSCSI-SCST without it. Also report this + problem to the SCST mailing list scs...@li.... + Usage ----- @@ -71,9 +85,9 @@ iscsi-scstd.conf. All LUN information is configured using the regular SCST interface. The LUN information in iscsi-scstd.conf will be ignored. This is because now responsibilities are divided (as it should be) -between the target driver (iSCSI-SCST) and the SCST core. The target -driver is responsible for handling targets and their parameters, SCST -core is responsible for handling backstorage. +between the target driver (iSCSI-SCST) and the SCST core as it logically +should be: the target driver is responsible for handling targets and +their parameters, SCST core is responsible for handling backstorage. If you need to configure different LUs for different targets you should create for each target group "Default_target_name", where target name @@ -98,6 +112,26 @@ - DEBUG_DIGEST_FAILURES - simulates digest failures in random places. +Creating version of put_page_callback patch for your kernel +----------------------------------------------------------- + +If you need your own version of put_page_callback patch for your custom +kernel, for which there is no prepared version, you can create it +yourself. This is pretty mechanical work, you don't need to understand +how it works, you only need to do the following two steps: + +1. Apply the closest version of put_page_callback-<kernel-version>.patch +on your kernel. Resolve only failed hanks from include/ and +net/core/utils.c, ignore other failures. + +2. Search net/ in your kernel source for "put_page" and "get_page" +functions. Replace them by "net_put_page" and "net_get_page" +correspondingly. + +That's all. Then please send your new +put_page_callback-<kernel-version>.patch to the SCST mailing list +sc...@li.... + Credits ------- Added: trunk/perf2debug =================================================================== --- trunk/perf2debug (rev 0) +++ trunk/perf2debug 2007-09-25 09:30:12 UTC (rev 194) @@ -0,0 +1,8 @@ +#!/bin/bash + +echo "Changing current debug state from full performance to full debug" + +patch -p0 -R <scst-full_perf.patch && \ +patch -p0 -R <usr-full_perf.patch && \ +patch -p0 -R <qla2x00t-full_perf.patch && \ +patch -p0 -R <iscsi-full_perf.patch Added: trunk/qla2x00t-full_perf.patch =================================================================== --- trunk/qla2x00t-full_perf.patch (rev 0) +++ trunk/qla2x00t-full_perf.patch 2007-09-25 09:30:12 UTC (rev 194) @@ -0,0 +1,17 @@ +Index: qla2x00t/qla2x00-target/Makefile +=================================================================== +--- qla2x00t/qla2x00-target/Makefile (revision 324) ++++ qla2x00t/qla2x00-target/Makefile (working copy) +@@ -35,10 +35,10 @@ INSTALL_DIR := /lib/modules/$(shell unam + + EXTRA_CFLAGS += -I$(SCST_INC_DIR) -DFC_TARGET_SUPPORT -Wextra -Wno-unused-parameter + +-EXTRA_CFLAGS += -DEXTRACHECKS ++#EXTRA_CFLAGS += -DEXTRACHECKS + #EXTRA_CFLAGS += -DTRACING + +-EXTRA_CFLAGS += -DDEBUG_TGT -g ++#EXTRA_CFLAGS += -DDEBUG_TGT -g + #EXTRA_CFLAGS += -DDEBUG_WORK_IN_THREAD + #EXTRA_CFLAGS += -DDEBUG_SRR + Added: trunk/qla2x00t-release.patch =================================================================== --- trunk/qla2x00t-release.patch (rev 0) +++ trunk/qla2x00t-release.patch 2007-09-25 09:30:12 UTC (rev 194) @@ -0,0 +1,18 @@ +Index: qla2x00t/qla2x00-target/Makefile +=================================================================== +--- qla2x00t/qla2x00-target/Makefile (revision 324) ++++ qla2x00t/qla2x00-target/Makefile (working copy) +@@ -35,10 +35,10 @@ INSTALL_DIR := /lib/modules/$(shell unam + + EXTRA_CFLAGS += -I$(SCST_INC_DIR) -DFC_TARGET_SUPPORT -Wextra -Wno-unused-parameter + +-EXTRA_CFLAGS += -DEXTRACHECKS +-#EXTRA_CFLAGS += -DTRACING ++#EXTRA_CFLAGS += -DEXTRACHECKS ++EXTRA_CFLAGS += -DTRACING + +-EXTRA_CFLAGS += -DDEBUG_TGT -g ++#EXTRA_CFLAGS += -DDEBUG_TGT -g + #EXTRA_CFLAGS += -DDEBUG_WORK_IN_THREAD + #EXTRA_CFLAGS += -DDEBUG_SRR + Added: trunk/release2debug =================================================================== --- trunk/release2debug (rev 0) +++ trunk/release2debug 2007-09-25 09:30:12 UTC (rev 194) @@ -0,0 +1,8 @@ +#!/bin/bash + +echo "Changing current debug state from release to full debug" + +patch -p0 -R <scst-release.patch && \ +patch -p0 -R <usr-release.patch && \ +patch -p0 -R <qla2x00t-release.patch && \ +patch -p0 -R <iscsi-release.patch Modified: trunk/scst/README =================================================================== --- trunk/scst/README 2007-09-25 09:20:30 UTC (rev 193) +++ trunk/scst/README 2007-09-25 09:30:12 UTC (rev 194) @@ -509,14 +509,13 @@ ------------------------------------------- User space program fileio_tgt uses interface of scst_user dev handler -and allows to see how it work in various modes. Fileio_tgt provides -mostly the same functionality as scst_vdisk handler with the only -exceptions that it has implemented O_DIRECT mode and doesn't support -BLOCKIO one. O_DIRECT mode is basically the same as BLOCKIO, but also -supports files, so for some loads it could be significantly faster, than -regular FILEIO access. All the words about BLOCKIO from above apply to -O_DIRECT as well. While running fileio_tgt if you don't understand some -its options, use defaults for them, those values are the fastest. +and allows to see how it works in various modes. Fileio_tgt provides +mostly the same functionality as scst_vdisk handler with the most +noticeable difference that it supports O_DIRECT mode. O_DIRECT mode is +basically the same as BLOCKIO, but also supports files, so for some +loads it could be significantly faster, than the regular FILEIO access. +All the words about BLOCKIO from above apply to O_DIRECT as well. See +fileio_tgt's README file for more details. Performance ----------- @@ -550,8 +549,11 @@ IMPORTANT: Some of the compilation options enabled by default, i.e. SCST ========= is optimized currently rather for development and bug hunting, - not for performance. + than for performance. +If you use SCST version taken directly from its SVN repository, you can +set the above options using debug2perf script file. + 4. For kernel: - Don't enable debug/hacking features, i.e. use them as they are by Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2007-09-25 09:20:30 UTC (rev 193) +++ trunk/scst/src/scst_lib.c 2007-09-25 09:30:12 UTC (rev 194) @@ -90,8 +90,7 @@ TRACE_ENTRY(); - if ((c <= 1) || (cmd->sess->init_phase != SCST_SESS_IPH_READY)) - { + if ((c <= 1) || (cmd->sess->init_phase != SCST_SESS_IPH_READY)) { scst_set_cmd_error_status(cmd, SAM_STAT_BUSY); TRACE_MGMT_DBG("Sending BUSY status to initiator %s " "(cmds count %d, queue_type %x, sess->init_phase %d)", Modified: trunk/scst/src/scst_mem.c =================================================================== --- trunk/scst/src/scst_mem.c 2007-09-25 09:20:30 UTC (rev 193) +++ trunk/scst/src/scst_mem.c 2007-09-25 09:30:12 UTC (rev 194) @@ -425,7 +425,7 @@ return 1; } -/* Called under pool_mgr_lock held, but drops/reaquire it inside */ +/* Called under pool_mgr_lock held, but drops/reaquires it inside */ static int sgv_pool_oom_free_objs(int pgs) { TRACE_MEM("Shrinking pools about %d pages", pgs); @@ -478,10 +478,11 @@ "memory for being executed commands " "exceeds allowed maximum %dMB, " "should you increase scst_max_cmd_mem " - "(requested %d pages)? (This message " - "will be shown only the first 100 " - "times)", sgv_pools_mgr.mgr.thr.hi_wmk >> - (20-PAGE_SHIFT), pages_to_alloc); + "(requested %d pages)? (This warning " + "will be shown only %d more times)", + sgv_pools_mgr.mgr.thr.hi_wmk >> + (20-PAGE_SHIFT), pages_to_alloc, + 100-q); } sgv_pools_mgr.mgr.thr.releases_failed++; res = -ENOMEM; Added: trunk/scst-full_perf.patch =================================================================== --- trunk/scst-full_perf.patch (rev 0) +++ trunk/scst-full_perf.patch 2007-09-25 09:30:12 UTC (rev 194) @@ -0,0 +1,37 @@ +Index: scst/src/Makefile +=================================================================== +--- scst/src/Makefile (revision 324) ++++ scst/src/Makefile (working copy) +@@ -114,13 +114,13 @@ EXTRA_CFLAGS += -I$(SCST_INC_DIR) -Wextr + + #EXTRA_CFLAGS += -DSTRICT_SERIALIZING + +-EXTRA_CFLAGS += -DEXTRACHECKS ++#EXTRA_CFLAGS += -DEXTRACHECKS + + #EXTRA_CFLAGS += -fno-inline + + #EXTRA_CFLAGS += -DTRACING + +-EXTRA_CFLAGS += -DDEBUG -g ++#EXTRA_CFLAGS += -DDEBUG -g + #EXTRA_CFLAGS += -DDEBUG_TM -DTM_DBG_GO_OFFLINE=0 + #EXTRA_CFLAGS += -DDEBUG_RETRY + #EXTRA_CFLAGS += -DDEBUG_OOM +Index: scst/src/dev_handlers/Makefile +=================================================================== +--- scst/src/dev_handlers/Makefile (revision 324) ++++ scst/src/dev_handlers/Makefile (working copy) +@@ -68,10 +68,10 @@ endif + + EXTRA_CFLAGS += -I$(SUBDIRS) -I$(SCST_INC_DIR) -Wextra -Wno-unused-parameter + +-EXTRA_CFLAGS += -DEXTRACHECKS ++#EXTRA_CFLAGS += -DEXTRACHECKS + + #EXTRA_CFLAGS += -DTRACING +-EXTRA_CFLAGS += -DDEBUG -g ++#EXTRA_CFLAGS += -DDEBUG -g + + clean: + rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend Modules.symvers Module.symvers Added: trunk/scst-release.patch =================================================================== --- trunk/scst-release.patch (rev 0) +++ trunk/scst-release.patch 2007-09-25 09:30:12 UTC (rev 194) @@ -0,0 +1,39 @@ +Index: scst/src/Makefile +=================================================================== +--- scst/src/Makefile (revision 324) ++++ scst/src/Makefile (working copy) +@@ -114,13 +114,13 @@ EXTRA_CFLAGS += -I$(SCST_INC_DIR) -Wextr + + #EXTRA_CFLAGS += -DSTRICT_SERIALIZING + +-EXTRA_CFLAGS += -DEXTRACHECKS ++#EXTRA_CFLAGS += -DEXTRACHECKS + + #EXTRA_CFLAGS += -fno-inline + +-#EXTRA_CFLAGS += -DTRACING ++EXTRA_CFLAGS += -DTRACING + +-EXTRA_CFLAGS += -DDEBUG -g ++#EXTRA_CFLAGS += -DDEBUG -g + #EXTRA_CFLAGS += -DDEBUG_TM -DTM_DBG_GO_OFFLINE=0 + #EXTRA_CFLAGS += -DDEBUG_RETRY + #EXTRA_CFLAGS += -DDEBUG_OOM +Index: scst/src/dev_handlers/Makefile +=================================================================== +--- scst/src/dev_handlers/Makefile (revision 324) ++++ scst/src/dev_handlers/Makefile (working copy) +@@ -68,10 +68,10 @@ endif + + EXTRA_CFLAGS += -I$(SUBDIRS) -I$(SCST_INC_DIR) -Wextra -Wno-unused-parameter + +-EXTRA_CFLAGS += -DEXTRACHECKS ++#EXTRA_CFLAGS += -DEXTRACHECKS + +-#EXTRA_CFLAGS += -DTRACING +-EXTRA_CFLAGS += -DDEBUG -g ++EXTRA_CFLAGS += -DTRACING ++#EXTRA_CFLAGS += -DDEBUG -g + + clean: + rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend Modules.symvers Module.symvers Added: trunk/usr/fileio/README =================================================================== --- trunk/usr/fileio/README (rev 0) +++ trunk/usr/fileio/README 2007-09-25 09:30:12 UTC (rev 194) @@ -0,0 +1,83 @@ +User space FILEIO handler +========================= + +Version 0.9.6, XX XXX 200X +-------------------------- + +User space program fileio_tgt uses interface of SCST's scst_user dev +handler as well as allows to see how it works in various modes. +Fileio_tgt provides mostly the same functionality as the kernel space +SCST's scst_vdisk handler with the only exceptions that it supports +O_DIRECT mode and doesn't support BLOCKIO one. O_DIRECT mode is +basically the same as BLOCKIO, but also supports files, so for some +loads it could be significantly faster, than the regular FILEIO access. +All the words about BLOCKIO mode from SCST's README file apply to +O_DIRECT mode as well. + +Installation +------------ + +Make sure you have installed SCST core, if not, see its README file for +details how to do it. + +Then run "make all install" + +For the best performance make sure you don't have any debug options +(i.e. lines like "CFLAGS += -DDEBUG" containing "-DDEBUG*" string) +enabled in the Makefile. + +Usage +----- + +Load scst_user module using modprobe or insmod, then start fileio_tgt +program. It can be used as the following: + +fileio_tgt [OPTION] name path + +Where: + + - OPTION - one or several not required options, see below. + + - name - name of the virtual device as it will be seen by SCST and used + in the subsequent access management using the corresponding SCST interface. + + - path - path to the device file. + +The following options are supported: + + -b or --block=size: block size, must be power of 2 and >=512 + + -e or --threads=count: number of threads + + -t or --write_through: write through mode + + -r or --read_only: read only + + -o or --direct: O_DIRECT mode, see above for details + + -n or --nullio: NULLIO mode, see SCST's README file for details + + -c or --nv_cache: NV_CACHE mode, see SCST's README file for details + + -p or --parse=type: parse type, one of "std" (default), "call" or "excpt" + + -f or --on_free=type: on free call type, one of "ignore" (default) or "call" + + -m or --mem_reuse=type: Memory reuse type, one of "all" (default), "read", + "write" or "none" + + -s or --prio_thread: Use separate thread for mgmt (prio) commands + + -l or --non_blocking: Use non-blocking operations + +Also in the debug builds the following options are supported: + + -d or --debug=level: debug tracing level + + -g or --debug_tm_ignore: turn on DEBUG_TM_IGNORE, one of the task management + debugging features + +If you don't understand some these options, don't use them, default +values provide the best performance. + +Vladislav Bolkhovitin <vs...@vl...>, http://scst.sourceforge.net Added: trunk/usr-full_perf.patch =================================================================== --- trunk/usr-full_perf.patch (rev 0) +++ trunk/usr-full_perf.patch 2007-09-25 09:30:12 UTC (rev 194) @@ -0,0 +1,16 @@ +Index: usr/fileio/Makefile +=================================================================== +--- usr/fileio/Makefile (revision 324) ++++ usr/fileio/Makefile (working copy) +@@ -28,9 +28,9 @@ CFLAGS += -O2 -Wall -Wextra -Wno-unused- + PROGS = fileio_tgt + LIBS = -lpthread + +-CFLAGS += -DEXTRACHECKS ++#CFLAGS += -DEXTRACHECKS + #CFLAGS += -DTRACING +-CFLAGS += -DDEBUG -g ++#CFLAGS += -DDEBUG -g + + #CFLAGS += -DDEBUG_NOMEM + #CFLAGS += -DDEBUG_SENSE Added: trunk/usr-release.patch =================================================================== --- trunk/usr-release.patch (rev 0) +++ trunk/usr-release.patch 2007-09-25 09:30:12 UTC (rev 194) @@ -0,0 +1,17 @@ +Index: usr/fileio/Makefile +=================================================================== +--- usr/fileio/Makefile (revision 324) ++++ usr/fileio/Makefile (working copy) +@@ -28,9 +28,9 @@ CFLAGS += -O2 -Wall -Wextra -Wno-unused- + PROGS = fileio_tgt + LIBS = -lpthread + +-CFLAGS += -DEXTRACHECKS +-#CFLAGS += -DTRACING +-CFLAGS += -DDEBUG -g ++#CFLAGS += -DEXTRACHECKS ++CFLAGS += -DTRACING ++#CFLAGS += -DDEBUG -g + + #CFLAGS += -DDEBUG_NOMEM + #CFLAGS += -DDEBUG_SENSE This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2007-09-25 09:52:54
|
Revision: 199 http://scst.svn.sourceforge.net/scst/?rev=199&view=rev Author: vlnb Date: 2007-09-25 02:52:53 -0700 (Tue, 25 Sep 2007) Log Message: ----------- - Fixes memory leaks in scst_user spotted by new SGV cache backend - Version changed on -pre3 - Minor fixes and cosmetics Modified Paths: -------------- trunk/scst/include/scsi_tgt.h trunk/scst/src/dev_handlers/scst_user.c trunk/scst/src/scst_mem.c trunk/usr/fileio/common.c trunk/usr/fileio/fileio.c Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2007-09-25 09:46:36 UTC (rev 198) +++ trunk/scst/include/scsi_tgt.h 2007-09-25 09:52:53 UTC (rev 199) @@ -39,7 +39,7 @@ /* Version numbers, the same as for the kernel */ #define SCST_VERSION_CODE 0x000906 #define SCST_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) -#define SCST_VERSION_STRING "0.9.6-pre2" +#define SCST_VERSION_STRING "0.9.6-pre3" /************************************************************* ** States of command processing state machine Modified: trunk/scst/src/dev_handlers/scst_user.c =================================================================== --- trunk/scst/src/dev_handlers/scst_user.c 2007-09-25 09:46:36 UTC (rev 198) +++ trunk/scst/src/dev_handlers/scst_user.c 2007-09-25 09:52:53 UTC (rev 199) @@ -361,7 +361,7 @@ { TRACE_ENTRY(); - TRACE_DBG("Preparing ON_CACHED_MEM_FREE (ucmd %p, h %d, ubuff %lx)", + TRACE_MEM("Preparing ON_CACHED_MEM_FREE (ucmd %p, h %d, ubuff %lx)", ucmd, ucmd->h, ucmd->ubuff); ucmd->user_cmd.cmd_h = ucmd->h; @@ -400,18 +400,14 @@ return; } -static void dev_user_free_sg_entries(struct scatterlist *sg, int sg_count, - void *priv) +static void __dev_user_free_sg_entries(struct dev_user_cmd *ucmd) { - struct dev_user_cmd *ucmd = (struct dev_user_cmd*)priv; - TRACE_ENTRY(); sBUG_ON(ucmd->data_pages == NULL); - TRACE_MEM("Freeing data pages (ucmd=%p, ubuff=%lx, sg=%p, sg_count=%d, " - "buff_cached=%d)", ucmd, ucmd->ubuff, sg, sg_count, - ucmd->buff_cached); + TRACE_MEM("Freeing data pages (ucmd=%p, ubuff=%lx, buff_cached=%d)", + ucmd, ucmd->ubuff, ucmd->buff_cached); dev_user_unmap_buf(ucmd); @@ -424,6 +420,19 @@ return; } +static void dev_user_free_sg_entries(struct scatterlist *sg, int sg_count, + void *priv) +{ + struct dev_user_cmd *ucmd = (struct dev_user_cmd*)priv; + + TRACE_MEM("Freeing data pages (sg=%p, sg_count=%d, priv %p)", sg, + sg_count, ucmd); + + __dev_user_free_sg_entries(ucmd); + + return; +} + static inline int is_buff_cached(struct dev_user_cmd *ucmd) { int mem_reuse_type = ucmd->dev->memory_reuse_type; @@ -510,9 +519,8 @@ cmd->tgt->sg_tablesize); ll++; } - sgv_pool_free(ucmd->sgv); - ucmd->sgv = NULL; cmd->sg = NULL; + /* sgv will be freed in dev_user_free_sgv() */ res = -1; } } else { @@ -520,9 +528,9 @@ "sg_cnt %d, ubuff %lx, sgv %p", ucmd, ucmd->h, ucmd->buff_cached, cmd->sg_cnt, ucmd->ubuff, ucmd->sgv); if (unlikely(cmd->sg_cnt == 0)) { + TRACE_MEM("Refused allocation (ucmd %p)", ucmd); + sBUG_ON(ucmd->sgv != NULL); res = -1; - if (ucmd->data_pages != NULL) - dev_user_unmap_buf(ucmd); } else { switch(ucmd->state & ~UCMD_STATE_MASK) { case UCMD_STATE_BUF_ALLOCING: @@ -530,8 +538,6 @@ break; case UCMD_STATE_EXECING: res = -1; - if (ucmd->data_pages != NULL) - dev_user_unmap_buf(ucmd); break; default: sBUG(); @@ -810,7 +816,12 @@ if (ucmd->sgv != NULL) { sgv_pool_free(ucmd->sgv); ucmd->sgv = NULL; + } else if (ucmd->data_pages != NULL) { + /* We mapped pages, but for some reason didn't allocate them */ + ucmd_get(ucmd, 0); + __dev_user_free_sg_entries(ucmd); } + return; } static void dev_user_on_free_cmd(struct scst_cmd *cmd) @@ -822,7 +833,7 @@ if (unlikely(ucmd == NULL)) goto out; - TRACE_DBG("ucmd %p, cmd %p, buff_cached %d, ubuff %lx", ucmd, ucmd->cmd, + TRACE_MEM("ucmd %p, cmd %p, buff_cached %d, ubuff %lx", ucmd, ucmd->cmd, ucmd->buff_cached, ucmd->ubuff); ucmd->cmd = NULL; @@ -998,6 +1009,8 @@ if (unlikely(ubuff == 0)) goto out_nomem; + sBUG_ON(ucmd->data_pages != NULL); + ucmd->num_data_pages = num_pg; ucmd->data_pages = kzalloc(sizeof(*ucmd->data_pages)*ucmd->num_data_pages, Modified: trunk/scst/src/scst_mem.c =================================================================== --- trunk/scst/src/scst_mem.c 2007-09-25 09:46:36 UTC (rev 198) +++ trunk/scst/src/scst_mem.c 2007-09-25 09:52:53 UTC (rev 199) @@ -503,6 +503,8 @@ int no_cached = flags & SCST_POOL_ALLOC_NO_CACHED; int no_fail = ((gfp_mask & __GFP_NOFAIL) == __GFP_NOFAIL); + TRACE_ENTRY(); + sBUG_ON(size == 0); pages = ((size + PAGE_SIZE - 1) >> PAGE_SHIFT); @@ -519,13 +521,8 @@ EXTRACHECKS_BUG_ON(obj->sg_count != 0); pages_to_alloc = (1 << order); cache = pool->caches[obj->order]; - if (sgv_pool_hiwmk_check(pages_to_alloc, no_fail) != 0) { - obj->sg_count = 0; - if ((flags & SCST_POOL_RETURN_OBJ_ON_ALLOC_FAIL)) - goto out_return1; - else - goto out_fail_free_sg_entries; - } + if (sgv_pool_hiwmk_check(pages_to_alloc, no_fail) != 0) + goto out_fail_free_sg_entries; } else if ((order < SGV_POOL_ELEMENTS) && !no_cached) { cache = pool->caches[order]; obj = sgv_pool_cached_get(pool, order, gfp_mask); @@ -579,13 +576,8 @@ goto out_return; obj->allocator_priv = priv; - if (sgv_pool_hiwmk_check(pages_to_alloc, no_fail) != 0) { - obj->sg_count = 0; - if ((flags & SCST_POOL_RETURN_OBJ_ON_ALLOC_FAIL)) - goto out_return1; - else - goto out_fail_free_sg_entries; - } + if (sgv_pool_hiwmk_check(pages_to_alloc, no_fail) != 0) + goto out_fail_free_sg_entries; } else { int sz; pages_to_alloc = pages; @@ -604,10 +596,8 @@ obj->sg_entries = obj->sg_entries_data; obj->allocator_priv = priv; - if (sgv_pool_hiwmk_check(pages_to_alloc, no_fail) != 0) { - obj->sg_count = 0; + if (sgv_pool_hiwmk_check(pages_to_alloc, no_fail) != 0) goto out_fail_free_sg_entries; - } TRACE_MEM("Big or no_cached sgv_obj %p (size %d)", obj, sz); } @@ -662,6 +652,7 @@ obj->sg_count, *count, obj->sg_entries[obj->orig_sg].length); out: + TRACE_EXIT_HRES(res); return res; out_return: Modified: trunk/usr/fileio/common.c =================================================================== --- trunk/usr/fileio/common.c 2007-09-25 09:46:36 UTC (rev 198) +++ trunk/usr/fileio/common.c 2007-09-25 09:52:53 UTC (rev 199) @@ -663,9 +663,9 @@ vcmd.fd = open_dev_fd(dev); if (vcmd.fd < 0) { - res = vcmd.fd; + res = -errno; PRINT_ERROR_PR("Unable to open file %s (%s)", dev->file_name, - strerror(res)); + strerror(-res)); goto out; } Modified: trunk/usr/fileio/fileio.c =================================================================== --- trunk/usr/fileio/fileio.c 2007-09-25 09:46:36 UTC (rev 198) +++ trunk/usr/fileio/fileio.c 2007-09-25 09:52:53 UTC (rev 199) @@ -277,9 +277,9 @@ TRACE_DBG("Opening file %s", dev.file_name); fd = open(dev.file_name, O_RDONLY|O_LARGEFILE); if (fd < 0) { - res = errno; + res = -errno; PRINT_ERROR_PR("Unable to open file %s (%s)", dev.file_name, - strerror(res)); + strerror(-res)); goto out_done; } @@ -368,9 +368,9 @@ dev.scst_usr_fd = open(DEV_USER_PATH DEV_USER_NAME, O_RDWR | (dev.non_blocking ? O_NONBLOCK : 0)); if (dev.scst_usr_fd < 0) { - res = dev.scst_usr_fd; + res = -errno; PRINT_ERROR_PR("Unable to open SCST device %s (%s)", - DEV_USER_PATH DEV_USER_NAME, strerror(res)); + DEV_USER_PATH DEV_USER_NAME, strerror(-res)); goto out_done; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2007-09-28 13:57:17
|
Revision: 201 http://scst.svn.sourceforge.net/scst/?rev=201&view=rev Author: vlnb Date: 2007-09-28 06:57:06 -0700 (Fri, 28 Sep 2007) Log Message: ----------- - Put_page patches remaned to correspond with the full kernel versions, for which they were created - Minor cleanups Modified Paths: -------------- trunk/usr/fileio/fileio.c Added Paths: ----------- trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.16.29.patch trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.18.1.patch trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.21.1.patch Removed Paths: ------------- trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.16.patch trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.18.patch trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.21.patch Copied: trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.16.29.patch (from rev 190, trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.16.patch) =================================================================== --- trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.16.29.patch (rev 0) +++ trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.16.29.patch 2007-09-28 13:57:06 UTC (rev 201) @@ -0,0 +1,248 @@ +diff -upr linux-2.6.16.29/include/linux/mm.h linux-2.6.16.29/include/linux/mm.h +--- linux-2.6.16.29/include/linux/mm.h 2006-09-12 22:02:10.000000000 +0400 ++++ linux-2.6.16.29/include/linux/mm.h 2007-08-07 19:54:27.000000000 +0400 +@@ -263,6 +263,15 @@ struct page { + void *virtual; /* Kernel virtual address (NULL if + not kmapped, ie. highmem) */ + #endif /* WANT_PAGE_VIRTUAL */ ++ /* ++ * Used to implement support for notification on zero-copy TCP transfer ++ * completeion. Not good to have this field here, it's better to have ++ * it in struct sk_buff, but it would make the code much more ++ * complicated and fragile, if maintained as a separate patch, since all ++ * skb then would have to contain only pages with the same value in this ++ * field. ++ */ ++ void *net_priv; + }; + + #define page_private(page) ((page)->private) +diff -upr linux-2.6.16.29/include/linux/net.h linux-2.6.16.29/include/linux/net.h +--- linux-2.6.16.29/include/linux/net.h 2006-09-12 22:02:10.000000000 +0400 ++++ linux-2.6.16.29/include/linux/net.h 2007-08-29 18:31:40.000000000 +0400 +@@ -57,6 +57,7 @@ typedef enum { + #define __SO_ACCEPTCON (1 << 16) /* performed a listen */ + + #ifdef __KERNEL__ ++#include <linux/mm.h> + + #define SOCK_ASYNC_NOSPACE 0 + #define SOCK_ASYNC_WAITDATA 1 +@@ -294,5 +295,30 @@ extern int net_msg_cost; + extern int net_msg_burst; + #endif + ++/* Support for notification on zero-copy TCP transfer completeion */ ++#define NET_PAGE_CALLBACKS_DEFINED ++typedef void (*net_get_page_callback_t)(struct page *page); ++typedef void (*net_put_page_callback_t)(struct page *page); ++ ++extern net_get_page_callback_t net_get_page_callback; ++extern net_put_page_callback_t net_put_page_callback; ++ ++extern int net_set_get_put_page_callbacks( ++ net_get_page_callback_t get_callback, ++ net_put_page_callback_t put_callback); ++ ++static inline void net_get_page(struct page *page) ++{ ++ if (page->net_priv != 0) ++ net_get_page_callback(page); ++ get_page(page); ++} ++static inline void net_put_page(struct page *page) ++{ ++ if (page->net_priv != 0) ++ net_put_page_callback(page); ++ put_page(page); ++} ++ + #endif /* __KERNEL__ */ + #endif /* _LINUX_NET_H */ +diff -upr linux-2.6.16.29/net/core/skbuff.c linux-2.6.16.29/net/core/skbuff.c +--- linux-2.6.16.29/net/core/skbuff.c 2006-09-12 22:02:10.000000000 +0400 ++++ linux-2.6.16.29/net/core/skbuff.c 2007-08-07 19:55:51.000000000 +0400 +@@ -271,7 +271,7 @@ void skb_release_data(struct sk_buff *sk + if (skb_shinfo(skb)->nr_frags) { + int i; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + } + + if (skb_shinfo(skb)->frag_list) +@@ -588,7 +588,7 @@ struct sk_buff *pskb_copy(struct sk_buff + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i]; +- get_page(skb_shinfo(n)->frags[i].page); ++ net_get_page(skb_shinfo(n)->frags[i].page); + } + skb_shinfo(n)->nr_frags = i; + } +@@ -642,7 +642,7 @@ int pskb_expand_head(struct sk_buff *skb + memcpy(data + size, skb->end, sizeof(struct skb_shared_info)); + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) +- get_page(skb_shinfo(skb)->frags[i].page); ++ net_get_page(skb_shinfo(skb)->frags[i].page); + + if (skb_shinfo(skb)->frag_list) + skb_clone_fraglist(skb); +@@ -794,7 +794,7 @@ int ___pskb_trim(struct sk_buff *skb, un + return -ENOMEM; + } + if (len <= offset) { +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + skb_shinfo(skb)->nr_frags--; + } else { + skb_shinfo(skb)->frags[i].size = len - offset; +@@ -940,7 +940,7 @@ pull_pages: + k = 0; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + if (skb_shinfo(skb)->frags[i].size <= eat) { +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + eat -= skb_shinfo(skb)->frags[i].size; + } else { + skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; +@@ -1522,7 +1522,7 @@ static inline void skb_split_no_header(s + * where splitting is expensive. + * 2. Split is accurately. We make this. + */ +- get_page(skb_shinfo(skb)->frags[i].page); ++ net_get_page(skb_shinfo(skb)->frags[i].page); + skb_shinfo(skb1)->frags[0].page_offset += len - pos; + skb_shinfo(skb1)->frags[0].size -= len - pos; + skb_shinfo(skb)->frags[i].size = len - pos; +diff -upr linux-2.6.16.29/net/core/utils.c linux-2.6.16.29/net/core/utils.c +--- linux-2.6.16.29/net/core/utils.c 2006-09-12 22:02:10.000000000 +0400 ++++ linux-2.6.16.29/net/core/utils.c 2007-08-23 19:54:03.000000000 +0400 +@@ -24,11 +24,15 @@ + #include <linux/random.h> + #include <linux/percpu.h> + #include <linux/init.h> ++#include <linux/skbuff.h> + + #include <asm/byteorder.h> + #include <asm/system.h> + #include <asm/uaccess.h> + ++net_get_page_callback_t net_get_page_callback __read_mostly; ++net_put_page_callback_t net_put_page_callback __read_mostly; ++ + /* + This is a maximally equidistributed combined Tausworthe generator + based on code from GNU Scientific Library 1.5 (30 Jun 2004) +@@ -190,3 +194,32 @@ __be32 in_aton(const char *str) + } + + EXPORT_SYMBOL(in_aton); ++ ++int net_set_get_put_page_callbacks( ++ net_get_page_callback_t get_callback, ++ net_put_page_callback_t put_callback) ++{ ++ int res = 0; ++ ++ if ((net_get_page_callback != NULL) && (get_callback != NULL) && ++ (net_get_page_callback != get_callback)) { ++ res = -EBUSY; ++ goto out; ++ } ++ ++ if ((net_put_page_callback != NULL) && (put_callback != NULL) && ++ (net_put_page_callback != put_callback)) { ++ res = -EBUSY; ++ goto out; ++ } ++ ++ net_get_page_callback = get_callback; ++ net_put_page_callback = put_callback; ++ ++out: ++ return res; ++} ++EXPORT_SYMBOL(net_set_get_put_page_callbacks); ++ ++EXPORT_SYMBOL(net_get_page_callback); ++EXPORT_SYMBOL(net_put_page_callback); +diff -upr linux-2.6.16.29/net/ipv4/ip_output.c linux-2.6.16.29/net/ipv4/ip_output.c +--- linux-2.6.16.29/net/ipv4/ip_output.c 2006-09-12 22:02:10.000000000 +0400 ++++ linux-2.6.16.29/net/ipv4/ip_output.c 2007-08-07 19:54:27.000000000 +0400 +@@ -997,7 +997,7 @@ alloc_new_skb: + err = -EMSGSIZE; + goto error; + } +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); + frag = &skb_shinfo(skb)->frags[i]; + } +@@ -1155,7 +1155,7 @@ ssize_t ip_append_page(struct sock *sk, + if (skb_can_coalesce(skb, i, page, offset)) { + skb_shinfo(skb)->frags[i-1].size += len; + } else if (i < MAX_SKB_FRAGS) { +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, offset, len); + } else { + err = -EMSGSIZE; +diff -upr linux-2.6.16.29/net/ipv4/tcp.c linux-2.6.16.29/net/ipv4/tcp.c +--- linux-2.6.16.29/net/ipv4/tcp.c 2006-09-12 22:02:10.000000000 +0400 ++++ linux-2.6.16.29/net/ipv4/tcp.c 2007-08-07 19:54:27.000000000 +0400 +@@ -558,7 +558,7 @@ new_segment: + if (can_coalesce) { + skb_shinfo(skb)->frags[i - 1].size += copy; + } else { +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, offset, copy); + } + +@@ -767,7 +767,7 @@ new_segment: + goto new_segment; + } else if (page) { + if (off == PAGE_SIZE) { +- put_page(page); ++ net_put_page(page); + TCP_PAGE(sk) = page = NULL; + off = 0; + } +@@ -808,9 +808,9 @@ new_segment: + } else { + skb_fill_page_desc(skb, i, page, off, copy); + if (TCP_PAGE(sk)) { +- get_page(page); ++ net_get_page(page); + } else if (off + copy < PAGE_SIZE) { +- get_page(page); ++ net_get_page(page); + TCP_PAGE(sk) = page; + } + } +diff -upr linux-2.6.16.29/net/ipv4/tcp_output.c linux-2.6.16.29/net/ipv4/tcp_output.c +--- linux-2.6.16.29/net/ipv4/tcp_output.c 2006-09-12 22:02:10.000000000 +0400 ++++ linux-2.6.16.29/net/ipv4/tcp_output.c 2007-08-07 19:54:27.000000000 +0400 +@@ -633,7 +633,7 @@ static unsigned char *__pskb_trim_head(s + k = 0; + for (i=0; i<skb_shinfo(skb)->nr_frags; i++) { + if (skb_shinfo(skb)->frags[i].size <= eat) { +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + eat -= skb_shinfo(skb)->frags[i].size; + } else { + skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; +diff -upr linux-2.6.16.29/net/ipv6/ip6_output.c linux-2.6.16.29/net/ipv6/ip6_output.c +--- linux-2.6.16.29/net/ipv6/ip6_output.c 2006-09-12 22:02:10.000000000 +0400 ++++ linux-2.6.16.29/net/ipv6/ip6_output.c 2007-08-07 19:54:27.000000000 +0400 +@@ -1100,7 +1100,7 @@ alloc_new_skb: + err = -EMSGSIZE; + goto error; + } +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); + frag = &skb_shinfo(skb)->frags[i]; + } Deleted: trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.16.patch =================================================================== --- trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.16.patch 2007-09-25 13:39:25 UTC (rev 200) +++ trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.16.patch 2007-09-28 13:57:06 UTC (rev 201) @@ -1,248 +0,0 @@ -diff -upr linux-2.6.16.29/include/linux/mm.h linux-2.6.16.29/include/linux/mm.h ---- linux-2.6.16.29/include/linux/mm.h 2006-09-12 22:02:10.000000000 +0400 -+++ linux-2.6.16.29/include/linux/mm.h 2007-08-07 19:54:27.000000000 +0400 -@@ -263,6 +263,15 @@ struct page { - void *virtual; /* Kernel virtual address (NULL if - not kmapped, ie. highmem) */ - #endif /* WANT_PAGE_VIRTUAL */ -+ /* -+ * Used to implement support for notification on zero-copy TCP transfer -+ * completeion. Not good to have this field here, it's better to have -+ * it in struct sk_buff, but it would make the code much more -+ * complicated and fragile, if maintained as a separate patch, since all -+ * skb then would have to contain only pages with the same value in this -+ * field. -+ */ -+ void *net_priv; - }; - - #define page_private(page) ((page)->private) -diff -upr linux-2.6.16.29/include/linux/net.h linux-2.6.16.29/include/linux/net.h ---- linux-2.6.16.29/include/linux/net.h 2006-09-12 22:02:10.000000000 +0400 -+++ linux-2.6.16.29/include/linux/net.h 2007-08-29 18:31:40.000000000 +0400 -@@ -57,6 +57,7 @@ typedef enum { - #define __SO_ACCEPTCON (1 << 16) /* performed a listen */ - - #ifdef __KERNEL__ -+#include <linux/mm.h> - - #define SOCK_ASYNC_NOSPACE 0 - #define SOCK_ASYNC_WAITDATA 1 -@@ -294,5 +295,30 @@ extern int net_msg_cost; - extern int net_msg_burst; - #endif - -+/* Support for notification on zero-copy TCP transfer completeion */ -+#define NET_PAGE_CALLBACKS_DEFINED -+typedef void (*net_get_page_callback_t)(struct page *page); -+typedef void (*net_put_page_callback_t)(struct page *page); -+ -+extern net_get_page_callback_t net_get_page_callback; -+extern net_put_page_callback_t net_put_page_callback; -+ -+extern int net_set_get_put_page_callbacks( -+ net_get_page_callback_t get_callback, -+ net_put_page_callback_t put_callback); -+ -+static inline void net_get_page(struct page *page) -+{ -+ if (page->net_priv != 0) -+ net_get_page_callback(page); -+ get_page(page); -+} -+static inline void net_put_page(struct page *page) -+{ -+ if (page->net_priv != 0) -+ net_put_page_callback(page); -+ put_page(page); -+} -+ - #endif /* __KERNEL__ */ - #endif /* _LINUX_NET_H */ -diff -upr linux-2.6.16.29/net/core/skbuff.c linux-2.6.16.29/net/core/skbuff.c ---- linux-2.6.16.29/net/core/skbuff.c 2006-09-12 22:02:10.000000000 +0400 -+++ linux-2.6.16.29/net/core/skbuff.c 2007-08-07 19:55:51.000000000 +0400 -@@ -271,7 +271,7 @@ void skb_release_data(struct sk_buff *sk - if (skb_shinfo(skb)->nr_frags) { - int i; - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) -- put_page(skb_shinfo(skb)->frags[i].page); -+ net_put_page(skb_shinfo(skb)->frags[i].page); - } - - if (skb_shinfo(skb)->frag_list) -@@ -588,7 +588,7 @@ struct sk_buff *pskb_copy(struct sk_buff - - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i]; -- get_page(skb_shinfo(n)->frags[i].page); -+ net_get_page(skb_shinfo(n)->frags[i].page); - } - skb_shinfo(n)->nr_frags = i; - } -@@ -642,7 +642,7 @@ int pskb_expand_head(struct sk_buff *skb - memcpy(data + size, skb->end, sizeof(struct skb_shared_info)); - - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) -- get_page(skb_shinfo(skb)->frags[i].page); -+ net_get_page(skb_shinfo(skb)->frags[i].page); - - if (skb_shinfo(skb)->frag_list) - skb_clone_fraglist(skb); -@@ -794,7 +794,7 @@ int ___pskb_trim(struct sk_buff *skb, un - return -ENOMEM; - } - if (len <= offset) { -- put_page(skb_shinfo(skb)->frags[i].page); -+ net_put_page(skb_shinfo(skb)->frags[i].page); - skb_shinfo(skb)->nr_frags--; - } else { - skb_shinfo(skb)->frags[i].size = len - offset; -@@ -940,7 +940,7 @@ pull_pages: - k = 0; - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - if (skb_shinfo(skb)->frags[i].size <= eat) { -- put_page(skb_shinfo(skb)->frags[i].page); -+ net_put_page(skb_shinfo(skb)->frags[i].page); - eat -= skb_shinfo(skb)->frags[i].size; - } else { - skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; -@@ -1522,7 +1522,7 @@ static inline void skb_split_no_header(s - * where splitting is expensive. - * 2. Split is accurately. We make this. - */ -- get_page(skb_shinfo(skb)->frags[i].page); -+ net_get_page(skb_shinfo(skb)->frags[i].page); - skb_shinfo(skb1)->frags[0].page_offset += len - pos; - skb_shinfo(skb1)->frags[0].size -= len - pos; - skb_shinfo(skb)->frags[i].size = len - pos; -diff -upr linux-2.6.16.29/net/core/utils.c linux-2.6.16.29/net/core/utils.c ---- linux-2.6.16.29/net/core/utils.c 2006-09-12 22:02:10.000000000 +0400 -+++ linux-2.6.16.29/net/core/utils.c 2007-08-23 19:54:03.000000000 +0400 -@@ -24,11 +24,15 @@ - #include <linux/random.h> - #include <linux/percpu.h> - #include <linux/init.h> -+#include <linux/skbuff.h> - - #include <asm/byteorder.h> - #include <asm/system.h> - #include <asm/uaccess.h> - -+net_get_page_callback_t net_get_page_callback __read_mostly; -+net_put_page_callback_t net_put_page_callback __read_mostly; -+ - /* - This is a maximally equidistributed combined Tausworthe generator - based on code from GNU Scientific Library 1.5 (30 Jun 2004) -@@ -190,3 +194,32 @@ __be32 in_aton(const char *str) - } - - EXPORT_SYMBOL(in_aton); -+ -+int net_set_get_put_page_callbacks( -+ net_get_page_callback_t get_callback, -+ net_put_page_callback_t put_callback) -+{ -+ int res = 0; -+ -+ if ((net_get_page_callback != NULL) && (get_callback != NULL) && -+ (net_get_page_callback != get_callback)) { -+ res = -EBUSY; -+ goto out; -+ } -+ -+ if ((net_put_page_callback != NULL) && (put_callback != NULL) && -+ (net_put_page_callback != put_callback)) { -+ res = -EBUSY; -+ goto out; -+ } -+ -+ net_get_page_callback = get_callback; -+ net_put_page_callback = put_callback; -+ -+out: -+ return res; -+} -+EXPORT_SYMBOL(net_set_get_put_page_callbacks); -+ -+EXPORT_SYMBOL(net_get_page_callback); -+EXPORT_SYMBOL(net_put_page_callback); -diff -upr linux-2.6.16.29/net/ipv4/ip_output.c linux-2.6.16.29/net/ipv4/ip_output.c ---- linux-2.6.16.29/net/ipv4/ip_output.c 2006-09-12 22:02:10.000000000 +0400 -+++ linux-2.6.16.29/net/ipv4/ip_output.c 2007-08-07 19:54:27.000000000 +0400 -@@ -997,7 +997,7 @@ alloc_new_skb: - err = -EMSGSIZE; - goto error; - } -- get_page(page); -+ net_get_page(page); - skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); - frag = &skb_shinfo(skb)->frags[i]; - } -@@ -1155,7 +1155,7 @@ ssize_t ip_append_page(struct sock *sk, - if (skb_can_coalesce(skb, i, page, offset)) { - skb_shinfo(skb)->frags[i-1].size += len; - } else if (i < MAX_SKB_FRAGS) { -- get_page(page); -+ net_get_page(page); - skb_fill_page_desc(skb, i, page, offset, len); - } else { - err = -EMSGSIZE; -diff -upr linux-2.6.16.29/net/ipv4/tcp.c linux-2.6.16.29/net/ipv4/tcp.c ---- linux-2.6.16.29/net/ipv4/tcp.c 2006-09-12 22:02:10.000000000 +0400 -+++ linux-2.6.16.29/net/ipv4/tcp.c 2007-08-07 19:54:27.000000000 +0400 -@@ -558,7 +558,7 @@ new_segment: - if (can_coalesce) { - skb_shinfo(skb)->frags[i - 1].size += copy; - } else { -- get_page(page); -+ net_get_page(page); - skb_fill_page_desc(skb, i, page, offset, copy); - } - -@@ -767,7 +767,7 @@ new_segment: - goto new_segment; - } else if (page) { - if (off == PAGE_SIZE) { -- put_page(page); -+ net_put_page(page); - TCP_PAGE(sk) = page = NULL; - off = 0; - } -@@ -808,9 +808,9 @@ new_segment: - } else { - skb_fill_page_desc(skb, i, page, off, copy); - if (TCP_PAGE(sk)) { -- get_page(page); -+ net_get_page(page); - } else if (off + copy < PAGE_SIZE) { -- get_page(page); -+ net_get_page(page); - TCP_PAGE(sk) = page; - } - } -diff -upr linux-2.6.16.29/net/ipv4/tcp_output.c linux-2.6.16.29/net/ipv4/tcp_output.c ---- linux-2.6.16.29/net/ipv4/tcp_output.c 2006-09-12 22:02:10.000000000 +0400 -+++ linux-2.6.16.29/net/ipv4/tcp_output.c 2007-08-07 19:54:27.000000000 +0400 -@@ -633,7 +633,7 @@ static unsigned char *__pskb_trim_head(s - k = 0; - for (i=0; i<skb_shinfo(skb)->nr_frags; i++) { - if (skb_shinfo(skb)->frags[i].size <= eat) { -- put_page(skb_shinfo(skb)->frags[i].page); -+ net_put_page(skb_shinfo(skb)->frags[i].page); - eat -= skb_shinfo(skb)->frags[i].size; - } else { - skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; -diff -upr linux-2.6.16.29/net/ipv6/ip6_output.c linux-2.6.16.29/net/ipv6/ip6_output.c ---- linux-2.6.16.29/net/ipv6/ip6_output.c 2006-09-12 22:02:10.000000000 +0400 -+++ linux-2.6.16.29/net/ipv6/ip6_output.c 2007-08-07 19:54:27.000000000 +0400 -@@ -1100,7 +1100,7 @@ alloc_new_skb: - err = -EMSGSIZE; - goto error; - } -- get_page(page); -+ net_get_page(page); - skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); - frag = &skb_shinfo(skb)->frags[i]; - } Copied: trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.18.1.patch (from rev 190, trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.18.patch) =================================================================== --- trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.18.1.patch (rev 0) +++ trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.18.1.patch 2007-09-28 13:57:06 UTC (rev 201) @@ -0,0 +1,257 @@ +diff -upr linux-2.6.18.1/include/linux/mm.h linux-2.6.18.1/include/linux/mm.h +--- linux-2.6.18.1/include/linux/mm.h 2006-09-20 07:42:06.000000000 +0400 ++++ linux-2.6.18.1/include/linux/mm.h 2007-08-07 19:35:51.000000000 +0400 +@@ -267,6 +267,15 @@ struct page { + void *virtual; /* Kernel virtual address (NULL if + not kmapped, ie. highmem) */ + #endif /* WANT_PAGE_VIRTUAL */ ++ /* ++ * Used to implement support for notification on zero-copy TCP transfer ++ * completeion. Not good to have this field here, it's better to have ++ * it in struct sk_buff, but it would make the code much more ++ * complicated and fragile, if maintained as a separate patch, since all ++ * skb then would have to contain only pages with the same value in this ++ * field. ++ */ ++ void *net_priv; + }; + + #define page_private(page) ((page)->private) +diff -upr linux-2.6.18.1/include/linux/net.h linux-2.6.18.1/include/linux/net.h +--- linux-2.6.18.1/include/linux/net.h 2006-09-20 07:42:06.000000000 +0400 ++++ linux-2.6.18.1/include/linux/net.h 2007-08-29 18:28:21.000000000 +0400 +@@ -56,6 +56,7 @@ typedef enum { + + #ifdef __KERNEL__ + #include <linux/stringify.h> ++#include <linux/mm.h> + + #define SOCK_ASYNC_NOSPACE 0 + #define SOCK_ASYNC_WAITDATA 1 +@@ -304,5 +305,30 @@ extern int net_msg_cost; + extern int net_msg_burst; + #endif + ++/* Support for notification on zero-copy TCP transfer completeion */ ++#define NET_PAGE_CALLBACKS_DEFINED ++typedef void (*net_get_page_callback_t)(struct page *page); ++typedef void (*net_put_page_callback_t)(struct page *page); ++ ++extern net_get_page_callback_t net_get_page_callback; ++extern net_put_page_callback_t net_put_page_callback; ++ ++extern int net_set_get_put_page_callbacks( ++ net_get_page_callback_t get_callback, ++ net_put_page_callback_t put_callback); ++ ++static inline void net_get_page(struct page *page) ++{ ++ if (page->net_priv != 0) ++ net_get_page_callback(page); ++ get_page(page); ++} ++static inline void net_put_page(struct page *page) ++{ ++ if (page->net_priv != 0) ++ net_put_page_callback(page); ++ put_page(page); ++} ++ + #endif /* __KERNEL__ */ + #endif /* _LINUX_NET_H */ +diff -upr linux-2.6.18.1/net/core/skbuff.c linux-2.6.18.1/net/core/skbuff.c +--- linux-2.6.18.1/net/core/skbuff.c 2006-09-20 07:42:06.000000000 +0400 ++++ linux-2.6.18.1/net/core/skbuff.c 2007-08-07 19:35:51.000000000 +0400 +@@ -309,7 +309,7 @@ static void skb_release_data(struct sk_b + if (skb_shinfo(skb)->nr_frags) { + int i; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + } + + if (skb_shinfo(skb)->frag_list) +@@ -646,7 +646,7 @@ struct sk_buff *pskb_copy(struct sk_buff + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i]; +- get_page(skb_shinfo(n)->frags[i].page); ++ net_get_page(skb_shinfo(n)->frags[i].page); + } + skb_shinfo(n)->nr_frags = i; + } +@@ -700,7 +700,7 @@ int pskb_expand_head(struct sk_buff *skb + memcpy(data + size, skb->end, sizeof(struct skb_shared_info)); + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) +- get_page(skb_shinfo(skb)->frags[i].page); ++ net_get_page(skb_shinfo(skb)->frags[i].page); + + if (skb_shinfo(skb)->frag_list) + skb_clone_fraglist(skb); +@@ -882,7 +882,7 @@ drop_pages: + skb_shinfo(skb)->nr_frags = i; + + for (; i < nfrags; i++) +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + + if (skb_shinfo(skb)->frag_list) + skb_drop_fraglist(skb); +@@ -1051,7 +1051,7 @@ pull_pages: + k = 0; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + if (skb_shinfo(skb)->frags[i].size <= eat) { +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + eat -= skb_shinfo(skb)->frags[i].size; + } else { + skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; +@@ -1633,7 +1633,7 @@ static inline void skb_split_no_header(s + * where splitting is expensive. + * 2. Split is accurately. We make this. + */ +- get_page(skb_shinfo(skb)->frags[i].page); ++ net_get_page(skb_shinfo(skb)->frags[i].page); + skb_shinfo(skb1)->frags[0].page_offset += len - pos; + skb_shinfo(skb1)->frags[0].size -= len - pos; + skb_shinfo(skb)->frags[i].size = len - pos; +@@ -2002,7 +2002,7 @@ struct sk_buff *skb_segment(struct sk_bu + BUG_ON(i >= nfrags); + + *frag = skb_shinfo(skb)->frags[i]; +- get_page(frag->page); ++ net_get_page(frag->page); + size = frag->size; + + if (pos < offset) { +diff -upr linux-2.6.18.1/net/core/utils.c linux-2.6.18.1/net/core/utils.c +--- linux-2.6.18.1/net/core/utils.c 2006-09-20 07:42:06.000000000 +0400 ++++ linux-2.6.18.1/net/core/utils.c 2007-08-23 19:49:40.000000000 +0400 +@@ -24,11 +24,15 @@ + #include <linux/random.h> + #include <linux/percpu.h> + #include <linux/init.h> ++#include <linux/skbuff.h> + + #include <asm/byteorder.h> + #include <asm/system.h> + #include <asm/uaccess.h> + ++net_get_page_callback_t net_get_page_callback __read_mostly; ++net_put_page_callback_t net_put_page_callback __read_mostly; ++ + /* + This is a maximally equidistributed combined Tausworthe generator + based on code from GNU Scientific Library 1.5 (30 Jun 2004) +@@ -191,3 +195,32 @@ __be32 in_aton(const char *str) + } + + EXPORT_SYMBOL(in_aton); ++ ++int net_set_get_put_page_callbacks( ++ net_get_page_callback_t get_callback, ++ net_put_page_callback_t put_callback) ++{ ++ int res = 0; ++ ++ if ((net_get_page_callback != NULL) && (get_callback != NULL) && ++ (net_get_page_callback != get_callback)) { ++ res = -EBUSY; ++ goto out; ++ } ++ ++ if ((net_put_page_callback != NULL) && (put_callback != NULL) && ++ (net_put_page_callback != put_callback)) { ++ res = -EBUSY; ++ goto out; ++ } ++ ++ net_get_page_callback = get_callback; ++ net_put_page_callback = put_callback; ++ ++out: ++ return res; ++} ++EXPORT_SYMBOL(net_set_get_put_page_callbacks); ++ ++EXPORT_SYMBOL(net_get_page_callback); ++EXPORT_SYMBOL(net_put_page_callback); +diff -upr linux-2.6.18.1/net/ipv4/ip_output.c linux-2.6.18.1/net/ipv4/ip_output.c +--- linux-2.6.18.1/net/ipv4/ip_output.c 2006-09-20 07:42:06.000000000 +0400 ++++ linux-2.6.18.1/net/ipv4/ip_output.c 2007-08-07 19:37:24.000000000 +0400 +@@ -999,7 +999,7 @@ alloc_new_skb: + err = -EMSGSIZE; + goto error; + } +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); + frag = &skb_shinfo(skb)->frags[i]; + } +@@ -1159,7 +1159,7 @@ ssize_t ip_append_page(struct sock *sk, + if (skb_can_coalesce(skb, i, page, offset)) { + skb_shinfo(skb)->frags[i-1].size += len; + } else if (i < MAX_SKB_FRAGS) { +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, offset, len); + } else { + err = -EMSGSIZE; +diff -upr linux-2.6.18.1/net/ipv4/tcp.c linux-2.6.18.1/net/ipv4/tcp.c +--- linux-2.6.18.1/net/ipv4/tcp.c 2006-09-20 07:42:06.000000000 +0400 ++++ linux-2.6.18.1/net/ipv4/tcp.c 2007-08-07 19:35:51.000000000 +0400 +@@ -559,7 +559,7 @@ new_segment: + if (can_coalesce) { + skb_shinfo(skb)->frags[i - 1].size += copy; + } else { +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, offset, copy); + } + +@@ -762,7 +762,7 @@ new_segment: + goto new_segment; + } else if (page) { + if (off == PAGE_SIZE) { +- put_page(page); ++ net_put_page(page); + TCP_PAGE(sk) = page = NULL; + off = 0; + } +@@ -803,9 +803,9 @@ new_segment: + } else { + skb_fill_page_desc(skb, i, page, off, copy); + if (TCP_PAGE(sk)) { +- get_page(page); ++ net_get_page(page); + } else if (off + copy < PAGE_SIZE) { +- get_page(page); ++ net_get_page(page); + TCP_PAGE(sk) = page; + } + } +diff -upr linux-2.6.18.1/net/ipv4/tcp_output.c linux-2.6.18.1/net/ipv4/tcp_output.c +--- linux-2.6.18.1/net/ipv4/tcp_output.c 2006-09-20 07:42:06.000000000 +0400 ++++ linux-2.6.18.1/net/ipv4/tcp_output.c 2007-08-07 19:35:51.000000000 +0400 +@@ -657,7 +657,7 @@ static void __pskb_trim_head(struct sk_b + k = 0; + for (i=0; i<skb_shinfo(skb)->nr_frags; i++) { + if (skb_shinfo(skb)->frags[i].size <= eat) { +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + eat -= skb_shinfo(skb)->frags[i].size; + } else { + skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; +diff -upr linux-2.6.18.1/net/ipv6/ip6_output.c linux-2.6.18.1/net/ipv6/ip6_output.c +--- linux-2.6.18.1/net/ipv6/ip6_output.c 2006-09-20 07:42:06.000000000 +0400 ++++ linux-2.6.18.1/net/ipv6/ip6_output.c 2007-08-07 19:35:51.000000000 +0400 +@@ -1149,7 +1149,7 @@ alloc_new_skb: + err = -EMSGSIZE; + goto error; + } +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); + frag = &skb_shinfo(skb)->frags[i]; + } Deleted: trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.18.patch =================================================================== --- trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.18.patch 2007-09-25 13:39:25 UTC (rev 200) +++ trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.18.patch 2007-09-28 13:57:06 UTC (rev 201) @@ -1,257 +0,0 @@ -diff -upr linux-2.6.18.1/include/linux/mm.h linux-2.6.18.1/include/linux/mm.h ---- linux-2.6.18.1/include/linux/mm.h 2006-09-20 07:42:06.000000000 +0400 -+++ linux-2.6.18.1/include/linux/mm.h 2007-08-07 19:35:51.000000000 +0400 -@@ -267,6 +267,15 @@ struct page { - void *virtual; /* Kernel virtual address (NULL if - not kmapped, ie. highmem) */ - #endif /* WANT_PAGE_VIRTUAL */ -+ /* -+ * Used to implement support for notification on zero-copy TCP transfer -+ * completeion. Not good to have this field here, it's better to have -+ * it in struct sk_buff, but it would make the code much more -+ * complicated and fragile, if maintained as a separate patch, since all -+ * skb then would have to contain only pages with the same value in this -+ * field. -+ */ -+ void *net_priv; - }; - - #define page_private(page) ((page)->private) -diff -upr linux-2.6.18.1/include/linux/net.h linux-2.6.18.1/include/linux/net.h ---- linux-2.6.18.1/include/linux/net.h 2006-09-20 07:42:06.000000000 +0400 -+++ linux-2.6.18.1/include/linux/net.h 2007-08-29 18:28:21.000000000 +0400 -@@ -56,6 +56,7 @@ typedef enum { - - #ifdef __KERNEL__ - #include <linux/stringify.h> -+#include <linux/mm.h> - - #define SOCK_ASYNC_NOSPACE 0 - #define SOCK_ASYNC_WAITDATA 1 -@@ -304,5 +305,30 @@ extern int net_msg_cost; - extern int net_msg_burst; - #endif - -+/* Support for notification on zero-copy TCP transfer completeion */ -+#define NET_PAGE_CALLBACKS_DEFINED -+typedef void (*net_get_page_callback_t)(struct page *page); -+typedef void (*net_put_page_callback_t)(struct page *page); -+ -+extern net_get_page_callback_t net_get_page_callback; -+extern net_put_page_callback_t net_put_page_callback; -+ -+extern int net_set_get_put_page_callbacks( -+ net_get_page_callback_t get_callback, -+ net_put_page_callback_t put_callback); -+ -+static inline void net_get_page(struct page *page) -+{ -+ if (page->net_priv != 0) -+ net_get_page_callback(page); -+ get_page(page); -+} -+static inline void net_put_page(struct page *page) -+{ -+ if (page->net_priv != 0) -+ net_put_page_callback(page); -+ put_page(page); -+} -+ - #endif /* __KERNEL__ */ - #endif /* _LINUX_NET_H */ -diff -upr linux-2.6.18.1/net/core/skbuff.c linux-2.6.18.1/net/core/skbuff.c ---- linux-2.6.18.1/net/core/skbuff.c 2006-09-20 07:42:06.000000000 +0400 -+++ linux-2.6.18.1/net/core/skbuff.c 2007-08-07 19:35:51.000000000 +0400 -@@ -309,7 +309,7 @@ static void skb_release_data(struct sk_b - if (skb_shinfo(skb)->nr_frags) { - int i; - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) -- put_page(skb_shinfo(skb)->frags[i].page); -+ net_put_page(skb_shinfo(skb)->frags[i].page); - } - - if (skb_shinfo(skb)->frag_list) -@@ -646,7 +646,7 @@ struct sk_buff *pskb_copy(struct sk_buff - - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i]; -- get_page(skb_shinfo(n)->frags[i].page); -+ net_get_page(skb_shinfo(n)->frags[i].page); - } - skb_shinfo(n)->nr_frags = i; - } -@@ -700,7 +700,7 @@ int pskb_expand_head(struct sk_buff *skb - memcpy(data + size, skb->end, sizeof(struct skb_shared_info)); - - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) -- get_page(skb_shinfo(skb)->frags[i].page); -+ net_get_page(skb_shinfo(skb)->frags[i].page); - - if (skb_shinfo(skb)->frag_list) - skb_clone_fraglist(skb); -@@ -882,7 +882,7 @@ drop_pages: - skb_shinfo(skb)->nr_frags = i; - - for (; i < nfrags; i++) -- put_page(skb_shinfo(skb)->frags[i].page); -+ net_put_page(skb_shinfo(skb)->frags[i].page); - - if (skb_shinfo(skb)->frag_list) - skb_drop_fraglist(skb); -@@ -1051,7 +1051,7 @@ pull_pages: - k = 0; - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - if (skb_shinfo(skb)->frags[i].size <= eat) { -- put_page(skb_shinfo(skb)->frags[i].page); -+ net_put_page(skb_shinfo(skb)->frags[i].page); - eat -= skb_shinfo(skb)->frags[i].size; - } else { - skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; -@@ -1633,7 +1633,7 @@ static inline void skb_split_no_header(s - * where splitting is expensive. - * 2. Split is accurately. We make this. - */ -- get_page(skb_shinfo(skb)->frags[i].page); -+ net_get_page(skb_shinfo(skb)->frags[i].page); - skb_shinfo(skb1)->frags[0].page_offset += len - pos; - skb_shinfo(skb1)->frags[0].size -= len - pos; - skb_shinfo(skb)->frags[i].size = len - pos; -@@ -2002,7 +2002,7 @@ struct sk_buff *skb_segment(struct sk_bu - BUG_ON(i >= nfrags); - - *frag = skb_shinfo(skb)->frags[i]; -- get_page(frag->page); -+ net_get_page(frag->page); - size = frag->size; - - if (pos < offset) { -diff -upr linux-2.6.18.1/net/core/utils.c linux-2.6.18.1/net/core/utils.c ---- linux-2.6.18.1/net/core/utils.c 2006-09-20 07:42:06.000000000 +0400 -+++ linux-2.6.18.1/net/core/utils.c 2007-08-23 19:49:40.000000000 +0400 -@@ -24,11 +24,15 @@ - #include <linux/random.h> - #include <linux/percpu.h> - #include <linux/init.h> -+#include <linux/skbuff.h> - - #include <asm/byteorder.h> - #include <asm/system.h> - #include <asm/uaccess.h> - -+net_get_page_callback_t net_get_page_callback __read_mostly; -+net_put_page_callback_t net_put_page_callback __read_mostly; -+ - /* - This is a maximally equidistributed combined Tausworthe generator - based on code from GNU Scientific Library 1.5 (30 Jun 2004) -@@ -191,3 +195,32 @@ __be32 in_aton(const char *str) - } - - EXPORT_SYMBOL(in_aton); -+ -+int net_set_get_put_page_callbacks( -+ net_get_page_callback_t get_callback, -+ net_put_page_callback_t put_callback) -+{ -+ int res = 0; -+ -+ if ((net_get_page_callback != NULL) && (get_callback != NULL) && -+ (net_get_page_callback != get_callback)) { -+ res = -EBUSY; -+ goto out; -+ } -+ -+ if ((net_put_page_callback != NULL) && (put_callback != NULL) && -+ (net_put_page_callback != put_callback)) { -+ res = -EBUSY; -+ goto out; -+ } -+ -+ net_get_page_callback = get_callback; -+ net_put_page_callback = put_callback; -+ -+out: -+ return res; -+} -+EXPORT_SYMBOL(net_set_get_put_page_callbacks); -+ -+EXPORT_SYMBOL(net_get_page_callback); -+EXPORT_SYMBOL(net_put_page_callback); -diff -upr linux-2.6.18.1/net/ipv4/ip_output.c linux-2.6.18.1/net/ipv4/ip_output.c ---- linux-2.6.18.1/net/ipv4/ip_output.c 2006-09-20 07:42:06.000000000 +0400 -+++ linux-2.6.18.1/net/ipv4/ip_output.c 2007-08-07 19:37:24.000000000 +0400 -@@ -999,7 +999,7 @@ alloc_new_skb: - err = -EMSGSIZE; - goto error; - } -- get_page(page); -+ net_get_page(page); - skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); - frag = &skb_shinfo(skb)->frags[i]; - } -@@ -1159,7 +1159,7 @@ ssize_t ip_append_page(struct sock *sk, - if (skb_can_coalesce(skb, i, page, offset)) { - skb_shinfo(skb)->frags[i-1].size += len; - } else if (i < MAX_SKB_FRAGS) { -- get_page(page); -+ net_get_page(page); - skb_fill_page_desc(skb, i, page, offset, len); - } else { - err = -EMSGSIZE; -diff -upr linux-2.6.18.1/net/ipv4/tcp.c linux-2.6.18.1/net/ipv4/tcp.c ---- linux-2.6.18.1/net/ipv4/tcp.c 2006-09-20 07:42:06.000000000 +0400 -+++ linux-2.6.18.1/net/ipv4/tcp.c 2007-08-07 19:35:51.000000000 +0400 -@@ -559,7 +559,7 @@ new_segment: - if (can_coalesce) { - skb_shinfo(skb)->frags[i - 1].size += copy; - } else { -- get_page(page); -+ net_get_page(page); - skb_fill_page_desc(skb, i, page, offset, copy); - } - -@@ -762,7 +762,7 @@ new_segment: - goto new_segment; - } else if (page) { - if (off == PAGE_SIZE) { -- put_page(page); -+ net_put_page(page); - TCP_PAGE(sk) = page = NULL; - off = 0; - } -@@ -803,9 +803,9 @@ new_segment: - } else { - skb_fill_page_desc(skb, i, page, off, copy); - if (TCP_PAGE(sk)) { -- get_page(page); -+ net_get_page(page); - } else if (off + copy < PAGE_SIZE) { -- get_page(page); -+ net_get_page(page); - TCP_PAGE(sk) = page; - } - } -diff -upr linux-2.6.18.1/net/ipv4/tcp_output.c linux-2.6.18.1/net/ipv4/tcp_output.c ---- linux-2.6.18.1/net/ipv4/tcp_output.c 2006-09-20 07:42:06.000000000 +0400 -+++ linux-2.6.18.1/net/ipv4/tcp_output.c 2007-08-07 19:35:51.000000000 +0400 -@@ -657,7 +657,7 @@ static void __pskb_trim_head(struct sk_b - k = 0; - for (i=0; i<skb_shinfo(skb)->nr_frags; i++) { - if (skb_shinfo(skb)->frags[i].size <= eat) { -- put_page(skb_shinfo(skb)->frags[i].page); -+ net_put_page(skb_shinfo(skb)->frags[i].page); - eat -= skb_shinfo(skb)->frags[i].size; - } else { - skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; -diff -upr linux-2.6.18.1/net/ipv6/ip6_output.c linux-2.6.18.1/net/ipv6/ip6_output.c ---- linux-2.6.18.1/net/ipv6/ip6_output.c 2006-09-20 07:42:06.000000000 +0400 -+++ linux-2.6.18.1/net/ipv6/ip6_output.c 2007-08-07 19:35:51.000000000 +0400 -@@ -1149,7 +1149,7 @@ alloc_new_skb: - err = -EMSGSIZE; - goto error; - } -- get_page(page); -+ net_get_page(page); - skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); - frag = &skb_shinfo(skb)->frags[i]; - } Copied: trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.21.1.patch (from rev 190, trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.21.patch) =================================================================== --- trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.21.1.patch (rev 0) +++ trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.21.1.patch 2007-09-28 13:57:06 UTC (rev 201) @@ -0,0 +1,259 @@ +diff -upr linux-2.6.21.1/include/linux/mm_types.h linux-2.6.21.1/include/linux/mm_types.h +--- linux-2.6.21.1/include/linux/mm_types.h 2007-04-28 01:49:26.000000000 +0400 ++++ linux-2.6.21.1/include/linux/mm_types.h 2007-07-04 12:56:56.000000000 +0400 +@@ -62,6 +62,15 @@ struct page { + void *virtual; /* Kernel virtual address (NULL if + not kmapped, ie. highmem) */ + #endif /* WANT_PAGE_VIRTUAL */ ++ /* ++ * Used to implement support for notification on zero-copy TCP transfer ++ * completeion. Not good to have this field here, it's better to have ++ * it in struct sk_buff, but it would make the code much more ++ * complicated and fragile, if maintained as a separate patch, since all ++ * skb then would have to contain only pages with the same value in this ++ * field. ++ */ ++ void *net_priv; + }; + + #endif /* _LINUX_MM_TYPES_H */ +diff -upr linux-2.6.21.1/include/linux/net.h linux-2.6.21.1/include/linux/net.h +--- linux-2.6.21.1/include/linux/net.h 2007-04-28 01:49:26.000000000 +0400 ++++ linux-2.6.21.1/include/linux/net.h 2007-08-29 14:57:06.000000000 +0400 +@@ -57,6 +57,7 @@ typedef enum { + #ifdef __KERNEL__ + #include <linux/stringify.h> + #include <linux/random.h> ++#include <linux/mm.h> + + #define SOCK_ASYNC_NOSPACE 0 + #define SOCK_ASYNC_WAITDATA 1 +@@ -319,5 +320,30 @@ extern int net_msg_cost; + extern int net_msg_burst; + #endif + ++/* Support for notification on zero-copy TCP transfer completeion */ ++#define NET_PAGE_CALLBACKS_DEFINED ++typedef void (*net_get_page_callback_t)(struct page *page); ++typedef void (*net_put_page_callback_t)(struct page *page); ++ ++extern net_get_page_callback_t net_get_page_callback; ++extern net_put_page_callback_t net_put_page_callback; ++ ++extern int net_set_get_put_page_callbacks( ++ net_get_page_callback_t get_callback, ++ net_put_page_callback_t put_callback); ++ ++static inline void net_get_page(struct page *page) ++{ ++ if (page->net_priv != 0) ++ net_get_page_callback(page); ++ get_page(page); ++} ++static inline void net_put_page(struct page *page) ++{ ++ if (page->net_priv != 0) ++ net_put_page_callback(page); ++ put_page(page); ++} ++ + #endif /* __KERNEL__ */ + #endif /* _LINUX_NET_H */ +diff -upr linux-2.6.21.1/net/core/skbuff.c linux-2.6.21.1/net/core/skbuff.c +--- linux-2.6.21.1/net/core/skbuff.c 2007-04-28 01:49:26.000000000 +0400 ++++ linux-2.6.21.1/net/core/skbuff.c 2007-07-04 13:18:04.000000000 +0400 +@@ -257,7 +257,7 @@ static void skb_release_data(struct sk_b + if (skb_shinfo(skb)->nr_frags) { + int i; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + } + + if (skb_shinfo(skb)->frag_list) +@@ -596,7 +596,7 @@ struct sk_buff *pskb_copy(struct sk_buff + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i]; +- get_page(skb_shinfo(n)->frags[i].page); ++ net_get_page(skb_shinfo(n)->frags[i].page); + } + skb_shinfo(n)->nr_frags = i; + } +@@ -650,7 +650,7 @@ int pskb_expand_head(struct sk_buff *skb + memcpy(data + size, skb->end, sizeof(struct skb_shared_info)); + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) +- get_page(skb_shinfo(skb)->frags[i].page); ++ net_get_page(skb_shinfo(skb)->frags[i].page); + + if (skb_shinfo(skb)->frag_list) + skb_clone_fraglist(skb); +@@ -832,7 +832,7 @@ drop_pages: + skb_shinfo(skb)->nr_frags = i; + + for (; i < nfrags; i++) +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + + if (skb_shinfo(skb)->frag_list) + skb_drop_fraglist(skb); +@@ -1001,7 +1001,7 @@ pull_pages: + k = 0; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + if (skb_shinfo(skb)->frags[i].size <= eat) { +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + eat -= skb_shinfo(skb)->frags[i].size; + } else { + skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; +@@ -1583,7 +1583,7 @@ static inline void skb_split_no_header(s + * where splitting is expensive. + * 2. Split is accurately. We make this. + */ +- get_page(skb_shinfo(skb)->frags[i].page); ++ net_get_page(skb_shinfo(skb)->frags[i].page); + skb_shinfo(skb1)->frags[0].page_offset += len - pos; + skb_shinfo(skb1)->frags[0].size -= len - pos; + skb_shinfo(skb)->frags[i].size = len - pos; +@@ -1951,7 +1951,7 @@ struct sk_buff *skb_segment(struct sk_bu + BUG_ON(i >= nfrags); + + *frag = skb_shinfo(skb)->frags[i]; +- get_page(frag->page); ++ net_get_page(frag->page); + size = frag->size; + + if (pos < offset) { +diff -upr linux-2.6.21.1/net/core/utils.c linux-2.6.21.1/net/core/utils.c +--- linux-2.6.21.1/net/core/utils.c 2007-04-28 01:49:26.000000000 +0400 ++++ linux-2.6.21.1/net/core/utils.c 2007-08-23 19:38:32.000000000 +0400 +@@ -25,6 +25,7 @@ + #include <linux/random.h> + #include <linux/percpu.h> + #include <linux/init.h> ++#include <linux/skbuff.h> + + #include <asm/byteorder.h> + #include <asm/system.h> +@@ -33,6 +34,9 @@ + int net_msg_cost = 5*HZ; + int net_msg_burst = 10; + ++net_get_page_callback_t net_get_page_callback __read_mostly; ++net_put_page_callback_t net_put_page_callback __read_mostly; ++ + /* + * All net warning printk()s should be guarded by this function. + */ +@@ -290,3 +294,32 @@ out: + } + + EXPORT_SYMBOL(in6_pton); ++ ++int net_set_get_put_page_callbacks( ++ net_get_page_callback_t get_callback, ++ net_put_page_callback_t put_callback) ++{ ++ int res = 0; ++ ++ if ((net_get_page_callback != NULL) && (get_callback != NULL) && ++ (net_get_page_callback != get_callback)) { ++ res = -EBUSY; ++ goto out; ++ } ++ ++ if ((net_put_page_callback != NULL) && (put_callback != NULL) && ++ (net_put_page_callback != put_callback)) { ++ res = -EBUSY; ++ goto out; ++ } ++ ++ net_get_page_callback = get_callback; ++ net_put_page_callback = put_callback; ++ ++out: ++ return res; ++} ++EXPORT_SYMBOL(net_set_get_put_page_callbacks); ++ ++EXPORT_SYMBOL(net_get_page_callback); ++EXPORT_SYMBOL(net_put_page_callback); +diff -upr linux-2.6.21.1/net/ipv4/ip_output.c linux-2.6.21.1/net/ipv4/ip_output.c +--- linux-2.6.21.1/net/ipv4/ip_output.c 2007-04-28 01:49:26.000000000 +0400 ++++ linux-2.6.21.1/net/ipv4/ip_output.c 2007-07-04 13:17:53.000000000 +0400 +@@ -991,7 +991,7 @@ alloc_new_skb: + err = -EMSGSIZE; + goto error; + } +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); + frag = &skb_shinfo(skb)->frags[i]; + } +@@ -1151,7 +1151,7 @@ ssize_t ip_append_page(struct sock *sk, + if (skb_can_coalesce(skb, i, page, offset)) { + skb_shinfo(skb)->frags[i-1].size += len; + } else if (i < MAX_SKB_FRAGS) { +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, offset, len); + } else { + err = -EMSGSIZE; +diff -upr linux-2.6.21.1/net/ipv4/tcp.c linux-2.6.21.1/net/ipv4/tcp.c +--- linux-2.6.21.1/net/ipv4/tcp.c 2007-04-28 01:49:26.000000000 +0400 ++++ linux-2.6.21.1/net/ipv4/tcp.c 2007-07-04 13:17:58.000000000 +0400 +@@ -561,7 +561,7 @@ new_segment: + if (can_coalesce) { + skb_shinfo(skb)->frags[i - 1].size += copy; + } else { +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, offset, copy); + } + +@@ -764,7 +764,7 @@ new_segment: + goto new_segment; + } else if (page) { + if (off == PAGE_SIZE) { +- put_page(page); ++ net_put_page(page); + TCP_PAGE(sk) = page = NULL; + off = 0; + } +@@ -805,9 +805,9 @@ new_segment: + } else { + skb_fill_page_desc(skb, i, page, off, copy); + if (TCP_PAGE(sk)) { +- get_page(page); ++ net_get_page(page); + } else if (off + copy < PAGE_SIZE) { +- get_page(page); ++ net_get_page(page); + TCP_PAGE(sk) = page; + } + } +diff -upr linux-2.6.21.1/net/ipv4/tcp_output.c linux-2.6.21.1/net/ipv4/tcp_output.c +--- linux-2.6.21.1/net/ipv4/tcp_output.c 2007-04-28 01:49:26.000000000 +0400 ++++ linux-2.6.21.1/net/ipv4/tcp_output.c 2007-07-04 13:17:05.000000000 +0400 +@@ -722,7 +722,7 @@ static void __pskb_trim_head(struct sk_b + k = 0; + for (i=0; i<skb_shinfo(skb)->nr_frags; i++) { + if (skb_shinfo(skb)->frags[i].size <= eat) { +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + eat -= skb_shinfo(skb)->frags[i].size; + } else { + skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; +diff -upr linux-2.6.21.1/net/ipv6/ip6_output.c linux-2.6.21.1/net/ipv6/ip6_output.c +--- linux-2.6.21.1/net/ipv6/ip6_output.c 2007-04-28 01:49:26.000000000 +0400 ++++ linux-2.6.21.1/net/ipv6/ip6_output.c 2007-07-04 13:17:49.000000000 +0400 +@@ -1227,7 +1227,7 @@ alloc_new_skb: + err = -EMSGSIZE; + goto error; + } +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); + frag = &skb_shinfo(skb)->frags[i]; + } Deleted: trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.21.patch =================================================================== --- trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.21.patch 2007-09-25 13:39:25 UTC (rev 200) +++ trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.21.patch 2007-09-28 13:57:06 UTC (rev 201) @@ -1,259 +0,0 @@ -diff -upr linux-2.6.21.1/include/linux/mm_types.h linux-2.6.21.1/include/linux/mm_types.h ---- linux-2.6.21.1/include/linux/mm_types.h 2007-04-28 01:49:26.000000000 +0400 -+++ linux-2.6.21.1/include/linux/mm_types.h 2007-07-04 12:56:56.000000000 +0400 -@@ -62,6 +62,15 @@ struct page { - void *virtual; /* Kernel virtual address (NULL if - not kmapped, ie. highmem) */ - #endif /* WANT_PAGE_VIRTUAL */ -+ /* -+ * Used to implement support for notification on zero-copy TCP transfer -+ * completeion. Not good to have this field here, it's better to have -+ * it in struct sk_buff, but it would make the code much more -+ * complicated and fragile, if maintained as a separate patch, since all -+ * skb then would have to contain only pages with the same value in this -+ * field. -+ */ -+ void *net_priv; - }; - - #endif /* _LINUX_MM_TYPES_H */ -diff -upr linux-2.6.21.1/include/linux/net.h linux-2.6.21.1/include/linux/net.h ---- linux-2.6.21.1/include/linux/net.h 2007-04-28 01:49:26.000000000 +0400 -+++ linux-2.6.21.1/include/linux/net.h 2007-08-29 14:57:06.000000000 +0400 -@@ -57,6 +57,7 @@ typedef enum { - #ifdef __KERNEL__ - #include <linux/stringify.h> - #include <linux/random.h> -+#include <linux/mm.h> - - #define SOCK_ASYNC_NOSPACE 0 - #define SOCK_ASYNC_WAITDATA 1 -@@ -319,5 +320,30 @@ extern int net_msg_cost; - extern int net_msg_burst; - #endif - -+/* Support for notification on zero-copy TCP transfer completeion */ -+#define NET_PAGE_CALLBACKS_DEFINED -+typedef void (*net_get_page_callback_t)(struct page *page); -+typedef void (*net_put_page_callback_t)(struct page *page); -+ -+extern net_get_page_callback_t net_get_page_callback; -+extern net_put_page_callback_t net_put_page_callback; -+ -+extern int net_set_get_put_page_callbacks( -+ net_get_page_callback_t get_callback, -+ net_put_page_callback_t put_callback); -+ -+static inline void net_get_page(struct page *page) -+{ -+ if (page->net_priv != 0) -+ net_get_page_callback(page); -+ get_page(page); -+} -+static inline void net_put_page(struct page *page) -+{ -+ if (page->net_priv != 0) -+ net_put_page_callback(page); -+ put_page(page); -+} -+ - #endif /* __KERNEL__ */ - #endif /* _LINUX_NET_H */ -diff -upr linux-2.6.21.1/net/core/skbuff.c linux-2.6.21.1/net/core/skbuff.c ---- linux-2.6.21.1/net/core/skbuff.c 2007-04-28 01:49:26.000000000 +0400 -+++ linux-2.6.21.1/net/core/skbuff.c 2007-07-04 13:18:04.000000000 +0400 -@@ -257,7 +257,7 @@ static void skb_release_data(struct sk_b - if (skb_shinfo(skb)->nr_frags) { - int i; - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) -- put_page(skb_shinfo(skb)->frags[i].page); -+ net_put_page(skb_shinfo(skb)->frags[i].page); - } - - if (skb_shinfo(skb)->frag_list) -@@ -596,7 +596,7 @@ struct sk_buff *pskb_copy(struct sk_buff - - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i]; -- get_page(skb_shinfo(n)->frags[i].page); -+ net_get_page(skb_shinfo(n)->frags[i].page); - } - skb_shinfo(n)->nr_frags = i; - } -@@ -650,7 +650,7 @@ int pskb_expand_head(struct sk_buff *skb - memcpy(data + size, skb->end, sizeof(struct skb_shared_info)); - - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) -- get_page(skb_shinfo(skb)->frags[i].page); -+ net_get_page(skb_shinfo(skb)->frags[i].page); - - if (skb_shinfo(skb)->frag_list) - skb_clone_fraglist(skb); -@@ -832,7 +832,7 @@ drop_pages: - skb_shinfo(skb)->nr_frags = i; - - for (; i < nfrags; i++) -- put_page(skb_shinfo(skb)->frags[i].page); -+ net_put_page(skb_shinfo(skb)->frags[i].page); - - if (skb_shinfo(skb)->frag_list) - skb_drop_fraglist(skb); -@@ -1001,7 +1001,7 @@ pull_pages: - k = 0; - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - if (skb_shinfo(skb)->frags[i].size <= eat) { -- put_page(skb_shinfo(skb)->frags[i].page); -+ net_put_page(skb_shinfo(skb)->frags[i].page); - eat -= skb_shinfo(skb)->frags[i].size; - } else { - skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; -@@ -1583,7 +1583,7 @@ static inline void skb_split_no_header(s - * where splitting is expensive. - * 2. Split is accurately. We make this. - */ -- get_page(skb_shinfo(skb)->frags[i].page); -+ net_get_page(skb_shinfo(skb)->frags[i].page); - skb_shinfo(skb1)->frags[0].page_offset += len - pos; - skb_shinfo(skb1)->frags[0].size -= len - pos; - skb_shinfo(skb)->frags[i].size = len - pos; -@@ -1951,7 +1951,7 @@ struct sk_buff *skb_segment(struct sk_bu - BUG_ON(i >= nfrags); - - *frag = skb_shinfo(skb)->frags[i]; -- get_page(frag->page); -+ net_get_page(frag->page); - size = frag->size; - - if (pos < offset) { -diff -upr linux-2.6.21.1/net/core/utils.c linux-2.6.21.1/net/core/utils.c ---- linux-2.6.21.1/net/core/utils.c 2007-04-28 01:49:26.000000000 +0400 -+++ linux-2.6.21.1/net/core/utils.c 2007-08-23 19:38:32.000000000 +0400 -@@ -25,6 +25,7 @@ - #include <linux/random.h> - #include <linux/percpu.h> - #include <linux/init.h> -+#include <linux/skbuff.h> - - #include <asm/byteorder.h> - #include <asm/system.h> -@@ -33,6 +34,9 @@ - int net_msg_cost = 5*HZ; - int net_msg_burst = 10; - -+net_get_page_callback_t net_get_page_callback __read_mostly; -+net_put_page_callback_t net_put_page_callback __read_mostly; -+ - /* - * All net warning printk()s should be guarded by this function. - */ -@@ -290,3 +294,32 @@ out: - } - - EXPORT_SYMBOL(in6_pton); -+ -+int net_set_get_put_page_callbacks( -+ net_get_page_callback_t get_callback, -+ net_put_page_callback_t put_callback) -+{ -+ int res = 0; -+ -+ if ((net_get_page_callback != NULL) && (get_callback != NULL) && -+ (net_get_page_callback != get_callback)) { -+ res = -EBUSY; -+ goto out; -+ } -+ -+ if ((net_put_page_callback != NULL) && (put_callback != NULL) && -+ (net_put_page_callback != put_callback)) { -+ res = -EBUSY; -+ goto out; -+ } -+ -+ net_get_page_callback = get_callback; -+ net_put_page_callback = put_callback; -+ -+out: -+ return res; -+} -+EXPORT_SYMBOL(net_set_get_put_page_callbacks); -+ -+EXPORT_SYMBOL(net_get_page_callback); -+EXPORT_SYMBOL(net_put_page_callback); -diff -upr linux-2.6.21.1/net/ipv4/ip_output.c linux-2.6.21.1/net/ipv4/ip_output.c ---- linux-2.6.21.1/net/ipv4/ip_output.c 2007-04-28 01:49:26.000000000 +0400 -+++ linux-2.6.21.1/net/ipv4/ip_output.c 2007-07-04 13:17:53.000000000 +0400 -@@ -991,7 +991,7 @@ alloc_new_skb: - err = -EMSGSIZE; - goto error; - } -- get_page(page); -+ net_get_page(page); - skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); - frag = &skb_shinfo(skb)->frags[i]; - } -@@ -1151,7 +1151,7 @@ ssize_t ip_append_page(struct sock *sk, - if (skb_can_coalesce(skb, i, page, offset)) { - skb_shinfo(skb)->frags[i-1].size += len; - } else if (i < MAX_SKB_FRAGS) { -- get_page(page); -+ net_get_page(page); - skb_fill_page_desc(skb, i, page, offset, len); - } else { - err = -EMSGSIZE; -diff -upr linux-2.6.21.1/net/ipv4/tcp.c linux-2.6.21.1/net/ipv4/tcp.c ---- linux-2.6.21.1/net/ipv4/tcp.c 2007-04-28 01:49:26.000000000 +0400 -+++ linux-2.6.21.1/net/ipv4/tcp.c 2007-07-04 13:17:58.000000000 +0400 -@@ -561,7 +561,7 @@ new_segment: - if (can_coalesce) { - skb_shinfo(skb)->frags[i - 1].size += copy; - } else { -- get_page(page); -+ net_get_page(page); - skb_fill_page_desc(skb, i, page, offset, copy); - } - -@@ -764,7 +764,7 @@ new_segment: - goto new_segment; - } else if (page) { - if (off == PAGE_SIZE) { -- put_page(page); -+ net_put_page(page); - TCP_PAGE(sk) = page = NULL; - off = 0; - } -@@ -805,9 +805,9 @@ new_segment: - } else { - skb_fill_page_desc(skb, i, page, off, copy); - if (TCP_PAGE(sk)) { -- get_page(page); -+ net_get_page(page); - } else if (off + copy < PAGE_SIZE) { -- get_page(page); -+ net_get_page(page); - TCP_PAGE(sk) = page; - } - } -diff -upr linux-2.6.21.1/net/ipv4/tcp_output.c linux-2.6.21.1/net/ipv4/tcp_output.c ---- linux-2.6.21.1/net/ipv4/tcp_output.c 2007-04-28 01:49:26.000000000 +0400 -+++ linux-2.6.21.1/net/ipv4/tcp_output.c 2007-07-04 13:17:05.000000000 +0400 -@@ -722,7 +722,7 @@ static void __pskb_trim_head(struct sk_b - k = 0; - for (i=0; i<skb_shinfo(skb)->nr_frags; i++) { - if (skb_shinfo(skb)->frags[i].size <= eat) { -- put_page(skb_shinfo(skb)->frags[i].page); -+ net_put_page(skb_shinfo(skb)->frags[i].page); - eat -= skb_shinfo(skb)->frags[i].size; - } else { - skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; -diff -upr linux-2.6.21.1/net/ipv6/ip6_output.c linux-2.6.21.1/net/ipv6/ip6_output.c ---- linux-2.6.21.1/net/ipv6/ip6_output.c 2007-04-28 01:49:26.000000000 +0400 -+++ linux-2.6.21.1/net/ipv6/ip6_output.c 2007-07-04 13:17:49.000000000 +0400 -@@ -1227,7 +1227,7 @@ alloc_new_skb: - err = -EMSGSIZE; - goto error; - } -- get_page(page); -+ net_get_page(page); - skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); - frag = &skb_shinfo(skb)->frags[i]; - } Modified: trunk/usr/fileio/fileio.c =================================================================== --- trunk/usr/fileio/fileio.c 2007-09-25 13:39:25 UTC (rev 200) +++ trunk/usr/fileio/fileio.c 2007-09-28 13:57:06 UTC (rev 201) @@ -46,7 +46,7 @@ ~TRACE_SCSI & ~TRACE_SCSI_SERIALIZING & ~TRACE_DEBUG) */ #define DEFAULT_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MINOR | TRACE_PID | \ - TRACE_FUNCTION | TRACE_SPECIAL | TRACE_MGMT | TRACE_MGMT_DEBUG | TRACE_ORDER | \ + TRACE_FUNCTION | TRACE_SPECIAL | TRACE_MGMT | TRACE_MGMT_DEBUG | \ TRACE_TIME) #define TRACE_SN(args...) TRACE(TRACE_SCSI_SERIALIZING, args) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2007-10-23 15:35:25
|
Revision: 209 http://scst.svn.sourceforge.net/scst/?rev=209&view=rev Author: vlnb Date: 2007-10-23 08:35:20 -0700 (Tue, 23 Oct 2007) Log Message: ----------- Update to work on 2.6.23+ kernels + some other related fixes and updates Modified Paths: -------------- trunk/iscsi-scst/kernel/iscsi.c trunk/qla2x00t/qla2x00-target/qla2x00t.c trunk/qla2x00t/qla_attr.c trunk/qla2x00t/qla_os.c trunk/scst/include/scsi_tgt.h trunk/scst/include/scst_debug.h trunk/scst/src/dev_handlers/scst_user.c trunk/scst/src/dev_handlers/scst_vdisk.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_main.c trunk/scst/src/scst_mem.c trunk/scst/src/scst_mem.h trunk/scst/src/scst_proc.c Added Paths: ----------- trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.23.patch trunk/scst/kernel/scst_exec_req_fifo-2.6.23.patch Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2007-10-23 09:51:55 UTC (rev 208) +++ trunk/iscsi-scst/kernel/iscsi.c 2007-10-23 15:35:20 UTC (rev 209) @@ -2471,8 +2471,7 @@ if ((err = event_init()) < 0) goto out_reg; - iscsi_cmnd_cache = kmem_cache_create("scst_iscsi_cmnd", - sizeof(struct iscsi_cmnd), 0, 0, NULL, NULL); + iscsi_cmnd_cache = KMEM_CACHE(iscsi_cmnd, SCST_SLAB_FLAGS); if (!iscsi_cmnd_cache) { err = -ENOMEM; goto out_event; Added: trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.23.patch =================================================================== --- trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.23.patch (rev 0) +++ trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.23.patch 2007-10-23 15:35:20 UTC (rev 209) @@ -0,0 +1,259 @@ +diff -upkr linux-2.6.23/include/linux/mm_types.h linux-2.6.23/include/linux/mm_types.h +--- linux-2.6.23/include/linux/mm_types.h 2007-10-10 00:31:38.000000000 +0400 ++++ linux-2.6.23/include/linux/mm_types.h 2007-10-10 13:42:46.000000000 +0400 +@@ -78,6 +78,15 @@ struct page { + void *virtual; /* Kernel virtual address (NULL if + not kmapped, ie. highmem) */ + #endif /* WANT_PAGE_VIRTUAL */ ++ /* ++ * Used to implement support for notification on zero-copy TCP transfer ++ * completeion. Not good to have this field here, it's better to have ++ * it in struct sk_buff, but it would make the code much more ++ * complicated and fragile, if maintained as a separate patch, since all ++ * skb then would have to contain only pages with the same value in this ++ * field. ++ */ ++ void *net_priv; + }; + + #endif /* _LINUX_MM_TYPES_H */ +diff -upkr linux-2.6.23/include/linux/net.h linux-2.6.23/include/linux/net.h +--- linux-2.6.23/include/linux/net.h 2007-10-10 00:31:38.000000000 +0400 ++++ linux-2.6.23/include/linux/net.h 2007-10-10 13:42:46.000000000 +0400 +@@ -57,6 +57,7 @@ typedef enum { + #ifdef __KERNEL__ + #include <linux/stringify.h> + #include <linux/random.h> ++#include <linux/mm.h> + + #define SOCK_ASYNC_NOSPACE 0 + #define SOCK_ASYNC_WAITDATA 1 +@@ -319,5 +320,30 @@ extern int net_msg_cost; + extern int net_msg_burst; + #endif + ++/* Support for notification on zero-copy TCP transfer completeion */ ++#define NET_PAGE_CALLBACKS_DEFINED ++typedef void (*net_get_page_callback_t)(struct page *page); ++typedef void (*net_put_page_callback_t)(struct page *page); ++ ++extern net_get_page_callback_t net_get_page_callback; ++extern net_put_page_callback_t net_put_page_callback; ++ ++extern int net_set_get_put_page_callbacks( ++ net_get_page_callback_t get_callback, ++ net_put_page_callback_t put_callback); ++ ++static inline void net_get_page(struct page *page) ++{ ++ if (page->net_priv != 0) ++ net_get_page_callback(page); ++ get_page(page); ++} ++static inline void net_put_page(struct page *page) ++{ ++ if (page->net_priv != 0) ++ net_put_page_callback(page); ++ put_page(page); ++} ++ + #endif /* __KERNEL__ */ + #endif /* _LINUX_NET_H */ +diff -upkr linux-2.6.23/net/core/skbuff.c linux-2.6.23/net/core/skbuff.c +--- linux-2.6.23/net/core/skbuff.c 2007-10-10 00:31:38.000000000 +0400 ++++ linux-2.6.23/net/core/skbuff.c 2007-10-10 13:42:46.000000000 +0400 +@@ -262,7 +262,7 @@ static void skb_release_data(struct sk_b + if (skb_shinfo(skb)->nr_frags) { + int i; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + } + + if (skb_shinfo(skb)->frag_list) +@@ -601,7 +601,7 @@ struct sk_buff *pskb_copy(struct sk_buff + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i]; +- get_page(skb_shinfo(n)->frags[i].page); ++ net_get_page(skb_shinfo(n)->frags[i].page); + } + skb_shinfo(n)->nr_frags = i; + } +@@ -664,7 +664,7 @@ int pskb_expand_head(struct sk_buff *skb + sizeof(struct skb_shared_info)); + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) +- get_page(skb_shinfo(skb)->frags[i].page); ++ net_get_page(skb_shinfo(skb)->frags[i].page); + + if (skb_shinfo(skb)->frag_list) + skb_clone_fraglist(skb); +@@ -862,7 +862,7 @@ drop_pages: + skb_shinfo(skb)->nr_frags = i; + + for (; i < nfrags; i++) +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + + if (skb_shinfo(skb)->frag_list) + skb_drop_fraglist(skb); +@@ -1031,7 +1031,7 @@ pull_pages: + k = 0; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + if (skb_shinfo(skb)->frags[i].size <= eat) { +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + eat -= skb_shinfo(skb)->frags[i].size; + } else { + skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; +@@ -1600,7 +1600,7 @@ static inline void skb_split_no_header(s + * where splitting is expensive. + * 2. Split is accurately. We make this. + */ +- get_page(skb_shinfo(skb)->frags[i].page); ++ net_get_page(skb_shinfo(skb)->frags[i].page); + skb_shinfo(skb1)->frags[0].page_offset += len - pos; + skb_shinfo(skb1)->frags[0].size -= len - pos; + skb_shinfo(skb)->frags[i].size = len - pos; +@@ -1976,7 +1976,7 @@ struct sk_buff *skb_segment(struct sk_bu + BUG_ON(i >= nfrags); + + *frag = skb_shinfo(skb)->frags[i]; +- get_page(frag->page); ++ net_get_page(frag->page); + size = frag->size; + + if (pos < offset) { +diff -upkr linux-2.6.23/net/core/utils.c linux-2.6.23/net/core/utils.c +--- linux-2.6.23/net/core/utils.c 2007-10-10 00:31:38.000000000 +0400 ++++ linux-2.6.23/net/core/utils.c 2007-10-10 13:43:13.000000000 +0400 +@@ -25,6 +25,7 @@ + #include <linux/random.h> + #include <linux/percpu.h> + #include <linux/init.h> ++#include <linux/skbuff.h> + #include <net/sock.h> + + #include <asm/byteorder.h> +@@ -36,6 +37,9 @@ int net_msg_burst __read_mostly = 10; + int net_msg_warn __read_mostly = 1; + EXPORT_SYMBOL(net_msg_warn); + ++net_get_page_callback_t net_get_page_callback __read_mostly; ++net_put_page_callback_t net_put_page_callback __read_mostly; ++ + /* + * All net warning printk()s should be guarded by this function. + */ +@@ -293,3 +297,32 @@ out: + } + + EXPORT_SYMBOL(in6_pton); ++ ++int net_set_get_put_page_callbacks( ++ net_get_page_callback_t get_callback, ++ net_put_page_callback_t put_callback) ++{ ++ int res = 0; ++ ++ if ((net_get_page_callback != NULL) && (get_callback != NULL) && ++ (net_get_page_callback != get_callback)) { ++ res = -EBUSY; ++ goto out; ++ } ++ ++ if ((net_put_page_callback != NULL) && (put_callback != NULL) && ++ (net_put_page_callback != put_callback)) { ++ res = -EBUSY; ++ goto out; ++ } ++ ++ net_get_page_callback = get_callback; ++ net_put_page_callback = put_callback; ++ ++out: ++ return res; ++} ++EXPORT_SYMBOL(net_set_get_put_page_callbacks); ++ ++EXPORT_SYMBOL(net_get_page_callback); ++EXPORT_SYMBOL(net_put_page_callback); +diff -upkr linux-2.6.23/net/ipv4/ip_output.c linux-2.6.23/net/ipv4/ip_output.c +--- linux-2.6.23/net/ipv4/ip_output.c 2007-10-10 00:31:38.000000000 +0400 ++++ linux-2.6.23/net/ipv4/ip_output.c 2007-10-10 13:42:46.000000000 +0400 +@@ -999,7 +999,7 @@ alloc_new_skb: + err = -EMSGSIZE; + goto error; + } +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); + frag = &skb_shinfo(skb)->frags[i]; + } +@@ -1157,7 +1157,7 @@ ssize_t ip_append_page(struct sock *sk, + if (skb_can_coalesce(skb, i, page, offset)) { + skb_shinfo(skb)->frags[i-1].size += len; + } else if (i < MAX_SKB_FRAGS) { +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, offset, len); + } else { + err = -EMSGSIZE; +diff -upkr linux-2.6.23/net/ipv4/tcp.c linux-2.6.23/net/ipv4/tcp.c +--- linux-2.6.23/net/ipv4/tcp.c 2007-10-10 00:31:38.000000000 +0400 ++++ linux-2.6.23/net/ipv4/tcp.c 2007-10-10 13:42:46.000000000 +0400 +@@ -560,7 +560,7 @@ new_segment: + if (can_coalesce) { + skb_shinfo(skb)->frags[i - 1].size += copy; + } else { +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, offset, copy); + } + +@@ -765,7 +765,7 @@ new_segment: + goto new_segment; + } else if (page) { + if (off == PAGE_SIZE) { +- put_page(page); ++ net_put_page(page); + TCP_PAGE(sk) = page = NULL; + off = 0; + } +@@ -806,9 +806,9 @@ new_segment: + } else { + skb_fill_page_desc(skb, i, page, off, copy); + if (TCP_PAGE(sk)) { +- get_page(page); ++ net_get_page(page); + } else if (off + copy < PAGE_SIZE) { +- get_page(page); ++ net_get_page(page); + TCP_PAGE(sk) = page; + } + } +diff -upkr linux-2.6.23/net/ipv4/tcp_output.c linux-2.6.23/net/ipv4/tcp_output.c +--- linux-2.6.23/net/ipv4/tcp_output.c 2007-10-10 00:31:38.000000000 +0400 ++++ linux-2.6.23/net/ipv4/tcp_output.c 2007-10-10 13:42:46.000000000 +0400 +@@ -729,7 +729,7 @@ static void __pskb_trim_head(struct sk_b + k = 0; + for (i=0; i<skb_shinfo(skb)->nr_frags; i++) { + if (skb_shinfo(skb)->frags[i].size <= eat) { +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + eat -= skb_shinfo(skb)->frags[i].size; + } else { + skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; +diff -upkr linux-2.6.23/net/ipv6/ip6_output.c linux-2.6.23/net/ipv6/ip6_output.c +--- linux-2.6.23/net/ipv6/ip6_output.c 2007-10-10 00:31:38.000000000 +0400 ++++ linux-2.6.23/net/ipv6/ip6_output.c 2007-10-10 13:42:46.000000000 +0400 +@@ -1295,7 +1295,7 @@ alloc_new_skb: + err = -EMSGSIZE; + goto error; + } +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); + frag = &skb_shinfo(skb)->frags[i]; + } Modified: trunk/qla2x00t/qla2x00-target/qla2x00t.c =================================================================== --- trunk/qla2x00t/qla2x00-target/qla2x00t.c 2007-10-23 09:51:55 UTC (rev 208) +++ trunk/qla2x00t/qla2x00-target/qla2x00t.c 2007-10-23 15:35:20 UTC (rev 209) @@ -47,15 +47,6 @@ #error "FC_TARGET_SUPPORT is NOT DEFINED" #endif -/* - * Whether to use slab cach instead of kmalloc/kfree - */ -#if defined(DEBUG) && defined(CONFIG_DEBUG_SLAB) -#define Q2T_CACHE_FLAGS ( SLAB_RED_ZONE | SLAB_POISON ) -#else -#define Q2T_CACHE_FLAGS 0L -#endif - #ifdef DEBUG #define Q2T_DEFAULT_LOG_FLAGS (TRACE_FUNCTION | TRACE_PID | \ TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MGMT_DEBUG | \ @@ -2206,9 +2197,7 @@ TRACE_ENTRY(); - q2t_cmd_cachep = kmem_cache_create("q2t_cmd_struct", - sizeof(struct q2t_cmd), - 0, Q2T_CACHE_FLAGS, NULL, NULL); + q2t_cmd_cachep = KMEM_CACHE(q2t_cmd, SCST_SLAB_FLAGS); if (q2t_cmd_cachep == NULL) { res = -ENOMEM; goto out; Modified: trunk/qla2x00t/qla_attr.c =================================================================== --- trunk/qla2x00t/qla_attr.c 2007-10-23 09:51:55 UTC (rev 208) +++ trunk/qla2x00t/qla_attr.c 2007-10-23 15:35:20 UTC (rev 209) @@ -321,9 +321,15 @@ qla2x00_update_portdb); #endif +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) static ssize_t qla2x00_sysfs_read_fw_dump(struct kobject *kobj, char *buf, loff_t off, size_t count) +#else +static ssize_t +qla2x00_sysfs_read_fw_dump(struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +#endif { struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, struct device, kobj))); @@ -340,9 +346,15 @@ return (count); } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) static ssize_t qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off, size_t count) +#else +static ssize_t +qla2x00_sysfs_write_fw_dump(struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +#endif { struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, struct device, kobj))); @@ -419,9 +431,15 @@ .write = qla2x00_sysfs_write_fw_dump, }; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) static ssize_t qla2x00_sysfs_read_nvram(struct kobject *kobj, char *buf, loff_t off, size_t count) +#else +static ssize_t +qla2x00_sysfs_read_nvram(struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +#endif { struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, struct device, kobj))); @@ -439,9 +457,15 @@ return ha->nvram_size; } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) static ssize_t qla2x00_sysfs_write_nvram(struct kobject *kobj, char *buf, loff_t off, size_t count) +#else +static ssize_t +qla2x00_sysfs_write_nvram(struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +#endif { struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, struct device, kobj))); @@ -493,9 +517,15 @@ .write = qla2x00_sysfs_write_nvram, }; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) static ssize_t qla2x00_sysfs_read_optrom(struct kobject *kobj, char *buf, loff_t off, size_t count) +#else +static ssize_t +qla2x00_sysfs_read_optrom(struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +#endif { struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, struct device, kobj))); @@ -512,9 +542,15 @@ return count; } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) static ssize_t qla2x00_sysfs_write_optrom(struct kobject *kobj, char *buf, loff_t off, size_t count) +#else +static ssize_t +qla2x00_sysfs_write_optrom(struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +#endif { struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, struct device, kobj))); @@ -542,9 +578,15 @@ .write = qla2x00_sysfs_write_optrom, }; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) static ssize_t qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, char *buf, loff_t off, size_t count) +#else +static ssize_t +qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +#endif { struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, struct device, kobj))); @@ -622,9 +664,15 @@ .write = qla2x00_sysfs_write_optrom_ctl, }; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) static ssize_t qla2x00_sysfs_read_vpd(struct kobject *kobj, char *buf, loff_t off, size_t count) +#else +static ssize_t +qla2x00_sysfs_read_vpd(struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +#endif { struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, struct device, kobj))); @@ -644,9 +692,15 @@ return ha->vpd_size; } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) static ssize_t qla2x00_sysfs_write_vpd(struct kobject *kobj, char *buf, loff_t off, size_t count) +#else +static ssize_t +qla2x00_sysfs_write_vpd(struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +#endif { struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, struct device, kobj))); Modified: trunk/qla2x00t/qla_os.c =================================================================== --- trunk/qla2x00t/qla_os.c 2007-10-23 09:51:55 UTC (rev 208) +++ trunk/qla2x00t/qla_os.c 2007-10-23 15:35:20 UTC (rev 209) @@ -2775,7 +2775,12 @@ /* Allocate cache for SRBs. */ srb_cachep = kmem_cache_create("qla2xxx_srbs", sizeof(srb_t), 0, - SLAB_HWCACHE_ALIGN, NULL, NULL); + SLAB_HWCACHE_ALIGN, NULL +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) + , NULL); +#else + ); +#endif if (srb_cachep == NULL) { printk(KERN_ERR "qla2xxx: Unable to allocate SRB cache...Failing load!\n"); Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2007-10-23 09:51:55 UTC (rev 208) +++ trunk/scst/include/scsi_tgt.h 2007-10-23 15:35:20 UTC (rev 209) @@ -359,6 +359,15 @@ #define SCST_PROC_ENTRY_NAME "scsi_tgt" /************************************************************* + ** Kernel cache creation helper + *************************************************************/ +#ifndef KMEM_CACHE +#define KMEM_CACHE(__struct, __flags) kmem_cache_create(#__struct,\ + sizeof(struct __struct), __alignof__(struct __struct),\ + (__flags), NULL, NULL) +#endif + +/************************************************************* * TYPES *************************************************************/ Modified: trunk/scst/include/scst_debug.h =================================================================== --- trunk/scst/include/scst_debug.h 2007-10-23 09:51:55 UTC (rev 208) +++ trunk/scst/include/scst_debug.h 2007-10-23 15:35:20 UTC (rev 209) @@ -399,4 +399,10 @@ #endif /* DEBUG */ +#if defined(DEBUG) && defined(CONFIG_DEBUG_SLAB) +#define SCST_SLAB_FLAGS ( SLAB_RED_ZONE | SLAB_POISON ) +#else +#define SCST_SLAB_FLAGS 0L +#endif + #endif /* __SCST_DEBUG_H */ Added: trunk/scst/kernel/scst_exec_req_fifo-2.6.23.patch =================================================================== --- trunk/scst/kernel/scst_exec_req_fifo-2.6.23.patch (rev 0) +++ trunk/scst/kernel/scst_exec_req_fifo-2.6.23.patch 2007-10-23 15:35:20 UTC (rev 209) @@ -0,0 +1,109 @@ +diff -upr linux-2.6.23/drivers/scsi/scsi_lib.c linux-2.6.23/drivers/scsi/scsi_lib.c +--- linux-2.6.23/drivers/scsi/scsi_lib.c 2007-10-10 00:31:38.000000000 +0400 ++++ linux-2.6.23/drivers/scsi/scsi_lib.c 2007-10-10 12:37:27.000000000 +0400 +@@ -366,7 +366,7 @@ free_bios: + } + + /** +- * scsi_execute_async - insert request ++ * __scsi_execute_async - insert request + * @sdev: scsi device + * @cmd: scsi command + * @cmd_len: length of scsi cdb +@@ -377,11 +377,14 @@ free_bios: + * @timeout: request timeout in seconds + * @retries: number of times to retry request + * @flags: or into request flags ++ * @at_head: insert request at head or tail of queue + **/ +-int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, ++static inline int __scsi_execute_async(struct scsi_device *sdev, ++ const unsigned char *cmd, + int cmd_len, int data_direction, void *buffer, unsigned bufflen, + int use_sg, int timeout, int retries, void *privdata, +- void (*done)(void *, char *, int, int), gfp_t gfp) ++ void (*done)(void *, char *, int, int), gfp_t gfp, ++ int at_head) + { + struct request *req; + struct scsi_io_context *sioc; +@@ -418,7 +421,7 @@ int scsi_execute_async(struct scsi_devic + sioc->data = privdata; + sioc->done = done; + +- blk_execute_rq_nowait(req->q, NULL, req, 1, scsi_end_async); ++ blk_execute_rq_nowait(req->q, NULL, req, at_head, scsi_end_async); + return 0; + + free_req: +@@ -427,8 +430,53 @@ free_sense: + kmem_cache_free(scsi_io_context_cache, sioc); + return DRIVER_ERROR << 24; + } ++ ++/** ++ * scsi_execute_async - insert request ++ * @sdev: scsi device ++ * @cmd: scsi command ++ * @cmd_len: length of scsi cdb ++ * @data_direction: data direction ++ * @buffer: data buffer (this can be a kernel buffer or scatterlist) ++ * @bufflen: len of buffer ++ * @use_sg: if buffer is a scatterlist this is the number of elements ++ * @timeout: request timeout in seconds ++ * @retries: number of times to retry request ++ * @flags: or into request flags ++ **/ ++int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, ++ int cmd_len, int data_direction, void *buffer, unsigned bufflen, ++ int use_sg, int timeout, int retries, void *privdata, ++ void (*done)(void *, char *, int, int), gfp_t gfp) ++{ ++ return __scsi_execute_async(sdev, cmd, cmd_len, data_direction, buffer, ++ bufflen, use_sg, timeout, retries, privdata, done, gfp, 1); ++} + EXPORT_SYMBOL_GPL(scsi_execute_async); + ++/** ++ * scsi_execute_async_fifo - insert request at tail, in FIFO order ++ * @sdev: scsi device ++ * @cmd: scsi command ++ * @cmd_len: length of scsi cdb ++ * @data_direction: data direction ++ * @buffer: data buffer (this can be a kernel buffer or scatterlist) ++ * @bufflen: len of buffer ++ * @use_sg: if buffer is a scatterlist this is the number of elements ++ * @timeout: request timeout in seconds ++ * @retries: number of times to retry request ++ * @flags: or into request flags ++ **/ ++int scsi_execute_async_fifo(struct scsi_device *sdev, const unsigned char *cmd, ++ int cmd_len, int data_direction, void *buffer, unsigned bufflen, ++ int use_sg, int timeout, int retries, void *privdata, ++ void (*done)(void *, char *, int, int), gfp_t gfp) ++{ ++ return __scsi_execute_async(sdev, cmd, cmd_len, data_direction, buffer, ++ bufflen, use_sg, timeout, retries, privdata, done, gfp, 0); ++} ++EXPORT_SYMBOL_GPL(scsi_execute_async_fifo); ++ + /* + * Function: scsi_init_cmd_errh() + * +diff -upr linux-2.6.23/include/scsi/scsi_device.h linux-2.6.23/include/scsi/scsi_device.h +--- linux-2.6.23/include/scsi/scsi_device.h 2007-10-10 00:31:38.000000000 +0400 ++++ linux-2.6.23/include/scsi/scsi_device.h 2007-10-10 12:37:27.000000000 +0400 +@@ -303,6 +303,13 @@ extern int scsi_execute_async(struct scs + int timeout, int retries, void *privdata, + void (*done)(void *, char *, int, int), + gfp_t gfp); ++#define SCSI_EXEC_REQ_FIFO_DEFINED ++extern int scsi_execute_async_fifo(struct scsi_device *sdev, ++ const unsigned char *cmd, int cmd_len, int data_direction, ++ void *buffer, unsigned bufflen, int use_sg, ++ int timeout, int retries, void *privdata, ++ void (*done)(void *, char *, int, int), ++ gfp_t gfp); + + static inline int __must_check scsi_device_reprobe(struct scsi_device *sdev) + { Modified: trunk/scst/src/dev_handlers/scst_user.c =================================================================== --- trunk/scst/src/dev_handlers/scst_user.c 2007-10-23 09:51:55 UTC (rev 208) +++ trunk/scst/src/dev_handlers/scst_user.c 2007-10-23 15:35:20 UTC (rev 209) @@ -33,12 +33,6 @@ for details. #endif -#if defined(DEBUG) && defined(CONFIG_DEBUG_SLAB) -#define DEV_USER_SLAB_FLAGS ( SLAB_RED_ZONE | SLAB_POISON ) -#else -#define DEV_USER_SLAB_FLAGS 0L -#endif - #define DEV_USER_MAJOR 237 #define DEV_USER_CMD_HASH_ORDER 6 #define DEV_USER_TM_TIMEOUT (10*HZ) @@ -99,7 +93,7 @@ struct completion cleanup_cmpl; }; -struct dev_user_pre_unreg_sess_obj +struct scst_user_pre_unreg_sess_obj { struct scst_tgt_dev *tgt_dev; unsigned int active:1; @@ -113,7 +107,7 @@ }; /* Most fields are unprotected, since only one thread at time can access them */ -struct dev_user_cmd +struct scst_user_cmd { struct scst_cmd *cmd; struct scst_user_dev *dev; @@ -126,7 +120,7 @@ unsigned int internal_reset_tm:1; unsigned int aborted:1; - struct dev_user_cmd *buf_ucmd; + struct scst_user_cmd *buf_ucmd; int cur_data_page; int num_data_pages; @@ -148,9 +142,9 @@ int result; }; -static struct dev_user_cmd *dev_user_alloc_ucmd(struct scst_user_dev *dev, +static struct scst_user_cmd *dev_user_alloc_ucmd(struct scst_user_dev *dev, int gfp_mask); -static void dev_user_free_ucmd(struct dev_user_cmd *ucmd); +static void dev_user_free_ucmd(struct scst_user_cmd *ucmd); static int dev_user_parse(struct scst_cmd *cmd, struct scst_info_cdb *info_cdb); static int dev_user_exec(struct scst_cmd *cmd); @@ -166,16 +160,16 @@ static void dev_user_free_sg_entries(struct scatterlist *sg, int sg_count, void *priv); -static void dev_user_add_to_ready(struct dev_user_cmd *ucmd); +static void dev_user_add_to_ready(struct scst_user_cmd *ucmd); -static void dev_user_unjam_cmd(struct dev_user_cmd *ucmd, int busy, +static void dev_user_unjam_cmd(struct scst_user_cmd *ucmd, int busy, unsigned long *flags); static void dev_user_unjam_dev(struct scst_user_dev *dev, int tm, struct scst_tgt_dev *tgt_dev); -static int dev_user_process_reply_tm_exec(struct dev_user_cmd *ucmd, +static int dev_user_process_reply_tm_exec(struct scst_user_cmd *ucmd, int status); -static int dev_user_process_reply_sess(struct dev_user_cmd *ucmd, int status); +static int dev_user_process_reply_sess(struct scst_user_cmd *ucmd, int status); static int dev_user_register_dev(struct file *file, const struct scst_user_dev_desc *dev_desc); static int __dev_user_set_opt(struct scst_user_dev *dev, @@ -213,7 +207,7 @@ static DECLARE_WAIT_QUEUE_HEAD(cleanup_list_waitQ); static struct task_struct *cleanup_thread; -static inline void ucmd_get(struct dev_user_cmd *ucmd, int barrier) +static inline void ucmd_get(struct scst_user_cmd *ucmd, int barrier) { TRACE_DBG("ucmd %p, ucmd_ref %d", ucmd, atomic_read(&ucmd->ucmd_ref)); atomic_inc(&ucmd->ucmd_ref); @@ -221,7 +215,7 @@ smp_mb__after_atomic_inc(); } -static inline void ucmd_put(struct dev_user_cmd *ucmd) +static inline void ucmd_put(struct scst_user_cmd *ucmd) { TRACE_DBG("ucmd %p, ucmd_ref %d", ucmd, atomic_read(&ucmd->ucmd_ref)); if (atomic_dec_and_test(&ucmd->ucmd_ref)) @@ -255,18 +249,18 @@ return 0; } -static inline int dev_user_cmd_hashfn(int h) +static inline int scst_user_cmd_hashfn(int h) { return h & ((1 << DEV_USER_CMD_HASH_ORDER) - 1); } -static inline struct dev_user_cmd *__ucmd_find_hash(struct scst_user_dev *dev, +static inline struct scst_user_cmd *__ucmd_find_hash(struct scst_user_dev *dev, unsigned int h) { struct list_head *head; - struct dev_user_cmd *ucmd; + struct scst_user_cmd *ucmd; - head = &dev->ucmd_hash[dev_user_cmd_hashfn(h)]; + head = &dev->ucmd_hash[scst_user_cmd_hashfn(h)]; list_for_each_entry(ucmd, head, hash_list_entry) { if (ucmd->h == h) { TRACE_DBG("Found ucmd %p", ucmd); @@ -276,11 +270,11 @@ return NULL; } -static void cmnd_insert_hash(struct dev_user_cmd *ucmd) +static void cmnd_insert_hash(struct scst_user_cmd *ucmd) { struct list_head *head; struct scst_user_dev *dev = ucmd->dev; - struct dev_user_cmd *u; + struct scst_user_cmd *u; unsigned long flags; spin_lock_irqsave(&dev->cmd_lists.cmd_list_lock, flags); @@ -288,7 +282,7 @@ ucmd->h = dev->handle_counter++; u = __ucmd_find_hash(dev, ucmd->h); } while(u != NULL); - head = &dev->ucmd_hash[dev_user_cmd_hashfn(ucmd->h)]; + head = &dev->ucmd_hash[scst_user_cmd_hashfn(ucmd->h)]; list_add_tail(&ucmd->hash_list_entry, head); spin_unlock_irqrestore(&dev->cmd_lists.cmd_list_lock, flags); @@ -296,7 +290,7 @@ return; } -static inline void cmnd_remove_hash(struct dev_user_cmd *ucmd) +static inline void cmnd_remove_hash(struct scst_user_cmd *ucmd) { unsigned long flags; spin_lock_irqsave(&ucmd->dev->cmd_lists.cmd_list_lock, flags); @@ -307,7 +301,7 @@ return; } -static void dev_user_free_ucmd(struct dev_user_cmd *ucmd) +static void dev_user_free_ucmd(struct scst_user_cmd *ucmd) { TRACE_ENTRY(); @@ -325,7 +319,7 @@ static struct page *dev_user_alloc_pages(struct scatterlist *sg, gfp_t gfp_mask, void *priv) { - struct dev_user_cmd *ucmd = (struct dev_user_cmd*)priv; + struct scst_user_cmd *ucmd = (struct scst_user_cmd*)priv; TRACE_ENTRY(); @@ -357,7 +351,7 @@ return sg->page; } -static void dev_user_on_cached_mem_free(struct dev_user_cmd *ucmd) +static void dev_user_on_cached_mem_free(struct scst_user_cmd *ucmd) { TRACE_ENTRY(); @@ -376,7 +370,7 @@ return; } -static void dev_user_unmap_buf(struct dev_user_cmd *ucmd) +static void dev_user_unmap_buf(struct scst_user_cmd *ucmd) { int i; @@ -400,7 +394,7 @@ return; } -static void __dev_user_free_sg_entries(struct dev_user_cmd *ucmd) +static void __dev_user_free_sg_entries(struct scst_user_cmd *ucmd) { TRACE_ENTRY(); @@ -423,7 +417,7 @@ static void dev_user_free_sg_entries(struct scatterlist *sg, int sg_count, void *priv) { - struct dev_user_cmd *ucmd = (struct dev_user_cmd*)priv; + struct scst_user_cmd *ucmd = (struct scst_user_cmd*)priv; TRACE_MEM("Freeing data pages (sg=%p, sg_count=%d, priv %p)", sg, sg_count, ucmd); @@ -433,7 +427,7 @@ return; } -static inline int is_buff_cached(struct dev_user_cmd *ucmd) +static inline int is_buff_cached(struct scst_user_cmd *ucmd) { int mem_reuse_type = ucmd->dev->memory_reuse_type; @@ -451,7 +445,7 @@ * Returns 0 for success, <0 for fatal failure, >0 - need pages. * Unmaps the buffer, if needed in case of error */ -static int dev_user_alloc_sg(struct dev_user_cmd *ucmd, int cached_buff) +static int dev_user_alloc_sg(struct scst_user_cmd *ucmd, int cached_buff) { int res = 0; struct scst_cmd *cmd = ucmd->cmd; @@ -489,8 +483,8 @@ cmd->sg = sgv_pool_alloc(dev->pool, bufflen, gfp_mask, flags, &cmd->sg_cnt, &ucmd->sgv, ucmd); if (cmd->sg != NULL) { - struct dev_user_cmd *buf_ucmd = - (struct dev_user_cmd*)sgv_get_priv(ucmd->sgv); + struct scst_user_cmd *buf_ucmd = + (struct scst_user_cmd*)sgv_get_priv(ucmd->sgv); TRACE_MEM("Buf ucmd %p", buf_ucmd); @@ -551,7 +545,7 @@ return res; } -static int dev_user_alloc_space(struct dev_user_cmd *ucmd) +static int dev_user_alloc_space(struct scst_user_cmd *ucmd) { int rc, res = SCST_CMD_STATE_DEFAULT; struct scst_cmd *cmd = ucmd->cmd; @@ -596,10 +590,10 @@ return res; } -static struct dev_user_cmd *dev_user_alloc_ucmd(struct scst_user_dev *dev, +static struct scst_user_cmd *dev_user_alloc_ucmd(struct scst_user_dev *dev, int gfp_mask) { - struct dev_user_cmd *ucmd = NULL; + struct scst_user_cmd *ucmd = NULL; TRACE_ENTRY(); @@ -641,7 +635,7 @@ static int dev_user_parse(struct scst_cmd *cmd, struct scst_info_cdb *info_cdb) { int rc, res = SCST_CMD_STATE_DEFAULT; - struct dev_user_cmd *ucmd; + struct scst_user_cmd *ucmd; int atomic = scst_cmd_atomic(cmd); struct scst_user_dev *dev = (struct scst_user_dev*)cmd->dev->dh_priv; int gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL; @@ -662,7 +656,7 @@ ucmd->cmd = cmd; cmd->dh_priv = ucmd; } else { - ucmd = (struct dev_user_cmd*)cmd->dh_priv; + ucmd = (struct scst_user_cmd*)cmd->dh_priv; TRACE_DBG("Used ucmd %p, state %x", ucmd, ucmd->state); } @@ -743,9 +737,9 @@ goto out; } -static void dev_user_flush_dcache(struct dev_user_cmd *ucmd) +static void dev_user_flush_dcache(struct scst_user_cmd *ucmd) { - struct dev_user_cmd *buf_ucmd = ucmd->buf_ucmd; + struct scst_user_cmd *buf_ucmd = ucmd->buf_ucmd; unsigned long start = buf_ucmd->ubuff; int i; @@ -773,7 +767,7 @@ static int dev_user_exec(struct scst_cmd *cmd) { - struct dev_user_cmd *ucmd = (struct dev_user_cmd*)cmd->dh_priv; + struct scst_user_cmd *ucmd = (struct scst_user_cmd*)cmd->dh_priv; TRACE_ENTRY(); @@ -811,7 +805,7 @@ return SCST_EXEC_COMPLETED; } -static void dev_user_free_sgv(struct dev_user_cmd *ucmd) +static void dev_user_free_sgv(struct scst_user_cmd *ucmd) { if (ucmd->sgv != NULL) { sgv_pool_free(ucmd->sgv); @@ -826,7 +820,7 @@ static void dev_user_on_free_cmd(struct scst_cmd *cmd) { - struct dev_user_cmd *ucmd = (struct dev_user_cmd*)cmd->dh_priv; + struct scst_user_cmd *ucmd = (struct scst_user_cmd*)cmd->dh_priv; TRACE_ENTRY(); @@ -905,7 +899,7 @@ return res; } -static void dev_user_add_to_ready(struct dev_user_cmd *ucmd) +static void dev_user_add_to_ready(struct scst_user_cmd *ucmd) { struct scst_user_dev *dev = ucmd->dev; unsigned long flags; @@ -934,7 +928,7 @@ !(dev->attach_cmd_active || dev->tm_cmd_active || dev->internal_reset_active || (dev->detach_cmd_count != 0))) { - struct dev_user_pre_unreg_sess_obj *p, *found = NULL; + struct scst_user_pre_unreg_sess_obj *p, *found = NULL; list_for_each_entry(p, &dev->pre_unreg_sess_list, pre_unreg_sess_list_entry) { if (p->tgt_dev == ucmd->cmd->tgt_dev) { @@ -998,7 +992,7 @@ return; } -static int dev_user_map_buf(struct dev_user_cmd *ucmd, unsigned long ubuff, +static int dev_user_map_buf(struct scst_user_cmd *ucmd, unsigned long ubuff, int num_pg) { int res = 0, rc; @@ -1066,7 +1060,7 @@ goto out_err; } -static int dev_user_process_reply_alloc(struct dev_user_cmd *ucmd, +static int dev_user_process_reply_alloc(struct scst_user_cmd *ucmd, struct scst_user_reply_cmd *reply) { int res = 0; @@ -1105,7 +1099,7 @@ goto out_process; } -static int dev_user_process_reply_parse(struct dev_user_cmd *ucmd, +static int dev_user_process_reply_parse(struct scst_user_cmd *ucmd, struct scst_user_reply_cmd *reply) { int res = 0; @@ -1153,7 +1147,7 @@ goto out_process; } -static int dev_user_process_reply_on_free(struct dev_user_cmd *ucmd) +static int dev_user_process_reply_on_free(struct scst_user_cmd *ucmd) { int res = 0; @@ -1168,7 +1162,7 @@ return res; } -static int dev_user_process_reply_on_cache_free(struct dev_user_cmd *ucmd) +static int dev_user_process_reply_on_cache_free(struct scst_user_cmd *ucmd) { int res = 0; @@ -1182,7 +1176,7 @@ return res; } -static int dev_user_process_reply_exec(struct dev_user_cmd *ucmd, +static int dev_user_process_reply_exec(struct scst_user_cmd *ucmd, struct scst_user_reply_cmd *reply) { int res = 0; @@ -1296,7 +1290,7 @@ struct scst_user_reply_cmd *reply) { int res = 0; - struct dev_user_cmd *ucmd; + struct scst_user_cmd *ucmd; int state; TRACE_ENTRY(); @@ -1460,9 +1454,9 @@ } /* Called under cmd_lists.cmd_list_lock and IRQ off */ -struct dev_user_cmd *__dev_user_get_next_cmd(struct list_head *cmd_list) +struct scst_user_cmd *__dev_user_get_next_cmd(struct list_head *cmd_list) { - struct dev_user_cmd *u; + struct scst_user_cmd *u; again: u = NULL; @@ -1522,7 +1516,7 @@ /* Called under cmd_lists.cmd_list_lock and IRQ off */ static int dev_user_get_next_cmd(struct scst_user_dev *dev, - struct dev_user_cmd **ucmd) + struct scst_user_cmd **ucmd) { int res = 0; wait_queue_t wait; @@ -1588,7 +1582,7 @@ /* Called under cmd_lists.cmd_list_lock and IRQ off */ static int dev_user_get_next_prio_cmd(struct scst_user_dev *dev, - struct dev_user_cmd **ucmd) + struct scst_user_cmd **ucmd) { int res = 0; wait_queue_t wait; @@ -1641,7 +1635,7 @@ struct scst_user_dev *dev; struct scst_user_get_cmd *cmd; struct scst_user_reply_cmd *reply; - struct dev_user_cmd *ucmd; + struct scst_user_cmd *ucmd; uint64_t ureply; TRACE_ENTRY(); @@ -1829,7 +1823,7 @@ /* * Called under cmd_lists.cmd_list_lock, but can drop it inside, then reaquire. */ -static void dev_user_unjam_cmd(struct dev_user_cmd *ucmd, int busy, +static void dev_user_unjam_cmd(struct scst_user_cmd *ucmd, int busy, unsigned long *flags) { int state = ucmd->state & ~UCMD_STATE_MASK; @@ -1939,7 +1933,7 @@ return; } -static int __unjam_check_tgt_dev(struct dev_user_cmd *ucmd, int state, +static int __unjam_check_tgt_dev(struct scst_user_cmd *ucmd, int state, struct scst_tgt_dev *tgt_dev) { int res = 0; @@ -1964,7 +1958,7 @@ return res; } -static int __unjam_check_tm(struct dev_user_cmd *ucmd, int state) +static int __unjam_check_tm(struct scst_user_cmd *ucmd, int state) { int res = 0; @@ -1991,7 +1985,7 @@ { int i; unsigned long flags; - struct dev_user_cmd *ucmd; + struct scst_user_cmd *ucmd; TRACE_ENTRY(); @@ -2065,7 +2059,7 @@ ** We also don't queue >1 ATTACH_SESS commands and after timeout fail it. **/ -static int dev_user_process_reply_tm_exec(struct dev_user_cmd *ucmd, +static int dev_user_process_reply_tm_exec(struct scst_user_cmd *ucmd, int status) { int res = 0; @@ -2103,9 +2097,9 @@ struct scst_tgt_dev *tgt_dev) { int res, rc; - struct dev_user_cmd *ucmd; + struct scst_user_cmd *ucmd; struct scst_user_dev *dev = (struct scst_user_dev*)tgt_dev->dev->dh_priv; - struct dev_user_cmd *ucmd_to_abort = NULL; + struct scst_user_cmd *ucmd_to_abort = NULL; TRACE_ENTRY(); @@ -2121,7 +2115,7 @@ ucmd->user_cmd.tm_cmd.fn = mcmd->fn; if (mcmd->cmd_to_abort != NULL) { - ucmd_to_abort = (struct dev_user_cmd*)mcmd->cmd_to_abort->dh_priv; + ucmd_to_abort = (struct scst_user_cmd*)mcmd->cmd_to_abort->dh_priv; if (ucmd_to_abort != NULL) ucmd->user_cmd.tm_cmd.cmd_h_to_abort = ucmd_to_abort->h; } @@ -2237,7 +2231,7 @@ return; } -static int dev_user_process_reply_sess(struct dev_user_cmd *ucmd, int status) +static int dev_user_process_reply_sess(struct scst_user_cmd *ucmd, int status) { int res = 0; unsigned long flags; @@ -2276,7 +2270,7 @@ struct scst_user_dev *dev = (struct scst_user_dev*)tgt_dev->dev->dh_priv; int res = 0, rc; - struct dev_user_cmd *ucmd; + struct scst_user_cmd *ucmd; TRACE_ENTRY(); @@ -2360,10 +2354,10 @@ #endif { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) - struct dev_user_pre_unreg_sess_obj *pd = (struct dev_user_pre_unreg_sess_obj*)p; + struct scst_user_pre_unreg_sess_obj *pd = (struct scst_user_pre_unreg_sess_obj*)p; #else - struct dev_user_pre_unreg_sess_obj *pd = container_of( - (struct delayed_work*)work, struct dev_user_pre_unreg_sess_obj, + struct scst_user_pre_unreg_sess_obj *pd = container_of( + (struct delayed_work*)work, struct scst_user_pre_unreg_sess_obj, pre_unreg_sess_work); #endif struct scst_user_dev *dev = @@ -2393,7 +2387,7 @@ { struct scst_user_dev *dev = (struct scst_user_dev*)tgt_dev->dev->dh_priv; - struct dev_user_pre_unreg_sess_obj *pd; + struct scst_user_pre_unreg_sess_obj *pd; TRACE_ENTRY(); @@ -2425,8 +2419,8 @@ { struct scst_user_dev *dev = (struct scst_user_dev*)tgt_dev->dev->dh_priv; - struct dev_user_cmd *ucmd; - struct dev_user_pre_unreg_sess_obj *pd = NULL, *p; + struct scst_user_cmd *ucmd; + struct scst_user_pre_unreg_sess_obj *pd = NULL, *p; TRACE_ENTRY(); @@ -2722,7 +2716,7 @@ if ((dev->prio_queue_type != opt->prio_queue_type) && (opt->prio_queue_type == SCST_USER_PRIO_QUEUE_SINGLE)) { - struct dev_user_cmd *u, *t; + struct scst_user_cmd *u, *t; /* No need for lock, the activity is suspended */ list_for_each_entry_safe(u, t, &dev->prio_ready_cmd_list, ready_cmd_list_entry) { @@ -2887,7 +2881,7 @@ static void dev_user_process_cleanup(struct scst_user_dev *dev) { - struct dev_user_cmd *ucmd; + struct scst_user_cmd *ucmd; int rc; TRACE_ENTRY(); @@ -2917,7 +2911,7 @@ int i; for(i = 0; i < (int)ARRAY_SIZE(dev->ucmd_hash); i++) { struct list_head *head = &dev->ucmd_hash[i]; - struct dev_user_cmd *ucmd, *t; + struct scst_user_cmd *ucmd, *t; list_for_each_entry_safe(ucmd, t, head, hash_list_entry) { PRINT_ERROR_PR("Lost ucmd %p (state %x, ref %d)", ucmd, ucmd->state, atomic_read(&ucmd->ucmd_ref)); @@ -3003,9 +2997,7 @@ goto out; #endif - user_cmd_cachep = kmem_cache_create("scst_user_cmd", - sizeof(struct dev_user_cmd), 0, DEV_USER_SLAB_FLAGS, NULL, - NULL); + user_cmd_cachep = KMEM_CACHE(scst_user_cmd, SCST_SLAB_FLAGS); if (user_cmd_cachep == NULL) { res = -ENOMEM; goto out; Modified: trunk/scst/src/dev_handlers/scst_vdisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_vdisk.c 2007-10-23 09:51:55 UTC (rev 208) +++ trunk/scst/src/dev_handlers/scst_vdisk.c 2007-10-23 15:35:20 UTC (rev 209) @@ -55,12 +55,6 @@ #include "scst_dev_handler.h" -#if defined(DEBUG) && defined(CONFIG_DEBUG_SLAB) -#define VDISK_SLAB_FLAGS ( SLAB_RED_ZONE | SLAB_POISON ) -#else -#define VDISK_SLAB_FLAGS 0L -#endif - /* 8 byte ASCII Vendor */ #define SCST_FIO_VENDOR "SCST_FIO" #define SCST_BIO_VENDOR "SCST_BIO" @@ -3170,9 +3164,7 @@ { int res, num_threads; - vdisk_thr_cachep = kmem_cache_create("vdisk_thr_data", - sizeof(struct scst_vdisk_thr), 0, VDISK_SLAB_FLAGS, NULL, - NULL); + vdisk_thr_cachep = KMEM_CACHE(scst_vdisk_thr, SCST_SLAB_FLAGS); if (vdisk_thr_cachep == NULL) { res = -ENOMEM; goto out; Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2007-10-23 09:51:55 UTC (rev 208) +++ trunk/scst/src/scst_lib.c 2007-10-23 15:35:20 UTC (rev 209) @@ -667,13 +667,24 @@ } out: + if (res == 0) { + if (dev->virt_name != NULL) { + PRINT_INFO_PR("Added device %s to group %s", + dev->virt_name, acg->acg_name); + } else { + PRINT_INFO_PR("Added device %d:%d:%d:%d to group %s", + dev->scsi_dev->host->host_no, + dev->scsi_dev->channel, dev->scsi_dev->id, + dev->scsi_dev->lun, acg->acg_name); + } + } + TRACE_EXIT_RES(res); return res; out_free: list_for_each_entry(tgt_dev, &tmp_tgt_dev_list, - extra_tgt_dev_list_entry) - { + extra_tgt_dev_list_entry) { scst_free_tgt_dev(tgt_dev); } scst_free_acg_dev(acg_dev); @@ -710,7 +721,19 @@ } scst_free_acg_dev(acg_dev); -out: +out: + if (res == 0) { + if (dev->virt_name != NULL) { + PRINT_INFO_PR("Removed device %s from group %s", + dev->virt_name, acg->acg_name); + } else { + PRINT_INFO_PR("Removed device %d:%d:%d:%d from group %s", + dev->scsi_dev->host->host_no, + dev->scsi_dev->channel, dev->scsi_dev->id, + dev->scsi_dev->lun, acg->acg_name); + } + } + TRACE_EXIT_RES(res); return res; } @@ -728,8 +751,8 @@ list_for_each_entry(n, &acg->acn_list, acn_list_entry) { if (strcmp(n->name, name) == 0) { - PRINT_ERROR_PR("Name %s already exists in access " - "control group %s", name, acg->acg_name); + PRINT_ERROR_PR("Name %s already exists in group %s", + name, acg->acg_name); res = -EINVAL; goto out; } @@ -756,6 +779,10 @@ list_add_tail(&n->acn_list_entry, &acg->acn_list); out: + if (res == 0) { + PRINT_INFO_PR("Added name %s to group %s", name, acg->acg_name); + } + TRACE_EXIT_RES(res); return res; @@ -783,9 +810,12 @@ } } - if (res != 0) { - PRINT_ERROR_PR("Unable to find name %s in access control " - "group %s", name, acg->acg_name); + if (res == 0) { + PRINT_INFO_PR("Removed name %s from group %s", name, + acg->acg_name); + } else { + PRINT_ERROR_PR("Unable to find name %s in group %s", name, + acg->acg_name); } TRACE_EXIT_RES(res); Modified: trunk/scst/src/scst_main.c =================================================================== --- trunk/scst/src/scst_main.c 2007-10-23 09:51:55 UTC (rev 208) +++ trunk/scst/src/scst_main.c 2007-10-23 15:35:20 UTC (rev 209) @@ -1418,26 +1418,19 @@ scst_threads_info_init(); -#define INIT_CACHEP(p, s, t, o) do { \ - p = kmem_cache_create(s, sizeof(struct t), 0, \ - SCST_SLAB_FLAGS, NULL, NULL); \ - TRACE_MEM("Slab create: %s at %p size %zd", s, p, \ - sizeof(struct t)); \ +#define INIT_CACHEP(p, s, o) do { \ + p = KMEM_CACHE(s, SCST_SLAB_FLAGS); \ + TRACE_MEM("Slab create: %s at %p size %zd", #s, p, \ + sizeof(struct s)); \ if (p == NULL) { res = -ENOMEM; goto o; } \ } while (0) - INIT_CACHEP(scst_mgmt_cachep, SCST_MGMT_CMD_CACHE_STRING, - scst_mgmt_cmd, out); - INIT_CACHEP(scst_ua_cachep, SCST_UA_CACHE_STRING, - scst_tgt_dev_UA, out_destroy_mgmt_cache); - INIT_CACHEP(scst_cmd_cachep, SCST_CMD_CACHE_STRING, - scst_cmd, out_destroy_ua_cache); - INIT_CACHEP(scst_sess_cachep, SCST_SESSION_CACHE_STRING, - scst_session, out_destroy_cmd_cache); - INIT_CACHEP(scst_tgtd_cachep, SCST_TGT_DEV_CACHE_STRING, - scst_tgt_dev, out_destroy_sess_cache); - INIT_CACHEP(scst_acgd_cachep, SCST_ACG_DEV_CACHE_STRING, - scst_acg_dev, out_destroy_tgt_cache); + INIT_CACHEP(scst_mgmt_cachep, scst_mgmt_cmd, out); + INIT_CACHEP(scst_ua_cachep, scst_tgt_dev_UA, out_destroy_mgmt_cache); + INIT_CACHEP(scst_cmd_cachep, scst_cmd, out_destroy_ua_cache); + INIT_CACHEP(scst_sess_cachep, scst_session, out_destroy_cmd_cache); + INIT_CACHEP(scst_tgtd_cachep, scst_tgt_dev, out_destroy_sess_cache); + INIT_CACHEP(scst_acgd_cachep, scst_acg_dev, out_destroy_tgt_cache); scst_mgmt_mempool = mempool_create(10, mempool_alloc_slab, mempool_free_slab, scst_mgmt_cachep); @@ -1564,30 +1557,20 @@ scst_sgv_pools_deinit(); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) -#define DEINIT_CACHEP(p, s) do { \ - if (kmem_cache_destroy(p)) { \ - PRINT_INFO_PR("kmem_cache_destroy of %s returned an "\ - "error", s); \ - } \ - p = NULL; \ +#define DEINIT_CACHEP(p) do { \ + kmem_cache_destroy(p); \ + p = NULL; \ } while (0) -#else -#define DEINIT_CACHEP(p, s) do { \ - kmem_cache_destroy(p); \ - p = NULL; \ - } while (0) -#endif mempool_destroy(scst_mgmt_mempool); mempool_destroy(scst_ua_mempool); - DEINIT_CACHEP(scst_mgmt_cachep, SCST_MGMT_CMD_CACHE_STRING); - DEINIT_CACHEP(scst_ua_cachep, SCST_UA_CACHE_STRING); - DEINIT_CACHEP(scst_cmd_cachep, SCST_CMD_CACHE_STRING); - DEINIT_CACHEP(scst_sess_cachep, SCST_SESSION_CACHE_STRING); - DEINIT_CACHEP(scst_tgtd_cachep, SCST_TGT_DEV_CACHE_STRING); - DEINIT_CACHEP(scst_acgd_cachep, SCST_ACG_DEV_CACHE_STRING); + DEINIT_CACHEP(scst_mgmt_cachep); + DEINIT_CACHEP(scst_ua_cachep); + DEINIT_CACHEP(scst_cmd_cachep); + DEINIT_CACHEP(scst_sess_cachep); + DEINIT_CACHEP(scst_tgtd_cachep); + DEINIT_CACHEP(scst_acgd_cachep); PRINT_INFO_PR("%s", "SCST unloaded"); Modified: trunk/scst/src/scst_mem.c =================================================================== --- trunk/scst/src/scst_mem.c 2007-10-23 09:51:55 UTC (rev 208) +++ trunk/scst/src/scst_mem.c 2007-10-23 15:35:20 UTC (rev 209) @@ -840,7 +840,12 @@ scnprintf(pool->cache_names[i], sizeof(pool->cache_names[i]), "%s-%luK", name, (PAGE_SIZE >> 10) << i); pool->caches[i] = kmem_cache_create(pool->cache_names[i], - size, 0, SCST_SLAB_FLAGS, NULL, NULL); + size, 0, SCST_SLAB_FLAGS, NULL +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) + , NULL); +#else + ); +#endif if (pool->caches[i] == NULL) { TRACE(TRACE_OUT_OF_MEM, "Allocation of sgv_pool cache " "%s(%d) failed", name, i); @@ -1086,8 +1091,14 @@ INIT_WORK(&pools->mgr.apit_pool, sgv_pool_cached_pitbool, NULL); #endif +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) pools->mgr.sgv_shrinker = set_shrinker(DEFAULT_SEEKS, sgv_pool_cached_shrinker); +#else + pools->mgr.sgv_shrinker.shrink = sgv_pool_cached_shrinker; + pools->mgr.sgv_shrinker.seeks = DEFAULT_SEEKS; + register_shrinker(&pools->mgr.sgv_shrinker); +#endif out: TRACE_EXIT_RES(res); @@ -1112,7 +1123,12 @@ TRACE_ENTRY(); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) remove_shrinker(pools->mgr.sgv_shrinker); +#else + unregister_shrinker(&pools->mgr.sgv_shrinker); +#endif + cancel_delayed_work(&pools->mgr.apit_pool); #ifdef SCST_HIGHMEM Modified: trunk/scst/src/scst_mem.h =================================================================== --- trunk/scst/src/scst_mem.h 2007-10-23 09:51:55 UTC (rev 208) +++ trunk/scst/src/scst_mem.h 2007-10-23 15:35:20 UTC (rev 209) @@ -20,12 +20,6 @@ #define SGV_POOL_ELEMENTS 11 -#if defined(DEBUG) && defined(CONFIG_DEBUG_SLAB) -#define SCST_SLAB_FLAGS ( SLAB_RED_ZONE | SLAB_POISON ) -#else -#define SCST_SLAB_FLAGS 0L -#endif - /* * sg_num is indexed by the page number, pg_count is indexed by the sg number. * Made in one entry to simplify the code (eg all sizeof(*) parts) and save @@ -118,8 +112,12 @@ u32 releases_on_hiwmk; u32 releases_failed; } thr; /* protected by pool_mgr_lock */ - + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) struct shrinker *sgv_shrinker; +#else + struct shrinker sgv_shrinker; +#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) struct delayed_work apit_pool; Modified: trunk/scst/src/scst_proc.c =================================================================== --- trunk/scst/src/scst_proc.c 2007-10-23 09:51:55 UTC (rev 208) +++ trunk/scst/src/scst_proc.c 2007-10-23 15:35:20 UTC (rev 209) @@ -2004,8 +2004,12 @@ int scst_single_seq_open(struct inode *inode, struct file *file) { - return single_open(file, - container_of(inode->i_fop, struct scst_proc_data, seq_op)->show, - PDE(inode)->data); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) + struct scst_proc_data *pdata = container_of(PDE(inode)->proc_fops, + struct scst_proc_data, seq_op); +#else + struct scst_proc_data *pdata = container_of(inode->i_fop, + struct scst_proc_data, seq_op); +#endif + return single_open(file, pdata->show, pdata->data); } - This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2007-11-01 17:07:11
|
Revision: 214 http://scst.svn.sourceforge.net/scst/?rev=214&view=rev Author: vlnb Date: 2007-11-01 10:07:07 -0700 (Thu, 01 Nov 2007) Log Message: ----------- Cleanups, debug imporvements and minor fixes Modified Paths: -------------- trunk/iscsi-scst/kernel/config.c trunk/iscsi-scst/kernel/conn.c trunk/iscsi-scst/kernel/digest.c trunk/iscsi-scst/kernel/event.c trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/kernel/iscsi_dbg.h trunk/iscsi-scst/kernel/nthread.c trunk/iscsi-scst/kernel/param.c trunk/iscsi-scst/kernel/session.c trunk/iscsi-scst/kernel/target.c trunk/qla2x00t/qla2x00-target/qla2x00t.c trunk/qla2x00t-full_perf.patch trunk/qla2x00t-release.patch trunk/scst/include/scst_debug.h trunk/scst/src/dev_handlers/scst_cdrom.c trunk/scst/src/dev_handlers/scst_changer.c trunk/scst/src/dev_handlers/scst_dev_handler.h trunk/scst/src/dev_handlers/scst_disk.c trunk/scst/src/dev_handlers/scst_modisk.c trunk/scst/src/dev_handlers/scst_processor.c trunk/scst/src/dev_handlers/scst_raid.c trunk/scst/src/dev_handlers/scst_tape.c trunk/scst/src/dev_handlers/scst_user.c trunk/scst/src/dev_handlers/scst_vdisk.c trunk/scst/src/scst_debug.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_main.c trunk/scst/src/scst_priv.h trunk/scst/src/scst_proc.c trunk/scst/src/scst_targ.c trunk/usr/fileio/common.c trunk/usr/fileio/debug.c trunk/usr/fileio/debug.h trunk/usr/fileio/fileio.c Modified: trunk/iscsi-scst/kernel/config.c =================================================================== --- trunk/iscsi-scst/kernel/config.c 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/iscsi-scst/kernel/config.c 2007-11-01 17:07:07 UTC (rev 214) @@ -32,6 +32,7 @@ { TRACE_CONN_OC, "conn" }, { TRACE_D_IOV, "iov" }, { TRACE_D_DUMP_PDU, "pdu" }, + { TRACE_NET_PG, "net_page" }, { 0, NULL } }; @@ -113,7 +114,7 @@ p = scst_create_proc_entry(root, ISCSI_PROC_VERSION_NAME, &iscsi_version_proc_data); if (p == NULL) { - PRINT_ERROR_PR("Not enough memory to register " + PRINT_ERROR("Not enough memory to register " "target driver %s entry %s in /proc", templ->name, ISCSI_PROC_VERSION_NAME); res = -ENOMEM; @@ -126,7 +127,7 @@ p = scst_create_proc_entry(root, ISCSI_PROC_LOG_ENTRY_NAME, &iscsi_log_proc_data); if (p == NULL) { - PRINT_ERROR_PR("Not enough memory to register " + PRINT_ERROR("Not enough memory to register " "target driver %s entry %s in /proc", templ->name, ISCSI_PROC_LOG_ENTRY_NAME); res = -ENOMEM; @@ -390,7 +391,7 @@ if (cmd == ADD_TARGET) if (target) { err = -EEXIST; - PRINT_ERROR_PR("Target %u already exist!", id); + PRINT_ERROR("Target %u already exist!", id); goto out_unlock; } @@ -401,7 +402,7 @@ } if (!target) { - PRINT_ERROR_PR("can't find the target %u", id); + PRINT_ERROR("can't find the target %u", id); err = -EINVAL; goto out_unlock; } @@ -442,7 +443,7 @@ break; default: - PRINT_ERROR_PR("invalid ioctl cmd %x", cmd); + PRINT_ERROR("invalid ioctl cmd %x", cmd); err = -EINVAL; } @@ -457,6 +458,7 @@ static int release(struct inode *inode, struct file *filp) { + TRACE(TRACE_MGMT, "%s", "Releasing allocated resources"); target_del_all(); return 0; } Modified: trunk/iscsi-scst/kernel/conn.c =================================================================== --- trunk/iscsi-scst/kernel/conn.c 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/iscsi-scst/kernel/conn.c 2007-11-01 17:07:07 UTC (rev 214) @@ -175,7 +175,7 @@ if (sk->sk_state != TCP_ESTABLISHED) { if (!conn->closing) { - PRINT_ERROR_PR("Connection with initiator %s (%p) " + PRINT_ERROR("Connection with initiator %s (%p) " "unexpectedly closed!", conn->session->initiator_name, conn); mark_conn_closed(conn); @@ -238,7 +238,7 @@ conn->sock = SOCKET_I(conn->file->f_dentry->d_inode); if (conn->sock->ops->sendpage == NULL) { - PRINT_ERROR_PR("Socket for sid %llu doesn't support sendpage()", + PRINT_ERROR("Socket for sid %llu doesn't support sendpage()", session->sid); res = -EINVAL; goto out; @@ -385,7 +385,7 @@ if (!conn) return err; - PRINT_INFO_PR("Deleting connection with initiator %s (%p)", + PRINT_INFO("Deleting connection with initiator %s (%p)", conn->session->initiator_name, conn); mark_conn_closed(conn); Modified: trunk/iscsi-scst/kernel/digest.c =================================================================== --- trunk/iscsi-scst/kernel/digest.c 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/iscsi-scst/kernel/digest.c 2007-11-01 17:07:07 UTC (rev 214) @@ -31,7 +31,7 @@ #endif if ((*val & DIGEST_CRC32C) && !crc32c) { - PRINT_ERROR_PR("%s", "CRC32C digest algorithm not available " + PRINT_ERROR("%s", "CRC32C digest algorithm not available " "in kernel"); *val |= ~DIGEST_CRC32C; } @@ -70,7 +70,7 @@ #ifdef DEBUG_DIGEST_FAILURES if (((scst_random() % 100000) == 752)) { - PRINT_INFO_PR("%s", "Simulating digest failure"); + PRINT_INFO("%s", "Simulating digest failure"); return 0; } #endif @@ -143,7 +143,7 @@ crc = digest_header(&cmnd->pdu); if (crc != cmnd->hdigest) { - PRINT_ERROR_PR("%s", "RX header digest failed"); + PRINT_ERROR("%s", "RX header digest failed"); return -EIO; } else TRACE_DBG("RX header digest OK for cmd %p", cmnd); @@ -184,7 +184,7 @@ crc = digest_data(req, cmnd->pdu.datasize, offset); if (crc != cmnd->ddigest) { - PRINT_ERROR_PR("%s", "RX data digest failed"); + PRINT_ERROR("%s", "RX data digest failed"); res = -EIO; } else TRACE_DBG("RX data digest OK for cmd %p", cmnd); Modified: trunk/iscsi-scst/kernel/event.c =================================================================== --- trunk/iscsi-scst/kernel/event.c 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/iscsi-scst/kernel/event.c 2007-11-01 17:07:07 UTC (rev 214) @@ -113,7 +113,7 @@ THIS_MODULE); #endif if (!nl) { - PRINT_ERROR_PR("%s", "netlink_kernel_create() failed"); + PRINT_ERROR("%s", "netlink_kernel_create() failed"); return -ENOMEM; } else return 0; Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/iscsi-scst/kernel/iscsi.c 2007-11-01 17:07:07 UTC (rev 214) @@ -145,7 +145,7 @@ if (unlikely(cmnd->on_write_list)) { struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd); - PRINT_ERROR_PR("cmnd %p still on some list?, %x, %x, %x, %x, %x, %x, %x", + PRINT_ERROR("cmnd %p still on some list?, %x, %x, %x, %x, %x, %x, %x", cmnd, req->opcode, req->scb[0], req->flags, req->itt, be32_to_cpu(req->data_length), req->cmd_sn, be32_to_cpu(cmnd->pdu.datasize)); @@ -153,7 +153,7 @@ if (cmnd->parent_req) { struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd->parent_req); - PRINT_ERROR_PR("%p %x %u", req, req->opcode, req->scb[0]); + PRINT_ERROR("%p %x %u", req, req->opcode, req->scb[0]); } sBUG(); } @@ -199,7 +199,7 @@ scst_tgt_cmd_done(cmnd->scst_cmd); break; default: - PRINT_ERROR_PR("Unexpected cmnd scst state %d", + PRINT_ERROR("Unexpected cmnd scst state %d", cmnd->scst_state); sBUG(); break; @@ -445,7 +445,7 @@ LIST_HEAD(head); if (unlikely(rsp->on_write_list)) { - PRINT_ERROR_PR("cmd already on write list (%x %x %x %x %u %u " + PRINT_ERROR("cmd already on write list (%x %x %x %x %u %u " "%u %u %u %u %u %d %d", cmnd_itt(rsp), cmnd_ttt(rsp), cmnd_opcode(rsp), cmnd_scsicode(rsp), rsp->r2t_sn, @@ -680,7 +680,7 @@ TRACE_DBG("%d(%d)", cmd_sn, session->exp_cmd_sn); if ((s32)(cmd_sn - session->exp_cmd_sn) >= 0) return 0; - PRINT_ERROR_PR("sequence error (%x,%x)", cmd_sn, session->exp_cmd_sn); + PRINT_ERROR("sequence error (%x,%x)", cmd_sn, session->exp_cmd_sn); return -ISCSI_REASON_PROTOCOL_ERROR; } @@ -778,7 +778,7 @@ list_del(&cmnd->hash_list_entry); cmnd->hashed = 0; } else { - PRINT_ERROR_PR("%p:%x not found", cmnd, cmnd_itt(cmnd)); + PRINT_ERROR("%p:%x not found", cmnd, cmnd_itt(cmnd)); } spin_unlock(&session->cmnd_hash_lock); @@ -838,7 +838,7 @@ rsp = get_rsp_cmnd(req); rsp_hdr = (struct iscsi_scsi_rsp_hdr *)&rsp->pdu.bhs; if (cmnd_opcode(rsp) != ISCSI_OP_SCSI_RSP) { - PRINT_ERROR_PR("unexpected response command %u", cmnd_opcode(rsp)); + PRINT_ERROR("unexpected response command %u", cmnd_opcode(rsp)); return; } @@ -878,7 +878,7 @@ if ((offset >= bufflen) || (offset + size > bufflen)) { - PRINT_ERROR_PR("Wrong ltn (%u %u %u)", offset, size, bufflen); + PRINT_ERROR("Wrong ltn (%u %u %u)", offset, size, bufflen); mark_conn_closed(conn); res = -EIO; goto out; @@ -910,7 +910,7 @@ size -= conn->read_iov[i].iov_len; offset = 0; if (++i >= ISCSI_CONN_IOV_MAX) { - PRINT_ERROR_PR("Initiator %s violated negotiated " + PRINT_ERROR("Initiator %s violated negotiated " "parameters by sending too much data (size " "left %d)", conn->session->initiator_name, size); mark_conn_closed(conn); @@ -1046,14 +1046,14 @@ * We don't request a NOP-Out by sending a NOP-In. * See 10.18.2 in the draft 20. */ - PRINT_ERROR_PR("initiator bug %x", cmnd_itt(cmnd)); + PRINT_ERROR("initiator bug %x", cmnd_itt(cmnd)); err = -ISCSI_REASON_PROTOCOL_ERROR; goto out; } if (cmnd_itt(cmnd) == cpu_to_be32(ISCSI_RESERVED_TAG)) { if (!(cmnd->pdu.bhs.opcode & ISCSI_OP_IMMEDIATE)) - PRINT_ERROR_PR("%s","initiator bug!"); + PRINT_ERROR("%s","initiator bug!"); spin_lock(&conn->session->sn_lock); __update_stat_sn(cmnd); err = check_cmd_sn(cmnd); @@ -1061,7 +1061,7 @@ if (err) goto out; } else if ((err = cmnd_insert_hash(cmnd)) < 0) { - PRINT_ERROR_PR("Can't insert in hash: ignore this request %x", + PRINT_ERROR("Can't insert in hash: ignore this request %x", cmnd_itt(cmnd)); goto out; } @@ -1183,7 +1183,7 @@ scst_cmd->queue_type = SCST_CMD_QUEUE_UNTAGGED; break; default: - PRINT_ERROR_PR("Unknown task code %x, use ORDERED instead", + PRINT_ERROR("Unknown task code %x, use ORDERED instead", req_hdr->flags & ISCSI_CMD_ATTR_MASK); scst_cmd->queue_type = SCST_CMD_QUEUE_ORDERED; break; @@ -1218,7 +1218,7 @@ dir = scst_cmd_get_data_direction(scst_cmd); if (dir != SCST_DATA_WRITE) { if (!(req_hdr->flags & ISCSI_CMD_FINAL) || req->pdu.datasize) { - PRINT_ERROR_PR("Unexpected unsolicited data (ITT %x " + PRINT_ERROR("Unexpected unsolicited data (ITT %x " "CDB %x", cmnd_itt(req), req_hdr->scb[0]); create_sense_rsp(req, ABORTED_COMMAND, 0xc, 0xc); cmnd_prepare_skip_pdu_set_resid(req); @@ -1234,7 +1234,7 @@ req->sg = scst_cmd_get_sg(scst_cmd); req->bufflen = scst_cmd_get_bufflen(scst_cmd); if (req->r2t_length > req->bufflen) { - PRINT_ERROR_PR("req->r2t_length %d > req->bufflen %d", + PRINT_ERROR("req->r2t_length %d > req->bufflen %d", req->r2t_length, req->bufflen); req->r2t_length = req->bufflen; } @@ -1245,7 +1245,7 @@ if (!session->sess_param.immediate_data && req->pdu.datasize) { - PRINT_ERROR_PR("Initiator %s violated negotiated paremeters: " + PRINT_ERROR("Initiator %s violated negotiated paremeters: " "forbidden immediate data sent (ITT %x, op %x)", session->initiator_name, cmnd_itt(req), req_hdr->scb[0]); res = -EINVAL; @@ -1254,7 +1254,7 @@ if (session->sess_param.initial_r2t && !(req_hdr->flags & ISCSI_CMD_FINAL)) { - PRINT_ERROR_PR("Initiator %s violated negotiated paremeters: " + PRINT_ERROR("Initiator %s violated negotiated paremeters: " "initial R2T is required (ITT %x, op %x)", session->initiator_name, cmnd_itt(req), req_hdr->scb[0]); res = -EINVAL; @@ -1263,7 +1263,7 @@ if (req->pdu.datasize) { if (dir != SCST_DATA_WRITE) { - PRINT_ERROR_PR("pdu.datasize(%d) >0, but dir(%x) isn't WRITE", + PRINT_ERROR("pdu.datasize(%d) >0, but dir(%x) isn't WRITE", req->pdu.datasize, dir); create_sense_rsp(req, ABORTED_COMMAND, 0xc, 0xc); cmnd_prepare_skip_pdu_set_resid(req); @@ -1296,13 +1296,13 @@ cmnd->cmd_req = req = cmnd_find_hash(conn->session, req_hdr->itt, req_hdr->ttt); if (!req) { - PRINT_ERROR_PR("unable to find scsi task %x %x", + PRINT_ERROR("unable to find scsi task %x %x", cmnd_itt(cmnd), cmnd_ttt(cmnd)); goto skip_pdu; } if (req->r2t_length < cmnd->pdu.datasize) { - PRINT_ERROR_PR("Invalid data len %x %u %u", cmnd_itt(req), + PRINT_ERROR("Invalid data len %x %u %u", cmnd_itt(req), cmnd->pdu.datasize, req->r2t_length); mark_conn_closed(conn); res = -EINVAL; @@ -1310,7 +1310,7 @@ } if (req->r2t_length + offset != cmnd_write_size(req)) { - PRINT_ERROR_PR("Wrong cmd lengths (%x %u %u %u)", + PRINT_ERROR("Wrong cmd lengths (%x %u %u %u)", cmnd_itt(req), req->r2t_length, offset, cmnd_write_size(req)); mark_conn_closed(conn); @@ -1323,7 +1323,7 @@ /* Check unsolicited burst data */ if ((req_hdr->ttt == cpu_to_be32(ISCSI_RESERVED_TAG)) && (req->pdu.bhs.flags & ISCSI_FLG_FINAL)) { - PRINT_ERROR_PR("unexpected data from %x %x", + PRINT_ERROR("unexpected data from %x %x", cmnd_itt(cmnd), cmnd_ttt(cmnd)); mark_conn_closed(conn); res = -EINVAL; @@ -1380,7 +1380,7 @@ req->outstanding_r2t, req->r2t_length); /* ToDo : proper error handling */ if (!(req_hdr->flags & ISCSI_FLG_FINAL) && (req->r2t_length == 0)) - PRINT_ERROR_PR("initiator error %x", cmnd_itt(req)); + PRINT_ERROR("initiator error %x", cmnd_itt(req)); if (!(req_hdr->flags & ISCSI_FLG_FINAL)) goto out; @@ -1409,13 +1409,14 @@ if (cmnd->tmfabort) goto out; - TRACE(TRACE_MGMT, "Aborting cmd %p, scst_cmd %p (scst state %x, " - "itt %x, op %x, r2t_len %x, CDB op %x, size to write %u, " - "is_unsolicited_data %u, outstanding_r2t %u)", - cmnd, cmnd->scst_cmd, cmnd->scst_state, cmnd_itt(cmnd), - cmnd_opcode(cmnd), cmnd->r2t_length, cmnd_scsicode(cmnd), - cmnd_write_size(cmnd), cmnd->is_unsolicited_data, - cmnd->outstanding_r2t); + TRACE_MGMT_DBG("Aborting cmd %p, scst_cmd %p (scst state %x, " + "ref_cnt %d, net_ref_cnt %d, itt %x, op %x, r2t_len %x, " + "CDB op %x, size to write %u, is_unsolicited_data %u, " + "outstanding_r2t %u)", cmnd, cmnd->scst_cmd, cmnd->scst_state, + atomic_read(&cmnd->ref_cnt), atomic_read(&cmnd->net_ref_cnt), + cmnd_itt(cmnd), cmnd_opcode(cmnd), cmnd->r2t_length, + cmnd_scsicode(cmnd), cmnd_write_size(cmnd), + cmnd->is_unsolicited_data, cmnd->outstanding_r2t); iscsi_extracheck_is_rd_thread(cmnd->conn); @@ -1452,7 +1453,7 @@ struct iscsi_scsi_cmd_hdr *hdr = cmnd_hdr(cmnd); if (req_hdr->lun != hdr->lun) { - PRINT_ERROR_PR("ABORT TASK: LUN mismatch: req LUN " + PRINT_ERROR("ABORT TASK: LUN mismatch: req LUN " "%Lx, cmd LUN %Lx, rtt %u", req_hdr->lun, hdr->lun, req_hdr->rtt); err = ISCSI_RESPONSE_FUNCTION_REJECTED; @@ -1461,7 +1462,7 @@ if (before(req_hdr->cmd_sn, hdr->cmd_sn) || (req_hdr->cmd_sn == hdr->cmd_sn)) { - PRINT_ERROR_PR("ABORT TASK: SN mismatch: req SN %x, " + PRINT_ERROR("ABORT TASK: SN mismatch: req SN %x, " "cmd SN %x, rtt %u", req_hdr->cmd_sn, hdr->cmd_sn, req_hdr->rtt); err = ISCSI_RESPONSE_FUNCTION_REJECTED; @@ -1587,7 +1588,7 @@ if ((function != ISCSI_FUNCTION_ABORT_TASK) && (req_hdr->rtt != ISCSI_RESERVED_TAG)) { - PRINT_ERROR_PR("Invalid RTT %x (TM fn %x)", req_hdr->rtt, + PRINT_ERROR("Invalid RTT %x (TM fn %x)", req_hdr->rtt, function); err = -1; goto reject; @@ -1717,7 +1718,7 @@ struct iscsi_cmnd *rsp; struct iscsi_logout_rsp_hdr *rsp_hdr; - PRINT_INFO_PR("Logout received from initiator %s", + PRINT_INFO("Logout received from initiator %s", req->conn->session->initiator_name); TRACE_DBG("%p", req); @@ -1765,7 +1766,7 @@ req_cmnd_release(cmnd); break; default: - PRINT_ERROR_PR("unexpected cmnd op %x", cmnd_opcode(cmnd)); + PRINT_ERROR("unexpected cmnd op %x", cmnd_opcode(cmnd)); req_cmnd_release(cmnd); break; } @@ -1866,7 +1867,7 @@ cmnd_send_pdu(conn, cmnd); break; default: - PRINT_ERROR_PR("unexpected cmnd op %x", cmnd_opcode(cmnd)); + PRINT_ERROR("unexpected cmnd op %x", cmnd_opcode(cmnd)); break; } @@ -1894,13 +1895,13 @@ case ISCSI_OP_LOGOUT_RSP: break; default: - PRINT_ERROR_PR("unexpected cmnd op %x", cmnd_opcode(cmnd)); + PRINT_ERROR("unexpected cmnd op %x", cmnd_opcode(cmnd)); sBUG(); break; } if (cmnd->should_close_conn) { - PRINT_INFO_PR("Closing connection at initiator %s request", + PRINT_INFO("Closing connection at initiator %s request", conn->session->initiator_name); mark_conn_closed(conn); } @@ -1953,12 +1954,12 @@ } else { cmnd->pending = 1; if (before(cmd_sn, session->exp_cmd_sn)) { /* close the conn */ - PRINT_ERROR_PR("unexpected cmd_sn (%u,%u)", cmd_sn, + PRINT_ERROR("unexpected cmd_sn (%u,%u)", cmd_sn, session->exp_cmd_sn); } if (after(cmd_sn, session->exp_cmd_sn + session->max_queued_cmnds)) { - PRINT_ERROR_PR("too large cmd_sn (%u,%u)", cmd_sn, + PRINT_ERROR("too large cmd_sn (%u,%u)", cmd_sn, session->exp_cmd_sn); } @@ -1983,7 +1984,7 @@ struct iscsi_session *session = conn->session; if (cmnd->pdu.datasize > session->sess_param.max_recv_data_length) { - PRINT_ERROR_PR("Initiator %s violated negotiated parameters: " + PRINT_ERROR("Initiator %s violated negotiated parameters: " "data too long (ITT %x, datasize %u, " "max_recv_data_length %u", session->initiator_name, cmnd_itt(cmnd), cmnd->pdu.datasize, @@ -2040,7 +2041,7 @@ if (unlikely(rc < 0)) { struct iscsi_scsi_cmd_hdr *hdr = cmnd_hdr(cmnd); - PRINT_ERROR_PR("Error %d (iSCSI opcode %x, ITT %x, op %x)", rc, + PRINT_ERROR("Error %d (iSCSI opcode %x, ITT %x, op %x)", rc, cmnd_opcode(cmnd), cmnd_itt(cmnd), (cmnd_opcode(cmnd) == ISCSI_OP_SCSI_CMD ? hdr->scb[0] : -1)); @@ -2082,7 +2083,7 @@ req_cmnd_release(cmnd); break; default: - PRINT_ERROR_PR("unexpected cmnd op %x", cmnd_opcode(cmnd)); + PRINT_ERROR("unexpected cmnd op %x", cmnd_opcode(cmnd)); req_cmnd_release(cmnd); break; } @@ -2240,7 +2241,7 @@ resp_flags, req->bufflen, req->sg); if ((req->bufflen != 0) && !(resp_flags & SCST_TSC_FLAG_STATUS)) { - PRINT_ERROR_PR("%s", "Sending DATA without STATUS is unsupported"); + PRINT_ERROR("%s", "Sending DATA without STATUS is unsupported"); scst_set_cmd_error(scst_cmd, SCST_LOAD_SENSE(scst_sense_hardw_error)); resp_flags = scst_cmd_get_tgt_resp_flags(scst_cmd); @@ -2313,7 +2314,7 @@ (struct iscsi_task_mgt_hdr *)&req->pdu.bhs; struct iscsi_task_rsp_hdr *rsp_hdr; - TRACE(TRACE_MGMT, "req %p, status %d", req, status); + TRACE(TRACE_MGMT, "TM req %p finished, status %d", req, status); rsp = iscsi_cmnd_create_rsp_cmnd(req); rsp_hdr = (struct iscsi_task_rsp_hdr *)&rsp->pdu.bhs; @@ -2360,7 +2361,7 @@ scst_mgmt_cmd_get_tgt_priv(scst_mcmd); int status = iscsi_get_mgmt_response(scst_mgmt_cmd_get_status(scst_mcmd)); - TRACE(TRACE_MGMT, "scst_mcmd %p, status %d", scst_mcmd, + TRACE_MGMT_DBG("req %p, scst_mcmd %p, scst status %d", req, scst_mcmd, scst_mgmt_cmd_get_status(scst_mcmd)); iscsi_send_task_mgmt_resp(req, status); @@ -2408,13 +2409,13 @@ thr = kmalloc(sizeof(*thr), GFP_KERNEL); if (!thr) { res = -ENOMEM; - PRINT_ERROR_PR("Failed to allocate thr %d", res); + PRINT_ERROR("Failed to allocate thr %d", res); goto out; } thr->thr = kthread_run(fn, NULL, "%s%d", name, i); if (IS_ERR(thr->thr)) { res = PTR_ERR(thr->thr); - PRINT_ERROR_PR("kthread_create() failed: %d", res); + PRINT_ERROR("kthread_create() failed: %d", res); kfree(thr); goto out; } @@ -2445,17 +2446,17 @@ int err; int num; - PRINT_INFO_PR("iSCSI SCST Target - version %s", ISCSI_VERSION_STRING); + PRINT_INFO("iSCSI SCST Target - version %s", ISCSI_VERSION_STRING); #ifdef NET_PAGE_CALLBACKS_DEFINED err = net_set_get_put_page_callbacks(iscsi_get_page_callback, iscsi_put_page_callback); if (err != 0) { - PRINT_INFO_PR("Unable to set page callbackes: %d", err); + PRINT_INFO("Unable to set page callbackes: %d", err); goto out; } #else - PRINT_INFO_PR("%s", "Patch put_page_callback-<kernel-version>.patch " + PRINT_INFO("%s", "Patch put_page_callback-<kernel-version>.patch " "not applied on your kernel. Running in the performance " "degraded mode. Refer README file for details"); #endif @@ -2463,7 +2464,7 @@ BUILD_BUG_ON(MAX_DATA_SEG_LEN != (ISCSI_CONN_IOV_MAX<<PAGE_SHIFT)); if ((ctr_major = register_chrdev(0, ctr_name, &ctr_fops)) < 0) { - PRINT_ERROR_PR("failed to register the control device %d", ctr_major); + PRINT_ERROR("failed to register the control device %d", ctr_major); err = ctr_major; goto out_callb; } Modified: trunk/iscsi-scst/kernel/iscsi_dbg.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi_dbg.h 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/iscsi-scst/kernel/iscsi_dbg.h 2007-11-01 17:07:07 UTC (rev 214) @@ -16,6 +16,8 @@ #ifndef ISCSI_DBG_H #define ISCSI_DBG_H +#define LOG_PREFIX "iscsi-scst" + #include <scst_debug.h> #define TRACE_D_READ 0x80000000 @@ -23,20 +25,18 @@ #define TRACE_CONN_OC 0x20000000 #define TRACE_D_IOV 0x10000000 #define TRACE_D_DUMP_PDU 0x08000000 +#define TRACE_NET_PG 0x04000000 #define TRACE_D_DATA (TRACE_D_READ | TRACE_D_WRITE) #define TRACE_ALL_NO_DATA (TRACE_ALL & ~TRACE_D_IOV & ~TRACE_D_DUMP_PDU & ~TRACE_D_DATA) -#define LOG_PREFIX "iscsi-scst" - #ifdef DEBUG #define ISCSI_DEFAULT_LOG_FLAGS (TRACE_FUNCTION | TRACE_LINE | TRACE_PID | \ TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MGMT_DEBUG | \ TRACE_MINOR | TRACE_SPECIAL | TRACE_CONN_OC) #else -#define ISCSI_DEFAULT_LOG_FLAGS (TRACE_FUNCTION | TRACE_PID | \ - TRACE_OUT_OF_MEM | TRACE_MGMT | \ +#define ISCSI_DEFAULT_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MGMT | \ TRACE_MINOR | TRACE_SPECIAL) #endif @@ -59,7 +59,8 @@ if (trace_flag & TRACE_CONN_OC) \ { \ char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, __FUNCTION__, __LINE__) > 0) \ + if (debug_print_prefix(trace_flag, LOG_PREFIX, __FUNCTION__, \ + __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ } \ @@ -67,8 +68,23 @@ } \ } while(0) +#define TRACE_NET_PAGE(format, args...) \ +do { \ + if (trace_flag & TRACE_NET_PG) \ + { \ + char *__tflag = LOG_FLAG; \ + if (debug_print_prefix(trace_flag, LOG_PREFIX, __FUNCTION__, \ + __LINE__) > 0) \ + { \ + __tflag = NO_FLAG; \ + } \ + PRINT(NO_FLAG, "%s" format, __tflag, args); \ + } \ +} while(0) + #else /* defined(DEBUG) || defined(TRACING) */ #define TRACE_CONN_CLOSE(format, args...) {} +#define TRACE_NET_PAGE(format, args...) {} #endif #endif Modified: trunk/iscsi-scst/kernel/nthread.c =================================================================== --- trunk/iscsi-scst/kernel/nthread.c 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/iscsi-scst/kernel/nthread.c 2007-11-01 17:07:07 UTC (rev 214) @@ -62,7 +62,7 @@ TRACE_ENTRY(); - TRACE_CONN_CLOSE("conn %p, conn_ref_cnt=%d", conn, + TRACE_CONN_CLOSE("Closing connection %p (conn_ref_cnt=%d)", conn, atomic_read(&conn->conn_ref_cnt)); iscsi_extracheck_is_rd_thread(conn); @@ -86,8 +86,8 @@ struct list_head *pending_list = &session->pending_list; struct iscsi_cmnd *tmp; - TRACE_CONN_CLOSE("Disposing pending commands on conn " - "%p, conn_ref_cnt=%d", conn, + TRACE_CONN_CLOSE("Disposing pending commands on " + "connection %p (conn_ref_cnt=%d)", conn, atomic_read(&conn->conn_ref_cnt)); list_for_each_entry_safe(cmnd, tmp, pending_list, @@ -172,7 +172,7 @@ msleep(50); } - TRACE_CONN_CLOSE("Notifying user space about closing conn %p", conn); + TRACE_CONN_CLOSE("Notifying user space about closing connection %p", conn); event_send(target->tid, session->sid, conn->cid, E_CONN_CLOSE, 0); mutex_lock(&target->target_mutex); @@ -248,7 +248,7 @@ "conn %p", res, conn); break; default: - PRINT_ERROR_PR("sock_recvmsg() failed: %d", res); + PRINT_ERROR("sock_recvmsg() failed: %d", res); mark_conn_closed(conn); break; } @@ -283,7 +283,7 @@ int res = digest_rx_header(cmnd); if (unlikely(res != 0)) { - PRINT_ERROR_PR("rx header digest for initiator %s failed " + PRINT_ERROR("rx header digest for initiator %s failed " "(%d)", conn->session->initiator_name, res); mark_conn_closed(conn); } @@ -397,7 +397,7 @@ } break; default: - PRINT_ERROR_PR("%d %x", conn->read_state, cmnd_opcode(cmnd)); + PRINT_ERROR("%d %x", conn->read_state, cmnd_opcode(cmnd)); sBUG(); } @@ -408,7 +408,7 @@ goto out; if (conn->read_size) { - PRINT_ERROR_PR("%d %x %d", res, cmnd_opcode(cmnd), conn->read_size); + PRINT_ERROR("%d %x %d", res, cmnd_opcode(cmnd), conn->read_size); sBUG(); } @@ -540,13 +540,13 @@ struct iscsi_cmnd *cmd = (struct iscsi_cmnd*)page->net_priv; int v; - TRACE_DBG("cmd %p, page %p, _count %d, new net_ref_cnt %d", + TRACE_NET_PAGE("cmd %p, page %p, _count %d, new net_ref_cnt %d", cmd, page, atomic_read(&page->_count), atomic_read(&cmd->net_ref_cnt)+1); v = atomic_inc_return(&cmd->net_ref_cnt); if (v == 1) { - TRACE_DBG("getting cmd %p for page %p", cmd, page); + TRACE_NET_PAGE("getting cmd %p for page %p", cmd, page); cmnd_get(cmd); } } @@ -555,19 +555,30 @@ { struct iscsi_cmnd *cmd = (struct iscsi_cmnd*)page->net_priv; - TRACE_DBG("cmd %p, page %p, _count %d, new net_ref_cnt %d", + TRACE_NET_PAGE("cmd %p, page %p, _count %d, new net_ref_cnt %d", cmd, page, atomic_read(&page->_count), atomic_read(&cmd->net_ref_cnt)-1); if (atomic_dec_and_test(&cmd->net_ref_cnt)) { int i, sg_cnt = get_pgcnt(cmd->bufflen, cmd->sg[0].offset); for(i = 0; i < sg_cnt; i++) { - TRACE_DBG("Clearing page %p", cmd->sg[i].page); + TRACE_NET_PAGE("Clearing page %p", cmd->sg[i].page); cmd->sg[i].page->net_priv = NULL; } cmnd_put(cmd); } } + +static void check_net_priv(struct iscsi_cmnd *cmd, struct page *page) +{ + if (atomic_read(&cmd->net_ref_cnt) == 0) { + TRACE_DBG("%s", "sendpage() not called get_page(), " + "zeroing net_priv"); + page->net_priv = NULL; + } +} +#else +static inline void check_net_priv(struct iscsi_cmnd *cmd, struct page *page) {} #endif /* This is partially taken from the Ardis code. */ @@ -607,7 +618,7 @@ set_fs(KERNEL_DS); res = vfs_writev(file, (struct iovec __user *)iop, count, &off); set_fs(oldfs); - TRACE(TRACE_D_DATA, "%#Lx:%u: %d(%ld)", + TRACE(TRACE_D_WRITE, "%#Lx:%u: %d(%ld)", (unsigned long long) conn->session->sid, conn->cid, res, (long) iop->iov_len); if (unlikely(res <= 0)) { @@ -642,7 +653,7 @@ sg = write_cmnd->sg; if (sg == NULL) { - PRINT_ERROR_PR("%s", "warning data missing!"); + PRINT_ERROR("%s", "warning data missing!"); return 0; } offset = conn->write_offset; @@ -667,7 +678,7 @@ #ifdef NET_PAGE_CALLBACKS_DEFINED if (unlikely((sg[idx].page->net_priv != NULL) && (sg[idx].page->net_priv != ref_cmd))) { - PRINT_ERROR_PR("net_priv isn't NULL and != ref_cmd " + PRINT_ERROR("net_priv isn't NULL and != ref_cmd " "(write_cmnd %p, ref_cmd %p, sg %p, idx %d, " "net_priv %p)", write_cmnd, ref_cmd, sg, idx, sg[idx].page->net_priv); @@ -679,7 +690,7 @@ if (size <= sendsize) { retry2: res = sendpage(sock, sg[idx].page, offset, size, flags); - TRACE(TRACE_D_DATA, "%s %#Lx:%u: %d(%lu,%u,%u)", + TRACE(TRACE_D_WRITE, "%s %#Lx:%u: %d(%lu,%u,%u)", sock->ops->sendpage ? "sendpage" : "sock_no_sendpage", (unsigned long long)conn->session->sid, conn->cid, res, sg[idx].page->index, offset, size); @@ -689,13 +700,7 @@ else goto out_res; } -#ifdef NET_PAGE_CALLBACKS_DEFINED - if (atomic_read(&ref_cmd->net_ref_cnt) == 0) { - TRACE_DBG("%s", "sendpage() not called " - "get_page(), zeroing net_priv"); - sg[idx].page->net_priv = NULL; - } -#endif + check_net_priv(ref_cmd, sg[idx].page); if (res == size) { conn->write_size = 0; return saved_size; @@ -708,7 +713,7 @@ retry1: res = sendpage(sock, sg[idx].page, offset, sendsize, flags | MSG_MORE); - TRACE(TRACE_D_DATA, "%s %#Lx:%u: %d(%lu,%u,%u)", + TRACE(TRACE_D_WRITE, "%s %#Lx:%u: %d(%lu,%u,%u)", sock->ops->sendpage ? "sendpage" : "sock_no_sendpage", (unsigned long long ) conn->session->sid, conn->cid, res, sg[idx].page->index, offset, sendsize); @@ -718,13 +723,7 @@ else goto out_res; } -#ifdef NET_PAGE_CALLBACKS_DEFINED - if (atomic_read(&ref_cmd->net_ref_cnt) == 0) { - TRACE_DBG("%s", "sendpage() not called get_page(), " - "zeroing net_priv"); - sg[idx].page->net_priv = NULL; - } -#endif + check_net_priv(ref_cmd, sg[idx].page); if (res == sendsize) { idx++; offset = 0; @@ -742,12 +741,7 @@ return saved_size - size; out_res: -#ifdef NET_PAGE_CALLBACKS_DEFINED - if (atomic_read(&ref_cmd->net_ref_cnt) == 0) { - TRACE_DBG("sendpage() returned %d, zeroing net_priv", res); - sg[idx].page->net_priv = NULL; - } -#endif + check_net_priv(ref_cmd, sg[idx].page); if (res == -EAGAIN) goto out; /* else go through */ @@ -757,7 +751,7 @@ if (!conn->closing) #endif { - PRINT_ERROR_PR("error %d at sid:cid %#Lx:%u, cmnd %p", res, + PRINT_ERROR("error %d at sid:cid %#Lx:%u, cmnd %p", res, (unsigned long long)conn->session->sid, conn->cid, conn->write_cmnd); } @@ -778,7 +772,7 @@ if (!conn->closing) #endif { - PRINT_ERROR_PR("Sending data failed: initiator %s, " + PRINT_ERROR("Sending data failed: initiator %s, " "write_size %d, write_state %d, res %d", conn->session->initiator_name, conn->write_size, conn->write_state, res); @@ -892,7 +886,7 @@ res = tx_ddigest(cmnd, TX_END); break; default: - PRINT_ERROR_PR("%d %d %x", res, conn->write_state, + PRINT_ERROR("%d %d %x", res, conn->write_state, cmnd_opcode(cmnd)); sBUG(); } @@ -904,7 +898,7 @@ goto out; if (conn->write_size) { - PRINT_ERROR_PR("%d %x %u", res, cmnd_opcode(cmnd), + PRINT_ERROR("%d %x %u", res, cmnd_opcode(cmnd), conn->write_size); sBUG(); } Modified: trunk/iscsi-scst/kernel/param.c =================================================================== --- trunk/iscsi-scst/kernel/param.c 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/iscsi-scst/kernel/param.c 2007-11-01 17:07:07 UTC (rev 214) @@ -21,7 +21,7 @@ if (!info->partial || (info->partial & 1 << key_##word)) \ if (iparam[key_##word] < min || \ iparam[key_##word] > max) { \ - PRINT_ERROR_PR("%s: %u is out of range (%u %u)",\ + PRINT_ERROR("%s: %u is out of range (%u %u)",\ #word, iparam[key_##word], min, max); \ iparam[key_##word] = min; \ } \ @@ -63,21 +63,21 @@ static void log_params(struct iscsi_sess_param *param) { - PRINT_INFO_PR("Negotiated parameters: InitialR2T %s, ImmediateData %s, " + PRINT_INFO("Negotiated parameters: InitialR2T %s, ImmediateData %s, " "MaxConnections %d, MaxRecvDataSegmentLength %d, " "MaxXmitDataSegmentLength %d, ", get_bool_name(param->initial_r2t), get_bool_name(param->immediate_data), param->max_connections, param->max_recv_data_length, param->max_xmit_data_length); - PRINT_INFO_PR(" MaxBurstLength %d, FirstBurstLength %d, " + PRINT_INFO(" MaxBurstLength %d, FirstBurstLength %d, " "DefaultTime2Wait %d, DefaultTime2Retain %d, ", param->max_burst_length, param->first_burst_length, param->default_wait_time, param->default_retain_time); - PRINT_INFO_PR(" MaxOutstandingR2T %d, DataPDUInOrder %s, " + PRINT_INFO(" MaxOutstandingR2T %d, DataPDUInOrder %s, " "DataSequenceInOrder %s, ErrorRecoveryLevel %d, ", param->max_outstanding_r2t, get_bool_name(param->data_pdu_inorder), get_bool_name(param->data_sequence_inorder), param->error_recovery_level); - PRINT_INFO_PR(" HeaderDigest %s, DataDigest %s, OFMarker %s, " + PRINT_INFO(" HeaderDigest %s, DataDigest %s, OFMarker %s, " "IFMarker %s, OFMarkInt %d, IFMarkInt %d", get_digest_name(param->header_digest), get_digest_name(param->data_digest), @@ -191,7 +191,7 @@ trgt_param_set(target, info); prm = &target->trgt_param; - PRINT_INFO_PR("Target parameter changed: queued_cmnds %d", + PRINT_INFO("Target parameter changed: queued_cmnds %d", prm->queued_cmnds); } else trgt_param_get(&target->trgt_param, info); Modified: trunk/iscsi-scst/kernel/session.c =================================================================== --- trunk/iscsi-scst/kernel/session.c 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/iscsi-scst/kernel/session.c 2007-11-01 17:07:07 UTC (rev 214) @@ -84,7 +84,7 @@ session->scst_sess = scst_register_session(target->scst_tgt, 0, name, NULL, NULL); if (session->scst_sess == NULL) { - PRINT_ERROR_PR("%s", "scst_register_session() failed"); + PRINT_ERROR("%s", "scst_register_session() failed"); err = -ENOMEM; goto err; } @@ -151,7 +151,7 @@ return -ENOENT; if (!list_empty(&session->conn_list)) { - PRINT_ERROR_PR("%llu still have connections", + PRINT_ERROR("%llu still have connections", (unsigned long long)session->sid); return -EBUSY; } Modified: trunk/iscsi-scst/kernel/target.c =================================================================== --- trunk/iscsi-scst/kernel/target.c 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/iscsi-scst/kernel/target.c 2007-11-01 17:07:07 UTC (rev 214) @@ -88,12 +88,12 @@ TRACE_MGMT_DBG("Creating target tid %u, name %s", tid, name); if (!(len = strlen(name))) { - PRINT_ERROR_PR("The length of the target name is zero %u", tid); + PRINT_ERROR("The length of the target name is zero %u", tid); goto out; } if (!try_module_get(THIS_MODULE)) { - PRINT_ERROR_PR("Fail to get module %u", tid); + PRINT_ERROR("Fail to get module %u", tid); goto out; } @@ -118,7 +118,7 @@ target->scst_tgt = scst_register(&iscsi_template, target->name); if (!target->scst_tgt) { - PRINT_ERROR_PR("%s", "scst_register() failed"); + PRINT_ERROR("%s", "scst_register() failed"); goto out_free; } @@ -216,7 +216,7 @@ TRACE_ENTRY(); - TRACE(TRACE_MGMT, "%s", "Deleting all targets"); + TRACE_MGMT_DBG("%s", "Deleting all targets"); /* Complete brain damage, ToDo */ while(1) { Modified: trunk/qla2x00t/qla2x00-target/qla2x00t.c =================================================================== --- trunk/qla2x00t/qla2x00-target/qla2x00t.c 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/qla2x00t/qla2x00-target/qla2x00t.c 2007-11-01 17:07:07 UTC (rev 214) @@ -53,8 +53,8 @@ TRACE_MINOR | TRACE_SPECIAL) #else # ifdef TRACING -#define Q2T_DEFAULT_LOG_FLAGS (TRACE_FUNCTION | TRACE_PID | \ - TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MINOR | TRACE_SPECIAL) +#define Q2T_DEFAULT_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MINOR | \ + TRACE_SPECIAL) # endif #endif Modified: trunk/qla2x00t-full_perf.patch =================================================================== --- trunk/qla2x00t-full_perf.patch 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/qla2x00t-full_perf.patch 2007-11-01 17:07:07 UTC (rev 214) @@ -1,17 +1,16 @@ Index: qla2x00t/qla2x00-target/Makefile =================================================================== ---- qla2x00t/qla2x00-target/Makefile (revision 324) +--- qla2x00t/qla2x00-target/Makefile (revision 213) +++ qla2x00t/qla2x00-target/Makefile (working copy) -@@ -35,10 +35,10 @@ INSTALL_DIR := /lib/modules/$(shell unam +@@ -35,9 +35,9 @@ EXTRA_CFLAGS += -I$(SCST_INC_DIR) -DFC_T - EXTRA_CFLAGS += -I$(SCST_INC_DIR) -DFC_TARGET_SUPPORT -Wextra -Wno-unused-parameter + INSTALL_DIR := /lib/modules/$(shell uname -r)/extra -EXTRA_CFLAGS += -DEXTRACHECKS +#EXTRA_CFLAGS += -DEXTRACHECKS #EXTRA_CFLAGS += -DTRACING - -EXTRA_CFLAGS += -DDEBUG_TGT -g +#EXTRA_CFLAGS += -DDEBUG_TGT -g #EXTRA_CFLAGS += -DDEBUG_WORK_IN_THREAD - #EXTRA_CFLAGS += -DDEBUG_SRR + ifeq ($(KVER),) Modified: trunk/qla2x00t-release.patch =================================================================== --- trunk/qla2x00t-release.patch 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/qla2x00t-release.patch 2007-11-01 17:07:07 UTC (rev 214) @@ -1,18 +1,17 @@ Index: qla2x00t/qla2x00-target/Makefile =================================================================== ---- qla2x00t/qla2x00-target/Makefile (revision 324) +--- qla2x00t/qla2x00-target/Makefile (revision 213) +++ qla2x00t/qla2x00-target/Makefile (working copy) -@@ -35,10 +35,10 @@ INSTALL_DIR := /lib/modules/$(shell unam +@@ -35,9 +35,9 @@ EXTRA_CFLAGS += -I$(SCST_INC_DIR) -DFC_T - EXTRA_CFLAGS += -I$(SCST_INC_DIR) -DFC_TARGET_SUPPORT -Wextra -Wno-unused-parameter + INSTALL_DIR := /lib/modules/$(shell uname -r)/extra -EXTRA_CFLAGS += -DEXTRACHECKS -#EXTRA_CFLAGS += -DTRACING +-EXTRA_CFLAGS += -DDEBUG_TGT -g +#EXTRA_CFLAGS += -DEXTRACHECKS +EXTRA_CFLAGS += -DTRACING - --EXTRA_CFLAGS += -DDEBUG_TGT -g +#EXTRA_CFLAGS += -DDEBUG_TGT -g #EXTRA_CFLAGS += -DDEBUG_WORK_IN_THREAD - #EXTRA_CFLAGS += -DDEBUG_SRR + ifeq ($(KVER),) Modified: trunk/scst/include/scst_debug.h =================================================================== --- trunk/scst/include/scst_debug.h 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/scst/include/scst_debug.h 2007-11-01 17:07:07 UTC (rev 214) @@ -125,9 +125,16 @@ #define PRINT(log_flag, format, args...) printk(log_flag format "\n", ## args); #define PRINTN(log_flag, format, args...) printk(log_flag format, ## args); +#ifdef LOG_PREFIX +#define __LOG_PREFIX LOG_PREFIX +#else +#define __LOG_PREFIX NULL +#endif + #if defined(DEBUG) || defined(TRACING) -extern int debug_print_prefix(unsigned long trace_flag, const char *func, int line); +extern int debug_print_prefix(unsigned long trace_flag, const char *prefix, + const char *func, int line); extern void debug_print_buffer(const void *data, int len); #define TRACE(trace, format, args...) \ @@ -135,7 +142,8 @@ if (trace_flag & (trace)) \ { \ char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, __FUNCTION__, __LINE__) > 0) \ + if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \ + __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ } \ @@ -148,7 +156,8 @@ char *__tflag = log_flag; \ if (trace_flag & (trace)) \ { \ - if (debug_print_prefix(trace_flag, __FUNCTION__, __LINE__) > 0) \ + if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \ + __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ } \ @@ -161,7 +170,8 @@ if (trace_flag & TRACE_BUFF) \ { \ char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, __FUNCTION__, __LINE__) > 0) \ + if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \ + __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ } \ @@ -175,7 +185,8 @@ if (trace_flag & (flag)) \ { \ char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, __FUNCTION__, __LINE__) > 0) \ + if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \ + __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ } \ @@ -199,7 +210,8 @@ if (trace_flag & TRACE_MEMORY) \ { \ char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, __FUNCTION__, __LINE__) > 0) \ + if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \ + __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ } \ @@ -212,7 +224,8 @@ if (trace_flag & TRACE_DEBUG) \ { \ char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, __FUNCTION__, __LINE__) > 0) \ + if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \ + __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ } \ @@ -225,7 +238,8 @@ if (trace_flag & (TRACE_DEBUG|TRACE_SPECIAL)) \ { \ char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, __FUNCTION__, __LINE__) > 0) \ + if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \ + __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ } \ @@ -238,7 +252,8 @@ if (trace_flag & TRACE_MGMT_DEBUG) \ { \ char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, __FUNCTION__, __LINE__) > 0) \ + if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \ + __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ } \ @@ -251,7 +266,8 @@ if (trace_flag & (TRACE_MGMT_DEBUG|TRACE_SPECIAL)) \ { \ char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, __FUNCTION__, __LINE__) > 0) \ + if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \ + __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ } \ @@ -259,28 +275,6 @@ } \ } while(0) -#define PRINT_ERROR_PR(format, args...) \ -do { \ - if (ERROR_FLAG != LOG_FLAG) \ - { \ - TRACE_LOG_FLAG(LOG_FLAG, trace_flag, "%s: ***ERROR*** " format, \ - LOG_PREFIX, args); \ - } \ - TRACE_LOG_FLAG(ERROR_FLAG, trace_flag, "%s: ***ERROR*** " format, \ - LOG_PREFIX, args); \ -} while(0) - -#define PRINT_INFO_PR(format, args...) \ -do { \ - if (INFO_FLAG != LOG_FLAG) \ - { \ - TRACE_LOG_FLAG(LOG_FLAG, trace_flag, "%s: " \ - format, LOG_PREFIX, args); \ - } \ - TRACE_LOG_FLAG(INFO_FLAG, trace_flag, "%s: " \ - format, LOG_PREFIX, args); \ -} while(0) - #define PRINT_ERROR(format, args...) \ do { \ if (ERROR_FLAG != LOG_FLAG) \ @@ -375,17 +369,21 @@ #define TRACE_EXIT_RES(res) {} #define TRACE_EXIT_HRES(res) {} -#define PRINT_INFO_PR(format, args...) \ +#ifdef LOG_PREFIX + +#define PRINT_INFO(format, args...) \ do { \ PRINT(INFO_FLAG, "%s: " format, LOG_PREFIX, args); \ } while(0) -#define PRINT_ERROR_PR(format, args...) \ +#define PRINT_ERROR(format, args...) \ do { \ PRINT(ERROR_FLAG, "%s: ***ERROR*** " \ format, LOG_PREFIX, args); \ } while(0) +#else + #define PRINT_INFO(format, args...) \ do { \ PRINT(INFO_FLAG, format, args); \ @@ -397,6 +395,8 @@ format, args); \ } while(0) +#endif /* LOG_PREFIX */ + #endif /* DEBUG */ #if defined(DEBUG) && defined(CONFIG_DEBUG_SLAB) Modified: trunk/scst/src/dev_handlers/scst_cdrom.c =================================================================== --- trunk/scst/src/dev_handlers/scst_cdrom.c 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/scst/src/dev_handlers/scst_cdrom.c 2007-11-01 17:07:07 UTC (rev 214) @@ -80,7 +80,7 @@ if (dev->scsi_dev == NULL || dev->scsi_dev->type != dev->handler->type) { - PRINT_ERROR_PR("%s", "SCSI device not define or illegal type"); + PRINT_ERROR("%s", "SCSI device not define or illegal type"); res = -ENODEV; goto out; } @@ -123,7 +123,7 @@ break; } if (!--retries) { - PRINT_ERROR_PR("UA not clear after %d retries", + PRINT_ERROR("UA not clear after %d retries", SCST_DEV_UA_RETRIES); params->block_shift = CDROM_DEF_BLOCK_SHIFT; // res = -ENODEV; Modified: trunk/scst/src/dev_handlers/scst_changer.c =================================================================== --- trunk/scst/src/dev_handlers/scst_changer.c 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/scst/src/dev_handlers/scst_changer.c 2007-11-01 17:07:07 UTC (rev 214) @@ -65,7 +65,7 @@ if (dev->scsi_dev == NULL || dev->scsi_dev->type != dev->handler->type) { - PRINT_ERROR_PR("%s", "SCSI device not define or illegal type"); + PRINT_ERROR("%s", "SCSI device not define or illegal type"); res = -ENODEV; goto out; } Modified: trunk/scst/src/dev_handlers/scst_dev_handler.h =================================================================== --- trunk/scst/src/dev_handlers/scst_dev_handler.h 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/scst/src/dev_handlers/scst_dev_handler.h 2007-11-01 17:07:07 UTC (rev 214) @@ -18,7 +18,8 @@ TRACE_LINE | TRACE_FUNCTION | TRACE_MGMT | TRACE_MINOR | \ TRACE_MGMT_DEBUG | TRACE_SPECIAL) #else -#define SCST_DEFAULT_DEV_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MINOR) +#define SCST_DEFAULT_DEV_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MGMT | \ + TRACE_MINOR | TRACE_SPECIAL) #endif static unsigned long dh_trace_flag = SCST_DEFAULT_DEV_LOG_FLAGS; @@ -72,7 +73,7 @@ p = scst_create_proc_entry(root, DEV_HANDLER_LOG_ENTRY_NAME, &dev_handler_log_proc_data); if (p == NULL) { - PRINT_ERROR_PR("Not enough memory to register dev " + PRINT_ERROR("Not enough memory to register dev " "handler %s entry %s in /proc", dev_type->name, DEV_HANDLER_LOG_ENTRY_NAME); res = -ENOMEM; Modified: trunk/scst/src/dev_handlers/scst_disk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_disk.c 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/scst/src/dev_handlers/scst_disk.c 2007-11-01 17:07:07 UTC (rev 214) @@ -156,7 +156,7 @@ if (dev->scsi_dev == NULL || dev->scsi_dev->type != dev->handler->type) { - PRINT_ERROR_PR("%s", "SCSI device not define or illegal type"); + PRINT_ERROR("%s", "SCSI device not define or illegal type"); res = -ENODEV; goto out; } @@ -199,7 +199,7 @@ break; } if (!--retries) { - PRINT_ERROR_PR("UA not clear after %d retries", + PRINT_ERROR("UA not clear after %d retries", SCST_DEV_UA_RETRIES); res = -ENODEV; goto out_free_buf; Modified: trunk/scst/src/dev_handlers/scst_modisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_modisk.c 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/scst/src/dev_handlers/scst_modisk.c 2007-11-01 17:07:07 UTC (rev 214) @@ -156,7 +156,7 @@ if (dev->scsi_dev == NULL || dev->scsi_dev->type != dev->handler->type) { - PRINT_ERROR_PR("%s", "SCSI device not define or illegal type"); + PRINT_ERROR("%s", "SCSI device not define or illegal type"); res = -ENODEV; goto out; } @@ -211,7 +211,7 @@ break; } if (!--retries) { - PRINT_ERROR_PR("UA not clear after %d retries", + PRINT_ERROR("UA not clear after %d retries", SCST_DEV_UA_RETRIES); goto out_free_buf; } Modified: trunk/scst/src/dev_handlers/scst_processor.c =================================================================== --- trunk/scst/src/dev_handlers/scst_processor.c 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/scst/src/dev_handlers/scst_processor.c 2007-11-01 17:07:07 UTC (rev 214) @@ -65,7 +65,7 @@ if (dev->scsi_dev == NULL || dev->scsi_dev->type != dev->handler->type) { - PRINT_ERROR_PR("%s", "SCSI device not define or illegal type"); + PRINT_ERROR("%s", "SCSI device not define or illegal type"); res = -ENODEV; goto out; } Modified: trunk/scst/src/dev_handlers/scst_raid.c =================================================================== --- trunk/scst/src/dev_handlers/scst_raid.c 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/scst/src/dev_handlers/scst_raid.c 2007-11-01 17:07:07 UTC (rev 214) @@ -65,7 +65,7 @@ if (dev->scsi_dev == NULL || dev->scsi_dev->type != dev->handler->type) { - PRINT_ERROR_PR("%s", "SCSI device not define or illegal type"); + PRINT_ERROR("%s", "SCSI device not define or illegal type"); res = -ENODEV; goto out; } Modified: trunk/scst/src/dev_handlers/scst_tape.c =================================================================== --- trunk/scst/src/dev_handlers/scst_tape.c 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/scst/src/dev_handlers/scst_tape.c 2007-11-01 17:07:07 UTC (rev 214) @@ -158,7 +158,7 @@ if (dev->scsi_dev == NULL || dev->scsi_dev->type != dev->handler->type) { - PRINT_ERROR_PR("%s", "SCSI device not define or illegal type"); + PRINT_ERROR("%s", "SCSI device not define or illegal type"); res = -ENODEV; goto out; } Modified: trunk/scst/src/dev_handlers/scst_user.c =================================================================== --- trunk/scst/src/dev_handlers/scst_user.c 2007-10-26 15:58:50 UTC (rev 213) +++ trunk/scst/src/dev_handlers/scst_user.c 2007-11-01 17:07:07 UTC (rev 214) @@ -236,7 +236,7 @@ static void __dev_user_not_reg(void) { - PRINT_ERROR_PR("%s", "Device not registered"); + PRINT_ERROR("%s", "Device not registered"); return; } @@ -728,7 +728,7 @@ return res; out_invalid: - PRINT_ERROR_PR("PARSE failed (ucmd %p, rc %d, invalid %d)", ucmd, rc, + PRINT_ERROR("PARSE failed (ucmd %p, rc %d, invalid %d)", ucmd, rc, info_cdb->flags & SCST_INFO_INVALID); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_invalid_opcode)); @@ -942,7 +942,7 @@ "active (ucmd %p)", ucmd); break; } else { - TRACE(TRACE_MGMT, "Pre unreg sess %p " + TRACE_MGMT_DBG("Pre unreg sess %p " "active (ucmd %p)", found, ucmd); } } @@ -1047,7 +1047,7 @@ goto out; out_unmap: - PRINT_ERROR_PR("Failed to get %d user pages (rc %d)", + PRINT_ERROR("Failed to get %d user pages (rc %d)", ucmd->num_data_pages, rc); if (rc > 0) { for(i = 0; i < rc; i++) @@ -1074,7 +1074,7 @@ int pages; if (ucmd->buff_cached) { if (unlikely((reply->alloc_reply.pbuf & ~PAGE_MASK) != 0)) { - PRINT_ERROR_PR("Supplied pbuf %Lx isn't " + PRINT_ERROR("Supplied pbuf %Lx isn't " "page aligned", reply->alloc_reply.pbuf); goto out_hwerr; } @@ -1141,7 +1141,7 @@ return res; out_inval: - PRINT_ERROR_PR("%s", "Invalid parse_reply parameter(s)"); + PRINT_ERROR("%s", "Invalid parse_reply parameter(s)"); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error)); res = -EINVAL; goto out_process; @@ -1220,7 +1220,7 @@ goto out_busy; if (ucmd->buff_cached) { if (unlikely((ereply->pbuf & ~PAGE_MASK) != 0)) { - PRINT_ERROR_PR("Supplied pbuf %Lx isn't " + PRINT_ERROR("Supplied pbuf %Lx isn't " "page aligned", ereply->pbuf); goto out_hwerr; } @@ -1252,7 +1252,7 @@ min(sizeof(cmd->sense_buffer), (unsigned int)ereply->sense_len)); if (res < 0) { - PRINT_ERROR_PR("%s", "Unable to get sense data"); + PRINT_ERROR("%s", "Unable to get sense data"); goto out_hwerr_res_set; } } @@ -1267,7 +1267,7 @@ return res; out_inval: - PRINT_ERROR_PR("%s", "Invalid exec_reply parameter(s)"); + PRINT_ERROR("%s", "Invalid exec_reply parameter(s)"); out_hwerr: res = -EINVAL; @@ -1374,7 +1374,7 @@ return res; out_wrong_state: - PRINT_ERROR_PR("Command's %p subcode %x doesn't match internal " + PRINT_ERROR("Command's %p subcode %x doesn't match internal " "command's state %x or reply->subcode (%x) != ucmd->subcode " "(%x)", ucmd, _IOC_NR(reply->subcode), ucmd->state, reply->subcode, ucmd->user_cmd.subcode); @@ -1761,7 +1761,7 @@ break; default: - PRINT_ERROR_PR("Invalid ioctl cmd %x", cmd); + PRINT_ERROR("Invalid ioctl cmd %x", cmd); res = -EINVAL; goto out; } @@ -1923,7 +1923,7 @@ } default: - PRINT_ERROR_PR("Wrong ucmd state %x", state); + PRINT_ERROR("Wrong ucmd state %x", state); sBUG(); break; } @@ -2129,7 +2129,7 @@ spin_lock_irq(&dev->cmd_lists.cmd_list_lock); if (dev->internal_reset_active) { - PRINT_ERROR_PR("Loosing TM cmd %d, because there are other " + PRINT_ERROR("Loosing TM cmd %d, because there are other " "unprocessed TM commands", mcmd->fn); res = SCST_MGMT_STATUS_FAILED; goto out_locked_free; @@ -2138,7 +2138,7 @@ * We are going to miss some TM commands, so replace it * by the hardest one. */ - PRINT_ERROR_PR("Replacing TM cmd %d by TARGET_RESET, because " + PRINT_ERROR("Replacing TM cmd %d by TARGET_RESET, because " "there is another unprocessed TM command", mcmd->fn); ucmd->user_cmd.tm_cmd.fn = SCST_TARGET_RESET; ucmd->internal_reset_tm = 1; @@ -2159,7 +2159,7 @@ if (rc > 0) res = ucmd->result; else { - PRINT_ERROR_PR("Task management command %p timeout", ucmd); + PRINT_ERROR("Task management command %p timeout", ucmd); res = SCST_MGMT_STATUS_FAILED; } @@ -2196,7 +2196,7 @@ } spin_unlock(&dev_list_lock); if (dev == NULL) { - PRINT_ERROR_PR("Device %s not found", sdev->virt_name); + PRINT_ERROR("Device %s not found", sdev->virt_name); res = -EINVAL; goto out; } @@ -2205,7 +2205,7 @@ sdev->dh_priv = dev; - PRINT_INFO_PR("Attached user space SCSI target virtual device \"%s\"", + PRINT_INFO("Attached user space SCSI target virtual device \"%s\"", dev->name); out: @@ -2221,7 +2221,7 @@ TRACE_DBG("virt_id %d", sdev->virt_id); - PRINT_INFO_PR("Detached user space SCSI target virtual device \"%s\"", + PRINT_INFO("Detached user space SCSI target virtual device \"%s\"", dev->name); /* dev will be freed by the caller */ @@ -2306,7 +2306,7 @@ spin_lock_irq(&dev->cmd_lists.cmd_list_lock); if (dev->attach_cmd_active) { - PRINT_ERROR_PR("%s", "ATTACH_SESS command failed, because " + PRINT_ERROR("%s", "ATTACH_SESS command failed, because " "there is another unprocessed ATTACH_SESS command"); res = -EBUSY; goto out_locked_free; @@ -2321,7 +2321,7 @@ if (rc > 0) res = ucmd->result; else { - PRINT_ERROR_PR("%s", "ATTACH_SESS command timeout"); + PRINT_ERROR("%s", "ATTACH_SESS command timeout"); res = -EFAULT; } @@ -2512,7 +2512,7 @@ break; default: - PRINT_INFO_PR("Unknown SCSI type %x, using PARSE_CALL " + PRINT_INFO("Unknown SCSI type %x, using PARSE_CALL " "for it", dev->devtype.type); dev->parse_type = SCST_USER_PARSE_CALL; break; @@ -2536,7 +2536,7 @@ TRACE_ENTRY(); if (dev_desc->version != DEV_USER_VERSION) { - PRINT_ERROR_PR("Version mismatch (requested %d, required %d)", + PRINT_ERROR("Version mismatch (requested %d, required %d)", dev_desc->version, DEV_USER_VERSION); res = -EINVAL; goto out; @@ -2547,7 +2547,7 @@ case TYPE_ROM: case TYPE_MOD: if (dev_desc->block_size == 0) { - PRINT_ERROR_PR("Wrong block size %d", dev_desc->block_size); + PRINT_ERROR("Wrong block size %d", dev_desc->block_size); res = -EINVAL; goto out; } @@ -2563,7 +2563,7 @@ } if (!try_module_get(THIS_MODULE)) { - PRINT_ERROR_PR("%s", "Fail to get module"); + PRINT_ERROR("%s", "Fail to get module"); goto out; } @@ -2632,7 +2632,7 @@ list_for_each_entry(d, &dev_list, dev_list_entry) { if (strcmp(d->name, dev->name) == 0) { - PRINT_ERROR_PR("Device %s already exist", + PRINT_ERROR("Device %s already exist", dev->name); res = -EEXIST; spin_unlock(&dev_list_lock); @@ -2660,7 +2660,7 @@ mutex_lock(&dev_priv_mutex); if (file->private_data != NULL) { mutex_unlock(&dev_priv_mutex); - PRINT_ERROR_PR("%s", "Device already registered"); + PRINT_ERROR("%s", "Device already registered"); res = -EINVAL; goto out_unreg_drv; } @@ -2709,7 +2709,7 @@ (opt->memory_reuse_type > SCST_USER_MAX_MEM_REUSE_OPT) || (opt->prio_queue_type > SCST_USER_MAX_PRIO_QUEUE_OPT) || (opt->partial_transfers_type > SCST_USER_MAX_PARTIAL_TRANSFERS_OPT)) { - PRINT_ERROR_PR("%s", "Invalid option"); + PRINT_ERROR("%s", "Invalid option"); res = -EINVAL; goto out; } @@ -2913,7 +2913,7 @@ struct list_head *head = &dev->ucmd_hash[i]; struct scst_user_cmd *ucmd, *t; list_for_each_entry_safe(ucmd, t, head, hash_list_entry) { - PRINT_ERROR_PR("Lost ucmd %p (state %x, ref %d)", ucmd, + PRINT_ERROR("Lost ucmd %p (state %x, ref %d)", ucmd, ucmd->state, atomic_read(&ucmd->ucmd_ref)); ucmd_put(ucmd); } @@ -2990,7 +2990,7 @@ TRACE_ENTRY(); #if defined(CONFIG_HIGHMEM4G) || defined(CONFIG_HIGHMEM64G) - PRINT_ERROR_PR("%s", "HIGHMEM kerne... [truncated message content] |
From: <vl...@us...> - 2007-11-12 11:22:57
|
Revision: 220 http://scst.svn.sourceforge.net/scst/?rev=220&view=rev Author: vlnb Date: 2007-11-12 03:21:54 -0800 (Mon, 12 Nov 2007) Log Message: ----------- - Now iSCSI target service load considered successful if at least one listen socket was successfully open and setup - Minor race on BLOCKIO requests submittion was fixed - Other minor fixes and cleanups Modified Paths: -------------- trunk/iscsi-scst/etc/initd/initd.debian trunk/iscsi-scst/etc/initd/initd.redhat trunk/iscsi-scst/etc/scst.conf trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/usr/iscsi_scstd.c trunk/scst/src/dev_handlers/scst_vdisk.c trunk/scst/src/scst_main.c trunk/scstadmin/init.d/scst Removed Paths: ------------- trunk/scstadmin/scst.conf Modified: trunk/iscsi-scst/etc/initd/initd.debian =================================================================== --- trunk/iscsi-scst/etc/initd/initd.debian 2007-11-07 19:00:58 UTC (rev 219) +++ trunk/iscsi-scst/etc/initd/initd.debian 2007-11-12 11:21:54 UTC (rev 220) @@ -59,6 +59,7 @@ echo "succeeded." else echo "failed." + rmmod iscsi-scst fi } Modified: trunk/iscsi-scst/etc/initd/initd.redhat =================================================================== --- trunk/iscsi-scst/etc/initd/initd.redhat 2007-11-07 19:00:58 UTC (rev 219) +++ trunk/iscsi-scst/etc/initd/initd.redhat 2007-11-12 11:21:54 UTC (rev 220) @@ -67,7 +67,6 @@ stop() { echo -n "Stopping iSCSI target service: " -# iscsi-scst-adm --op delete killall iscsi-scstd rmmod -w iscsi-scst RETVAL=$? Modified: trunk/iscsi-scst/etc/scst.conf =================================================================== --- trunk/iscsi-scst/etc/scst.conf 2007-11-07 19:00:58 UTC (rev 219) +++ trunk/iscsi-scst/etc/scst.conf 2007-11-12 11:21:54 UTC (rev 220) @@ -1,7 +1,7 @@ [HANDLER vdisk] #DEVICE <vdisk name>,<device path>,<options>,<block size> DEVICE disk1,/path/disk1,,512 -DEVICE hdc1,/dev/hdc1,BLOCKIO,512 +DEVICE hdc1,/dev/hdc1,BIO,512 DEVICE nullio,none,NULLIO,1024 [HANDLER vcdrom] @@ -10,14 +10,11 @@ [ASSIGNMENT Default] #DEVICE <device name>,<lun> -[GROUP Default_iqn.2007-05.com.example:storage.disk2.sys1.xyz] -# This user isn't needed in this default group, but current version of -# scstadmin (0.7.1) has a problem that it refuses to create a group if -# it doesn't have at least one user. -USER NULL_USER - -[ASSIGNMENT Default_iqn.2007-05.com.example:storage.disk2.sys1.xyz] +[ASSIGNMENT Default_iqn.2007-05.com.example:storage.disk1.sys1.xyz] #DEVICE <device name>,<lun> DEVICE disk1,0 -DEVICE hdc1,1 DEVICE nullio,3 + +[ASSIGNMENT Default_iqn.2007-05.com.example:storage.disk2.sys1.xyz] +#DEVICE <device name>,<lun> +DEVICE hdc1,0 Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2007-11-07 19:00:58 UTC (rev 219) +++ trunk/iscsi-scst/kernel/iscsi.c 2007-11-12 11:21:54 UTC (rev 220) @@ -1410,14 +1410,18 @@ goto out; TRACE_MGMT_DBG("Aborting cmd %p, scst_cmd %p (scst state %x, " - "ref_cnt %d, net_ref_cnt %d, itt %x, op %x, r2t_len %x, " - "CDB op %x, size to write %u, is_unsolicited_data %u, " - "outstanding_r2t %u)", cmnd, cmnd->scst_cmd, cmnd->scst_state, - atomic_read(&cmnd->ref_cnt), atomic_read(&cmnd->net_ref_cnt), + "ref_cnt %d, itt %x, op %x, r2t_len %x, CDB op %x, " + "size to write %u, is_unsolicited_data %u, " + "outstanding_r2t %u)", cmnd, cmnd->scst_cmd, + cmnd->scst_state, atomic_read(&cmnd->ref_cnt), cmnd_itt(cmnd), cmnd_opcode(cmnd), cmnd->r2t_length, cmnd_scsicode(cmnd), cmnd_write_size(cmnd), cmnd->is_unsolicited_data, cmnd->outstanding_r2t); +#ifdef NET_PAGE_CALLBACKS_DEFINED + TRACE_MGMT_DBG("net_ref_cnt %d", atomic_read(&cmnd->net_ref_cnt)); +#endif + iscsi_extracheck_is_rd_thread(cmnd->conn); cmnd->tmfabort = 1; Modified: trunk/iscsi-scst/usr/iscsi_scstd.c =================================================================== --- trunk/iscsi-scst/usr/iscsi_scstd.c 2007-11-07 19:00:58 UTC (rev 219) +++ trunk/iscsi-scst/usr/iscsi_scstd.c 2007-11-12 11:21:54 UTC (rev 220) @@ -155,13 +155,14 @@ exit(1); } - for (i = 0, res = res0; res && i < LISTEN_MAX; i++, res = res->ai_next) { + i = 0; + for (res = res0; res && i < LISTEN_MAX; res = res->ai_next) { sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (sock < 0) { log_error("Unable to create server socket (%s) %d %d %d!", strerror(errno), res->ai_family, res->ai_socktype, res->ai_protocol); - exit(1); + continue; } sock_set_keepalive(sock, 50); @@ -174,26 +175,34 @@ if (res->ai_family == AF_INET6 && setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt))) { log_error("Unable to restrict IPv6 socket (%s)", strerror(errno)); - exit(1); + close(sock); + continue; } if (bind(sock, res->ai_addr, res->ai_addrlen)) { log_error("Unable to bind server socket (%s)!", strerror(errno)); - exit(1); + close(sock); + continue; } if (listen(sock, INCOMING_MAX)) { log_error("Unable to listen to server socket (%s)!", strerror(errno)); - exit(1); + close(sock); + continue; } set_non_blocking(sock); array[i].fd = sock; array[i].events = POLLIN; + + i++; } freeaddrinfo(res0); + + if (i == 0) + exit(1); } static void accept_connection(int listen) Modified: trunk/scst/src/dev_handlers/scst_vdisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_vdisk.c 2007-11-07 19:00:58 UTC (rev 219) +++ trunk/scst/src/dev_handlers/scst_vdisk.c 2007-11-12 11:21:54 UTC (rev 220) @@ -2076,6 +2076,17 @@ struct scst_cmd *cmd; }; +static inline void blockio_check_finish(struct blockio_work *blockio_work) +{ + /* Decrement the bios in processing, and if zero signal completion */ + if (atomic_dec_and_test(&blockio_work->bios_inflight)) { + blockio_work->cmd->completed = 1; + blockio_work->cmd->scst_cmd_done(blockio_work->cmd, + SCST_CMD_STATE_DEFAULT); + kfree(blockio_work); + } +} + static int blockio_endio(struct bio *bio, unsigned int bytes_done, int error) { struct blockio_work *blockio_work = bio->bi_private; @@ -2101,13 +2112,7 @@ SCST_LOAD_SENSE(scst_sense_read_error)); } - /* Decrement the bios in processing, and if zero signal completion */ - if (atomic_dec_and_test(&blockio_work->bios_inflight)) { - blockio_work->cmd->completed = 1; - blockio_work->cmd->scst_cmd_done(blockio_work->cmd, - SCST_CMD_STATE_DEFAULT); - kfree(blockio_work); - } + blockio_check_finish(blockio_work); bio_put(bio); return 0; @@ -2154,6 +2159,8 @@ thislen = 0; while (len > 0) { + int rc; + if (need_new_bio) { bio = bio_alloc(GFP_KERNEL, max_nr_vecs); if (!bio) { @@ -2181,7 +2188,9 @@ bytes = min_t(unsigned int, len, PAGE_SIZE - off); - if (bio_add_page(bio, page, bytes, off) < bytes) { + rc = bio_add_page(bio, page, bytes, off); + if (rc < bytes) { + sBUG_ON(rc != 0); need_new_bio = 1; lba_start += thislen >> virt_dev->block_shift; thislen = 0; @@ -2196,8 +2205,11 @@ lba_start += sgl[j].length >> virt_dev->block_shift; } - atomic_set(&blockio_work->bios_inflight, bios); + /* +1 to prevent erroneous too early command completion */ + atomic_set(&blockio_work->bios_inflight, bios+1); + smp_mb(); + while (hbio) { bio = hbio; hbio = hbio->bi_next; @@ -2208,6 +2220,8 @@ if (q && q->unplug_fn) q->unplug_fn(q); + blockio_check_finish(blockio_work); + out: TRACE_EXIT(); return; Modified: trunk/scst/src/scst_main.c =================================================================== --- trunk/scst/src/scst_main.c 2007-11-07 19:00:58 UTC (rev 219) +++ trunk/scst/src/scst_main.c 2007-11-12 11:21:54 UTC (rev 220) @@ -1486,9 +1486,8 @@ if (scst_threads == 0) scst_threads = scst_num_cpus; - if (scst_threads < scst_num_cpus) { - PRINT_ERROR("%s", "scst_threads can not be less than " - "CPUs count"); + if (scst_threads < 1) { + PRINT_ERROR("%s", "scst_threads can not be less than 1"); scst_threads = scst_num_cpus; } Modified: trunk/scstadmin/init.d/scst =================================================================== --- trunk/scstadmin/init.d/scst 2007-11-07 19:00:58 UTC (rev 219) +++ trunk/scstadmin/init.d/scst 2007-11-12 11:21:54 UTC (rev 220) @@ -5,7 +5,7 @@ SCST_CFG=/etc/scst.conf # Modules to load/unload -SCST_MODULES="scst_vdisk scst_disk scst_cdrom" +SCST_MODULES="qla2x00tgt scst_vdisk scst_disk" OPTIONS="" @@ -13,10 +13,8 @@ case "$1" in start) - echo -n "Loading and configuring SCSI Target Mid-level: scst " + echo -n "Loading and configuring SCSI Target Mid-level SCST " - modprobe qla2x00tgt || { echo "[qla2x00tgt failed]" ; exit 1 ; } - for module in ${SCST_MODULES}; do modprobe ${module} || { echo "[${module} failed]" ; exit 1 ; } done @@ -33,13 +31,12 @@ echo "." ;; stop) - echo -n "Stopping SCSI Target Mid-level: scst " + echo -n "Stopping SCSI Target Mid-level SCST " for module in ${SCST_MODULES}; do rmmod ${module} || { echo "[${module} failed]" ; } done - rmmod qla2x00tgt || { echo "[qla2x00tgt failed]" ; } rmmod scst || { echo "[scst failed]" ; } echo "." @@ -50,7 +47,7 @@ $0 start ;; reload-config) - echo -n "Reloading configuration: scst " + echo -n "Reloading SCST configuration " $SCST_CMD -config $SCST_CFG Deleted: trunk/scstadmin/scst.conf =================================================================== --- trunk/scstadmin/scst.conf 2007-11-07 19:00:58 UTC (rev 219) +++ trunk/scstadmin/scst.conf 2007-11-12 11:21:54 UTC (rev 220) @@ -1,51 +0,0 @@ -# SCST Configurator v0.2 - -# Handler devices -[HANDLER disk] -# DEVICE <H:C:I:L> - -[HANDLER disk_fileio] -# DEVICE <vname>,<path>,<WRITE_THROUGH|READ_ONLY|O_DIRECT|NV_CACHE|NULLIO>,<block size> -DEVICE DISK01,/tmp/test1.dsk,READ_ONLY|WRITE_THROUGH -DEVICE DISK02,/tmp/test2.dsk -DEVICE DISK03,/tmp/test3.dsk,O_DIRECT -DEVICE DISK04,/tmp/test4.dsk,,512 - -[HANDLER disk_perf] - -[HANDLER cdrom] -# DEVICE <H:C:I:L> - -[HANDLER changer] -# DEVICE <H:C:I:L> - -[HANDLER modisk] -# DEVICE <H:C:I:L> - -[HANDLER modisk_perf] - -[HANDLER tape] -# DEVICE <H:C:I:L> - -[HANDLER tape_perf] - -# Security Group -[GROUP Test] -# USER <user> -USER 50060b000001369d - -# Device Assignments -[ASSIGNMENT Test] -# DEVICE <device>,<vlun> -DEVICE DISK01,0 -DEVICE DISK02,1 -DEVICE DISK03 - -# Target to enable -[TARGETS enable] -HOST 50:06:0B:00:00:39:71:78 -HOST host4 - -# Targets to disable -[TARGETS disable] -HOST host5 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2007-12-07 17:00:51
|
Revision: 227 http://scst.svn.sourceforge.net/scst/?rev=227&view=rev Author: vlnb Date: 2007-12-07 09:00:42 -0800 (Fri, 07 Dec 2007) Log Message: ----------- Simple bugfix for concurrent work of several targets, which eventually turned out in a massive cleanup and fixes. Particularly: - Added ability for target drivers to set result of command's status delvery to initiator (see scst_set_delivery_status()) - Added ability for user space devices set some mode page parameters to make SCST core behave correspondingly - TM improvements - Few possible crashes fixed - Logging improvements - Performance improvements - Docs updates Modified Paths: -------------- trunk/doc/scst_user_spec.txt trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/kernel/iscsi_dbg.h trunk/iscsi-scst/kernel/nthread.c trunk/mpt/mpt_scst.c trunk/qla2x00t/qla2x00-target/qla2x00t.c trunk/qla_isp/linux/isp_scst.c trunk/scst/README trunk/scst/include/scsi_tgt.h trunk/scst/include/scst_const.h trunk/scst/include/scst_debug.h trunk/scst/include/scst_user.h trunk/scst/src/dev_handlers/scst_cdrom.c trunk/scst/src/dev_handlers/scst_changer.c trunk/scst/src/dev_handlers/scst_dev_handler.h trunk/scst/src/dev_handlers/scst_disk.c trunk/scst/src/dev_handlers/scst_modisk.c trunk/scst/src/dev_handlers/scst_processor.c trunk/scst/src/dev_handlers/scst_raid.c trunk/scst/src/dev_handlers/scst_tape.c trunk/scst/src/dev_handlers/scst_user.c trunk/scst/src/dev_handlers/scst_vdisk.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_main.c trunk/scst/src/scst_priv.h trunk/scst/src/scst_proc.c trunk/scst/src/scst_targ.c trunk/usr/fileio/common.c trunk/usr/fileio/common.h trunk/usr/fileio/debug.h trunk/usr/fileio/fileio.c Modified: trunk/doc/scst_user_spec.txt =================================================================== --- trunk/doc/scst_user_spec.txt 2007-11-26 16:47:16 UTC (rev 226) +++ trunk/doc/scst_user_spec.txt 2007-12-07 17:00:42 UTC (rev 227) @@ -2,7 +2,7 @@ USER SPACE INTERFACE DESCRIPTION. - Version 0.9.6/1 + Version 0.9.6/2 I. Description. @@ -62,6 +62,7 @@ { uint8_t version; uint8_t type; + uint8_t has_own_order_mgmt; struct scst_user_opt opt; uint32_t block_size; char name[SCST_MAX_NAME]; @@ -73,6 +74,10 @@ - type - SCSI type of the device + - has_own_order_mgmt - set it in non-zero, if device implements own + ORDERED commands management, i.e. guarantees commands execution order + requirements, specified by SAM. + - opt - device options, see SCST_USER_SET_OPTIONS/SCST_USER_GET_OPTIONS below - block_size - block size, shall be divisible by 512 for block devices @@ -101,6 +106,11 @@ uint8_t prio_queue_type; uint8_t partial_transfers_type; uint32_t partial_len; + + uint8_t tst; + uint8_t queue_alg; + uint8_t tas; + uint8_t swp; }, where: @@ -181,6 +191,9 @@ * SCST_USER_PARTIAL_TRANSFERS_SUPPORTED - the partial data transfers are supported without limitations. + - tst, queue_alg, tas and swp - set values for TST, QUEUE ALGORITHM MODIFIER, + TAS and SWP fields from control mode page correspondingly, see SPC. + Flags parse_type and on_free_cmd_type are designed to improve performance by eliminating context switches to the user space handler, when processing of the corresponding events isn't needed. @@ -572,6 +585,7 @@ uint8_t buffer_cached; uint8_t aborted; uint8_t status; + uint8_t delivery_status; }, where: @@ -586,7 +600,14 @@ - aborted - true, if command was aborted - status - SAM status of the commands execution + + - delivery_status - status of cmd's status/data delivery to remote + initiator. Can be: + * SCST_CMD_DELIVERY_SUCCESS - delivery succeeded + + * SCST_CMD_DELIVERY_FAILED - delivery failed + The user space handler should reply using the corresponding reply command. No error code is needed. Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2007-11-26 16:47:16 UTC (rev 226) +++ trunk/iscsi-scst/kernel/iscsi.c 2007-12-07 17:00:42 UTC (rev 227) @@ -721,7 +721,8 @@ spin_lock(&session->cmnd_hash_lock); cmnd = __cmnd_find_hash(session, itt, ttt); - cmnd_get(cmnd); + if (cmnd) + cmnd_get(cmnd); spin_unlock(&session->cmnd_hash_lock); return cmnd; @@ -1296,7 +1297,7 @@ cmnd->cmd_req = req = cmnd_find_hash(conn->session, req_hdr->itt, req_hdr->ttt); if (!req) { - PRINT_ERROR("unable to find scsi task %x %x", + PRINT_ERROR("Unable to find scsi task %x %x", cmnd_itt(cmnd), cmnd_ttt(cmnd)); goto skip_pdu; } @@ -1583,7 +1584,8 @@ int err = 0, function = req_hdr->function & ISCSI_FUNCTION_MASK; struct scst_rx_mgmt_params params; - TRACE(TRACE_MGMT, "TM cmd: req %p, itt %x, fn %d, rtt %x", req, cmnd_itt(req), + TRACE((function == ISCSI_FUNCTION_ABORT_TASK) ? TRACE_MGMT_MINOR : TRACE_MGMT, + "TM cmd: req %p, itt %x, fn %d, rtt %x", req, cmnd_itt(req), function, req_hdr->rtt); memset(¶ms, 0, sizeof(params)); @@ -2318,7 +2320,9 @@ (struct iscsi_task_mgt_hdr *)&req->pdu.bhs; struct iscsi_task_rsp_hdr *rsp_hdr; - TRACE(TRACE_MGMT, "TM req %p finished, status %d", req, status); + TRACE((req_hdr->function == ISCSI_FUNCTION_ABORT_TASK) ? + TRACE_MGMT_MINOR : TRACE_MGMT, + "TM req %p finished, status %d", req, status); rsp = iscsi_cmnd_create_rsp_cmnd(req); rsp_hdr = (struct iscsi_task_rsp_hdr *)&rsp->pdu.bhs; Modified: trunk/iscsi-scst/kernel/iscsi_dbg.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi_dbg.h 2007-11-26 16:47:16 UTC (rev 226) +++ trunk/iscsi-scst/kernel/iscsi_dbg.h 2007-12-07 17:00:42 UTC (rev 227) @@ -34,7 +34,7 @@ #ifdef DEBUG #define ISCSI_DEFAULT_LOG_FLAGS (TRACE_FUNCTION | TRACE_LINE | TRACE_PID | \ - TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MGMT_DEBUG | \ + TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MGMT_MINOR | TRACE_MGMT_DEBUG | \ TRACE_MINOR | TRACE_SPECIAL | TRACE_CONN_OC) #else #define ISCSI_DEFAULT_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MGMT | \ Modified: trunk/iscsi-scst/kernel/nthread.c =================================================================== --- trunk/iscsi-scst/kernel/nthread.c 2007-11-26 16:47:16 UTC (rev 226) +++ trunk/iscsi-scst/kernel/nthread.c 2007-12-07 17:00:42 UTC (rev 227) @@ -817,6 +817,9 @@ (unsigned long long)conn->session->sid, conn->cid, conn->write_cmnd); } + if (ref_cmd->scst_cmd != NULL) + scst_set_delivery_status(ref_cmd->scst_cmd, + SCST_CMD_DELIVERY_FAILED); return res; } Modified: trunk/mpt/mpt_scst.c =================================================================== --- trunk/mpt/mpt_scst.c 2007-11-26 16:47:16 UTC (rev 226) +++ trunk/mpt/mpt_scst.c 2007-12-07 17:00:42 UTC (rev 227) @@ -65,8 +65,8 @@ #ifdef DEBUG #define SCST_DEFAULT_MPT_LOG_FLAGS (TRACE_FUNCTION | TRACE_PID | \ - TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MGMT_DEBUG | \ - TRACE_MINOR | TRACE_SPECIAL) + TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MGMT_MINOR | \ + TRACE_MGMT_DEBUG | TRACE_MINOR | TRACE_SPECIAL) #else # ifdef TRACING #define SCST_DEFAULT_MPT_LOG_FLAGS (TRACE_FUNCTION | TRACE_PID | \ @@ -803,6 +803,7 @@ case MPT_STATUS_SENSE_ATTEMPT: atomic_set(&priv->pending_sense[init_index], MPT_STATUS_SENSE_IDLE); + /* ToDo: check and set scst_set_delivery_status(), if necessary */ scst_tgt_cmd_done(scst_cmd); break; @@ -813,6 +814,7 @@ case MPT_STATUS_SENSE_NOT_SENT: atomic_set(&priv->pending_sense[init_index], MPT_STATUS_SENSE_HANDLE_RQ); + /* ToDo: check and set scst_set_delivery_status(), if necessary */ scst_tgt_cmd_done(scst_cmd); break; @@ -831,10 +833,12 @@ default: /* nothing much to do here, we aren't * handling cached sense/status */ + /* ToDo: check and set scst_set_delivery_status(), if necessary */ scst_tgt_cmd_done(scst_cmd); break; } } else { + /* ToDo: check and set scst_set_delivery_status(), if necessary */ scst_tgt_cmd_done(scst_cmd); } @@ -1674,6 +1678,7 @@ return res; out_tgt_free: + /* ToDo: check and set scst_set_delivery_status(), if necessary */ scst_tgt_cmd_done(scst_cmd); goto out; } Modified: trunk/qla2x00t/qla2x00-target/qla2x00t.c =================================================================== --- trunk/qla2x00t/qla2x00-target/qla2x00t.c 2007-11-26 16:47:16 UTC (rev 226) +++ trunk/qla2x00t/qla2x00-target/qla2x00t.c 2007-12-07 17:00:42 UTC (rev 227) @@ -49,8 +49,8 @@ #ifdef DEBUG #define Q2T_DEFAULT_LOG_FLAGS (TRACE_FUNCTION | TRACE_PID | \ - TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MGMT_DEBUG | \ - TRACE_MINOR | TRACE_SPECIAL) + TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MGMT_MINOR | \ + TRACE_MGMT_DEBUG | TRACE_MINOR | TRACE_SPECIAL) #else # ifdef TRACING #define Q2T_DEFAULT_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MINOR | \ @@ -689,7 +689,7 @@ if (unlikely(scst_cmd_aborted(scst_cmd))) { scsi_qla_host_t *ha = sess->tgt->ha; - TRACE(TRACE_MGMT, "qla2x00tgt(%ld): terminating exchange " + TRACE(TRACE_MGMT_MINOR, "qla2x00tgt(%ld): terminating exchange " "for aborted scst_cmd=%p (tag=%Ld)", ha->instance, scst_cmd, scst_cmd_get_tag(scst_cmd)); @@ -1004,13 +1004,13 @@ handle &= ~CTIO_COMPLETION_HANDLE_MARK; if (status != CTIO_SUCCESS) { + err = 1; switch (status) { case CTIO_LIP_RESET: case CTIO_TARGET_RESET: case CTIO_ABORTED: case CTIO_TIMEOUT: case CTIO_INVALID_RX_ID: - err = 1; /* they are OK */ TRACE_MGMT_DBG("qla2x00tgt(%ld): CTIO with status %#x " "received (LIP_RESET=e, ABORTED=2, " @@ -1020,14 +1020,12 @@ case CTIO_PORT_LOGGED_OUT: case CTIO_PORT_UNAVAILABLE: - err = 1; PRINT_INFO("qla2x00tgt(%ld): CTIO with PORT LOGGED " "OUT (29) or PORT UNAVAILABLE (28) status %x " "received", ha->instance, status); break; default: - err = 1; PRINT_ERROR("qla2x00tgt(%ld): CTIO with error status " "0x%x received", ha->instance, status); break; @@ -1133,6 +1131,7 @@ out_free: if (unlikely(err)) { TRACE_MGMT_DBG("%s", "Finishing failed CTIO"); + scst_set_delivery_status(scst_cmd, SCST_CMD_DELIVERY_FAILED); } scst_tgt_cmd_done(scst_cmd); goto out; @@ -1360,7 +1359,6 @@ /* le64_to_cpu(*(uint64_t *)(((char *)atio)+0x2c))); */ /*le32_to_cpu(*(uint32_t *)atio->initiator_port_name)); */ - if (tgt->tgt_shutdown) { TRACE_MGMT_DBG("New command while device %p is shutting " "down", tgt); @@ -1606,8 +1604,9 @@ TRACE_ENTRY(); - TRACE(TRACE_MGMT, "scst_mcmd (%p) status %#x state %#x", scst_mcmd, - scst_mcmd->status, scst_mcmd->state); + TRACE((scst_mcmd->fn == SCST_ABORT_TASK) ? TRACE_MGMT_MINOR : TRACE_MGMT, + "scst_mcmd (%p) status %#x state %#x", scst_mcmd, + scst_mcmd->status, scst_mcmd->state); mcmd = scst_mgmt_cmd_get_tgt_priv(scst_mcmd); if (unlikely(mcmd == NULL)) { @@ -1671,7 +1670,7 @@ break; case IMM_NTFY_ABORT_TASK: - TRACE(TRACE_MGMT, "Abort Task (S %04x I %#x -> L %#x)", + TRACE(TRACE_MGMT_MINOR, "Abort Task (S %04x I %#x -> L %#x)", le16_to_cpu(iocb->seq_id), loop_id, le16_to_cpu(iocb->lun)); if (q2t_abort_task(ha, iocb) == 0) Modified: trunk/qla_isp/linux/isp_scst.c =================================================================== --- trunk/qla_isp/linux/isp_scst.c 2007-11-26 16:47:16 UTC (rev 226) +++ trunk/qla_isp/linux/isp_scst.c 2007-12-07 17:00:42 UTC (rev 227) @@ -547,6 +547,7 @@ xfr->td_hflags &= ~TDFH_DATA_MASK; xfr->td_xfrlen = 0; } + /* ToDo: check and set scst_set_delivery_status(), if necessary */ scst_tgt_cmd_done(scst_cmd); return; } @@ -561,6 +562,7 @@ } scst_rx_data(scst_cmd, SCST_RX_STATUS_SUCCESS, SCST_CONTEXT_TASKLET); } else { + /* ToDo: check and set scst_set_delivery_status(), if necessary */ scst_tgt_cmd_done(scst_cmd); } } else { @@ -569,6 +571,7 @@ } else if (xfr->td_hflags & TDFH_DATA_IN) { xfr->td_hflags &= ~TDFH_DATA_MASK; xfr->td_xfrlen = 0; + /* ToDo: check and set scst_set_delivery_status(), if necessary */ scst_tgt_cmd_done(scst_cmd); } } Modified: trunk/scst/README =================================================================== --- trunk/scst/README 2007-11-26 16:47:16 UTC (rev 226) +++ trunk/scst/README 2007-12-07 17:00:42 UTC (rev 227) @@ -465,9 +465,19 @@ usually it turned off by default and the status of barriers usage isn't reported anywhere in the system logs as well as there is no way to know it on the mounted file system (at - least no known one). Also note that on some real-life - workloads write through caching might perform better, than - write back one with the barrier protection turned on. + least no known one). Windows and, AFAIK, other UNIX'es don't + need any special explicit options and do necessary barrier + actions on write-back caching devices by default. Also note + that on some real-life workloads write through caching might + perform better, than write back one with the barrier + protection turned on. + Also you should realize that Linux doesn't provide a + guarantee that after sync()/fsync() all written data really + hit permanent storage, they can be then in the cache of your + backstorage device and lost on power failure event. Thus, + ever with write-through cache mode, you still need a good UPS + to protect yourself from your data loss (note, data loss, not + the file system integrity). IMPORTANT: Some disk and partition table management utilities don't support ========= block sizes >512 bytes, therefore make sure that your favorite one @@ -598,10 +608,10 @@ set the above options, except ALLOW_PASSTHROUGH_IO_SUBMIT_IN_SIRQ, using debug2perf Makefile target. -4. For kernel: +4. For other target and initiator software parts: - - Don't enable debug/hacking features, i.e. use them as they are by - default. + - Don't enable debug/hacking features in the kernel, i.e. use them as + they are by default. - The default kernel read-ahead and queuing settings are optimized for locally attached disks, therefore they are not optimal if they @@ -639,24 +649,32 @@ directory, they also affect performance. If you find the best values, please share them with us. - - Use on the target deadline IO scheduler with read_expire and - write_expire increased on all exported devices to 5000 and 20000 - correspondingly. + - On the target deadline IO scheduler with read_expire and + write_expire increased on all exported devices to 5000 and 15000 + correspondingly used to be the fastest, but currently seems CFQ often + outperforms it. So, try on your load and use the best one. - It is recommended to turn the kernel preemption off, i.e. set the kernel preemption model to "No Forced Preemption (Server)". -5. For hardware. + - Looks like XFS is the best filesystem on the target to store device + files, because it allows considerably better linear write throughput, + than ext3. - - Make sure that your target hardware (e.g. target FC card) and underlaying - IO hardware (e.g. IO card, like SATA, SCSI or RAID to which your - disks connected) stay on different PCI buses. They have to work in - parallel, so it will be better if they don't compete for the bus. The - problem is not only in the bandwidth, which they have to share, but - also in the interaction between cards during that competition. In - some cases it could lead up to 5-10 times less performance, than - expected. +5. For hardware on target. + - Make sure that your target hardware (e.g. target FC or network card) + and underlaying IO hardware (e.g. IO card, like SATA, SCSI or RAID to + which your disks connected) don't share the same PCI bus. They have + to work in parallel, so it will be better if they don't compete for + the bus. The problem is not only in the bandwidth, which they have to + share, but also in the interaction between cards during that + competition. This is very important, because in some cases if target + and backend storage controllers share the same PCI bus, it could lead + up to 5-10 times less performance, than expected. If you have no + choice, but PCI bus sharing, set in the BIOS PCI latency as low as + possible. + IMPORTANT: If you use on initiator some versions of Windows (at least W2K) ========= you can't get good write performance for VDISK FILEIO devices with default 512 bytes block sizes. You could get about 10% of the Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2007-11-26 16:47:16 UTC (rev 226) +++ trunk/scst/include/scsi_tgt.h 2007-12-07 17:00:42 UTC (rev 227) @@ -39,74 +39,92 @@ /* Version numbers, the same as for the kernel */ #define SCST_VERSION_CODE 0x000906 #define SCST_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) -#define SCST_VERSION_STRING "0.9.6-pre3" +#define SCST_VERSION_STRING "0.9.6-rc1" /************************************************************* - ** States of command processing state machine + ** States of command processing state machine. At first, + ** "active" states, then - "passive" ones. This is to have + ** more efficient generated code of the corresponding + ** "switch" statements. *************************************************************/ -/* A cmd is created, but scst_cmd_init_done() not called */ -#define SCST_CMD_STATE_INIT_WAIT 1 +/* Internal parsing */ +#define SCST_CMD_STATE_PRE_PARSE 0 -/* LUN translation (cmd->tgt_dev assignment) */ -#define SCST_CMD_STATE_INIT 2 - /* Dev handler's parse() is going to be called */ -#define SCST_CMD_STATE_DEV_PARSE 4 +#define SCST_CMD_STATE_DEV_PARSE 1 /* Allocation of the cmd's data buffer */ -#define SCST_CMD_STATE_PREPARE_SPACE 5 +#define SCST_CMD_STATE_PREPARE_SPACE 2 -/* Allocation of the cmd's data buffer */ -#define SCST_CMD_STATE_PREPROCESS_DONE 6 - /* Target driver's rdy_to_xfer() is going to be called */ -#define SCST_CMD_STATE_RDY_TO_XFER 7 +#define SCST_CMD_STATE_RDY_TO_XFER 3 -/* Waiting for data from the initiator (until scst_rx_data() called) */ -#define SCST_CMD_STATE_DATA_WAIT 8 - /* Target driver's pre_exec() is going to be called */ -#define SCST_CMD_STATE_PRE_EXEC 9 +#define SCST_CMD_STATE_TGT_PRE_EXEC 4 /* CDB is going to be sent to SCSI mid-level for execution */ -#define SCST_CMD_STATE_SEND_TO_MIDLEV 10 +#define SCST_CMD_STATE_SEND_TO_MIDLEV 5 -/* Waiting for CDB's execution finish */ -#define SCST_CMD_STATE_EXECUTING 11 +/* Internal pos-exec checks */ +#define SCST_CMD_STATE_PRE_DEV_DONE 6 +/* Internal MODE SELECT pages related checks */ +#define SCST_CMD_STATE_MODE_SELECT_CHECKS 7 + /* Dev handler's dev_done() is going to be called */ -#define SCST_CMD_STATE_DEV_DONE 12 +#define SCST_CMD_STATE_DEV_DONE 8 /* Target driver's xmit_response() is going to be called */ -#define SCST_CMD_STATE_XMIT_RESP 13 +#define SCST_CMD_STATE_PRE_XMIT_RESP 9 -/* Waiting for response's transmission finish */ -#define SCST_CMD_STATE_XMIT_WAIT 14 +/* Target driver's xmit_response() is going to be called */ +#define SCST_CMD_STATE_XMIT_RESP 10 /* The cmd finished */ -#define SCST_CMD_STATE_FINISHED 15 +#define SCST_CMD_STATE_FINISHED 11 +#define SCST_CMD_STATE_LAST_ACTIVE (SCST_CMD_STATE_FINISHED+100) + + +/* A cmd is created, but scst_cmd_init_done() not called */ +#define SCST_CMD_STATE_INIT_WAIT (SCST_CMD_STATE_LAST_ACTIVE+1) + +/* LUN translation (cmd->tgt_dev assignment) */ +#define SCST_CMD_STATE_INIT (SCST_CMD_STATE_LAST_ACTIVE+2) + +/* Allocation of the cmd's data buffer */ +#define SCST_CMD_STATE_PREPROCESS_DONE (SCST_CMD_STATE_LAST_ACTIVE+3) + +/* Waiting for data from the initiator (until scst_rx_data() called) */ +#define SCST_CMD_STATE_DATA_WAIT (SCST_CMD_STATE_LAST_ACTIVE+4) + +/* Waiting for CDB's execution finish */ +#define SCST_CMD_STATE_EXECUTING (SCST_CMD_STATE_LAST_ACTIVE+5) + +/* Waiting for response's transmission finish */ +#define SCST_CMD_STATE_XMIT_WAIT (SCST_CMD_STATE_LAST_ACTIVE+6) + /************************************************************* - ** Can be retuned instead of cmd's state by dev handlers' - ** functions, if the command's state should be set by default + * Can be retuned instead of cmd's state by dev handlers' + * functions, if the command's state should be set by default *************************************************************/ -#define SCST_CMD_STATE_DEFAULT 0 +#define SCST_CMD_STATE_DEFAULT 500 /************************************************************* - ** Can be retuned instead of cmd's state by dev handlers' - ** functions, if it is impossible to complete requested - ** task in atomic context. The cmd will be restarted in thread - ** context. + * Can be retuned instead of cmd's state by dev handlers' + * functions, if it is impossible to complete requested + * task in atomic context. The cmd will be restarted in thread + * context. *************************************************************/ -#define SCST_CMD_STATE_NEED_THREAD_CTX 100 +#define SCST_CMD_STATE_NEED_THREAD_CTX 1000 /************************************************************* - ** Can be retuned instead of cmd's state by dev handlers' - ** parse function, if the cmd processing should be stopped - ** for now. The cmd will be restarted by dev handlers itself. + * Can be retuned instead of cmd's state by dev handlers' + * parse function, if the cmd processing should be stopped + * for now. The cmd will be restarted by dev handlers itself. *************************************************************/ -#define SCST_CMD_STATE_STOP 101 +#define SCST_CMD_STATE_STOP 1001 /************************************************************* ** States of mgmt command processing state machine @@ -206,6 +224,9 @@ */ #define SCST_PREPROCESS_STATUS_ERROR_FATAL 3 +/* Thread context requested */ +#define SCST_PREPROCESS_STATUS_NEED_THREAD 4 + /************************************************************* ** Allowed return codes for xmit_response(), rdy_to_xfer(), ** report_aen() @@ -314,22 +335,8 @@ /* Set if no response should be sent to the target about this cmd */ #define SCST_CMD_NO_RESP 2 -/* - * Set if the cmd is being executed. Needed to guarantee that - * "no further responses from the task are sent to - * the SCSI initiator port" after response from the TM function is - * sent (SAM) as well as correct ABORT TASK status code - */ -#define SCST_CMD_EXECUTING 3 - -/* - * Set if the cmd status/data are being xmitted. The purpose is the - * same as for SCST_CMD_EXECUTING - */ -#define SCST_CMD_XMITTING 4 - /* Set if the cmd is dead and can be destroyed at any time */ -#define SCST_CMD_CAN_BE_DESTROYED 5 +#define SCST_CMD_CAN_BE_DESTROYED 3 /************************************************************* ** Tgt_dev's flags (tgt_dev_flags) @@ -664,9 +671,6 @@ /* Set, if no /proc files should be automatically created by SCST */ unsigned no_proc:1; - /* Set if increment expected_sn in cmd->scst_cmd_done() */ - unsigned inc_expected_sn_on_done:1; - /* * Called to parse CDB from the cmd and initialize * cmd->bufflen and cmd->data_direction (both - REQUIRED). @@ -964,6 +968,9 @@ */ unsigned int sent_to_midlev:1; + /* Set if scst_local_exec() was already called for this cmd */ + unsigned int local_exec_done:1; + /* Set if the cmd's action is completed */ unsigned int completed:1; @@ -1058,9 +1065,6 @@ /* Set if the cmd is deferred HEAD OF QUEUE */ unsigned int hq_deferred:1; - /* Set if the internal parse should be skipped */ - unsigned int skip_parse:1; - /* * Set if increment expected_sn in cmd->scst_cmd_done() (to save * extra dereferences) @@ -1074,14 +1078,17 @@ unsigned long cmd_flags; /* cmd's async flags */ + /* Keeps status of cmd's status/data delivery to remote initiator */ + int delivery_status; + struct scst_tgt_template *tgtt; /* to save extra dereferences */ struct scst_tgt *tgt; /* to save extra dereferences */ struct scst_device *dev; /* to save extra dereferences */ + struct scst_tgt_dev *tgt_dev; /* corresponding device for this cmd */ + lun_t lun; /* LUN for this cmd */ - struct scst_tgt_dev *tgt_dev; /* corresponding device for this cmd */ - /* The corresponding mgmt cmd, if any, protected by sess_list_lock */ struct scst_mgmt_cmd *mgmt_cmnd; @@ -1276,6 +1283,26 @@ /**************************************************************/ + /************************************************************* + ** Dev's control mode page related values. Updates serialized + ** by scst_block_dev(). It's long to not interfere with the + ** above flags. + *************************************************************/ + + unsigned long queue_alg:4; + unsigned long tst:3; + unsigned long tas:1; + unsigned long swp:1; + + /* + * Set if device implements own ordered commands management. + * Particularly, if set, expected_sn will be incremented immediately + * after exec() returned. + */ + unsigned long has_own_order_mgmt:1; + + /**************************************************************/ + spinlock_t dev_lock; /* device lock */ /* @@ -1304,8 +1331,8 @@ /* Used to wait for requested amount of "on_dev" commands */ wait_queue_head_t on_dev_waitQ; - /* A list entry used during RESETs, protected by scst_mutex */ - struct list_head reset_dev_list_entry; + /* A list entry used during TM, protected by scst_mutex */ + struct list_head tm_dev_list_entry; /* Virtual device internal ID */ int virt_id; @@ -1411,8 +1438,6 @@ /* internal tmp list entry */ struct list_head extra_tgt_dev_list_entry; - - }; /* @@ -1692,7 +1717,9 @@ /* * Notifies SCST that the driver sent the response and the command - * can be freed now. + * can be freed now. Don't forget to set the delivery status, if it + * isn't success, using scst_set_delivery_status() before calling + * this function. */ void scst_tgt_cmd_done(struct scst_cmd *cmd); @@ -2135,6 +2162,22 @@ } /* + * Get/clear functions for cmd's delivery_status. It is one of + * SCST_CMD_DELIVERY_* constants, it specifies the status of the + * command's delivery to initiator. + */ +static inline int scst_get_delivery_status(struct scst_cmd *cmd) +{ + return cmd->delivery_status; +} + +static inline void scst_set_delivery_status(struct scst_cmd *cmd, + int delivery_status) +{ + cmd->delivery_status = delivery_status; +} + +/* * Get/Set function for mgmt cmd's target private data */ static inline void *scst_mgmt_cmd_get_tgt_priv(struct scst_mgmt_cmd *mcmd) @@ -2314,6 +2357,9 @@ int scst_add_cmd_threads(int num); void scst_del_cmd_threads(int num); +void scst_set_sense(uint8_t *buffer, int len, int key, + int asc, int ascq); + void scst_set_cmd_error_sense(struct scst_cmd *cmd, uint8_t *sense, unsigned int len); @@ -2334,7 +2380,7 @@ * Checks if total memory allocated by commands is less, than defined * limit (scst_cur_max_cmd_mem) and returns 0, if it is so. Otherwise, * returnes 1 and sets on cmd QUEUE FULL or BUSY status as well as - * SCST_CMD_STATE_XMIT_RESP state. Target drivers and dev handlers are + * SCST_CMD_STATE_PRE_XMIT_RESP state. Target drivers and dev handlers are * required to call this function if they allocate data buffers on their * own. */ Modified: trunk/scst/include/scst_const.h =================================================================== --- trunk/scst/include/scst_const.h 2007-11-26 16:47:16 UTC (rev 226) +++ trunk/scst/include/scst_const.h 2007-12-07 17:00:42 UTC (rev 227) @@ -3,7 +3,7 @@ * * Copyright (C) 2004-2007 Vladislav Bolkhovitin <vs...@vl...> * - * Contains macroses for execution tracing and error reporting + * Contains common SCST constants. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -29,6 +29,13 @@ /* Max size of sense */ #define SCST_SENSE_BUFFERSIZE 96 +/************************************************************* + ** Allowed delivery statuses for cmd's delivery_status + *************************************************************/ + +#define SCST_CMD_DELIVERY_SUCCESS 0 +#define SCST_CMD_DELIVERY_FAILED -1 + /************************************************************* ** Values for task management functions *************************************************************/ @@ -48,7 +55,7 @@ */ #define SCST_NEXUS_LOSS_SESS 6 -/* Aborts all tasks in the corresponding session with TASK_ABORTED status */ +/* Aborts all tasks in the corresponding session */ #define SCST_ABORT_ALL_TASKS_SESS 7 /* @@ -58,7 +65,7 @@ */ #define SCST_NEXUS_LOSS 8 -/* Aborts all tasks in all sessions of the tgt with TASK_ABORTED status */ +/* Aborts all tasks in all sessions of the tgt */ #define SCST_ABORT_ALL_TASKS 9 /************************************************************* @@ -100,6 +107,11 @@ #define SCST_NO_SENSE(sense) (((uint8_t *)(sense))[2] == 0) +static inline int scst_is_ua_sense(const uint8_t *sense) +{ + return SCST_SENSE_VALID(sense) && (sense[2] == UNIT_ATTENTION); +} + /************************************************************* ** Sense data for the appropriate errors. Can be used with ** scst_set_cmd_error() @@ -122,7 +134,10 @@ #define scst_sense_write_error MEDIUM_ERROR, 0x03, 0 #define scst_sense_not_ready NOT_READY, 0x04, 0x10 #define scst_sense_invalid_message ILLEGAL_REQUEST, 0x49, 0 +#define scst_sense_cleared_by_another_ini_UA UNIT_ATTENTION, 0x2F, 0 +#define SCST_STANDARD_SENSE_LEN 14 + /************************************************************* * SCSI opcodes not listed anywhere else *************************************************************/ @@ -231,6 +246,18 @@ #define LONG_BIT 2 #define BT_BIT 1 +/************************************************************* + ** Values for the control mode page TST field + *************************************************************/ +#define SCST_CONTR_MODE_ONE_TASK_SET 0 +#define SCST_CONTR_MODE_SEP_TASK_SETS 1 + +/******************************************************************* + ** Values for the control mode page QUEUE ALGORITHM MODIFIER field + *******************************************************************/ +#define SCST_CONTR_MODE_QUEUE_ALG_RESTRICTED_REORDER 0 +#define SCST_CONTR_MODE_QUEUE_ALG_UNRESTRICTED_REORDER 1 + /************************************************************* ** Misc SCSI constants *************************************************************/ Modified: trunk/scst/include/scst_debug.h =================================================================== --- trunk/scst/include/scst_debug.h 2007-11-26 16:47:16 UTC (rev 226) +++ trunk/scst/include/scst_debug.h 2007-12-07 17:00:42 UTC (rev 227) @@ -116,9 +116,10 @@ #define TRACE_OUT_OF_MEM 0x00000100 #define TRACE_MINOR 0x00000200 /* less important events */ #define TRACE_MGMT 0x00000400 -#define TRACE_MGMT_DEBUG 0x00000800 -#define TRACE_SCSI 0x00001000 -#define TRACE_SPECIAL 0x00002000 /* filtering debug, etc */ +#define TRACE_MGMT_MINOR 0x00000800 +#define TRACE_MGMT_DEBUG 0x00001000 +#define TRACE_SCSI 0x00002000 +#define TRACE_SPECIAL 0x00004000 /* filtering debug, etc */ #define TRACE_ALL 0xffffffff /* Flags 0xXXXX0000 are local for users */ @@ -151,26 +152,12 @@ } \ } while(0) -#define TRACE_LOG_FLAG(log_flag, trace, format, args...) \ -do { \ - char *__tflag = log_flag; \ - if (trace_flag & (trace)) \ - { \ - if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \ - __LINE__) > 0) \ - { \ - __tflag = NO_FLAG; \ - } \ - } \ - PRINT(NO_FLAG, "%s" format, __tflag, args); \ -} while(0) - #define TRACE_BUFFER(message, buff, len) \ do { \ if (trace_flag & TRACE_BUFF) \ { \ char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \ + if (debug_print_prefix(trace_flag, NULL, __FUNCTION__, \ __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ @@ -185,7 +172,7 @@ if (trace_flag & (flag)) \ { \ char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \ + if (debug_print_prefix(trace_flag, NULL, __FUNCTION__, \ __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ @@ -195,11 +182,18 @@ } \ } while(0) +#define PRINT_BUFFER(message, buff, len) \ +do { \ + PRINT(NO_FLAG, "%s:", message); \ + debug_print_buffer(buff, len); \ +} while(0) + #else /* DEBUG || TRACING */ #define TRACE(trace, args...) {} #define TRACE_BUFFER(message, buff, len) {} #define TRACE_BUFF_FLAG(flag, message, buff, len) {} +#define PRINT_BUFFER(message, buff, len) {} #endif /* DEBUG || TRACING */ @@ -210,7 +204,7 @@ if (trace_flag & TRACE_MEMORY) \ { \ char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \ + if (debug_print_prefix(trace_flag, NULL, __FUNCTION__, \ __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ @@ -224,7 +218,7 @@ if (trace_flag & TRACE_DEBUG) \ { \ char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \ + if (debug_print_prefix(trace_flag, NULL, __FUNCTION__, \ __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ @@ -238,7 +232,7 @@ if (trace_flag & (TRACE_DEBUG|TRACE_SPECIAL)) \ { \ char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \ + if (debug_print_prefix(trace_flag, NULL, __FUNCTION__, \ __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ @@ -252,7 +246,7 @@ if (trace_flag & TRACE_MGMT_DEBUG) \ { \ char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \ + if (debug_print_prefix(trace_flag, NULL, __FUNCTION__, \ __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ @@ -266,7 +260,7 @@ if (trace_flag & (TRACE_MGMT_DEBUG|TRACE_SPECIAL)) \ { \ char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \ + if (debug_print_prefix(trace_flag, NULL, __FUNCTION__, \ __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ @@ -275,24 +269,35 @@ } \ } while(0) -#define PRINT_ERROR(format, args...) \ -do { \ - if (ERROR_FLAG != LOG_FLAG) \ - { \ - TRACE_LOG_FLAG(LOG_FLAG, trace_flag, "***ERROR*** " format, args); \ - } \ - TRACE_LOG_FLAG(ERROR_FLAG, trace_flag, "***ERROR*** " format, args); \ +#define PRINT_LOG_FLAG(log_flag, format, args...) \ +do { \ + char *__tflag = log_flag; \ + if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \ + __LINE__) > 0) \ + { \ + __tflag = NO_FLAG; \ + } \ + PRINT(NO_FLAG, "%s" format, __tflag, args); \ } while(0) -#define PRINT_INFO(format, args...) \ -do { \ - if (INFO_FLAG != LOG_FLAG) \ - { \ - TRACE_LOG_FLAG(LOG_FLAG, trace_flag, format, args); \ - } \ - TRACE_LOG_FLAG(INFO_FLAG, trace_flag, format, args); \ +#define PRINT_ERROR(format, args...) \ +do { \ + if (ERROR_FLAG != LOG_FLAG) \ + { \ + PRINT_LOG_FLAG(LOG_FLAG, "***ERROR*** " format, args); \ + } \ + PRINT_LOG_FLAG(ERROR_FLAG, "***ERROR*** " format, args); \ } while(0) +#define PRINT_INFO(format, args...) \ +do { \ + if (INFO_FLAG != LOG_FLAG) \ + { \ + PRINT_LOG_FLAG(LOG_FLAG, format, args); \ + } \ + PRINT_LOG_FLAG(INFO_FLAG, format, args); \ +} while(0) + #define TRACE_ENTRY() \ do { \ if (trace_flag & TRACE_ENTRYEXIT) \ Modified: trunk/scst/include/scst_user.h =================================================================== --- trunk/scst/include/scst_user.h 2007-11-26 16:47:16 UTC (rev 226) +++ trunk/scst/include/scst_user.h 2007-12-07 17:00:42 UTC (rev 227) @@ -3,7 +3,9 @@ * * Copyright (C) 2007 Vladislav Bolkhovitin <vs...@vl...> * - * Contains macroses for execution tracing and error reporting + * Contains constants and data structures for scst_user module. + * See http://scst.sourceforge.net/doc/scst_user_spec.txt or + * scst_user_spec.txt for description. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -23,7 +25,7 @@ #define DEV_USER_NAME "scst_user" #define DEV_USER_PATH "/dev/" -#define DEV_USER_VERSION 961 +#define DEV_USER_VERSION 962 /* * Chosen so sizeof(scst_user_sess) <= sizeof(scst_user_scsi_cmd_exec) @@ -91,6 +93,14 @@ uint8_t prio_queue_type; uint8_t partial_transfers_type; int32_t partial_len; + + /* SCSI control mode page parameters, see SPC */ + uint8_t tst; + uint8_t queue_alg; + uint8_t tas; + uint8_t swp; + + uint8_t has_own_order_mgmt; }; struct scst_user_dev_desc @@ -170,6 +180,7 @@ uint8_t buffer_cached; uint8_t aborted; uint8_t status; + uint8_t delivery_status; }; struct scst_user_on_cached_mem_free Modified: trunk/scst/src/dev_handlers/scst_cdrom.c =================================================================== --- trunk/scst/src/dev_handlers/scst_cdrom.c 2007-11-26 16:47:16 UTC (rev 226) +++ trunk/scst/src/dev_handlers/scst_cdrom.c 2007-12-07 17:00:42 UTC (rev 227) @@ -18,6 +18,7 @@ */ #include <linux/cdrom.h> +#include <scsi/scsi_host.h> #define LOG_PREFIX "dev_cdrom" @@ -210,7 +211,7 @@ scst_cdrom_generic_parse(cmd, info_cdb, cdrom_get_block_shift); - cmd->retries = 1; + cmd->retries = SCST_PASSTHROUGH_RETRIES; if (info_cdb->flags & SCST_SMALL_TIMEOUT) { cmd->timeout = CDROM_SMALL_TIMEOUT; Modified: trunk/scst/src/dev_handlers/scst_changer.c =================================================================== --- trunk/scst/src/dev_handlers/scst_changer.c 2007-11-26 16:47:16 UTC (rev 226) +++ trunk/scst/src/dev_handlers/scst_changer.c 2007-12-07 17:00:42 UTC (rev 227) @@ -17,6 +17,8 @@ * GNU General Public License for more details. */ +#include <scsi/scsi_host.h> + #define LOG_PREFIX "dev_changer" #include "scsi_tgt.h" @@ -130,7 +132,7 @@ scst_changer_generic_parse(cmd, info_cdb, 0); - cmd->retries = 1; + cmd->retries = SCST_PASSTHROUGH_RETRIES; if (info_cdb->flags & SCST_LONG_TIMEOUT) { cmd->timeout = CHANGER_LONG_TIMEOUT; Modified: trunk/scst/src/dev_handlers/scst_dev_handler.h =================================================================== --- trunk/scst/src/dev_handlers/scst_dev_handler.h 2007-11-26 16:47:16 UTC (rev 226) +++ trunk/scst/src/dev_handlers/scst_dev_handler.h 2007-12-07 17:00:42 UTC (rev 227) @@ -15,8 +15,8 @@ #ifdef DEBUG #define SCST_DEFAULT_DEV_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_PID | \ - TRACE_LINE | TRACE_FUNCTION | TRACE_MGMT | TRACE_MINOR | \ - TRACE_MGMT_DEBUG | TRACE_SPECIAL) + TRACE_LINE | TRACE_FUNCTION | TRACE_MGMT | TRACE_MGMT_MINOR | \ + TRACE_MINOR | TRACE_MGMT_DEBUG | TRACE_SPECIAL) #else #define SCST_DEFAULT_DEV_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MGMT | \ TRACE_MINOR | TRACE_SPECIAL) @@ -29,6 +29,8 @@ #define trace_log_tbl NULL #endif +#define SCST_PASSTHROUGH_RETRIES 0 + static struct scst_proc_data dev_handler_log_proc_data; static int dev_handler_log_info_show(struct seq_file *seq, void *v) Modified: trunk/scst/src/dev_handlers/scst_disk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_disk.c 2007-11-26 16:47:16 UTC (rev 226) +++ trunk/scst/src/dev_handlers/scst_disk.c 2007-12-07 17:00:42 UTC (rev 227) @@ -22,6 +22,7 @@ #include <linux/module.h> #include <linux/init.h> +#include <scsi/scsi_host.h> #define LOG_PREFIX "dev_disk" @@ -282,7 +283,7 @@ scst_sbc_generic_parse(cmd, info_cdb, disk_get_block_shift); - cmd->retries = 1; + cmd->retries = SCST_PASSTHROUGH_RETRIES; if (info_cdb->flags & SCST_SMALL_TIMEOUT) { cmd->timeout = DISK_SMALL_TIMEOUT; Modified: trunk/scst/src/dev_handlers/scst_modisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_modisk.c 2007-11-26 16:47:16 UTC (rev 226) +++ trunk/scst/src/dev_handlers/scst_modisk.c 2007-12-07 17:00:42 UTC (rev 227) @@ -22,6 +22,7 @@ #include <linux/module.h> #include <linux/init.h> +#include <scsi/scsi_host.h> #define LOG_PREFIX "dev_modisk" @@ -297,7 +298,7 @@ scst_modisk_generic_parse(cmd, info_cdb, modisk_get_block_shift); - cmd->retries = 1; + cmd->retries = SCST_PASSTHROUGH_RETRIES; if (info_cdb->flags & SCST_SMALL_TIMEOUT) { cmd->timeout = MODISK_SMALL_TIMEOUT; Modified: trunk/scst/src/dev_handlers/scst_processor.c =================================================================== --- trunk/scst/src/dev_handlers/scst_processor.c 2007-11-26 16:47:16 UTC (rev 226) +++ trunk/scst/src/dev_handlers/scst_processor.c 2007-12-07 17:00:42 UTC (rev 227) @@ -17,6 +17,8 @@ * GNU General Public License for more details. */ +#include <scsi/scsi_host.h> + #define LOG_PREFIX "dev_processor" #include "scsi_tgt.h" @@ -130,7 +132,7 @@ scst_processor_generic_parse(cmd, info_cdb, 0); - cmd->retries = 1; + cmd->retries = SCST_PASSTHROUGH_RETRIES; if (info_cdb->flags & SCST_LONG_TIMEOUT) { cmd->timeout = PROCESSOR_LONG_TIMEOUT; Modified: trunk/scst/src/dev_handlers/scst_raid.c =================================================================== --- trunk/scst/src/dev_handlers/scst_raid.c 2007-11-26 16:47:16 UTC (rev 226) +++ trunk/scst/src/dev_handlers/scst_raid.c 2007-12-07 17:00:42 UTC (rev 227) @@ -19,6 +19,8 @@ #define LOG_PREFIX "dev_raid" +#include <scsi/scsi_host.h> + #include "scsi_tgt.h" #include "scst_dev_handler.h" @@ -30,9 +32,9 @@ parse_atomic: 1, \ /* dev_done_atomic: 1,*/ \ attach: raid_attach, \ -/* detach: raid_detach,*/ \ +/* detach: raid_detach,*/ \ parse: raid_parse, \ -/* dev_done: raid_done*/ \ +/* dev_done: raid_done*/ \ } #define RAID_RETRIES 2 @@ -130,7 +132,7 @@ scst_raid_generic_parse(cmd, info_cdb, 0); - cmd->retries = 1; + cmd->retries = SCST_PASSTHROUGH_RETRIES; if (info_cdb->flags & SCST_LONG_TIMEOUT) { cmd->timeout = RAID_LONG_TIMEOUT; Modified: trunk/scst/src/dev_handlers/scst_tape.c =================================================================== --- trunk/scst/src/dev_handlers/scst_tape.c 2007-11-26 16:47:16 UTC (rev 226) +++ trunk/scst/src/dev_handlers/scst_tape.c 2007-12-07 17:00:42 UTC (rev 227) @@ -22,6 +22,7 @@ #include <linux/module.h> #include <linux/init.h> +#include <scsi/scsi_host.h> #define LOG_PREFIX "dev_tape" @@ -285,7 +286,7 @@ scst_tape_generic_parse(cmd, info_cdb, tape_get_block_size); - cmd->retries = 1; + cmd->retries = SCST_PASSTHROUGH_RETRIES; if (info_cdb->flags & SCST_SMALL_TIMEOUT) { cmd->timeout = TAPE_SMALL_TIMEOUT; Modified: trunk/scst/src/dev_handlers/scst_user.c =================================================================== --- trunk/scst/src/dev_handlers/scst_user.c 2007-11-26 16:47:16 UTC (rev 226) +++ trunk/scst/src/dev_handlers/scst_user.c 2007-12-07 17:00:42 UTC (rev 227) @@ -59,6 +59,12 @@ unsigned short internal_reset_active:1; unsigned short pre_unreg_sess_active:1; /* just a small optimization */ + unsigned short tst:3; + unsigned short queue_alg:4; + unsigned short tas:1; + unsigned short swp:1; + unsigned short has_own_order_mgmt:1; + unsigned short detach_cmd_count; int (*generic_parse)(struct scst_cmd *cmd, struct scst_info_cdb *info_cdb, @@ -82,6 +88,8 @@ unsigned int handle_counter; struct list_head ucmd_hash[1<<DEV_USER_CMD_HASH_ORDER]; + struct scst_device *sdev; + int virt_id; struct list_head dev_list_entry; char name[SCST_MAX_NAME]; @@ -552,6 +560,14 @@ TRACE_ENTRY(); + if (unlikely(ucmd->cmd->data_buf_tgt_alloc)) { + PRINT_ERROR("Target driver %s requested own memory " + "allocation", ucmd->cmd->tgtt->name); + scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error)); + res = SCST_CMD_STATE_PRE_XMIT_RESP; + goto out; + } + ucmd->state = UCMD_STATE_BUF_ALLOCING; cmd->data_buf_alloced = 1; @@ -560,7 +576,7 @@ goto out; else if (rc < 0) { scst_set_busy(cmd); - res = SCST_CMD_STATE_XMIT_RESP; + res = SCST_CMD_STATE_PRE_XMIT_RESP; goto out; } @@ -671,16 +687,14 @@ rc = dev->generic_parse(cmd, info_cdb, dev_user_get_block); if ((rc != 0) || (info_cdb->flags & SCST_INFO_INVALID)) goto out_invalid; - ucmd->cmd->skip_parse = 1; break; case SCST_USER_PARSE_EXCEPTION: TRACE_DBG("PARSE EXCEPTION: ucmd %p", ucmd); rc = dev->generic_parse(cmd, info_cdb, dev_user_get_block); - if ((rc == 0) && (!(info_cdb->flags & SCST_INFO_INVALID))) { - ucmd->cmd->skip_parse = 1; + if ((rc == 0) && (!(info_cdb->flags & SCST_INFO_INVALID))) break; - } else if (rc == SCST_CMD_STATE_NEED_THREAD_CTX) { + else if (rc == SCST_CMD_STATE_NEED_THREAD_CTX) { TRACE_MEM("Restarting PARSE to thread context " "(ucmd %p)", ucmd); res = SCST_CMD_STATE_NEED_THREAD_CTX; @@ -691,7 +705,6 @@ case SCST_USER_PARSE_CALL: TRACE_DBG("Preparing PARSE for user space (ucmd=%p, h=%d, " "bufflen %d)", ucmd, ucmd->h, cmd->bufflen); - ucmd->cmd->skip_parse = 1; ucmd->user_cmd.cmd_h = ucmd->h; ucmd->user_cmd.subcode = SCST_USER_PARSE; ucmd->user_cmd.parse_cmd.sess_h = (unsigned long)cmd->tgt_dev; @@ -733,7 +746,7 @@ scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_invalid_opcode)); out_error: - res = SCST_CMD_STATE_XMIT_RESP; + res = SCST_CMD_STATE_PRE_XMIT_RESP; goto out; } @@ -850,6 +863,7 @@ ucmd->user_cmd.on_free_cmd.buffer_cached = ucmd->buff_cached; ucmd->user_cmd.on_free_cmd.aborted = ucmd->aborted; ucmd->user_cmd.on_free_cmd.status = cmd->status; + ucmd->user_cmd.on_free_cmd.delivery_status = cmd->delivery_status; ucmd->state = UCMD_STATE_ON_FREEING; @@ -1043,7 +1057,7 @@ /* go through */ out_err: - ucmd->cmd->state = SCST_CMD_STATE_XMIT_RESP; + ucmd->cmd->state = SCST_CMD_STATE_PRE_XMIT_RESP; goto out; out_unmap: @@ -1084,7 +1098,7 @@ res = dev_user_map_buf(ucmd, reply->alloc_reply.pbuf, pages); } else { scst_set_busy(ucmd->cmd); - ucmd->cmd->state = SCST_CMD_STATE_XMIT_RESP; + ucmd->cmd->state = SCST_CMD_STATE_PRE_XMIT_RESP; } out_process: @@ -1868,7 +1882,6 @@ if (test_bit(SCST_CMD_ABORTED, &ucmd->cmd->cmd_flags)) ucmd->aborted = 1; else { - ucmd->cmd->completed = 1; if (busy) scst_set_busy(ucmd->cmd); else @@ -2202,9 +2215,15 @@ } sdev->p_cmd_lists = &dev->cmd_lists; - sdev->dh_priv = dev; + sdev->tst = dev->tst; + sdev->queue_alg = dev->queue_alg; + sdev->swp = dev->swp; + sdev->tas = dev->tas; + sdev->has_own_order_mgmt = dev->has_own_order_mgmt; + dev->sdev = sdev; + PRINT_INFO("Attached user space SCSI target virtual device \"%s\"", dev->name); @@ -2226,6 +2245,7 @@ /* dev will be freed by the caller */ sdev->dh_priv = NULL; + dev->sdev = NULL; TRACE_EXIT(); return; @@ -2610,7 +2630,6 @@ dev->devtype.exec_atomic = 0; /* no point to make it 1 */ dev->devtype.dev_done_atomic = 1; dev->devtype.no_proc = 1; - dev->devtype.inc_expected_sn_on_done = 1; dev->devtype.attach = dev_user_attach; dev->devtype.detach = dev_user_detach; dev->devtype.attach_tgt = dev_user_attach_tgt; @@ -2714,6 +2733,18 @@ goto out; } + if (((opt->tst != SCST_CONTR_MODE_ONE_TASK_SET) && + (opt->tst != SCST_CONTR_MODE_SEP_TASK_SETS)) || + ((opt->queue_alg != SCST_CONTR_MODE_QUEUE_ALG_RESTRICTED_REORDER) && + (opt->queue_alg != SCST_CONTR_MODE_QUEUE_ALG_UNRESTRICTED_REORDER)) || + (opt->swp > 1) || (opt->tas > 1) || (opt->has_own_order_mgmt > 1)) { + PRINT_ERROR("Invalid SCSI option (tst %x, queue_alg %x, swp %x, " + "tas %x, has_own_order_mgmt %x)", opt->tst, + opt->queue_alg, opt->swp, opt->tas, opt->has_own_order_mgmt); + res = -EINVAL; + goto out; + } + if ((dev->prio_queue_type != opt->prio_queue_type) && (opt->prio_queue_type == SCST_USER_PRIO_QUEUE_SINGLE)) { struct scst_user_cmd *u, *t; @@ -2732,6 +2763,19 @@ dev->partial_transfers_type = opt->partial_transfers_type; dev->partial_len = opt->partial_len; + dev->tst = opt->tst; + dev->queue_alg = opt->queue_alg; + dev->swp = opt->swp; + dev->tas = opt->tas; + dev->has_own_order_mgmt = opt->has_own_order_mgmt; + if (dev->sdev != NULL) { + dev->sdev->tst = opt->tst; + dev->sdev->queue_alg = opt->queue_alg; + dev->sdev->swp = opt->swp; + dev->sdev->tas = opt->tas; + dev->sdev->has_own_order_mgmt = opt->has_own_order_mgmt; + } + dev_user_setup_functions(dev); out: @@ -2791,6 +2835,11 @@ opt.prio_queue_type = dev->prio_queue_type; opt.partial_transfers_type = dev->partial_transfers_type; opt.partial_len = dev->partial_len; + opt.tst = dev->tst; + opt.queue_alg = dev->queue_alg; + opt.tas = dev->tas; + opt.swp = dev->swp; + opt.has_own_order_mgmt = dev->has_own_order_mgmt; TRACE_DBG("parse_type %x, on_free_cmd_type %x, memory_reuse_type %x, " "partial_transfers_type %x, partial_len %d", opt.parse_type, Modified: trunk/scst/src/dev_handlers/scst_vdisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_vdisk.c 2007-11-26 16:47:16 UTC (rev 226) +++ trunk/scst/src/dev_handlers/scst_vdisk.c 2007-12-07 17:00:42 UTC (rev 227) @@ -88,6 +88,16 @@ #define VDISK_NAME "vdisk" #define VCDROM_NAME "vcdrom" +#define DEF_TST SCST_CONTR_MODE_SEP_TASK_SETS +/* + * Since we can't control backstorage device's reordering, we have to always + * report unrestricted reordering. + */ +#define DEF_QUEUE_ALG_WT SCST_CONTR_MODE_QUEUE_ALG_UNRESTRICTED_REORDER +#define DEF_QUEUE_ALG SCST_CONTR_MODE_QUEUE_ALG_UNRESTRICTED_REORDER +#define DEF_SWP 0 +#define DEF_TAS 0 + #define VDISK_PROC_HELP "help" static unsigned int random_values[256] = { @@ -188,7 +198,8 @@ struct scst_vdisk_tgt_dev { /* * Used without locking since SCST core ensures that only commands - * of the same type per tgt_dev can be processed simultaneously + * with the same ORDERED type per tgt_dev can be processed + * simultaneously. */ enum scst_cmd_queue_type last_write_cmd_queue_type; }; @@ -223,6 +234,7 @@ static void vdisk_exec_read_capacity(struct scst_cmd *cmd); static void vdisk_exec_read_capacity16(struct scst_cmd *cmd); static void vdisk_exec_inquiry(struct scst_cmd *cmd); +static void vdisk_exec_request_sense(struct scst_cmd *cmd); static void vdisk_exec_mode_sense(struct scst_cmd *cmd); static void vdisk_exec_mode_select(struct scst_cmd *cmd); static void vdisk_exec_log(struct scst_cmd *cmd); @@ -236,6 +248,8 @@ static int vcdrom_read_proc(struct seq_file *seq, struct scst_dev_type *dev_type); static int vcdrom_write_proc(char *buffer, char **start, off_t offset, int length, int *eof, struct scst_dev_type *dev_type); +static int vdisk_task_mgmt_fn(struct scst_mgmt_cmd *mcmd, + struct scst_tgt_dev *tgt_dev); #define VDISK_TYPE { \ name: VDISK_NAME, \ @@ -252,6 +266,7 @@ exec: vdisk_do_job, \ read_proc: vdisk_read_proc, \ write_proc: vdisk_write_proc, \ + task_mgmt_fn: vdisk_task_mgmt_fn, \ } #define VDISK_BLK_TYPE { \ @@ -262,13 +277,13 @@ exec_atomic: 0, \ dev_done_atomic: 1, \ no_proc: 1, \ - inc_expected_sn_on_done: 1, \ attach: vdisk_attach, \ detach: vdisk_detach, \ attach_tgt: vdisk_attach_tgt, \ detach_tgt: vdisk_detach_tgt, \ parse: vdisk_parse, \ exec: vdisk_do_job, \ + task_mgmt_fn: vdisk_task_mgmt_fn, \ } #define VCDROM_TYPE { \ @@ -286,6 +301,7 @@ exec: vcdrom_exec, \ read_proc: vcdrom_read_proc, \ write_proc: vcdrom_write_proc, \ + task_mgmt_fn: vdisk_task_mgmt_fn, \ } static DEFINE_MUTEX(scst_vdisk_mutex); @@ -469,6 +485,14 @@ dev->dh_priv = virt_dev; + dev->tst = DEF_TST; + if (virt_dev->wt_flag) + dev->queue_alg = DEF_QUEUE_ALG_WT; + else + dev->queue_alg = DEF_QUEUE_ALG; + dev->swp = DEF_SWP; + dev->tas = DEF_TAS; + out: TRACE_EXIT(); return res; @@ -823,7 +847,7 @@ /* ToDo: BLOCKIO VERIFY */ vdisk_exec_write(cmd, thr, loff); /* O_SYNC flag is used for WT devices */ - if (cmd->status == 0) + if (scsi_status_is_good(cmd->status)) vdisk_exec_verify(cmd, thr, loff); else if (do_fsync) vdisk_fsync(thr, loff, data_len, cmd); @@ -890,6 +914,9 @@ case INQUIRY: vdisk_exec_inquiry(cmd); break; + case REQUEST_SENSE: + vdisk_exec_request_sense(cmd); + break; case READ_CAPACITY: vdisk_exec_read_capacity(cmd); break; @@ -989,7 +1016,7 @@ TRACE_DBG("%s", "CDROM empty"); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_not_ready)); - goto out_complete; + goto out_done; } if (virt_dev->media_changed && (cmd->cdb[0] != INQUIRY) && @@ -1001,7 +1028,7 @@ scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_medium_changed_UA)); spin_unlock(&virt_dev->flags_lock); - goto out_complete; + goto out_done; } spin_unlock(&virt_dev->flags_lock); } @@ -1012,8 +1039,7 @@ TRACE_EXIT(); return SCST_EXEC_COMPLETED; -out_complete: - cmd->completed = 1; +out_done: cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT); goto out; } @@ -1193,6 +1219,36 @@ return; } +static void vdisk_exec_request_sense(struct scst_cmd *cmd) +{ + int32_t length; + uint8_t *address; + + TRACE_ENTRY(); + + length = scst_get_buf_first(cmd, &address); + TRACE_DBG("length %d", length); + if (unlikely(length < SCST_STANDARD_SENSE_LEN)) { + PRINT_ERROR("scst_get_buf_first() failed or too small " + "requested buffer (returned %d)", length); + scst_set_cmd_error(cmd, + SCST_LOAD_SENSE(scst_sense_invalid_field_in_parm_list)); + if (length > 0) + goto out_put; + else + goto out; + } + + scst_set_sense(address, length, SCST_LOAD_SENSE(scst_sense_no_sense)); + +out_put: + scst_put_buf(cmd, address); + +out: + TRACE_EXIT(); + return; +} + /* * <<Following mode pages info copied from ST318451LW with some corrections>> * @@ -1256,14 +1312,38 @@ static int vdisk_ctrl_m_pg(unsigned char *p, int pcontrol, struct scst_vdisk_dev *virt_dev) { /* Control mode page for mode_sense */ - const unsigned char ctrl_m_pg[] = {0xa, 0xa, 0x20, 0, 0, 0x40, 0, 0, + const unsigned char ctrl_m_pg[] = {0xa, 0xa, 0, 0, 0, 0, 0, 0, 0, 0, 0x2, 0x4b}; memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg)); - if (!virt_dev->wt_flag && !virt_dev->nv_cache) - p[3] |= 0x10; /* Enable unrestricted reordering */ - if (1 == pcontrol) + switch(pcontrol) { + case 0: + p[2] |= virt_dev->dev->tst << 5; + p[3] |= virt_dev->dev->queue_alg << 4; + p[4] |= virt_dev->dev->swp << 3; + p[5] |= virt_dev->dev->tas << 6; + break; + case 1: memset(p + 2, 0, sizeof(ctrl_m_pg) - 2); +#if 0 /* Too early, see corresponding comment in vdisk_exec_mode_select() */ + p[2] |= 7 << 5; + p[3] |= 0xF << 4; + p[4] |= 1 << 3; + p[5] |= 1 << 6; +#endif + break; + case 2: + p[2] |= DEF_TST << 5; + if (virt_dev->wt_flag) + p[3] |= DEF_QUEUE_ALG_WT << 4; + else + p[3] |= DEF_QUEUE_ALG << 4; + p[4] |= DEF_SWP << 3; + p[5] |= DEF_TAS << 6; + break; + default: + sBUG(); + } return sizeof(ctrl_m_pg); } @@ -1519,6 +1599,25 @@ goto out_put; } break; +#if 0 /* + * It's too early to implement it, since we can't control the backstorage + * device parameters. ToDo + */ + } else if ((address[offset] & 0x3f) == 0xA) { /* Control page */ + ... [truncated message content] |
From: <vl...@us...> - 2007-12-13 18:33:32
|
Revision: 234 http://scst.svn.sourceforge.net/scst/?rev=234&view=rev Author: vlnb Date: 2007-12-13 10:33:30 -0800 (Thu, 13 Dec 2007) Log Message: ----------- Perf/release patches fixes Modified Paths: -------------- trunk/scst-full_perf.patch trunk/scst-release.patch Modified: trunk/scst-full_perf.patch =================================================================== --- trunk/scst-full_perf.patch 2007-12-13 18:28:34 UTC (rev 233) +++ trunk/scst-full_perf.patch 2007-12-13 18:33:30 UTC (rev 234) @@ -1,6 +1,6 @@ Index: scst/src/Makefile =================================================================== ---- scst/src/Makefile (revision 210) +--- scst/src/Makefile (revision 233) +++ scst/src/Makefile (working copy) @@ -114,7 +114,7 @@ EXTRA_CFLAGS += -I$(SCST_INC_DIR) -Wextr @@ -11,7 +11,7 @@ #EXTRA_CFLAGS += -DUSE_EXPECTED_VALUES #EXTRA_CFLAGS += -DALLOW_PASSTHROUGH_IO_SUBMIT_IN_SIRQ -@@ -123,7 +123,7 @@ EXTRA_CFLAGS += -DEXTRACHECKS +@@ -124,7 +124,7 @@ EXTRA_CFLAGS += -DEXTRACHECKS #EXTRA_CFLAGS += -DTRACING @@ -22,7 +22,7 @@ #EXTRA_CFLAGS += -DDEBUG_OOM Index: scst/src/dev_handlers/Makefile =================================================================== ---- scst/src/dev_handlers/Makefile (revision 208) +--- scst/src/dev_handlers/Makefile (revision 230) +++ scst/src/dev_handlers/Makefile (working copy) @@ -68,10 +68,10 @@ endif Modified: trunk/scst-release.patch =================================================================== --- trunk/scst-release.patch 2007-12-13 18:28:34 UTC (rev 233) +++ trunk/scst-release.patch 2007-12-13 18:33:30 UTC (rev 234) @@ -1,8 +1,8 @@ Index: scst/src/Makefile =================================================================== ---- scst/src/Makefile (revision 210) +--- scst/src/Makefile (revision 233) +++ scst/src/Makefile (working copy) -@@ -114,16 +114,16 @@ EXTRA_CFLAGS += -I$(SCST_INC_DIR) -Wextr +@@ -114,7 +114,7 @@ EXTRA_CFLAGS += -I$(SCST_INC_DIR) -Wextr #EXTRA_CFLAGS += -DSTRICT_SERIALIZING @@ -11,6 +11,7 @@ #EXTRA_CFLAGS += -DUSE_EXPECTED_VALUES #EXTRA_CFLAGS += -DALLOW_PASSTHROUGH_IO_SUBMIT_IN_SIRQ +@@ -122,9 +122,9 @@ EXTRA_CFLAGS += -DEXTRACHECKS #EXTRA_CFLAGS += -fno-inline @@ -24,7 +25,7 @@ #EXTRA_CFLAGS += -DDEBUG_OOM Index: scst/src/dev_handlers/Makefile =================================================================== ---- scst/src/dev_handlers/Makefile (revision 208) +--- scst/src/dev_handlers/Makefile (revision 230) +++ scst/src/dev_handlers/Makefile (working copy) @@ -68,10 +68,10 @@ endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2007-12-24 10:20:26
|
Revision: 238 http://scst.svn.sourceforge.net/scst/?rev=238&view=rev Author: vlnb Date: 2007-12-24 02:20:18 -0800 (Mon, 24 Dec 2007) Log Message: ----------- Patches from Arne Redlich <ag...@po...>: 1. The kernel's log level is a string, so strcmp needs to be used for comparisons. 2. Svn HEAD doesn't compile against kernel versions < 2.6.19 because "bool" had its debut only in 2.6.19. Here's a quick fix. 3. Iscsi-scstd dies with SIGPIPE if run in foreground mode because the reading end of the init_report_pipe is already closed in this mode. Modified Paths: -------------- trunk/iscsi-scst/usr/iscsi_scstd.c trunk/scst/include/scsi_tgt.h trunk/scst/include/scst_debug.h Modified: trunk/iscsi-scst/usr/iscsi_scstd.c =================================================================== --- trunk/iscsi-scst/usr/iscsi_scstd.c 2007-12-21 19:10:40 UTC (rev 237) +++ trunk/iscsi-scst/usr/iscsi_scstd.c 2007-12-24 10:20:18 UTC (rev 238) @@ -454,7 +454,10 @@ close(init_report_pipe[0]); res = 0; - write(init_report_pipe[1], &res, sizeof(res)); + + if (log_daemon) + write(init_report_pipe[1], &res, sizeof(res)); + close(init_report_pipe[1]); while (1) { Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2007-12-21 19:10:40 UTC (rev 237) +++ trunk/scst/include/scsi_tgt.h 2007-12-24 10:20:18 UTC (rev 238) @@ -36,6 +36,10 @@ #include <scst_const.h> +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) +typedef _Bool bool; +#endif + /* Version numbers, the same as for the kernel */ #define SCST_VERSION_CODE 0x000906 #define SCST_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) Modified: trunk/scst/include/scst_debug.h =================================================================== --- trunk/scst/include/scst_debug.h 2007-12-21 19:10:40 UTC (rev 237) +++ trunk/scst/include/scst_debug.h 2007-12-24 10:20:18 UTC (rev 238) @@ -282,7 +282,7 @@ #define PRINT_ERROR(format, args...) \ do { \ - if (ERROR_FLAG != LOG_FLAG) \ + if (strcmp(ERROR_FLAG, LOG_FLAG)) \ { \ PRINT_LOG_FLAG(LOG_FLAG, "***ERROR*** " format, args); \ } \ @@ -291,7 +291,7 @@ #define PRINT_INFO(format, args...) \ do { \ - if (INFO_FLAG != LOG_FLAG) \ + if (strcmp(INFO_FLAG, LOG_FLAG)) \ { \ PRINT_LOG_FLAG(LOG_FLAG, format, args); \ } \ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2007-12-24 19:22:09
|
Revision: 239 http://scst.svn.sourceforge.net/scst/?rev=239&view=rev Author: vlnb Date: 2007-12-24 11:22:02 -0800 (Mon, 24 Dec 2007) Log Message: ----------- - Broken VERIFY commands fixed (hopefully; compile tested only) - Mistyped spin_lock() instead spin_lock_bh() fixed - DEBUG_TM and small logging improvements - Docs update Modified Paths: -------------- trunk/iscsi-scst/README trunk/scst/README trunk/scst/src/scst_cdbprobe.h trunk/scst/src/scst_lib.c trunk/scst/src/scst_priv.h trunk/scst/src/scst_targ.c Modified: trunk/iscsi-scst/README =================================================================== --- trunk/iscsi-scst/README 2007-12-24 10:20:18 UTC (rev 238) +++ trunk/iscsi-scst/README 2007-12-24 19:22:02 UTC (rev 239) @@ -111,6 +111,10 @@ In this case value like 16 or even 10 depending of your backstorage speed could be more appropriate. +CAUTION: Working of target and initiator on the same host isn't +======== supported. See SCST README file for details. + + Compilation options ------------------- Modified: trunk/scst/README =================================================================== --- trunk/scst/README 2007-12-24 10:20:18 UTC (rev 238) +++ trunk/scst/README 2007-12-24 19:22:02 UTC (rev 239) @@ -95,6 +95,14 @@ 'echo "scsi add-single-device A 0 0 B" >/proc/scsi/scsi', where A - is the host number, B - LUN. +IMPORTANT: Working of target and initiator on the same host isn't +========= supported. This is a limitation of the Linux memory/cache + manager, because in this case an OOM deadlock like: system + needs some memory -> it decides to clear some cache -> cache + needs to write on a target exported device -> initiator sends + request to the target -> target needs memory -> problem is + possible. + IMPORTANT: Experience shows that if people work with out of SCST tree target ========= drivers, like target driver for Infiniband or in case if they downloaded and use the released versions of SCST and target Modified: trunk/scst/src/scst_cdbprobe.h =================================================================== --- trunk/scst/src/scst_cdbprobe.h 2007-12-24 10:20:18 UTC (rev 238) +++ trunk/scst/src/scst_cdbprobe.h 2007-12-24 19:22:02 UTC (rev 239) @@ -172,7 +172,7 @@ {0x12, "MMMMMMMMMMMMMMMM", "INQUIRY", SCST_DATA_READ, SCST_SMALL_TIMEOUT, 4, get_trans_len_1}, {0x13, "VOVVVV ", "VERIFY(6)", - SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 2, get_trans_len_3}, + SCST_DATA_NONE, SCST_TRANSFER_LEN_TYPE_FIXED, 2, get_trans_len_3}, {0x14, "VOOVVV ", "RECOVER BUFFERED DATA", SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED, 2, get_trans_len_3}, {0x15, "OMOOOOOOOOOOOOOO", "MODE SELECT(6)", @@ -248,7 +248,7 @@ {0x2E, "O OO O ", "WRITE AND VERIFY(10)", SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 7, get_trans_len_2}, {0x2F, "O OO O ", "VERIFY(10)", - SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 7, get_trans_len_2}, + SCST_DATA_NONE, SCST_TRANSFER_LEN_TYPE_FIXED, 7, get_trans_len_2}, {0x33, "O OO O ", "SET LIMITS(10)", SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none}, {0x34, " O ", "READ POSITION", @@ -376,7 +376,7 @@ {0x8E, "O OO O ", "WRITE AND VERIFY(16)", SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 10, get_trans_len_4}, {0x8F, "O OO O ", "VERIFY(16)", - SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 10, get_trans_len_4}, + SCST_DATA_NONE, SCST_TRANSFER_LEN_TYPE_FIXED, 10, get_trans_len_4}, {0x90, "O OO O ", "PRE-FETCH(16)", SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none}, {0x91, "O OO O ", "SYNCHRONIZE CACHE(16)", @@ -440,7 +440,7 @@ {0xAE, "O OO O ", "WRITE AND VERIFY(12)", SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 6, get_trans_len_4}, {0xAF, "O OO O ", "VERIFY(12)", - SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 6, get_trans_len_4}, + SCST_DATA_NONE, SCST_TRANSFER_LEN_TYPE_FIXED, 6, get_trans_len_4}, /* No need to support at all. {0xB0, " OO O ", "SEARCH DATA HIGH(12)", SCST_DATA_WRITE, FLAG_NONE, 9, get_trans_len_1}, Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2007-12-24 10:20:18 UTC (rev 238) +++ trunk/scst/src/scst_lib.c 2007-12-24 19:22:02 UTC (rev 239) @@ -1893,8 +1893,7 @@ if ((cmd->cdb[1] & BYTCHK) == 0) { cmd->data_len = cmd->bufflen << get_block_shift(cmd); cmd->bufflen = 0; - cmd->data_direction = SCST_DATA_NONE; - cmd->op_flags &= ~SCST_TRANSFER_LEN_TYPE_FIXED; + goto out; } else cmd->data_len = 0; break; @@ -1911,6 +1910,7 @@ cmd->bufflen = cmd->bufflen << get_block_shift(cmd); } +out: TRACE_DBG("res %d, bufflen %d, data_len %d, direct %d", res, cmd->bufflen, cmd->data_len, cmd->data_direction); @@ -1943,8 +1943,7 @@ if ((cmd->cdb[1] & BYTCHK) == 0) { cmd->data_len = cmd->bufflen << get_block_shift(cmd); cmd->bufflen = 0; - cmd->data_direction = SCST_DATA_NONE; - cmd->op_flags &= ~SCST_TRANSFER_LEN_TYPE_FIXED; + goto out; } break; default: @@ -1955,8 +1954,9 @@ if (cmd->op_flags & SCST_TRANSFER_LEN_TYPE_FIXED) cmd->bufflen = cmd->bufflen << get_block_shift(cmd); - TRACE_DBG("res %d bufflen %d direct %d", - res, cmd->bufflen, cmd->data_direction); +out: + TRACE_DBG("res=%d, bufflen=%d, direct=%d", res, cmd->bufflen, + cmd->data_direction); TRACE_EXIT(); return res; @@ -1987,8 +1987,7 @@ if ((cmd->cdb[1] & BYTCHK) == 0) { cmd->data_len = cmd->bufflen << get_block_shift(cmd); cmd->bufflen = 0; - cmd->data_direction = SCST_DATA_NONE; - cmd->op_flags &= ~SCST_TRANSFER_LEN_TYPE_FIXED; + goto out; } break; default: @@ -1999,8 +1998,9 @@ if (cmd->op_flags & SCST_TRANSFER_LEN_TYPE_FIXED) cmd->bufflen = cmd->bufflen << get_block_shift(cmd); - TRACE_DBG("res %d bufflen %d direct %d", - res, cmd->bufflen, cmd->data_direction); +out: + TRACE_DBG("res=%d, bufflen=%d, direct=%d", res, cmd->bufflen, + cmd->data_direction); TRACE_EXIT_RES(res); return res; @@ -2488,7 +2488,7 @@ TRACE_ENTRY(); - spin_lock(&tgt_dev->tgt_dev_lock); + spin_lock_bh(&tgt_dev->tgt_dev_lock); list_for_each_entry(UA_entry_tmp, &tgt_dev->UA_list, UA_list_entry) { @@ -2502,7 +2502,7 @@ if (skip_UA == 0) scst_alloc_set_UA(tgt_dev, sense, sense_len, head); - spin_unlock(&tgt_dev->tgt_dev_lock); + spin_unlock_bh(&tgt_dev->tgt_dev_lock); TRACE_EXIT(); return; @@ -3321,18 +3321,33 @@ spin_unlock_irqrestore(&scst_tm_dbg_lock, flags); } -/* No locks */ -void tm_dbg_task_mgmt(struct scst_tgt_dev *tgt_dev, const char *fn, int force) +/* Might be called under scst_mutex */ +void tm_dbg_task_mgmt(struct scst_device *dev, const char *fn, int force) { unsigned long flags; if (!tm_dbg_flags.tm_dbg_active) goto out; - if ((tgt_dev != NULL) && !test_bit(SCST_TGT_DEV_UNDER_TM_DBG, - &tgt_dev->tgt_dev_flags)) - goto out; + if (dev != NULL) { + struct scst_tgt_dev *tgt_dev; + bool found = 0; + spin_lock_bh(&dev->dev_lock); + list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list, + dev_tgt_dev_list_entry) { + if (test_bit(SCST_TGT_DEV_UNDER_TM_DBG, + &tgt_dev->tgt_dev_flags)) { + found = 1; + break; + } + } + spin_unlock_bh(&dev->dev_lock); + + if (!found) + goto out; + } + spin_lock_irqsave(&scst_tm_dbg_lock, flags); if ((tm_dbg_state != TM_DBG_STATE_OFFLINE) || force) { TRACE_MGMT_DBG("%s: freeing %d delayed cmds", fn, Modified: trunk/scst/src/scst_priv.h =================================================================== --- trunk/scst/src/scst_priv.h 2007-12-24 10:20:18 UTC (rev 238) +++ trunk/scst/src/scst_priv.h 2007-12-24 19:22:02 UTC (rev 239) @@ -512,7 +512,7 @@ extern void tm_dbg_check_released_cmds(void); extern int tm_dbg_check_cmd(struct scst_cmd *cmd); extern void tm_dbg_release_cmd(struct scst_cmd *cmd); -extern void tm_dbg_task_mgmt(struct scst_tgt_dev *tgt_dev, const char *fn, +extern void tm_dbg_task_mgmt(struct scst_device *dev, const char *fn, int force); extern int tm_dbg_is_release(void); #else @@ -525,7 +525,7 @@ return 0; } static inline void tm_dbg_release_cmd(struct scst_cmd *cmd) {} -static inline void tm_dbg_task_mgmt(struct scst_tgt_dev *tgt_dev, const char *fn, +static inline void tm_dbg_task_mgmt(struct scst_device *dev, const char *fn, int force) {} static inline int tm_dbg_is_release(void) { Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2007-12-24 10:20:18 UTC (rev 238) +++ trunk/scst/src/scst_targ.c 2007-12-24 19:22:02 UTC (rev 239) @@ -3729,6 +3729,8 @@ } if (!found) list_add_tail(&dev->tm_dev_list_entry, &host_devs); + + tm_dbg_task_mgmt(dev, "TARGET RESET", 0); } /* @@ -3761,7 +3763,6 @@ mutex_unlock(&scst_mutex); - tm_dbg_task_mgmt(mcmd->mcmd_tgt_dev, "TARGET RESET", 0); res = scst_set_mcmd_next_state(mcmd); TRACE_EXIT_RES(res); @@ -3802,7 +3803,8 @@ } out_tm_dbg: - tm_dbg_task_mgmt(mcmd->mcmd_tgt_dev, "LUN RESET", 0); + tm_dbg_task_mgmt(mcmd->mcmd_tgt_dev->dev, "LUN RESET", 0); + res = scst_set_mcmd_next_state(mcmd); TRACE_EXIT_RES(res); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2008-01-24 11:52:08
|
Revision: 249 http://scst.svn.sourceforge.net/scst/?rev=249&view=rev Author: vlnb Date: 2008-01-24 03:52:01 -0800 (Thu, 24 Jan 2008) Log Message: ----------- - Version protection added - Cleanups Modified Paths: -------------- trunk/iscsi-scst/kernel/iscsi.c trunk/mpt/mpt_scst.c trunk/qla2x00t/qla2x00-target/qla2x00t.c trunk/scst/include/scsi_tgt.h trunk/scst/include/scst_const.h trunk/scst/include/scst_user.h trunk/scst/src/dev_handlers/scst_cdrom.c trunk/scst/src/dev_handlers/scst_changer.c trunk/scst/src/dev_handlers/scst_disk.c trunk/scst/src/dev_handlers/scst_modisk.c trunk/scst/src/dev_handlers/scst_processor.c trunk/scst/src/dev_handlers/scst_raid.c trunk/scst/src/dev_handlers/scst_tape.c trunk/scst/src/dev_handlers/scst_user.c trunk/scst/src/scst_main.c trunk/usr/fileio/fileio.c Property Changed: ---------------- trunk/scst/include/scsi_tgt.h trunk/scst/include/scst_const.h trunk/scst/include/scst_user.h Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2008-01-24 10:56:35 UTC (rev 248) +++ trunk/iscsi-scst/kernel/iscsi.c 2008-01-24 11:52:01 UTC (rev 249) @@ -2768,10 +2768,10 @@ goto out_event; } - if (scst_register_target_template(&iscsi_template) < 0) { - err = -ENODEV; + err = scst_register_target_template(&iscsi_template); + if (err < 0) goto out_kmem; - } + iscsi_template_registered = 1; if ((err = iscsi_procfs_init()) < 0) Modified: trunk/mpt/mpt_scst.c =================================================================== --- trunk/mpt/mpt_scst.c 2008-01-24 10:56:35 UTC (rev 248) +++ trunk/mpt/mpt_scst.c 2008-01-24 11:52:01 UTC (rev 249) @@ -5523,11 +5523,10 @@ int res = 0; TRACE_ENTRY(); - - if (scst_register_target_template(&tgt_template) < 0) { - res = -ENODEV; + + res = scst_register_target_template(&tgt_template); + if (res < 0) goto out; - } res = mpt_proc_log_entry_build(&tgt_template); if (res < 0) { Modified: trunk/qla2x00t/qla2x00-target/qla2x00t.c =================================================================== --- trunk/qla2x00t/qla2x00-target/qla2x00t.c 2008-01-24 10:56:35 UTC (rev 248) +++ trunk/qla2x00t/qla2x00-target/qla2x00t.c 2008-01-24 11:52:01 UTC (rev 249) @@ -2211,11 +2211,10 @@ res = -ENOMEM; goto out; } - - if (scst_register_target_template(&tgt_template) < 0) { - res = -ENODEV; + + res = scst_register_target_template(&tgt_template); + if (res < 0) goto out; - } /* qla2xxx_tgt_register_driver() happens in q2t_target_detect * called via scst_register_target_template() Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2008-01-24 10:56:35 UTC (rev 248) +++ trunk/scst/include/scsi_tgt.h 2008-01-24 11:52:01 UTC (rev 249) @@ -41,9 +41,10 @@ #endif /* Version numbers, the same as for the kernel */ -#define SCST_VERSION_CODE 0x000906 -#define SCST_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#define SCST_VERSION_CODE 0x00090601 +#define SCST_VERSION(a,b,c,d) (((a) << 24) + ((b) << 16) + ((c) << 8) + d) #define SCST_VERSION_STRING "0.9.6-rc1" +#define SCST_INTERFACE_VERSION SCST_VERSION_STRING "$Revision$" SCST_CONST_VERSION /************************************************************* ** States of command processing state machine. At first, @@ -1539,7 +1540,12 @@ * Registers target template * Returns 0 on success or appropriate error code otherwise */ -int scst_register_target_template(struct scst_tgt_template *vtt); +int __scst_register_target_template(struct scst_tgt_template *vtt, + const char *version); +static inline int scst_register_target_template(struct scst_tgt_template *vtt) +{ + return __scst_register_target_template(vtt, SCST_INTERFACE_VERSION); +} /* * Unregisters target template @@ -1646,7 +1652,12 @@ * Registers dev handler driver * Returns 0 on success or appropriate error code otherwise */ -int scst_register_dev_driver(struct scst_dev_type *dev_type); +int __scst_register_dev_driver(struct scst_dev_type *dev_type, + const char *version); +static inline int scst_register_dev_driver(struct scst_dev_type *dev_type) +{ + return __scst_register_dev_driver(dev_type, SCST_INTERFACE_VERSION); +} /* * Unregisters dev handler driver @@ -1657,7 +1668,14 @@ * Registers dev handler driver for virtual devices (eg VDISK) * Returns 0 on success or appropriate error code otherwise */ -int scst_register_virtual_dev_driver(struct scst_dev_type *dev_type); +int __scst_register_virtual_dev_driver(struct scst_dev_type *dev_type, + const char *version); +static inline int scst_register_virtual_dev_driver( + struct scst_dev_type *dev_type) +{ + return __scst_register_virtual_dev_driver(dev_type, + SCST_INTERFACE_VERSION); +} /* * Unregisters dev handler driver for virtual devices Property changes on: trunk/scst/include/scsi_tgt.h ___________________________________________________________________ Name: svn:keywords + Revision Modified: trunk/scst/include/scst_const.h =================================================================== --- trunk/scst/include/scst_const.h 2008-01-24 10:56:35 UTC (rev 248) +++ trunk/scst/include/scst_const.h 2008-01-24 11:52:01 UTC (rev 249) @@ -21,6 +21,8 @@ #include <scsi/scsi.h> +#define SCST_CONST_VERSION "$Revision$" + /*** Shared constants between user and kernel spaces ***/ /* Max size of CDB */ Property changes on: trunk/scst/include/scst_const.h ___________________________________________________________________ Name: svn:keywords + Revision Modified: trunk/scst/include/scst_user.h =================================================================== --- trunk/scst/include/scst_user.h 2008-01-24 10:56:35 UTC (rev 248) +++ trunk/scst/include/scst_user.h 2008-01-24 11:52:01 UTC (rev 249) @@ -25,7 +25,8 @@ #define DEV_USER_NAME "scst_user" #define DEV_USER_PATH "/dev/" -#define DEV_USER_VERSION 963 +#define DEV_USER_VERSION_NAME "0.9.6" +#define DEV_USER_VERSION DEV_USER_VERSION_NAME "$Revision$" SCST_CONST_VERSION /* * Chosen so sizeof(scst_user_sess) <= sizeof(scst_user_scsi_cmd_exec) @@ -105,7 +106,7 @@ struct scst_user_dev_desc { - uint32_t version; + aligned_u64 version_str; uint8_t type; struct scst_user_opt opt; uint32_t block_size; Property changes on: trunk/scst/include/scst_user.h ___________________________________________________________________ Name: svn:keywords + Revision Modified: trunk/scst/src/dev_handlers/scst_cdrom.c =================================================================== --- trunk/scst/src/dev_handlers/scst_cdrom.c 2008-01-24 10:56:35 UTC (rev 248) +++ trunk/scst/src/dev_handlers/scst_cdrom.c 2008-01-24 11:52:01 UTC (rev 249) @@ -276,10 +276,10 @@ TRACE_ENTRY(); cdrom_devtype.module = THIS_MODULE; - if (scst_register_dev_driver(&cdrom_devtype) < 0) { - res = -ENODEV; + + res = scst_register_dev_driver(&cdrom_devtype); + if (res < 0) goto out; - } res = scst_dev_handler_build_std_proc(&cdrom_devtype); if (res != 0) Modified: trunk/scst/src/dev_handlers/scst_changer.c =================================================================== --- trunk/scst/src/dev_handlers/scst_changer.c 2008-01-24 10:56:35 UTC (rev 248) +++ trunk/scst/src/dev_handlers/scst_changer.c 2008-01-24 11:52:01 UTC (rev 249) @@ -196,10 +196,10 @@ TRACE_ENTRY(); changer_devtype.module = THIS_MODULE; - if (scst_register_dev_driver(&changer_devtype) < 0) { - res = -ENODEV; + + res = scst_register_dev_driver(&changer_devtype); + if (res < 0) goto out; - } res = scst_dev_handler_build_std_proc(&changer_devtype); if (res != 0) Modified: trunk/scst/src/dev_handlers/scst_disk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_disk.c 2008-01-24 10:56:35 UTC (rev 248) +++ trunk/scst/src/dev_handlers/scst_disk.c 2008-01-24 11:52:01 UTC (rev 249) @@ -84,20 +84,20 @@ TRACE_ENTRY(); disk_devtype.module = THIS_MODULE; - if (scst_register_dev_driver(&disk_devtype) < 0) { - res = -ENODEV; + + res = scst_register_dev_driver(&disk_devtype); + if (res < 0) goto out; - } res = scst_dev_handler_build_std_proc(&disk_devtype); if (res != 0) goto out_unreg1; disk_devtype_perf.module = THIS_MODULE; - if (scst_register_dev_driver(&disk_devtype_perf) < 0) { - res = -ENODEV; + + res = scst_register_dev_driver(&disk_devtype_perf); + if (res < 0) goto out_unreg1_err1; - } res = scst_dev_handler_build_std_proc(&disk_devtype_perf); if (res != 0) Modified: trunk/scst/src/dev_handlers/scst_modisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_modisk.c 2008-01-24 10:56:35 UTC (rev 248) +++ trunk/scst/src/dev_handlers/scst_modisk.c 2008-01-24 11:52:01 UTC (rev 249) @@ -84,20 +84,20 @@ TRACE_ENTRY(); modisk_devtype.module = THIS_MODULE; - if (scst_register_dev_driver(&modisk_devtype) < 0) { - res = -ENODEV; + + res = scst_register_dev_driver(&modisk_devtype); + if (res < 0) goto out; - } res = scst_dev_handler_build_std_proc(&modisk_devtype); if (res != 0) goto out_unreg1; modisk_devtype_perf.module = THIS_MODULE; - if (scst_register_dev_driver(&modisk_devtype_perf) < 0) { - res = -ENODEV; + + res = scst_register_dev_driver(&modisk_devtype_perf); + if (res < 0) goto out_unreg1_err1; - } res = scst_dev_handler_build_std_proc(&modisk_devtype_perf); if (res != 0) Modified: trunk/scst/src/dev_handlers/scst_processor.c =================================================================== --- trunk/scst/src/dev_handlers/scst_processor.c 2008-01-24 10:56:35 UTC (rev 248) +++ trunk/scst/src/dev_handlers/scst_processor.c 2008-01-24 11:52:01 UTC (rev 249) @@ -195,10 +195,10 @@ TRACE_ENTRY(); processor_devtype.module = THIS_MODULE; - if (scst_register_dev_driver(&processor_devtype) < 0) { - res = -ENODEV; + + res = scst_register_dev_driver(&processor_devtype); + if (res < 0) goto out; - } res = scst_dev_handler_build_std_proc(&processor_devtype); if (res != 0) Modified: trunk/scst/src/dev_handlers/scst_raid.c =================================================================== --- trunk/scst/src/dev_handlers/scst_raid.c 2008-01-24 10:56:35 UTC (rev 248) +++ trunk/scst/src/dev_handlers/scst_raid.c 2008-01-24 11:52:01 UTC (rev 249) @@ -195,10 +195,10 @@ TRACE_ENTRY(); raid_devtype.module = THIS_MODULE; - if (scst_register_dev_driver(&raid_devtype) < 0) { - res = -ENODEV; + + res = scst_register_dev_driver(&raid_devtype); + if (res < 0) goto out; - } res = scst_dev_handler_build_std_proc(&raid_devtype); if (res != 0) Modified: trunk/scst/src/dev_handlers/scst_tape.c =================================================================== --- trunk/scst/src/dev_handlers/scst_tape.c 2008-01-24 10:56:35 UTC (rev 248) +++ trunk/scst/src/dev_handlers/scst_tape.c 2008-01-24 11:52:01 UTC (rev 249) @@ -89,20 +89,20 @@ TRACE_ENTRY(); tape_devtype.module = THIS_MODULE; - if (scst_register_dev_driver(&tape_devtype) < 0) { - res = -ENODEV; + + res = scst_register_dev_driver(&tape_devtype); + if (res < 0) goto out; - } res = scst_dev_handler_build_std_proc(&tape_devtype); if (res != 0) goto out_unreg1; tape_devtype_perf.module = THIS_MODULE; - if (scst_register_dev_driver(&tape_devtype_perf) < 0) { - res = -ENODEV; + + res = scst_register_dev_driver(&tape_devtype_perf); + if (res < 0) goto out_unreg1_err1; - } res = scst_dev_handler_build_std_proc(&tape_devtype_perf); if (res != 0) Modified: trunk/scst/src/dev_handlers/scst_user.c =================================================================== --- trunk/scst/src/dev_handlers/scst_user.c 2008-01-24 10:56:35 UTC (rev 248) +++ trunk/scst/src/dev_handlers/scst_user.c 2008-01-24 11:52:01 UTC (rev 249) @@ -1755,6 +1755,7 @@ goto out; } TRACE_BUFFER("dev_desc", dev_desc, sizeof(*dev_desc)); + dev_desc->name[sizeof(dev_desc->name)-1] = '\0'; res = dev_user_register_dev(file, dev_desc); kfree(dev_desc); break; @@ -2551,6 +2552,31 @@ return; } +static int dev_user_check_version(const struct scst_user_dev_desc *dev_desc) +{ + char ver[sizeof(DEV_USER_VERSION)+1]; + int res; + + res = copy_from_user(ver, (void*)(unsigned long)dev_desc->version_str, + sizeof(ver)); + if (res < 0) { + PRINT_ERROR("%s", "Unable to get version string"); + goto out; + } + ver[sizeof(ver)-1] = '\0'; + + if (strcmp(ver, DEV_USER_VERSION) != 0) { + /* ->name already 0-terminated in dev_user_ioctl() */ + PRINT_ERROR("Incorrect version of user device %s (%s)", + dev_desc->name, ver); + res = -EINVAL; + goto out; + } + +out: + return res; +} + static int dev_user_register_dev(struct file *file, const struct scst_user_dev_desc *dev_desc) { @@ -2560,12 +2586,9 @@ TRACE_ENTRY(); - if (dev_desc->version != DEV_USER_VERSION) { - PRINT_ERROR("Version mismatch (requested %d, required %d)", - dev_desc->version, DEV_USER_VERSION); - res = -EINVAL; + res = dev_user_check_version(dev_desc); + if (res != 0) goto out; - } switch(dev_desc->type) { case TYPE_DISK: @@ -3062,10 +3085,10 @@ } dev_user_devtype.module = THIS_MODULE; - if (scst_register_virtual_dev_driver(&dev_user_devtype) < 0) { - res = -ENODEV; + + res = scst_register_virtual_dev_driver(&dev_user_devtype); + if (res < 0) goto out_cache; - } res = scst_dev_handler_build_std_proc(&dev_user_devtype); if (res != 0) Modified: trunk/scst/src/scst_main.c =================================================================== --- trunk/scst/src/scst_main.c 2008-01-24 10:56:35 UTC (rev 248) +++ trunk/scst/src/scst_main.c 2008-01-24 11:52:01 UTC (rev 249) @@ -142,7 +142,8 @@ name: "none", }; -int scst_register_target_template(struct scst_tgt_template *vtt) +int __scst_register_target_template(struct scst_tgt_template *vtt, + const char *version) { int res = 0; struct scst_tgt_template *t; @@ -152,6 +153,12 @@ INIT_LIST_HEAD(&vtt->tgt_list); + if (strcmp(version, SCST_INTERFACE_VERSION) != 0) { + PRINT_ERROR("Incorrect version of target %s", vtt->name); + res = -EINVAL; + goto out_err; + } + if (!vtt->detect) { PRINT_ERROR("Target driver %s doesn't have a " "detect() method.", vtt->name); @@ -742,7 +749,8 @@ return; } -int scst_register_dev_driver(struct scst_dev_type *dev_type) +int __scst_register_dev_driver(struct scst_dev_type *dev_type, + const char *version) { struct scst_dev_type *dt; struct scst_device *dev; @@ -751,6 +759,13 @@ TRACE_ENTRY(); + if (strcmp(version, SCST_INTERFACE_VERSION) != 0) { + PRINT_ERROR("Incorrect version of dev handler %s", + dev_type->name); + res = -EINVAL; + goto out_error; + } + res = scst_dev_handler_check(dev_type); if (res != 0) goto out_error; @@ -872,12 +887,20 @@ goto out; } -int scst_register_virtual_dev_driver(struct scst_dev_type *dev_type) +int __scst_register_virtual_dev_driver(struct scst_dev_type *dev_type, + const char *version) { int res; TRACE_ENTRY(); + if (strcmp(version, SCST_INTERFACE_VERSION) != 0) { + PRINT_ERROR("Incorrect version of virtual dev handler %s", + dev_type->name); + res = -EINVAL; + goto out_err; + } + res = scst_dev_handler_check(dev_type); if (res != 0) goto out_err; @@ -1658,14 +1681,14 @@ /* * Device Handler Side (i.e. scst_vdisk) */ -EXPORT_SYMBOL(scst_register_dev_driver); +EXPORT_SYMBOL(__scst_register_dev_driver); EXPORT_SYMBOL(scst_unregister_dev_driver); EXPORT_SYMBOL(scst_register); EXPORT_SYMBOL(scst_unregister); EXPORT_SYMBOL(scst_register_virtual_device); EXPORT_SYMBOL(scst_unregister_virtual_device); -EXPORT_SYMBOL(scst_register_virtual_dev_driver); +EXPORT_SYMBOL(__scst_register_virtual_dev_driver); EXPORT_SYMBOL(scst_unregister_virtual_dev_driver); EXPORT_SYMBOL(scst_set_busy); @@ -1683,7 +1706,7 @@ EXPORT_SYMBOL(scst_register_session); EXPORT_SYMBOL(scst_unregister_session); -EXPORT_SYMBOL(scst_register_target_template); +EXPORT_SYMBOL(__scst_register_target_template); EXPORT_SYMBOL(scst_unregister_target_template); EXPORT_SYMBOL(scst_cmd_init_done); Modified: trunk/usr/fileio/fileio.c =================================================================== --- trunk/usr/fileio/fileio.c 2008-01-24 10:56:35 UTC (rev 248) +++ trunk/usr/fileio/fileio.c 2008-01-24 11:52:01 UTC (rev 249) @@ -374,7 +374,7 @@ } memset(&desc, 0, sizeof(desc)); - desc.version = DEV_USER_VERSION; + desc.version_str = (unsigned long)DEV_USER_VERSION; strncpy(desc.name, dev.name, sizeof(desc.name)-1); desc.name[sizeof(desc.name)-1] = '\0'; desc.type = dev.type; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2008-01-31 18:28:48
|
Revision: 251 http://scst.svn.sourceforge.net/scst/?rev=251&view=rev Author: vlnb Date: 2008-01-31 10:28:43 -0800 (Thu, 31 Jan 2008) Log Message: ----------- - Update to work on 2.6.24 - Minor cleanups Modified Paths: -------------- trunk/iscsi-scst/kernel/digest.c trunk/iscsi-scst/kernel/event.c trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/kernel/nthread.c trunk/qla2x00t/qla2x00-target/qla2x00t.c trunk/qla2x00t/qla2x00-target/qla2x00t.h trunk/qla2x00t/qla_attr.c trunk/scst/include/scsi_tgt.h trunk/scst/src/dev_handlers/scst_user.c trunk/scst/src/dev_handlers/scst_vdisk.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_main.c trunk/scst/src/scst_mem.c trunk/scst/src/scst_mem.h trunk/scst/src/scst_targ.c Modified: trunk/iscsi-scst/kernel/digest.c =================================================================== --- trunk/iscsi-scst/kernel/digest.c 2008-01-24 12:21:45 UTC (rev 250) +++ trunk/iscsi-scst/kernel/digest.c 2008-01-31 18:28:43 UTC (rev 251) @@ -56,13 +56,6 @@ return 0; } -/* Copied from linux-iscsi initiator and slightly adjusted */ -#define SETSG(sg, p, l) do { \ - (sg).page = virt_to_page((p)); \ - (sg).offset = ((unsigned long)(p) & ~PAGE_MASK); \ - (sg).length = (l); \ -} while (0) - static u32 evaluate_crc32_from_sg(struct scatterlist *sg, int total, int pad_bytes) { @@ -80,7 +73,7 @@ int d = min(min(total, (int)(sg->length)), (int)(PAGE_SIZE - sg->offset)); - crc = crc32c(crc, page_address(sg->page) + sg->offset, d); + crc = crc32c(crc, sg_virt(sg), d); total -= d; sg++; } @@ -103,9 +96,11 @@ struct scatterlist sg[2]; unsigned int nbytes = sizeof(struct iscsi_hdr); - SETSG(sg[0], &pdu->bhs, nbytes); + sg_init_table(sg, 2); + + sg_set_buf(&sg[0], &pdu->bhs, nbytes); if (pdu->ahssize) { - SETSG(sg[1], pdu->ahs, pdu->ahssize); + sg_set_buf(&sg[1], pdu->ahs, pdu->ahssize); nbytes += pdu->ahssize; } return evaluate_crc32_from_sg(sg, nbytes, 0); Modified: trunk/iscsi-scst/kernel/event.c =================================================================== --- trunk/iscsi-scst/kernel/event.c 2008-01-24 12:21:45 UTC (rev 250) +++ trunk/iscsi-scst/kernel/event.c 2008-01-31 18:28:43 UTC (rev 251) @@ -39,7 +39,11 @@ return 0; } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) static int event_recv_skb(struct sk_buff *skb) +#else +static void event_recv_skb(struct sk_buff *skb) +#endif { int err; struct nlmsghdr *nlh; @@ -48,7 +52,7 @@ while (skb->len >= NLMSG_SPACE(0)) { nlh = (struct nlmsghdr *)skb->data; if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) - return 0; + goto out; rlen = NLMSG_ALIGN(nlh->nlmsg_len); if (rlen > skb->len) rlen = skb->len; @@ -58,9 +62,16 @@ netlink_ack(skb, nlh, 0); skb_pull(skb, rlen); } + +out: +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) return 0; +#else + return; +#endif } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) static void event_recv(struct sock *sk, int length) { struct sk_buff *skb; @@ -72,6 +83,7 @@ kfree_skb(skb); } } +#endif static int notify(void *data, int len, int gfp_mask) { @@ -107,10 +119,16 @@ int __init event_init(void) { #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) - nl = netlink_kernel_create(NETLINK_ISCSI_SCST, 1, event_recv, THIS_MODULE); + nl = netlink_kernel_create(NETLINK_ISCSI_SCST, 1, event_recv, + THIS_MODULE); #else - nl = netlink_kernel_create(NETLINK_ISCSI_SCST, 1, event_recv, NULL, + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + nl = netlink_kernel_create(NETLINK_ISCSI_SCST, 1, event_recv, NULL, THIS_MODULE); + #else + nl = netlink_kernel_create(&init_net, NETLINK_ISCSI_SCST, 1, + event_recv_skb, NULL, THIS_MODULE); + #endif #endif if (!nl) { PRINT_ERROR("%s", "netlink_kernel_create() failed"); Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2008-01-24 12:21:45 UTC (rev 250) +++ trunk/iscsi-scst/kernel/iscsi.c 2008-01-31 18:28:43 UTC (rev 251) @@ -531,7 +531,7 @@ if (cmnd->pdu.datasize & 3) { int idx = (offset + cmnd->pdu.datasize) >> PAGE_SHIFT; - u8 *p = (u8 *)page_address(cmnd->sg[idx].page) + + u8 *p = (u8 *)page_address(sg_page(&cmnd->sg[idx])) + ((offset + cmnd->pdu.datasize) & ~PAGE_MASK); int i = 4 - (cmnd->pdu.datasize & 3); while (i--) @@ -627,7 +627,7 @@ /* ToDo(); */ } rsp->own_sg = 1; - sense = (struct iscsi_sense_data *)page_address(sg[0].page); + sense = (struct iscsi_sense_data *)page_address(sg_page(&sg[0])); sense->length = cpu_to_be16(sense_len); memcpy(sense->data, sense_buf, sense_len); rsp->pdu.datasize = sizeof(struct iscsi_sense_data) + sense_len; @@ -686,7 +686,7 @@ /* ToDo(); */ } rsp->own_sg = 1; - addr = page_address(sg[0].page); + addr = page_address(sg_page(&sg[0])); clear_page(addr); memcpy(addr, &req->pdu.bhs, sizeof(struct iscsi_hdr)); rsp->bufflen = rsp->pdu.datasize = sizeof(struct iscsi_hdr); @@ -817,6 +817,8 @@ TRACE_DBG("%p:%x", cmnd, itt); if (unlikely(itt == ISCSI_RESERVED_TAG)) { PRINT_ERROR("%s", "ITT is RESERVED_TAG"); + PRINT_BUFFER("Incorrect BHS", &cmnd->pdu.bhs, + sizeof(cmnd->pdu.bhs)); err = -ISCSI_REASON_PROTOCOL_ERROR; goto out; } @@ -894,7 +896,7 @@ cmnd->bufflen = PAGE_SIZE; } - addr = page_address(sg[0].page); + addr = page_address(sg_page(&sg[0])); sBUG_ON(addr == NULL); size = (size + 3) & -4; conn->read_size = size; @@ -975,8 +977,7 @@ i = 0; while (1) { - sBUG_ON(sg[idx].page == NULL); - addr = page_address(sg[idx].page); + addr = page_address(sg_page(&sg[idx])); sBUG_ON(addr == NULL); conn->read_iov[i].iov_base = addr + offset; if (offset + size <= PAGE_SIZE) { @@ -1162,7 +1163,7 @@ for (i = 0; i < cmnd->sg_cnt; i++) { conn->read_iov[i].iov_base = - page_address(sg[i].page); + page_address(sg_page(&sg[i])); tmp = min_t(u32, size, PAGE_SIZE); conn->read_iov[i].iov_len = tmp; conn->read_size += tmp; Modified: trunk/iscsi-scst/kernel/nthread.c =================================================================== --- trunk/iscsi-scst/kernel/nthread.c 2008-01-24 12:21:45 UTC (rev 250) +++ trunk/iscsi-scst/kernel/nthread.c 2008-01-31 18:28:43 UTC (rev 251) @@ -96,17 +96,18 @@ if (cmnd_get_check(cmnd)) continue; for(i = 0; i < sg_cnt; i++) { - TRACE_CONN_CLOSE_DBG("page %p, net_priv %p, _count %d", - cmnd->sg[i].page, cmnd->sg[i].page->net_priv, - atomic_read(&cmnd->sg[i].page->_count)); + struct page *page = sg_page(&cmnd->sg[i]); + TRACE_CONN_CLOSE_DBG("page %p, net_priv %p, " + "_count %d", page, page->net_priv, + atomic_read(&page->_count)); - if (cmnd->sg[i].page->net_priv != NULL) { + if (page->net_priv != NULL) { if (restart == 0) { spin_unlock_bh(&conn->cmd_list_lock); restart = 1; } - while(cmnd->sg[i].page->net_priv != NULL) - iscsi_put_page_callback(cmnd->sg[i].page); + while(page->net_priv != NULL) + iscsi_put_page_callback(page); } } cmnd_put(cmnd); @@ -131,19 +132,19 @@ if (cmnd_get_check(rsp)) continue; for(i = 0; i < sg_cnt; i++) { + struct page *page = sg_page(&rsp->sg[i]); TRACE_CONN_CLOSE_DBG(" page %p, net_priv %p, " - "_count %d", rsp->sg[i].page, - rsp->sg[i].page->net_priv, - atomic_read(&rsp->sg[i].page->_count)); + "_count %d", page, page->net_priv, + atomic_read(&page->_count)); - if (rsp->sg[i].page->net_priv != NULL) { + if (page->net_priv != NULL) { if (restart == 0) { spin_unlock_bh(&cmnd->rsp_cmd_lock); spin_unlock_bh(&conn->cmd_list_lock); restart = 1; } - while(rsp->sg[i].page->net_priv != NULL) - iscsi_put_page_callback(rsp->sg[i].page); + while(page->net_priv != NULL) + iscsi_put_page_callback(page); } } cmnd_put(rsp); @@ -336,9 +337,10 @@ sg_cnt = get_pgcnt(cmnd->bufflen, cmnd->sg[0].offset); for(i = 0; i < sg_cnt; i++) { + struct page *page = sg_page(&cmnd->sg[i]); TRACE_CONN_CLOSE_DBG("page %p, net_priv %p, _count %d", - cmnd->sg[i].page, cmnd->sg[i].page->net_priv, - atomic_read(&cmnd->sg[i].page->_count)); + page, page->net_priv, + atomic_read(&page->_count)); } } @@ -356,9 +358,9 @@ sBUG_ON(rsp->sg_cnt != sg_cnt); for(i = 0; i < sg_cnt; i++) { TRACE_CONN_CLOSE_DBG(" page %p, net_priv %p, " - "_count %d", rsp->sg[i].page, - rsp->sg[i].page->net_priv, - atomic_read(&rsp->sg[i].page->_count)); + "_count %d", sg_page(&rsp->sg[i]), + sg_page(&rsp->sg[i])->net_priv, + atomic_read(&sg_page(&rsp->sg[i])->_count)); } } } @@ -809,8 +811,8 @@ if (atomic_dec_and_test(&cmd->net_ref_cnt)) { int i, sg_cnt = get_pgcnt(cmd->bufflen, cmd->sg[0].offset); for(i = 0; i < sg_cnt; i++) { - TRACE_NET_PAGE("Clearing page %p", cmd->sg[i].page); - cmd->sg[i].page->net_priv = NULL; + TRACE_NET_PAGE("Clearing page %p", sg_page(&cmd->sg[i])); + sg_page(&cmd->sg[i])->net_priv = NULL; } cmnd_put(cmd); } @@ -923,31 +925,31 @@ while (1) { #ifdef NET_PAGE_CALLBACKS_DEFINED - if (unlikely((sg[idx].page->net_priv != NULL) && - (sg[idx].page->net_priv != ref_cmd))) { + if (unlikely((sg_page(&sg[idx])->net_priv != NULL) && + (sg_page(&sg[idx])->net_priv != ref_cmd))) { PRINT_ERROR("net_priv isn't NULL and != ref_cmd " "(write_cmnd %p, ref_cmd %p, sg %p, idx %d, " "net_priv %p)", write_cmnd, ref_cmd, sg, idx, - sg[idx].page->net_priv); + sg_page(&sg[idx])->net_priv); sBUG(); } - sg[idx].page->net_priv = ref_cmd; + sg_page(&sg[idx])->net_priv = ref_cmd; #endif sendsize = PAGE_SIZE - offset; if (size <= sendsize) { retry2: - res = sendpage(sock, sg[idx].page, offset, size, flags); + res = sendpage(sock, sg_page(&sg[idx]), offset, size, flags); TRACE_WRITE("%s %#Lx:%u: %d(%lu,%u,%u)", sock->ops->sendpage ? "sendpage" : "sock_no_sendpage", (unsigned long long)conn->session->sid, conn->cid, - res, sg[idx].page->index, offset, size); + res, sg_page(&sg[idx])->index, offset, size); if (unlikely(res <= 0)) { if (res == -EINTR) goto retry2; else goto out_res; } - check_net_priv(ref_cmd, sg[idx].page); + check_net_priv(ref_cmd, sg_page(&sg[idx])); if (res == size) { conn->write_size = 0; return saved_size; @@ -958,19 +960,19 @@ } retry1: - res = sendpage(sock, sg[idx].page, offset, sendsize, + res = sendpage(sock, sg_page(&sg[idx]), offset, sendsize, flags | MSG_MORE); TRACE_WRITE("%s %#Lx:%u: %d(%lu,%u,%u)", sock->ops->sendpage ? "sendpage" : "sock_no_sendpage", (unsigned long long ) conn->session->sid, conn->cid, - res, sg[idx].page->index, offset, sendsize); + res, sg_page(&sg[idx])->index, offset, sendsize); if (unlikely(res <= 0)) { if (res == -EINTR) goto retry1; else goto out_res; } - check_net_priv(ref_cmd, sg[idx].page); + check_net_priv(ref_cmd, sg_page(&sg[idx])); if (res == sendsize) { idx++; offset = 0; @@ -988,7 +990,7 @@ return saved_size - size; out_res: - check_net_priv(ref_cmd, sg[idx].page); + check_net_priv(ref_cmd, sg_page(&sg[idx])); if (res == -EAGAIN) goto out; /* else go through */ Modified: trunk/qla2x00t/qla2x00-target/qla2x00t.c =================================================================== --- trunk/qla2x00t/qla2x00-target/qla2x00t.c 2008-01-24 12:21:45 UTC (rev 250) +++ trunk/qla2x00t/qla2x00-target/qla2x00t.c 2008-01-31 18:28:43 UTC (rev 251) @@ -1016,8 +1016,8 @@ case CTIO_TIMEOUT: case CTIO_INVALID_RX_ID: /* they are OK */ - TRACE_MGMT_DBG("qla2x00tgt(%ld): CTIO with status %#x " - "received (LIP_RESET=e, ABORTED=2, " + TRACE(TRACE_MGMT_MINOR, "qla2x00tgt(%ld): CTIO with " + "status %#x received (LIP_RESET=e, ABORTED=2, " "TARGET_RESET=17, TIMEOUT=b, " "INVALID_RX_ID=8)", ha->instance, status); break; @@ -1052,7 +1052,7 @@ goto out; } if (unlikely(err)) { - PRINT_INFO("Found by handle failed CTIO scst_cmd " + TRACE_MGMT_DBG("Found by handle failed CTIO scst_cmd " "%p (op %x)", scst_cmd, scst_cmd->cdb[0]); } } else if (ctio != NULL) { @@ -1075,7 +1075,7 @@ goto out; } if (unlikely(err)) { - PRINT_INFO("Found by ctio failed CTIO scst_cmd %p " + TRACE_MGMT_DBG("Found by ctio failed CTIO scst_cmd %p " "(op %x)", scst_cmd, scst_cmd->cdb[0]); } @@ -1085,7 +1085,8 @@ cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd); if (unlikely(err)) { - PRINT_INFO("Failed CTIO state %d", cmd->state); + TRACE(TRACE_MGMT_MINOR, "Failed CTIO state %d (err %x)", + cmd->state, status); } if (cmd->state == Q2T_STATE_PROCESSED) { @@ -1120,7 +1121,7 @@ scst_rx_data(scst_cmd, rx_status, context); } else if (cmd->state == Q2T_STATE_ABORTED) { - TRACE_DBG("Aborted command %p finished", cmd); + TRACE_MGMT_DBG("Aborted command %p finished", cmd); goto out_free; } else { PRINT_ERROR("qla2x00tgt(%ld): A command in state (%d) should " Modified: trunk/qla2x00t/qla2x00-target/qla2x00t.h =================================================================== --- trunk/qla2x00t/qla2x00-target/qla2x00t.h 2008-01-24 12:21:45 UTC (rev 250) +++ trunk/qla2x00t/qla2x00-target/qla2x00t.h 2008-01-31 18:28:43 UTC (rev 251) @@ -69,10 +69,10 @@ #define NOTIFY_ACK_TM_RESP_CODE_VALID BIT_4 /* Command's states */ -#define Q2T_STATE_NEW 0 /* New command and SCST processes it */ +#define Q2T_STATE_NEW 0 /* New command and SCST processing it */ #define Q2T_STATE_PROCESSED 1 /* SCST done processing */ -#define Q2T_STATE_NEED_DATA 2 /* SCST needs data to process */ -#define Q2T_STATE_DATA_IN 3 /* Data arrived and SCST processes it */ +#define Q2T_STATE_NEED_DATA 2 /* SCST needs data to continue */ +#define Q2T_STATE_DATA_IN 3 /* Data arrived and SCST processing them */ #define Q2T_STATE_ABORTED 4 /* Command aborted */ /* Misc */ Modified: trunk/qla2x00t/qla_attr.c =================================================================== --- trunk/qla2x00t/qla_attr.c 2008-01-24 12:21:45 UTC (rev 250) +++ trunk/qla2x00t/qla_attr.c 2008-01-31 18:28:43 UTC (rev 251) @@ -61,14 +61,14 @@ case '0' : if ((ha->flags.enable_target_mode) || force) { qla_target.tgt_host_action(ha, DISABLE_TARGET_MODE); + msleep_interruptible(10*1000); } - msleep_interruptible(3*1000); break; case '1' : if ((ha->flags.enable_target_mode == 0) || force) { qla_target.tgt_host_action(ha, ENABLE_TARGET_MODE); + msleep_interruptible(10*1000); } - msleep_interruptible(3*1000); break; default: printk("%s: Requested action not understood: %s\n", Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2008-01-24 12:21:45 UTC (rev 250) +++ trunk/scst/include/scsi_tgt.h 2008-01-31 18:28:43 UTC (rev 251) @@ -36,6 +36,10 @@ #include <scst_const.h> +#ifndef DECLARE_MUTEX_LOCKED +#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name, 0) +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) typedef _Bool bool; #endif @@ -2235,6 +2239,52 @@ return mcmd->status; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + +static inline struct page *sg_page(struct scatterlist *sg) +{ + return sg->page; +} + +static inline void *sg_virt(struct scatterlist *sg) +{ + return page_address(sg_page(sg)) + sg->offset; +} + +static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents) +{ + memset(sgl, 0, sizeof(*sgl) * nents); +} + +static inline void sg_assign_page(struct scatterlist *sg, struct page *page) +{ + sg->page = page; +} + +static inline void sg_set_page(struct scatterlist *sg, struct page *page, + unsigned int len, unsigned int offset) +{ + sg_assign_page(sg, page); + sg->offset = offset; + sg->length = len; +} + +static inline void sg_set_buf(struct scatterlist *sg, const void *buf, + unsigned int buflen) +{ + sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf)); +} + +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) */ + +static inline void sg_clear(struct scatterlist *sg) +{ + memset(sg, 0, sizeof(*sg)); +#ifdef CONFIG_DEBUG_SG + sg->sg_magic = SG_MAGIC; +#endif +} + /* * Functions for access to the commands data (SG) buffer, * including HIGHMEM environment. Should be used instead of direct @@ -2245,7 +2295,41 @@ * * The "put" function unmaps the buffer. */ -int __scst_get_buf(struct scst_cmd *cmd, uint8_t **buf); +static inline int __scst_get_buf(struct scst_cmd *cmd, uint8_t **buf) +{ + int res = 0; + struct scatterlist *sg = cmd->sg; + int i = cmd->get_sg_buf_entry_num; + + *buf = NULL; + + if ((i >= cmd->sg_cnt) || unlikely(sg == NULL)) + goto out; +#ifdef SCST_HIGHMEM /* HIGHMEM isn't currently supported */ + /* + * HIGHMEM pages not merged (clustered), so if it's + * not HIGHMEM page, kmap() is the same as page_address() + */ + if (scst_cmd_atomic(cmd)) { + enum km_type km; + if (in_softirq()) + km = KM_SOFTIRQ0; + else + km = KM_USER0; + *buf = kmap_atomic(sg[i].page, km); + } else + *buf = kmap(sg[i].page); +#else + *buf = page_address(sg_page(&sg[i])); +#endif + *buf += sg[i].offset; + res = sg[i].length; + cmd->get_sg_buf_entry_num++; + +out: + return res; +} + static inline int scst_get_buf_first(struct scst_cmd *cmd, uint8_t **buf) { cmd->get_sg_buf_entry_num = 0; @@ -2260,7 +2344,7 @@ static inline void scst_put_buf(struct scst_cmd *cmd, void *buf) { -#ifdef SCST_HIGHMEM +#ifdef SCST_HIGHMEM /* HIGHMEM isn't currently supported */ if (cmd->sg_cnt) { if (scst_cmd_atomic(cmd)) { enum km_type km; Modified: trunk/scst/src/dev_handlers/scst_user.c =================================================================== --- trunk/scst/src/dev_handlers/scst_user.c 2008-01-24 12:21:45 UTC (rev 250) +++ trunk/scst/src/dev_handlers/scst_user.c 2008-01-31 18:28:43 UTC (rev 251) @@ -346,17 +346,16 @@ if (ucmd->cur_data_page >= ucmd->num_data_pages) goto out; - sg->page = ucmd->data_pages[ucmd->cur_data_page]; - sg->length = PAGE_SIZE - sg->offset; - + sg_set_page(sg, ucmd->data_pages[ucmd->cur_data_page], + PAGE_SIZE - sg->offset, 0); ucmd->cur_data_page++; - TRACE_MEM("page=%p, length=%d", sg->page, sg->length); - TRACE_BUFFER("Page data", page_address(sg->page), sg->length); + TRACE_MEM("page=%p, length=%d", sg_page(sg), sg->length); + TRACE_BUFFER("Page data", sg_virt(sg), sg->length); out: TRACE_EXIT(); - return sg->page; + return sg_page(sg); } static void dev_user_on_cached_mem_free(struct scst_user_cmd *ucmd) Modified: trunk/scst/src/dev_handlers/scst_vdisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_vdisk.c 2008-01-24 12:21:45 UTC (rev 250) +++ trunk/scst/src/dev_handlers/scst_vdisk.c 2008-01-31 18:28:43 UTC (rev 251) @@ -2196,12 +2196,18 @@ } } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) static int blockio_endio(struct bio *bio, unsigned int bytes_done, int error) +#else +static void blockio_endio(struct bio *bio, int error) +#endif { struct blockio_work *blockio_work = bio->bi_private; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) if (bio->bi_size) return 1; +#endif error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? error : -EIO; @@ -2224,7 +2230,11 @@ blockio_check_finish(blockio_work); bio_put(bio); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) return 0; +#else + return; +#endif } static void blockio_exec_rw(struct scst_cmd *cmd, struct scst_vdisk_thr *thr, @@ -2233,10 +2243,10 @@ struct scst_vdisk_dev *virt_dev = thr->virt_dev; struct block_device *bdev = thr->bdev; struct request_queue *q = bdev_get_queue(bdev); - int j, max_nr_vecs = 0; + int length, max_nr_vecs = 0; + uint8_t *address; struct bio *bio = NULL, *hbio = NULL, *tbio = NULL; int need_new_bio; - struct scatterlist *sgl = cmd->sg; struct blockio_work *blockio_work; int bios = 0; @@ -2258,24 +2268,27 @@ max_nr_vecs = 1; need_new_bio = 1; - for (j = 0; j < cmd->sg_cnt; ++j) { + + length = scst_get_buf_first(cmd, &address); + while(length > 0) { int len, bytes, off, thislen; - struct page *page; + uint8_t *addr; - page = sgl[j].page; - off = sgl[j].offset; - len = sgl[j].length; + addr = address; + off = offset_in_page(addr); + len = length; thislen = 0; while (len > 0) { int rc; + struct page *page = virt_to_page(addr); if (need_new_bio) { bio = bio_alloc(GFP_KERNEL, max_nr_vecs); if (!bio) { PRINT_ERROR("Failed to create bio " - "for data segment= %d " - "cmd %p", j, cmd); + "for data segment= %d cmd %p", + cmd->get_sg_buf_entry_num, cmd); goto out_no_bio; } @@ -2306,13 +2319,16 @@ continue; } - page++; + addr += PAGE_SIZE; thislen += bytes; len -= bytes; off = 0; } - lba_start += sgl[j].length >> virt_dev->block_shift; + lba_start += length >> virt_dev->block_shift; + + scst_put_buf(cmd, address); + length = scst_get_buf_next(cmd, &address); } /* +1 to prevent erroneous too early command completion */ Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2008-01-24 12:21:45 UTC (rev 250) +++ trunk/scst/src/scst_lib.c 2008-01-31 18:28:43 UTC (rev 251) @@ -1567,44 +1567,6 @@ return; } -int __scst_get_buf(struct scst_cmd *cmd, uint8_t **buf) -{ - int res = 0; - struct scatterlist *sg = cmd->sg; - int i = cmd->get_sg_buf_entry_num; - - TRACE_ENTRY(); - - *buf = NULL; - - if ((i >= cmd->sg_cnt) || unlikely(sg == NULL)) - goto out; -#ifdef SCST_HIGHMEM - /* - * HIGHMEM pages not merged (clustered), so if it's - * not HIGHMEM page, kmap() is the same as page_address() - */ - if (scst_cmd_atomic(cmd)) { - enum km_type km; - if (in_softirq()) - km = KM_SOFTIRQ0; - else - km = KM_USER0; - *buf = kmap_atomic(sg[i].page, km); - } else - *buf = kmap(sg[i].page); -#else - *buf = page_address(sg[i].page); -#endif - *buf += sg[i].offset; - res = sg[i].length; - cmd->get_sg_buf_entry_num++; - -out: - TRACE_EXIT_RES(res); - return res; -} - static const int SCST_CDB_LENGTH[8] = { 6, 10, 10, -1, 16, 12, -1, -1 }; #define SCST_CDB_GROUP(opcode) ((opcode >> 5) & 0x7) Modified: trunk/scst/src/scst_main.c =================================================================== --- trunk/scst/src/scst_main.c 2008-01-24 12:21:45 UTC (rev 250) +++ trunk/scst/src/scst_main.c 2008-01-31 18:28:43 UTC (rev 251) @@ -296,7 +296,7 @@ tgt = kzalloc(sizeof(*tgt), GFP_KERNEL); if (tgt == NULL) { - TRACE(TRACE_OUT_OF_MEM, "%s", "kzalloc() failed"); + TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of tgt failed"); goto out_err; } @@ -1736,7 +1736,6 @@ EXPORT_SYMBOL(scst_create_proc_entry); EXPORT_SYMBOL(scst_single_seq_open); -EXPORT_SYMBOL(__scst_get_buf); EXPORT_SYMBOL(scst_get); EXPORT_SYMBOL(scst_put); Modified: trunk/scst/src/scst_mem.c =================================================================== --- trunk/scst/src/scst_mem.c 2008-01-24 12:21:45 UTC (rev 250) +++ trunk/scst/src/scst_mem.c 2008-01-31 18:28:43 UTC (rev 251) @@ -75,7 +75,7 @@ { int res = -1; int i = hint; - unsigned long pfn_cur = page_to_pfn(sg[cur].page); + unsigned long pfn_cur = page_to_pfn(sg_page(&sg[cur])); int len_cur = sg[cur].length; unsigned long pfn_cur_next = pfn_cur + (len_cur >> PAGE_SHIFT); int full_page_cur = (len_cur & (PAGE_SIZE - 1)) == 0; @@ -95,7 +95,7 @@ /* check the hint first */ if (i >= 0) { - pfn = page_to_pfn(sg[i].page); + pfn = page_to_pfn(sg_page(&sg[i])); pfn_next = pfn + (sg[i].length >> PAGE_SHIFT); full_page = (sg[i].length & (PAGE_SIZE - 1)) == 0; @@ -108,7 +108,7 @@ /* ToDo: implement more intelligent search */ for(i = cur - 1; i >= 0; i--) { - pfn = page_to_pfn(sg[i].page); + pfn = page_to_pfn(sg_page(&sg[i])); pfn_next = pfn + (sg[i].length >> PAGE_SHIFT); full_page = (sg[i].length & (PAGE_SIZE - 1)) == 0; @@ -125,15 +125,15 @@ out_tail: TRACE_MEM("SG segment %d will be tail merged with segment %d", cur, i); sg[i].length += len_cur; - memset(&sg[cur], 0, sizeof(sg[cur])); + sg_clear(&sg[cur]); res = i; goto out; out_head: TRACE_MEM("SG segment %d will be head merged with segment %d", cur, i); - sg[i].page = sg[cur].page; + sg_assign_page(&sg[i], sg_page(&sg[cur])); sg[i].length += len_cur; - memset(&sg[cur], 0, sizeof(sg[cur])); + sg_clear(&sg[cur]); res = i; goto out; } @@ -146,7 +146,7 @@ TRACE_MEM("sg=%p, sg_count=%d", sg, sg_count); for(i = 0; i < sg_count; i++) { - struct page *p = sg[i].page; + struct page *p = sg_page(&sg[i]); int len = sg[i].length; int pages = (len >> PAGE_SHIFT) + ((len & ~PAGE_MASK) != 0); @@ -182,15 +182,15 @@ static struct page *scst_alloc_sys_pages(struct scatterlist *sg, gfp_t gfp_mask, void *priv) { - sg->page = alloc_pages(gfp_mask, 0); - sg->offset = 0; - sg->length = PAGE_SIZE; - TRACE_MEM("page=%p, sg=%p, priv=%p", sg->page, sg, priv); - if (sg->page == NULL) { + struct page *page = alloc_pages(gfp_mask, 0); + + sg_set_page(sg, page, PAGE_SIZE, 0); + TRACE_MEM("page=%p, sg=%p, priv=%p", page, sg, priv); + if (page == NULL) { TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of " "sg page failed"); } - return sg->page; + return page; } static int scst_alloc_sg_entries(struct scatterlist *sg, int pages, @@ -265,7 +265,7 @@ sz = pages_to_alloc * sizeof(obj->sg_entries[0]); - obj->sg_entries = (struct scatterlist*)kzalloc(sz, gfp_mask); + obj->sg_entries = (struct scatterlist*)kmalloc(sz, gfp_mask); if (unlikely(obj->sg_entries == NULL)) { TRACE(TRACE_OUT_OF_MEM, "Allocation of sgv_pool_obj " "SG vector failed (size %d)", sz); @@ -273,6 +273,8 @@ goto out; } + sg_init_table(obj->sg_entries, pages_to_alloc); + if (obj->owner_pool->clustered) { if (order <= sgv_pools_mgr.sgv_max_trans_order) { obj->trans_tbl = (struct trans_tbl_ent*)obj->sg_entries_data; @@ -528,7 +530,6 @@ if (obj->sg_count != 0) { TRACE_MEM("Cached sgv_obj %p", obj); EXTRACHECKS_BUG_ON(obj->order != order); - atomic_inc(&pool->acc.hit_alloc); atomic_inc(&pool->cache_acc[order].hit_alloc); goto success; } @@ -540,9 +541,8 @@ TRACE_MEM("Brand new sgv_obj %p", obj); if (order <= sgv_pools_mgr.sgv_max_local_order) { obj->sg_entries = obj->sg_entries_data; + sg_init_table(obj->sg_entries, pages_to_alloc); TRACE_MEM("sg_entries %p", obj->sg_entries); - memset(obj->sg_entries, 0, - pages_to_alloc*sizeof(obj->sg_entries[0])); if (pool->clustered) { obj->trans_tbl = (struct trans_tbl_ent*) (obj->sg_entries + pages_to_alloc); @@ -572,16 +572,19 @@ goto out_return2; cache = NULL; sz = sizeof(*obj) + pages*sizeof(obj->sg_entries[0]); - obj = kzalloc(sz, gfp_mask); + obj = kmalloc(sz, gfp_mask); if (unlikely(obj == NULL)) { TRACE(TRACE_OUT_OF_MEM, "Allocation of " "sgv_pool_obj failed (size %d)", size); goto out_fail; } + memset(obj, 0, sizeof(*obj)); obj->owner_pool = pool; obj->order = -1 - order; + obj->allocator_priv = priv; + obj->sg_entries = obj->sg_entries_data; - obj->allocator_priv = priv; + sg_init_table(obj->sg_entries, pages); if (sgv_pool_hiwmk_check(pages_to_alloc, no_fail) != 0) goto out_fail_free_sg_entries; @@ -600,7 +603,6 @@ } success: - atomic_inc(&pool->acc.total_alloc); spin_lock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock); sgv_pools_mgr.mgr.thr.active_pages_total += 1 << order; spin_unlock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock); @@ -728,10 +730,12 @@ goto out; } - res = kzalloc(pages*sizeof(*res), gfp_mask); + res = kmalloc(pages*sizeof(*res), gfp_mask); if (res == NULL) goto out; + sg_init_table(res, pages); + /* * If we allow use clustering here, we will have troubles in * scst_free() to figure out how many pages are in the SG vector. @@ -791,8 +795,6 @@ atomic_set(&pool->acc.other_alloc, 0); atomic_set(&pool->acc.big_alloc, 0); - atomic_set(&pool->acc.total_alloc, 0); - atomic_set(&pool->acc.hit_alloc, 0); pool->clustered = clustered; pool->alloc_fns.alloc_pages_fn = scst_alloc_sys_pages; @@ -1058,8 +1060,8 @@ int res; struct scst_sgv_pools_manager *pools = &sgv_pools_mgr; + TRACE_ENTRY(); - TRACE_ENTRY(); memset(pools, 0, sizeof(*pools)); sgv_pools_mgr.mgr.thr.hi_wmk = mem_hwmark >> PAGE_SHIFT; @@ -1154,11 +1156,15 @@ static void scst_do_sgv_read(struct seq_file *seq, const struct sgv_pool *pool) { - int i; + int i, total = 0, hit = 0; + + for(i = 0; i < SGV_POOL_ELEMENTS; i++) { + hit += atomic_read(&pool->cache_acc[i].hit_alloc); + total += atomic_read(&pool->cache_acc[i].total_alloc); + } seq_printf(seq, "\n%-30s %-11d %-11d %d/%d (P/O)\n", pool->name, - atomic_read(&pool->acc.hit_alloc), - atomic_read(&pool->acc.total_alloc), + hit, total, pool->acc.cached_pages, pool->acc.cached_entries); Modified: trunk/scst/src/scst_mem.h =================================================================== --- trunk/scst/src/scst_mem.h 2008-01-24 12:21:45 UTC (rev 250) +++ trunk/scst/src/scst_mem.h 2008-01-31 18:28:43 UTC (rev 251) @@ -52,7 +52,6 @@ struct sgv_pool_acc { - atomic_t total_alloc, hit_alloc; u32 cached_pages, cached_entries; atomic_t big_alloc, other_alloc; }; Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2008-01-24 12:21:45 UTC (rev 250) +++ trunk/scst/src/scst_targ.c 2008-01-31 18:28:43 UTC (rev 251) @@ -1211,10 +1211,10 @@ int i; struct scatterlist *sg = cmd->sg; TRACE_RECV_TOP("Exec'd %d S/G(s) at %p sg[0].page at " - "%p", cmd->sg_cnt, sg, (void*)sg[0].page); + "%p", cmd->sg_cnt, sg, (void*)sg_page(&sg[0])); for(i = 0; i < cmd->sg_cnt; ++i) { TRACE_BUFF_FLAG(TRACE_RCV_TOP, - "Exec'd sg", page_address(sg[i].page), + "Exec'd sg", sg_virt(&sg[i]), sg[i].length); } } @@ -2553,10 +2553,10 @@ int i; struct scatterlist *sg = cmd->sg; TRACE_SEND_BOT("Xmitting %d S/G(s) at %p sg[0].page at %p", - cmd->sg_cnt, sg, (void*)sg[0].page); + cmd->sg_cnt, sg, (void*)sg_page(&sg[0])); for(i = 0; i < cmd->sg_cnt; ++i) { TRACE_BUFF_FLAG(TRACE_SND_BOT, - "Xmitting sg", page_address(sg[i].page), + "Xmitting sg", sg_virt(&sg[i]), sg[i].length); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2008-02-01 10:33:52
|
Revision: 252 http://scst.svn.sourceforge.net/scst/?rev=252&view=rev Author: vlnb Date: 2008-02-01 02:33:47 -0800 (Fri, 01 Feb 2008) Log Message: ----------- Forgotten in the previous commit kernel patches Added Paths: ----------- trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.24.patch trunk/scst/kernel/scst_exec_req_fifo-2.6.24.patch Added: trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.24.patch =================================================================== --- trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.24.patch (rev 0) +++ trunk/iscsi-scst/kernel/patches/put_page_callback-2.6.24.patch 2008-02-01 10:33:47 UTC (rev 252) @@ -0,0 +1,259 @@ +diff -upkr linux-2.6.24/include/linux/mm_types.h linux-2.6.24/include/linux/mm_types.h +--- linux-2.6.24/include/linux/mm_types.h 2008-01-25 01:58:37.000000000 +0300 ++++ linux-2.6.24/include/linux/mm_types.h 2008-01-28 11:11:16.000000000 +0300 +@@ -88,6 +88,15 @@ struct page { + void *virtual; /* Kernel virtual address (NULL if + not kmapped, ie. highmem) */ + #endif /* WANT_PAGE_VIRTUAL */ ++ /* ++ * Used to implement support for notification on zero-copy TCP transfer ++ * completion. Not good to have this field here, it's better to have ++ * it in struct sk_buff, but it would make the code much more ++ * complicated and fragile, if maintained as a separate patch, since all ++ * skb then would have to contain only pages with the same value in this ++ * field. ++ */ ++ void *net_priv; + }; + + /* +diff -upkr linux-2.6.24/include/linux/net.h linux-2.6.24/include/linux/net.h +--- linux-2.6.24/include/linux/net.h 2008-01-25 01:58:37.000000000 +0300 ++++ linux-2.6.24/include/linux/net.h 2008-01-28 11:11:16.000000000 +0300 +@@ -58,6 +58,7 @@ typedef enum { + #ifdef __KERNEL__ + #include <linux/stringify.h> + #include <linux/random.h> ++#include <linux/mm.h> + + #define SOCK_ASYNC_NOSPACE 0 + #define SOCK_ASYNC_WAITDATA 1 +@@ -332,5 +333,30 @@ extern int net_msg_cost; + extern int net_msg_burst; + #endif + ++/* Support for notification on zero-copy TCP transfer completion */ ++#define NET_PAGE_CALLBACKS_DEFINED ++typedef void (*net_get_page_callback_t)(struct page *page); ++typedef void (*net_put_page_callback_t)(struct page *page); ++ ++extern net_get_page_callback_t net_get_page_callback; ++extern net_put_page_callback_t net_put_page_callback; ++ ++extern int net_set_get_put_page_callbacks( ++ net_get_page_callback_t get_callback, ++ net_put_page_callback_t put_callback); ++ ++static inline void net_get_page(struct page *page) ++{ ++ if (page->net_priv != 0) ++ net_get_page_callback(page); ++ get_page(page); ++} ++static inline void net_put_page(struct page *page) ++{ ++ if (page->net_priv != 0) ++ net_put_page_callback(page); ++ put_page(page); ++} ++ + #endif /* __KERNEL__ */ + #endif /* _LINUX_NET_H */ +diff -upkr linux-2.6.24/net/core/skbuff.c linux-2.6.24/net/core/skbuff.c +--- linux-2.6.24/net/core/skbuff.c 2008-01-25 01:58:37.000000000 +0300 ++++ linux-2.6.24/net/core/skbuff.c 2008-01-28 11:11:16.000000000 +0300 +@@ -262,7 +262,7 @@ static void skb_release_data(struct sk_b + if (skb_shinfo(skb)->nr_frags) { + int i; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + } + + if (skb_shinfo(skb)->frag_list) +@@ -596,7 +596,7 @@ struct sk_buff *pskb_copy(struct sk_buff + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i]; +- get_page(skb_shinfo(n)->frags[i].page); ++ net_get_page(skb_shinfo(n)->frags[i].page); + } + skb_shinfo(n)->nr_frags = i; + } +@@ -659,7 +659,7 @@ int pskb_expand_head(struct sk_buff *skb + sizeof(struct skb_shared_info)); + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) +- get_page(skb_shinfo(skb)->frags[i].page); ++ net_get_page(skb_shinfo(skb)->frags[i].page); + + if (skb_shinfo(skb)->frag_list) + skb_clone_fraglist(skb); +@@ -856,7 +856,7 @@ drop_pages: + skb_shinfo(skb)->nr_frags = i; + + for (; i < nfrags; i++) +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + + if (skb_shinfo(skb)->frag_list) + skb_drop_fraglist(skb); +@@ -1025,7 +1025,7 @@ pull_pages: + k = 0; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + if (skb_shinfo(skb)->frags[i].size <= eat) { +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + eat -= skb_shinfo(skb)->frags[i].size; + } else { + skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; +@@ -1594,7 +1594,7 @@ static inline void skb_split_no_header(s + * where splitting is expensive. + * 2. Split is accurately. We make this. + */ +- get_page(skb_shinfo(skb)->frags[i].page); ++ net_get_page(skb_shinfo(skb)->frags[i].page); + skb_shinfo(skb1)->frags[0].page_offset += len - pos; + skb_shinfo(skb1)->frags[0].size -= len - pos; + skb_shinfo(skb)->frags[i].size = len - pos; +@@ -1970,7 +1970,7 @@ struct sk_buff *skb_segment(struct sk_bu + BUG_ON(i >= nfrags); + + *frag = skb_shinfo(skb)->frags[i]; +- get_page(frag->page); ++ net_get_page(frag->page); + size = frag->size; + + if (pos < offset) { +diff -upkr linux-2.6.24/net/core/utils.c linux-2.6.24/net/core/utils.c +--- linux-2.6.24/net/core/utils.c 2008-01-25 01:58:37.000000000 +0300 ++++ linux-2.6.24/net/core/utils.c 2008-01-28 11:11:16.000000000 +0300 +@@ -25,6 +25,7 @@ + #include <linux/random.h> + #include <linux/percpu.h> + #include <linux/init.h> ++#include <linux/skbuff.h> + #include <net/sock.h> + + #include <asm/byteorder.h> +@@ -36,6 +37,9 @@ int net_msg_burst __read_mostly = 10; + int net_msg_warn __read_mostly = 1; + EXPORT_SYMBOL(net_msg_warn); + ++net_get_page_callback_t net_get_page_callback __read_mostly; ++net_put_page_callback_t net_put_page_callback __read_mostly; ++ + /* + * All net warning printk()s should be guarded by this function. + */ +@@ -293,3 +297,32 @@ out: + } + + EXPORT_SYMBOL(in6_pton); ++ ++int net_set_get_put_page_callbacks( ++ net_get_page_callback_t get_callback, ++ net_put_page_callback_t put_callback) ++{ ++ int res = 0; ++ ++ if ((net_get_page_callback != NULL) && (get_callback != NULL) && ++ (net_get_page_callback != get_callback)) { ++ res = -EBUSY; ++ goto out; ++ } ++ ++ if ((net_put_page_callback != NULL) && (put_callback != NULL) && ++ (net_put_page_callback != put_callback)) { ++ res = -EBUSY; ++ goto out; ++ } ++ ++ net_get_page_callback = get_callback; ++ net_put_page_callback = put_callback; ++ ++out: ++ return res; ++} ++EXPORT_SYMBOL(net_set_get_put_page_callbacks); ++ ++EXPORT_SYMBOL(net_get_page_callback); ++EXPORT_SYMBOL(net_put_page_callback); +diff -upkr linux-2.6.24/net/ipv4/ip_output.c linux-2.6.24/net/ipv4/ip_output.c +--- linux-2.6.24/net/ipv4/ip_output.c 2008-01-25 01:58:37.000000000 +0300 ++++ linux-2.6.24/net/ipv4/ip_output.c 2008-01-28 11:11:16.000000000 +0300 +@@ -999,7 +999,7 @@ alloc_new_skb: + err = -EMSGSIZE; + goto error; + } +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); + frag = &skb_shinfo(skb)->frags[i]; + } +@@ -1157,7 +1157,7 @@ ssize_t ip_append_page(struct sock *sk, + if (skb_can_coalesce(skb, i, page, offset)) { + skb_shinfo(skb)->frags[i-1].size += len; + } else if (i < MAX_SKB_FRAGS) { +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, offset, len); + } else { + err = -EMSGSIZE; +diff -upkr linux-2.6.24/net/ipv4/tcp.c linux-2.6.24/net/ipv4/tcp.c +--- linux-2.6.24/net/ipv4/tcp.c 2008-01-25 01:58:37.000000000 +0300 ++++ linux-2.6.24/net/ipv4/tcp.c 2008-01-28 11:11:16.000000000 +0300 +@@ -561,7 +561,7 @@ new_segment: + if (can_coalesce) { + skb_shinfo(skb)->frags[i - 1].size += copy; + } else { +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, offset, copy); + } + +@@ -766,7 +766,7 @@ new_segment: + goto new_segment; + } else if (page) { + if (off == PAGE_SIZE) { +- put_page(page); ++ net_put_page(page); + TCP_PAGE(sk) = page = NULL; + off = 0; + } +@@ -807,9 +807,9 @@ new_segment: + } else { + skb_fill_page_desc(skb, i, page, off, copy); + if (TCP_PAGE(sk)) { +- get_page(page); ++ net_get_page(page); + } else if (off + copy < PAGE_SIZE) { +- get_page(page); ++ net_get_page(page); + TCP_PAGE(sk) = page; + } + } +diff -upkr linux-2.6.24/net/ipv4/tcp_output.c linux-2.6.24/net/ipv4/tcp_output.c +--- linux-2.6.24/net/ipv4/tcp_output.c 2008-01-25 01:58:37.000000000 +0300 ++++ linux-2.6.24/net/ipv4/tcp_output.c 2008-01-28 11:11:16.000000000 +0300 +@@ -794,7 +794,7 @@ static void __pskb_trim_head(struct sk_b + k = 0; + for (i=0; i<skb_shinfo(skb)->nr_frags; i++) { + if (skb_shinfo(skb)->frags[i].size <= eat) { +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + eat -= skb_shinfo(skb)->frags[i].size; + } else { + skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; +diff -upkr linux-2.6.24/net/ipv6/ip6_output.c linux-2.6.24/net/ipv6/ip6_output.c +--- linux-2.6.24/net/ipv6/ip6_output.c 2008-01-25 01:58:37.000000000 +0300 ++++ linux-2.6.24/net/ipv6/ip6_output.c 2008-01-28 11:11:16.000000000 +0300 +@@ -1299,7 +1299,7 @@ alloc_new_skb: + err = -EMSGSIZE; + goto error; + } +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); + frag = &skb_shinfo(skb)->frags[i]; + } Added: trunk/scst/kernel/scst_exec_req_fifo-2.6.24.patch =================================================================== --- trunk/scst/kernel/scst_exec_req_fifo-2.6.24.patch (rev 0) +++ trunk/scst/kernel/scst_exec_req_fifo-2.6.24.patch 2008-02-01 10:33:47 UTC (rev 252) @@ -0,0 +1,109 @@ +diff -upkr linux-2.6.24/drivers/scsi/scsi_lib.c linux-2.6.24/drivers/scsi/scsi_lib.c +--- linux-2.6.24/drivers/scsi/scsi_lib.c 2008-01-25 01:58:37.000000000 +0300 ++++ linux-2.6.24/drivers/scsi/scsi_lib.c 2008-01-28 11:10:30.000000000 +0300 +@@ -361,7 +361,7 @@ free_bios: + } + + /** +- * scsi_execute_async - insert request ++ * __scsi_execute_async - insert request + * @sdev: scsi device + * @cmd: scsi command + * @cmd_len: length of scsi cdb +@@ -372,11 +372,14 @@ free_bios: + * @timeout: request timeout in seconds + * @retries: number of times to retry request + * @flags: or into request flags ++ * @at_head: insert request at head or tail of queue + **/ +-int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, ++static inline int __scsi_execute_async(struct scsi_device *sdev, ++ const unsigned char *cmd, + int cmd_len, int data_direction, void *buffer, unsigned bufflen, + int use_sg, int timeout, int retries, void *privdata, +- void (*done)(void *, char *, int, int), gfp_t gfp) ++ void (*done)(void *, char *, int, int), gfp_t gfp, ++ int at_head) + { + struct request *req; + struct scsi_io_context *sioc; +@@ -413,7 +416,7 @@ int scsi_execute_async(struct scsi_devic + sioc->data = privdata; + sioc->done = done; + +- blk_execute_rq_nowait(req->q, NULL, req, 1, scsi_end_async); ++ blk_execute_rq_nowait(req->q, NULL, req, at_head, scsi_end_async); + return 0; + + free_req: +@@ -422,8 +425,53 @@ free_sense: + kmem_cache_free(scsi_io_context_cache, sioc); + return DRIVER_ERROR << 24; + } ++ ++/** ++ * scsi_execute_async - insert request ++ * @sdev: scsi device ++ * @cmd: scsi command ++ * @cmd_len: length of scsi cdb ++ * @data_direction: data direction ++ * @buffer: data buffer (this can be a kernel buffer or scatterlist) ++ * @bufflen: len of buffer ++ * @use_sg: if buffer is a scatterlist this is the number of elements ++ * @timeout: request timeout in seconds ++ * @retries: number of times to retry request ++ * @flags: or into request flags ++ **/ ++int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, ++ int cmd_len, int data_direction, void *buffer, unsigned bufflen, ++ int use_sg, int timeout, int retries, void *privdata, ++ void (*done)(void *, char *, int, int), gfp_t gfp) ++{ ++ return __scsi_execute_async(sdev, cmd, cmd_len, data_direction, buffer, ++ bufflen, use_sg, timeout, retries, privdata, done, gfp, 1); ++} + EXPORT_SYMBOL_GPL(scsi_execute_async); + ++/** ++ * scsi_execute_async_fifo - insert request at tail, in FIFO order ++ * @sdev: scsi device ++ * @cmd: scsi command ++ * @cmd_len: length of scsi cdb ++ * @data_direction: data direction ++ * @buffer: data buffer (this can be a kernel buffer or scatterlist) ++ * @bufflen: len of buffer ++ * @use_sg: if buffer is a scatterlist this is the number of elements ++ * @timeout: request timeout in seconds ++ * @retries: number of times to retry request ++ * @flags: or into request flags ++ **/ ++int scsi_execute_async_fifo(struct scsi_device *sdev, const unsigned char *cmd, ++ int cmd_len, int data_direction, void *buffer, unsigned bufflen, ++ int use_sg, int timeout, int retries, void *privdata, ++ void (*done)(void *, char *, int, int), gfp_t gfp) ++{ ++ return __scsi_execute_async(sdev, cmd, cmd_len, data_direction, buffer, ++ bufflen, use_sg, timeout, retries, privdata, done, gfp, 0); ++} ++EXPORT_SYMBOL_GPL(scsi_execute_async_fifo); ++ + /* + * Function: scsi_init_cmd_errh() + * +diff -upkr linux-2.6.24/include/scsi/scsi_device.h linux-2.6.24/include/scsi/scsi_device.h +--- linux-2.6.24/include/scsi/scsi_device.h 2008-01-25 01:58:37.000000000 +0300 ++++ linux-2.6.24/include/scsi/scsi_device.h 2008-01-28 11:10:30.000000000 +0300 +@@ -331,6 +331,13 @@ extern int scsi_execute_async(struct scs + int timeout, int retries, void *privdata, + void (*done)(void *, char *, int, int), + gfp_t gfp); ++#define SCSI_EXEC_REQ_FIFO_DEFINED ++extern int scsi_execute_async_fifo(struct scsi_device *sdev, ++ const unsigned char *cmd, int cmd_len, int data_direction, ++ void *buffer, unsigned bufflen, int use_sg, ++ int timeout, int retries, void *privdata, ++ void (*done)(void *, char *, int, int), ++ gfp_t gfp); + + static inline int __must_check scsi_device_reprobe(struct scsi_device *sdev) + { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2008-02-13 17:15:56
|
Revision: 287 http://scst.svn.sourceforge.net/scst/?rev=287&view=rev Author: vlnb Date: 2008-02-13 09:15:47 -0800 (Wed, 13 Feb 2008) Log Message: ----------- - Fixed minor problem in iSCSI-SCST - Important reference counting and barriers usage cleanups - Sense buffer made dynamic - Other minor improvements and cleanups - Docs updates Modified Paths: -------------- trunk/iscsi-scst/README trunk/iscsi-scst/include/iscsi_u.h trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/kernel/iscsi.h trunk/iscsi-scst/kernel/nthread.c trunk/mpt/mpt_scst.c trunk/qla2x00t/qla_init.c trunk/scst/README trunk/scst/include/scsi_tgt.h trunk/scst/include/scst_const.h trunk/scst/src/dev_handlers/scst_tape.c trunk/scst/src/dev_handlers/scst_user.c trunk/scst/src/dev_handlers/scst_vdisk.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_main.c trunk/scst/src/scst_priv.h trunk/scst/src/scst_targ.c Added Paths: ----------- trunk/AskingQuestions trunk/iscsi-scst/AskingQuestions trunk/qla2x00t/qla2x00-target/AskingQuestions trunk/scst/AskingQuestions Added: trunk/AskingQuestions =================================================================== --- trunk/AskingQuestions (rev 0) +++ trunk/AskingQuestions 2008-02-13 17:15:47 UTC (rev 287) @@ -0,0 +1,316 @@ +Before asking any questions to me directly or scst-devel mailing list +make sure that you read *ALL* relevant documentation files (at least, 2 +README files: one for SCST and one for target driver you are using) and +*understood* *ALL* written there. I personally very much like working +with people who understand what they are doing and hate when somebody +tries to use me as a replacement of his brain and to save his time on +expense of mine. So, in such cases don't be surprised if your question +will be ignored or answered in the RTFM style. + +Particularly, I will refuse to answer on any questions about low +performance if you don't *explicitly* write in your question that you +don't use the debug build and ensured (write from what) that your target +and backstorage devices don't share the same PCI bus. + +Another too FAQ area is "What are those aborts and resets, which your +target from time to time logging, mean and what to do with them?", "Do +they relate to I/O stalls I sometimes experience" and "Why after them my +device was put offline?". + +Sorry, if the above might sound too harsh. Unfortunately, I have a +limited power and can't waste it keeping explaining basic concepts and +answering on the same questions. + +Example of a really bad question: + +====================================================================== + +In our user space driver , i use epoll_wait to wait on multiple file +descriptors for multiple devices. Apparently when i wait on the ioctl in +blocking mode , everything works well , but when i wait on epoll , and +try to attach a target device , i get immediately a "Bad address" error +value from the epoll. + +What is the reason ? + +====================================================================== + +It is bad, because, apparently, the author was doing something wrong +with epoll, but instead of checking the source code to find out when +"Bad address" error can be returned and understand possible reasons for +it, he expected me to do that for him. He even didn't bothered to look +in the kernel log, where, very probably, the reason for the error was +logged. + + +Here are three examples of good questions: + +====================================================================== + +I'm looking for a help in understanding of SCST internal architecture +and operation. The problem I'm experiencing now is that SCST seems to +process deferred commands incorrectly in some cases. More specifically, +I'm confused with the 'while' loop in scst_send_to_midlev function. + +As far as I understand, the basic execution path consists of a call to +scst_do_send_midlev followed by taking of a decision on this command +(continue with this command, reschedule it, or move to the next one), +the decision is stored in 'int res', which is then returned from the +function. + +However, if there are deferred commands on the device, the function does +not return but makes another call to scst_do_send_to_midlev, analyzes +the return code again and stores the decision in 'int res' thereby +erasing the decision for the previous command. If scst_send_to_midlev +exits now, it will return the _new_ decision (for the deferred command) +whereas the scst_process_active_cmd will think that it is the decision +for the command that was originally passed to scst_send_to_midlev. + +For example, this will cause problems in the following situation: +1. scst_send_to_midlev is called with cmd == 0x80000100 +2. scst_do_send_to_midlev is called with cmd == 0x8000100 +3. scst_do_send_to_midlev returns with SCST_EXEC_COMPLETED + (in certain scenarios the command is already destroyed at this point) +4. scst_check_deferred_commands finds the defferred cmd == 0x80000200 +5. scst_do_send_to_midlev is called with cmd == 0x80000200 +6. scst_do_send_to_midlev returns with SCST_EXEC_NEED_THREAD +7. scst_send_to_midlev returns with SCST_CMD_STATE_RES_NEED_THREAD +8. Now, the scst_process_active_cmd will try to reschedule command 0x8000100 + which is already destroyed at this point ! + +Can anyone on the list confirm my guess? Or, this situation should never +happen because of some other condition which I may have missed? Right +now I can't think of any of simple methods to work around the issue, +i.e. any of my ideas require rewriting significant part of the code. + +====================================================================== + +Hello, + +I have two machines (SCST targets) with the following parameters: +- two dual core Xeon CPUs +- QLA2342 FC HBA +- Areca SATA RAID HBA +- Linux 2.6.21.3, running in 64 bit mode with 16G RAM +- SCST trunk version + +On the client side there is a Solaris 10 U3 machine, with the same (chip +wise) Qlogic controller. + +There is an FC switch between the three machines, and each of the +targets are zoned to the client's port in a one-by-one manner, so HBA +port 1 sees only target 1 and port 2 sees only target 2. + +The targets are configured with two large sparse files on XFS (8 TB +each, with dd if=/dev/zero of=file bs=1M count=0 seek=8388608). + +In Solaris I do various tests with SVM (Sun's built in volume manager) +and multiterabyte UFS. Occasionally, there are some strange write +errors, where the volume manager drops its volumes and without a VM, a +simple UFS fs write can fail too. + +I see various errors logged by the kernel (Solaris'), these are some +examples, both with and without SVM: +Jun 21 10:42:14 solaris fctl: [ID 517869 kern.warning] WARNING: +fp(1)::GPN_ID for D_ID=621200 failed +Jun 21 10:42:14 solaris fctl: [ID 517869 kern.warning] WARNING: +fp(1)::N_x Port with D_ID=621200, PWWN=210000e08b944419 disappeared from +fabric +Jun 21 10:42:53 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 10:42:53 solaris SCSI transport failed: reason +'tran_err': retrying command +Jun 21 10:43:06 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 10:43:06 solaris SCSI transport failed: reason 'timeout': +retrying command +Jun 21 10:43:13 solaris scsi: [ID 107833 kern.notice] Device is gone +Jun 21 10:43:13 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 10:43:13 solaris transport rejected fatal error +Jun 21 10:43:13 solaris md_stripe: [ID 641072 kern.warning] WARNING: md: +d10: write error on /dev/dsk/c2t210000E08B944419d0s6 +Jun 21 10:43:13 solaris last message repeated 9 times +Jun 21 10:43:13 solaris scsi: [ID 243001 kern.info] +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0 (fcp1): +Jun 21 10:43:13 solaris offlining lun=0 (trace=0), target=621200 +(trace=2800004) +Jun 21 10:43:13 solaris ufs: [ID 702911 kern.warning] WARNING: Error +writing master during ufs log roll +Jun 21 10:43:13 solaris ufs: [ID 127457 kern.warning] WARNING: ufs log +for /mnt changed state to Error +Jun 21 10:43:13 solaris ufs: [ID 616219 kern.warning] WARNING: Please +umount(1M) /mnt and run fsck(1M) +Jun 21 11:08:55 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:08:55 solaris offline or reservation conflict +Jun 21 11:09:41 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:41 solaris offline or reservation conflict +Jun 21 11:09:41 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:41 solaris offline or reservation conflict +Jun 21 11:09:41 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:41 solaris i/o to invalid geometry +Jun 21 11:09:41 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:41 solaris offline or reservation conflict +Jun 21 11:09:41 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:41 solaris i/o to invalid geometry +Jun 21 11:09:41 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:41 solaris offline or reservation conflict +Jun 21 11:09:41 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:41 solaris i/o to invalid geometry +Jun 21 11:09:43 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:43 solaris offline or reservation conflict +Jun 21 11:09:43 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:43 solaris SYNCHRONIZE CACHE command failed (5) + +I don't see anything in the dmesg on the target side. + +After these errors SCST seems to be dead. I can't unload its modules and +can't communicate it via /proc. +A simple cat vdisk just waits and waits. + +Could you please help? What should I set/collect/send in this case to +help resolving this issue? + +====================================================================== + +Hello, + +I am trying to get scst working on an Opteron machine. + +After some hours, playing with different kernel versions and different +missing functions, I've sticked with a 2.6.15 and a +drivers/scsi/scsi_lib.c hack from 2.6.14, which contains the +scsi_wait_req. (Linux is a mess, each point release changes something. +How can developers keep up with this?) + +Now everything seems to be OK, I could load the modules and such. + +I have a setup of two machines connected to each other in an FC-P2P +manner. The two machines has two 2G links between them. On the initiator +side I have FreeBSD, because I know that better and this is what I did +some target mode tests. + +The strange thing is that the loop seems to be only running at 1 Gbps: +[ 61.731265] QLogic Fibre Channel HBA Driver +[ 61.731454] GSI 21 sharing vector 0xD1 and IRQ 21 +[ 61.731563] ACPI: PCI Interrupt 0000:06:01.0[A] -> GSI 36 (level, low) -> IRQ 21 +[ 61.731821] qla2300 0000:06:01.0: Found an ISP2312, irq 21, iobase 0xffffc200 +00014000 +[ 61.732194] qla2300 0000:06:01.0: Configuring PCI space... +[ 61.732441] qla2300 0000:06:01.0: Configure NVRAM parameters... +[ 61.816885] qla2300 0000:06:01.0: Verifying loaded RISC code... +[ 61.852177] qla2300 0000:06:01.0: Extended memory detected (512 KB)... +[ 61.852294] qla2300 0000:06:01.0: Resizing request queue depth (2048 -> 4096) +... +[ 61.852604] qla2300 0000:06:01.0: LIP reset occured (f8e8). +[ 61.852740] qla2300 0000:06:01.0: Waiting for LIP to complete... +[ 62.865911] qla2300 0000:06:01.0: LIP occured (f7f7). +[ 62.866042] qla2300 0000:06:01.0: LOOP UP detected (1 Gbps). +[ 62.866269] qla2300 0000:06:01.0: Topology - (Loop), Host Loop address 0x0 +[ 62.868285] scsi0 : qla2xxx +[ 62.868507] qla2300 0000:06:01.0: +[ 62.868507] QLogic Fibre Channel HBA Driver: 8.01.03-k +[ 62.868508] QLogic QLA2312 - +[ 62.868509] ISP2312: PCI-X (100 MHz) @ 0000:06:01.0 hdma+, host#=0, fw=3.03.18 IPX + + +I did the following: +modprobe qla2x00tgt: + +[ 104.988170] qla2x00tgt: no version for "scst_unregister" found: kernel tainted. + +echo "open lun0 /data/lun0" >/proc/scsi_tgt/disk_fileio/disk_fileio" +[ 169.102877] scst: Device handler disk_fileio for type 0 loaded successfully +[ 169.103002] scst: Device handler cdrom_fileio for type 5 loaded successfully +[ 191.261000] dev_fileio: Attached SCSI target virtual disk lun0 (file="/data/l +un0", fs=1000001MB, bs=512, nblocks=2048002048, cyln=1000001) +[ 191.261191] scst: Attached SCSI target mid-level to virtual device lun0 (id 1 +) + +and +echo "add lun0 0" > /proc/scsi_tgt/groups/Default/devices + +On the other side a camcontrol rescan all (SCSI rescan) gives me the following with a verbose logging kernel: +Mar 29 18:09:17 blade2 kernel: pass1: <SCST_FIO lun0 093> Fixed Direct Access SCSI-4 device +Mar 29 18:09:17 blade2 kernel: pass1: Serial Number 383 +Mar 29 18:09:17 blade2 kernel: pass1: 100.000MB/s transfers +Mar 29 18:09:17 blade2 kernel: da1 at isp0 bus 0 target 0 lun 0 +Mar 29 18:09:17 blade2 kernel: da1: <SCST_FIO lun0 093> Fixed Direct Access SCSI-4 device +Mar 29 18:09:17 blade2 kernel: da1: Serial Number 383 +Mar 29 18:09:17 blade2 kernel: da1: 100.000MB/s transfers +Mar 29 18:09:17 blade2 kernel: da1: 1024MB (2097152 512 byte sectors: 64H 32S/T 1024C) +Mar 29 18:09:17 blade2 kernel: (probe0:isp0:0:0:1): error 6 +Mar 29 18:09:17 blade2 kernel: (probe0:isp0:0:0:1): Unretryable Error +Mar 29 18:09:17 blade2 kernel: isp0: data overrun for command on 0.0.0 +Mar 29 18:09:17 blade2 kernel: (da1:isp0:0:0:0): Data Overrun +Mar 29 18:09:17 blade2 kernel: (da1:isp0:0:0:0): Retrying Command +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:2): error 6 +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:2): Unretryable Error +Mar 29 18:09:18 blade2 kernel: isp0: data overrun for command on 0.0.0 +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Data Overrun +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Retrying Command +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:3): error 6 +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:3): Unretryable Error +Mar 29 18:09:18 blade2 kernel: isp0: data overrun for command on 0.0.0 +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Data Overrun +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Retrying Command +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:4): error 6 +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:4): Unretryable Error +Mar 29 18:09:18 blade2 kernel: isp0: data overrun for command on 0.0.0 +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Data Overrun +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Retrying Command +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:5): error 6 +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:5): Unretryable Error +Mar 29 18:09:18 blade2 kernel: isp0: data overrun for command on 0.0.0 +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Data Overrun +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): error 5 +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Retries Exausted +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:6): error 6 +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:6): Unretryable Error +Mar 29 18:09:19 blade2 kernel: (probe0:isp0:0:0:7): error 6 +Mar 29 18:09:19 blade2 kernel: (probe0:isp0:0:0:7): Unretryable Error + + +The device is there, but I cannot use it. + +BTW, the target mode machine (Linux) runs on a dual Opteron in 64 bit +mode, with 8GB of RAM. I've lowered it with mem=800M, but the effect is +the same. + +Assuming that mixed 2.6.14-.15 kernel is the fault, could you please +tell me what version should I use, for which all of the patches will +work? + +====================================================================== + +So, as a bottom line, if you want me to be friendly, don't ask questions +answers on which you can find out yourself by a simple documentation +reading and minimal thinking effort. + +Also it is very desirable if you attach to your question full kernel log +from target since it's booted. + +Vladislav Bolkhovitin <vs...@vl...>, http://scst.sourceforge.net Added: trunk/iscsi-scst/AskingQuestions =================================================================== --- trunk/iscsi-scst/AskingQuestions (rev 0) +++ trunk/iscsi-scst/AskingQuestions 2008-02-13 17:15:47 UTC (rev 287) @@ -0,0 +1,316 @@ +Before asking any questions to me directly or scst-devel mailing list +make sure that you read *ALL* relevant documentation files (at least, 2 +README files: one for SCST and one for target driver you are using) and +*understood* *ALL* written there. I personally very much like working +with people who understand what they are doing and hate when somebody +tries to use me as a replacement of his brain and to save his time on +expense of mine. So, in such cases don't be surprised if your question +will be ignored or answered in the RTFM style. + +Particularly, I will refuse to answer on any questions about low +performance if you don't *explicitly* write in your question that you +don't use the debug build and ensured (write from what) that your target +and backstorage devices don't share the same PCI bus. + +Another too FAQ area is "What are those aborts and resets, which your +target from time to time logging, mean and what to do with them?", "Do +they relate to I/O stalls I sometimes experience" and "Why after them my +device was put offline?". + +Sorry, if the above might sound too harsh. Unfortunately, I have a +limited power and can't waste it keeping explaining basic concepts and +answering on the same questions. + +Example of a really bad question: + +====================================================================== + +In our user space driver , i use epoll_wait to wait on multiple file +descriptors for multiple devices. Apparently when i wait on the ioctl in +blocking mode , everything works well , but when i wait on epoll , and +try to attach a target device , i get immediately a "Bad address" error +value from the epoll. + +What is the reason ? + +====================================================================== + +It is bad, because, apparently, the author was doing something wrong +with epoll, but instead of checking the source code to find out when +"Bad address" error can be returned and understand possible reasons for +it, he expected me to do that for him. He even didn't bothered to look +in the kernel log, where, very probably, the reason for the error was +logged. + + +Here are three examples of good questions: + +====================================================================== + +I'm looking for a help in understanding of SCST internal architecture +and operation. The problem I'm experiencing now is that SCST seems to +process deferred commands incorrectly in some cases. More specifically, +I'm confused with the 'while' loop in scst_send_to_midlev function. + +As far as I understand, the basic execution path consists of a call to +scst_do_send_midlev followed by taking of a decision on this command +(continue with this command, reschedule it, or move to the next one), +the decision is stored in 'int res', which is then returned from the +function. + +However, if there are deferred commands on the device, the function does +not return but makes another call to scst_do_send_to_midlev, analyzes +the return code again and stores the decision in 'int res' thereby +erasing the decision for the previous command. If scst_send_to_midlev +exits now, it will return the _new_ decision (for the deferred command) +whereas the scst_process_active_cmd will think that it is the decision +for the command that was originally passed to scst_send_to_midlev. + +For example, this will cause problems in the following situation: +1. scst_send_to_midlev is called with cmd == 0x80000100 +2. scst_do_send_to_midlev is called with cmd == 0x8000100 +3. scst_do_send_to_midlev returns with SCST_EXEC_COMPLETED + (in certain scenarios the command is already destroyed at this point) +4. scst_check_deferred_commands finds the defferred cmd == 0x80000200 +5. scst_do_send_to_midlev is called with cmd == 0x80000200 +6. scst_do_send_to_midlev returns with SCST_EXEC_NEED_THREAD +7. scst_send_to_midlev returns with SCST_CMD_STATE_RES_NEED_THREAD +8. Now, the scst_process_active_cmd will try to reschedule command 0x8000100 + which is already destroyed at this point ! + +Can anyone on the list confirm my guess? Or, this situation should never +happen because of some other condition which I may have missed? Right +now I can't think of any of simple methods to work around the issue, +i.e. any of my ideas require rewriting significant part of the code. + +====================================================================== + +Hello, + +I have two machines (SCST targets) with the following parameters: +- two dual core Xeon CPUs +- QLA2342 FC HBA +- Areca SATA RAID HBA +- Linux 2.6.21.3, running in 64 bit mode with 16G RAM +- SCST trunk version + +On the client side there is a Solaris 10 U3 machine, with the same (chip +wise) Qlogic controller. + +There is an FC switch between the three machines, and each of the +targets are zoned to the client's port in a one-by-one manner, so HBA +port 1 sees only target 1 and port 2 sees only target 2. + +The targets are configured with two large sparse files on XFS (8 TB +each, with dd if=/dev/zero of=file bs=1M count=0 seek=8388608). + +In Solaris I do various tests with SVM (Sun's built in volume manager) +and multiterabyte UFS. Occasionally, there are some strange write +errors, where the volume manager drops its volumes and without a VM, a +simple UFS fs write can fail too. + +I see various errors logged by the kernel (Solaris'), these are some +examples, both with and without SVM: +Jun 21 10:42:14 solaris fctl: [ID 517869 kern.warning] WARNING: +fp(1)::GPN_ID for D_ID=621200 failed +Jun 21 10:42:14 solaris fctl: [ID 517869 kern.warning] WARNING: +fp(1)::N_x Port with D_ID=621200, PWWN=210000e08b944419 disappeared from +fabric +Jun 21 10:42:53 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 10:42:53 solaris SCSI transport failed: reason +'tran_err': retrying command +Jun 21 10:43:06 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 10:43:06 solaris SCSI transport failed: reason 'timeout': +retrying command +Jun 21 10:43:13 solaris scsi: [ID 107833 kern.notice] Device is gone +Jun 21 10:43:13 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 10:43:13 solaris transport rejected fatal error +Jun 21 10:43:13 solaris md_stripe: [ID 641072 kern.warning] WARNING: md: +d10: write error on /dev/dsk/c2t210000E08B944419d0s6 +Jun 21 10:43:13 solaris last message repeated 9 times +Jun 21 10:43:13 solaris scsi: [ID 243001 kern.info] +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0 (fcp1): +Jun 21 10:43:13 solaris offlining lun=0 (trace=0), target=621200 +(trace=2800004) +Jun 21 10:43:13 solaris ufs: [ID 702911 kern.warning] WARNING: Error +writing master during ufs log roll +Jun 21 10:43:13 solaris ufs: [ID 127457 kern.warning] WARNING: ufs log +for /mnt changed state to Error +Jun 21 10:43:13 solaris ufs: [ID 616219 kern.warning] WARNING: Please +umount(1M) /mnt and run fsck(1M) +Jun 21 11:08:55 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:08:55 solaris offline or reservation conflict +Jun 21 11:09:41 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:41 solaris offline or reservation conflict +Jun 21 11:09:41 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:41 solaris offline or reservation conflict +Jun 21 11:09:41 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:41 solaris i/o to invalid geometry +Jun 21 11:09:41 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:41 solaris offline or reservation conflict +Jun 21 11:09:41 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:41 solaris i/o to invalid geometry +Jun 21 11:09:41 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:41 solaris offline or reservation conflict +Jun 21 11:09:41 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:41 solaris i/o to invalid geometry +Jun 21 11:09:43 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:43 solaris offline or reservation conflict +Jun 21 11:09:43 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:43 solaris SYNCHRONIZE CACHE command failed (5) + +I don't see anything in the dmesg on the target side. + +After these errors SCST seems to be dead. I can't unload its modules and +can't communicate it via /proc. +A simple cat vdisk just waits and waits. + +Could you please help? What should I set/collect/send in this case to +help resolving this issue? + +====================================================================== + +Hello, + +I am trying to get scst working on an Opteron machine. + +After some hours, playing with different kernel versions and different +missing functions, I've sticked with a 2.6.15 and a +drivers/scsi/scsi_lib.c hack from 2.6.14, which contains the +scsi_wait_req. (Linux is a mess, each point release changes something. +How can developers keep up with this?) + +Now everything seems to be OK, I could load the modules and such. + +I have a setup of two machines connected to each other in an FC-P2P +manner. The two machines has two 2G links between them. On the initiator +side I have FreeBSD, because I know that better and this is what I did +some target mode tests. + +The strange thing is that the loop seems to be only running at 1 Gbps: +[ 61.731265] QLogic Fibre Channel HBA Driver +[ 61.731454] GSI 21 sharing vector 0xD1 and IRQ 21 +[ 61.731563] ACPI: PCI Interrupt 0000:06:01.0[A] -> GSI 36 (level, low) -> IRQ 21 +[ 61.731821] qla2300 0000:06:01.0: Found an ISP2312, irq 21, iobase 0xffffc200 +00014000 +[ 61.732194] qla2300 0000:06:01.0: Configuring PCI space... +[ 61.732441] qla2300 0000:06:01.0: Configure NVRAM parameters... +[ 61.816885] qla2300 0000:06:01.0: Verifying loaded RISC code... +[ 61.852177] qla2300 0000:06:01.0: Extended memory detected (512 KB)... +[ 61.852294] qla2300 0000:06:01.0: Resizing request queue depth (2048 -> 4096) +... +[ 61.852604] qla2300 0000:06:01.0: LIP reset occured (f8e8). +[ 61.852740] qla2300 0000:06:01.0: Waiting for LIP to complete... +[ 62.865911] qla2300 0000:06:01.0: LIP occured (f7f7). +[ 62.866042] qla2300 0000:06:01.0: LOOP UP detected (1 Gbps). +[ 62.866269] qla2300 0000:06:01.0: Topology - (Loop), Host Loop address 0x0 +[ 62.868285] scsi0 : qla2xxx +[ 62.868507] qla2300 0000:06:01.0: +[ 62.868507] QLogic Fibre Channel HBA Driver: 8.01.03-k +[ 62.868508] QLogic QLA2312 - +[ 62.868509] ISP2312: PCI-X (100 MHz) @ 0000:06:01.0 hdma+, host#=0, fw=3.03.18 IPX + + +I did the following: +modprobe qla2x00tgt: + +[ 104.988170] qla2x00tgt: no version for "scst_unregister" found: kernel tainted. + +echo "open lun0 /data/lun0" >/proc/scsi_tgt/disk_fileio/disk_fileio" +[ 169.102877] scst: Device handler disk_fileio for type 0 loaded successfully +[ 169.103002] scst: Device handler cdrom_fileio for type 5 loaded successfully +[ 191.261000] dev_fileio: Attached SCSI target virtual disk lun0 (file="/data/l +un0", fs=1000001MB, bs=512, nblocks=2048002048, cyln=1000001) +[ 191.261191] scst: Attached SCSI target mid-level to virtual device lun0 (id 1 +) + +and +echo "add lun0 0" > /proc/scsi_tgt/groups/Default/devices + +On the other side a camcontrol rescan all (SCSI rescan) gives me the following with a verbose logging kernel: +Mar 29 18:09:17 blade2 kernel: pass1: <SCST_FIO lun0 093> Fixed Direct Access SCSI-4 device +Mar 29 18:09:17 blade2 kernel: pass1: Serial Number 383 +Mar 29 18:09:17 blade2 kernel: pass1: 100.000MB/s transfers +Mar 29 18:09:17 blade2 kernel: da1 at isp0 bus 0 target 0 lun 0 +Mar 29 18:09:17 blade2 kernel: da1: <SCST_FIO lun0 093> Fixed Direct Access SCSI-4 device +Mar 29 18:09:17 blade2 kernel: da1: Serial Number 383 +Mar 29 18:09:17 blade2 kernel: da1: 100.000MB/s transfers +Mar 29 18:09:17 blade2 kernel: da1: 1024MB (2097152 512 byte sectors: 64H 32S/T 1024C) +Mar 29 18:09:17 blade2 kernel: (probe0:isp0:0:0:1): error 6 +Mar 29 18:09:17 blade2 kernel: (probe0:isp0:0:0:1): Unretryable Error +Mar 29 18:09:17 blade2 kernel: isp0: data overrun for command on 0.0.0 +Mar 29 18:09:17 blade2 kernel: (da1:isp0:0:0:0): Data Overrun +Mar 29 18:09:17 blade2 kernel: (da1:isp0:0:0:0): Retrying Command +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:2): error 6 +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:2): Unretryable Error +Mar 29 18:09:18 blade2 kernel: isp0: data overrun for command on 0.0.0 +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Data Overrun +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Retrying Command +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:3): error 6 +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:3): Unretryable Error +Mar 29 18:09:18 blade2 kernel: isp0: data overrun for command on 0.0.0 +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Data Overrun +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Retrying Command +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:4): error 6 +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:4): Unretryable Error +Mar 29 18:09:18 blade2 kernel: isp0: data overrun for command on 0.0.0 +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Data Overrun +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Retrying Command +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:5): error 6 +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:5): Unretryable Error +Mar 29 18:09:18 blade2 kernel: isp0: data overrun for command on 0.0.0 +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Data Overrun +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): error 5 +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Retries Exausted +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:6): error 6 +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:6): Unretryable Error +Mar 29 18:09:19 blade2 kernel: (probe0:isp0:0:0:7): error 6 +Mar 29 18:09:19 blade2 kernel: (probe0:isp0:0:0:7): Unretryable Error + + +The device is there, but I cannot use it. + +BTW, the target mode machine (Linux) runs on a dual Opteron in 64 bit +mode, with 8GB of RAM. I've lowered it with mem=800M, but the effect is +the same. + +Assuming that mixed 2.6.14-.15 kernel is the fault, could you please +tell me what version should I use, for which all of the patches will +work? + +====================================================================== + +So, as a bottom line, if you want me to be friendly, don't ask questions +answers on which you can find out yourself by a simple documentation +reading and minimal thinking effort. + +Also it is very desirable if you attach to your question full kernel log +from target since it's booted. + +Vladislav Bolkhovitin <vs...@vl...>, http://scst.sourceforge.net Modified: trunk/iscsi-scst/README =================================================================== --- trunk/iscsi-scst/README 2008-02-13 16:28:35 UTC (rev 286) +++ trunk/iscsi-scst/README 2008-02-13 17:15:47 UTC (rev 287) @@ -111,8 +111,9 @@ If under high load you experience I/O stalls or see in the kernel log abort or reset messages, then try to reduce QueuedCommands parameter in -iscsi-scstd.conf file for the corresponding target. See also SCST README -file for more details about that issue. +iscsi-scstd.conf file for the corresponding target to some lower value, +like 8 (default is 32). See also SCST README file for more details about +that issue. Sometimes, when there are communication problems with initiator(s), shutting down iSCSI-SCST can take very long time, up to about 10 Modified: trunk/iscsi-scst/include/iscsi_u.h =================================================================== --- trunk/iscsi-scst/include/iscsi_u.h 2008-02-13 16:28:35 UTC (rev 286) +++ trunk/iscsi-scst/include/iscsi_u.h 2008-02-13 17:15:47 UTC (rev 287) @@ -20,7 +20,7 @@ #include <sys/uio.h> #endif -#define ISCSI_VERSION_STRING "0.9.6/0.4.15r145" +#define ISCSI_VERSION_STRING "0.9.6/0.4.15r147" /* The maximum length of 223 bytes in the RFC. */ #define ISCSI_NAME_LEN 256 Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2008-02-13 16:28:35 UTC (rev 286) +++ trunk/iscsi-scst/kernel/iscsi.c 2008-02-13 17:15:47 UTC (rev 287) @@ -454,12 +454,14 @@ static inline struct iscsi_cmnd *get_rsp_cmnd(struct iscsi_cmnd *req) { - struct iscsi_cmnd *res; + struct iscsi_cmnd *res = NULL; /* Currently this lock isn't needed, but just in case.. */ spin_lock_bh(&req->rsp_cmd_lock); - res = list_entry(req->rsp_cmd_list.prev, struct iscsi_cmnd, - rsp_cmd_list_entry); + if (!list_empty(&req->rsp_cmd_list)) { + res = list_entry(req->rsp_cmd_list.prev, struct iscsi_cmnd, + rsp_cmd_list_entry); + } spin_unlock_bh(&req->rsp_cmd_lock); return res; @@ -472,6 +474,8 @@ struct iscsi_conn *conn = rsp->conn; struct list_head *pos, *next; + sBUG_ON(list_empty(send)); + /* * If we don't remove hashed req cmd from the hash list here, before * submitting it for transmittion, we will have a race, when for @@ -618,8 +622,8 @@ rsp_hdr->cmd_status = status; rsp_hdr->itt = cmnd_hdr(req)->itt; - if (status == SAM_STAT_CHECK_CONDITION) { - TRACE_DBG("%s", "CHECK_CONDITION"); + if (SCST_SENSE_VALID(sense_buf)) { + TRACE_DBG("%s", "SENSE VALID"); /* ToDo: __GFP_NOFAIL ?? */ sg = rsp->sg = scst_alloc(PAGE_SIZE, GFP_KERNEL|__GFP_NOFAIL, &rsp->sg_cnt); @@ -920,12 +924,13 @@ TRACE_DBG("%p", req); rsp = get_rsp_cmnd(req); + if (rsp == NULL) + goto skip; + rsp_hdr = (struct iscsi_scsi_rsp_hdr *)&rsp->pdu.bhs; - if (unlikely(cmnd_opcode(rsp) != ISCSI_OP_SCSI_RSP)) { - PRINT_ERROR("Unexpected response command %u", cmnd_opcode(rsp)); - return; - } + sBUG_ON(cmnd_opcode(rsp) != ISCSI_OP_SCSI_RSP); + size = cmnd_write_size(req); if (size) { rsp_hdr->flags |= ISCSI_FLG_RESIDUAL_UNDERFLOW; @@ -941,6 +946,8 @@ rsp_hdr->residual_count = cpu_to_be32(size); } } + +skip: req->pdu.bhs.opcode = (req->pdu.bhs.opcode & ~ISCSI_OPCODE_MASK) | ISCSI_OP_SCSI_REJECT; @@ -1285,7 +1292,6 @@ if (unlikely(req->scst_state != ISCSI_CMD_STATE_AFTER_PREPROC)) { TRACE_DBG("req %p is in %x state", req, req->scst_state); if (req->scst_state == ISCSI_CMD_STATE_PROCESSED) { - /* Response is already prepared */ cmnd_prepare_skip_pdu_set_resid(req); goto out; } @@ -1437,7 +1443,8 @@ iscsi_extracheck_is_rd_thread(cmnd->conn); - if (!(cmnd->conn->ddigest_type & DIGEST_NONE)) { + if (!(cmnd->conn->ddigest_type & DIGEST_NONE) && + !cmnd->ddigest_checked) { cmd_add_on_rx_ddigest_list(req, cmnd); cmnd_get(cmnd); } @@ -1900,12 +1907,16 @@ logout_exec(cmnd); break; case ISCSI_OP_SCSI_REJECT: - TRACE_MGMT_DBG("REJECT cmnd %p (scst_cmd %p)", cmnd, - cmnd->scst_cmd); - iscsi_cmnd_init_write(get_rsp_cmnd(cmnd), - ISCSI_INIT_WRITE_REMOVE_HASH | ISCSI_INIT_WRITE_WAKE); + { + struct iscsi_cmnd *rsp = get_rsp_cmnd(cmnd); + TRACE_MGMT_DBG("REJECT cmnd %p (scst_cmd %p), rsp %p", cmnd, + cmnd->scst_cmd, rsp); + if (rsp != NULL) + iscsi_cmnd_init_write(rsp, ISCSI_INIT_WRITE_REMOVE_HASH | + ISCSI_INIT_WRITE_WAKE); req_cmnd_release(cmnd); break; + } default: PRINT_ERROR("unexpected cmnd op %x", cmnd_opcode(cmnd)); req_cmnd_release(cmnd); @@ -2281,10 +2292,14 @@ data_out_end(cmnd); break; case ISCSI_OP_PDU_REJECT: - iscsi_cmnd_init_write(get_rsp_cmnd(cmnd), - ISCSI_INIT_WRITE_REMOVE_HASH | ISCSI_INIT_WRITE_WAKE); + { + struct iscsi_cmnd *rsp = get_rsp_cmnd(cmnd); + if (rsp != NULL) + iscsi_cmnd_init_write(rsp, ISCSI_INIT_WRITE_REMOVE_HASH | + ISCSI_INIT_WRITE_WAKE); req_cmnd_release(cmnd); break; + } case ISCSI_OP_DATA_REJECT: req_cmnd_release(cmnd); break; Modified: trunk/iscsi-scst/kernel/iscsi.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi.h 2008-02-13 16:28:35 UTC (rev 286) +++ trunk/iscsi-scst/kernel/iscsi.h 2008-02-13 17:15:47 UTC (rev 287) @@ -237,6 +237,7 @@ unsigned int data_waiting:1; unsigned int force_cleanup_done:1; unsigned int dec_active_cmnds:1; + unsigned int ddigest_checked:1; #ifdef EXTRACHECKS unsigned int on_rx_digest_list:1; unsigned int release_called:1; Modified: trunk/iscsi-scst/kernel/nthread.c =================================================================== --- trunk/iscsi-scst/kernel/nthread.c 2008-02-13 16:28:35 UTC (rev 286) +++ trunk/iscsi-scst/kernel/nthread.c 2008-02-13 17:15:47 UTC (rev 287) @@ -622,7 +622,17 @@ break; case RX_CHECK_DDIGEST: conn->read_state = RX_END; - if (cmnd_opcode(cmnd) == ISCSI_OP_SCSI_CMD) { + if (cmnd->pdu.datasize <= 16*1024) { + /* It's cache hot, so let's compute it inline */ + TRACE_DBG("cmnd %p, opcode %x: checking RX " + "ddigest inline", cmnd, cmnd_opcode(cmnd)); + cmnd->ddigest_checked = 1; + rc = digest_rx_data(cmnd); + if (unlikely(rc != 0)) { + mark_conn_closed(conn); + goto out; + } + } else if (cmnd_opcode(cmnd) == ISCSI_OP_SCSI_CMD) { cmd_add_on_rx_ddigest_list(cmnd, cmnd); cmnd_get(cmnd); } else if (cmnd_opcode(cmnd) != ISCSI_OP_SCSI_DATA_OUT) { @@ -631,12 +641,12 @@ * specify how to deal with digest errors in this case. * Is closing connection correct? */ - TRACE_DBG("cmnd %p, opcode %x: checking RX " - "ddigest inline", cmnd, cmnd_opcode(cmnd)); + TRACE_DBG("cmnd %p, opcode %x: checking NOP RX " + "ddigest", cmnd, cmnd_opcode(cmnd)); rc = digest_rx_data(cmnd); if (unlikely(rc != 0)) { - conn->read_state = RX_CHECK_DDIGEST; mark_conn_closed(conn); + goto out; } } break; Modified: trunk/mpt/mpt_scst.c =================================================================== --- trunk/mpt/mpt_scst.c 2008-02-13 16:28:35 UTC (rev 286) +++ trunk/mpt/mpt_scst.c 2008-02-13 17:15:47 UTC (rev 287) @@ -1611,7 +1611,7 @@ TRACE_DBG("rq_result=%x, resp_flags=%x, %x, %d", prm.rq_result, resp_flags, prm.bufflen, prm.sense_buffer_len); - if (prm.rq_result != 0) + if ((prm.rq_result != 0) && (prm.sense_buffer != NULL)) TRACE_BUFFER("Sense", prm.sense_buffer, prm.sense_buffer_len); if ((resp_flags & SCST_TSC_FLAG_STATUS) == 0) { Added: trunk/qla2x00t/qla2x00-target/AskingQuestions =================================================================== --- trunk/qla2x00t/qla2x00-target/AskingQuestions (rev 0) +++ trunk/qla2x00t/qla2x00-target/AskingQuestions 2008-02-13 17:15:47 UTC (rev 287) @@ -0,0 +1,316 @@ +Before asking any questions to me directly or scst-devel mailing list +make sure that you read *ALL* relevant documentation files (at least, 2 +README files: one for SCST and one for target driver you are using) and +*understood* *ALL* written there. I personally very much like working +with people who understand what they are doing and hate when somebody +tries to use me as a replacement of his brain and to save his time on +expense of mine. So, in such cases don't be surprised if your question +will be ignored or answered in the RTFM style. + +Particularly, I will refuse to answer on any questions about low +performance if you don't *explicitly* write in your question that you +don't use the debug build and ensured (write from what) that your target +and backstorage devices don't share the same PCI bus. + +Another too FAQ area is "What are those aborts and resets, which your +target from time to time logging, mean and what to do with them?", "Do +they relate to I/O stalls I sometimes experience" and "Why after them my +device was put offline?". + +Sorry, if the above might sound too harsh. Unfortunately, I have a +limited power and can't waste it keeping explaining basic concepts and +answering on the same questions. + +Example of a really bad question: + +====================================================================== + +In our user space driver , i use epoll_wait to wait on multiple file +descriptors for multiple devices. Apparently when i wait on the ioctl in +blocking mode , everything works well , but when i wait on epoll , and +try to attach a target device , i get immediately a "Bad address" error +value from the epoll. + +What is the reason ? + +====================================================================== + +It is bad, because, apparently, the author was doing something wrong +with epoll, but instead of checking the source code to find out when +"Bad address" error can be returned and understand possible reasons for +it, he expected me to do that for him. He even didn't bothered to look +in the kernel log, where, very probably, the reason for the error was +logged. + + +Here are three examples of good questions: + +====================================================================== + +I'm looking for a help in understanding of SCST internal architecture +and operation. The problem I'm experiencing now is that SCST seems to +process deferred commands incorrectly in some cases. More specifically, +I'm confused with the 'while' loop in scst_send_to_midlev function. + +As far as I understand, the basic execution path consists of a call to +scst_do_send_midlev followed by taking of a decision on this command +(continue with this command, reschedule it, or move to the next one), +the decision is stored in 'int res', which is then returned from the +function. + +However, if there are deferred commands on the device, the function does +not return but makes another call to scst_do_send_to_midlev, analyzes +the return code again and stores the decision in 'int res' thereby +erasing the decision for the previous command. If scst_send_to_midlev +exits now, it will return the _new_ decision (for the deferred command) +whereas the scst_process_active_cmd will think that it is the decision +for the command that was originally passed to scst_send_to_midlev. + +For example, this will cause problems in the following situation: +1. scst_send_to_midlev is called with cmd == 0x80000100 +2. scst_do_send_to_midlev is called with cmd == 0x8000100 +3. scst_do_send_to_midlev returns with SCST_EXEC_COMPLETED + (in certain scenarios the command is already destroyed at this point) +4. scst_check_deferred_commands finds the defferred cmd == 0x80000200 +5. scst_do_send_to_midlev is called with cmd == 0x80000200 +6. scst_do_send_to_midlev returns with SCST_EXEC_NEED_THREAD +7. scst_send_to_midlev returns with SCST_CMD_STATE_RES_NEED_THREAD +8. Now, the scst_process_active_cmd will try to reschedule command 0x8000100 + which is already destroyed at this point ! + +Can anyone on the list confirm my guess? Or, this situation should never +happen because of some other condition which I may have missed? Right +now I can't think of any of simple methods to work around the issue, +i.e. any of my ideas require rewriting significant part of the code. + +====================================================================== + +Hello, + +I have two machines (SCST targets) with the following parameters: +- two dual core Xeon CPUs +- QLA2342 FC HBA +- Areca SATA RAID HBA +- Linux 2.6.21.3, running in 64 bit mode with 16G RAM +- SCST trunk version + +On the client side there is a Solaris 10 U3 machine, with the same (chip +wise) Qlogic controller. + +There is an FC switch between the three machines, and each of the +targets are zoned to the client's port in a one-by-one manner, so HBA +port 1 sees only target 1 and port 2 sees only target 2. + +The targets are configured with two large sparse files on XFS (8 TB +each, with dd if=/dev/zero of=file bs=1M count=0 seek=8388608). + +In Solaris I do various tests with SVM (Sun's built in volume manager) +and multiterabyte UFS. Occasionally, there are some strange write +errors, where the volume manager drops its volumes and without a VM, a +simple UFS fs write can fail too. + +I see various errors logged by the kernel (Solaris'), these are some +examples, both with and without SVM: +Jun 21 10:42:14 solaris fctl: [ID 517869 kern.warning] WARNING: +fp(1)::GPN_ID for D_ID=621200 failed +Jun 21 10:42:14 solaris fctl: [ID 517869 kern.warning] WARNING: +fp(1)::N_x Port with D_ID=621200, PWWN=210000e08b944419 disappeared from +fabric +Jun 21 10:42:53 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 10:42:53 solaris SCSI transport failed: reason +'tran_err': retrying command +Jun 21 10:43:06 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 10:43:06 solaris SCSI transport failed: reason 'timeout': +retrying command +Jun 21 10:43:13 solaris scsi: [ID 107833 kern.notice] Device is gone +Jun 21 10:43:13 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 10:43:13 solaris transport rejected fatal error +Jun 21 10:43:13 solaris md_stripe: [ID 641072 kern.warning] WARNING: md: +d10: write error on /dev/dsk/c2t210000E08B944419d0s6 +Jun 21 10:43:13 solaris last message repeated 9 times +Jun 21 10:43:13 solaris scsi: [ID 243001 kern.info] +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0 (fcp1): +Jun 21 10:43:13 solaris offlining lun=0 (trace=0), target=621200 +(trace=2800004) +Jun 21 10:43:13 solaris ufs: [ID 702911 kern.warning] WARNING: Error +writing master during ufs log roll +Jun 21 10:43:13 solaris ufs: [ID 127457 kern.warning] WARNING: ufs log +for /mnt changed state to Error +Jun 21 10:43:13 solaris ufs: [ID 616219 kern.warning] WARNING: Please +umount(1M) /mnt and run fsck(1M) +Jun 21 11:08:55 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:08:55 solaris offline or reservation conflict +Jun 21 11:09:41 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:41 solaris offline or reservation conflict +Jun 21 11:09:41 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:41 solaris offline or reservation conflict +Jun 21 11:09:41 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:41 solaris i/o to invalid geometry +Jun 21 11:09:41 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:41 solaris offline or reservation conflict +Jun 21 11:09:41 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:41 solaris i/o to invalid geometry +Jun 21 11:09:41 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:41 solaris offline or reservation conflict +Jun 21 11:09:41 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:41 solaris i/o to invalid geometry +Jun 21 11:09:43 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:43 solaris offline or reservation conflict +Jun 21 11:09:43 solaris scsi: [ID 107833 kern.warning] WARNING: +/pci@1,0/pci1022,7450@a/pcie11,105@1,1/fp@0,0/disk@w210000e08b944419,0 +(sd1): +Jun 21 11:09:43 solaris SYNCHRONIZE CACHE command failed (5) + +I don't see anything in the dmesg on the target side. + +After these errors SCST seems to be dead. I can't unload its modules and +can't communicate it via /proc. +A simple cat vdisk just waits and waits. + +Could you please help? What should I set/collect/send in this case to +help resolving this issue? + +====================================================================== + +Hello, + +I am trying to get scst working on an Opteron machine. + +After some hours, playing with different kernel versions and different +missing functions, I've sticked with a 2.6.15 and a +drivers/scsi/scsi_lib.c hack from 2.6.14, which contains the +scsi_wait_req. (Linux is a mess, each point release changes something. +How can developers keep up with this?) + +Now everything seems to be OK, I could load the modules and such. + +I have a setup of two machines connected to each other in an FC-P2P +manner. The two machines has two 2G links between them. On the initiator +side I have FreeBSD, because I know that better and this is what I did +some target mode tests. + +The strange thing is that the loop seems to be only running at 1 Gbps: +[ 61.731265] QLogic Fibre Channel HBA Driver +[ 61.731454] GSI 21 sharing vector 0xD1 and IRQ 21 +[ 61.731563] ACPI: PCI Interrupt 0000:06:01.0[A] -> GSI 36 (level, low) -> IRQ 21 +[ 61.731821] qla2300 0000:06:01.0: Found an ISP2312, irq 21, iobase 0xffffc200 +00014000 +[ 61.732194] qla2300 0000:06:01.0: Configuring PCI space... +[ 61.732441] qla2300 0000:06:01.0: Configure NVRAM parameters... +[ 61.816885] qla2300 0000:06:01.0: Verifying loaded RISC code... +[ 61.852177] qla2300 0000:06:01.0: Extended memory detected (512 KB)... +[ 61.852294] qla2300 0000:06:01.0: Resizing request queue depth (2048 -> 4096) +... +[ 61.852604] qla2300 0000:06:01.0: LIP reset occured (f8e8). +[ 61.852740] qla2300 0000:06:01.0: Waiting for LIP to complete... +[ 62.865911] qla2300 0000:06:01.0: LIP occured (f7f7). +[ 62.866042] qla2300 0000:06:01.0: LOOP UP detected (1 Gbps). +[ 62.866269] qla2300 0000:06:01.0: Topology - (Loop), Host Loop address 0x0 +[ 62.868285] scsi0 : qla2xxx +[ 62.868507] qla2300 0000:06:01.0: +[ 62.868507] QLogic Fibre Channel HBA Driver: 8.01.03-k +[ 62.868508] QLogic QLA2312 - +[ 62.868509] ISP2312: PCI-X (100 MHz) @ 0000:06:01.0 hdma+, host#=0, fw=3.03.18 IPX + + +I did the following: +modprobe qla2x00tgt: + +[ 104.988170] qla2x00tgt: no version for "scst_unregister" found: kernel tainted. + +echo "open lun0 /data/lun0" >/proc/scsi_tgt/disk_fileio/disk_fileio" +[ 169.102877] scst: Device handler disk_fileio for type 0 loaded successfully +[ 169.103002] scst: Device handler cdrom_fileio for type 5 loaded successfully +[ 191.261000] dev_fileio: Attached SCSI target virtual disk lun0 (file="/data/l +un0", fs=1000001MB, bs=512, nblocks=2048002048, cyln=1000001) +[ 191.261191] scst: Attached SCSI target mid-level to virtual device lun0 (id 1 +) + +and +echo "add lun0 0" > /proc/scsi_tgt/groups/Default/devices + +On the other side a camcontrol rescan all (SCSI rescan) gives me the following with a verbose logging kernel: +Mar 29 18:09:17 blade2 kernel: pass1: <SCST_FIO lun0 093> Fixed Direct Access SCSI-4 device +Mar 29 18:09:17 blade2 kernel: pass1: Serial Number 383 +Mar 29 18:09:17 blade2 kernel: pass1: 100.000MB/s transfers +Mar 29 18:09:17 blade2 kernel: da1 at isp0 bus 0 target 0 lun 0 +Mar 29 18:09:17 blade2 kernel: da1: <SCST_FIO lun0 093> Fixed Direct Access SCSI-4 device +Mar 29 18:09:17 blade2 kernel: da1: Serial Number 383 +Mar 29 18:09:17 blade2 kernel: da1: 100.000MB/s transfers +Mar 29 18:09:17 blade2 kernel: da1: 1024MB (2097152 512 byte sectors: 64H 32S/T 1024C) +Mar 29 18:09:17 blade2 kernel: (probe0:isp0:0:0:1): error 6 +Mar 29 18:09:17 blade2 kernel: (probe0:isp0:0:0:1): Unretryable Error +Mar 29 18:09:17 blade2 kernel: isp0: data overrun for command on 0.0.0 +Mar 29 18:09:17 blade2 kernel: (da1:isp0:0:0:0): Data Overrun +Mar 29 18:09:17 blade2 kernel: (da1:isp0:0:0:0): Retrying Command +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:2): error 6 +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:2): Unretryable Error +Mar 29 18:09:18 blade2 kernel: isp0: data overrun for command on 0.0.0 +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Data Overrun +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Retrying Command +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:3): error 6 +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:3): Unretryable Error +Mar 29 18:09:18 blade2 kernel: isp0: data overrun for command on 0.0.0 +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Data Overrun +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Retrying Command +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:4): error 6 +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:4): Unretryable Error +Mar 29 18:09:18 blade2 kernel: isp0: data overrun for command on 0.0.0 +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Data Overrun +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Retrying Command +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:5): error 6 +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:5): Unretryable Error +Mar 29 18:09:18 blade2 kernel: isp0: data overrun for command on 0.0.0 +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Data Overrun +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): error 5 +Mar 29 18:09:18 blade2 kernel: (da1:isp0:0:0:0): Retries Exausted +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:6): error 6 +Mar 29 18:09:18 blade2 kernel: (probe0:isp0:0:0:6): Unretryable Error +Mar 29 18:09:19 blade2 kernel: (probe0:isp0:0:0:7): error 6 +Mar 29 18:09:19 blade2 kernel: (probe0:isp0:0:0:7): Unretryable Error + + +The device is there, but I cannot use it. + +BTW, the target mode machine (Linux) runs on a dual Opteron in 64 bit +mode, with 8GB of RAM. I've lowered it with mem=800M, but the effect is +the same. + +Assuming that mixed 2.6.14-.15 kernel is the fault, could you please +tell me what version should I use, for which all of the patches will +work? + +====================================================================== + +So, as a bottom line, if you want me to be friendly, don't ask questions +answers on which you can find out yourself by a simple documentation +reading and minimal thinking effort. + +Also it is very desirable if you attach to your question full kernel log +from target since it's booted. + +Vladislav Bolkhovitin <vs...@vl...>, http://scst.sourceforge.net Modified: trunk/qla2x00t/qla_init.c =================================================================== --- trunk/qla2x00t/qla_init.c 2008-02-13 16:28:35 UTC (rev 286) +++ trunk/qla2x00t/qla_init.c 2008-02-13 17:15:47 UTC (rev 287) @@ -4135,8 +4135,9 @@ ENTER(__func__); - if ((tgt_data == NULL) || (tgt_data->magic != QLA2X_TARGET_MAGIC)) - { + if ((tgt_data == NULL) || (tgt_data->magic != QLA2X_TARGET_MAGIC)) { + printk("***ERROR*** Wrong version of the target driver: %d\n", + tgt_data->magic); res = -EINVAL; goto out; } Added: trunk/scst/AskingQuestions =================================================================== --- trunk/scst/AskingQuestions (rev 0) +++ trunk/scst/AskingQuestions 2008-02-13 17:15:47 UTC (rev 287) @@ -0,0 +1,316 @@ +Before asking any questions to me directly or scst-devel mailing list +make sure that you read *ALL* relevant documentation files (at least, 2 +README files: one for SCST and one for target driver you are using) and +*understood* *ALL* written there. I personally very much like working +with people who understand what they are doing and hate when somebody +tries to use me as a replacement of his brain and to save his time on +expense of mine. So, in such cases don't be surprised if your question +will be ignored or answered in the RTFM style. + +Particularly, I will refuse to answer on any questions about low +performance if you don't *explicitly* write in your question that you +don't use the debug build and ensured (write from what) that your target +and backstorage devices don't share the same PCI bus. + +Another too FAQ area is "What are those aborts and resets, which your +target from time to time logging, mean and what to do with them?", "Do +they relate to I/O stalls I sometimes experience" and "Why after them my +device was put offline?". + +Sorry, if the above might sound too harsh. Unfortunately, I have a +limited power and can't waste it keeping explaining basic concepts and +answering on the same questions. + +Example of a really bad question: + +====================================================================== + +In our user space driver , i use epoll_wait to wait on multiple file +descriptors for multiple devices. Apparently when i wait on the ioctl in +blocking mode , everything works well , but when i wait on epoll , and +try to attach a target device , i get immediately a "Bad address" error +value from the epoll. + +What is the reason ? + +====================================================================== + +It is bad, because, apparently, the author was doing something wrong +with epoll, but instead of checking the source code to find out when +"Bad address" error can be returned and understand possible reasons for +it, he expected me to do that for him. He even didn't bothered to look +in the kernel log, where, very probably, the reason for the error was +logged. + + +Here are three examples of good questions: + +====================================================================== + +I'm looking for a help in understanding of SCST internal architecture +and operation. The problem I'm experiencing now is that SCST seems to +process deferred commands incorrectly in some cases. More specifically, +I'm confused with the 'while' loop in scst_send_to_midlev function. + +As far as I understand, the basic execution path consists of a call to +scst_do_send_midlev followed by taking of a decision on this command +(continue with this command, reschedule it, or move to the next one), +the decision is stored in 'int res', which is then returned from the +function. + +However, if there are deferred commands on the device, the function does +not return but makes another call to scst_do_send_to_midlev, analyzes +the return code again and stores the decision in 'int res' thereby +erasing the decision for the previous command. If scst_send_to_midlev +exits now, it will return the _new_ decision (for the deferred command) +whereas the scst_process_active_cmd will think that it... [truncated message content] |