Merge trunk r6221 into iser branch

git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/iser@6222 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Bart Van Assche
2015-06-09 00:32:21 +00:00
parent 025574018e
commit 74e73e3694
215 changed files with 35846 additions and 10291 deletions
+59 -5
View File
@@ -1,8 +1,8 @@
#
# Common makefile for SCSI target mid-level and its drivers
#
# Copyright (C) 2004 - 2014 Vladislav Bolkhovitin <vst@vlnb.net>
# Copyright (C) 2007 - 2014 Fusion-io, Inc.
# Copyright (C) 2004 - 2015 Vladislav Bolkhovitin <vst@vlnb.net>
# Copyright (C) 2007 - 2015 SanDisk Corporation
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@@ -50,6 +50,7 @@ SRP_DIR=srpt
SCST_LOCAL_DIR=scst_local
MVSAS_DIR=mvsas_tgt
FCST_DIR=fcst
EMULEX_DIR=emulex
ISCSI_DIR=iscsi-scst
@@ -94,6 +95,12 @@ help:
@echo " iscsi_install : ISCSI target: install"
@echo " iscsi_uninstall : ISCSI target: uninstall"
@echo ""
@echo " emulex : make Emulex target"
@echo " emulex_clean : Emulex target: clean "
@echo " emulex_extraclean : Emulex target: clean + clean dependencies"
@echo " emulex_install : Emulex target: install"
@echo " emulex_uninstall : Emulex target: uninstall"
@echo ""
@echo " lsi : make LSI MPT target"
@echo " lsi_clean : lsi target: clean "
@echo " lsi_extraclean : lsi target: clean + clean dependencies"
@@ -148,6 +155,7 @@ all:
@if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi
@if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi
@if [ -d $(SCST_LOCAL_DIR) ]; then cd $(SCST_LOCAL_DIR) && $(MAKE) $@; fi
@if [ -d $(EMULEX_DIR) ]; then cd $(EMULEX_DIR) && $(MAKE) $@; fi
install:
cd $(SCST_DIR) && $(MAKE) $@
@@ -159,6 +167,7 @@ install:
@if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi
@if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi
@if [ -d $(SCST_LOCAL_DIR) ]; then cd $(SCST_LOCAL_DIR) && $(MAKE) $@; fi
@if [ -d $(EMULEX_DIR) ]; then cd $(EMULEX_DIR) && $(MAKE) $@; fi
uninstall:
cd $(SCST_DIR) && $(MAKE) $@
@@ -170,6 +179,7 @@ uninstall:
@if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi
@if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi
@if [ -d $(SCST_LOCAL_DIR) ]; then cd $(SCST_LOCAL_DIR) && $(MAKE) $@; fi
@if [ -d $(EMULEX_DIR) ]; then cd $(EMULEX_DIR) && $(MAKE) $@; fi
clean:
cd $(SCST_DIR) && $(MAKE) $@
@@ -183,6 +193,7 @@ clean:
@if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi
@if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi
@if [ -d $(SCST_LOCAL_DIR) ]; then cd $(SCST_LOCAL_DIR) && $(MAKE) $@; fi
@if [ -d $(EMULEX_DIR) ]; then cd $(EMULEX_DIR) && $(MAKE) $@; fi
extraclean:
-rm -f TAGS
@@ -197,6 +208,7 @@ extraclean:
@if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi
@if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi
@if [ -d $(SCST_LOCAL_DIR) ]; then cd $(SCST_LOCAL_DIR) && $(MAKE) $@; fi
@if [ -d $(EMULEX_DIR) ]; then cd $(EMULEX_DIR) && $(MAKE) $@; fi
tags:
find . -type f -name "*.[ch]" | ctags --c-kinds=+p --fields=+iaS --extra=+q -e -L-
@@ -257,7 +269,7 @@ qla_clean:
cd $(QLA_DIR) && $(MAKE) clean
qla_extraclean:
cd $(QLA_INI_DIR)/.. && $(MAKE) extraclean
cd $(QLA_INI_DIR) && pwd && $(MAKE) extraclean
cd $(QLA_DIR) && $(MAKE) extraclean
qla_old:
@@ -290,6 +302,21 @@ iscsi_clean:
iscsi_extraclean:
cd $(ISCSI_DIR) && $(MAKE) extraclean
emulex:
cd $(EMULEX_DIR) && $(MAKE) all
emulex_install:
cd $(EMULEX_DIR) && $(MAKE) install
emulex_uninstall:
cd $(EMULEX_DIR) && $(MAKE) uninstall
emulex_clean:
cd $(EMULEX_DIR) && $(MAKE) clean
emulex_extraclean:
cd $(EMULEX_DIR) && $(MAKE) extraclean
lsi:
cd $(LSI_DIR) && $(MAKE) all
@@ -405,9 +432,25 @@ scst-rpm:
for d in BUILD RPMS SOURCES SPECS SRPMS; do \
mkdir -p $${rpmtopdir}/$$d; \
done && \
cp $${name}-$(VERSION).tar.bz2 $${rpmtopdir}/SOURCES && \
cp scst-$(VERSION).tar.bz2 $${rpmtopdir}/SOURCES && \
sed "s/@rpm_version@/$(VERSION)/g" \
<$${name}.spec.in >$${name}.spec; \
<$${name}.spec.in >$${name}.spec && \
MAKE="$(MAKE)" rpmbuild --define="%_topdir $${rpmtopdir}" \
$(if $(KVER),--define="%kversion $(KVER)") \
-ba $${name}.spec && \
rm -f $${name}-$(VERSION).tar.bz2
scst-dkms-rpm:
name=scst-dkms && \
rpmtopdir="$$(if [ $$(id -u) = 0 ]; then echo /usr/src/packages;\
else echo $$PWD/rpmbuilddir; fi)" && \
$(MAKE) scst-dist-gzip && \
for d in BUILD RPMS SOURCES SPECS SRPMS; do \
mkdir -p $${rpmtopdir}/$$d; \
done && \
cp scst-$(VERSION).tar.bz2 $${rpmtopdir}/SOURCES && \
sed "s/@rpm_version@/$(VERSION)/g" \
<$${name}.spec.in >$${name}.spec && \
MAKE="$(MAKE)" rpmbuild --define="%_topdir $${rpmtopdir}" \
$(if $(KVER),--define="%kversion $(KVER)") \
-ba $${name}.spec && \
@@ -422,6 +465,16 @@ rpm:
find -name '*.rpm'; \
fi
release-archive:
$(MAKE) 2release
for m in $$(find -name Makefile | \
xargs grep -l '^release-archive:' | \
grep -v '^\./Makefile'); \
do \
(cd $$(dirname $$m) && $(MAKE) release-archive) \
done
$(MAKE) 2debug
2perf: extraclean
cd $(SCST_DIR) && $(MAKE) $@
@if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; fi
@@ -480,6 +533,7 @@ disable_proc: extraclean
qla_old qla_old_install qla_old_uninstall qla_old_clean qla_old_extraclean \
lsi lsi_install lsi_uninstall lsi_clean lsi_extraclean \
iscsi iscsi_install iscsi_uninstall iscsi_clean iscsi_extraclean \
emulex emulex_install emulex_uninstall emulex_clean emulex_extraclean \
scst scst_install scst_uninstall scst_clean scst_extraclean \
docs docs_clean docs_extraclean \
scstadm scstadm_install scstadm_uninstall scstadm_clean scstadm_extraclean \
+2
View File
@@ -17,3 +17,5 @@ SRPT 1.0.0 450
2.2.x branch start 3981, which is a copy of r3979 on the 2.1.0.x branch
2.2.0 4102
2.2.1 4737 on the 2.2.x branch
3.0.x branch start 5534, which is a copy of trunk r5533.
3.0.0 5815 on the 3.0.x branch
+6 -10
View File
@@ -151,16 +151,8 @@ function, or close on its file descriptor.
<sect1> SCST_USER_UNREGISTER_DEVICE
<p>
SCST_USER_UNREGISTER_DEVICE unregisters the corresponding virtual user
space device. It doesn't have any parameters.
During execution of SCST_USER_UNREGISTER_DEVICE at least one another
thread must process all coming subcommands, otherwise after timeout it
will fail with EBUSY error. The processing should stop on receiving
ENODEV error.
SCST_USER_UNREGISTER_DEVICE returns 0 on success or -1 in case of error,
and errno is set appropriately.
SCST_USER_UNREGISTER_DEVICE is obsolete and should not be used. Just
close the device's fd instead.
<sect1> SCST_USER_SET_OPTIONS/SCST_USER_GET_OPTIONS
@@ -290,6 +282,10 @@ thread, which also handles incoming commands, otherwise there could be a
but nobody handles them. This "deadlock" will be resolved only when
initiator, which sent those commands, aborts them after timeout.
<bf/IMPORTANT!/ It is duty of the caller to serialize
SCST_USER_SET_OPTIONS invocations. The kernel code does not have any
locking around modifying above properties.
<sect1> SCST_USER_REPLY_AND_GET_CMD
+1 -1
View File
@@ -3,7 +3,7 @@
# Based on ../mvsas_tgt/Makefile
#
# Copyright (C) 2006 - 2008 Jacky Feng <jfeng@marvell.com>
# Copyright (C) 2011 - 2014 Bart Van Assche <bvanassche@acm.org>
# Copyright (C) 2011 - 2015 Bart Van Assche <bvanassche@acm.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
-1
View File
@@ -147,7 +147,6 @@ int ft_send_xfer_rdy(struct scst_cmd *);
void ft_cmd_timeout(struct scst_cmd *);
void ft_cmd_free(struct scst_cmd *);
void ft_cmd_tm_done(struct scst_mgmt_cmd *);
int ft_tgt_detect(struct scst_tgt_template *);
int ft_tgt_release(struct scst_tgt *);
int ft_tgt_enable(struct scst_tgt *, bool);
bool ft_tgt_enabled(struct scst_tgt *);
+2 -1
View File
@@ -57,7 +57,8 @@ void ft_cmd_dump(struct scst_cmd *cmd, const char *caller)
prefix, cmd, fcmd->write_data_len, fcmd->read_data_len);
pr_info("%s exp_dir %x exp_xfer_len %d exp_in_len %d\n",
prefix, cmd->expected_data_direction,
cmd->expected_transfer_len, cmd->expected_out_transfer_len);
cmd->expected_transfer_len_full,
cmd->expected_out_transfer_len);
pr_info("%s dir %x data_len %lld bufflen %d out_bufflen %d\n",
prefix, cmd->data_direction, cmd->data_len,
cmd->bufflen, cmd->out_bufflen);
-1
View File
@@ -44,7 +44,6 @@ struct scst_tgt_template ft_scst_template = {
.on_hw_pending_cmd_timeout = ft_cmd_timeout,
.on_free_cmd = ft_cmd_free,
.task_mgmt_fn_done = ft_cmd_tm_done,
.detect = ft_tgt_detect,
.release = ft_tgt_release,
.report_aen = ft_report_aen,
.enable_target = ft_tgt_enable,
-9
View File
@@ -26,8 +26,6 @@
static void ft_sess_put(struct ft_sess *sess);
static int ft_tport_count;
static ssize_t ft_format_wwn(char *buf, size_t len, u64 wwn)
{
u8 b[8];
@@ -75,7 +73,6 @@ static struct ft_tport *ft_tport_create(struct fc_lport *lport)
return NULL;
}
scst_tgt_set_tgt_priv(tport->tgt, tport);
ft_tport_count++;
tport->lport = lport;
for (i = 0; i < FT_SESS_HASH_SIZE; i++)
@@ -120,7 +117,6 @@ static void ft_tport_delete(struct ft_tport *tport)
#else
call_rcu(&tport->rcu, ft_tport_rcu_free);
#endif
ft_tport_count--;
}
/*
@@ -643,11 +639,6 @@ bool ft_tgt_enabled(struct scst_tgt *tgt)
return tport->enabled;
}
int ft_tgt_detect(struct scst_tgt_template *tt)
{
return ft_tport_count;
}
/*
* Report AEN (Asynchronous Event Notification) from device to initiator.
* See notes in scst.h.
-16
View File
@@ -116,7 +116,6 @@ struct vio_port {
bool enabled;
};
static atomic_t ibmvstgt_device_count;
static struct workqueue_struct *vtgtd;
static unsigned max_vdma_size = MAX_H_COPY_RDMA;
static struct scst_tgt_template ibmvstgt_template;
@@ -392,16 +391,6 @@ static bool ibmvstgt_is_target_enabled(struct scst_tgt *scst_tgt)
}
#endif
/**
* ibmvstgt_detect() - Returns the number of target adapters.
*
* Callback function called by the SCST core.
*/
static int ibmvstgt_detect(struct scst_tgt_template *tp)
{
return atomic_read(&ibmvstgt_device_count);
}
/**
* ibmvstgt_release() - Free the resources associated with an SCST target.
*
@@ -1225,7 +1214,6 @@ static struct scst_tgt_template ibmvstgt_template = {
.enable_target = ibmvstgt_enable_target,
.is_target_enabled = ibmvstgt_is_target_enabled,
#endif
.detect = ibmvstgt_detect,
.release = ibmvstgt_release,
.xmit_response = ibmvstgt_xmit_response,
.rdy_to_xfer = ibmvstgt_rdy_to_xfer,
@@ -1308,8 +1296,6 @@ static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id)
#endif
goto destroy_crq_queue;
atomic_inc(&ibmvstgt_device_count);
return 0;
destroy_crq_queue:
@@ -1334,8 +1320,6 @@ static int ibmvstgt_remove(struct vio_dev *dev)
if (!target)
return 0;
atomic_dec(&ibmvstgt_device_count);
vport = target->ldata;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
class_device_unregister(&vport->dev);
+2 -2
View File
@@ -111,8 +111,8 @@ include/iscsi_scst_itf_ver.h: include/iscsi_scst.h
echo "/* Autogenerated, don't edit */" >include/iscsi_scst_itf_ver.h
echo "" >>include/iscsi_scst_itf_ver.h
echo -n "#define ISCSI_SCST_INTERFACE_VERSION " >>include/iscsi_scst_itf_ver.h
echo -n "ISCSI_VERSION_STRING \"_\" " >>include/iscsi_scst_itf_ver.h
echo "\"`sha1sum include/iscsi_scst.h|awk '{printf $$1}'`\"" >>include/iscsi_scst_itf_ver.h
echo -n "ISCSI_VERSION_STRING \"_" >>include/iscsi_scst_itf_ver.h
echo "`sha1sum include/iscsi_scst.h|awk '{printf $$1}'`\"" >>include/iscsi_scst_itf_ver.h
install: all
@install -vD -m 755 usr/iscsi-scstd $(DESTDIR)$(SBINDIR)/iscsi-scstd
+2 -2
View File
@@ -19,8 +19,8 @@ include/iscsi_scst_itf_ver.h: include/iscsi_scst.h
echo "/* Autogenerated, don't edit */" >include/iscsi_scst_itf_ver.h
echo "" >>include/iscsi_scst_itf_ver.h
echo -n "#define ISCSI_SCST_INTERFACE_VERSION " >>include/iscsi_scst_itf_ver.h
echo -n "ISCSI_VERSION_STRING \"_\" " >>include/iscsi_scst_itf_ver.h
echo "\"`sha1sum include/iscsi_scst.h|awk '{printf $$1}'`\"" >>include/iscsi_scst_itf_ver.h
echo -n "ISCSI_VERSION_STRING \"_" >>include/iscsi_scst_itf_ver.h
echo "`sha1sum include/iscsi_scst.h|awk '{printf $$1}'`\"" >>include/iscsi_scst_itf_ver.h
install: all
@install -vD -m 755 usr/iscsi-scstd $(DESTDIR)$(SBINDIR)/iscsi-scstd
+2 -2
View File
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -2
View File
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -2
View File
@@ -1,8 +1,8 @@
#
# Makefile for the kernel part of iSCSI-SCST.
#
# Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
# Copyright (C) 2007 - 2014 Fusion-io, Inc.
# Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
# Copyright (C) 2007 - 2015 SanDisk Corporation
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
+5 -5
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2004 - 2005 FUJITA Tomonori <tomof@acm.org>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -1270,18 +1270,18 @@ void iscsi_dump_pdu(struct iscsi_pdu *pdu)
int i;
buf = (void *)&pdu->bhs;
printk(KERN_DEBUG "BHS: (%p,%zd)\n", buf, sizeof(pdu->bhs));
pr_debug("BHS: (%p,%zd)\n", buf, sizeof(pdu->bhs));
for (i = 0; i < (int)sizeof(pdu->bhs); i++)
iscsi_dump_char(*buf++, text, &pos);
iscsi_dump_char(-1, text, &pos);
buf = (void *)pdu->ahs;
printk(KERN_DEBUG "AHS: (%p,%d)\n", buf, pdu->ahssize);
pr_debug("AHS: (%p,%d)\n", buf, pdu->ahssize);
for (i = 0; i < pdu->ahssize; i++)
iscsi_dump_char(*buf++, text, &pos);
iscsi_dump_char(-1, text, &pos);
printk(KERN_DEBUG "Data: (%d)\n", pdu->datasize);
pr_debug("Data: (%d)\n", pdu->datasize);
}
}
+3 -3
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2002 - 2003 Ardis Technolgies <roman@ardistech.com>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -766,7 +766,7 @@ static int conn_setup_sock(struct iscsi_conn *conn)
TRACE_DBG("%llx", (unsigned long long int)session->sid);
conn->sock = SOCKET_I(conn->file->f_dentry->d_inode);
conn->sock = SOCKET_I(file_inode(conn->file));
if (conn->sock->ops->sendpage == NULL) {
PRINT_ERROR("Socket for sid %llx doesn't support sendpage()",
+2 -2
View File
@@ -3,8 +3,8 @@
*
* Copyright (C) 2004 - 2006 Xiranet Communications GmbH
* <arne.redlich@xiranet.com>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -2
View File
@@ -2,8 +2,8 @@
* iSCSI digest handling.
*
* Copyright (C) 2004 Xiranet Communications GmbH <arne.redlich@xiranet.com>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -2
View File
@@ -2,8 +2,8 @@
* Event notification code.
*
* Copyright (C) 2005 FUJITA Tomonori <tomof@acm.org>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+41 -34
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2002 - 2003 Ardis Technolgies <roman@ardistech.com>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -1450,8 +1450,8 @@ static void cmnd_prepare_get_rejected_immed_data(struct iscsi_cmnd *cmnd)
{
struct iscsi_conn *conn = cmnd->conn;
struct scatterlist *sg = cmnd->sg;
char __user *addr;
u32 size;
char *addr;
u32 size, s, e;
unsigned int i;
TRACE_ENTRY();
@@ -1484,18 +1484,22 @@ static void cmnd_prepare_get_rejected_immed_data(struct iscsi_cmnd *cmnd)
cmnd->own_sg = 1;
}
addr = (char __force __user *)(page_address(sg_page(&sg[0])));
conn->read_size = size;
for (i = 0; size > PAGE_SIZE; i++, size -= PAGE_SIZE) {
addr = page_address(sg_page(&sg[0]));
for (s = size, i = 0; s > 0; i++, s -= e) {
/* We already checked pdu.datasize in check_segment_length() */
sBUG_ON(i >= ISCSI_CONN_IOV_MAX);
conn->read_iov[i].iov_base = addr;
conn->read_iov[i].iov_len = PAGE_SIZE;
e = min_t(u32, s, PAGE_SIZE);
conn->read_iov[i].iov_len = e;
}
conn->read_iov[i].iov_base = addr;
conn->read_iov[i].iov_len = size;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
iov_iter_kvec(&conn->read_msg.msg_iter, READ | ITER_KVEC,
conn->read_iov, i, size);
#else
conn->read_msg.msg_iov = conn->read_iov;
conn->read_msg.msg_iovlen = ++i;
conn->read_msg.msg_iovlen = i;
conn->read_size = size;
#endif
out:
TRACE_EXIT();
@@ -1576,6 +1580,7 @@ static int cmnd_prepare_recv_pdu(struct iscsi_conn *conn,
struct scatterlist *sg = cmd->sg;
unsigned int bufflen = cmd->bufflen;
unsigned int idx, i, buff_offs;
const u32 read_size = size;
int res = 0;
TRACE_ENTRY();
@@ -1590,13 +1595,10 @@ static int cmnd_prepare_recv_pdu(struct iscsi_conn *conn,
idx = offset >> PAGE_SHIFT;
offset &= ~PAGE_MASK;
conn->read_msg.msg_iov = conn->read_iov;
conn->read_size = size;
i = 0;
while (1) {
unsigned int sg_len;
char __user *addr;
char *addr;
if (unlikely(buff_offs >= bufflen)) {
TRACE_DBG("Residual overflow (cmd %p, buff_offs %d, "
@@ -1606,7 +1608,7 @@ static int cmnd_prepare_recv_pdu(struct iscsi_conn *conn,
offset = 0;
}
addr = (char __force __user *)(page_address(sg_page(&sg[idx])));
addr = page_address(sg_page(&sg[idx]));
EXTRACHECKS_BUG_ON(addr == NULL);
sg_len = sg[idx].offset + sg[idx].length - offset;
@@ -1616,7 +1618,6 @@ static int cmnd_prepare_recv_pdu(struct iscsi_conn *conn,
TRACE_DBG("idx=%d, i=%d, offset=%u, size=%d, addr=%p",
idx, i, offset, size, addr);
conn->read_iov[i].iov_len = size;
conn->read_msg.msg_iovlen = i+1;
break;
}
conn->read_iov[i].iov_len = sg_len;
@@ -1635,16 +1636,26 @@ static int cmnd_prepare_recv_pdu(struct iscsi_conn *conn,
size);
mark_conn_closed(conn);
res = -EINVAL;
break;
goto out;
}
idx++;
offset = 0;
}
TRACE_DBG("msg_iov=%p, msg_iovlen=%zd",
conn->read_msg.msg_iov, conn->read_msg.msg_iovlen);
i++;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
iov_iter_kvec(&conn->read_msg.msg_iter, READ | ITER_KVEC,
conn->read_iov, i, read_size);
#else
conn->read_msg.msg_iov = conn->read_iov;
conn->read_msg.msg_iovlen = i;
conn->read_size = read_size;
#endif
TRACE_DBG("msg_iov=%p, msg_iovlen=%u", conn->read_iov, i);
out:
TRACE_EXIT_RES(res);
return res;
}
@@ -1784,7 +1795,6 @@ static int nop_out_start(struct iscsi_cmnd *cmnd)
size = cmnd->pdu.datasize;
if (size && !conn->session->sess_params.rdma_extensions) {
conn->read_msg.msg_iov = conn->read_iov;
if (cmnd->pdu.bhs.itt != ISCSI_RESERVED_TAG) {
struct scatterlist *sg;
@@ -1805,10 +1815,9 @@ static int nop_out_start(struct iscsi_cmnd *cmnd)
for (i = 0; i < cmnd->sg_cnt; i++) {
conn->read_iov[i].iov_base =
(void __force __user *)(page_address(sg_page(&sg[i])));
page_address(sg_page(&sg[i]));
tmp = min_t(u32, size, PAGE_SIZE);
conn->read_iov[i].iov_len = tmp;
conn->read_size += tmp;
size -= tmp;
}
sBUG_ON(size != 0);
@@ -1820,10 +1829,9 @@ static int nop_out_start(struct iscsi_cmnd *cmnd)
*/
for (i = 0; i < (signed)ISCSI_CONN_IOV_MAX; i++) {
conn->read_iov[i].iov_base =
(void __force __user *)(page_address(dummy_page));
page_address(dummy_page);
tmp = min_t(u32, size, PAGE_SIZE);
conn->read_iov[i].iov_len = tmp;
conn->read_size += tmp;
size -= tmp;
}
@@ -1831,9 +1839,15 @@ static int nop_out_start(struct iscsi_cmnd *cmnd)
sBUG_ON(size != 0);
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
iov_iter_kvec(&conn->read_msg.msg_iter, READ | ITER_KVEC,
conn->read_iov, i, cmnd->pdu.datasize);
#else
conn->read_msg.msg_iov = conn->read_iov;
conn->read_msg.msg_iovlen = i;
TRACE_DBG("msg_iov=%p, msg_iovlen=%zd", conn->read_msg.msg_iov,
conn->read_msg.msg_iovlen);
conn->read_size = cmnd->pdu.datasize;
#endif
TRACE_DBG("msg_iov=%p, msg_iovlen=%d", conn->read_iov, i);
}
out:
@@ -3995,12 +4009,6 @@ out:
}
#endif
static int iscsi_target_detect(struct scst_tgt_template *templ)
{
/* Nothing to do */
return 0;
}
static int iscsi_target_release(struct scst_tgt *scst_tgt)
{
/* Nothing to do */
@@ -4055,7 +4063,6 @@ struct scst_tgt_template iscsi_template = {
.trace_tbl_help = ISCSI_TRACE_TBL_HELP,
#endif
#endif
.detect = iscsi_target_detect,
.release = iscsi_target_release,
.xmit_response = iscsi_xmit_response,
#if !defined(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION)
+7 -3
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2002 - 2003 Ardis Technolgies <roman@ardistech.com>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -291,9 +291,13 @@ struct iscsi_conn {
*/
struct iscsi_cmnd *read_cmnd;
struct msghdr read_msg;
u32 read_size;
int read_state;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
struct kvec *read_iov;
#else
u32 read_size;
struct iovec *read_iov;
#endif
struct task_struct *rx_task;
uint32_t rpadding;
+2 -2
View File
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2002 - 2003 Ardis Technolgies <roman@ardistech.com>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+57 -40
View File
@@ -2,8 +2,8 @@
* Network threads.
*
* Copyright (C) 2004 - 2005 FUJITA Tomonori <tomof@acm.org>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -616,13 +616,18 @@ void start_close_conn(struct iscsi_conn *conn)
EXPORT_SYMBOL(start_close_conn);
static inline void iscsi_conn_init_read(struct iscsi_conn *conn,
void __user *data, size_t len)
void *data, size_t len)
{
conn->read_iov[0].iov_base = data;
conn->read_iov[0].iov_len = len;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
iov_iter_kvec(&conn->read_msg.msg_iter, READ | ITER_KVEC,
conn->read_iov, 1, len);
#else
conn->read_msg.msg_iov = conn->read_iov;
conn->read_msg.msg_iovlen = 1;
conn->read_size = len;
#endif
return;
}
@@ -634,7 +639,7 @@ static void iscsi_conn_prepare_read_ahs(struct iscsi_conn *conn,
/* ToDo: __GFP_NOFAIL ?? */
cmnd->pdu.ahs = kmalloc(asize, __GFP_NOFAIL|GFP_KERNEL);
sBUG_ON(cmnd->pdu.ahs == NULL);
iscsi_conn_init_read(conn, (void __force __user *)cmnd->pdu.ahs, asize);
iscsi_conn_init_read(conn, cmnd->pdu.ahs, asize);
return;
}
@@ -684,8 +689,12 @@ static int do_recv(struct iscsi_conn *conn)
{
int res;
mm_segment_t oldfs;
struct msghdr msg;
struct msghdr *msg;
int read_size;
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)
struct iovec *first_iov;
int first_len;
#endif
EXTRACHECKS_BUG_ON(conn->read_cmnd == NULL);
@@ -701,45 +710,48 @@ static int do_recv(struct iscsi_conn *conn)
*/
restart:
memset(&msg, 0, sizeof(msg));
msg.msg_iov = conn->read_msg.msg_iov;
msg.msg_iovlen = conn->read_msg.msg_iovlen;
first_len = msg.msg_iov->iov_len;
msg = &conn->read_msg;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
read_size = msg->msg_iter.count;
#else
read_size = conn->read_size;
first_iov = msg->msg_iov;
first_len = first_iov->iov_len;
#endif
oldfs = get_fs();
set_fs(get_ds());
res = sock_recvmsg(conn->sock, &msg, conn->read_size,
res = sock_recvmsg(conn->sock, msg, read_size,
MSG_DONTWAIT | MSG_NOSIGNAL);
set_fs(oldfs);
TRACE_DBG("msg_iovlen %zd, first_len %d, read_size %d, res %d",
msg.msg_iovlen, first_len, conn->read_size, res);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
TRACE_DBG("nr_segs %zd, bytes_left %zd, res %d",
msg->msg_iter.nr_segs, msg->msg_iter.count, res);
#else
TRACE_DBG("msg_iovlen %zd, read_size %d, res %d", msg->msg_iovlen,
read_size, res);
#endif
if (res > 0) {
/*
* To save some considerable effort and CPU power we
* suppose that TCP functions adjust
* conn->read_msg.msg_iov and conn->read_msg.msg_iovlen
* on amount of copied data. This BUG_ON is intended
* to catch if it is changed in the future.
* To save CPU cycles we suppose that sock_recvmsg() adjusts
* msg->msg_iov and msg->msg_iovlen. The BUG_ON() statements
* below verifies this.
*/
sBUG_ON((res >= first_len) &&
(conn->read_msg.msg_iov->iov_len != 0));
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
sBUG_ON(msg->msg_iter.count + res != read_size);
res = msg->msg_iter.count;
#else
sBUG_ON((res >= first_len) && (first_iov->iov_len != 0));
conn->read_size -= res;
if (conn->read_size != 0) {
if (res >= first_len) {
int done = 1 + ((res - first_len) >> PAGE_SHIFT);
TRACE_DBG("done %d", done);
conn->read_msg.msg_iov += done;
conn->read_msg.msg_iovlen -= done;
}
}
res = conn->read_size;
#endif
} else {
switch (res) {
case -EAGAIN:
TRACE_DBG("EAGAIN received for conn %p", conn);
res = conn->read_size;
res = read_size;
break;
case -ERESTARTSYS:
TRACE_DBG("ERESTARTSYS received for conn %p", conn);
@@ -825,7 +837,7 @@ static int iscsi_rx_check_ddigest(struct iscsi_conn *conn)
static int process_read_io(struct iscsi_conn *conn, int *closed)
{
struct iscsi_cmnd *cmnd = conn->read_cmnd;
int res;
int bytes_left, res;
TRACE_ENTRY();
@@ -837,9 +849,8 @@ static int process_read_io(struct iscsi_conn *conn, int *closed)
EXTRACHECKS_BUG_ON(conn->read_cmnd != NULL);
cmnd = conn->transport->iscsit_alloc_cmd(conn, NULL);
conn->read_cmnd = cmnd;
iscsi_conn_init_read(cmnd->conn,
(void __force __user *)&cmnd->pdu.bhs,
sizeof(cmnd->pdu.bhs));
iscsi_conn_init_read(cmnd->conn, &cmnd->pdu.bhs,
sizeof(cmnd->pdu.bhs));
conn->read_state = RX_BHS;
/* go through */
@@ -904,7 +915,7 @@ static int process_read_io(struct iscsi_conn *conn, int *closed)
if (psz != 0) {
TRACE_DBG("padding %d bytes", psz);
iscsi_conn_init_read(conn,
(void __force __user *)&conn->rpadding, psz);
&conn->rpadding, psz);
conn->read_state = RX_PADDING;
} else if ((conn->ddigest_type & DIGEST_NONE) != 0)
conn->read_state = RX_END;
@@ -914,10 +925,15 @@ static int process_read_io(struct iscsi_conn *conn, int *closed)
break;
case RX_END:
if (unlikely(conn->read_size != 0)) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
bytes_left = conn->read_msg.msg_iter.count;
#else
bytes_left = conn->read_size;
#endif
if (unlikely(bytes_left != 0)) {
PRINT_CRIT_ERROR("conn read_size !=0 on RX_END "
"(conn %p, op %x, read_size %d)", conn,
cmnd_opcode(cmnd), conn->read_size);
cmnd_opcode(cmnd), bytes_left);
sBUG();
}
conn->read_cmnd = NULL;
@@ -925,7 +941,11 @@ static int process_read_io(struct iscsi_conn *conn, int *closed)
cmnd_rx_end(cmnd);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
EXTRACHECKS_BUG_ON(conn->read_msg.msg_iter.count != 0);
#else
EXTRACHECKS_BUG_ON(conn->read_size != 0);
#endif
/*
* To maintain fairness. Res must be 0 here anyway, the
@@ -936,8 +956,7 @@ static int process_read_io(struct iscsi_conn *conn, int *closed)
goto out;
case RX_INIT_HDIGEST:
iscsi_conn_init_read(conn,
(void __force __user *)&cmnd->hdigest, sizeof(u32));
iscsi_conn_init_read(conn, &cmnd->hdigest, sizeof(u32));
conn->read_state = RX_CHECK_HDIGEST;
/* go through */
@@ -957,9 +976,7 @@ static int process_read_io(struct iscsi_conn *conn, int *closed)
break;
case RX_INIT_DDIGEST:
iscsi_conn_init_read(conn,
(void __force __user *)&cmnd->ddigest,
sizeof(u32));
iscsi_conn_init_read(conn, &cmnd->ddigest, sizeof(u32));
conn->read_state = RX_CHECK_DDIGEST;
/* go through */
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2005 FUJITA Tomonori <tomof@acm.org>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -0,0 +1,387 @@
Subject: [PATCH] put_page_callback
---
drivers/block/drbd/drbd_receiver.c | 2 +-
include/linux/mm_types.h | 11 +++++++++
include/linux/net.h | 40 ++++++++++++++++++++++++++++++
include/linux/skbuff.h | 4 +--
net/Kconfig | 12 +++++++++
net/ceph/pagevec.c | 2 +-
net/core/skbuff.c | 14 +++++------
net/core/sock.c | 4 +--
net/ipv4/Makefile | 1 +
net/ipv4/ip_output.c | 4 +--
net/ipv4/tcp.c | 4 +--
net/ipv4/tcp_zero_copy.c | 50 ++++++++++++++++++++++++++++++++++++++
net/ipv6/ip6_output.c | 2 +-
13 files changed, 132 insertions(+), 18 deletions(-)
create mode 100644 net/ipv4/tcp_zero_copy.c
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index d169b4a..ec913c2 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -132,7 +132,7 @@ static int page_chain_free(struct page *page)
struct page *tmp;
int i = 0;
page_chain_for_each_safe(page, tmp) {
- put_page(page);
+ net_put_page(page);
++i;
}
return i;
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 6d34aa2..a536ed7 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -197,6 +197,17 @@ struct page {
#ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS
int _last_cpupid;
#endif
+
+#if defined(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION)
+ /*
+ * Used to implement support for notification on zero-copy TCP transfer
+ * completion. It might look as not good to have this field here and
+ * it's better to have it in struct sk_buff, but it would make the code
+ * much more complicated and fragile, since all skb then would have to
+ * contain only pages with the same value in this field.
+ */
+ void *net_priv;
+#endif
}
/*
* The struct page can be forced to be double word aligned so that atomic ops
diff --git a/include/linux/net.h b/include/linux/net.h
index 17d8339..f784384 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -19,6 +19,7 @@
#define _LINUX_NET_H
#include <linux/stringify.h>
+#include <linux/mm.h>
#include <linux/random.h>
#include <linux/wait.h>
#include <linux/fcntl.h> /* For O_CLOEXEC and O_NONBLOCK */
@@ -285,6 +286,45 @@ int kernel_sendpage(struct socket *sock, struct page *page, int offset,
int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg);
int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how);
+#if defined(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION)
+/* Support for notification on zero-copy TCP transfer completion */
+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);
+
+/*
+ * See comment for net_set_get_put_page_callbacks() why those functions
+ * don't need any protection.
+ */
+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);
+}
+#else
+static inline void net_get_page(struct page *page)
+{
+ get_page(page);
+}
+static inline void net_put_page(struct page *page)
+{
+ put_page(page);
+}
+#endif /* CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION */
+
#define MODULE_ALIAS_NETPROTO(proto) \
MODULE_ALIAS("net-pf-" __stringify(proto))
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 85ab7d7..fb82e86 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2254,7 +2254,7 @@ static inline struct page *skb_frag_page(const skb_frag_t *frag)
*/
static inline void __skb_frag_ref(skb_frag_t *frag)
{
- get_page(skb_frag_page(frag));
+ net_get_page(skb_frag_page(frag));
}
/**
@@ -2277,7 +2277,7 @@ static inline void skb_frag_ref(struct sk_buff *skb, int f)
*/
static inline void __skb_frag_unref(skb_frag_t *frag)
{
- put_page(skb_frag_page(frag));
+ net_put_page(skb_frag_page(frag));
}
/**
diff --git a/net/Kconfig b/net/Kconfig
index ff9ffc1..a270579 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -76,6 +76,18 @@ config INET
Short answer: say Y.
+config TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION
+ bool "TCP/IP zero-copy transfer completion notification"
+ depends on INET
+ default SCST_ISCSI
+ ---help---
+ Adds support for sending a notification upon completion of a
+ zero-copy TCP/IP transfer. This can speed up certain TCP/IP
+ software. Currently this is only used by the iSCSI target driver
+ iSCSI-SCST.
+
+ If unsure, say N.
+
if INET
source "net/ipv4/Kconfig"
source "net/ipv6/Kconfig"
diff --git a/net/ceph/pagevec.c b/net/ceph/pagevec.c
index 5550130..993f710 100644
--- a/net/ceph/pagevec.c
+++ b/net/ceph/pagevec.c
@@ -51,7 +51,7 @@ void ceph_put_page_vector(struct page **pages, int num_pages, bool dirty)
for (i = 0; i < num_pages; i++) {
if (dirty)
set_page_dirty_lock(pages[i]);
- put_page(pages[i]);
+ net_put_page(pages[i]);
}
if (is_vmalloc_addr(pages))
vfree(pages);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 62c67be..35074d3 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -479,7 +479,7 @@ static struct sk_buff *__alloc_rx_skb(unsigned int length, gfp_t gfp_mask,
if (likely(data)) {
skb = build_skb(data, fragsz);
if (unlikely(!skb))
- put_page(virt_to_head_page(data));
+ net_put_page(virt_to_head_page(data));
}
} else {
skb = __alloc_skb(length, gfp_mask,
@@ -592,7 +592,7 @@ static void skb_clone_fraglist(struct sk_buff *skb)
static void skb_free_head(struct sk_buff *skb)
{
if (skb->head_frag)
- put_page(virt_to_head_page(skb->head));
+ net_put_page(virt_to_head_page(skb->head));
else
kfree(skb->head);
}
@@ -920,7 +920,7 @@ int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask)
if (!page) {
while (head) {
struct page *next = (struct page *)page_private(head);
- put_page(head);
+ net_put_page(head);
head = next;
}
return -ENOMEM;
@@ -1767,7 +1767,7 @@ EXPORT_SYMBOL(skb_copy_bits);
*/
static void sock_spd_release(struct splice_pipe_desc *spd, unsigned int i)
{
- put_page(spd->pages[i]);
+ net_put_page(spd->pages[i]);
}
static struct page *linear_to_page(struct page *page, unsigned int *len,
@@ -1820,7 +1820,7 @@ static bool spd_fill_page(struct splice_pipe_desc *spd,
spd->partial[spd->nr_pages - 1].len += *len;
return false;
}
- get_page(page);
+ net_get_page(page);
spd->pages[spd->nr_pages] = page;
spd->partial[spd->nr_pages].len = *len;
spd->partial[spd->nr_pages].offset = offset;
@@ -2279,7 +2279,7 @@ skb_zerocopy(struct sk_buff *to, struct sk_buff *from, int len, int hlen)
page = virt_to_head_page(from->head);
offset = from->data - (unsigned char *)page_address(page);
__skb_fill_page_desc(to, 0, page, offset, plen);
- get_page(page);
+ net_get_page(page);
j = 1;
len -= plen;
}
@@ -2933,7 +2933,7 @@ int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
copy);
frg_cnt++;
pfrag->offset += copy;
- get_page(pfrag->page);
+ net_get_page(pfrag->page);
skb->truesize += copy;
atomic_add(copy, &sk->sk_wmem_alloc);
diff --git a/net/core/sock.c b/net/core/sock.c
index 1c7a33d..ec95185 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1864,7 +1864,7 @@ bool skb_page_frag_refill(unsigned int sz, struct page_frag *pfrag, gfp_t gfp)
}
if (pfrag->offset + sz <= pfrag->size)
return true;
- put_page(pfrag->page);
+ net_put_page(pfrag->page);
}
pfrag->offset = 0;
@@ -2615,7 +2615,7 @@ void sk_common_release(struct sock *sk)
sk_refcnt_debug_release(sk);
if (sk->sk_frag.page) {
- put_page(sk->sk_frag.page);
+ net_put_page(sk->sk_frag.page);
sk->sk_frag.page = NULL;
}
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index 518c04e..4072a87 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_TCP_CONG_ILLINOIS) += tcp_illinois.o
obj-$(CONFIG_MEMCG_KMEM) += tcp_memcontrol.o
obj-$(CONFIG_NETLABEL) += cipso_ipv4.o
obj-$(CONFIG_GENEVE) += geneve.o
+obj-$(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION) += tcp_zero_copy.o
obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \
xfrm4_output.o xfrm4_protocol.o
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 2e2f687..87f5bff 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1052,7 +1052,7 @@ alloc_new_skb:
__skb_fill_page_desc(skb, i, pfrag->page,
pfrag->offset, 0);
skb_shinfo(skb)->nr_frags = ++i;
- get_page(pfrag->page);
+ net_get_page(pfrag->page);
}
copy = min_t(int, copy, pfrag->size - pfrag->offset);
if (getfrag(from,
@@ -1277,7 +1277,7 @@ ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
if (skb_can_coalesce(skb, i, page, offset)) {
skb_frag_size_add(&skb_shinfo(skb)->frags[i-1], 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 --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 3075723..396b887 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -931,7 +931,7 @@ new_segment:
if (can_coalesce) {
skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], copy);
} else {
- get_page(page);
+ net_get_page(page);
skb_fill_page_desc(skb, i, page, offset, copy);
}
skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
@@ -1232,7 +1232,7 @@ new_segment:
} else {
skb_fill_page_desc(skb, i, pfrag->page,
pfrag->offset, copy);
- get_page(pfrag->page);
+ net_get_page(pfrag->page);
}
pfrag->offset += copy;
}
diff --git a/net/ipv4/tcp_zero_copy.c b/net/ipv4/tcp_zero_copy.c
new file mode 100644
index 0000000..430147e
--- /dev/null
+++ b/net/ipv4/tcp_zero_copy.c
@@ -0,0 +1,50 @@
+/*
+ * Support routines for TCP zero copy transmit
+ *
+ * Created by Vladislav Bolkhovitin
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+
+#include <linux/export.h>
+#include <linux/skbuff.h>
+
+net_get_page_callback_t net_get_page_callback __read_mostly;
+EXPORT_SYMBOL_GPL(net_get_page_callback);
+
+net_put_page_callback_t net_put_page_callback __read_mostly;
+EXPORT_SYMBOL_GPL(net_put_page_callback);
+
+/*
+ * Caller of this function must ensure that at the moment when it's called
+ * there are no pages in the system with net_priv field set to non-zero
+ * value. Hence, this function, as well as net_get_page() and net_put_page(),
+ * don't need any protection.
+ */
+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_GPL(net_set_get_put_page_callbacks);
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 3f5aa99..777f267 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1460,7 +1460,7 @@ alloc_new_skb:
__skb_fill_page_desc(skb, i, pfrag->page,
pfrag->offset, 0);
skb_shinfo(skb)->nr_frags = ++i;
- get_page(pfrag->page);
+ net_get_page(pfrag->page);
}
copy = min_t(int, copy, pfrag->size - pfrag->offset);
if (getfrag(from,
--
1.9.1
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2002 - 2003 Ardis Technolgies <roman@ardistech.com>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2002 - 2003 Ardis Technolgies <roman@ardistech.com>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -5
View File
@@ -1,8 +1,8 @@
#
# Makefile for the user space part of iSCSI-SCST.
#
# Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
# Copyright (C) 2007 - 2014 Fusion-io, Inc.
# Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
# Copyright (C) 2007 - 2015 SanDisk Corporation
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@@ -26,9 +26,6 @@ OBJS_D = $(SRCS_D:.c=.o)
SRCS_ADM = iscsi_adm.c param.c
OBJS_ADM = $(SRCS_ADM:.c=.o)
SCST_INC_DIR := ../../scst/include
#SCST_INC_DIR := $(PREFIX)/include/scst
CFLAGS += -O2 -fno-inline -Wall -Wextra -Wstrict-prototypes -Wno-sign-compare \
-Wimplicit-function-declaration -Wno-unused-parameter \
-Wno-missing-field-initializers -g -I../include -I$(SCST_INC_DIR)
+2 -2
View File
@@ -3,8 +3,8 @@
*
* Copyright (C) 2004 Xiranet Communications GmbH <arne.redlich@xiranet.com>
* Copyright (C) 2002 - 2003 Ardis Technolgies <roman@ardistech.com>,
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* and code taken from UNH iSCSI software:
* Copyright (C) 2001-2003 InterOperability Lab (IOL)
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2005 FUJITA Tomonori <tomof@acm.org>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2002 - 2003 Ardis Technolgies <roman@ardistech.com>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2004 - 2005 FUJITA Tomonori <tomof@acm.org>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -2
View File
@@ -2,8 +2,8 @@
* Event notification code.
*
* Copyright (C) 2005 FUJITA Tomonori <tomof@acm.org>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -2
View File
@@ -2,8 +2,8 @@
* iscsi_adm - manage iSCSI-SCST Target software.
*
* Copyright (C) 2004 - 2005 FUJITA Tomonori <tomof@acm.org>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -2
View File
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2002 - 2003 Ardis Technolgies <roman@ardistech.com>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2002 - 2003 Ardis Technolgies <roman@ardistech.com>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2002 - 2003 Ardis Technolgies <roman@ardistech.com>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2002 - 2003 Ardis Technolgies <roman@ardistech.com>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -2
View File
@@ -2,8 +2,8 @@
* iSNS functions
*
* Copyright (C) 2006 FUJITA Tomonori <tomof@acm.org>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
+2 -2
View File
@@ -2,8 +2,8 @@
* iSNS protocol data types
*
* Copyright (C) 2006 FUJITA Tomonori <tomof@acm.org>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2002 - 2003 Ardis Technolgies <roman@ardistech.com>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2004 - 2005 FUJITA Tomonori <tomof@acm.org>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -2
View File
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -2
View File
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2005 FUJITA Tomonori <tomof@acm.org>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2005 FUJITA Tomonori <tomof@acm.org>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2002 - 2003 Ardis Technolgies <roman@ardistech.com>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+20 -6
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2002 - 2003 Ardis Technolgies <roman@ardistech.com>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -127,6 +127,15 @@ static int wildcmp(const char *wild, const char *string)
return __wildcmp(wild, string, 0);
}
/*
* Evaluate the list with wildcard patterns as follows:
* - If only positive wildcard patterns have been specified, it is sufficient
* that one wildcard pattern matches (logical or).
* - If only negative wildcard patterns have been specified, none of these
* patterns must match (logical and).
* - If positive and negative wildcard patterns have been specified, one of
* the positive patterns must match and none of the negative.
*/
int target_portal_allowed(struct target *target,
const char *target_portal, const char *initiator_name)
{
@@ -135,14 +144,19 @@ int target_portal_allowed(struct target *target,
if (!list_empty(&target->allowed_portals)) {
struct iscsi_attr *attr;
bool any_pos_cond = false, pos_match = false, neg_match = true;
res = 0;
list_for_each_entry(attr, &target->allowed_portals, ulist) {
if (wildcmp(attr->attr_key, target_portal)) {
res = 1;
break;
bool match = wildcmp(attr->attr_key, target_portal);
if (attr->attr_key[0] != '!') {
any_pos_cond = true;
pos_match = pos_match || match;
} else {
neg_match = neg_match && match;
}
}
res = (!any_pos_cond || pos_match) && neg_match;
if (res == 0)
goto out;
}
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2002 - 2003 Ardis Technolgies <roman@ardistech.com>
* Copyright (C) 2007 - 2014 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 Vladislav Bolkhovitin
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+5 -5
View File
@@ -3,15 +3,15 @@
ABT_DETAILS="x86_64"
ABT_JOBS=5
ABT_KERNELS=" \
3.18.5 \
3.18.8 \
3.17.8-nc \
3.16.7-nc \
3.15.10-nc \
3.14.31-nc \
3.14.37-nc \
3.13.11-nc \
3.12.36-nc \
3.12.38-nc \
3.11.10-nc \
3.10.67-nc \
3.10.73-nc \
3.9.11-nc \
3.8.13-nc \
3.7.10-nc \
@@ -19,7 +19,7 @@ ABT_KERNELS=" \
3.5.7-nc \
3.4.105-nc \
3.3.8-nc \
3.2.66-nc \
3.2.67-nc \
3.1.10-nc \
3.0.101-nc \
2.6.39.4-nc \
+2 -2
View File
@@ -1,7 +1,7 @@
ifeq ($(BUILD_2X_MODULE),)
qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \
qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o
qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o qla_bsg.o qla_nx.o
obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o
@@ -53,7 +53,7 @@ INSTALL_DIR := $(INSTALL_MOD_PATH)/lib/modules/$(KVER)/extra
ifneq ($(PATCHLEVEL),)
obj-m := qla2xxx_scst.o
qla2xxx_scst-objs := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \
qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o
qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o qla_bsg.o qla_nx.o
else
all:
+9 -1
View File
@@ -1,7 +1,15 @@
Summary of changes between versions 3.0 and 3.1
-----------------------------------------------
- Support for 26xx/8[1-3]xx added
- Update to a newer qla2xxx
Summary of changes between versions 2.1.0 and 3.0
-------------------------------------------------
- Update to kernels up to 3.3
- Update to kernels up to 3.6
- Bug fixes and other improvements
+2 -2
View File
@@ -1,9 +1,9 @@
#
# Qlogic 2x00 SCSI target driver makefile
#
# Copyright (C) 2004 - 2014 Vladislav Bolkhovitin <vst@vlnb.net>
# Copyright (C) 2004 - 2015 Vladislav Bolkhovitin <vst@vlnb.net>
# Copyright (C) 2004 - 2005 Leonid Stoljar
# Copyright (C) 2007 - 2014 Fusion-io, Inc.
# Copyright (C) 2007 - 2015 SanDisk Corporation
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@@ -0,0 +1,5 @@
ccflags-y += -Idrivers/scsi/qla2xxx
qla2x00tgt-y := qla2x00t.o
obj-$(CONFIG_SCST_QLA_TGT_ADDON) += qla2x00tgt.o
+12 -15
View File
@@ -1,9 +1,17 @@
Target driver for QLogic 22xx/23xx/24xx/25xx Fibre Channel cards
================================================================
Target driver for QLogic 2[2-6]xx/8[1-3]xx Fibre Channel cards
==============================================================
Version 3.1.0, XX XXXXX 2014
Version 3.1.0, XX XXXXX 2015
----------------------------
This is target driver for QLogic 2[2-6]xx/8[1-3]xx Fibre Channel cards.
Particularly, this driver supports 16G Hilda QLogic chip based adapters
(however, post-Hilda QLogic chips not supported). This driver should
also support FCoE, but that has never been verified. It has passed
intensive internal SanDisk tests. It is stable and production ready.
This driver is in stable maintenance mode in favor of the QLogic git
driver, which has support for all the latest QLogic adapters.
This driver consists from two parts: the target mode driver itself and
the changed initiator driver from Linux kernel, which is, particularly,
intended to perform all the initialization and shutdown tasks. The
@@ -12,22 +20,11 @@ necessary callbacks, but it's still capable to work as initiator only.
Mode, when a host acts as the initiator and the target simultaneously,
is supported as well.
This version is compatible with SCST core version 2.0.0 and higher and
This version is compatible with SCST core version 3.1.0 and higher and
Linux kernel 2.6.26 and higher. Sorry, kernels below 2.6.26 are not
supported, because it's too hard to backport used initiator driver to
older kernels.
The original initiator driver was taken from the kernel 2.6.26. Also the
following 2.6.26+ commits have been applied to it (upstream ID):
048feec5548c0582ee96148c61b87cccbcb5f9be,
031e134e5f95233d80fb1b62fdaf5e1be587597c,
5f3a9a207f1fccde476dd31b4c63ead2967d934f,
85821c906cf3563a00a3d98fa380a2581a7a5ff1,
3c01b4f9fbb43fc911acd33ea7a14ea7a4f9866b,
8eca3f39c4b11320787f7b216f63214aee8415a9,
0f19bc681ed0849a2b95778460a0a8132e3700e2,
a55aac79de0ea6fc52d35f535867b6573a5ff0f8.
See also "ToDo" file for list of known issues and unimplemented
features.
+4 -2
View File
@@ -1,10 +1,12 @@
Known issues and unimplemented features
---------------------------------------
- Allow to set port names through sysfs.
- NPIV targets not quite work. If you need NPIV, use QLogic git driver
- Minor "ToDo"'s spread in the code.
Very old and, probably, already fixed:
- If a Linux initiator asks for devices using INQUIRY command too soon
before the controller on the 23xx target is fully initialized in the
target mode, the initiator could receive garbage devices and the
-29
View File
@@ -1,29 +0,0 @@
Throughout the last three years ID7 and I have been working on an
enterprise class Fibre Channel target based on the QLogic range of 4/8Gb
HBA's. This has been solely funded by ID7 over the last years however
given the positive contributions by many of the SCST community both
personal and commercial, ID7 have chosen to merge with existing QLogic's
open source driver qla2x00t and introduce the driver under GPL license
for community use.
This driver was designed from ground up to perform at the highest of
levels and interoperate with leading infrastructures, accordingly the
design and flow is much more focused and structured whilst the stability
is as you would expect at the Enterprise level.
Although there is a current QLogic target driver qla_isp, this driver
has the key advantage that it was designed to be as simple as possible.
As the result, this driver is a lot smaller, cleaner and mainline Linux
kernel ready. It's going to be pushed for the in-kernel inclusion
together other SCST patches.
Another advantage is that this driver fully supports FC tapes, including
transport level retries on data delivery problems.
Once again we are grateful for all the positive work and contributions
and hopeful that this target helps drive SCST further forward as an
Enterprise class target. We encourage people to introduce and evaluate
this target driver.
Vladislav Bolkhovitin,
Mark Klarzynski, ID7 Ltd. (http://www.id-7.com)
File diff suppressed because it is too large Load Diff
+17 -14
View File
@@ -1,10 +1,10 @@
/*
* qla2x00t.h
*
* Copyright (C) 2004 - 2014 Vladislav Bolkhovitin <vst@vlnb.net>
* Copyright (C) 2004 - 2015 Vladislav Bolkhovitin <vst@vlnb.net>
* Copyright (C) 2004 - 2005 Leonid Stoljar
* Copyright (C) 2006 Nathaniel Clark <nate@misrule.us>
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* QLogic 22xx/23xx/24xx/25xx FC target driver.
*
@@ -30,7 +30,7 @@
/* Version numbers, the same as for the kernel */
#define Q2T_VERSION(a, b, c, d) (((a) << 030) + ((b) << 020) + (c) << 010 + (d))
#define Q2T_VERSION_CODE Q2T_VERSION(3, 1, 0, 0)
#define Q2T_VERSION_CODE Q2T_VERSION(4, 1, 0, 0)
#define Q2T_VERSION_STRING "3.1.0-pre1"
#define Q2T_PROC_VERSION_NAME "version"
@@ -47,7 +47,7 @@
#define IMM_NTFY_PORT_LOGOUT 0x0029
#define IMM_NTFY_PORT_CONFIG 0x002A
#define IMM_NTFY_GLBL_TPRLO 0x002D
#define IMM_NTFY_GLBL_LOGO 0x002E
#define IMM_NTFY_LINK_FAILURE 0x002E
#define IMM_NTFY_RESOURCE 0x0034
#define IMM_NTFY_MSG_RX 0x0036
#define IMM_NTFY_SRR 0x0045
@@ -118,7 +118,7 @@
struct q2t_tgt {
struct scst_tgt *scst_tgt;
scsi_qla_host_t *ha;
scsi_qla_host_t *vha;
/*
* To sync between IRQ handlers and q2t_target_release(). Needed,
@@ -129,8 +129,7 @@ struct q2t_tgt {
int datasegs_per_cmd, datasegs_per_cont;
/* Target's flags, serialized by pha->hardware_lock */
unsigned int tgt_enable_64bit_addr:1; /* 64-bits PCI addressing enabled */
/* Target's flags, serialized by ha->hardware_lock */
unsigned int link_reinit_iocb_pending:1;
unsigned int tm_to_unknown:1; /* TM to unknown session was sent */
unsigned int sess_works_pending:1; /* there are sess_work entries */
@@ -141,17 +140,17 @@ struct q2t_tgt {
*/
unsigned long tgt_stop; /* the driver is being stopped */
struct work_struct rscn_reg_work;
/* Count of sessions referring q2t_tgt. Protected by hardware_lock. */
int sess_count;
/*
* Protected by hardware_lock. Adding new sessions (not undelete)
* also protected by tgt_mutex.
*/
struct list_head sess_list;
struct work_struct rscn_reg_work;
/* Count of sessions referring q2t_tgt. Protected by hardware_lock. */
int sess_count;
/* Protected by hardware_lock */
struct list_head del_sess_list;
struct delayed_work sess_del_work;
@@ -174,8 +173,6 @@ struct q2t_tgt {
struct work_struct srr_work;
atomic_t tgt_global_resets_count;
struct list_head tgt_list_entry;
};
/*
@@ -230,6 +227,12 @@ struct q2t_cmd {
struct scst_cmd scst_cmd;
};
struct q2t_unknown_atio {
atio7_entry_t atio7;
scsi_qla_host_t *vha;
struct list_head unknown_atio_list_entry;
};
struct q2t_sess_work_param {
struct list_head sess_works_list_entry;
+50 -27
View File
@@ -1,10 +1,10 @@
/*
* qla2x_tgt.h
*
* Copyright (C) 2004 - 2014 Vladislav Bolkhovitin <vst@vlnb.net>
* Copyright (C) 2004 - 2015 Vladislav Bolkhovitin <vst@vlnb.net>
* Copyright (C) 2004 - 2005 Leonid Stoljar
* Copyright (C) 2006 Nathaniel Clark <nate@misrule.us>
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* Additional file for the target driver support.
*
@@ -28,7 +28,7 @@
#include <linux/version.h>
extern request_t *qla2x00_req_pkt(scsi_qla_host_t *ha);
extern request_t *qla2x00_req_pkt(scsi_qla_host_t *vha);
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
@@ -36,25 +36,25 @@ extern request_t *qla2x00_req_pkt(scsi_qla_host_t *ha);
extern struct qla_tgt_data qla_target;
void qla_set_tgt_mode(scsi_qla_host_t *ha);
void qla_clear_tgt_mode(scsi_qla_host_t *ha);
void qla_set_tgt_mode(scsi_qla_host_t *vha);
void qla_clear_tgt_mode(scsi_qla_host_t *vha);
static inline bool qla_tgt_mode_enabled(scsi_qla_host_t *ha)
static inline bool qla_tgt_mode_enabled(scsi_qla_host_t *vha)
{
return ha->host->active_mode & MODE_TARGET;
return vha->host->active_mode & MODE_TARGET;
}
static inline bool qla_ini_mode_enabled(scsi_qla_host_t *ha)
static inline bool qla_ini_mode_enabled(scsi_qla_host_t *vha)
{
return ha->host->active_mode & MODE_INITIATOR;
return vha->host->active_mode & MODE_INITIATOR;
}
static inline void qla_reverse_ini_mode(scsi_qla_host_t *ha)
static inline void qla_reverse_ini_mode(scsi_qla_host_t *vha)
{
if (ha->host->active_mode & MODE_INITIATOR)
ha->host->active_mode &= ~MODE_INITIATOR;
if (vha->host->active_mode & MODE_INITIATOR)
vha->host->active_mode &= ~MODE_INITIATOR;
else
ha->host->active_mode |= MODE_INITIATOR;
vha->host->active_mode |= MODE_INITIATOR;
}
/********************************************************************\
@@ -72,13 +72,14 @@ static inline void qla_reverse_ini_mode(scsi_qla_host_t *ha)
* then reacquire.
*/
static inline void
__qla2x00_send_enable_lun(scsi_qla_host_t *ha, int enable)
__qla2x00_send_enable_lun(scsi_qla_host_t *vha, int enable)
{
elun_entry_t *pkt;
struct qla_hw_data *ha = vha->hw;
BUG_ON(IS_FWI2_CAPABLE(ha));
pkt = (elun_entry_t *)qla2x00_req_pkt(ha);
pkt = (elun_entry_t *)qla2x00_req_pkt(vha);
if (pkt != NULL) {
pkt->entry_type = ENABLE_LUN_TYPE;
if (enable) {
@@ -90,16 +91,16 @@ __qla2x00_send_enable_lun(scsi_qla_host_t *ha, int enable)
pkt->immed_notify_count = 0;
pkt->timeout = 0;
}
DEBUG2(printk(KERN_DEBUG
ql_dbg(ql_dbg_init, vha, 0x0077,
"scsi%lu:ENABLE_LUN IOCB imm %u cmd %u timeout %u\n",
ha->host_no, pkt->immed_notify_count,
pkt->command_count, pkt->timeout));
vha->host_no, pkt->immed_notify_count,
pkt->command_count, pkt->timeout);
/* Issue command to ISP */
qla2x00_isp_cmd(ha);
qla2x00_start_iocbs(vha, vha->req);
} else
qla_clear_tgt_mode(ha);
qla_clear_tgt_mode(vha);
#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
if (!pkt)
pr_err("%s: **** FAILED ****\n", __func__);
@@ -117,14 +118,15 @@ __qla2x00_send_enable_lun(scsi_qla_host_t *ha, int enable)
* enable = enable/disable flag.
*/
static inline void
qla2x00_send_enable_lun(scsi_qla_host_t *ha, bool enable)
qla2x00_send_enable_lun(scsi_qla_host_t *vha, bool enable)
{
struct qla_hw_data *ha = vha->hw;
if (!IS_FWI2_CAPABLE(ha)) {
unsigned long flags;
scsi_qla_host_t *pha = to_qla_parent(ha);
spin_lock_irqsave(&pha->hardware_lock, flags);
__qla2x00_send_enable_lun(ha, enable);
spin_unlock_irqrestore(&pha->hardware_lock, flags);
spin_lock_irqsave(&ha->hardware_lock, flags);
__qla2x00_send_enable_lun(vha, enable);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
}
}
@@ -132,11 +134,32 @@ extern void qla2xxx_add_targets(void);
#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)) || \
defined(FC_VPORT_CREATE_DEFINED))
extern size_t
qla2xxx_add_vtarget(u64 *port_name, u64 *node_name, u64 *parent_host);
extern size_t qla2xxx_del_vtarget(u64 *port_name);
qla2xxx_add_vtarget(u64 port_name, u64 node_name, u64 parent_host);
extern size_t qla2xxx_del_vtarget(u64 port_name);
#endif /*((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)) || \
defined(FC_VPORT_CREATE_DEFINED))*/
extern void qla_unknown_atio_work_fn(struct delayed_work *work);
#else /* CONFIG_SCSI_QLA2XXX_TARGET */
static inline bool qla_tgt_mode_enabled(scsi_qla_host_t *vha)
{
return false;
}
static inline bool qla_ini_mode_enabled(scsi_qla_host_t *vha)
{
return true;
}
#endif /* CONFIG_SCSI_QLA2XXX_TARGET */
static inline bool qla_firmware_active(scsi_qla_host_t *vha)
{
struct qla_hw_data *ha = vha->hw;
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
return qla_tgt_mode_enabled(base_vha) || qla_ini_mode_enabled(base_vha);
}
#endif /* __QLA2X_TGT_H */
+38 -34
View File
@@ -1,10 +1,10 @@
/*
* qla2x_tgt_def.h
*
* Copyright (C) 2004 - 2014 Vladislav Bolkhovitin <vst@vlnb.net>
* Copyright (C) 2004 - 2015 Vladislav Bolkhovitin <vst@vlnb.net>
* Copyright (C) 2004 - 2005 Leonid Stoljar
* Copyright (C) 2006 Nathaniel Clark <nate@misrule.us>
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* Additional file for the target driver support.
*
@@ -44,13 +44,13 @@
* Must be changed on any change in any initiator visible interfaces or
* data in the target add-on
*/
#define QLA2X_TARGET_MAGIC 270
#define QLA2X_TARGET_MAGIC 1377
/*
* Must be changed on any change in any target visible interfaces or
* data in the initiator
*/
#define QLA2X_INITIATOR_MAGIC 57225
#define QLA2X_INITIATOR_MAGIC 59232
#define QLA2X_INI_MODE_STR_EXCLUSIVE "exclusive"
#define QLA2X_INI_MODE_STR_DISABLED "disabled"
@@ -148,7 +148,7 @@ typedef struct {
uint16_t reserved_5;
uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */
uint16_t reserved_6[20];
} __packed elun_entry_t;
} __attribute__((packed)) elun_entry_t;
#define ENABLE_LUN_SUCCESS 0x01
#define ENABLE_LUN_RC_NONZERO 0x04
#define ENABLE_LUN_INVALID_REQUEST 0x06
@@ -179,7 +179,7 @@ typedef struct {
uint16_t reserved_5;
uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */
uint16_t reserved_7[20];
} __packed modify_lun_entry_t;
} __attribute__((packed)) modify_lun_entry_t;
#define MODIFY_LUN_SUCCESS 0x01
#define MODIFY_LUN_CMD_ADD BIT_0
#define MODIFY_LUN_CMD_SUB BIT_1
@@ -219,7 +219,7 @@ typedef struct {
uint16_t srr_ox_id;
uint8_t reserved_2[30];
uint16_t ox_id;
} __packed notify_entry_t;
} __attribute__((packed)) notify_entry_t;
#endif
#ifndef NOTIFY_ACK_TYPE
@@ -250,7 +250,7 @@ typedef struct {
uint8_t srr_reject_code_expl;
uint8_t reserved_2[26];
uint16_t ox_id;
} __packed nack_entry_t;
} __attribute__((packed)) nack_entry_t;
#define NOTIFY_ACK_SRR_FLAGS_ACCEPT 0
#define NOTIFY_ACK_SRR_FLAGS_REJECT 1
@@ -287,7 +287,7 @@ typedef struct {
uint8_t initiator_port_name[WWN_SIZE]; /* on qla23xx */
uint16_t reserved_32[6];
uint16_t ox_id;
} __packed atio_entry_t;
} __attribute__((packed)) atio_entry_t;
#endif
#ifndef CONTINUE_TGT_IO_TYPE
@@ -314,7 +314,7 @@ typedef struct {
uint16_t scsi_status;
uint32_t transfer_length;
uint32_t dseg_0_address[0];
} __packed ctio_common_entry_t;
} __attribute__((packed)) ctio_common_entry_t;
#define ATIO_PATH_INVALID 0x07
#define ATIO_CANT_PROV_CAP 0x16
#define ATIO_CDB_VALID 0x3D
@@ -333,7 +333,7 @@ typedef struct {
uint32_t dseg_1_length; /* Data segment 1 length. */
uint32_t dseg_2_address; /* Data segment 2 address. */
uint32_t dseg_2_length; /* Data segment 2 length. */
} __packed ctio_entry_t;
} __attribute__((packed)) ctio_entry_t;
#define CTIO_SUCCESS 0x01
#define CTIO_ABORTED 0x02
#define CTIO_INVALID_RX_ID 0x08
@@ -371,7 +371,7 @@ typedef struct {
uint16_t scsi_status;
uint16_t response_length;
uint8_t sense_data[26];
} __packed ctio_ret_entry_t;
} __attribute__((packed)) ctio_ret_entry_t;
#endif
#define ATIO_TYPE7 0x06 /* Accept target I/O entry for 24xx */
@@ -389,7 +389,7 @@ typedef struct {
uint16_t ox_id;
uint16_t rx_id;
uint32_t parameter;
} __packed fcp_hdr_t;
} __attribute__((packed)) fcp_hdr_t;
typedef struct {
uint8_t d_id[3];
@@ -404,7 +404,7 @@ typedef struct {
uint16_t rx_id;
uint16_t ox_id;
uint32_t parameter;
} __packed fcp_hdr_le_t;
} __attribute__((packed)) fcp_hdr_le_t;
#define F_CTL_EXCH_CONTEXT_RESP BIT_23
#define F_CTL_SEQ_CONTEXT_RESIP BIT_22
@@ -449,7 +449,7 @@ typedef struct {
*/
uint8_t add_cdb[4];
/* uint32_t data_length; */
} __packed fcp_cmnd_t;
} __attribute__((packed)) fcp_cmnd_t;
/*
* ISP queue - Accept Target I/O (ATIO) type 7 entry for 24xx structure
@@ -470,7 +470,7 @@ typedef struct {
#define ATIO_EXCHANGE_ADDRESS_UNKNOWN 0xFFFFFFFF
fcp_hdr_t fcp_hdr;
fcp_cmnd_t fcp_cmnd;
} __packed atio7_entry_t;
} __attribute__((packed)) atio7_entry_t;
#define CTIO_TYPE7 0x12 /* Continue target I/O entry (for 24xx) */
@@ -494,7 +494,7 @@ typedef struct {
uint8_t initiator_id[3];
uint8_t reserved;
uint32_t exchange_addr;
} __packed ctio7_common_entry_t;
} __attribute__((packed)) ctio7_common_entry_t;
typedef struct {
ctio7_common_entry_t common;
@@ -509,7 +509,7 @@ typedef struct {
uint32_t reserved3;
uint32_t dseg_0_address[2]; /* Data segment 0 address. */
uint32_t dseg_0_length; /* Data segment 0 length. */
} __packed ctio7_status0_entry_t;
} __attribute__((packed)) ctio7_status0_entry_t;
typedef struct {
ctio7_common_entry_t common;
@@ -521,7 +521,7 @@ typedef struct {
uint16_t response_len;
uint16_t reserved;
uint8_t sense_data[24];
} __packed ctio7_status1_entry_t;
} __attribute__((packed)) ctio7_status1_entry_t;
typedef struct {
uint8_t entry_type; /* Entry type. */
@@ -542,7 +542,7 @@ typedef struct {
uint16_t reserved3;
uint32_t relative_offset;
uint8_t reserved4[24];
} __packed ctio7_fw_entry_t;
} __attribute__((packed)) ctio7_fw_entry_t;
/* CTIO7 flags values */
#define CTIO7_FLAGS_SEND_STATUS BIT_15
@@ -574,19 +574,22 @@ typedef struct {
uint16_t srr_rx_id;
uint16_t status;
uint8_t status_subcode;
uint8_t reserved_3;
uint8_t fw_handle;
uint32_t exchange_address;
uint32_t srr_rel_offs;
uint16_t srr_ui;
uint16_t srr_ox_id;
uint8_t reserved_4[19];
uint8_t els_nport_id[3];
uint8_t reserved_4;
uint16_t els_nport_handle;
uint8_t reserved_5[13];
uint8_t vp_index;
uint32_t reserved_5;
uint32_t reserved_6;
uint8_t port_id[3];
uint8_t reserved_6;
uint16_t reserved_7;
uint8_t reserved_7;
uint16_t reserved_8;
uint16_t ox_id;
} __packed notify24xx_entry_t;
} __attribute__((packed)) notify24xx_entry_t;
#define ELS_PLOGI 0x3
#define ELS_FLOGI 0x4
@@ -612,7 +615,7 @@ typedef struct {
uint16_t srr_rx_id;
uint16_t status;
uint8_t status_subcode;
uint8_t reserved_3;
uint8_t fw_handle;
uint32_t exchange_address;
uint32_t srr_rel_offs;
uint16_t srr_ui;
@@ -624,7 +627,7 @@ typedef struct {
uint8_t srr_reject_code;
uint8_t reserved_5[7];
uint16_t ox_id;
} __packed nack24xx_entry_t;
} __attribute__((packed)) nack24xx_entry_t;
/*
* ISP queue - ABTS received/response entries structure definition for 24xx.
@@ -652,7 +655,7 @@ typedef struct {
fcp_hdr_le_t fcp_hdr_le;
uint8_t reserved_4[16];
uint32_t exchange_addr_to_abort;
} __packed abts24_recv_entry_t;
} __attribute__((packed)) abts24_recv_entry_t;
#define ABTS_PARAM_ABORT_SEQ BIT_0
@@ -666,7 +669,7 @@ typedef struct {
uint16_t ox_id;
uint16_t high_seq_cnt;
uint16_t low_seq_cnt;
} __packed ba_acc_le_t;
} __attribute__((packed)) ba_acc_le_t;
typedef struct {
uint8_t vendor_uniq;
@@ -675,7 +678,7 @@ typedef struct {
#define BA_RJT_REASON_CODE_INVALID_COMMAND 0x1
#define BA_RJT_REASON_CODE_UNABLE_TO_PERFORM 0x9
uint8_t reserved;
} __packed ba_rjt_le_t;
} __attribute__((packed)) ba_rjt_le_t;
typedef struct {
uint8_t entry_type; /* Entry type. */
@@ -700,10 +703,10 @@ typedef struct {
union {
ba_acc_le_t ba_acct;
ba_rjt_le_t ba_rjt;
} __packed payload;
} __attribute__((packed)) payload;
uint32_t reserved_4;
uint32_t exchange_addr_to_abort;
} __packed abts24_resp_entry_t;
} __attribute__((packed)) abts24_resp_entry_t;
typedef struct {
uint8_t entry_type; /* Entry type. */
@@ -731,7 +734,7 @@ typedef struct {
#define ABTS_RESP_SUBCODE_ERR_ABORTED_EXCH_NOT_TERM 0x1E
uint32_t error_subcode2;
uint32_t exchange_addr_to_abort;
} __packed abts24_resp_fw_entry_t;
} __attribute__((packed)) abts24_resp_fw_entry_t;
/********************************************************************\
* Type Definitions used by initiator & target halves
@@ -754,6 +757,7 @@ struct qla_tgt_data {
void (*tgt2x_ctio_completion)(scsi_qla_host_t *ha, uint32_t handle);
void (*tgt_async_event)(uint16_t code, scsi_qla_host_t *ha,
uint16_t *mailbox);
void (*tgt_try_to_dequeue_unknown_atios)(struct qla_hw_data *ha);
int (*tgt_host_action)(scsi_qla_host_t *ha, qla2x_tgt_host_action_t
action);
void (*tgt_fc_port_added)(scsi_qla_host_t *ha, fc_port_t *fcport);
+1012 -567
View File
File diff suppressed because it is too large Load Diff
+1711
View File
File diff suppressed because it is too large Load Diff
+186
View File
@@ -0,0 +1,186 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2011 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#ifndef __QLA_BSG_H
#define __QLA_BSG_H
/* BSG Vendor specific commands */
#define QL_VND_LOOPBACK 0x01
#define QL_VND_A84_RESET 0x02
#define QL_VND_A84_UPDATE_FW 0x03
#define QL_VND_A84_MGMT_CMD 0x04
#define QL_VND_IIDMA 0x05
#define QL_VND_FCP_PRIO_CFG_CMD 0x06
#define QL_VND_READ_FLASH 0x07
#define QL_VND_UPDATE_FLASH 0x08
#define QL_VND_SET_FRU_VERSION 0x0B
#define QL_VND_READ_FRU_STATUS 0x0C
#define QL_VND_WRITE_FRU_STATUS 0x0D
/* BSG Vendor specific subcode returns */
#define EXT_STATUS_OK 0
#define EXT_STATUS_ERR 1
#define EXT_STATUS_INVALID_PARAM 6
#define EXT_STATUS_MAILBOX 11
#define EXT_STATUS_NO_MEMORY 17
/* BSG definations for interpreting CommandSent field */
#define INT_DEF_LB_LOOPBACK_CMD 0
#define INT_DEF_LB_ECHO_CMD 1
/* Loopback related definations */
#define EXTERNAL_LOOPBACK 0xF2
#define ENABLE_INTERNAL_LOOPBACK 0x02
#define INTERNAL_LOOPBACK_MASK 0x000E
#define MAX_ELS_FRAME_PAYLOAD 252
#define ELS_OPCODE_BYTE 0x10
/* BSG Vendor specific definations */
#define A84_ISSUE_WRITE_TYPE_CMD 0
#define A84_ISSUE_READ_TYPE_CMD 1
#define A84_CLEANUP_CMD 2
#define A84_ISSUE_RESET_OP_FW 3
#define A84_ISSUE_RESET_DIAG_FW 4
#define A84_ISSUE_UPDATE_OPFW_CMD 5
#define A84_ISSUE_UPDATE_DIAGFW_CMD 6
struct qla84_mgmt_param {
union {
struct {
uint32_t start_addr;
} mem; /* for QLA84_MGMT_READ/WRITE_MEM */
struct {
uint32_t id;
#define QLA84_MGMT_CONFIG_ID_UIF 1
#define QLA84_MGMT_CONFIG_ID_FCOE_COS 2
#define QLA84_MGMT_CONFIG_ID_PAUSE 3
#define QLA84_MGMT_CONFIG_ID_TIMEOUTS 4
uint32_t param0;
uint32_t param1;
} config; /* for QLA84_MGMT_CHNG_CONFIG */
struct {
uint32_t type;
#define QLA84_MGMT_INFO_CONFIG_LOG_DATA 1 /* Get Config Log Data */
#define QLA84_MGMT_INFO_LOG_DATA 2 /* Get Log Data */
#define QLA84_MGMT_INFO_PORT_STAT 3 /* Get Port Statistics */
#define QLA84_MGMT_INFO_LIF_STAT 4 /* Get LIF Statistics */
#define QLA84_MGMT_INFO_ASIC_STAT 5 /* Get ASIC Statistics */
#define QLA84_MGMT_INFO_CONFIG_PARAMS 6 /* Get Config Parameters */
#define QLA84_MGMT_INFO_PANIC_LOG 7 /* Get Panic Log */
uint32_t context;
/*
* context definitions for QLA84_MGMT_INFO_CONFIG_LOG_DATA
*/
#define IC_LOG_DATA_LOG_ID_DEBUG_LOG 0
#define IC_LOG_DATA_LOG_ID_LEARN_LOG 1
#define IC_LOG_DATA_LOG_ID_FC_ACL_INGRESS_LOG 2
#define IC_LOG_DATA_LOG_ID_FC_ACL_EGRESS_LOG 3
#define IC_LOG_DATA_LOG_ID_ETHERNET_ACL_INGRESS_LOG 4
#define IC_LOG_DATA_LOG_ID_ETHERNET_ACL_EGRESS_LOG 5
#define IC_LOG_DATA_LOG_ID_MESSAGE_TRANSMIT_LOG 6
#define IC_LOG_DATA_LOG_ID_MESSAGE_RECEIVE_LOG 7
#define IC_LOG_DATA_LOG_ID_LINK_EVENT_LOG 8
#define IC_LOG_DATA_LOG_ID_DCX_LOG 9
/*
* context definitions for QLA84_MGMT_INFO_PORT_STAT
*/
#define IC_PORT_STATISTICS_PORT_NUMBER_ETHERNET_PORT0 0
#define IC_PORT_STATISTICS_PORT_NUMBER_ETHERNET_PORT1 1
#define IC_PORT_STATISTICS_PORT_NUMBER_NSL_PORT0 2
#define IC_PORT_STATISTICS_PORT_NUMBER_NSL_PORT1 3
#define IC_PORT_STATISTICS_PORT_NUMBER_FC_PORT0 4
#define IC_PORT_STATISTICS_PORT_NUMBER_FC_PORT1 5
/*
* context definitions for QLA84_MGMT_INFO_LIF_STAT
*/
#define IC_LIF_STATISTICS_LIF_NUMBER_ETHERNET_PORT0 0
#define IC_LIF_STATISTICS_LIF_NUMBER_ETHERNET_PORT1 1
#define IC_LIF_STATISTICS_LIF_NUMBER_FC_PORT0 2
#define IC_LIF_STATISTICS_LIF_NUMBER_FC_PORT1 3
#define IC_LIF_STATISTICS_LIF_NUMBER_CPU 6
} info; /* for QLA84_MGMT_GET_INFO */
} u;
};
struct qla84_msg_mgmt {
uint16_t cmd;
#define QLA84_MGMT_READ_MEM 0x00
#define QLA84_MGMT_WRITE_MEM 0x01
#define QLA84_MGMT_CHNG_CONFIG 0x02
#define QLA84_MGMT_GET_INFO 0x03
uint16_t rsrvd;
struct qla84_mgmt_param mgmtp;/* parameters for cmd */
uint32_t len; /* bytes in payload following this struct */
uint8_t payload[0]; /* payload for cmd */
};
struct qla_bsg_a84_mgmt {
struct qla84_msg_mgmt mgmt;
} __attribute__ ((packed));
struct qla_scsi_addr {
uint16_t bus;
uint16_t target;
} __attribute__ ((packed));
struct qla_ext_dest_addr {
union {
uint8_t wwnn[8];
uint8_t wwpn[8];
uint8_t id[4];
struct qla_scsi_addr scsi_addr;
} dest_addr;
uint16_t dest_type;
#define EXT_DEF_TYPE_WWPN 2
uint16_t lun;
uint16_t padding[2];
} __attribute__ ((packed));
struct qla_port_param {
struct qla_ext_dest_addr fc_scsi_addr;
uint16_t mode;
uint16_t speed;
} __attribute__ ((packed));
/* FRU VPD */
#define MAX_FRU_SIZE 36
struct qla_field_address {
uint16_t offset;
uint16_t device;
uint16_t option;
} __packed;
struct qla_field_info {
uint8_t version[MAX_FRU_SIZE];
} __packed;
struct qla_image_version {
struct qla_field_address field_address;
struct qla_field_info field_info;
} __packed;
struct qla_image_version_list {
uint32_t count;
struct qla_image_version version[0];
} __packed;
struct qla_status_reg {
struct qla_field_address field_address;
uint8_t status_reg;
uint8_t reserved[7];
} __packed;
#endif
+1310 -128
View File
File diff suppressed because it is too large Load Diff
+169 -123
View File
@@ -1,132 +1,11 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2008 QLogic Corporation
* Copyright (c) 2003-2011 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
/*
* Driver debug definitions.
*/
/* #define QL_DEBUG_LEVEL_1 */ /* Output register accesses to COM1 */
/* #define QL_DEBUG_LEVEL_2 */ /* Output error msgs to COM1 */
/* #define QL_DEBUG_LEVEL_3 */ /* Output function trace msgs to COM1 */
/* #define QL_DEBUG_LEVEL_4 */ /* Output NVRAM trace msgs to COM1 */
/* #define QL_DEBUG_LEVEL_5 */ /* Output ring trace msgs to COM1 */
/* #define QL_DEBUG_LEVEL_6 */ /* Output WATCHDOG timer trace to COM1 */
/* #define QL_DEBUG_LEVEL_7 */ /* Output RISC load trace msgs to COM1 */
/* #define QL_DEBUG_LEVEL_8 */ /* Output ring saturation msgs to COM1 */
/* #define QL_DEBUG_LEVEL_9 */ /* Output IOCTL trace msgs */
/* #define QL_DEBUG_LEVEL_10 */ /* Output IOCTL error msgs */
/* #define QL_DEBUG_LEVEL_11 */ /* Output Mbx Cmd trace msgs */
/* #define QL_DEBUG_LEVEL_12 */ /* Output IP trace msgs */
/* #define QL_DEBUG_LEVEL_13 */ /* Output fdmi function trace msgs */
/* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */
/* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */
/* #define QL_DEBUG_LEVEL_16 */ /* Output ISP84XX trace msgs */
/*
* Macros use for debugging the driver.
*/
#define DEBUG(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#if defined(QL_DEBUG_LEVEL_1)
#define DEBUG1(x) do {x;} while (0)
#else
#define DEBUG1(x) do {} while (0)
#endif
#define DEBUG2(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#define DEBUG2_3(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#define DEBUG2_3_11(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#define DEBUG2_9_10(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#define DEBUG2_11(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#define DEBUG2_13(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#define DEBUG2_16(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#if defined(QL_DEBUG_LEVEL_3)
#define DEBUG3(x) do {x;} while (0)
#define DEBUG3_11(x) do {x;} while (0)
#else
#define DEBUG3(x) do {} while (0)
#endif
#if defined(QL_DEBUG_LEVEL_4)
#define DEBUG4(x) do {x;} while (0)
#else
#define DEBUG4(x) do {} while (0)
#endif
#if defined(QL_DEBUG_LEVEL_5)
#define DEBUG5(x) do {x;} while (0)
#else
#define DEBUG5(x) do {} while (0)
#endif
#if defined(QL_DEBUG_LEVEL_7)
#define DEBUG7(x) do {x;} while (0)
#else
#define DEBUG7(x) do {} while (0)
#endif
#if defined(QL_DEBUG_LEVEL_9)
#define DEBUG9(x) do {x;} while (0)
#define DEBUG9_10(x) do {x;} while (0)
#else
#define DEBUG9(x) do {} while (0)
#endif
#if defined(QL_DEBUG_LEVEL_10)
#define DEBUG10(x) do {x;} while (0)
#define DEBUG9_10(x) do {x;} while (0)
#else
#define DEBUG10(x) do {} while (0)
#if !defined(DEBUG9_10)
#define DEBUG9_10(x) do {} while (0)
#endif
#endif
#if defined(QL_DEBUG_LEVEL_11)
#define DEBUG11(x) do{x;} while(0)
#if !defined(DEBUG3_11)
#define DEBUG3_11(x) do{x;} while(0)
#endif
#else
#define DEBUG11(x) do{} while(0)
#if !defined(QL_DEBUG_LEVEL_3)
#define DEBUG3_11(x) do{} while(0)
#endif
#endif
#if defined(QL_DEBUG_LEVEL_12)
#define DEBUG12(x) do {x;} while (0)
#else
#define DEBUG12(x) do {} while (0)
#endif
#if defined(QL_DEBUG_LEVEL_13)
#define DEBUG13(x) do {x;} while (0)
#else
#define DEBUG13(x) do {} while (0)
#endif
#if defined(QL_DEBUG_LEVEL_14)
#define DEBUG14(x) do {x;} while (0)
#else
#define DEBUG14(x) do {} while (0)
#endif
#if defined(QL_DEBUG_LEVEL_15)
#define DEBUG15(x) do {x;} while (0)
#else
#define DEBUG15(x) do {} while (0)
#endif
#if defined(QL_DEBUG_LEVEL_16)
#define DEBUG16(x) do {x;} while (0)
#else
#define DEBUG16(x) do {} while (0)
#endif
#include "qla_def.h"
/*
* Firmware Dump structure definition
@@ -247,6 +126,93 @@ struct qla25xx_fw_dump {
uint32_t ext_mem[1];
};
struct qla81xx_fw_dump {
uint32_t host_status;
uint32_t host_risc_reg[32];
uint32_t pcie_regs[4];
uint32_t host_reg[32];
uint32_t shadow_reg[11];
uint32_t risc_io_reg;
uint16_t mailbox_reg[32];
uint32_t xseq_gp_reg[128];
uint32_t xseq_0_reg[48];
uint32_t xseq_1_reg[16];
uint32_t rseq_gp_reg[128];
uint32_t rseq_0_reg[32];
uint32_t rseq_1_reg[16];
uint32_t rseq_2_reg[16];
uint32_t aseq_gp_reg[128];
uint32_t aseq_0_reg[32];
uint32_t aseq_1_reg[16];
uint32_t aseq_2_reg[16];
uint32_t cmd_dma_reg[16];
uint32_t req0_dma_reg[15];
uint32_t resp0_dma_reg[15];
uint32_t req1_dma_reg[15];
uint32_t xmt0_dma_reg[32];
uint32_t xmt1_dma_reg[32];
uint32_t xmt2_dma_reg[32];
uint32_t xmt3_dma_reg[32];
uint32_t xmt4_dma_reg[32];
uint32_t xmt_data_dma_reg[16];
uint32_t rcvt0_data_dma_reg[32];
uint32_t rcvt1_data_dma_reg[32];
uint32_t risc_gp_reg[128];
uint32_t lmc_reg[128];
uint32_t fpm_hdw_reg[224];
uint32_t fb_hdw_reg[208];
uint32_t code_ram[0x2000];
uint32_t ext_mem[1];
};
struct qla83xx_fw_dump {
uint32_t host_status;
uint32_t host_risc_reg[48];
uint32_t pcie_regs[4];
uint32_t host_reg[32];
uint32_t shadow_reg[11];
uint32_t risc_io_reg;
uint16_t mailbox_reg[32];
uint32_t xseq_gp_reg[256];
uint32_t xseq_0_reg[48];
uint32_t xseq_1_reg[16];
uint32_t xseq_2_reg[16];
uint32_t rseq_gp_reg[256];
uint32_t rseq_0_reg[32];
uint32_t rseq_1_reg[16];
uint32_t rseq_2_reg[16];
uint32_t rseq_3_reg[16];
uint32_t aseq_gp_reg[256];
uint32_t aseq_0_reg[32];
uint32_t aseq_1_reg[16];
uint32_t aseq_2_reg[16];
uint32_t aseq_3_reg[16];
uint32_t cmd_dma_reg[64];
uint32_t req0_dma_reg[15];
uint32_t resp0_dma_reg[15];
uint32_t req1_dma_reg[15];
uint32_t xmt0_dma_reg[32];
uint32_t xmt1_dma_reg[32];
uint32_t xmt2_dma_reg[32];
uint32_t xmt3_dma_reg[32];
uint32_t xmt4_dma_reg[32];
uint32_t xmt_data_dma_reg[16];
uint32_t rcvt0_data_dma_reg[32];
uint32_t rcvt1_data_dma_reg[32];
uint32_t risc_gp_reg[128];
uint32_t lmc_reg[128];
uint32_t fpm_hdw_reg[256];
uint32_t rq0_array_reg[256];
uint32_t rq1_array_reg[256];
uint32_t rp0_array_reg[256];
uint32_t rp1_array_reg[256];
uint32_t queue_control_reg[16];
uint32_t fb_hdw_reg[432];
uint32_t at0_array_reg[128];
uint32_t code_ram[0x2400];
uint32_t ext_mem[1];
};
#define EFT_NUM_BUFFERS 4
#define EFT_BYTES_PER_BUFFER 0x4000
#define EFT_SIZE ((EFT_BYTES_PER_BUFFER) * (EFT_NUM_BUFFERS))
@@ -266,8 +232,31 @@ struct qla2xxx_fce_chain {
uint32_t eregs[8];
};
struct qla2xxx_mq_chain {
uint32_t type;
uint32_t chain_size;
uint32_t count;
uint32_t qregs[4 * QLA_MQ_SIZE];
};
struct qla2xxx_mqueue_header {
uint32_t queue;
#define TYPE_REQUEST_QUEUE 0x1
#define TYPE_RESPONSE_QUEUE 0x2
uint32_t number;
uint32_t size;
};
struct qla2xxx_mqueue_chain {
uint32_t type;
uint32_t chain_size;
};
#define DUMP_CHAIN_VARIANT 0x80000000
#define DUMP_CHAIN_FCE 0x7FFFFAF0
#define DUMP_CHAIN_MQ 0x7FFFFAF1
#define DUMP_CHAIN_QUEUE 0x7FFFFAF2
#define DUMP_CHAIN_LAST 0x80000000
struct qla2xxx_fw_dump {
@@ -300,5 +289,62 @@ struct qla2xxx_fw_dump {
struct qla2300_fw_dump isp23;
struct qla24xx_fw_dump isp24;
struct qla25xx_fw_dump isp25;
struct qla81xx_fw_dump isp81;
struct qla83xx_fw_dump isp83;
} isp;
};
#define QL_MSGHDR "qla2xxx"
#define QL_DBG_DEFAULT1_MASK 0x1e400000
#define ql_log_fatal 0 /* display fatal errors */
#define ql_log_warn 1 /* display critical errors */
#define ql_log_info 2 /* display all recovered errors */
#define ql_log_all 3 /* This value is only used by ql_errlev.
* No messages will use this value.
* This should be always highest value
* as compared to other log levels.
*/
extern int ql_errlev;
void __attribute__((format (printf, 4, 5)))
ql_dbg(uint32_t, scsi_qla_host_t *vha, int32_t, const char *fmt, ...);
void __attribute__((format (printf, 4, 5)))
ql_dbg_pci(uint32_t, struct pci_dev *pdev, int32_t, const char *fmt, ...);
void __attribute__((format (printf, 4, 5)))
ql_log(uint32_t, scsi_qla_host_t *vha, int32_t, const char *fmt, ...);
void __attribute__((format (printf, 4, 5)))
ql_log_pci(uint32_t, struct pci_dev *pdev, int32_t, const char *fmt, ...);
/* Debug Levels */
/* The 0x40000000 is the max value any debug level can have
* as ql2xextended_error_logging is of type signed int
*/
#define ql_dbg_init 0x40000000 /* Init Debug */
#define ql_dbg_mbx 0x20000000 /* MBX Debug */
#define ql_dbg_disc 0x10000000 /* Device Discovery Debug */
#define ql_dbg_io 0x08000000 /* IO Tracing Debug */
#define ql_dbg_dpc 0x04000000 /* DPC Thead Debug */
#define ql_dbg_async 0x02000000 /* Async events Debug */
#define ql_dbg_timer 0x01000000 /* Timer Debug */
#define ql_dbg_user 0x00800000 /* User Space Interations Debug */
#define ql_dbg_taskm 0x00400000 /* Task Management Debug */
#define ql_dbg_aer 0x00200000 /* AER/EEH Debug */
#define ql_dbg_multiq 0x00100000 /* MultiQ Debug */
#define ql_dbg_p3p 0x00080000 /* P3P specific Debug */
#define ql_dbg_vport 0x00040000 /* Virtual Port Debug */
#define ql_dbg_buffer 0x00020000 /* For dumping the buffer/regs */
#define ql_dbg_misc 0x00010000 /* For dumping everything that is not
* not covered by upper categories
*/
#define ql_dbg_verbose 0x00008000 /* More verbosity for each level
* This is to be used with other levels where
* more verbosity is required. It might not
* be applicable to all the levels.
*/
#define ql_dbg_tgt 0x00004000 /* Target mode */
#define ql_dbg_tgt_mgt 0x00002000 /* Target mode management */
#define ql_dbg_tgt_tmr 0x00001000 /* Target mode task management */
+836 -467
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -72,7 +72,7 @@ static char *qla2x00_model_name[QLA_MODEL_NAMES*2] = {
"QLA2462", "Sun PCI-X 2.0 to 4Gb FC, Dual Channel", /* 0x141 */
"QLE2460", "Sun PCI-Express to 2Gb FC, Single Channel", /* 0x142 */
"QLE2462", "Sun PCI-Express to 4Gb FC, Single Channel", /* 0x143 */
"QEM2462" "Server I/O Module 4Gb FC, Dual Channel", /* 0x144 */
"QEM2462", "Server I/O Module 4Gb FC, Dual Channel", /* 0x144 */
"QLE2440", "PCI-Express to 4Gb FC, Single Channel", /* 0x145 */
"QLE2464", "PCI-Express to 4Gb FC, Quad Channel", /* 0x146 */
"QLA2440", "PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x147 */
+26 -20
View File
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2008 QLogic Corporation
* Copyright (c) 2003-2011 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -15,10 +15,11 @@ static atomic_t qla2x00_dfs_root_count;
static int
qla2x00_dfs_fce_show(struct seq_file *s, void *unused)
{
scsi_qla_host_t *ha = s->private;
scsi_qla_host_t *vha = s->private;
uint32_t cnt;
uint32_t *fce;
uint64_t fce_start;
struct qla_hw_data *ha = vha->hw;
mutex_lock(&ha->fce_mutex);
@@ -51,7 +52,8 @@ qla2x00_dfs_fce_show(struct seq_file *s, void *unused)
static int
qla2x00_dfs_fce_open(struct inode *inode, struct file *file)
{
scsi_qla_host_t *ha = inode->i_private;
scsi_qla_host_t *vha = inode->i_private;
struct qla_hw_data *ha = vha->hw;
int rval;
if (!ha->flags.fce_enabled)
@@ -60,22 +62,23 @@ qla2x00_dfs_fce_open(struct inode *inode, struct file *file)
mutex_lock(&ha->fce_mutex);
/* Pause tracing to flush FCE buffers. */
rval = qla2x00_disable_fce_trace(ha, &ha->fce_wr, &ha->fce_rd);
rval = qla2x00_disable_fce_trace(vha, &ha->fce_wr, &ha->fce_rd);
if (rval)
qla_printk(KERN_WARNING, ha,
ql_dbg(ql_dbg_user, vha, 0x705c,
"DebugFS: Unable to disable FCE (%d).\n", rval);
ha->flags.fce_enabled = 0;
mutex_unlock(&ha->fce_mutex);
out:
return single_open(file, qla2x00_dfs_fce_show, ha);
return single_open(file, qla2x00_dfs_fce_show, vha);
}
static int
qla2x00_dfs_fce_release(struct inode *inode, struct file *file)
{
scsi_qla_host_t *ha = inode->i_private;
scsi_qla_host_t *vha = inode->i_private;
struct qla_hw_data *ha = vha->hw;
int rval;
if (ha->flags.fce_enabled)
@@ -86,10 +89,10 @@ qla2x00_dfs_fce_release(struct inode *inode, struct file *file)
/* Re-enable FCE tracing. */
ha->flags.fce_enabled = 1;
memset(ha->fce, 0, fce_calc_size(ha->fce_bufs));
rval = qla2x00_enable_fce_trace(ha, ha->fce_dma, ha->fce_bufs,
rval = qla2x00_enable_fce_trace(vha, ha->fce_dma, ha->fce_bufs,
ha->fce_mb, &ha->fce_bufs);
if (rval) {
qla_printk(KERN_WARNING, ha,
ql_dbg(ql_dbg_user, vha, 0x700d,
"DebugFS: Unable to reinitialize FCE (%d).\n", rval);
ha->flags.fce_enabled = 0;
}
@@ -107,9 +110,11 @@ static const struct file_operations dfs_fce_ops = {
};
int
qla2x00_dfs_setup(scsi_qla_host_t *ha)
qla2x00_dfs_setup(scsi_qla_host_t *vha)
{
if (!IS_QLA25XX(ha))
struct qla_hw_data *ha = vha->hw;
if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha))
goto out;
if (!ha->fce)
goto out;
@@ -120,8 +125,8 @@ qla2x00_dfs_setup(scsi_qla_host_t *ha)
atomic_set(&qla2x00_dfs_root_count, 0);
qla2x00_dfs_root = debugfs_create_dir(QLA2XXX_DRIVER_NAME, NULL);
if (!qla2x00_dfs_root) {
qla_printk(KERN_NOTICE, ha,
"DebugFS: Unable to create root directory.\n");
ql_log(ql_log_warn, vha, 0x00f7,
"Unable to create debugfs root directory.\n");
goto out;
}
@@ -130,21 +135,21 @@ create_dir:
goto create_nodes;
mutex_init(&ha->fce_mutex);
ha->dfs_dir = debugfs_create_dir(ha->host_str, qla2x00_dfs_root);
ha->dfs_dir = debugfs_create_dir(vha->host_str, qla2x00_dfs_root);
if (!ha->dfs_dir) {
qla_printk(KERN_NOTICE, ha,
"DebugFS: Unable to create ha directory.\n");
ql_log(ql_log_warn, vha, 0x00f8,
"Unable to create debugfs ha directory.\n");
goto out;
}
atomic_inc(&qla2x00_dfs_root_count);
create_nodes:
ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, ha,
ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, vha,
&dfs_fce_ops);
if (!ha->dfs_fce) {
qla_printk(KERN_NOTICE, ha,
"DebugFS: Unable to fce node.\n");
ql_log(ql_log_warn, vha, 0x00f9,
"Unable to create debugfs fce node.\n");
goto out;
}
out:
@@ -152,8 +157,9 @@ out:
}
int
qla2x00_dfs_remove(scsi_qla_host_t *ha)
qla2x00_dfs_remove(scsi_qla_host_t *vha)
{
struct qla_hw_data *ha = vha->hw;
if (ha->dfs_fce) {
debugfs_remove(ha->dfs_fce);
ha->dfs_fce = NULL;
+587 -21
View File
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2008 QLogic Corporation
* Copyright (c) 2003-2011 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -26,6 +26,7 @@
#define PDO_FORCE_ADISC BIT_1
#define PDO_FORCE_PLOGI BIT_0
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
struct qla_port23_data {
uint8_t port_name[WWN_SIZE];
uint16_t loop_id;
@@ -36,6 +37,7 @@ struct qla_port24_data {
uint16_t loop_id;
uint16_t reserved;
};
#endif /* CONFIG_SCSI_QLA2XXX_TARGET */
#define PORT_DATABASE_24XX_SIZE 64
struct port_database_24xx {
@@ -309,7 +311,9 @@ struct init_cb_24xx {
uint32_t response_q_address[2];
uint32_t prio_request_q_address[2];
uint8_t reserved_2[8];
uint16_t msix;
uint16_t msix_atio;
uint8_t reserved_2[4];
uint16_t atio_q_inpointer;
uint16_t atio_q_length;
@@ -382,8 +386,9 @@ struct init_cb_24xx {
* BIT 17-31 = Reserved
*/
uint32_t firmware_options_3;
uint8_t reserved_3[24];
uint16_t qos;
uint16_t rid;
uint8_t reserved_3[20];
};
/*
@@ -408,6 +413,7 @@ struct cmd_type_6 {
struct scsi_lun lun; /* FCP LUN (BE). */
uint16_t control_flags; /* Control flags. */
#define CF_DIF_SEG_DESCR_ENABLE BIT_3
#define CF_DATA_SEG_DESCR_ENABLE BIT_2
#define CF_READ_DATA BIT_1
#define CF_WRITE_DATA BIT_0
@@ -423,8 +429,7 @@ struct cmd_type_6 {
uint8_t vp_index;
uint32_t fcp_data_dseg_address[2]; /* Data segment address. */
uint16_t fcp_data_dseg_len; /* Data segment length. */
uint16_t reserved_1; /* MUST be set to 0. */
uint32_t fcp_data_dseg_len; /* Data segment length. */
};
#define COMMAND_TYPE_7 0x18 /* Command Type 7 entry */
@@ -474,6 +479,43 @@ struct cmd_type_7 {
uint32_t dseg_0_len; /* Data segment 0 length. */
};
#define COMMAND_TYPE_CRC_2 0x6A /* Command Type CRC_2 (Type 6)
* (T10-DIF) */
struct cmd_type_crc_2 {
uint8_t entry_type; /* Entry type. */
uint8_t entry_count; /* Entry count. */
uint8_t sys_define; /* System defined. */
uint8_t entry_status; /* Entry Status. */
uint32_t handle; /* System handle. */
uint16_t nport_handle; /* N_PORT handle. */
uint16_t timeout; /* Command timeout. */
uint16_t dseg_count; /* Data segment count. */
uint16_t fcp_rsp_dseg_len; /* FCP_RSP DSD length. */
struct scsi_lun lun; /* FCP LUN (BE). */
uint16_t control_flags; /* Control flags. */
uint16_t fcp_cmnd_dseg_len; /* Data segment length. */
uint32_t fcp_cmnd_dseg_address[2]; /* Data segment address. */
uint32_t fcp_rsp_dseg_address[2]; /* Data segment address. */
uint32_t byte_count; /* Total byte count. */
uint8_t port_id[3]; /* PortID of destination port. */
uint8_t vp_index;
uint32_t crc_context_address[2]; /* Data segment address. */
uint16_t crc_context_len; /* Data segment length. */
uint16_t reserved_1; /* MUST be set to 0. */
};
/*
* ISP queue - status entry structure definition.
*/
@@ -504,10 +546,22 @@ struct sts_entry_24xx {
uint32_t sense_len; /* FCP SENSE length. */
uint32_t rsp_data_len; /* FCP response data length. */
uint8_t data[28]; /* FCP response/sense information. */
/*
* If DIF Error is set in comp_status, these additional fields are
* defined:
*
* !!! NOTE: Firmware sends expected/actual DIF data in big endian
* format; but all of the "data" field gets swab32-d in the beginning
* of qla2x00_status_entry().
*
* &data[10] : uint8_t report_runt_bg[2]; - computed guard
* &data[12] : uint8_t actual_dif[8]; - DIF Data received
* &data[20] : uint8_t expected_dif[8]; - DIF Data computed
*/
};
/*
* Status entry completion status
*/
@@ -635,6 +689,39 @@ struct els_entry_24xx {
uint32_t rx_len; /* Data segment 1 length. */
};
struct els_sts_entry_24xx {
uint8_t entry_type; /* Entry type. */
uint8_t entry_count; /* Entry count. */
uint8_t sys_define; /* System Defined. */
uint8_t entry_status; /* Entry Status. */
uint32_t handle; /* System handle. */
uint16_t comp_status;
uint16_t nport_handle; /* N_PORT handle. */
uint16_t reserved_1;
uint8_t vp_index;
uint8_t sof_type;
uint32_t rx_xchg_address; /* Receive exchange address. */
uint16_t reserved_2;
uint8_t opcode;
uint8_t reserved_3;
uint8_t port_id[3];
uint8_t reserved_4;
uint16_t reserved_5;
uint16_t control_flags; /* Control flags. */
uint32_t total_byte_count;
uint32_t error_subcode_1;
uint32_t error_subcode_2;
};
/*
* ISP queue - Mailbox Command entry structure definition.
*/
@@ -764,7 +851,8 @@ struct abort_entry_24xx {
uint32_t handle_to_abort; /* System handle to abort. */
uint8_t reserved_1[32];
uint16_t req_que_no;
uint8_t reserved_1[30];
uint8_t port_id[3]; /* PortID of destination port. */
uint8_t vp_index;
@@ -799,14 +887,25 @@ struct device_reg_24xx {
#define FA_RISC_CODE_ADDR 0x20000
#define FA_RISC_CODE_SEGMENTS 2
#define FA_FLASH_DESCR_ADDR_24 0x11000
#define FA_FLASH_LAYOUT_ADDR_24 0x11400
#define FA_NPIV_CONF0_ADDR_24 0x16000
#define FA_NPIV_CONF1_ADDR_24 0x17000
#define FA_FW_AREA_ADDR 0x40000
#define FA_VPD_NVRAM_ADDR 0x48000
#define FA_FEATURE_ADDR 0x4C000
#define FA_FLASH_DESCR_ADDR 0x50000
#define FA_FLASH_LAYOUT_ADDR 0x50400
#define FA_HW_EVENT0_ADDR 0x54000
#define FA_HW_EVENT1_ADDR 0x54200
#define FA_HW_EVENT1_ADDR 0x54400
#define FA_HW_EVENT_SIZE 0x200
#define FA_HW_EVENT_ENTRY_SIZE 4
#define FA_NPIV_CONF0_ADDR 0x5C000
#define FA_NPIV_CONF1_ADDR 0x5D000
#define FA_FCP_PRIO0_ADDR 0x10000
#define FA_FCP_PRIO1_ADDR 0x12000
/*
* Flash Error Log Event Codes.
*/
@@ -816,10 +915,6 @@ struct device_reg_24xx {
#define HW_EVENT_NVRAM_CHKSUM_ERR 0xF023
#define HW_EVENT_FLASH_FW_ERR 0xF024
#define FA_BOOT_LOG_ADDR 0x58000
#define FA_FW_DUMP0_ADDR 0x60000
#define FA_FW_DUMP1_ADDR 0x70000
uint32_t flash_data; /* Flash/NVRAM BIOS data. */
uint32_t ctrl_status; /* Control/Status. */
@@ -880,7 +975,6 @@ struct device_reg_24xx {
/* HCCR statuses. */
#define HCCRX_HOST_INT BIT_6 /* Host to RISC interrupt bit. */
#define HCCRX_RISC_RESET BIT_5 /* RISC Reset mode bit. */
#define HCCRX_RISC_PAUSE BIT_4 /* RISC Pause mode bit. */
/* HCCR commands. */
/* NOOP. */
#define HCCRX_NOOP 0x00000000
@@ -993,12 +1087,12 @@ struct device_reg_24xx {
#define MIN_MULTI_ID_FABRIC 64 /* Must be power-of-2. */
#define MAX_MULTI_ID_FABRIC 256 /* ... */
#define for_each_mapped_vp_idx(_ha, _idx) \
for (_idx = find_next_bit((_ha)->vp_idx_map, \
(_ha)->max_npiv_vports + 1, 1); \
_idx <= (_ha)->max_npiv_vports; \
_idx = find_next_bit((_ha)->vp_idx_map, \
(_ha)->max_npiv_vports + 1, _idx + 1)) \
#define for_each_mapped_vp_idx(_vha, _idx) \
for (_idx = find_next_bit((_vha)->hw->vp_idx_map, \
(_vha)->hw->max_npiv_vports + 1, 1); \
_idx <= (_vha)->hw->max_npiv_vports; \
_idx = find_next_bit((_vha)->hw->vp_idx_map, \
(_vha)->hw->max_npiv_vports + 1, _idx + 1)) \
struct mid_conf_entry_24xx {
uint16_t reserved_1;
@@ -1129,7 +1223,7 @@ struct vp_config_entry_24xx {
uint16_t id;
uint16_t reserved_4;
uint16_t hopct;
uint8_t reserved_5;
uint8_t reserved_5[2];
};
#define VP_RPT_ID_IOCB_TYPE 0x32 /* Report ID Acquisition entry. */
@@ -1213,6 +1307,72 @@ struct qla_fdt_layout {
uint8_t unused2[65];
};
/* Flash Layout Table ********************************************************/
struct qla_flt_location {
uint8_t sig[4];
uint16_t start_lo;
uint16_t start_hi;
uint8_t version;
uint8_t unused[5];
uint16_t checksum;
};
struct qla_flt_header {
uint16_t version;
uint16_t length;
uint16_t checksum;
uint16_t unused;
};
#define FLT_REG_FW 0x01
#define FLT_REG_BOOT_CODE 0x07
#define FLT_REG_VPD_0 0x14
#define FLT_REG_NVRAM_0 0x15
#define FLT_REG_VPD_1 0x16
#define FLT_REG_NVRAM_1 0x17
#define FLT_REG_FDT 0x1a
#define FLT_REG_FLT 0x1c
#define FLT_REG_HW_EVENT_0 0x1d
#define FLT_REG_HW_EVENT_1 0x1f
#define FLT_REG_NPIV_CONF_0 0x29
#define FLT_REG_NPIV_CONF_1 0x2a
#define FLT_REG_GOLD_FW 0x2f
#define FLT_REG_FCP_PRIO_0 0x87
#define FLT_REG_FCP_PRIO_1 0x88
#define FLT_REG_FCOE_FW 0xA4
#define FLT_REG_FCOE_VPD_0 0xA9
#define FLT_REG_FCOE_NVRAM_0 0xAA
#define FLT_REG_FCOE_VPD_1 0xAB
#define FLT_REG_FCOE_NVRAM_1 0xAC
struct qla_flt_region {
uint32_t code;
uint32_t size;
uint32_t start;
uint32_t end;
};
/* Flash NPIV Configuration Table ********************************************/
struct qla_npiv_header {
uint8_t sig[2];
uint16_t version;
uint16_t entries;
uint16_t unused[4];
uint16_t checksum;
};
struct qla_npiv_entry {
uint16_t flags;
uint16_t vf_id;
uint8_t q_qos;
uint8_t f_qos;
uint16_t unused1;
uint8_t port_name[WWN_SIZE];
uint8_t node_name[WWN_SIZE];
};
/* 84XX Support **************************************************************/
#define MBA_ISP84XX_ALERT 0x800f /* Alert Notification. */
@@ -1335,4 +1495,410 @@ struct access_chip_rsp_84xx {
uint32_t reserved[12];
};
/* 81XX Support **************************************************************/
#define MBA_DCBX_START 0x8016
#define MBA_DCBX_COMPLETE 0x8030
#define MBA_FCF_CONF_ERR 0x8031
#define MBA_DCBX_PARAM_UPDATE 0x8032
#define MBA_IDC_COMPLETE 0x8100
#define MBA_IDC_NOTIFY 0x8101
#define MBA_IDC_TIME_EXT 0x8102
#define MBC_IDC_ACK 0x101
#define MBC_RESTART_MPI_FW 0x3d
#define MBC_FLASH_ACCESS_CTRL 0x3e /* Control flash access. */
#define MBC_GET_XGMAC_STATS 0x7a
#define MBC_GET_DCBX_PARAMS 0x51
/*
* ISP83xx mailbox commands
*/
#define MBC_WRITE_REMOTE_REG 0x0001 /* Write remote register */
/* Flash access control option field bit definitions */
#define FAC_OPT_FORCE_SEMAPHORE BIT_15
#define FAC_OPT_REQUESTOR_ID BIT_14
#define FAC_OPT_CMD_SUBCODE 0xff
/* Flash access control command subcodes */
#define FAC_OPT_CMD_WRITE_PROTECT 0x00
#define FAC_OPT_CMD_WRITE_ENABLE 0x01
#define FAC_OPT_CMD_ERASE_SECTOR 0x02
#define FAC_OPT_CMD_LOCK_SEMAPHORE 0x03
#define FAC_OPT_CMD_UNLOCK_SEMAPHORE 0x04
#define FAC_OPT_CMD_GET_SECTOR_SIZE 0x05
struct nvram_81xx {
/* NVRAM header. */
uint8_t id[4];
uint16_t nvram_version;
uint16_t reserved_0;
/* Firmware Initialization Control Block. */
uint16_t version;
uint16_t reserved_1;
uint16_t frame_payload_size;
uint16_t execution_throttle;
uint16_t exchange_count;
uint16_t reserved_2;
uint8_t port_name[WWN_SIZE];
uint8_t node_name[WWN_SIZE];
uint16_t login_retry_count;
uint16_t reserved_3;
uint16_t interrupt_delay_timer;
uint16_t login_timeout;
uint32_t firmware_options_1;
uint32_t firmware_options_2;
uint32_t firmware_options_3;
uint16_t reserved_4[4];
/* Offset 64. */
uint8_t enode_mac[6];
uint16_t reserved_5[5];
/* Offset 80. */
uint16_t reserved_6[24];
/* Offset 128. */
uint16_t ex_version;
uint8_t prio_fcf_matching_flags;
uint8_t reserved_6_1[3];
uint16_t pri_fcf_vlan_id;
uint8_t pri_fcf_fabric_name[8];
uint16_t reserved_6_2[7];
uint8_t spma_mac_addr[6];
uint16_t reserved_6_3[14];
/* Offset 192. */
uint16_t reserved_7[32];
/*
* BIT 0 = Enable spinup delay
* BIT 1 = Disable BIOS
* BIT 2 = Enable Memory Map BIOS
* BIT 3 = Enable Selectable Boot
* BIT 4 = Disable RISC code load
* BIT 5 = Disable Serdes
* BIT 6 = Opt boot mode
* BIT 7 = Interrupt enable
*
* BIT 8 = EV Control enable
* BIT 9 = Enable lip reset
* BIT 10 = Enable lip full login
* BIT 11 = Enable target reset
* BIT 12 = Stop firmware
* BIT 13 = Enable nodename option
* BIT 14 = Default WWPN valid
* BIT 15 = Enable alternate WWN
*
* BIT 16 = CLP LUN string
* BIT 17 = CLP Target string
* BIT 18 = CLP BIOS enable string
* BIT 19 = CLP Serdes string
* BIT 20 = CLP WWPN string
* BIT 21 = CLP WWNN string
* BIT 22 =
* BIT 23 =
* BIT 24 = Keep WWPN
* BIT 25 = Temp WWPN
* BIT 26-31 =
*/
uint32_t host_p;
uint8_t alternate_port_name[WWN_SIZE];
uint8_t alternate_node_name[WWN_SIZE];
uint8_t boot_port_name[WWN_SIZE];
uint16_t boot_lun_number;
uint16_t reserved_8;
uint8_t alt1_boot_port_name[WWN_SIZE];
uint16_t alt1_boot_lun_number;
uint16_t reserved_9;
uint8_t alt2_boot_port_name[WWN_SIZE];
uint16_t alt2_boot_lun_number;
uint16_t reserved_10;
uint8_t alt3_boot_port_name[WWN_SIZE];
uint16_t alt3_boot_lun_number;
uint16_t reserved_11;
/*
* BIT 0 = Selective Login
* BIT 1 = Alt-Boot Enable
* BIT 2 = Reserved
* BIT 3 = Boot Order List
* BIT 4 = Reserved
* BIT 5 = Selective LUN
* BIT 6 = Reserved
* BIT 7-31 =
*/
uint32_t efi_parameters;
uint8_t reset_delay;
uint8_t reserved_12;
uint16_t reserved_13;
uint16_t boot_id_number;
uint16_t reserved_14;
uint16_t max_luns_per_target;
uint16_t reserved_15;
uint16_t port_down_retry_count;
uint16_t link_down_timeout;
/* FCode parameters. */
uint16_t fcode_parameter;
uint16_t reserved_16[3];
/* Offset 352. */
uint8_t reserved_17[4];
uint16_t reserved_18[5];
uint8_t reserved_19[2];
uint16_t reserved_20[8];
/* Offset 384. */
uint8_t reserved_21[16];
uint16_t reserved_22[3];
/*
* BIT 0 = Extended BB credits for LR
* BIT 1 = Virtual Fabric Enable
* BIT 2 = Enhanced Features Unused
* BIT 3-7 = Enhanced Features Reserved
*/
/* Enhanced Features */
uint8_t enhanced_features;
uint8_t reserved_23;
uint16_t reserved_24[4];
/* Offset 416. */
uint16_t reserved_25[32];
/* Offset 480. */
uint8_t model_name[16];
/* Offset 496. */
uint16_t feature_mask_l;
uint16_t feature_mask_h;
uint16_t reserved_26[2];
uint16_t subsystem_vendor_id;
uint16_t subsystem_device_id;
uint32_t checksum;
};
/*
* ISP Initialization Control Block.
* Little endian except where noted.
*/
#define ICB_VERSION 1
struct init_cb_81xx {
uint16_t version;
uint16_t reserved_1;
uint16_t frame_payload_size;
uint16_t execution_throttle;
uint16_t exchange_count;
uint16_t reserved_2;
uint8_t port_name[WWN_SIZE]; /* Big endian. */
uint8_t node_name[WWN_SIZE]; /* Big endian. */
uint16_t response_q_inpointer;
uint16_t request_q_outpointer;
uint16_t login_retry_count;
uint16_t prio_request_q_outpointer;
uint16_t response_q_length;
uint16_t request_q_length;
uint16_t reserved_3;
uint16_t prio_request_q_length;
uint32_t request_q_address[2];
uint32_t response_q_address[2];
uint32_t prio_request_q_address[2];
uint8_t reserved_4[8];
uint16_t atio_q_inpointer;
uint16_t atio_q_length;
uint32_t atio_q_address[2];
uint16_t interrupt_delay_timer; /* 100us increments. */
uint16_t login_timeout;
/*
* BIT 0-3 = Reserved
* BIT 4 = Enable Target Mode
* BIT 5 = Disable Initiator Mode
* BIT 6 = Reserved
* BIT 7 = Reserved
*
* BIT 8-13 = Reserved
* BIT 14 = Node Name Option
* BIT 15-31 = Reserved
*/
uint32_t firmware_options_1;
/*
* BIT 0 = Operation Mode bit 0
* BIT 1 = Operation Mode bit 1
* BIT 2 = Operation Mode bit 2
* BIT 3 = Operation Mode bit 3
* BIT 4-7 = Reserved
*
* BIT 8 = Enable Class 2
* BIT 9 = Enable ACK0
* BIT 10 = Reserved
* BIT 11 = Enable FC-SP Security
* BIT 12 = FC Tape Enable
* BIT 13 = Reserved
* BIT 14 = Enable Target PRLI Control
* BIT 15-31 = Reserved
*/
uint32_t firmware_options_2;
/*
* BIT 0-3 = Reserved
* BIT 4 = FCP RSP Payload bit 0
* BIT 5 = FCP RSP Payload bit 1
* BIT 6 = Enable Receive Out-of-Order data frame handling
* BIT 7 = Reserved
*
* BIT 8 = Reserved
* BIT 9 = Enable Out-of-Order FCP_XFER_RDY relative offset handling
* BIT 10-16 = Reserved
* BIT 17 = Enable multiple FCFs
* BIT 18-20 = MAC addressing mode
* BIT 21-25 = Ethernet data rate
* BIT 26 = Enable ethernet header rx IOCB for ATIO q
* BIT 27 = Enable ethernet header rx IOCB for response q
* BIT 28 = SPMA selection bit 0
* BIT 28 = SPMA selection bit 1
* BIT 30-31 = Reserved
*/
uint32_t firmware_options_3;
uint8_t reserved_5[8];
uint8_t enode_mac[6];
uint8_t reserved_6[10];
};
struct mid_init_cb_81xx {
struct init_cb_81xx init_cb;
uint16_t count;
uint16_t options;
struct mid_conf_entry_24xx entries[MAX_MULTI_ID_FABRIC];
};
struct ex_init_cb_81xx {
uint16_t ex_version;
uint8_t prio_fcf_matching_flags;
uint8_t reserved_1[3];
uint16_t pri_fcf_vlan_id;
uint8_t pri_fcf_fabric_name[8];
uint16_t reserved_2[7];
uint8_t spma_mac_addr[6];
uint16_t reserved_3[14];
};
#define FARX_ACCESS_FLASH_CONF_81XX 0x7FFD0000
#define FARX_ACCESS_FLASH_DATA_81XX 0x7F800000
/* FCP priority config defines *************************************/
/* operations */
#define QLFC_FCP_PRIO_DISABLE 0x0
#define QLFC_FCP_PRIO_ENABLE 0x1
#define QLFC_FCP_PRIO_GET_CONFIG 0x2
#define QLFC_FCP_PRIO_SET_CONFIG 0x3
struct qla_fcp_prio_entry {
uint16_t flags; /* Describes parameter(s) in FCP */
/* priority entry that are valid */
#define FCP_PRIO_ENTRY_VALID 0x1
#define FCP_PRIO_ENTRY_TAG_VALID 0x2
#define FCP_PRIO_ENTRY_SPID_VALID 0x4
#define FCP_PRIO_ENTRY_DPID_VALID 0x8
#define FCP_PRIO_ENTRY_LUNB_VALID 0x10
#define FCP_PRIO_ENTRY_LUNE_VALID 0x20
#define FCP_PRIO_ENTRY_SWWN_VALID 0x40
#define FCP_PRIO_ENTRY_DWWN_VALID 0x80
uint8_t tag; /* Priority value */
uint8_t reserved; /* Reserved for future use */
uint32_t src_pid; /* Src port id. high order byte */
/* unused; -1 (wild card) */
uint32_t dst_pid; /* Src port id. high order byte */
/* unused; -1 (wild card) */
uint16_t lun_beg; /* 1st lun num of lun range. */
/* -1 (wild card) */
uint16_t lun_end; /* 2nd lun num of lun range. */
/* -1 (wild card) */
uint8_t src_wwpn[8]; /* Source WWPN: -1 (wild card) */
uint8_t dst_wwpn[8]; /* Destination WWPN: -1 (wild card) */
};
struct qla_fcp_prio_cfg {
uint8_t signature[4]; /* "HQOS" signature of config data */
uint16_t version; /* 1: Initial version */
uint16_t length; /* config data size in num bytes */
uint16_t checksum; /* config data bytes checksum */
uint16_t num_entries; /* Number of entries */
uint16_t size_of_entry; /* Size of each entry in num bytes */
uint8_t attributes; /* enable/disable, persistence */
#define FCP_PRIO_ATTR_DISABLE 0x0
#define FCP_PRIO_ATTR_ENABLE 0x1
#define FCP_PRIO_ATTR_PERSIST 0x2
uint8_t reserved; /* Reserved for future use */
#define FCP_PRIO_CFG_HDR_SIZE 0x10
struct qla_fcp_prio_entry entry[1]; /* fcp priority entries */
#define FCP_PRIO_CFG_ENTRY_SIZE 0x20
};
#define FCP_PRIO_CFG_SIZE (32*1024) /* fcp prio data per port*/
/* 25XX Support ****************************************************/
#define FA_FCP_PRIO0_ADDR_25 0x3C000
#define FA_FCP_PRIO1_ADDR_25 0x3E000
/* 81XX Flash locations -- occupies second 2MB region. */
#define FA_BOOT_CODE_ADDR_81 0x80000
#define FA_RISC_CODE_ADDR_81 0xA0000
#define FA_FW_AREA_ADDR_81 0xC0000
#define FA_VPD_NVRAM_ADDR_81 0xD0000
#define FA_VPD0_ADDR_81 0xD0000
#define FA_VPD1_ADDR_81 0xD0400
#define FA_NVRAM0_ADDR_81 0xD0080
#define FA_NVRAM1_ADDR_81 0xD0180
#define FA_FEATURE_ADDR_81 0xD4000
#define FA_FLASH_DESCR_ADDR_81 0xD8000
#define FA_FLASH_LAYOUT_ADDR_81 0xD8400
#define FA_HW_EVENT0_ADDR_81 0xDC000
#define FA_HW_EVENT1_ADDR_81 0xDC400
#define FA_NPIV_CONF0_ADDR_81 0xD1000
#define FA_NPIV_CONF1_ADDR_81 0xD2000
/* 83XX Flash locations -- occupies second 8MB region. */
#define FA_FLASH_LAYOUT_ADDR_83 0xFC400
#endif
+286 -43
View File
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2008 QLogic Corporation
* Copyright (c) 2003-2011 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -28,19 +28,25 @@ extern void qla2x00_reset_adapter(struct scsi_qla_host *);
extern void qla24xx_reset_adapter(struct scsi_qla_host *);
extern int qla2x00_nvram_config(struct scsi_qla_host *);
extern int qla24xx_nvram_config(struct scsi_qla_host *);
extern int qla81xx_nvram_config(struct scsi_qla_host *);
extern void qla2x00_update_fw_options(struct scsi_qla_host *);
extern void qla24xx_update_fw_options(scsi_qla_host_t *);
extern void qla81xx_update_fw_options(scsi_qla_host_t *);
extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *);
extern int qla24xx_load_risc(scsi_qla_host_t *, uint32_t *);
extern int qla81xx_load_risc(scsi_qla_host_t *, uint32_t *);
extern int qla2x00_perform_loop_resync(scsi_qla_host_t *);
extern int qla2x00_loop_resync(scsi_qla_host_t *);
extern int qla2x00_find_new_loop_id(scsi_qla_host_t *, fc_port_t *);
extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *);
extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *);
extern void qla2x00_update_fcports(scsi_qla_host_t *);
extern int qla2x00_abort_isp(scsi_qla_host_t *);
extern void qla2x00_abort_isp_cleanup(scsi_qla_host_t *);
extern void qla82xx_quiescent_state_cleanup(scsi_qla_host_t *);
extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);
@@ -51,13 +57,29 @@ extern void qla2x00_enable_tgt_mode(scsi_qla_host_t *ha);
extern void qla2x00_disable_tgt_mode(scsi_qla_host_t *ha);
extern int qla2x00_issue_marker(scsi_qla_host_t *ha, int ha_locked);
extern int qla2x00_get_thermal_temp(scsi_qla_host_t *, uint16_t *, uint16_t *);
extern void qla84xx_put_chip(struct scsi_qla_host *);
extern int qla2x00_configure_loop(scsi_qla_host_t *);
extern int qla2x00_configure_local_loop(scsi_qla_host_t *);
extern int qla2x00_configure_fabric(scsi_qla_host_t *);
extern int qla2x00_async_login(struct scsi_qla_host *, fc_port_t *,
uint16_t *);
extern int qla2x00_async_logout(struct scsi_qla_host *, fc_port_t *);
extern int qla2x00_async_adisc(struct scsi_qla_host *, fc_port_t *,
uint16_t *);
extern int qla2x00_async_tm_cmd(fc_port_t *, uint32_t, uint32_t, uint32_t);
extern void qla2x00_async_login_done(struct scsi_qla_host *, fc_port_t *,
uint16_t *);
extern void qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *,
uint16_t *);
extern void qla2x00_async_adisc_done(struct scsi_qla_host *, fc_port_t *,
uint16_t *);
extern void *qla2x00_alloc_iocbs(struct scsi_qla_host *, srb_t *);
extern fc_port_t *
qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t );
/*
* Global Data in qla_os.c source file.
*/
@@ -70,41 +92,75 @@ extern int ql2xloginretrycount;
extern int ql2xfdmienable;
extern int ql2xallocfwdump;
extern int ql2xextended_error_logging;
extern int ql2xqfullrampup;
extern int ql2xiidmaenable;
extern int ql2xmaxqueues;
extern int ql2xmultique_tag;
extern int ql2xfwloadbin;
extern int ql2xetsenable;
extern int ql2xshiftctondsd;
extern int ql2xdbwr;
extern int ql2xdontresethba;
extern unsigned int ql2xmaxlun;
extern int ql2xasynctmfenable;
extern int ql2xenabledif;
extern int ql2xenablehba_err_chk;
extern int ql2xtargetreset;
extern int ql2xgffidenable;
extern int ql2xmdcapmask;
extern int ql2xmdenable;
extern int num_hosts;
extern int qla2x00_loop_reset(scsi_qla_host_t *);
extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum
fc_host_event_code, u32);
extern int qla2x00_post_hwe_work(struct scsi_qla_host *, uint16_t , uint16_t,
uint16_t, uint16_t);
extern int qla2x00_post_idc_ack_work(struct scsi_qla_host *, uint16_t *);
extern int qla2x00_post_async_login_work(struct scsi_qla_host *, fc_port_t *,
uint16_t *);
extern int qla2x00_post_async_login_done_work(struct scsi_qla_host *,
fc_port_t *, uint16_t *);
extern int qla2x00_post_async_logout_work(struct scsi_qla_host *, fc_port_t *,
uint16_t *);
extern int qla2x00_post_async_logout_done_work(struct scsi_qla_host *,
fc_port_t *, uint16_t *);
extern int qla2x00_post_async_adisc_work(struct scsi_qla_host *, fc_port_t *,
uint16_t *);
extern int qla2x00_post_async_adisc_done_work(struct scsi_qla_host *,
fc_port_t *, uint16_t *);
extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32);
extern void qla2x00_abort_fcport_cmds(fc_port_t *);
extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *);
extern struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *,
struct qla_hw_data *);
extern void qla2x00_free_host(struct scsi_qla_host *);
extern void qla2x00_relogin(struct scsi_qla_host *);
extern void qla2x00_do_work(struct scsi_qla_host *);
extern void qla2x00_free_fcports(struct scsi_qla_host *);
/*
* Global Functions in qla_mid.c source file.
*/
extern struct scsi_host_template qla24xx_driver_template;
extern struct scsi_host_template qla2xxx_driver_template;
extern struct scsi_transport_template *qla2xxx_transport_vport_template;
extern void qla2x00_timer(scsi_qla_host_t *);
extern void qla2x00_start_timer(scsi_qla_host_t *, void *, unsigned long);
extern void qla24xx_deallocate_vp_id(scsi_qla_host_t *);
extern int qla24xx_disable_vp (scsi_qla_host_t *);
extern int qla24xx_enable_vp (scsi_qla_host_t *);
extern int qla24xx_init_vp(scsi_qla_host_t *);
extern int qla24xx_disable_vp(scsi_qla_host_t *);
extern int qla24xx_enable_vp(scsi_qla_host_t *);
extern int qla24xx_control_vp(scsi_qla_host_t *, int );
extern int qla24xx_modify_vp_config(scsi_qla_host_t *);
extern int qla2x00_send_change_request(scsi_qla_host_t *, uint16_t, uint16_t);
extern void qla2x00_vp_stop_timer(scsi_qla_host_t *);
extern int qla24xx_configure_vhba (scsi_qla_host_t *);
extern int qla24xx_configure_vhba(scsi_qla_host_t *);
extern void qla24xx_report_id_acquisition(scsi_qla_host_t *,
struct vp_rpt_id_entry_24xx *);
extern void qla2x00_do_dpc_all_vps(scsi_qla_host_t *);
extern int qla24xx_vport_create_req_sanity_check(struct fc_vport *);
extern scsi_qla_host_t * qla24xx_create_vhost(struct fc_vport *);
extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *);
extern scsi_qla_host_t *qla24xx_create_vhost(struct fc_vport *);
extern void qla2x00_sp_free_dma(void *, void *);
extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *);
extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int);
@@ -113,25 +169,33 @@ extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int);
extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *);
extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *);
extern int qla2x00_wait_for_chip_reset(scsi_qla_host_t *);
extern int qla2x00_wait_for_fcoe_ctx_reset(scsi_qla_host_t *);
extern void qla2xxx_wake_dpc(scsi_qla_host_t *);
extern void qla2x00_alert_all_vps(scsi_qla_host_t *, uint16_t *);
extern void qla2x00_async_event(scsi_qla_host_t *, uint16_t *);
extern void qla2x00_vp_abort_isp(scsi_qla_host_t *);
extern void qla2xxx_wake_dpc(struct scsi_qla_host *);
extern void qla2x00_alert_all_vps(struct rsp_que *, uint16_t *);
extern void qla2x00_async_event(scsi_qla_host_t *, struct rsp_que *,
uint16_t *);
extern int qla2x00_vp_abort_isp(scsi_qla_host_t *);
/*
* Global Function Prototypes in qla_iocb.c source file.
*/
extern void qla2x00_isp_cmd(scsi_qla_host_t *);
extern void qla2x00_start_iocbs(struct scsi_qla_host *, struct req_que *);
extern uint16_t qla2x00_calc_iocbs_32(uint16_t);
extern uint16_t qla2x00_calc_iocbs_64(uint16_t);
extern void qla2x00_build_scsi_iocbs_32(srb_t *, cmd_entry_t *, uint16_t);
extern void qla2x00_build_scsi_iocbs_64(srb_t *, cmd_entry_t *, uint16_t);
extern int qla2x00_start_scsi(srb_t *sp);
extern int qla24xx_start_scsi(srb_t *sp);
int qla2x00_marker(scsi_qla_host_t *, uint16_t, uint16_t, uint8_t);
int __qla2x00_marker(scsi_qla_host_t *, uint16_t, uint16_t, uint8_t);
extern int qla2x00_marker(struct scsi_qla_host *, struct req_que *, struct rsp_que *,
uint16_t, uint16_t, uint8_t);
extern int __qla2x00_marker(struct scsi_qla_host *, struct req_que *,
struct rsp_que *, uint16_t, uint16_t, uint8_t);
extern int qla2x00_start_sp(srb_t *);
extern uint16_t qla24xx_calc_iocbs(scsi_qla_host_t *, uint16_t);
extern void qla24xx_build_scsi_iocbs(srb_t *, struct cmd_type_7 *, uint16_t);
extern int qla24xx_dif_start_scsi(srb_t *);
/*
* Global Function Prototypes in qla_mbx.c source file.
@@ -145,9 +209,8 @@ qla2x00_dump_ram(scsi_qla_host_t *, dma_addr_t, uint32_t, uint32_t);
extern int
qla2x00_execute_fw(scsi_qla_host_t *, uint32_t);
extern void
qla2x00_get_fw_version(scsi_qla_host_t *, uint16_t *,
uint16_t *, uint16_t *, uint16_t *, uint32_t *);
extern int
qla2x00_get_fw_version(scsi_qla_host_t *);
extern int
qla2x00_get_fw_options(scsi_qla_host_t *, uint16_t *);
@@ -165,13 +228,13 @@ extern int
qla2x00_issue_iocb(scsi_qla_host_t *, void *, dma_addr_t, size_t);
extern int
qla2x00_abort_command(scsi_qla_host_t *, srb_t *);
qla2x00_abort_command(srb_t *);
extern int
qla2x00_abort_target(struct fc_port *, unsigned int);
qla2x00_abort_target(struct fc_port *, unsigned int, int);
extern int
qla2x00_lun_reset(struct fc_port *, unsigned int);
qla2x00_lun_reset(struct fc_port *, unsigned int, int);
extern int
qla2x00_get_adapter_id(scsi_qla_host_t *, uint16_t *, uint8_t *, uint8_t *,
@@ -183,9 +246,11 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *, uint8_t *, uint8_t *, uint16_t *);
extern int
qla2x00_init_firmware(scsi_qla_host_t *, uint16_t);
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
extern int
qla2x00_get_node_name_list(scsi_qla_host_t *ha,
qla2x00_get_node_name_list(scsi_qla_host_t *ha, bool include_initiators,
void **out_data, int *out_len);
#endif
extern int
qla2x00_get_port_database(scsi_qla_host_t *, fc_port_t *, uint8_t);
@@ -227,7 +292,7 @@ qla2x00_get_id_list(scsi_qla_host_t *, void *, dma_addr_t, uint16_t *);
extern int
qla2x00_get_resource_cnts(scsi_qla_host_t *, uint16_t *, uint16_t *,
uint16_t *, uint16_t *, uint16_t *);
uint16_t *, uint16_t *, uint16_t *, uint16_t *);
extern int
qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map);
@@ -240,10 +305,14 @@ extern int
qla24xx_get_isp_stats(scsi_qla_host_t *, struct link_statistics *,
dma_addr_t);
extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *);
extern int qla24xx_abort_target(struct fc_port *, unsigned int);
extern int qla24xx_lun_reset(struct fc_port *, unsigned int);
extern int qla24xx_abort_command(srb_t *);
extern int
qla24xx_abort_target(struct fc_port *, unsigned int, int);
extern int
qla24xx_lun_reset(struct fc_port *, unsigned int, int);
extern int
qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *, unsigned int,
unsigned int, enum nexus_wait_type);
extern int
qla2x00_system_error(scsi_qla_host_t *);
@@ -266,25 +335,73 @@ extern int
qla2x00_disable_fce_trace(scsi_qla_host_t *, uint64_t *, uint64_t *);
extern int
qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t);
qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint8_t *,
uint16_t, uint16_t, uint16_t, uint16_t);
extern int
qla2x00_write_sfp(scsi_qla_host_t *, dma_addr_t, uint8_t *,
uint16_t, uint16_t, uint16_t, uint16_t);
extern int
qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *);
extern int qla84xx_verify_chip(struct scsi_qla_host *, uint16_t *);
extern int qla81xx_idc_ack(scsi_qla_host_t *, uint16_t *);
extern int
qla81xx_fac_get_sector_size(scsi_qla_host_t *, uint32_t *);
extern int
qla81xx_fac_do_write_enable(scsi_qla_host_t *, int);
extern int
qla81xx_fac_erase_sector(scsi_qla_host_t *, uint32_t, uint32_t);
extern int
qla2x00_get_xgmac_stats(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t *);
extern int
qla2x00_get_dcbx_params(scsi_qla_host_t *, dma_addr_t, uint16_t);
extern int
qla2x00_read_ram_word(scsi_qla_host_t *, uint32_t, uint32_t *);
extern int
qla2x00_write_ram_word(scsi_qla_host_t *, uint32_t, uint32_t);
extern int
qla81xx_write_mpi_register(scsi_qla_host_t *, uint16_t *);
extern int qla2x00_get_data_rate(scsi_qla_host_t *);
extern int qla24xx_set_fcp_prio(scsi_qla_host_t *, uint16_t, uint16_t,
uint16_t *);
extern int
qla81xx_get_port_config(scsi_qla_host_t *, uint16_t *);
extern int
qla81xx_set_port_config(scsi_qla_host_t *, uint16_t *);
extern int
qla2x00_port_logout(scsi_qla_host_t *, struct fc_port *);
/*
* Global Function Prototypes in qla_isr.c source file.
*/
extern irqreturn_t qla2100_intr_handler(int, void *);
extern irqreturn_t qla2300_intr_handler(int, void *);
extern irqreturn_t qla24xx_intr_handler(int, void *);
extern void qla2x00_process_response_queue(struct scsi_qla_host *);
extern void qla24xx_process_response_queue(struct scsi_qla_host *);
extern int qla2x00_request_irqs(scsi_qla_host_t *);
extern void qla2x00_process_response_queue(struct rsp_que *);
extern void
qla24xx_process_response_queue(struct scsi_qla_host *, struct rsp_que *);
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
extern void qla24xx_process_atio_queue(struct scsi_qla_host *ha);
#endif
extern int qla2x00_request_irqs(struct qla_hw_data *, struct rsp_que *);
extern void qla2x00_free_irqs(scsi_qla_host_t *);
extern int qla2x00_get_data_rate(scsi_qla_host_t *);
extern char* qla2x00_get_link_speed_str(struct qla_hw_data *);
/*
* Global Function Prototypes in qla_sup.c source file.
*/
@@ -310,6 +427,11 @@ extern void qla2x00_beacon_blink(struct scsi_qla_host *);
extern int qla24xx_beacon_on(struct scsi_qla_host *);
extern int qla24xx_beacon_off(struct scsi_qla_host *);
extern void qla24xx_beacon_blink(struct scsi_qla_host *);
extern void qla83xx_beacon_blink(struct scsi_qla_host *);
extern int qla82xx_beacon_on(struct scsi_qla_host *);
extern int qla82xx_beacon_off(struct scsi_qla_host *);
extern int qla83xx_write_remote_reg(scsi_qla_host_t *ha, uint32_t reg,
uint32_t data);
extern uint8_t *qla2x00_read_optrom_data(struct scsi_qla_host *, uint8_t *,
uint32_t, uint32_t);
@@ -325,12 +447,12 @@ extern uint8_t *qla25xx_read_optrom_data(struct scsi_qla_host *, uint8_t *,
extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *);
extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *);
extern int qla2xxx_hw_event_log(scsi_qla_host_t *, uint16_t , uint16_t,
uint16_t, uint16_t);
extern void qla2xxx_get_flash_info(scsi_qla_host_t *);
extern int qla2xxx_get_flash_info(scsi_qla_host_t *);
extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t);
extern void qla2xxx_flash_npiv_conf(scsi_qla_host_t *);
extern int qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp);
extern int qla24xx_read_fcp_prio_cfg(scsi_qla_host_t *);
/*
* Global Function Prototypes in qla_dbg.c source file.
@@ -339,8 +461,14 @@ extern void qla2100_fw_dump(scsi_qla_host_t *, int);
extern void qla2300_fw_dump(scsi_qla_host_t *, int);
extern void qla24xx_fw_dump(scsi_qla_host_t *, int);
extern void qla25xx_fw_dump(scsi_qla_host_t *, int);
extern void qla81xx_fw_dump(scsi_qla_host_t *, int);
extern void qla2x00_dump_regs(scsi_qla_host_t *);
extern void qla2x00_dump_buffer(uint8_t *, uint32_t);
extern void qla2x00_dump_buffer_zipped(uint8_t *, uint32_t);
extern void qla2xxx_dump_post_process(scsi_qla_host_t *, int);
extern void ql_dump_regs(uint32_t, scsi_qla_host_t *, int32_t);
extern void ql_dump_buffer(uint32_t, scsi_qla_host_t *, int32_t,
uint8_t *, uint32_t);
/*
* Global Function Prototypes in qla_gs.c source file.
@@ -351,6 +479,7 @@ extern int qla2x00_ga_nxt(scsi_qla_host_t *, fc_port_t *);
extern int qla2x00_gid_pt(scsi_qla_host_t *, sw_info_t *);
extern int qla2x00_gpn_id(scsi_qla_host_t *, sw_info_t *);
extern int qla2x00_gnn_id(scsi_qla_host_t *, sw_info_t *);
extern void qla2x00_gff_id(scsi_qla_host_t *, sw_info_t *);
extern int qla2x00_rft_id(scsi_qla_host_t *);
extern int qla2x00_rff_id(scsi_qla_host_t *);
extern int qla2x00_rnn_id(scsi_qla_host_t *);
@@ -361,7 +490,6 @@ extern int qla2x00_fdmi_register(scsi_qla_host_t *);
extern int qla2x00_gfpn_id(scsi_qla_host_t *, sw_info_t *);
extern int qla2x00_gpsc(scsi_qla_host_t *, sw_info_t *);
extern void qla2x00_get_sym_node_name(scsi_qla_host_t *, uint8_t *);
extern int qla2x00_mgmt_svr_login(scsi_qla_host_t *);
/*
* Global Function Prototypes in qla_attr.c source file.
@@ -376,10 +504,125 @@ extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *);
extern void qla2x00_init_host_attr(scsi_qla_host_t *);
extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *);
extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *);
extern int qla2x00_loopback_test(scsi_qla_host_t *, struct msg_echo_lb *, uint16_t *);
extern int qla2x00_echo_test(scsi_qla_host_t *,
struct msg_echo_lb *, uint16_t *);
extern int qla24xx_update_all_fcp_prio(scsi_qla_host_t *);
extern int qla24xx_fcp_prio_cfg_valid(scsi_qla_host_t *,
struct qla_fcp_prio_cfg *, uint8_t);
/*
* Global Function Prototypes in qla_dfs.c source file.
*/
extern int qla2x00_dfs_setup(scsi_qla_host_t *);
extern int qla2x00_dfs_remove(scsi_qla_host_t *);
/* Globa function prototypes for multi-q */
extern int qla25xx_request_irq(struct rsp_que *);
extern int qla25xx_init_req_que(struct scsi_qla_host *, struct req_que *);
extern int qla25xx_init_rsp_que(struct scsi_qla_host *, struct rsp_que *);
extern int qla25xx_create_req_que(struct qla_hw_data *, uint16_t, uint8_t,
uint16_t, int, uint8_t);
extern int qla25xx_create_rsp_que(struct qla_hw_data *, uint16_t, uint8_t,
uint16_t, int);
extern void qla2x00_init_response_q_entries(struct rsp_que *);
extern int qla25xx_delete_req_que(struct scsi_qla_host *, struct req_que *);
extern int qla25xx_delete_queues(struct scsi_qla_host *);
extern uint16_t qla24xx_rd_req_reg(struct qla_hw_data *, uint16_t);
extern uint16_t qla25xx_rd_req_reg(struct qla_hw_data *, uint16_t);
extern void qla24xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t);
extern void qla25xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t);
extern void qla25xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t);
extern void qla24xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t);
/* qla82xx related functions */
/* PCI related functions */
extern int qla82xx_pci_config(struct scsi_qla_host *);
extern char *qla82xx_pci_info_str(struct scsi_qla_host *, char *, int);
extern int qla82xx_iospace_config(struct qla_hw_data *);
/* Initialization related functions */
extern void qla82xx_reset_chip(struct scsi_qla_host *);
extern void qla82xx_config_rings(struct scsi_qla_host *);
extern void qla82xx_watchdog(scsi_qla_host_t *);
extern int qla82xx_start_firmware(scsi_qla_host_t *);
extern void qla2x00_set_model_info(scsi_qla_host_t *, uint8_t *,
size_t, char *);
/* Firmware and flash related functions */
extern int qla82xx_load_risc(scsi_qla_host_t *, uint32_t *);
extern uint8_t *qla82xx_read_optrom_data(struct scsi_qla_host *, uint8_t *,
uint32_t, uint32_t);
extern int qla82xx_write_optrom_data(struct scsi_qla_host *, uint8_t *,
uint32_t, uint32_t);
/* Mailbox related functions */
extern int qla82xx_abort_isp(scsi_qla_host_t *);
extern int qla82xx_restart_isp(scsi_qla_host_t *);
extern int qla82xx_mbx_intr_enable(scsi_qla_host_t *);
extern int qla82xx_mbx_intr_disable(scsi_qla_host_t *);
/* IOCB related functions */
extern int qla82xx_start_scsi(srb_t *);
extern void qla82xx_start_iocbs(scsi_qla_host_t *);
extern void qla2x00_sp_free(void *, void *);
extern void qla2x00_sp_timeout(unsigned long);
extern void qla2x00_bsg_job_done(void *, void *, int);
extern void qla2x00_bsg_sp_free(void *, void *);
/* Interrupt related */
extern irqreturn_t qla82xx_intr_handler(int, void *);
extern irqreturn_t qla82xx_msix_default(int, void *);
extern irqreturn_t qla82xx_msix_rsp_q(int, void *);
extern void qla82xx_enable_intrs(struct qla_hw_data *);
extern void qla82xx_disable_intrs(struct qla_hw_data *);
extern void qla82xx_poll(int, void *);
extern void qla82xx_init_flags(struct qla_hw_data *);
/* ISP 8021 hardware related */
extern void qla82xx_set_drv_active(scsi_qla_host_t *);
extern int qla82xx_wr_32(struct qla_hw_data *, ulong, u32);
extern int qla82xx_rd_32(struct qla_hw_data *, ulong);
/* ISP 8021 IDC */
extern void qla82xx_clear_drv_active(struct qla_hw_data *);
extern uint32_t qla82xx_wait_for_state_change(scsi_qla_host_t *, uint32_t);
extern int qla82xx_idc_lock(struct qla_hw_data *);
extern void qla82xx_idc_unlock(struct qla_hw_data *);
extern int qla82xx_device_state_handler(scsi_qla_host_t *);
extern void qla82xx_clear_qsnt_ready(scsi_qla_host_t *);
/* Reset related */
extern int qla82xx_fcoe_ctx_reset(scsi_qla_host_t *);
extern int qla82xx_check_md_needed(scsi_qla_host_t *);
extern void qla82xx_chip_reset_cleanup(scsi_qla_host_t *);
extern int qla81xx_set_led_config(scsi_qla_host_t *, uint16_t *);
extern int qla81xx_get_led_config(scsi_qla_host_t *, uint16_t *);
extern char *qdev_state(uint32_t);
extern int qla82xx_mbx_beacon_ctl(scsi_qla_host_t *, int);
extern void qla82xx_clear_pending_mbx(scsi_qla_host_t *);
/* BSG related functions */
extern int qla24xx_bsg_request(struct fc_bsg_job *);
extern int qla24xx_bsg_timeout(struct fc_bsg_job *);
extern int qla84xx_reset_chip(scsi_qla_host_t *, uint16_t);
extern int qla2x00_issue_iocb_timeout(scsi_qla_host_t *, void *,
dma_addr_t, size_t, uint32_t);
extern int qla2x00_get_idma_speed(scsi_qla_host_t *, uint16_t,
uint16_t *, uint16_t *);
/* 83xx related functions */
extern void qla83xx_fw_dump(scsi_qla_host_t *, int);
extern int qla83xx_configure_vfs(scsi_qla_host_t *);
/* Minidump related functions */
extern int qla82xx_md_get_template_size(scsi_qla_host_t *);
extern int qla82xx_md_get_template(scsi_qla_host_t *);
extern int qla82xx_md_alloc(scsi_qla_host_t *);
extern void qla82xx_md_free(scsi_qla_host_t *);
extern int qla82xx_md_collect(scsi_qla_host_t *);
extern void qla82xx_md_prep(scsi_qla_host_t *);
extern void qla82xx_set_reset_owner(scsi_qla_host_t *);
#endif /* _QLA_GBL_H */
+511 -392
View File
File diff suppressed because it is too large Load Diff
+2786 -1259
View File
File diff suppressed because it is too large Load Diff
+131 -13
View File
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2008 QLogic Corporation
* Copyright (c) 2003-2011 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -32,17 +32,20 @@ qla2x00_debounce_register(volatile uint16_t __iomem *addr)
}
static inline void
qla2x00_poll(scsi_qla_host_t *ha)
qla2x00_poll(struct rsp_que *rsp)
{
unsigned long flags;
struct qla_hw_data *ha = rsp->hw;
#ifdef CONFIG_PREEMPT_RT_FULL
local_irq_save_nort(flags);
#else
local_irq_save(flags);
#endif
ha->isp_ops->intr_handler(0, ha);
if (IS_QLA82XX(ha))
qla82xx_poll(0, rsp);
else
ha->isp_ops->intr_handler(0, rsp);
#ifdef CONFIG_PREEMPT_RT_FULL
local_irq_restore_nort(flags);
@@ -51,12 +54,6 @@ qla2x00_poll(scsi_qla_host_t *ha)
#endif
}
static __inline__ scsi_qla_host_t *
to_qla_parent(scsi_qla_host_t *ha)
{
return ha->parent ? ha->parent : ha;
}
static inline uint8_t *
host_to_fcp_swap(uint8_t *fcp, uint32_t bsize)
{
@@ -71,11 +68,132 @@ host_to_fcp_swap(uint8_t *fcp, uint32_t bsize)
}
static inline int
qla2x00_is_reserved_id(scsi_qla_host_t *ha, uint16_t loop_id)
qla2x00_is_reserved_id(scsi_qla_host_t *vha, uint16_t loop_id)
{
struct qla_hw_data *ha = vha->hw;
if (IS_FWI2_CAPABLE(ha))
return (loop_id > NPH_LAST_HANDLE);
return ((loop_id > ha->last_loop_id && loop_id < SNS_FIRST_LOOP_ID) ||
return ((loop_id > ha->max_loop_id && loop_id < SNS_FIRST_LOOP_ID) ||
loop_id == MANAGEMENT_SERVER || loop_id == BROADCAST);
};
}
static inline void
qla2x00_clean_dsd_pool(struct qla_hw_data *ha, srb_t *sp)
{
struct dsd_dma *dsd_ptr, *tdsd_ptr;
struct crc_context *ctx;
ctx = (struct crc_context *)GET_CMD_CTX_SP(sp);
/* clean up allocated prev pool */
list_for_each_entry_safe(dsd_ptr, tdsd_ptr,
&ctx->dsd_list, list) {
dma_pool_free(ha->dl_dma_pool, dsd_ptr->dsd_addr,
dsd_ptr->dsd_list_dma);
list_del(&dsd_ptr->list);
kfree(dsd_ptr);
}
INIT_LIST_HEAD(&ctx->dsd_list);
}
static inline void
qla2x00_set_fcport_state(fc_port_t *fcport, int state)
{
int old_state;
old_state = atomic_read(&fcport->state);
atomic_set(&fcport->state, state);
/* Don't print state transitions during initial allocation of fcport */
if (old_state && old_state != state) {
ql_dbg(ql_dbg_disc, fcport->vha, 0x207d,
"FCPort state transitioned from %s to %s - "
"portid=%02x%02x%02x.\n",
port_state_str[old_state], port_state_str[state],
fcport->d_id.b.domain, fcport->d_id.b.area,
fcport->d_id.b.al_pa);
}
}
static inline int
qla2x00_hba_err_chk_enabled(srb_t *sp)
{
/*
* Uncomment when corresponding SCSI changes are done.
*
if (!sp->cmd->prot_chk)
return 0;
*
*/
switch (scsi_get_prot_op(GET_CMD_SP(sp))) {
case SCSI_PROT_READ_STRIP:
case SCSI_PROT_WRITE_INSERT:
if (ql2xenablehba_err_chk >= 1)
return 1;
break;
case SCSI_PROT_READ_PASS:
case SCSI_PROT_WRITE_PASS:
if (ql2xenablehba_err_chk >= 2)
return 1;
break;
case SCSI_PROT_READ_INSERT:
case SCSI_PROT_WRITE_STRIP:
return 1;
}
return 0;
}
static inline srb_t *
qla2x00_get_sp(scsi_qla_host_t *vha, fc_port_t *fcport, gfp_t flag)
{
srb_t *sp = NULL;
struct qla_hw_data *ha = vha->hw;
uint8_t bail;
QLA_VHA_MARK_BUSY(vha, bail);
if (unlikely(bail))
return NULL;
sp = mempool_alloc(ha->srb_mempool, flag);
if (!sp)
goto done;
memset(sp, 0, sizeof(*sp));
sp->fcport = fcport;
sp->iocbs = 1;
done:
if (!sp)
QLA_VHA_MARK_NOT_BUSY(vha);
return sp;
}
static inline void
qla2x00_init_timer(srb_t *sp, unsigned long tmo)
{
init_timer(&sp->u.iocb_cmd.timer);
sp->u.iocb_cmd.timer.expires = jiffies + tmo * HZ;
sp->u.iocb_cmd.timer.data = (unsigned long)sp;
sp->u.iocb_cmd.timer.function = qla2x00_sp_timeout;
add_timer(&sp->u.iocb_cmd.timer);
sp->free = qla2x00_sp_free;
}
static inline int
qla2x00_reset_active(scsi_qla_host_t *vha)
{
scsi_qla_host_t *base_vha = pci_get_drvdata(vha->hw->pdev);
/* Test appropriate base-vha and vha flags. */
return test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) ||
test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
}
static inline int
qla2x00_gid_list_size(struct qla_hw_data *ha)
{
return (sizeof(struct gid_list_info) * ha->max_fibre_devices);
}
+2158 -227
View File
File diff suppressed because it is too large Load Diff
+1673 -1039
View File
File diff suppressed because it is too large Load Diff
+2487 -666
View File
File diff suppressed because it is too large Load Diff
+597 -172
View File
File diff suppressed because it is too large Load Diff
+4463
View File
File diff suppressed because it is too large Load Diff
+1194
View File
File diff suppressed because it is too large Load Diff
+2862 -1291
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2008 QLogic Corporation
* Copyright (c) 2003-2011 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
+1086 -462
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -1,15 +1,15 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2008 QLogic Corporation
* Copyright (c) 2003-2011 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
/*
* Driver version
*/
#define QLA2XXX_VERSION "8.02.01-k4-tgt"
#define QLA2XXX_VERSION "8.04.00.05.2.2-SCST.03-k-p"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 2
#define QLA_DRIVER_PATCH_VER 1
#define QLA_DRIVER_MINOR_VER 4
#define QLA_DRIVER_PATCH_VER 0
#define QLA_DRIVER_BETA_VER 0
+3
View File
@@ -15,6 +15,9 @@ version="$1"; shift
files="$*"
if [ -z "$files" ]; then
files=$($scriptdir/list-source-files)
if [ -e build_mode ]; then
files="${files} build_mode"
fi
fi
tar --owner=root --group=root --transform="s|^|$name-$version/|" \
-8
View File
@@ -278,14 +278,6 @@ CONFIG_TRACING CONFIG_X86_32 \
patch -p1 -f -s <"${p}" >>"${patchoutput}" 2>&1
done
fi &&
if [ -e $srcdir/srpt/patches/kernel-${kver}-pre-cflags.patch ]; then
echo "$srcdir/srpt/patches/kernel-${kver}-pre-cflags.patch ..." \
>>"${patchoutput}"
patch -p1 -f -s <$srcdir/srpt/patches/kernel-${kver}-pre-cflags.patch \
>>"${patchoutput}"
else
echo "srpt/patches/kernel-${kver}-pre-cflags.patch not found."
fi &&
make -s allmodconfig &>"${outputdir}/make-config-output.txt" &&
for c in $disable; do sed -i.tmp "s/^$c=[ym]\$/$c=n/" .config; done &&
make -s oldconfig &>/dev/null
+3 -1
View File
@@ -227,7 +227,7 @@ function evaluate(stmnt, pattern, arg, op, result) {
stmnt = "+#if " (op[2] != 0 ? op[1] : op[2])
}
pattern="^+#if[[:blank:]]*(!*[[:blank:]]*[A-Za-z_]*[[:blank:]]*)\\&\\&[[:blank:]]*([01])[[:blank:]]*$"
pattern="^+#if[[:blank:]]*(!*[[:blank:]]*[A-Za-z_]*)[[:blank:]]*\\&\\&[[:blank:]]*([01])[[:blank:]]*$"
while (match(stmnt, pattern, op) != 0)
{
stmnt = "+#if " (op[2] != 0 ? op[1] : op[2])
@@ -561,6 +561,8 @@ BEGIN {
delete_next_blank_line = 0
if (match($0, "^+ *#"))
{
if (debug)
printf "/* debug specialize-patch: line %d: %s*/\n", NR, $0
process_preprocessor_statement()
}
else if (output)
+55
View File
@@ -0,0 +1,55 @@
#!/bin/awk -f
BEGIN {
if (debug != "")
print "[<node>, <per_node_cpu_idx>]: <cpu>";
"ls -1d /sys/devices/system/node/node* 2>&1 | wc -l" | getline nodes
if (nodes > 1) {
for (i = 0; i < nodes; i++) {
cpus_per_node = 0
while (("cd /sys/devices/system/cpu && ls -d cpu*/node" i " | sed 's/^cpu//;s,/.*,,'|sort -n" | getline j) > 0) {
if (debug != "")
print "[" i ", " cpus_per_node "]: " j
cpu[i, cpus_per_node++] = j
}
}
} else {
cpus_per_node = 0
while (("cd /sys/devices/system/cpu && ls -d cpu[0-9]* | sed 's/^cpu//'|sort -n" | getline j) > 0) {
if (debug != "")
print "[0, " cpus_per_node "]: " j
cpu[0, cpus_per_node++] = j
}
}
for (i = 0; i < nodes; i++)
nextcpu[i] = 0
while (("sed -n 's/.*mlx4-ib-\\([0-9]*\\)-[0-9]*@\\(.*\\)$/\\1 \\2/p' /proc/interrupts | uniq" | getline) > 0) {
port = $1
bus = substr($0, length($1) + 2)
if (debug != "")
print "HCA port = " port "; bus = " bus
irqcount = 0
while (("sed -n 's/^[[:blank:]]*\\([0-9]*\\):[0-9[:blank:]]*[^[:blank:]]*[[:blank:]]*\\(mlx4-ib-" port "-[0-9]*@" bus "\\)$/\\1 \\2/p' </proc/interrupts" | getline) > 0) {
irq[irqcount] = $1
irqname[irqcount] = substr($0, length($1) + 2)
irqcount++
}
for (i = 0; i < nodes; i++) {
ch_start = i * irqcount / nodes
ch_end = (i + 1) * irqcount / nodes
for (ch = ch_start; ch < ch_end; ch++) {
c = cpu[i, nextcpu[i]++ % cpus_per_node]
if (nodes > 1)
nodetxt = " (node " i ")"
else
nodetxt = ""
print "IRQ " irq[ch] " (" irqname[ch] "): CPU " c nodetxt
cmd="echo " c " >/proc/irq/" irq[ch] "/smp_affinity_list"
if (debug != "")
print cmd
system(cmd)
}
}
}
exit 0
}
+27
View File
@@ -0,0 +1,27 @@
#!/bin/sh
# Update the version number in SCST source files.
usage() {
echo "Usage: $(basename $0) <major> <minor> <release> [<suffix>]"
exit 1
}
if [ $# != 3 -a $# != 4 ]; then
usage
fi
major=$1
minor=$2
release=$3
suffix=$4
fv=$major.$minor.$release$suffix
reldate=$(date "+%d %B %Y")
sed -i "s,^\(#define[[:blank:]]*\(FT_VERSION\|ISCSI_VERSION_STRING\|Q2T_VERSION_STRING\|SCST_LOCAL_VERSION\|SCST_VERSION_NAME\|DRV_VERSION\|VERSION_STR\)[[:blank:]]*\)\"[^\"]*\",\1\"$major.$minor.$release$suffix\"," scst_local/scst_local.c srpt/src/ib_srpt.c fcst/fcst.h iscsi-scst/include/iscsi_scst_ver.h qla2x00t/qla2x00-target/qla2x00t.h scst/include/scst_const.h
sed -i "s,^\(<date>Version[[:blank:]]*\)[^[:blank:]]*\(</date>\),\1$fv\2," doc/scst_user_spec.sgml
sed -i "s/^Version .*/Version $fv, $reldate/" iscsi-scst/README qla2x00t/qla2x00-target/README scst/README usr/fileio/README
sed -i "s/^\(\(static const char \*scst_local_version_date\|#define[[:blank:]]*DRV_RELDATE\)[[:blank:]]*\)\"[^\"]*\"/\1\"$reldate\"/" scst_local/scst_local.c srpt/src/ib_srpt.c
sed -i "s/^\(#define[[:blank:]]*[^[:blank:]]*_REV[[:blank:]]*\)\"[[:blank:]0-9]*\"/\1\"$(printf "%2d%d%d" $major $minor $release)\"/" usr/fileio/common.h scst/src/dev_handlers/scst_vdisk.c
sed -i "s/^\(#define[[:blank:]]*SCST_VERSION_CODE[[:blank:]]*\).*/\1SCST_VERSION($major, $minor, $release, 0)/" scst/include/scst.h
sed -i "s/^\(#define[[:blank:]]*Q2T_VERSION_CODE[[:blank:]]*\).*/\1Q2T_VERSION($major, $minor, $release, 0)/" qla2x00t/qla2x00-target/qla2x00t.h
sed -i "s/^\(.Version[[:blank:]]*=[[:blank:]]*'SCST Configurator v\)[0-9.]*/\1$fv/" scstadmin/scstadmin.sysfs/scstadmin
+250
View File
@@ -0,0 +1,250 @@
%define kmod_name scst
# kversion: Kernel version as it appears under /lib/modules.
# The algorithm for setting the variable kversion is as follows:
# - If the variable kversion has been set, use its value.
# - If an RPM with the name kernel-headers exists (RHEL / CentOS), use the
# version number of the kernel that package is based on. This provides the
# version number when building on a koji build server.
# - Otherwise use the version number of the running kernel.
%{!?kversion:%define kversion %{expand:%%(
if rpm --quiet -q kernel-headers; then
rpm -q --qf '%%%%{version}-%%%%{release}.%%%%{arch}\\n' \\
kernel-headers | head -n1;
else
uname -r;
fi
)}}
%{echo:kversion=%{kversion}
}
# kernel_rpm: Name of the kernel RPM if the kernel is available as an RPM.
%if %{expand:%%(rpm --quiet -q kernel-headers ||
rpm --quiet -qf /lib/modules/%{kversion}/kernel/arch 2>/dev/null;
echo $((1-$?)))}
%define kernel_rpm %{expand:%%(
if rpm --quiet -q kernel-headers; then
echo kernel;
else
rpm -q --qf '%%%%{name}\\n' \\
"$(rpm -qf /lib/modules/%%{kversion}/kernel/arch | head -n1)";
fi
)}
%endif
# krpmver: Version of the kernel RPM. Not necessarily identical to %{kversion}.
%{?kernel_rpm:%define krpmver %{expand:%%(
if rpm --quiet -q %%{kernel_rpm}; then
rpm -q --qf '%%%%{version}-%%%%{release}\\n' "%%{kernel_rpm}";
else
rpm -q --qf '%%%%{version}-%%%%{release}\\n' kernel-headers;
fi |
head -n1
)}}
%{echo:krpmver=%{krpmver}
}
# kernel_devel_rpm: Name of the kernel development RPM.
%{?kernel_rpm:%define kernel_devel_rpm %{kernel_rpm}-devel}
# Version of the RPM that is being built.
%define rpm_version @rpm_version@
# Make command with or without flags.
%define make %{expand:%%(echo ${MAKE:-make})}
%define pkgrel 1
%define dkms_version %{rpm_version}-%{pkgrel}%{?dist}
Name: %{kmod_name}-dkms
Version: %{rpm_version}
Release: %{pkgrel}%{?dist}
Summary: SCST mid-layer kernel drivers
Group: System/Kernel
License: GPLv2
Vendor: http://scst.sourceforge.net/
URL: http://scst.sourceforge.net/
# Unfortunately the Red Hat / CentOS kernel-debug-devel RPM provides
# kernel-devel so a workaround is needed to match the kernel-devel RPM.
BuildRequires: %{?kernel_rpm:%{kernel_rpm} = %{krpmver} %{kernel_devel_rpm} = %{krpmver}} gcc make
Source: %{kmod_name}-%{version}.tar.bz2
BuildRoot: %{_tmppath}/%{name}-%{version}-build
AutoReqProv: no
%description
A generic SCSI target subsystem for Linux that allows to convert any Linux
server into a sophisticated storage server. The three layers in SCST are the
target driver layer; the SCSI target core and the device handler layer. SCST
target drivers realize communication with an initiator and implement a storage
protocol like iSCSI, FC or SRP. SCST device handlers implement a SCSI
interface on top of local storage. Examples of such local storage are SCSI
RAID controller (dev_disk handler), block device (vdisk_blockio handler), file
(vdisk_fileio handler) or custom block device behavior implemented in user
space (scst_user).
Authors:
--------
Vladislav Bolkhovitin, Bart Van Assche and others
%package devel
Summary: SCST mid-layer kernel driver development package
Group: Development/Kernel
BuildArch: noarch
%description devel
A generic SCSI target subsystem for Linux (SCST) that allows to convert
any Linux server into a sophisticated storage server. SCST target drivers
implement protocols like iSCSI, FC or SRP. SCST device handlers either
provide access to a local SCSI RAID controller (dev_disk), block device
(vdisk_blockio), file (vdisk_fileio) or custom block device behavior
implemented in user space (scst_user).
Authors:
--------
Vladislav Bolkhovitin, Bart Van Assche and others
%package userspace
Summary: SCST mid-layer user space software
Group: Development/Kernel
Requires: scst-dkms
%description userspace
A generic SCSI target subsystem for Linux that allows to convert any Linux
server into a sophisticated storage server. The three layers in SCST are the
target driver layer; the SCSI target core and the device handler layer. SCST
target drivers realize communication with an initiator and implement a storage
protocol like iSCSI, FC or SRP. SCST device handlers implement a SCSI
interface on top of local storage. Examples of such local storage are SCSI
RAID controller (dev_disk handler), block device (vdisk_blockio handler), file
(vdisk_fileio handler) or custom block device behavior implemented in user
space (scst_user).
%prep
%setup -q -n %{kmod_name}-%{version}
%build
export KVER=%{kversion} PREFIX=%{_prefix}
export BUILD_2X_MODULE=y CONFIG_SCSI_QLA_FC=y CONFIG_SCSI_QLA2XXX_TARGET=y
for d in scst fcst iscsi-scst qla2x00t/qla2x00-target scst_local srpt; do
%{make} -C $d
done
%install
export KVER=%{kversion} PREFIX=%{_prefix} MANDIR=%{_mandir}
export BUILD_2X_MODULE=y CONFIG_SCSI_QLA_FC=y CONFIG_SCSI_QLA2XXX_TARGET=y
for d in scst; do
DESTDIR=%{buildroot} %{make} -C $d install
done
for d in fcst iscsi-scst qla2x00t/qla2x00-target scst_local srpt; do
DESTDIR=%{buildroot} INSTALL_MOD_PATH=%{buildroot} %{make} -C $d install
done
rm -f %{buildroot}/lib/modules/%{kversion}/[Mm]odule*
rm -rf %{buildroot}/lib/modules/%{kversion}/extra
install -d -m 755 %{buildroot}/usr/src/%{kmod_name}-%{dkms_version}
(
cd %{buildroot}/usr/src/%{kmod_name}-%{dkms_version} &&
tar --strip-components=1 -xaf %{SOURCE0}
)
cat >%{buildroot}/usr/src/%{kmod_name}-%{dkms_version}/dkms.conf <<"EOF"
PACKAGE_VERSION="%{dkms_version}"
PACKAGE_NAME="%{kmod_name}"
AUTOINSTALL=yes
MAKE[0]="export KVER=${kernelver} KDIR=${kernel_source_dir} BUILD_2X_MODULE=y CONFIG_SCSI_QLA_FC=y CONFIG_SCSI_QLA2XXX_TARGET=y && make -sC scst && make -sC fcst && make -sC iscsi-scst && make -sC qla2x00t/qla2x00-target && make -sC scst_local && make -sC srpt && cp */*.ko */*/*.ko */*/*/*.ko ."
CLEAN="make clean"
# Remove any existing ib_srpt.ko kernel modules
PRE_INSTALL="find /lib/modules/${kernelver} -name ib_srpt.ko -exec rm {} \;"
BUILT_MODULE_NAME[ 0]="fcst"
BUILT_MODULE_NAME[ 1]="ib_srpt"
BUILT_MODULE_NAME[ 2]="iscsi-scst"
BUILT_MODULE_NAME[ 3]="qla2x00tgt"
BUILT_MODULE_NAME[ 4]="qla2xxx_scst"
BUILT_MODULE_NAME[ 5]="scst"
BUILT_MODULE_NAME[ 6]="scst_local"
BUILT_MODULE_NAME[ 7]="scst_cdrom"
BUILT_MODULE_NAME[ 8]="scst_changer"
BUILT_MODULE_NAME[ 9]="scst_disk"
BUILT_MODULE_NAME[10]="scst_modisk"
BUILT_MODULE_NAME[11]="scst_processor"
BUILT_MODULE_NAME[12]="scst_raid"
BUILT_MODULE_NAME[13]="scst_tape"
BUILT_MODULE_NAME[14]="scst_user"
BUILT_MODULE_NAME[15]="scst_vdisk"
BUILT_MODULE_NAME[16]="isert-scst"
DEST_MODULE_LOCATION[ 0]="/extra"
DEST_MODULE_LOCATION[ 1]="/extra"
DEST_MODULE_LOCATION[ 2]="/extra"
DEST_MODULE_LOCATION[ 3]="/extra"
DEST_MODULE_LOCATION[ 4]="/extra"
DEST_MODULE_LOCATION[ 5]="/extra"
DEST_MODULE_LOCATION[ 6]="/extra"
DEST_MODULE_LOCATION[ 7]="/extra/dev_handlers"
DEST_MODULE_LOCATION[ 8]="/extra/dev_handlers"
DEST_MODULE_LOCATION[ 9]="/extra/dev_handlers"
DEST_MODULE_LOCATION[10]="/extra/dev_handlers"
DEST_MODULE_LOCATION[11]="/extra/dev_handlers"
DEST_MODULE_LOCATION[12]="/extra/dev_handlers"
DEST_MODULE_LOCATION[13]="/extra/dev_handlers"
DEST_MODULE_LOCATION[14]="/extra/dev_handlers"
DEST_MODULE_LOCATION[15]="/extra/dev_handlers"
DEST_MODULE_LOCATION[16]="/extra"
EOF
%clean
rm -rf %{buildroot}
%pre
# Remove any existing ib_srpt.ko kernel modules
find /lib/modules/%{kversion} -name ib_srpt.ko -exec rm {} \;
# Remove files installed by "make install"
rm -f /usr/local/man/man5/iscsi-scstd.conf.5
rm -f /usr/local/man/man8/iscsi-scst-adm.8
rm -f /usr/local/man/man8/iscsi-scstd.8
rm -f /usr/local/sbin/iscsi-scst-adm
rm -f /usr/local/sbin/iscsi-scstd
rm -rf /usr/local/include/scst
%pre userspace
# Remove files installed by "make install"
rm -f /usr/local/man/man5/iscsi-scstd.conf.5
rm -f /usr/local/man/man8/iscsi-scst-adm.8
rm -f /usr/local/man/man8/iscsi-scstd.8
rm -f /usr/local/sbin/iscsi-scst-adm
rm -f /usr/local/sbin/iscsi-scstd
rm -rf /usr/local/include/scst
%post
dkms add -m %{kmod_name} -v %{dkms_version} --rpm_safe_upgrade
dkms build -m %{kmod_name} -v %{dkms_version}
dkms install -m %{kmod_name} -v %{dkms_version}
%preun
dkms remove -m %{kmod_name} -v %{dkms_version} --rpm_safe_upgrade --all
true
%files
%defattr(-,root,root)
/usr/src/%{kmod_name}-%{dkms_version}/
%files userspace
%{_mandir}/man5/iscsi-scstd.conf.5.gz
%{_mandir}/man8/iscsi-scst-adm.8.gz
%{_mandir}/man8/iscsi-scstd.8.gz
%{_sbindir}/iscsi-scst-adm
%{_sbindir}/iscsi-scstd
%dir /var/lib/scst/pr
%dir /var/lib/scst/vdev_mode_pages
%files devel
%defattr(-,root,root)
%dir /usr/include/scst
/usr/include/scst/Module.symvers
/usr/include/scst/scst.h
/usr/include/scst/scst_const.h
/usr/include/scst/scst_debug.h
/usr/include/scst/scst_itf_ver.h
/usr/include/scst/scst_sgv.h
/usr/include/scst/scst_user.h
%changelog
* Mon Feb 23 2015 Bart Van Assche <bart.vanassche@sandisk.com>
- Split spec file into a non-DKMS and a DKMS spec file.
* Fri Jan 16 2015 Bart Van Assche <bart.vanassche@sandisk.com>
- Added DKMS support.
* Fri Nov 22 2013 Bart Van Assche <bvanassche@acm.org>
- Initial spec file.
+6 -107
View File
@@ -8,8 +8,8 @@
# - Otherwise use the version number of the running kernel.
%{!?kversion:%define kversion %{expand:%%(
if rpm --quiet -q kernel-headers; then
rpm -q --qf '%%%%{version}-%%%%{release}.%%%%{arch}' \\
kernel-headers;
rpm -q --qf '%%%%{version}-%%%%{release}.%%%%{arch}\\n' \\
kernel-headers | head -n1;
else
uname -r;
fi
@@ -47,9 +47,8 @@
# Make command with or without flags.
%define make %{expand:%%(echo ${MAKE:-make})}
%define pkgrel 1
%define dkms_version %{rpm_version}-%{pkgrel}%{?dist}
Name: %{kmod_name}
Name: %{kmod_name}-%{kversion}
Version: %{rpm_version}
Release: %{pkgrel}%{?dist}
Summary: SCST mid-layer kernel drivers
@@ -57,9 +56,9 @@ Group: System/Kernel
License: GPLv2
Vendor: http://scst.sourceforge.net/
URL: http://scst.sourceforge.net/
%{?kernel_rpm:Requires: %{kernel_rpm} = %{krpmver}}
# Unfortunately the Red Hat / CentOS kernel-debug-devel RPM provides
# kernel-devel so a workaround is needed to match the kernel-devel RPM.
%{?kernel_rpm:Requires: %{kernel_rpm} = %{krpmver}}
BuildRequires: %{?kernel_rpm:%{kernel_rpm} = %{krpmver} %{kernel_devel_rpm} = %{krpmver}} gcc make
Source: %{kmod_name}-%{version}.tar.bz2
@@ -81,22 +80,6 @@ Authors:
--------
Vladislav Bolkhovitin, Bart Van Assche and others
%package userspace
Summary: SCST mid-layer user space software
Group: Development/Kernel
Requires: scst-dkms
%description userspace
A generic SCSI target subsystem for Linux that allows to convert any Linux
server into a sophisticated storage server. The three layers in SCST are the
target driver layer; the SCSI target core and the device handler layer. SCST
target drivers realize communication with an initiator and implement a storage
protocol like iSCSI, FC or SRP. SCST device handlers implement a SCSI
interface on top of local storage. Examples of such local storage are SCSI
RAID controller (dev_disk handler), block device (vdisk_blockio handler), file
(vdisk_fileio handler) or custom block device behavior implemented in user
space (scst_user).
%package devel
Summary: SCST mid-layer kernel driver development package
Group: Development/Kernel
@@ -110,25 +93,6 @@ provide access to a local SCSI RAID controller (dev_disk), block device
(vdisk_blockio), file (vdisk_fileio) or custom block device behavior
implemented in user space (scst_user).
Authors:
--------
Vladislav Bolkhovitin, Bart Van Assche and others
%package dkms
Summary: DKMS-enabled SCST source code package
Group: System/Kernel
BuildArch: noarch
Requires(pre): dkms gcc make
Requires(post): dkms
%description dkms
A generic SCSI target subsystem for Linux (SCST) that allows to convert
any Linux server into a sophisticated storage server. SCST target drivers
implement protocols like iSCSI, FC or SRP. SCST device handlers either
provide access to a local SCSI RAID controller (dev_disk), block device
(vdisk_blockio), file (vdisk_fileio) or custom block device behavior
implemented in user space (scst_user).
Authors:
--------
Vladislav Bolkhovitin, Bart Van Assche and others
@@ -155,55 +119,6 @@ for d in fcst iscsi-scst qla2x00t/qla2x00-target scst_local srpt; do
done
rm -f %{buildroot}/lib/modules/%{kversion}/[Mm]odule*
install -d -m 755 %{buildroot}/usr/src/%{kmod_name}-%{dkms_version}
(
cd %{buildroot}/usr/src/%{kmod_name}-%{dkms_version} &&
tar --strip-components=1 -xaf %{SOURCE0}
)
cat >%{buildroot}/usr/src/%{kmod_name}-%{dkms_version}/dkms.conf <<"EOF"
PACKAGE_VERSION="%{dkms_version}"
PACKAGE_NAME="%{kmod_name}"
AUTOINSTALL=yes
MAKE[0]="export KVER=${kernelver} KDIR=${kernel_source_dir} BUILD_2X_MODULE=y CONFIG_SCSI_QLA_FC=y CONFIG_SCSI_QLA2XXX_TARGET=y && make -sC scst && make -sC fcst && make -sC iscsi-scst && make -sC qla2x00t/qla2x00-target && make -sC scst_local && make -sC srpt && cp */*.ko */*/*.ko */*/*/*.ko ."
CLEAN="make clean"
# Remove any existing ib_srpt.ko kernel modules
PRE_INSTALL="find /lib/modules/${kernelver} -name ib_srpt.ko -exec rm {} \;"
BUILT_MODULE_NAME[ 0]="fcst"
BUILT_MODULE_NAME[ 1]="ib_srpt"
BUILT_MODULE_NAME[ 2]="iscsi-scst"
BUILT_MODULE_NAME[ 3]="qla2x00tgt"
BUILT_MODULE_NAME[ 4]="qla2xxx_scst"
BUILT_MODULE_NAME[ 5]="scst"
BUILT_MODULE_NAME[ 6]="scst_local"
BUILT_MODULE_NAME[ 7]="scst_cdrom"
BUILT_MODULE_NAME[ 8]="scst_changer"
BUILT_MODULE_NAME[ 9]="scst_disk"
BUILT_MODULE_NAME[10]="scst_modisk"
BUILT_MODULE_NAME[11]="scst_processor"
BUILT_MODULE_NAME[12]="scst_raid"
BUILT_MODULE_NAME[13]="scst_tape"
BUILT_MODULE_NAME[14]="scst_user"
BUILT_MODULE_NAME[15]="scst_vdisk"
BUILT_MODULE_NAME[16]="isert-scst"
DEST_MODULE_LOCATION[ 0]="/extra"
DEST_MODULE_LOCATION[ 1]="/extra"
DEST_MODULE_LOCATION[ 2]="/extra"
DEST_MODULE_LOCATION[ 3]="/extra"
DEST_MODULE_LOCATION[ 4]="/extra"
DEST_MODULE_LOCATION[ 5]="/extra"
DEST_MODULE_LOCATION[ 6]="/extra"
DEST_MODULE_LOCATION[ 7]="/extra/dev_handlers"
DEST_MODULE_LOCATION[ 8]="/extra/dev_handlers"
DEST_MODULE_LOCATION[ 9]="/extra/dev_handlers"
DEST_MODULE_LOCATION[10]="/extra/dev_handlers"
DEST_MODULE_LOCATION[11]="/extra/dev_handlers"
DEST_MODULE_LOCATION[12]="/extra/dev_handlers"
DEST_MODULE_LOCATION[13]="/extra/dev_handlers"
DEST_MODULE_LOCATION[14]="/extra/dev_handlers"
DEST_MODULE_LOCATION[15]="/extra/dev_handlers"
DEST_MODULE_LOCATION[16]="/extra"
EOF
%clean
rm -rf %{buildroot}
@@ -217,9 +132,6 @@ rm -f /usr/local/man/man8/iscsi-scstd.8
rm -f /usr/local/sbin/iscsi-scst-adm
rm -f /usr/local/sbin/iscsi-scstd
rm -rf /usr/local/include/scst
%pre userspace
# Remove files installed by "make install"
rm -f /usr/local/man/man5/iscsi-scstd.conf.5
rm -f /usr/local/man/man8/iscsi-scst-adm.8
rm -f /usr/local/man/man8/iscsi-scstd.8
@@ -230,15 +142,6 @@ rm -rf /usr/local/include/scst
%post
/sbin/depmod -a %{kversion}
%post dkms
dkms add -m %{kmod_name} -v %{dkms_version} --rpm_safe_upgrade
dkms build -m %{kmod_name} -v %{dkms_version}
dkms install -m %{kmod_name} -v %{dkms_version}
%preun dkms
dkms remove -m %{kmod_name} -v %{dkms_version} --rpm_safe_upgrade --all
true
%files
%defattr(-,root,root)
%dir /lib/modules/%{kversion}/extra
@@ -267,8 +170,6 @@ true
%{_sbindir}/iscsi-scstd
%dir /var/lib/scst/pr
%dir /var/lib/scst/vdev_mode_pages
%files userspace
%{_mandir}/man5/iscsi-scstd.conf.5.gz
%{_mandir}/man8/iscsi-scst-adm.8.gz
%{_mandir}/man8/iscsi-scstd.8.gz
@@ -288,11 +189,9 @@ true
/usr/include/scst/scst_sgv.h
/usr/include/scst/scst_user.h
%files dkms
%defattr(-,root,root)
/usr/src/%{kmod_name}-%{dkms_version}/
%changelog
* Mon Feb 23 2015 Bart Van Assche <bart.vanassche@sandisk.com>
- Split spec file into a non-DKMS and a DKMS spec file.
* Fri Jan 16 2015 Bart Van Assche <bart.vanassche@sandisk.com>
- Added DKMS support.
* Fri Nov 22 2013 Bart Van Assche <bvanassche@acm.org>
+2 -2
View File
@@ -1,9 +1,9 @@
#
# Common makefile for SCSI target mid-level and its drivers
#
# Copyright (C) 2004 - 2014 Vladislav Bolkhovitin <vst@vlnb.net>
# Copyright (C) 2004 - 2015 Vladislav Bolkhovitin <vst@vlnb.net>
# Copyright (C) 2004 - 2005 Leonid Stoljar
# Copyright (C) 2007 - 2014 Fusion-io, Inc.
# Copyright (C) 2007 - 2015 SanDisk Corporation
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
+180 -13
View File
@@ -159,6 +159,23 @@ IMPORTANT: In the current version simultaneous access to local SCSI devices
To uninstall, type 'make scst_uninstall'.
Creating a kernel patch or patched kernel
-----------------------------------------
You can use generate-kernel-patch or generate-patched-kernel scripts in
the scripts/ subdirectory to convert SCST source tree as it exists
in the Subversion repository to a Linux kernel patch or generate a
kernel source tree with the SCST patches applied correspondingly. This
subdirectory exists only in the SVN tree.
Example how to use generate-kernel-patch you can find at "How To install
SCST on Ubutuntu 15.04 with in-tree kernel patches"
https://gist.github.com/chrwei/42f8bbb687290b04b598, thanks to Chris Weiss.
Script rebuild-rhel-kernel-rpm might also be useful in this regard.
Migration from the obsolete proc interface
------------------------------------------
@@ -331,6 +348,11 @@ in/out in Makefile and scst.h:
can clear already measured results by writing 0 in each file. Note,
you need a non-preemptible kernel to have correct results.
- CONFIG_SCST_DIF_INJECT_CORRUPTED_TAGS - if defined, allows injection
of corrupted DIF tags according to the Oracle specification. This
functionality is working only if dif_mode doesn't contain dev_store
and dif_type is 1.
HIGHMEM kernel configurations are fully supported, but not recommended
for performance reasons, except for scst_user, where they are not
supported, because this module deals with user supplied memory on a
@@ -584,15 +606,25 @@ Every target should have at least the following entries:
* 0 - disable black hole mode
* 1 - immediately abort all coming commands
* 1 - immediately abort all coming SCSI commands, i.e. all SCSI commands
are dropped and TM requests return that they completed. It is
supposed to simulate lost front end responses.
* 2 - immediately abort all coming commands and drop all coming TM
commands
* 2 - immediately abort all coming SCSI commands and drop all coming TM
commands. It is supposed to simulate logical target hang, when the
target stops responding, but on the HW/TCP connection level still
appears to be online.
* 3 - immediately abort all coming data transfer commands.
* 3 - immediately abort all coming data transfer SCSI commands, i.e.
only data transfer SCSI commands are dropped, while commands like
INQUIRY and TEST UNIT READY pass well. It is supposed to simulate
flaky front end connectivity, when responses for small commands
pass well, but big data transfers fail.
* 4 - immediately abort all coming data transfer commands and drop all
coming TM commands
* 4 - immediately abort all coming data transfer SCSI commands and
drop all coming TM commands. It is supposed to simulate really
flaky front end connectivity, when TM requests or responses are
also lost.
Modes 3 and 4 are the most evil ones, because they are not too well
handled by many initiator OS'es, including Linux, so they may never
@@ -603,6 +635,17 @@ Every target should have at least the following entries:
particular target driver or not, you can find out by checking traces
or the target driver's source code.
- dif_capabilities - if this target supports T10-PI, returns which
exact DIF capabilities this target supports.
- dif_checks_failed - if this target supports T10-PI, returns
statistics how many DIF errors have been detected on the
corresponding processing stages on this target. It returns 3 rows of
numbers with 3 numbers in each row: for target driver stage, for SCST
stage and for dev handler stage. Numbers in each row: how many errors
detected checking application, reference and guard tags
correspondingly. Writing to this attribute resets the numbers.
- cpu_mask - defines CPU affinity mask for threads serving this target.
For threads serving LUNs it is used only for devices with
threads_pool_type "per_initiator".
@@ -639,6 +682,24 @@ Every target should have at least the following entries:
until rel_tgt_id becomes unique. This attribute initialized unique by
SCST by default.
- forwarding - if set this target is forwarding target, i.e. does not check
any local SCSI events (reservations, etc.). Those event supposed to
be checked on the another, requester's side.
- *count*, e.g. read_io_count_kb, - statistics about executed
commands and transferred data. Those attributes have speaking names
built from parts:
1. Data transfer direction
2. Alignment type: not specified or unaligned (on 4K boundaries)
3. Type: IO (commands) count or amount of transferred data
4. For transferred data: measurement units
For instance, read_unaligned_cmd_count means number of 4K unaligned IOs.
A target driver may have also the following entries:
- "hw_target" - if the target driver supports both hardware and virtual
@@ -648,9 +709,8 @@ A target driver may have also the following entries:
exist and contain value 1.
Subdirectory "sessions" contains one subdirectory for each connected
session with name equal to name of the connected initiator.
Each session subdirectory contains the following entries:
session with name equal to name of the connected initiator with the
following entries:
- initiator_name - contains initiator name
@@ -662,9 +722,48 @@ Each session subdirectory contains the following entries:
- commands - contains overall number of SCSI commands in this session.
- dif_checks_failed - if target of this session supports T10-PI, returns
statistics how many DIF errors have been detected on the
corresponding processing stages on all DIF-enabled LUNs in this
session. It returns 3 rows of numbers with 3 numbers in each row: for
target driver stage, for SCST stage and for dev handler stage.
Numbers in each row: how many errors detected checking application,
reference and guard tags correspondingly. Writing to this attribute
resets the numbers. Similar statistics returned in attribute with the
same name for each LUN in this session in this LUN's subdirectory, if
its device configured with dif_type > 0.
- read_cmd_count - number of READ SCSI commands received since beginning
or last reset (writing 0 in this attribute)
- read_io_count_kb - amount of data in KB read by the initiator since
beginning or last reset (writing 0 in this attribute)
- write_cmd_count - number of WRITE SCSI commands received since
beginning or last reset (writing 0 in this attribute)
- write_io_count_kb - amount of data in KB written by the initiator
since beginning or last reset (writing 0 in this attribute)
- bidi_cmd_count - number of BIDI SCSI commands received since
beginning or last reset (writing 0 in this attribute)
- bidi_io_count_kb - amount of data in KB transferred by the
initiator since beginning or last reset (writing 0 in this attribute)
- none_cmd_count - number of not transferring data SCSI commands
(e.g. INQUIRY or TEST UNIT READY) received since beginning or last
reset (writing 0 in this attribute)
- unknown_cmd_count - number of unknown SCSI commands received since
beginning or last reset (writing 0 in this attribute)
- latency - if CONFIG_SCST_MEASURE_LATENCY enabled, contains latency
statistics for this session.
- *count*, e.g. read_io_count_kb, - statistics about executed
commands and transferred data. See above for more details.
- luns - a link pointing out to the corresponding LUNs set (security
group) where this session was attached to.
@@ -959,6 +1058,49 @@ cache. The following parameters possible for vdisk_fileio:
- zero_copy - if set, then this device uses zero copy access to the
page cache. At the moment, only read side zero copy is implemented.
- dif_mode - specifies which T10-PI, or DIF, mode this device will use.
See SCSI standards from more info about T10-PI. Available DIF modes
(can be combined using '|'):
* tgt - DIF tags are checked on the target hardware, if supported
* scst - DIF tags are checked inside SCST core
* dev_check - DIF tags are checked inside backend device. No DIF
tags storing is required, but optionally possible.
* dev_store - DIF tags are stored inside backend device on the WRITE
path and read from it on the READ path. No DIF tags checking is
required, but optionally possible.
For instance, if only tgt DIF mode specified, then target driver,
serving this device, will inside hardware check, then STRIP DIF tags
from SCSI commands on the WRITE path and generate, then INSERT DIF
tags into SCSI commands on the READ path, so neither SCST core, nor
dev handler will see them.
Similarly, if only scst DIF mode specified, then target driver will
PASS DIF tags into SCST core, which then check/STRIP/generate/INSERT
them, so dev handler will not see them.
If only dev_check DIF mode specified, then both target driver and
SCST core will PASS DIF tags into the dev handler, which is then
responsible to check them in the backend hardware. If only dev_store
specified, then DIF tags will only be stored by the dev handler in
the backend hardware without checking at any level.
If all "tgt|scst|dev_check|dev_store" DIF mode specified, then all
target driver, SCST core and dev handler will check DIF tags, then
dev handler will store them in the backend hardware.
- dif_type - specifies which DIF SCSI type this device will use.
- dif_static_app_tag - specifies fixed (static) DIF application tag for
this device.
- dif_filename - specifies full path to filename, where DIF tags will
be stored.
Handler vdisk_blockio provides BLOCKIO mode to create virtual devices.
This mode performs direct block I/O with a block device, bypassing the
page cache for all operations. This mode works ideally with high-end
@@ -966,10 +1108,10 @@ storage HBAs and for applications that either do not need caching
between application and disk or need the large block throughput. See
below for more info.
The following common with vdisk_fileio parameters are possible for
vdisk_blockio: filename, blocksize, nv_cache, write_through, read_only,
removable, rotational, thin_provisioned, tst. See vdisk_fileio above for
description of those parameters.
The following parameters possible for vdisk_blockio: filename,
blocksize, nv_cache, read_only, removable, rotational, thin_provisioned,
tst, dif_mode, dif_type, dif_static_app_tag, dif_filename. See
vdisk_fileio above for description of those parameters.
Handler vdisk_nullio provides NULLIO mode to create virtual devices. In
this mode no real I/O is done, but success returned to initiators.
@@ -2060,6 +2202,31 @@ transfers. As the result, those threads won't receive all the processing
power of those CPUs and perform worse.
Commands suspending takes too long
----------------------------------
SCST is suspending commands during some management activities like
adding/deleting LUNs or devices. It is done to have lockless LUNs
translation on the hot commands processing path. This brings significant
performance advantage. You will see a message like "Waiting for X active
commands to complete" when this wait started.
But downside of it is that no new commands start executing until older
ones, which had started before the suspending begun, finished. This
wait can not be any longer, than the worst command latency any your
initiator is seeing at this particular time.
So, if this wait takes too long, in majority of cases it means that you
are overloading your storage. A proper storage should have worst case
latency below few hundreds of milliseconds. In this case the SCST
suspending will finish in few hundreds of milliseconds at worse.
Another case, when it can take too long to suspend is a hung user space
device (i.e. scst_user device) not responding to any command. In this
case you should kill the corresponding user space program to finish
suspending.
Work if target's backstorage or link is too slow
------------------------------------------------
+163 -13
View File
@@ -233,6 +233,11 @@ your favorite kernel configuration Makefile target, e.g. "make xconfig":
can clear already measured results by writing 0 in each file. Note,
you need a non-preemptible kernel to have correct results.
- CONFIG_SCST_DIF_INJECT_CORRUPTED_TAGS - if defined, allows injection
of corrupted DIF tags according to the Oracle specification. This
functionality is working only if dif_mode doesn't contain dev_store
and dif_type is 1.
HIGHMEM kernel configurations are fully supported, but not recommended
for performance reasons.
@@ -460,15 +465,25 @@ Every target should have at least the following entries:
* 0 - disable black hole mode
* 1 - immediately abort all coming commands
* 1 - immediately abort all coming SCSI commands, i.e. all SCSI commands
are dropped and TM requests return that they completed. It is
supposed to simulate lost front end responses.
* 2 - immediately abort all coming commands and drop all coming TM
commands
* 2 - immediately abort all coming SCSI commands and drop all coming TM
commands. It is supposed to simulate logical target hang, when the
target stops responding, but on the HW/TCP connection level still
appears to be online.
* 3 - immediately abort all coming data transfer commands.
* 3 - immediately abort all coming data transfer SCSI commands, i.e.
only data transfer SCSI commands are dropped, while commands like
INQUIRY and TEST UNIT READY pass well. It is supposed to simulate
flaky front end connectivity, when responses for small commands
pass well, but big data transfers fail.
* 4 - immediately abort all coming data transfer commands and drop all
coming TM commands
* 4 - immediately abort all coming data transfer SCSI commands and
drop all coming TM commands. It is supposed to simulate really
flaky front end connectivity, when TM requests or responses are
also lost.
Modes 3 and 4 are the most evil ones, because they are not too well
handled by many initiator OS'es, including Linux, so they may never
@@ -479,6 +494,17 @@ Every target should have at least the following entries:
particular target driver or not, you can find out by checking traces
or the target driver's source code.
- dif_capabilities - if this target supports T10-PI, returns which
exact DIF capabilities this target supports.
- dif_checks_failed - if this target supports T10-PI, returns
statistics how many DIF errors have been detected on the
corresponding processing stages on this target. It returns 3 rows of
numbers with 3 numbers in each row: for target driver stage, for SCST
stage and for dev handler stage. Numbers in each row: how many errors
detected checking application, reference and guard tags
correspondingly. Writing to this attribute resets the numbers.
- cpu_mask - defines CPU affinity mask for threads serving this target.
For threads serving LUNs it is used only for devices with
threads_pool_type "per_initiator".
@@ -515,6 +541,24 @@ Every target should have at least the following entries:
until rel_tgt_id becomes unique. This attribute initialized unique by
SCST by default.
- forwarding - if set this target is forwarding target, i.e. does not check
any local SCSI events (reservations, etc.). Those event supposed to
be checked on the another, requester's side.
- *count*, e.g. read_io_count_kb, - statistics about executed
commands and transferred data. Those attributes have speaking names
built from parts:
1. Data transfer direction
2. Alignment type: not specified or unaligned (on 4K boundaries)
3. Type: IO (commands) count or amount of transferred data
4. For transferred data: measurement units
For instance, read_unaligned_cmd_count means number of 4K unaligned IOs.
A target driver may have also the following entries:
- "hw_target" - if the target driver supports both hardware and virtual
@@ -524,9 +568,8 @@ A target driver may have also the following entries:
exist and contain value 1.
Subdirectory "sessions" contains one subdirectory for each connected
session with name equal to name of the connected initiator.
Each session subdirectory contains the following entries:
session with name equal to name of the connected initiator with the
following entries:
- initiator_name - contains initiator name
@@ -538,9 +581,48 @@ Each session subdirectory contains the following entries:
- commands - contains overall number of SCSI commands in this session.
- dif_checks_failed - if target of this session supports T10-PI, returns
statistics how many DIF errors have been detected on the
corresponding processing stages on all DIF-enabled LUNs in this
session. It returns 3 rows of numbers with 3 numbers in each row: for
target driver stage, for SCST stage and for dev handler stage.
Numbers in each row: how many errors detected checking application,
reference and guard tags correspondingly. Writing to this attribute
resets the numbers. Similar statistics returned in attribute with the
same name for each LUN in this session in this LUN's subdirectory, if
its device configured with dif_type > 0.
- read_cmd_count - number of READ SCSI commands received since beginning
or last reset (writing 0 in this attribute)
- read_io_count_kb - amount of data in KB read by the initiator since
beginning or last reset (writing 0 in this attribute)
- write_cmd_count - number of WRITE SCSI commands received since
beginning or last reset (writing 0 in this attribute)
- write_io_count_kb - amount of data in KB written by the initiator
since beginning or last reset (writing 0 in this attribute)
- bidi_cmd_count - number of BIDI SCSI commands received since
beginning or last reset (writing 0 in this attribute)
- bidi_io_count_kb - amount of data in KB transferred by the
initiator since beginning or last reset (writing 0 in this attribute)
- none_cmd_count - number of not transferring data SCSI commands
(e.g. INQUIRY or TEST UNIT READY) received since beginning or last
reset (writing 0 in this attribute)
- unknown_cmd_count - number of unknown SCSI commands received since
beginning or last reset (writing 0 in this attribute)
- latency - if CONFIG_SCST_MEASURE_LATENCY enabled, contains latency
statistics for this session.
- *count*, e.g. read_io_count_kb, - statistics about executed
commands and transferred data. See above for more details.
- luns - a link pointing out to the corresponding LUNs set (security
group) where this session was attached to.
@@ -831,6 +913,49 @@ cache. The following parameters possible for vdisk_fileio:
- zero_copy - if set, then this device uses zero copy access to the
page cache. At the moment, only read side zero copy is implemented.
- dif_mode - specifies which T10-PI, or DIF, mode this device will use.
See SCSI standards from more info about T10-PI. Available DIF modes
(can be combined using '|'):
* tgt - DIF tags are checked on the target hardware, if supported
* scst - DIF tags are checked inside SCST core
* dev_check - DIF tags are checked inside backend device. No DIF
tags storing is required, but optionally possible.
* dev_store - DIF tags are stored inside backend device on the WRITE
path and read from it on the READ path. No DIF tags checking is
required, but optionally possible.
For instance, if only tgt DIF mode specified, then target driver,
serving this device, will inside hardware check, then STRIP DIF tags
from SCSI commands on the WRITE path and generate, then INSERT DIF
tags into SCSI commands on the READ path, so neither SCST core, nor
dev handler will see them.
Similarly, if only scst DIF mode specified, then target driver will
PASS DIF tags into SCST core, which then check/STRIP/generate/INSERT
them, so dev handler will not see them.
If only dev_check DIF mode specified, then both target driver and
SCST core will PASS DIF tags into the dev handler, which is then
responsible to check them in the backend hardware. If only dev_store
specified, then DIF tags will only be stored by the dev handler in
the backend hardware without checking at any level.
If all "tgt|scst|dev_check|dev_store" DIF mode specified, then all
target driver, SCST core and dev handler will check DIF tags, then
dev handler will store them in the backend hardware.
- dif_type - specifies which DIF SCSI type this device will use.
- dif_static_app_tag - specifies fixed (static) DIF application tag for
this device.
- dif_filename - specifies full path to filename, where DIF tags will
be stored.
Handler vdisk_blockio provides BLOCKIO mode to create virtual devices.
This mode performs direct block I/O with a block device, bypassing the
page cache for all operations. This mode works ideally with high-end
@@ -838,10 +963,10 @@ storage HBAs and for applications that either do not need caching
between application and disk or need the large block throughput. See
below for more info.
The following common with vdisk_fileio parameters are possible for
vdisk_blockio: filename, blocksize, nv_cache, write_through, read_only,
removable, rotational, thin_provisioned, tst. See vdisk_fileio above for
description of those parameters.
The following parameters possible for vdisk_blockio: filename,
blocksize, nv_cache, read_only, removable, rotational, thin_provisioned,
tst, dif_mode, dif_type, dif_static_app_tag, dif_filename. See
vdisk_fileio above for description of those parameters.
Handler vdisk_nullio provides NULLIO mode to create virtual devices. In
this mode no real I/O is done, but success returned to initiators.
@@ -1556,6 +1681,31 @@ transfers. As the result, those threads won't receive all the processing
power of those CPUs and perform worse.
Commands suspending takes too long
----------------------------------
SCST is suspending commands during some management activities like
adding/deleting LUNs or devices. It is done to have lockless LUNs
translation on the hot commands processing path. This brings significant
performance advantage. You will see a message like "Waiting for X active
commands to complete" when this wait started.
But downside of it is that no new commands start executing until older
ones, which had started before the suspending begun, finished. This
wait can not be any longer, than the worst command latency any your
initiator is seeing at this particular time.
So, if this wait takes too long, in majority of cases it means that you
are overloading your storage. A proper storage should have worst case
latency below few hundreds of milliseconds. In this case the SCST
suspending will finish in few hundreds of milliseconds at worse.
Another case, when it can take too long to suspend is a hung user space
device (i.e. scst_user device) not responding to any command. In this
case you should kill the corresponding user space program to finish
suspending.
Work if target's backstorage or link is too slow
------------------------------------------------
+141
View File
@@ -0,0 +1,141 @@
GENERAL CONSIDERATIONS
======================
SCST has almost full features implementation of T10-PI standard
supporting all protection modes. The only missing feature is Application
Tag mode page. A patch implementing it is welcome.
SCST T10-PI implementation has 2 modes of operations:
1. Computing. In this mode no protection information (PI) is stored. It
only checked upon arrival (WRITEs) and calculated from the data upon
sending (READs). Goal of this mode to provide protection against uplink,
i.e. path to initiator, corruptions.
2. Storing. In this mode PI is stored either in a file/device as simple
array with 8 bytes entries, or inside block device using block integrity
extensions. In this mode full end-to-end protection could be
implemented.
In both "computing" and "storing" modes PI can be checked on any stages
of commands processing:
1. Target HW
2. SCST
3. Backend HW, if it supports block integrity extensions.
Any of them or all can be independently enabled or disabled depending
from level of performance overhead and required protection. For
instance, the target HW stage is the cheapest from performance
perspective, but doesn't protect against corruptions or misdirections on
PCI bus between the target HW and system. Another example, if backend HW
supports T10-PI, no checks on other stages are generally needed, but can
be used to localize place where corruption happened. Checking on each
stage to be able to localize corruption place is the recommended by T10
way of processing.
USER INTERFACE
==============
Currently only scst_vdisk handler supports T10-PI.
See in the main README description of SCST sysfs attributes:
dif_capabilities, dif_checks_failed, dif_mode, dif_type,
dif_static_app_tag and dif_filename.
Examples:
---------
dif_mode=tgt, dif_type=1 - TGT level only check, type 1
dif_mode=scst, dif_type=1, dif_static_app_tag=0x4149 -
SCST level only check, type 1, static app tag 0x4149
dif_mode=scst|dev_store, dif_type=1, dif_filename=/var/lib/scst/dif_tags/rd1_dif.dif -
SCST level only check and storing PI data in the file
dif_mode=scst, dif_type=2 - SCST level only check, type 2 (32-byte commands)
dif_mode=tag|scst|dev_check|dev_store, dif_type=1 - all levels check
storing tags using block integrity extensions, type 1
INTERFACE BETWEEN SCST AND TARGET DRIVERS
=========================================
To support T10-PI struct scst_tgt_template has several new fields:
supported_dif_block_sizes, dif_supported, hw_dif_type1_supported,
hw_dif_type2_supported, hw_dif_type3_supported, hw_dif_ip_supported,
hw_dif_same_sg_layout_required. See their description in their comments
in scst.h.
A READ-direction workflow from a target driver perspective should look
like:
1. No extra actions until xmit_response() stage*
2. On xmit_response() stage call scst_cmd_get_dif_sg(cmd)**. If returned
value is NULL, no further PI actions are needed.
3. Otherwise, call scst_get_read_dif_tgt_actions(cmd) to find out what
PI actions are needed. The return value has encoded 2 types of actions:
action itself and tags checks.
Possible actions, which could be extracted by using scst_get_dif_action(),
are:
- SCST_DIF_ACTION_STRIP - check, then strip the protection info, if it
is OK
- SCST_DIF_ACTION_INSERT - insert the protection info
- SCST_DIF_ACTION_PASS_CHECK - check the protection info, then pass it
to the initiator
- SCST_DIF_ACTION_PASS - then pass the protection information to the
initiator without checking
Possible tags checks, which could be extracted by using
scst_get_dif_checks() are:
- SCST_DIF_CHECK_GUARD_TAG - check the guard tags
- SCST_DIF_CHECK_REF_TAG - check the reference tags
- SCST_DIF_CHECK_APP_TAG - check the application tags comparing them to
the static tag set by dif_static_app_tag attribute
4. Perform the requested PI actions and transfer PI from the returned
dif_sg together with the regular data**.
A WRITE-direction workflow from a target driver perspective should look
like:
1. No extra actions until rdy_to_xfer() stage*
2. On rdy_to_xfer() stage call scst_cmd_get_dif_sg(cmd)**. If returned
value is NULL, no further PI actions are needed.
3. Otherwise, call scst_get_write_dif_tgt_actions(cmd) to find out what
PI actions are needed.
4. Perform the requested PI actions and transfer PI to the returned
dif_sg together with regular data**.
(*) If the target driver uses custom data buffer, on this stage it must
together with data sg by scst_cmd_set_tgt_dif_sg() function also set the
corresponding PI sg.
(**) The PI SG returned by scst_cmd_get_dif_sg() does not have the
corresponding SG-segments counter, because it is strictly bound to
number of blocks in the data SG.
You can find full external SCST T10-PI interface if you look in scst.h
functions with "_dif_" string in their name. They are well documented in
comments near them.
+886 -24
View File
File diff suppressed because it is too large Load Diff
+50 -3
View File
@@ -1,8 +1,8 @@
/*
* include/scst_const.h
*
* Copyright (C) 2004 - 2014 Vladislav Bolkhovitin <vst@vlnb.net>
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2004 - 2015 Vladislav Bolkhovitin <vst@vlnb.net>
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* Contains common SCST constants. This file supposed to be included
* from both kernel and user spaces.
@@ -334,6 +334,9 @@ static inline int scst_sense_response_code(const uint8_t *sense)
/* ABORTED_COMMAND is 0xb */
#define scst_sense_aborted_command ABORTED_COMMAND, 0x00, 0
#define scst_logical_block_guard_check_failed ABORTED_COMMAND, 0x10, 1
#define scst_logical_block_app_tag_check_failed ABORTED_COMMAND, 0x10, 2
#define scst_logical_block_ref_tag_check_failed ABORTED_COMMAND, 0x10, 3
#define scst_sense_internal_failure ABORTED_COMMAND, 0x44, 0 /* retriable */
/* MISCOMPARE is 0xe */
@@ -427,6 +430,13 @@ static inline int scst_sense_response_code(const uint8_t *sense)
#define UNMAP 0x42
#endif
/* Subcodes of VARIABLE_LENGTH_CMD (0x7F) */
#define SUBCODE_READ_32 0x09
#define SUBCODE_VERIFY_32 0x0a
#define SUBCODE_WRITE_32 0x0b
#define SUBCODE_WRITE_VERIFY_32 0x0c
#define SUBCODE_WRITE_SAME_32 0x0d
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0)
/*
* From <scsi/scsi.h>. See also commit
@@ -445,7 +455,6 @@ static inline int scst_sense_response_code(const uint8_t *sense)
#define BLKDISCARD _IO(0x12,119)
#endif
/*************************************************************
** SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft
** T10/1561-D Revision 4 Draft dated 7th November 2002.
@@ -520,6 +529,44 @@ enum {
#define SCST_QERR_2_RESERVED 2
#define SCST_QERR_3_ABORT_THIS_NEXUS_ONLY 3
/*************************************************************
** Values for the control mode page ATO field
*************************************************************/
/* I.e., app tags owned by storage */
#define SCST_ATO_0_MODIFIED_BY_STORAGE 0
/* I.e., app tags owned by application */
#define SCST_ATO_1_NOT_MODIFIED_BY_STORAGE 1
/*************************************************************
** Values for the control mode page DPICZ field
*************************************************************/
#define SCST_DPICZ_CHECK_ON_xPROT_0 0
#define SCST_DPICZ_NO_CHECK_ON_xPROT_0 1
/*************************************************************
** APP/REF TAG DIF constants
*************************************************************/
/* Skip all guards checks for this block */
#define SCST_DIF_NO_CHECK_ALL_APP_TAG cpu_to_be16(0xFFFF)
#define SCST_DIF_NO_CHECK_ALL_REF_TAG cpu_to_be32(0xFFFFFFFF)
/* Don't check app tag for this block */
#define SCST_DIF_NO_CHECK_APP_TAG 0
/*************************************************************
** Shift of size of DIF tag (8 bytes)
*************************************************************/
#define SCST_DIF_TAG_SHIFT 3
/*************************************************************
** Formats of DIF guard tags
*************************************************************/
#define SCST_DIF_GUARD_FORMAT_CRC 0
#define SCST_DIF_GUARD_FORMAT_IP 1
/*************************************************************
** TransportID protocol identifiers
*************************************************************/
+2 -2
View File
@@ -1,9 +1,9 @@
/*
* include/scst_debug.h
*
* Copyright (C) 2004 - 2014 Vladislav Bolkhovitin <vst@vlnb.net>
* Copyright (C) 2004 - 2015 Vladislav Bolkhovitin <vst@vlnb.net>
* Copyright (C) 2004 - 2005 Leonid Stoljar
* Copyright (C) 2007 - 2014 Fusion-io, Inc.
* Copyright (C) 2007 - 2015 SanDisk Corporation
*
* Contains macros for execution tracing and error reporting
*

Some files were not shown because too many files have changed in this diff Show More