Support for 24xx+ QLA chips added to qla2x00t. So far only for 2.6.26+ kernels.

git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1104 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2009-09-17 17:44:07 +00:00
parent 788c769a65
commit b03c72f55d
43 changed files with 9118 additions and 3997 deletions
+2 -4
View File
@@ -39,10 +39,8 @@ required.
<item> Undertakes most problems, related to execution contexts, thus
practically eliminating one of the most complicated problem in the
kernel drivers development. For example, a target driver for QLogic
22xx/23xx cards, which has all necessary features, is about 2000
lines of code long, that is at least in several times less, than the
initiator one.
kernel drivers development. For example, target drivers for Marvell SAS
adapters or for InfiniBand SRP are less 3000 lines of code long.
<item> Performs all required pre- and post- processing of incoming
requests and all necessary error recovery functionality.
+15 -3
View File
@@ -27,11 +27,23 @@ config SCSI_QLA_FC
ftp://ftp.qlogic.com/outgoing/linux/firmware/
config SCSI_QLA2XXX_TARGET
bool "QLogic 2XXX target mode support"
bool "QLogic 2xxx target mode support"
depends on SCSI_QLA_FC
default SCST
default y
---help---
This option enables target mode hooks used by the SCST qla2x00t driver.
This option enables target mode hooks used by the SCST QLA2x00tgt driver.
Once the qla2x00tgt module is loaded, target mode can be enable via a
sysfs interface under scsi_host, thus enabling target mode for specific
cards.
You will also need the SCST middle level drivers from http://scst.sf.net/.
config SCSI_QLA2XXX_TARGET_DISABLE_INI_MODE
bool "Disable initiator mode for ports with enabled target mode"
depends on SCSI_QLA2XXX_TARGET
default y
---help---
This option disables initiator mode for hosts for which target mode was
enabled. In other words, it disables possibility to use both target and
initiator mode simultaneously on the same host. It is needed, because
some switches don't handle well ports with both target and initiator
modes enabled.
+1 -25
View File
@@ -1,32 +1,8 @@
ifneq ($(PATCHLEVEL),)
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
obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o
else
ifeq ($(KVER),)
ifeq ($(KDIR),)
KVER = $(shell uname -r)
KDIR := /lib/modules/$(KVER)/build
endif
else
KDIR := /lib/modules/$(KVER)/build
endif
all:
$(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd)
install: all
$(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd) BUILD_INI=m \
modules_install
uninstall:
rm -f $(INSTALL_DIR)/qla2[2-3]00.ko $(INSTALL_DIR)/qla2xxx.ko
-/sbin/depmod -a $(KVER)
endif
clean:
rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend *~ Modules.symvers \
Module.symvers Module.markers modules.order
@@ -34,4 +10,4 @@ clean:
extraclean: clean
.PHONY: all install uninstall clean extraclean
.PHONY: clean extraclean
+9
View File
@@ -1,3 +1,12 @@
Summary of changes between versions 1.0.2 and 2.0.0
---------------------------------------------------
- Support for 24xx/25xx added
- Disable by default initiator mode if target mode enabled. It can be changed
using .config option CONFIG_SCSI_QLA2XXX_TARGET_DISABLE_INI_MODE.
Summary of changes between versions 1.0.1 and 1.0.2
---------------------------------------------------
+11
View File
@@ -17,3 +17,14 @@ config QLA_TGT_DEBUG_WORK_IN_THREAD
performance loss.
If unsure, say "N".
config QLA_TGT_DEBUG_SRR
bool "SRR debugging"
depends on SCST_QLA_TGT_ADDON
help
Turns on restransmitting packets (SRR)
debugging. In this mode some CTIOs will be "broken" to force the
initiator to issue a retransmit request. Useful for debugging and lead to big
performance loss.
If unsure, say "N".
+3
View File
@@ -2,7 +2,9 @@
# Qlogic 2x00 SCSI target driver makefile
#
# Copyright (C) 2004 - 2009 Vladislav Bolkhovitin <vst@vlnb.net>
# Copyright (C) 2004 - 2009 Vladislav Bolkhovitin <vst@vlnb.net>
# Copyright (C) 2004 - 2005 Leonid Stoljar
# Copyright (C) 2006 - 2009 ID7 Ltd.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@@ -41,6 +43,7 @@ EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECKS
#EXTRA_CFLAGS += -DCONFIG_SCST_TRACING
EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG -g
#EXTRA_CFLAGS += -DCONFIG_QLA_TGT_DEBUG_WORK_IN_THREAD
#EXTRA_CFLAGS += -DCONFIG_QLA_TGT_DEBUG_SRR
ifeq ($(KVER),)
ifeq ($(KDIR),)
+54 -22
View File
@@ -1,42 +1,43 @@
Target driver for Qlogic 22xx/23xx Fibre Channel cards
======================================================
Target driver for Qlogic 22xx/23xx/24xx/25xx Fibre Channel cards
================================================================
Version 1.0.2, XX XXXXX 2009
Version 2.0.0, XX XXXXX 2009
----------------------------
This driver has all required features and looks to be quite stable (for
beta) and useful. It 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. This driver was changed to provide the target mode support and
all 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 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
initiator driver was changed to provide the target mode support and all
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 1.0.2 and higher and
Linux kernel 2.6.26 and higher. If you need to use this driver on
kernels prior 2.6.26, you should apply qla_ini_pre-2.6.26.patch.
The original initiator driver was taken from the kernel 2.6.27.
The original initiator driver was taken from the kernel 2.6.26.
See also "ToDo" file for list of known issues and unimplemented
features.
Installation
------------
Only vanilla kernels from kernel.org and RHEL/CentOS 5.2 kernels are
supported, but SCST should work on other (vendors') kernels, if you
manage to successfully compile on them. The main problem with vendors'
kernels is that they often contain patches, which will appear only in
the next version of the vanilla kernel, therefore it's quite hard to
track such changes. Thus, if during compilation for some vendor kernel
your compiler complains about redefinition of some symbol, you should
either switch to vanilla kernel, or add or change as necessary the
corresponding to that symbol "#if LINUX_VERSION_CODE" statement.
manage to successfully compile it on them. The main problem with
vendors' kernels is that they often contain patches, which will appear
only in the next version of the vanilla kernel, therefore it's quite
hard to track such changes. Thus, if during compilation for some vendor
kernel your compiler complains about redefinition of some symbol, you
should either switch to vanilla kernel, or add or change as necessary
the corresponding to that symbol "#if LINUX_VERSION_CODE" statement.
At first, make sure that the link "/lib/modules/`you_kernel_version`/build"
points to the source code for your currently running kernel.
Befer installation make sure that the link
"/lib/modules/`you_kernel_version`/build" points to the source code for
your currently running kernel.
Then you should replace (or link) by the initiator driver from this
package "qla2xxx" subdirectory in kernel_source/drivers/scsi/ of the
@@ -80,6 +81,30 @@ You can find some installation and configuration HOWTOs in
http://scst.sourceforge.net/qla2x00t-howto.html and
https://forums.openfiler.com/viewtopic.php?id=3422.
Explicit conformation
---------------------
This option should (actually, almost always must) be enabled by echoing
"1" in /sys/class/scsi_host/hostX/explicit_conform_enabled, if a target
card exports at least one stateful SCSI device, like tape, and class 2
isn't used, otherwise link-level errors could lead to loss of the
target/initiator state synchronization. Also check if initiator supports
this feature, it is reported in the kernel logs ("confirmed completion
supported" or not). No major performance degradation was noticed, if it
is enabled. Supported only for 23xx+. Disabled by default.
Class 2
-------
Class 2 is the close equivalent of the TCP in the IP world. If you
enable it, all the Fibre Channel packets will be acknowledged. By
default, class 3 is used, which is UDP-like. Enable it by echoing
"1" in /sys/class/scsi_host/hostX/class2_enabled. This option needs
a special firmware with class 2 support. Disabled by default.
Compilation options
-------------------
@@ -98,11 +123,18 @@ in/out in Makefile:
callbacks in internal SCST threads context instead of SIRQ context,
where those commands were received. Useful for debugging and lead to
some performance loss.
- CONFIG_QLA_TGT_DEBUG_SRR - turns on restransmitting packets (SRR)
debugging. In this mode some CTIOs will be "broken" to force the
initiator to issue a retransmit request.
Credits
-------
Thanks to
Thanks to:
* QLogic support for their invaluable help.
* Nathaniel Clark <nate@misrule.us> for porting to new 2.6 kernel
initiator driver.
+5 -3
View File
@@ -1,8 +1,10 @@
Known issues and unimplemented features
---------------------------------------
- NPIV support
- If a Linux initiator asks for devices using INQUIRY command too soon
before the controller on the target is fully initialized in the
before the controller on the 23xx target is fully initialized in the
target mode, the initiator could receive garbage devices and the
messages "scsi: unknown device type 31" will be printed in the kernel
log on the initiator. After rescan on the initiator (eg by
@@ -15,9 +17,9 @@ Known issues and unimplemented features
- Minor "ToDo"'s spread in the code.
- On 2300 if on a tape with block size 0 we write block with size X
- On 23xx if on a tape with block size 0 we write block with size X
and then read it with bs <X the tape skips all blocks with size X
until the next correct block or filemark found, instead of returning
ILI with negative counter. Looks like the initiator retries the
command quetly. 2200 works correctly. With the latest firmware that
command quetly. 22xx works correctly. With the latest firmware that
might be fixed.
+29
View File
@@ -0,0 +1,29 @@
Throughout the last three years ID7 and we 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
+184 -74
View File
@@ -1,17 +1,18 @@
/*
* qla2x00t.h
*
*
* Copyright (C) 2004 - 2009 Vladislav Bolkhovitin <vst@vlnb.net>
* Copyright (C) 2004 - 2005 Leonid Stoljar
* Copyright (C) 2006 Nathaniel Clark <nate@misrule.us>
* Copyright (C) 2006 - 2009 ID7 Ltd.
*
* QLogic 2x00 SCSI target driver.
*
* QLogic 22xx/23xx/24xx/25xx FC target driver.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, version 2
* of the License.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -21,24 +22,26 @@
#ifndef __QLA2X00T_H
#define __QLA2X00T_H
/* Sneaky hack to skip redefinitions from qla_dbg.h */
#define __QLA_DBG_H
#include <qla_def.h>
#include "qla2x_tgt_def.h"
#include <qla2x_tgt.h>
#include <qla2x_tgt_def.h>
#include <scst_debug.h>
/* 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(1, 0, 2, 0)
#define Q2T_VERSION_STRING "1.0.2"
#define Q2T_VERSION(a,b,c,d) (((a) << 030) + ((b) << 020) + (c) << 010 + (d))
#define Q2T_VERSION_CODE Q2T_VERSION(1,0,2,0)
#define Q2T_VERSION_STRING "1.0.2priv"
#define Q2T_PROC_VERSION_NAME "version"
#define Q2T_MAX_CDB_LEN 16
#define Q2T_TIMEOUT 10 /* in seconds */
#define Q2T_MAX_HW_PENDING_TIME 60 /* in seconds */
/* Immediate notify status constants */
#define IMM_NTFY_LIP_RESET 0x000E
#define IMM_NTFY_LIP_LINK_REINIT 0x000F
#define IMM_NTFY_IOCB_OVERFLOW 0x0016
#define IMM_NTFY_ABORT_TASK 0x0020
#define IMM_NTFY_PORT_LOGOUT 0x0029
@@ -47,13 +50,21 @@
#define IMM_NTFY_GLBL_LOGO 0x002E
#define IMM_NTFY_RESOURCE 0x0034
#define IMM_NTFY_MSG_RX 0x0036
#define IMM_NTFY_SRR 0x0045
#define IMM_NTFY_ELS 0x0046
/* Immediate notify task flags */
#define IMM_NTFY_CLEAR_ACA 0x4000
#define IMM_NTFY_TARGET_RESET 0x2000
#define IMM_NTFY_LUN_RESET 0x1000
#define IMM_NTFY_CLEAR_TS 0x0400
#define IMM_NTFY_ABORT_TS 0x0200
#define IMM_NTFY_TASK_MGMT_SHIFT 9
#define Q2T_CLEAR_ACA 0x40
#define Q2T_TARGET_RESET 0x20
#define Q2T_LUN_RESET 0x10
#define Q2T_CLEAR_TS 0x04
#define Q2T_ABORT_TS 0x02
#define Q2T_ABORT_ALL_SESS 0xFFFF
#define Q2T_ABORT_ALL 0xFFFE
#define Q2T_NEXUS_LOSS_SESS 0xFFFD
#define Q2T_NEXUS_LOSS 0xFFFC
/* Notify Acknowledge flags */
#define NOTIFY_ACK_RES_COUNT BIT_8
@@ -62,26 +73,36 @@
/* Command's states */
#define Q2T_STATE_NEW 0 /* New command and SCST processing it */
#define Q2T_STATE_PROCESSED 1 /* SCST done processing */
#define Q2T_STATE_NEED_DATA 2 /* SCST needs data to continue */
#define Q2T_STATE_DATA_IN 3 /* Data arrived and SCST processing */
/* them */
#define Q2T_STATE_NEED_DATA 1 /* SCST needs data to continue */
#define Q2T_STATE_DATA_IN 2 /* Data arrived and SCST processing it */
#define Q2T_STATE_PROCESSED 3 /* SCST done processing */
#define Q2T_STATE_ABORTED 4 /* Command aborted */
/* Misc */
/* Special handles */
#define Q2T_NULL_HANDLE 0
#define Q2T_SKIP_HANDLE (0xFFFFFFFE & ~CTIO_COMPLETION_HANDLE_MARK)
#define Q2T_BUSY_HANDLE (0xFFFFFFFF & ~CTIO_COMPLETION_HANDLE_MARK)
#define Q2T_SKIP_HANDLE (0xFFFFFFFF & ~CTIO_COMPLETION_HANDLE_MARK)
/* ATIO task_codes fields */
/* ATIO task_codes field */
#define ATIO_SIMPLE_QUEUE 0
#define ATIO_HEAD_OF_QUEUE 1
#define ATIO_ORDERED_QUEUE 2
#define ATIO_ACA_QUEUE 4
#define ATIO_UNTAGGED 5
/* TM failed response code, see FCP */
#define FC_TM_FAILED 0x5
/* TM failed response codes, see FCP (9.4.11 FCP_RSP_INFO) */
#define FC_TM_SUCCESS 0
#define FC_TM_BAD_FCP_DATA 1
#define FC_TM_BAD_CMD 2
#define FC_TM_FCP_DATA_MISMATCH 3
#define FC_TM_REJECT 4
#define FC_TM_FAILED 5
/*
* Error code of q2t_pre_xmit_response() meaning that cmd's exchange was
* terminated, so no more actions is needed and success should be returned
* to SCST. Must be different from any SCST_TGT_RES_* codes.
*/
#define Q2T_PRE_XMIT_RESP_CMD_ABORTED 0x1717
#if (BITS_PER_LONG > 32) || defined(CONFIG_HIGHMEM64G)
#define pci_dma_lo32(a) (a & 0xffffffff)
@@ -91,74 +112,163 @@
#define pci_dma_hi32(a) 0
#endif
struct q2t_tgt
{
struct scst_tgt *scst_tgt;
scsi_qla_host_t *ha;
/*
* To sync between IRQ handlers and q2t_target_release(). Needed,
* because req_pkt() can drop/reaquire HW lock inside. Protected by
* HW lock.
*/
int irq_cmd_count;
int datasegs_per_cmd, datasegs_per_cont;
/* Target's flags, serialized by ha->hardware_lock */
unsigned int tgt_enable_64bit_addr:1; /* 64-bits PCI addressing enabled */
unsigned int link_reinit_iocb_pending:1;
unsigned int tm_to_unknown:1; /* TM to unknown session was sent */
/*
* Protected by tgt_mutex AND hardware_lock for writing and tgt_mutex
* OR hardware_lock for reading.
*/
unsigned long tgt_shutdown; /* the driver is being released */
/* Count of sessions refering q2t_tgt. Protected by hardware_lock. */
int sess_count;
/* Protected by hardware_lock. Addition also protected by tgt_mutex. */
struct list_head sess_list;
/* Protected by hardware_lock */
struct list_head del_sess_list;
struct timer_list sess_del_timer;
spinlock_t sess_work_lock;
struct list_head sess_works_list;
struct work_struct sess_work;
notify24xx_entry_t link_reinit_iocb;
wait_queue_head_t waitQ;
int notify_ack_expected;
int abts_resp_expected;
int modify_lun_expected;
int ctio_srr_id;
int imm_srr_id;
spinlock_t srr_lock;
struct list_head srr_ctio_list;
struct list_head srr_imm_list;
struct work_struct srr_work;
};
/*
* Equivilant to IT Nexus (Initiator-Target)
*/
struct q2t_sess {
struct list_head list;
struct q2t_sess
{
uint16_t loop_id;
port_id_t s_id;
unsigned int conf_compl_supported:1;
unsigned int deleted:1;
unsigned int local:1;
struct scst_session *scst_sess;
struct q2t_tgt *tgt;
int loop_id;
int sess_ref; /* protected by hardware_lock */
struct list_head sess_list_entry;
unsigned long expires;
struct list_head del_list_entry;
uint8_t port_name[WWN_SIZE];
};
struct q2t_cmd {
struct q2t_cmd
{
struct q2t_sess *sess;
struct scst_cmd *scst_cmd;
int state;
struct atio_entry atio;
dma_addr_t dma_handle;
uint32_t iocb_cnt;
};
struct scst_cmd *scst_cmd;
struct q2t_tgt {
struct scst_tgt *scst_tgt;
scsi_qla_host_t *ha;
int datasegs_per_cmd, datasegs_per_cont;
/* Target's flags, serialized by ha->hardware_lock */
unsigned int tgt_shutdown:1; /* The driver is being released */
unsigned int tgt_enable_64bit_addr:1; /* 64bit PCI addressing enabled */
wait_queue_head_t waitQ;
int notify_ack_expected;
int modify_lun_expected;
/* Count of sessions refering q2t_tgt, protected by hardware_lock */
int sess_count;
struct list_head sess_list;
};
unsigned int conf_compl_supported:1;/* to save extra sess dereferences */
unsigned int free_sg:1;
unsigned int aborted:1; /* Needed in case of SRR */
struct q2t_mgmt_cmd {
struct q2t_sess *sess;
struct notify_entry notify_entry;
};
struct q2t_prm {
struct q2t_tgt *tgt;
uint16_t req_cnt;
uint16_t seg_cnt;
int sg_cnt;
struct scatterlist *sg;
int bufflen;
struct scatterlist *sg; /* cmd data buffer SG vector */
int sg_cnt; /* SG segments count */
int bufflen; /* cmd buffer length */
int offset;
scst_data_direction data_direction;
uint32_t tag;
dma_addr_t dma_handle;
uint16_t loop_id; /* to save extra sess dereferences */
struct q2t_tgt *tgt; /* to save extra sess dereferences */
union {
atio7_entry_t atio7;
atio_entry_t atio2x;
} __attribute__((packed)) atio;
};
struct q2t_sess_work_param {
struct list_head sess_works_list_entry;
struct q2t_cmd *cmd;
};
struct q2t_mgmt_cmd
{
struct q2t_sess *sess;
unsigned int flags;
#define Q24_MGMT_SEND_NACK 1
union {
atio7_entry_t atio7;
notify_entry_t notify_entry;
notify24xx_entry_t notify_entry24;
abts24_recv_entry_t abts;
} __attribute__((packed)) orig_iocb;
};
struct q2t_prm
{
struct q2t_cmd *cmd;
struct q2t_tgt *tgt;
void *pkt;
struct scatterlist *sg; /* cmd data buffer SG vector */
int seg_cnt;
int req_cnt;
uint16_t rq_result;
uint16_t scsi_status;
unsigned char *sense_buffer;
unsigned int sense_buffer_len;
int sense_buffer_len;
int residual;
struct q2t_cmd *cmd;
struct ctio_common_entry *pkt;
int add_status_pkt;
};
/* ha->hardware_lock supposed to be held on entry (to protect tgt->sess_list) */
static inline struct q2t_sess *q2t_find_sess_by_lid(struct q2t_tgt *tgt,
uint16_t lid)
struct srr_imm
{
struct q2t_sess *sess;
sBUG_ON(tgt == NULL);
list_for_each_entry(sess, &tgt->sess_list, list) {
if (lid == sess->loop_id)
return sess;
}
struct list_head srr_list_entry;
int srr_id;
union {
notify_entry_t notify_entry;
notify24xx_entry_t notify_entry24;
} __attribute__((packed)) imm;
};
return NULL;
}
struct srr_ctio
{
struct list_head srr_list_entry;
int srr_id;
struct q2t_cmd *cmd;
};
#define Q2T_XMIT_DATA 1
#define Q2T_XMIT_STATUS 2
#define Q2T_XMIT_ALL (Q2T_XMIT_STATUS|Q2T_XMIT_DATA)
#endif /* __QLA2X00T_H */
+60 -46
View File
@@ -1,16 +1,18 @@
/*
* qla2x_tgt.h
*
* Copyright (C) 2004 - 2009 Vladislav Bolkhovitin <vst@vlnb.net>
*
* Copyright (C) 2004 - 2008 Vladislav Bolkhovitin <vst@vlnb.net>
* Copyright (C) 2004 - 2005 Leonid Stoljar
* Copyright (C) 2006 Nathaniel Clark <nate@misrule.us>
* Copyright (C) 2007 - 2008 CMS Distribution Limited
*
* Additional file for the target driver support.
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -20,19 +22,42 @@
* This should be included only from within qla2xxx module.
*/
#ifndef __QLA2X_TGT_H
#define __QLA2X_TGT_H
#ifndef CONFIG_SCSI_QLA2XXX_TARGET
#error __FILE__ " included without CONFIG_SCSI_QLA2XXX_TARGET"
#endif
extern request_t *qla2x00_req_pkt(scsi_qla_host_t *ha);
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
#include "qla2x_tgt_def.h"
extern struct qla2x_tgt_initiator qla_target;
extern struct qla_tgt_initiator qla_target;
/* declare here because it doesn't appear in any .h file just in qla_iocb.c */
extern request_t *qla2x00_req_pkt(scsi_qla_host_t *ha);
/* Called under HW lock */
static inline void qla_set_tgt_mode(scsi_qla_host_t *ha)
{
#ifdef CONFIG_SCSI_QLA2XXX_TARGET_DISABLE_INI_MODE
ha->host->active_mode = MODE_TARGET;
#else
ha->host->active_mode |= MODE_TARGET;
#endif
}
/* Called under HW lock */
static inline void qla_clear_tgt_mode(scsi_qla_host_t *ha)
{
#ifdef CONFIG_SCSI_QLA2XXX_TARGET_DISABLE_INI_MODE
ha->host->active_mode = MODE_INITIATOR;
#else
ha->host->active_mode &= ~MODE_TARGET;
#endif
}
static inline bool qla_tgt_mode_enabled(scsi_qla_host_t *ha)
{
return ha->host->active_mode & MODE_TARGET;
}
/********************************************************************\
* ISP Queue types left out of new QLogic driver (from old version)
@@ -41,80 +66,69 @@ extern request_t *qla2x00_req_pkt(scsi_qla_host_t *ha);
/*
* qla2x00_do_en_dis_lun
* Issue enable or disable LUN entry IOCB.
* Also set enable_target_mode in ha
*
* Input:
* ha = adapter block pointer.
*
* Caller MUST have hardware lock held. This function might release it,
* then reaquire.
*/
/* Caller MUST have hardware lock held */
static inline void
__qla2x00_en_dis_lun(scsi_qla_host_t *ha, int enable)
__qla2x00_send_enable_lun(scsi_qla_host_t *ha, int enable)
{
struct elun_entry *pkt;
elun_entry_t *pkt;
if ((pkt = (struct elun_entry *)qla2x00_req_pkt(ha)) != NULL) {
BUG_ON(IS_FWI2_CAPABLE(ha));
if ((pkt = (elun_entry_t *)qla2x00_req_pkt(ha)) != NULL) {
pkt->entry_type = ENABLE_LUN_TYPE;
if (enable) {
pkt->command_count = QLA2X00_COMMAND_COUNT_INIT;
pkt->immed_notify_count = QLA2X00_IMMED_NOTIFY_COUNT_INIT;
pkt->timeout = 0xffff;
}
else
{
else {
pkt->command_count = 0;
pkt->immed_notify_count = 0;
pkt->timeout = 0;
}
DEBUG2(printk(KERN_DEBUG
DEBUG2(printk(KERN_DEBUG
"scsi%lu:ENABLE_LUN IOCB imm %u cmd %u timeout %u\n",
ha->host_no, pkt->immed_notify_count,
pkt->command_count, pkt->timeout));
/* Issue command to ISP */
qla2x00_isp_cmd(ha);
ha->flags.enable_target_mode = enable;
}
} else
qla_clear_tgt_mode(ha);
#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
if (!pkt)
printk("qla2100_en_dis_lun: **** FAILED ****\n");
printk("%s: **** FAILED ****\n", __func__);
#endif
}
/* get-lock version */
static inline void
qla2x00_en_dis_lun(scsi_qla_host_t *ha, int enable)
{
unsigned long flags = 0;
spin_lock_irqsave(&ha->hardware_lock, flags);
__qla2x00_en_dis_lun(ha, enable);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
return;
}
/*
* qla2x00_enable_lun
* qla2x00_send_enable_lun
* Issue enable LUN entry IOCB.
*
* Input:
* ha = adapter block pointer.
* enable = enable/disable flag.
*/
static inline void
qla2x00_enable_lun(scsi_qla_host_t *ha)
qla2x00_send_enable_lun(scsi_qla_host_t *ha, bool enable)
{
qla2x00_en_dis_lun(ha, 1);
if (!IS_FWI2_CAPABLE(ha)) {
unsigned long flags;
spin_lock_irqsave(&ha->hardware_lock, flags);
__qla2x00_send_enable_lun(ha, enable);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
}
}
/*
* qla2x00_disable_lun
* Issue enable LUN entry IOCB (command_count = 0).
*
* Input:
* ha = adapter block pointer.
*/
static inline void
qla2x00_disable_lun(scsi_qla_host_t *ha)
{
qla2x00_en_dis_lun(ha, 0);
}
#endif /* CONFIG_SCSI_QLA2XXX_TARGET */
#endif /* __QLA2X_TGT_H */
+560 -158
View File
@@ -1,17 +1,18 @@
/*
* qla2x_tgt_def.h
*
* Copyright (C) 2004 - 2009 Vladislav Bolkhovitin <vst@vlnb.net>
*
* Copyright (C) 2004 - 2008 Vladislav Bolkhovitin <vst@vlnb.net>
* Copyright (C) 2004 - 2005 Leonid Stoljar
* Copyright (C) 2006 Nathaniel Clark <nate@misrule.us>
* Copyright (C) 2007 - 2008 CMS Distribution Limited
*
* Additional file for the target driver support. Intended to define
* for 2200 and 2300 thier own exported symbols with unique names.
*
* Additional file for the target driver support.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -39,56 +40,66 @@
#define LEAVE(a)
#endif
#define QLA2X_TARGET_MAGIC 153
#define QLA2X_INITIATOR_MAGIC 54208
#define QLA2X_TARGET_MAGIC 263
#define QLA2X_INITIATOR_MAGIC 57216
#define QLA2X00_COMMAND_COUNT_INIT 250
#define QLA2X00_IMMED_NOTIFY_COUNT_INIT 250
#define QLA_EXTENDED_LUN 1
/*
/*
* Used to mark which completion handles (for RIO Status's) are for CTIO's
* vs. regular (non-target) info.
* vs. regular (non-target) info. This is checked for in
* qla2x00_process_response_queue() to see if a handle coming back in a
* multi-complete should come to the tgt driver or be handled there by qla2xxx
*/
#define CTIO_COMPLETION_HANDLE_MARK BIT_15
#define CTIO_COMPLETION_HANDLE_MARK BIT_29
#if (CTIO_COMPLETION_HANDLE_MARK <= MAX_OUTSTANDING_COMMANDS)
#error "Hackish CTIO_COMPLETION_HANDLE_MARK no longer larger than \
MAX_OUTSTANDING_COMMANDS"
#error "Hackish CTIO_COMPLETION_HANDLE_MARK no longer larger than MAX_OUTSTANDING_COMMANDS"
#endif
#define HANDLE_IS_CTIO_COMP(h) (h & CTIO_COMPLETION_HANDLE_MARK)
/* Used to mark CTIO as intermediate */
#define CTIO_INTERMEDIATE_HANDLE_MARK BIT_30
#ifndef OF_SS_MODE_0
/*
* ISP target entries - Flags bit definitions.
*/
#define OF_SS_MODE_0 0
#define OF_SS_MODE_1 1
#define OF_SS_MODE_2 2
#define OF_SS_MODE_3 3
#define OF_SS_MODE_0 0
#define OF_SS_MODE_1 1
#define OF_SS_MODE_2 2
#define OF_SS_MODE_3 3
#define OF_RESET BIT_5 /* Reset LIP flag */
#define OF_DATA_IN BIT_6 /* Data in to initiator */
/* (data from target to initiator) */
#define OF_DATA_OUT BIT_7 /* Data out from initiator */
/* (data from initiator to target) */
#define OF_NO_DATA (BIT_7 | BIT_6)
#define OF_INC_RC BIT_8 /* Increment command resource count */
#define OF_FAST_POST BIT_9 /* Enable mailbox fast posting. */
#define OF_TERM_EXCH BIT_14 /* Terminate exchange */
#define OF_SSTS BIT_15 /* Send SCSI status */
#define OF_EXPL_CONF BIT_5 /* Explicit Confirmation Requested */
#define OF_DATA_IN BIT_6 /* Data in to initiator */
/* (data from target to initiator) */
#define OF_DATA_OUT BIT_7 /* Data out from initiator */
/* (data from initiator to target) */
#define OF_NO_DATA (BIT_7 | BIT_6)
#define OF_INC_RC BIT_8 /* Increment command resource count */
#define OF_FAST_POST BIT_9 /* Enable mailbox fast posting. */
#define OF_CONF_REQ BIT_13 /* Confirmation Requested */
#define OF_TERM_EXCH BIT_14 /* Terminate exchange */
#define OF_SSTS BIT_15 /* Send SCSI status */
#endif
#ifndef DATASEGS_PER_COMMAND32
#define DATASEGS_PER_COMMAND32 3
#define DATASEGS_PER_CONT32 7
#define DATASEGS_PER_COMMAND32 3
#define DATASEGS_PER_CONT32 7
#define QLA_MAX_SG32(ql) \
(DATASEGS_PER_COMMAND32 + (((ql) > 0) ? DATASEGS_PER_CONT32*((ql) - 1) : 0))
(((ql) > 0) ? (DATASEGS_PER_COMMAND32 + DATASEGS_PER_CONT32*((ql) - 1)) : 0)
#define DATASEGS_PER_COMMAND64 2
#define DATASEGS_PER_CONT64 5
#define DATASEGS_PER_COMMAND64 2
#define DATASEGS_PER_CONT64 5
#define QLA_MAX_SG64(ql) \
(DATASEGS_PER_COMMAND64 + (((ql) > 0) ? DATASEGS_PER_CONT64*((ql) - 1) : 0))
(((ql) > 0) ? (DATASEGS_PER_COMMAND64 + DATASEGS_PER_CONT64*((ql) - 1)) : 0)
#endif
#ifndef DATASEGS_PER_COMMAND_24XX
#define DATASEGS_PER_COMMAND_24XX 1
#define DATASEGS_PER_CONT_24XX 5
#define QLA_MAX_SG_24XX(ql) \
(min(1270, ((ql) > 0) ? (DATASEGS_PER_COMMAND_24XX + DATASEGS_PER_CONT_24XX*((ql) - 1)) : 0))
#endif
/********************************************************************\
@@ -100,7 +111,8 @@
/*
* ISP queue - enable LUN entry structure definition.
*/
struct elun_entry {
typedef struct
{
uint8_t entry_type; /* Entry type. */
uint8_t entry_count; /* Entry count. */
uint8_t sys_define; /* System defined. */
@@ -113,29 +125,29 @@ struct elun_entry {
uint8_t status;
uint8_t reserved_4;
uint8_t command_count; /* Number of ATIOs allocated. */
uint8_t immed_notify_count; /* Number of Immediate Notify entries */
/* allocated. */
uint8_t immed_notify_count; /* Number of Immediate Notify entries allocated. */
uint16_t reserved_5;
uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */
uint16_t reserved_6[20];
};
#define ENABLE_LUN_SUCCESS 0x01
#define ENABLE_LUN_RC_NONZERO 0x04
#define ENABLE_LUN_INVALID_REQUEST 0x06
#define ENABLE_LUN_ALREADY_ENABLED 0x3E
} __attribute__((packed)) elun_entry_t;
#define ENABLE_LUN_SUCCESS 0x01
#define ENABLE_LUN_RC_NONZERO 0x04
#define ENABLE_LUN_INVALID_REQUEST 0x06
#define ENABLE_LUN_ALREADY_ENABLED 0x3E
#endif
#ifndef MODIFY_LUN_TYPE
#define MODIFY_LUN_TYPE 0x0C
#define MODIFY_LUN_TYPE 0x0C /* Modify LUN entry. */
/*
* ISP queue - modify LUN entry structure definition.
*/
struct modify_lun_entry {
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 sys_define_2; /* System defined. */
typedef struct
{
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 sys_define_2; /* System defined. */
uint8_t reserved_8;
uint8_t reserved_1;
uint8_t operators;
@@ -143,87 +155,111 @@ struct modify_lun_entry {
uint32_t reserved_3;
uint8_t status;
uint8_t reserved_4;
uint8_t command_count; /* Number of ATIOs allocated. */
uint8_t immed_notify_count; /* Number of Immediate Notify */
uint8_t command_count; /* Number of ATIOs allocated. */
uint8_t immed_notify_count; /* Number of Immediate Notify */
/* entries allocated. */
uint16_t reserved_5;
uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */
uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */
uint16_t reserved_7[20];
};
} __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
#define MODIFY_LUN_IMM_ADD BIT_2
#define MODIFY_LUN_IMM_SUB BIT_3
#define MODIFY_LUN_CMD_ADD BIT_0
#define MODIFY_LUN_CMD_SUB BIT_1
#define MODIFY_LUN_IMM_ADD BIT_2
#define MODIFY_LUN_IMM_SUB BIT_3
#endif
#define GET_TARGET_ID(ha, iocb) ((HAS_EXTENDED_IDS(ha)) \
? le16_to_cpu((iocb)->target.extended) \
: (uint16_t)(iocb)->target.id.standard)
#ifndef IMMED_NOTIFY_TYPE
#define IMMED_NOTIFY_TYPE 0x0D /* Immediate notify entry. */
#define IMMED_NOTIFY_TYPE 0x0D /* Immediate notify entry. */
/*
* ISP queue - immediate notify entry structure definition.
*/
struct notify_entry {
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 sys_define_2; /* System defined. */
typedef struct
{
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 sys_define_2; /* System defined. */
target_id_t target;
uint16_t lun;
uint32_t reserved_2;
uint8_t target_id;
uint8_t reserved_1;
uint16_t status_modifier;
uint16_t status;
uint16_t task_flags;
uint16_t seq_id;
uint16_t reserved_5[11];
uint16_t scsi_status;
uint8_t sense_data[16];
uint16_t srr_rx_id;
uint32_t srr_rel_offs;
uint16_t srr_ui;
#define SRR_IU_DATA_IN 0x1
#define SRR_IU_DATA_OUT 0x5
#define SRR_IU_STATUS 0x7
uint16_t srr_ox_id;
uint8_t reserved_2[30];
uint16_t ox_id;
};
} __attribute__((packed)) notify_entry_t;
#endif
#ifndef NOTIFY_ACK_TYPE
#define NOTIFY_ACK_TYPE 0x0E /* Notify acknowledge entry. */
#define NOTIFY_ACK_TYPE 0x0E /* Notify acknowledge entry. */
/*
* ISP queue - notify acknowledge entry structure definition.
*/
struct nack_entry {
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 sys_define_2; /* System defined. */
typedef struct
{
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 sys_define_2; /* System defined. */
target_id_t target;
uint8_t reserved_1;
uint8_t target_id;
uint8_t reserved_1;
uint16_t flags;
uint16_t resp_code;
uint16_t status;
uint16_t task_flags;
uint16_t seq_id;
uint16_t reserved_3[20];
uint16_t srr_rx_id;
uint32_t srr_rel_offs;
uint16_t srr_ui;
uint16_t srr_flags;
uint16_t srr_reject_code;
uint8_t srr_reject_vendor_uniq;
uint8_t srr_reject_code_expl;
uint8_t reserved_2[26];
uint16_t ox_id;
};
#define NOTIFY_ACK_SUCCESS 0x01
} __attribute__((packed)) nack_entry_t;
#define NOTIFY_ACK_SRR_FLAGS_ACCEPT 0
#define NOTIFY_ACK_SRR_FLAGS_REJECT 1
#define NOTIFY_ACK_SRR_REJECT_REASON_UNABLE_TO_PERFORM 0x9
#define NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_NO_EXPL 0
#define NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_UNABLE_TO_SUPPLY_DATA 0x2a
#define NOTIFY_ACK_SUCCESS 0x01
#endif
#ifndef ACCEPT_TGT_IO_TYPE
#define ACCEPT_TGT_IO_TYPE 0x16 /* Accept target I/O entry. */
#define ACCEPT_TGT_IO_TYPE 0x16 /* Accept target I/O entry. */
/*
* ISP queue - Accept Target I/O (ATIO) entry structure definition.
*/
struct atio_entry {
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 sys_define_2; /* System defined. */
typedef struct
{
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 sys_define_2; /* System defined. */
target_id_t target;
uint16_t exchange_id;
uint16_t rx_id;
uint16_t flags;
uint16_t status;
uint8_t command_ref;
@@ -234,82 +270,88 @@ struct atio_entry {
uint32_t data_length;
uint16_t lun;
uint8_t initiator_port_name[WWN_SIZE]; /* on qla23xx */
uint8_t reserved2[12];
uint16_t reserved_32[6];
uint16_t ox_id;
};
} __attribute__((packed)) atio_entry_t;
#endif
#ifndef CONTINUE_TGT_IO_TYPE
#define CONTINUE_TGT_IO_TYPE 0x17
#define CONTINUE_TGT_IO_TYPE 0x17
/*
* ISP queue - Continue Target I/O (CTIO) entry for status mode 0
* structure definition.
*/
struct ctio_common_entry {
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 defined handle */
typedef struct
{
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 defined handle */
target_id_t target;
uint16_t exchange_id;
uint16_t rx_id;
uint16_t flags;
uint16_t status;
uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */
uint16_t dseg_count; /* Data segment count. */
uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */
uint16_t dseg_count; /* Data segment count. */
uint32_t relative_offset;
uint32_t residual;
uint16_t reserved_1[3];
uint16_t scsi_status;
uint32_t transfer_length;
uint32_t dseg_0_address[0];
};
#define ATIO_PATH_INVALID 0x07
#define ATIO_CANT_PROV_CAP 0x16
#define ATIO_CDB_VALID 0x3D
} __attribute__((packed)) ctio_common_entry_t;
#define ATIO_PATH_INVALID 0x07
#define ATIO_CANT_PROV_CAP 0x16
#define ATIO_CDB_VALID 0x3D
#define ATIO_EXEC_READ BIT_1
#define ATIO_EXEC_WRITE BIT_0
#define ATIO_EXEC_READ BIT_1
#define ATIO_EXEC_WRITE BIT_0
#endif
#ifndef CTIO_A64_TYPE
#define CTIO_A64_TYPE 0x1F
struct ctio_entry {
struct ctio_common_entry common;
uint32_t dseg_0_address; /* Data segment 0 address. */
uint32_t dseg_0_length; /* Data segment 0 length. */
uint32_t dseg_1_address; /* Data segment 1 address. */
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. */
};
#define CTIO_SUCCESS 0x01
#define CTIO_ABORTED 0x02
#define CTIO_INVALID_RX_ID 0x08
#define CTIO_TIMEOUT 0x0B
#define CTIO_LIP_RESET 0x0E
#define CTIO_TARGET_RESET 0x17
#define CTIO_PORT_UNAVAILABLE 0x28
#define CTIO_PORT_LOGGED_OUT 0x29
#define CTIO_A64_TYPE 0x1F
typedef struct
{
ctio_common_entry_t common;
uint32_t dseg_0_address; /* Data segment 0 address. */
uint32_t dseg_0_length; /* Data segment 0 length. */
uint32_t dseg_1_address; /* Data segment 1 address. */
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. */
} __attribute__((packed)) ctio_entry_t;
#define CTIO_SUCCESS 0x01
#define CTIO_ABORTED 0x02
#define CTIO_INVALID_RX_ID 0x08
#define CTIO_TIMEOUT 0x0B
#define CTIO_LIP_RESET 0x0E
#define CTIO_TARGET_RESET 0x17
#define CTIO_PORT_UNAVAILABLE 0x28
#define CTIO_PORT_LOGGED_OUT 0x29
#define CTIO_PORT_CONF_CHANGED 0x2A
#define CTIO_SRR_RECEIVED 0x45
#endif
#ifndef CTIO_RET_TYPE
#define CTIO_RET_TYPE 0x17 /* CTIO return entry */
#define CTIO_RET_TYPE 0x17 /* CTIO return entry */
/*
* ISP queue - CTIO returned entry structure definition.
*/
struct ctio_ret_entry {
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 defined handle. */
typedef struct
{
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 defined handle. */
target_id_t target;
uint16_t exchange_id;
uint16_t rx_id;
uint16_t flags;
uint16_t status;
uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */
uint16_t dseg_count; /* Data segment count. */
uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */
uint16_t dseg_count; /* Data segment count. */
uint32_t relative_offset;
uint32_t residual;
uint16_t reserved_1[2];
@@ -317,46 +359,406 @@ struct ctio_ret_entry {
uint16_t scsi_status;
uint16_t response_length;
uint8_t sense_data[26];
};
} __attribute__((packed)) ctio_ret_entry_t;
#endif
#define ATIO_TYPE7 0x06 /* Accept target I/O entry for 24xx */
typedef struct
{
uint8_t r_ctl;
uint8_t d_id[3];
uint8_t cs_ctl;
uint8_t s_id[3];
uint8_t type;
uint8_t f_ctl[3];
uint8_t seq_id;
uint8_t df_ctl;
uint16_t seq_cnt;
uint16_t ox_id;
uint16_t rx_id;
uint32_t parameter;
} __attribute__((packed)) fcp_hdr_t;
typedef struct
{
uint8_t d_id[3];
uint8_t r_ctl;
uint8_t s_id[3];
uint8_t cs_ctl;
uint8_t f_ctl[3];
uint8_t type;
uint16_t seq_cnt;
uint8_t df_ctl;
uint8_t seq_id;
uint16_t rx_id;
uint16_t ox_id;
uint32_t parameter;
} __attribute__((packed)) fcp_hdr_le_t;
#define F_CTL_EXCH_CONTEXT_RESP BIT_23
#define F_CTL_SEQ_CONTEXT_RESIP BIT_22
#define F_CTL_LAST_SEQ BIT_20
#define F_CTL_END_SEQ BIT_19
#define F_CTL_SEQ_INITIATIVE BIT_16
#define R_CTL_BASIC_LINK_SERV 0x80
#define R_CTL_B_ACC 0x4
#define R_CTL_B_RJT 0x5
typedef struct
{
uint64_t lun;
uint8_t cmnd_ref;
uint8_t task_attr:3;
uint8_t reserved:5;
uint8_t task_mgmt_flags;
#define FCP_CMND_TASK_MGMT_CLEAR_ACA 6
#define FCP_CMND_TASK_MGMT_TARGET_RESET 5
#define FCP_CMND_TASK_MGMT_LU_RESET 4
#define FCP_CMND_TASK_MGMT_CLEAR_TASK_SET 2
#define FCP_CMND_TASK_MGMT_ABORT_TASK_SET 1
uint8_t wrdata:1;
uint8_t rddata:1;
uint8_t add_cdb_len:6;
uint8_t cdb[16];
/* Valid only if add_cdb_len=0, otherwise this is additional CDB data */
uint32_t data_length;
} __attribute__((packed)) fcp_cmnd_t;
/*
* ISP queue - Accept Target I/O (ATIO) type 7 entry for 24xx structure
* definition.
*/
typedef struct
{
uint8_t entry_type; /* Entry type. */
uint8_t entry_count; /* Entry count. */
uint8_t fcp_cmnd_len_low;
uint8_t fcp_cmnd_len_high:4;
uint8_t attr:4;
uint32_t exchange_addr;
#define ATIO_EXCHANGE_ADDRESS_UNKNOWN 0xFFFFFFFF
fcp_hdr_t fcp_hdr;
fcp_cmnd_t fcp_cmnd;
} __attribute__((packed)) atio7_entry_t;
#define CTIO_TYPE7 0x12 /* Continue target I/O entry (for 24xx) */
/*
* ISP queue - Continue Target I/O (ATIO) type 7 entry (for 24xx) structure
* definition.
*/
typedef struct
{
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 defined handle */
uint16_t nport_handle;
#define CTIO7_NHANDLE_UNRECOGNIZED 0xFFFF
uint16_t timeout;
uint16_t dseg_count; /* Data segment count. */
uint8_t vp_index;
uint8_t add_flags;
uint8_t initiator_id[3];
uint8_t reserved;
uint32_t exchange_addr;
} __attribute__((packed)) ctio7_common_entry_t;
typedef struct
{
ctio7_common_entry_t common;
uint16_t reserved1;
uint16_t flags;
uint32_t residual;
uint16_t ox_id;
uint16_t scsi_status;
uint32_t relative_offset;
uint32_t reserved2;
uint32_t transfer_length;
uint32_t reserved3;
uint32_t dseg_0_address[2]; /* Data segment 0 address. */
uint32_t dseg_0_length; /* Data segment 0 length. */
} __attribute__((packed)) ctio7_status0_entry_t;
typedef struct
{
ctio7_common_entry_t common;
uint16_t sense_length;
uint16_t flags;
uint32_t residual;
uint16_t ox_id;
uint16_t scsi_status;
uint16_t response_len;
uint16_t reserved;
uint8_t sense_data[24];
} __attribute__((packed)) ctio7_status1_entry_t;
typedef struct
{
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 defined handle */
uint16_t status;
uint16_t timeout;
uint16_t dseg_count; /* Data segment count. */
uint8_t reserved1[6];
uint32_t exchange_address;
uint16_t reserved2;
uint16_t flags;
uint32_t residual;
uint16_t ox_id;
uint16_t reserved3;
uint32_t relative_offset;
uint8_t reserved4[24];
} __attribute__((packed)) ctio7_fw_entry_t;
/* CTIO7 flags values */
#define CTIO7_FLAGS_SEND_STATUS BIT_15
#define CTIO7_FLAGS_TERMINATE BIT_14
#define CTIO7_FLAGS_CONFORM_REQ BIT_13
#define CTIO7_FLAGS_DONT_RET_CTIO BIT_8
#define CTIO7_FLAGS_STATUS_MODE_0 0
#define CTIO7_FLAGS_STATUS_MODE_1 BIT_6
#define CTIO7_FLAGS_EXPLICIT_CONFORM BIT_5
#define CTIO7_FLAGS_CONFIRM_SATISF BIT_4
#define CTIO7_FLAGS_DSD_PTR BIT_2
#define CTIO7_FLAGS_DATA_IN BIT_1
#define CTIO7_FLAGS_DATA_OUT BIT_0
/*
* ISP queue - immediate notify entry structure definition for 24xx.
*/
typedef struct
{
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 reserved;
uint16_t nport_handle;
uint16_t reserved_2;
uint16_t flags;
#define NOTIFY24XX_FLAGS_GLOBAL_TPRLO BIT_1
#define NOTIFY24XX_FLAGS_PUREX_IOCB BIT_0
uint16_t srr_rx_id;
uint16_t status;
uint8_t status_subcode;
uint8_t reserved_3;
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 vp_index;
uint32_t reserved_5;
uint8_t port_id[3];
uint8_t reserved_6;
uint16_t reserved_7;
uint16_t ox_id;
} __attribute__((packed)) notify24xx_entry_t;
#define ELS_PLOGI 0x3
#define ELS_FLOGI 0x4
#define ELS_LOGO 0x5
#define ELS_PRLI 0x20
#define ELS_PRLO 0x21
#define ELS_TPRLO 0x24
#define ELS_PDISC 0x50
#define ELS_ADISC 0x52
/*
* ISP queue - notify acknowledge entry structure definition for 24xx.
*/
typedef struct
{
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;
uint16_t nport_handle;
uint16_t reserved_1;
uint16_t flags;
uint16_t srr_rx_id;
uint16_t status;
uint8_t status_subcode;
uint8_t reserved_3;
uint32_t exchange_address;
uint32_t srr_rel_offs;
uint16_t srr_ui;
uint16_t srr_flags;
uint8_t reserved_4[19];
uint8_t vp_index;
uint8_t srr_reject_vendor_uniq;
uint8_t srr_reject_code_expl;
uint8_t srr_reject_code;
uint8_t reserved_5[7];
uint16_t ox_id;
} __attribute__((packed)) nack24xx_entry_t;
/*
* ISP queue - ABTS received/response entries structure definition for 24xx.
*/
#define ABTS_RECV_24XX 0x54 /* ABTS received (for 24xx) */
#define ABTS_RESP_24XX 0x55 /* ABTS responce (for 24xx) */
typedef struct
{
uint8_t entry_type; /* Entry type. */
uint8_t entry_count; /* Entry count. */
uint8_t sys_define; /* System defined. */
uint8_t entry_status; /* Entry Status. */
uint8_t reserved_1[6];
uint16_t nport_handle;
uint8_t reserved_2[3];
uint8_t reserved_3:4;
uint8_t sof_type:4;
uint32_t exchange_address;
fcp_hdr_le_t fcp_hdr_le;
uint8_t reserved_4[16];
uint32_t exchange_addr_to_abort;
} __attribute__((packed)) abts24_recv_entry_t;
#define ABTS_PARAM_ABORT_SEQ BIT_0
typedef struct
{
uint16_t reserved;
uint8_t seq_id_last;
uint8_t seq_id_valid;
#define SEQ_ID_VALID 0x80
#define SEQ_ID_INVALID 0x00
uint16_t rx_id;
uint16_t ox_id;
uint16_t high_seq_cnt;
uint16_t low_seq_cnt;
} __attribute__((packed)) ba_acc_le_t;
typedef struct
{
uint8_t vendor_uniq;
uint8_t reason_expl;
uint8_t reason_code;
#define BA_RJT_REASON_CODE_INVALID_COMMAND 0x1
#define BA_RJT_REASON_CODE_UNABLE_TO_PERFORM 0x9
uint8_t reserved;
} __attribute__((packed)) ba_rjt_le_t;
typedef struct
{
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;
uint16_t reserved_1;
uint16_t nport_handle;
uint16_t control_flags;
#define ABTS_CONTR_FLG_TERM_EXCHG BIT_0
uint8_t reserved_2;
uint8_t reserved_3:4;
uint8_t sof_type:4;
uint32_t exchange_address;
fcp_hdr_le_t fcp_hdr_le;
union {
ba_acc_le_t ba_acct;
ba_rjt_le_t ba_rjt;
} __attribute__((packed)) payload;
uint32_t reserved_4;
uint32_t exchange_addr_to_abort;
} __attribute__((packed)) abts24_resp_entry_t;
typedef struct
{
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;
uint16_t compl_status;
#define ABTS_RESP_COMPL_SUCCESS 0
#define ABTS_RESP_COMPL_SUBCODE_ERROR 0x31
uint16_t nport_handle;
uint16_t reserved_1;
uint8_t reserved_2;
uint8_t reserved_3:4;
uint8_t sof_type:4;
uint32_t exchange_address;
fcp_hdr_le_t fcp_hdr_le;
uint8_t reserved_4[8];
uint32_t error_subcode1;
#define ABTS_RESP_SUBCODE_ERR_ABORTED_EXCH_NOT_TERM 0x1E
uint32_t error_subcode2;
uint32_t exchange_addr_to_abort;
} __attribute__((packed)) abts24_resp_fw_entry_t;
/********************************************************************\
* Type Definitions used by initiator & target halves
\********************************************************************/
enum qla2x_tgt_host_action {
DISABLE_TARGET_MODE = 0,
ENABLE_TARGET_MODE = 1
};
typedef enum {
DISABLE_TARGET_MODE = 0,
ENABLE_TARGET_MODE = 1
} qla2x_tgt_host_action_t;
struct qla2x_tgt_initiator {
struct qla_tgt_initiator
{
int magic;
/* Callbacks */
void (*tgt_response_pkt)(scsi_qla_host_t *ha, sts_entry_t *pkt);
void (*tgt_ctio_completion)(scsi_qla_host_t *ha, uint32_t handle);
void (*tgt24_atio_pkt)(scsi_qla_host_t *ha, atio7_entry_t *pkt);
void (*tgt_response_pkt)(scsi_qla_host_t *ha, response_t *pkt);
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_host_action)(scsi_qla_host_t *ha,
enum qla2x_tgt_host_action action);
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);
void (*tgt_fc_port_deleted)(scsi_qla_host_t *ha, fc_port_t *fcport);
};
struct qla2x_tgt_target {
struct qla_target
{
int magic;
/* Callbacks - H/W lock MUST be held while calling any */
request_t *(*req_pkt)(scsi_qla_host_t *ha);
/*
* Callbacks - H/W lock MUST be held while calling any.
*
* !!! req_pkt() and issue_marker() could unlock/lock it inside !!!
*
* But it isn't an issue, since in the current implementation:
*
* - Either we in IRQ and only IRQ handler can modify HW data,
* including rings related fields.
*
* - Or access to target mode variables from struct q2t_tgt don't
* cross those functions boundaries, except tgt_shutdown, which
* additionally protected by irq_cmd_count.
*/
request_t *(*req_pkt)(scsi_qla_host_t *ha);
void (*isp_cmd)(scsi_qla_host_t *ha);
void (*enable_lun)(scsi_qla_host_t *ha);
void (*disable_lun)(scsi_qla_host_t *ha);
int (*issue_marker)(scsi_qla_host_t *ha);
cont_entry_t *(*req_cont_pkt)(scsi_qla_host_t *ha);
int (*get_counts)(scsi_qla_host_t *ha, uint8_t *cmd, uint8_t *imm);
void (*enable_tgt_mode)(scsi_qla_host_t *ha);
void (*disable_tgt_mode)(scsi_qla_host_t *ha);
int (*issue_marker)(scsi_qla_host_t *ha, int ha_locked);
void (*mark_all_devices_lost)(scsi_qla_host_t *ha, int defer);
int (*get_id_list)(scsi_qla_host_t *ha, void *id_list,
dma_addr_t id_list_dma, uint16_t *entries);
int (*get_port_database)(scsi_qla_host_t *ha, fc_port_t *fcport,
uint8_t opt);
};
int qla2xxx_tgt_register_driver(/* IN */ struct qla2x_tgt_initiator *tgt,
/* OUT */ struct qla2x_tgt_target *init);
int qla2xxx_tgt_register_driver(/* IN */ struct qla_tgt_initiator *tgt,
/* OUT */ struct qla_target *init);
void qla2xxx_tgt_unregister_driver(void);
#endif
int qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha);
int qla2x00_wait_for_hba_online(scsi_qla_host_t *ha);
#endif /* __QLA2X_TGT_DEF_H */
+358 -237
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -216,7 +216,7 @@ qla24xx_soft_reset(scsi_qla_host_t *ha)
static int
qla2xxx_dump_ram(scsi_qla_host_t *ha, uint32_t addr, uint16_t *ram,
uint32_t ram_words, void **nxt)
uint16_t ram_words, void **nxt)
{
int rval;
uint32_t cnt, stat, timer, words, idx;
+78 -31
View File
@@ -94,7 +94,6 @@
#define LSD(x) ((uint32_t)((uint64_t)(x)))
#define MSD(x) ((uint32_t)((((uint64_t)(x)) >> 16) >> 16))
/*
* I/O register
*/
@@ -181,6 +180,7 @@
#define REQUEST_ENTRY_CNT_24XX 4096 /* Number of request entries. */
#define RESPONSE_ENTRY_CNT_2100 64 /* Number of response entries.*/
#define RESPONSE_ENTRY_CNT_2300 512 /* Number of response entries.*/
#define ATIO_ENTRY_CNT_24XX 4096 /* Number of ATIO entries. */
/*
* SCSI Request Block
@@ -466,7 +466,7 @@ typedef struct {
#define MBA_SYSTEM_ERR 0x8002 /* System Error. */
#define MBA_REQ_TRANSFER_ERR 0x8003 /* Request Transfer Error. */
#define MBA_RSP_TRANSFER_ERR 0x8004 /* Response Transfer Error. */
#define MBA_WAKEUP_THRES 0x8005 /* Request Queue Wake-up. */
#define MBA_ATIO_TRANSFER_ERR 0x8005 /* ATIO Queue Transfer Error. */
#define MBA_LIP_OCCURRED 0x8010 /* Loop Initialization Procedure */
/* occurred. */
#define MBA_LOOP_UP 0x8011 /* FC Loop UP. */
@@ -864,8 +864,7 @@ struct link_statistics {
uint32_t prim_seq_err_cnt;
uint32_t inval_xmit_word_cnt;
uint32_t inval_crc_cnt;
uint32_t lip_cnt;
uint32_t unused1[0x1a];
uint32_t unused1[0x1b];
uint32_t tx_frames;
uint32_t rx_frames;
uint32_t dumped_frames;
@@ -1130,11 +1129,27 @@ typedef struct {
* ISP queue - response queue entry definition.
*/
typedef struct {
uint8_t data[60];
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 defined handle */
uint8_t data[52];
uint32_t signature;
#define RESPONSE_PROCESSED 0xDEADDEAD /* Signature */
} response_t;
/*
* ISP queue - ATIO queue entry definition.
*/
typedef struct {
uint8_t entry_type;
uint8_t entry_count;
uint8_t data[58];
uint32_t signature;
#define ATIO_PROCESSED 0xDEADDEAD /* Signature */
} atio_t;
typedef union {
uint16_t extended;
struct {
@@ -1529,6 +1544,8 @@ typedef struct fc_port {
uint8_t node_name[WWN_SIZE];
uint8_t port_name[WWN_SIZE];
/* True, if confirmed completion is supported */
uint8_t conf_compl_supported:1;
port_id_t d_id;
uint16_t loop_id;
uint16_t old_loop_id;
@@ -1545,6 +1562,7 @@ typedef struct fc_port {
int login_retry;
atomic_t port_down_timer;
spinlock_t rport_lock;
struct fc_rport *rport, *drport;
u32 supported_classes;
@@ -2155,10 +2173,6 @@ struct qla_chip_state_84xx {
uint32_t gold_fw_version;
};
struct qla_statistics {
uint32_t total_isp_aborts;
};
/*
* Linux Host Adapter structure
*/
@@ -2170,6 +2184,7 @@ typedef struct scsi_qla_host {
struct pci_dev *pdev;
unsigned long host_no;
unsigned long instance;
volatile struct {
uint32_t init_done :1;
@@ -2197,10 +2212,6 @@ typedef struct scsi_qla_host {
uint32_t npiv_supported :1;
uint32_t fce_enabled :1;
uint32_t hw_event_marker_found :1;
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
uint32_t enable_target_mode :1;
uint32_t host_shutting_down :1;
#endif
} flags;
atomic_t loop_state;
@@ -2241,7 +2252,6 @@ typedef struct scsi_qla_host {
#define REGISTER_FDMI_NEEDED 26
#define FCPORT_UPDATE_NEEDED 27
#define VP_DPC_NEEDED 28 /* wake up for VP dpc handling */
#define UNLOADING 29
uint32_t device_flags;
#define DFLG_LOCAL_DEVICES BIT_0
@@ -2338,6 +2348,28 @@ typedef struct scsi_qla_host {
uint16_t rsp_ring_index; /* Current index. */
uint16_t response_q_length;
/* Protected by hw lock */
unsigned int enable_class_2 :1;
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
unsigned int enable_explicit_conf :1;
unsigned int host_shutting_down :1;
dma_addr_t atio_dma; /* Physical address. */
atio_t *atio_ring; /* Base virtual address */
atio_t *atio_ring_ptr; /* Current address. */
uint16_t atio_ring_index; /* Current index. */
uint16_t atio_q_length;
/*
* Protected by tgt_mutex AND hardware_lock for writing and
* tgt_mutex OR hardware_lock for reading.
*/
struct q2t_tgt *tgt;
struct q2t_cmd *cmds[MAX_OUTSTANDING_COMMANDS];
uint16_t current_handle;
#endif /* CONFIG_SCSI_QLA2XXX_TARGET */
struct isp_operations *isp_ops;
/* Outstandings ISP commands. */
@@ -2411,13 +2443,19 @@ typedef struct scsi_qla_host {
struct list_head work_list;
/*
* Fibre Channel Device List.
*
* This list can be accessed from many contexts, including concurrently.
* So, although anything never deleted from this list, it needs the
* corresponding protection anyway. Let's do it by making access to
* it using RCU functions.
/*
* To surprise, fcports list isn't anyhow protected, although it can be
* accessed from many contexts, including concurrently. Seems, the
* original author of this code thought that if anything never deleted
* from this list, it is always safe to travel over it without any
* protection. Obviously, this isn't true. (The whole decision to keep
* stale entries forever is quite questionable as well.) We will fix
* that making access to fcports list using RCU functions. This isn't
* a complete solution, because it isn't clear if it's safe if some
* function going over this list misses just added entry, but definitely
* better, than currently. Also, most likely, fcports isn't the only
* variable in this structure wrongly accessed in an unprotected
* manner, so ToDo. VLNB.
*/
struct list_head fcports;
@@ -2523,7 +2561,8 @@ typedef struct scsi_qla_host {
uint32_t hw_event_ptr;
uint32_t hw_event_pause_errors;
uint8_t host_str[16];
#define HA_HOST_STR_SIZE 16
uint8_t host_str[HA_HOST_STR_SIZE];
uint32_t pci_attr;
uint16_t chip_revision;
@@ -2531,7 +2570,7 @@ typedef struct scsi_qla_host {
uint8_t model_number[16+1];
#define BINZERO "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
char model_desc[80];
char *model_desc;
uint8_t adapter_id[16+1];
uint8_t *node_name;
@@ -2578,12 +2617,6 @@ typedef struct scsi_qla_host {
uint16_t zio_timer;
struct fc_host_statistics fc_host_stat;
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
struct q2t_cmd *cmds[MAX_OUTSTANDING_COMMANDS];
uint16_t current_cmd;
struct q2t_tgt *tgt;
#endif /* CONFIG_SCSI_QLA2XXX_TARGET */
struct qla_msix_entry msix_entries[QLA_MSIX_ENTRIES];
struct list_head vp_list; /* list of VP */
@@ -2593,6 +2626,18 @@ typedef struct scsi_qla_host {
uint16_t num_vsans; /* number of vsan created */
uint16_t vp_idx; /* vport ID */
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
struct mutex tgt_mutex;
int saved_set;
uint16_t saved_exchange_count;
uint32_t saved_firmware_options_1;
uint32_t saved_firmware_options_2;
uint32_t saved_firmware_options_3;
uint8_t saved_firmware_options[2];
uint8_t saved_add_firmware_options[2];
#endif
struct scsi_qla_host *parent; /* holds pport */
unsigned long vp_flags;
struct list_head vp_fcports; /* list of fcports */
@@ -2618,9 +2663,9 @@ typedef struct scsi_qla_host {
int cur_vport_count;
struct qla_chip_state_84xx *cs84xx;
struct qla_statistics qla_stats;
} scsi_qla_host_t;
/*
* Macros to help code, maintain, etc.
*/
@@ -2629,6 +2674,8 @@ typedef struct scsi_qla_host {
test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || \
atomic_read(&ha->loop_state) == LOOP_DOWN)
#define to_qla_host(x) ((scsi_qla_host_t *) (x)->hostdata)
#define qla_printk(level, ha, format, arg...) \
dev_printk(level , &((ha)->pdev->dev) , format , ## arg)
@@ -2682,4 +2729,4 @@ typedef struct scsi_qla_host {
#define CMD_ACTUAL_SNSLEN(Cmnd) ((Cmnd)->SCp.Message)
#define CMD_ENTRY_STATUS(Cmnd) ((Cmnd)->SCp.have_data_in)
#endif
#endif /* __QLA_DEF_H */
+4 -12
View File
@@ -49,10 +49,6 @@ extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *);
extern void qla84xx_put_chip(struct scsi_qla_host *);
extern int qla2x00_configure_loop(scsi_qla_host_t *ha);
extern int qla2x00_configure_local_loop(scsi_qla_host_t *ha);
extern int qla2x00_configure_fabric(scsi_qla_host_t *ha);
/*
* Global Data in qla_os.c source file.
*/
@@ -66,7 +62,7 @@ extern int ql2xfdmienable;
extern int ql2xallocfwdump;
extern int ql2xextended_error_logging;
extern int ql2xqfullrampup;
extern int ql2xiidmaenable;
extern int num_hosts;
extern int qla2x00_loop_reset(scsi_qla_host_t *);
extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
@@ -75,8 +71,6 @@ extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum
extern int qla2x00_post_hwe_work(struct scsi_qla_host *, uint16_t , uint16_t,
uint16_t, uint16_t);
extern void qla2x00_abort_fcport_cmds(fc_port_t *);
/*
* Global Functions in qla_mid.c source file.
*/
@@ -118,6 +112,7 @@ extern void 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 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);
@@ -130,9 +125,6 @@ int __qla2x00_marker(scsi_qla_host_t *, uint16_t, uint16_t, uint8_t);
/*
* Global Function Prototypes in qla_mbx.c source file.
*/
extern int
qla2x00_mailbox_command(scsi_qla_host_t *pvha, mbx_cmd_t *mcp);
extern int
qla2x00_load_ram(scsi_qla_host_t *, dma_addr_t, uint32_t, uint32_t);
@@ -322,7 +314,8 @@ 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_vpd_field(scsi_qla_host_t *, char *, char *, size_t);
extern int qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp);
/*
* Global Function Prototypes in qla_dbg.c source file.
@@ -373,5 +366,4 @@ extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *);
*/
extern int qla2x00_dfs_setup(scsi_qla_host_t *);
extern int qla2x00_dfs_remove(scsi_qla_host_t *);
#endif /* _QLA_GBL_H */
+6 -7
View File
@@ -5,6 +5,7 @@
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
#include "qla2x_tgt.h"
static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *);
static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *);
@@ -544,8 +545,12 @@ qla2x00_rff_id(scsi_qla_host_t *ha)
/*
* FC-4 Feature bit 0 indicates target functionality to the name server.
*/
if (ha->flags.enable_target_mode) {
if (qla_tgt_mode_enabled(ha)) {
#ifdef CONFIG_SCSI_QLA2XXX_TARGET_DISABLE_INI_MODE
ct_req->req.rff_id.fc4_feature = BIT_0;
#else
ct_req->req.rff_id.fc4_feature = BIT_0 | BIT_1;
#endif
} else
#endif
ct_req->req.rff_id.fc4_feature = BIT_1;
@@ -1670,12 +1675,6 @@ qla2x00_fdmi_register(scsi_qla_host_t *ha)
{
int rval;
if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
DEBUG2(printk("scsi(%ld): FDMI unsupported on "
"ISP2100/ISP2200.\n", ha->host_no));
return QLA_SUCCESS;
}
rval = qla2x00_mgmt_svr_login(ha);
if (rval)
return rval;
+398 -270
View File
File diff suppressed because it is too large Load Diff
-26
View File
@@ -47,32 +47,6 @@ to_qla_parent(scsi_qla_host_t *ha)
return ha->parent ? ha->parent : ha;
}
/**
* qla2x00_issue_marker() - Issue a Marker IOCB if necessary.
* @ha: HA context
* @ha_locked: is function called with the hardware lock
*
* Returns non-zero if a failure occured, else zero.
*/
static inline int
qla2x00_issue_marker(scsi_qla_host_t *ha, int ha_locked)
{
/* Send marker if required */
if (ha->marker_needed != 0) {
if (ha_locked) {
if (__qla2x00_marker(ha, 0, 0, MK_SYNC_ALL) !=
QLA_SUCCESS)
return (QLA_FUNCTION_FAILED);
} else {
if (qla2x00_marker(ha, 0, 0, MK_SYNC_ALL) !=
QLA_SUCCESS)
return (QLA_FUNCTION_FAILED);
}
ha->marker_needed = 0;
}
return (QLA_SUCCESS);
}
static inline uint8_t *
host_to_fcp_swap(uint8_t *fcp, uint32_t bsize)
{
+10 -10
View File
@@ -11,7 +11,7 @@
#include <scsi/scsi_tcq.h>
request_t *qla2x00_req_pkt(scsi_qla_host_t *ha);
#include "qla2x_tgt.h"
/**
* qla2x00_get_cmd_direction() - Determine control_flag data direction.
@@ -407,6 +407,8 @@ queuing_error:
* Can be called from both normal and interrupt context.
*
* Returns non-zero if a failure occured, else zero.
*
* Hardware lock must be held on entrance. Might release it, then reaquire.
*/
int
__qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun,
@@ -453,11 +455,10 @@ qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun,
{
int ret;
unsigned long flags = 0;
scsi_qla_host_t *pha = to_qla_parent(ha);
spin_lock_irqsave(&pha->hardware_lock, flags);
spin_lock_irqsave(&ha->hardware_lock, flags);
ret = __qla2x00_marker(ha, loop_id, lun, type);
spin_unlock_irqrestore(&pha->hardware_lock, flags);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
return (ret);
}
@@ -467,6 +468,7 @@ qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun,
* @ha: HA context
*
* Note: The caller must hold the hardware lock before calling this routine.
* Might release it, then reaquire.
*
* Returns NULL if function failed, else, a pointer to the request packet.
*/
@@ -565,7 +567,6 @@ qla2x00_isp_cmd(scsi_qla_host_t *ha)
WRT_REG_WORD(ISP_REQ_Q_IN(ha, &reg->isp), ha->req_ring_index);
RD_REG_WORD_RELAXED(ISP_REQ_Q_IN(ha, &reg->isp));
}
}
/**
@@ -672,7 +673,7 @@ qla24xx_start_scsi(srb_t *sp)
{
int ret, nseg;
unsigned long flags;
scsi_qla_host_t *ha, *pha;
scsi_qla_host_t *ha;
struct scsi_cmnd *cmd;
uint32_t *clr_ptr;
uint32_t index;
@@ -686,7 +687,6 @@ qla24xx_start_scsi(srb_t *sp)
/* Setup device pointers. */
ret = 0;
ha = sp->ha;
pha = to_qla_parent(ha);
reg = &ha->iobase->isp24;
cmd = sp->cmd;
/* So we know we haven't pci_map'ed anything yet */
@@ -701,7 +701,7 @@ qla24xx_start_scsi(srb_t *sp)
}
/* Acquire ring specific lock */
spin_lock_irqsave(&pha->hardware_lock, flags);
spin_lock_irqsave(&ha->hardware_lock, flags);
/* Check for room in outstanding command list. */
handle = ha->current_outstanding_cmd;
@@ -796,14 +796,14 @@ qla24xx_start_scsi(srb_t *sp)
ha->response_ring_ptr->signature != RESPONSE_PROCESSED)
qla24xx_process_response_queue(ha);
spin_unlock_irqrestore(&pha->hardware_lock, flags);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
return QLA_SUCCESS;
queuing_error:
if (tot_dsds)
scsi_dma_unmap(cmd);
spin_unlock_irqrestore(&pha->hardware_lock, flags);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
return QLA_FUNCTION_FAILED;
}
+224 -88
View File
@@ -3,17 +3,18 @@
* Copyright (c) 2003-2008 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*
*/
#include "qla_def.h"
#include "qla2x_tgt.h"
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
struct qla_tgt_initiator qla_target;
#endif
#include <linux/delay.h>
#include <scsi/scsi_tcq.h>
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
#include "qla2x_tgt.h"
struct qla2x_tgt_initiator qla_target;
#endif /* CONFIG_SCSI_QLA2XXX_TARGET */
static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t);
static void qla2x00_status_entry(scsi_qla_host_t *, void *);
@@ -354,8 +355,8 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
case MBA_CTIO_COMPLETION:
if (qla_target.tgt_ctio_completion)
qla_target.tgt_ctio_completion(ha, handles[0]);
if (qla_target.tgt2x_ctio_completion)
qla_target.tgt2x_ctio_completion(ha, handles[0]);
break;
#endif
@@ -363,10 +364,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
DEBUG2(printk("scsi(%ld): Asynchronous RESET.\n", ha->host_no));
set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
if (qla_target.tgt_async_event)
qla_target.tgt_async_event(mb[0], ha, mb);
#endif
break;
case MBA_SYSTEM_ERR: /* System Error */
@@ -392,10 +389,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
ha->flags.online = 0;
} else
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
if (qla_target.tgt_async_event)
qla_target.tgt_async_event(mb[0], ha, mb);
#endif
break;
case MBA_REQ_TRANSFER_ERR: /* Request Transfer Error */
@@ -405,10 +398,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]);
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
if (qla_target.tgt_async_event)
qla_target.tgt_async_event(mb[0], ha, mb);
#endif
break;
case MBA_RSP_TRANSFER_ERR: /* Response Transfer Error */
@@ -418,19 +407,14 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]);
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
if (qla_target.tgt_async_event)
qla_target.tgt_async_event(mb[0], ha, mb);
#endif
break;
case MBA_WAKEUP_THRES: /* Request Queue Wake-up */
DEBUG2(printk("scsi(%ld): Asynchronous WAKEUP_THRES.\n",
case MBA_ATIO_TRANSFER_ERR: /* ATIO Queue Transfer Error */
DEBUG2(printk("scsi(%ld): ATIO Transfer Error.\n",
ha->host_no));
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
if (qla_target.tgt_async_event)
qla_target.tgt_async_event(mb[0], ha, mb);
#endif
qla_printk(KERN_WARNING, ha, "ATIO Transfer Error.\n");
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
break;
case MBA_LIP_OCCURRED: /* Loop Initialization Procedure */
@@ -454,10 +438,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
ha->flags.management_server_logged_in = 0;
qla2x00_post_aen_work(ha, FCH_EVT_LIP, mb[1]);
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
if (qla_target.tgt_async_event)
qla_target.tgt_async_event(mb[0], ha, mb);
#endif
break;
case MBA_LOOP_UP: /* Loop Up Event */
@@ -478,10 +458,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
ha->flags.management_server_logged_in = 0;
qla2x00_post_aen_work(ha, FCH_EVT_LINKUP, ha->link_data_rate);
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
if (qla_target.tgt_async_event)
qla_target.tgt_async_event(mb[0], ha, mb);
#endif
break;
case MBA_LOOP_DOWN: /* Loop Down Event */
@@ -505,10 +481,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
ha->flags.management_server_logged_in = 0;
ha->link_data_rate = PORT_SPEED_UNKNOWN;
qla2x00_post_aen_work(ha, FCH_EVT_LINKDOWN, 0);
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
if (qla_target.tgt_async_event)
qla_target.tgt_async_event(mb[0], ha, mb);
#endif
break;
case MBA_LIP_RESET: /* LIP reset occurred */
@@ -533,10 +505,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
ha->operating_mode = LOOP;
ha->flags.management_server_logged_in = 0;
qla2x00_post_aen_work(ha, FCH_EVT_LIPRESET, mb[1]);
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
if (qla_target.tgt_async_event)
qla_target.tgt_async_event(mb[0], ha, mb);
#endif
break;
case MBA_POINT_TO_POINT: /* Point-to-Point */
@@ -571,10 +539,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
ha->flags.gpsc_supported = 1;
ha->flags.management_server_logged_in = 0;
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
if (qla_target.tgt_async_event)
qla_target.tgt_async_event(mb[0], ha, mb);
#endif
break;
case MBA_CHG_IN_CONNECTION: /* Change in connection mode */
@@ -602,13 +566,13 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
if (qla_target.tgt_async_event)
qla_target.tgt_async_event(mb[0], ha, mb);
#endif
break;
case MBA_PORT_UPDATE: /* Port database update */
/* Only handle SCNs for our Vport index. */
if (ha->parent && ha->vp_idx != (mb[3] & 0xff))
break;
/*
* If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET
* event etc. earlier indicating loop is down) then process
@@ -621,8 +585,15 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
"ignored %04x/%04x/%04x.\n", ha->host_no, mb[1],
mb[2], mb[3]));
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
DEBUG2(printk("scsi(%ld): ha state %d init_done %d "
"oper_mode %d topo %d\n",
ha->host_no,
atomic_read(&ha->loop_state),
ha->flags.init_done,
ha->operating_mode,
ha->current_topology));
if (qla_target.tgt_async_event)
qla_target.tgt_async_event(mb[0], ha, mb);
qla_target.tgt_async_event(mb[0], ha, mb);
#endif
break;
}
@@ -646,7 +617,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
if (qla_target.tgt_async_event)
qla_target.tgt_async_event(mb[0], ha, mb);
qla_target.tgt_async_event(mb[0], ha, mb);
#endif
break;
@@ -692,10 +663,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
set_bit(RSCN_UPDATE, &ha->dpc_flags);
qla2x00_post_aen_work(ha, FCH_EVT_RSCN, rscn_entry);
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
if (qla_target.tgt_async_event)
qla_target.tgt_async_event(mb[0], ha, mb);
#endif
break;
/* case MBA_RIO_RESPONSE: */
@@ -757,6 +724,40 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
}
spin_unlock_irqrestore(&ha->cs84xx->access_lock, flags);
break;
case MBA_LOOP_INIT_ERR:
printk("scsi(%ld): Loop init error received -- "
"%04x %04x %04x.\n", ha->host_no, mb[1], mb[2],
mb[3]);
break;
default:
printk("scsi(%ld): Unhandled async event %d received -- "
"%04x %04x %04x.\n", ha->host_no, mb[0], mb[1], mb[2],
mb[3]);
break;
}
switch (mb[0]) {
case MBA_POINT_TO_POINT: /* Point-to-Point */
case MBA_CHG_IN_CONNECTION: /* Change in connection mode */
if (IS_QLA2100(ha))
break;
/* else go through */
case MBA_RESET: /* Reset */
case MBA_SYSTEM_ERR: /* System Error */
case MBA_REQ_TRANSFER_ERR: /* Request Transfer Error */
case MBA_RSP_TRANSFER_ERR: /* Response Transfer Error */
case MBA_ATIO_TRANSFER_ERR: /* ATIO Queue Transfer Error */
case MBA_LIP_OCCURRED: /* Loop Initialization Procedure */
case MBA_LOOP_UP: /* Loop Up Event */
case MBA_LOOP_DOWN: /* Loop Down Event */
case MBA_LIP_RESET: /* LIP reset occurred */
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
if (qla_target.tgt_async_event)
qla_target.tgt_async_event(mb[0], ha, mb);
#endif
break;
}
if (!ha->parent && ha->num_vhosts)
@@ -834,8 +835,8 @@ qla2x00_process_completed_request(struct scsi_qla_host *ha, uint32_t index)
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
if (HANDLE_IS_CTIO_COMP(index)) {
if (qla_target.tgt_ctio_completion)
qla_target.tgt_ctio_completion(ha, index);
if (qla_target.tgt2x_ctio_completion)
qla_target.tgt2x_ctio_completion(ha, index);
return;
}
#endif
@@ -846,7 +847,7 @@ qla2x00_process_completed_request(struct scsi_qla_host *ha, uint32_t index)
ha->host_no, index));
qla_printk(KERN_WARNING, ha,
"Invalid SCSI completion handle %d.\n", index);
DEBUG2(dump_stack());
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
return;
}
@@ -869,6 +870,7 @@ qla2x00_process_completed_request(struct scsi_qla_host *ha, uint32_t index)
ha->host_no));
qla_printk(KERN_WARNING, ha,
"Invalid ISP SCSI completion handle\n");
DEBUG2(dump_stack());
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
}
@@ -892,6 +894,9 @@ qla2x00_process_response_queue(struct scsi_qla_host *ha)
while (ha->response_ring_ptr->signature != RESPONSE_PROCESSED) {
pkt = (sts_entry_t *)ha->response_ring_ptr;
DEBUG5(printk("%s(): IOCB data:\n", __func__));
DEBUG5(qla2x00_dump_buffer((uint8_t *)pkt, RESPONSE_ENTRY_SIZE));
ha->rsp_ring_index++;
if (ha->rsp_ring_index == ha->response_q_length) {
ha->rsp_ring_index = 0;
@@ -905,29 +910,43 @@ qla2x00_process_response_queue(struct scsi_qla_host *ha)
"scsi(%ld): Process error entry.\n", ha->host_no));
qla2x00_error_entry(ha, pkt);
((response_t *)pkt)->signature = RESPONSE_PROCESSED;
wmb();
continue;
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
switch (pkt->entry_type) {
case ACCEPT_TGT_IO_TYPE:
case CONTINUE_TGT_IO_TYPE:
case CTIO_A64_TYPE:
case IMMED_NOTIFY_TYPE:
case NOTIFY_ACK_TYPE:
case ENABLE_LUN_TYPE:
case MODIFY_LUN_TYPE:
break;
default:
((response_t *)pkt)->signature = RESPONSE_PROCESSED;
wmb();
continue;
}
#endif
}
switch (pkt->entry_type) {
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
case ACCEPT_TGT_IO_TYPE:
case CONTINUE_TGT_IO_TYPE:
case CTIO_A64_TYPE:
case IMMED_NOTIFY_TYPE:
case NOTIFY_ACK_TYPE:
case ENABLE_LUN_TYPE:
case MODIFY_LUN_TYPE:
DEBUG4(printk(KERN_WARNING
case ACCEPT_TGT_IO_TYPE:
case CONTINUE_TGT_IO_TYPE:
case CTIO_A64_TYPE:
case IMMED_NOTIFY_TYPE:
case NOTIFY_ACK_TYPE:
case ENABLE_LUN_TYPE:
case MODIFY_LUN_TYPE:
DEBUG5(printk(KERN_WARNING
"qla2x00_response_pkt: "
"calling tgt_response_pkt %p "
"(type %02X)\n",
qla_target.tgt_response_pkt,
pkt->entry_type););
if (qla_target.tgt_response_pkt)
qla_target.tgt_response_pkt(ha, pkt);
break;
qla_target.tgt_response_pkt(ha,
(response_t*)pkt);
break;
#endif /* CONFIG_SCSI_QLA2XXX_TARGET */
case STATUS_TYPE:
qla2x00_status_entry(ha, pkt);
@@ -949,6 +968,8 @@ qla2x00_process_response_queue(struct scsi_qla_host *ha)
case STATUS_CONT_TYPE:
qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt);
break;
case MARKER_TYPE:
break;
default:
/* Type Not Supported. */
DEBUG4(printk(KERN_WARNING
@@ -984,12 +1005,11 @@ qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len)
sp->request_sense_ptr += sense_len;
sp->request_sense_length -= sense_len;
if (sp->request_sense_length != 0)
sp->fcport->ha->status_srb = sp;
sp->ha->status_srb = sp;
DEBUG5(printk("%s(): Check condition Sense data, scsi(%ld:%d:%d:%d) "
"cmd=%p pid=%ld\n", __func__, sp->fcport->ha->host_no,
cp->device->channel, cp->device->id, cp->device->lun, cp,
cp->serial_number));
"cmd=%p pid=%ld\n", __func__, sp->ha->host_no, cp->device->channel,
cp->device->id, cp->device->lun, cp, cp->serial_number));
if (sense_len)
DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,
CMD_ACTUAL_SNSLEN(cp)));
@@ -1308,8 +1328,9 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
atomic_read(&fcport->state)));
cp->result = DID_BUS_BUSY << 16;
if (atomic_read(&fcport->state) == FCS_ONLINE)
qla2x00_mark_device_lost(fcport->ha, fcport, 1, 1);
if (atomic_read(&fcport->state) == FCS_ONLINE) {
qla2x00_mark_device_lost(ha, fcport, 1, 1);
}
break;
case CS_RESET:
@@ -1352,7 +1373,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
/* Check to see if logout occurred. */
if ((le16_to_cpu(sts->status_flags) & SF_LOGOUT_SENT))
qla2x00_mark_device_lost(fcport->ha, fcport, 1, 1);
qla2x00_mark_device_lost(ha, fcport, 1, 1);
break;
default:
@@ -1432,9 +1453,12 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
srb_t *sp;
#if defined(QL_DEBUG_LEVEL_2)
if (pkt->entry_status & RF_INV_E_ORDER)
qla_printk(KERN_ERR, ha, "%s: Invalid Entry Order\n", __func__);
else if (pkt->entry_status & RF_INV_E_COUNT)
qla_printk(KERN_ERR, ha, "%s: Error entry with type %x:\n", __func__,
pkt->entry_type);
if (pkt->entry_status & RF_INV_E_ORDER) {
qla_printk(KERN_ERR, ha, "%s: Invalid Entry Order:\n", __func__);
qla2x00_dump_buffer((void*)pkt, sizeof(*pkt));
} else if (pkt->entry_status & RF_INV_E_COUNT)
qla_printk(KERN_ERR, ha, "%s: Invalid Entry Count\n", __func__);
else if (pkt->entry_status & RF_INV_E_PARAM)
qla_printk(KERN_ERR, ha,
@@ -1510,8 +1534,67 @@ qla24xx_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0)
DEBUG2_3(printk("%s(%ld): MBX pointer ERROR!\n",
__func__, ha->host_no));
}
#if defined(QL_DEBUG_LEVEL_1)
printk("scsi(%ld): Mailbox registers:", ha->host_no);
for (cnt = 0; cnt < ha->mbx_count; cnt++) {
if ((cnt % 4) == 0)
printk("\n");
printk("mbox %02d: 0x%04x ", cnt, ha->mailbox_out[cnt]);
}
printk("\n");
#endif
}
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
/**
* qla24xx_process_atio_queue() - Process ATIO queue entries.
* @ha: SCSI driver HA context
*/
static void
qla24xx_process_atio_queue(struct scsi_qla_host *ha)
{
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
atio_t *pkt;
int cnt, i;
if (!ha->flags.online)
return;
while (ha->atio_ring_ptr->signature != ATIO_PROCESSED) {
pkt = ha->atio_ring_ptr;
cnt = pkt->entry_count;
DEBUG5(printk("%s(): IOCB data:\n", __func__));
DEBUG5(qla2x00_dump_buffer((uint8_t *)pkt, RESPONSE_ENTRY_SIZE));
DEBUG5(printk(KERN_WARNING
"%s: calling tgt24_atio_pkt %p (type %02X, "
"count %d)\n", __func__, qla_target.tgt24_atio_pkt,
pkt->entry_type, cnt););
if (likely(qla_target.tgt24_atio_pkt))
qla_target.tgt24_atio_pkt(ha, (atio7_entry_t*)pkt);
for(i = 0; i < cnt; i++) {
ha->atio_ring_index++;
if (ha->atio_ring_index == ha->atio_q_length) {
ha->atio_ring_index = 0;
ha->atio_ring_ptr = ha->atio_ring;
} else
ha->atio_ring_ptr++;
pkt->signature = ATIO_PROCESSED;
pkt = ha->atio_ring_ptr;
}
wmb();
}
/* Adjust ring index */
WRT_REG_DWORD(&reg->atio_q_out, ha->atio_ring_index);
}
#endif /* CONFIG_SCSI_QLA2XXX_TARGET */
/**
* qla24xx_process_response_queue() - Process response queue entries.
* @ha: SCSI driver HA context
@@ -1528,6 +1611,9 @@ qla24xx_process_response_queue(struct scsi_qla_host *ha)
while (ha->response_ring_ptr->signature != RESPONSE_PROCESSED) {
pkt = (struct sts_entry_24xx *)ha->response_ring_ptr;
DEBUG5(printk("%s(): IOCB data:\n", __func__));
DEBUG5(qla2x00_dump_buffer((uint8_t *)pkt, RESPONSE_ENTRY_SIZE));
ha->rsp_ring_index++;
if (ha->rsp_ring_index == ha->response_q_length) {
ha->rsp_ring_index = 0;
@@ -1541,9 +1627,19 @@ qla24xx_process_response_queue(struct scsi_qla_host *ha)
"scsi(%ld): Process error entry.\n", ha->host_no));
qla2x00_error_entry(ha, (sts_entry_t *) pkt);
((response_t *)pkt)->signature = RESPONSE_PROCESSED;
wmb();
continue;
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
switch (pkt->entry_type) {
case ABTS_RECV_24XX:
case ABTS_RESP_24XX:
case CTIO_TYPE7:
case NOTIFY_ACK_TYPE:
break;
default:
((response_t *)pkt)->signature = RESPONSE_PROCESSED;
wmb();
continue;
}
#endif
}
switch (pkt->entry_type) {
@@ -1557,6 +1653,27 @@ qla24xx_process_response_queue(struct scsi_qla_host *ha)
qla24xx_report_id_acquisition(ha,
(struct vp_rpt_id_entry_24xx *)pkt);
break;
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
case ABTS_RECV_24XX:
/* ensure that the ATIO queue is empty */
qla24xx_process_atio_queue(ha);
/* go through */
case ABTS_RESP_24XX:
case CTIO_TYPE7:
case NOTIFY_ACK_TYPE:
DEBUG5(printk(KERN_WARNING
"qla2x00_response_pkt: "
"calling tgt_response_pkt %p "
"(type %02X)\n",
qla_target.tgt_response_pkt,
pkt->entry_type););
if (qla_target.tgt_response_pkt)
qla_target.tgt_response_pkt(ha,
(response_t*)pkt);
break;
#endif /* CONFIG_SCSI_QLA2XXX_TARGET */
case MARKER_TYPE:
break;
default:
/* Type Not Supported. */
DEBUG4(printk(KERN_WARNING
@@ -1694,6 +1811,15 @@ qla24xx_intr_handler(int irq, void *dev_id)
case 0x13:
qla24xx_process_response_queue(ha);
break;
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
case 0x1C: /* ATIO queue updated */
qla24xx_process_atio_queue(ha);
break;
case 0x1D: /* ATIO and response queues updated */
qla24xx_process_atio_queue(ha);
qla24xx_process_response_queue(ha);
break;
#endif
default:
DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
"(%d).\n",
@@ -1792,6 +1918,15 @@ qla24xx_msix_default(int irq, void *dev_id)
case 0x13:
qla24xx_process_response_queue(ha);
break;
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
case 0x1C: /* ATIO queue updated */
qla24xx_process_atio_queue(ha);
break;
case 0x1D: /* ATIO and response queues updated */
qla24xx_process_atio_queue(ha);
qla24xx_process_response_queue(ha);
break;
#endif
default:
DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
"(%d).\n",
@@ -1957,6 +2092,7 @@ clear_risc_ints:
WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_HOST_INT);
}
spin_unlock_irq(&ha->hardware_lock);
ha->isp_ops->enable_intrs(ha);
fail:
return ret;
+38 -7
View File
@@ -265,7 +265,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *pvha, mbx_cmd_t *mcp)
if (!abort_active)
complete(&ha->mbx_cmd_comp);
if (rval) {
if (rval != QLA_SUCCESS) {
DEBUG2_3_11(printk("%s(%ld): **** FAILED. mbx0=%x, mbx1=%x, "
"mbx2=%x, cmd=%x ****\n", __func__, ha->host_no,
mcp->mb[0], mcp->mb[1], mcp->mb[2], command));
@@ -918,8 +918,6 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa,
rval = qla2x00_mailbox_command(ha, mcp);
if (mcp->mb[0] == MBS_COMMAND_ERROR)
rval = QLA_COMMAND_ERROR;
else if (mcp->mb[0] == MBS_INVALID_COMMAND)
rval = QLA_INVALID_COMMAND;
/* Return data. */
*id = mcp->mb[1];
@@ -1024,6 +1022,28 @@ qla2x00_init_firmware(scsi_qla_host_t *ha, uint16_t size)
DEBUG11(printk("qla2x00_init_firmware(%ld): entered.\n",
ha->host_no));
#ifdef QL_DEBUG_LEVEL_5
if (IS_FWI2_CAPABLE(ha)) {
struct init_cb_24xx *icb = (struct init_cb_24xx *)ha->init_cb;
DEBUG5(printk("%s(): firmware_options_1 %x, "
"firmware_options_2 %x, firmware_options_3 %x\n",
__func__, icb->firmware_options_1,
icb->firmware_options_2, icb->firmware_options_3));
DEBUG5(printk("%s(): Control Block:\n", __func__));
DEBUG5(qla2x00_dump_buffer((uint8_t *)icb, sizeof(*icb)));
} else {
init_cb_t *icb = (init_cb_t *)ha->init_cb;
DEBUG5(printk("%s(): firmware_options[0] %x, "
"firmware_options[1] %x, add_firmware_options[0] %x, "
"add_firmware_options[1] %x\n", __func__,
icb->firmware_options[0], icb->firmware_options[1],
icb->add_firmware_options[0],
icb->add_firmware_options[1]));
DEBUG5(printk("%s(): Control Block:\n", __func__));
DEBUG5(qla2x00_dump_buffer((uint8_t *)icb, sizeof(*icb)));
}
#endif
if (ha->flags.npiv_supported)
mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE;
else
@@ -1156,6 +1176,13 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt)
fcport->port_type = FCT_INITIATOR;
else
fcport->port_type = FCT_UNKNOWN;
/* Passback COS information. */
fcport->supported_classes = (pd24->flags & PDF_CLASS_2) ?
FC_COS_CLASS2: FC_COS_CLASS3;
if (pd24->prli_svc_param_word_3[0] & BIT_7)
fcport->conf_compl_supported = 1;
} else {
/* Check for logged in state. */
if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
@@ -1189,6 +1216,9 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt)
/* Passback COS information. */
fcport->supported_classes = (pd->options & BIT_4) ?
FC_COS_CLASS2: FC_COS_CLASS3;
if (pd->prli_svc_param_word_3[0] & BIT_7)
fcport->conf_compl_supported = 1;
}
gpd_error_out:
@@ -1537,6 +1567,8 @@ qla24xx_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
mb[10] |= BIT_0; /* Class 2. */
if (lg->io_parameter[9] || lg->io_parameter[10])
mb[10] |= BIT_1; /* Class 3. */
if (lg->io_parameter[0] & __constant_cpu_to_le32(BIT_7))
mb[10] |= BIT_7; /* Confirmed Completion Allowed */
}
dma_pool_free(ha->s_dma_pool, lg, lg_dma);
@@ -2167,18 +2199,17 @@ qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp)
struct abort_entry_24xx *abt;
dma_addr_t abt_dma;
uint32_t handle;
scsi_qla_host_t *pha = to_qla_parent(ha);
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
fcport = sp->fcport;
spin_lock_irqsave(&pha->hardware_lock, flags);
spin_lock_irqsave(&ha->hardware_lock, flags);
for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
if (pha->outstanding_cmds[handle] == sp)
if (ha->outstanding_cmds[handle] == sp)
break;
}
spin_unlock_irqrestore(&pha->hardware_lock, flags);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (handle == MAX_OUTSTANDING_COMMANDS) {
/* Command not found. */
return QLA_FUNCTION_FAILED;
+11 -6
View File
@@ -6,6 +6,7 @@
*/
#include "qla_def.h"
#include <linux/version.h>
#include <linux/moduleparam.h>
#include <linux/vmalloc.h>
#include <linux/smp_lock.h>
@@ -42,7 +43,6 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha)
set_bit(vp_id, ha->vp_idx_map);
ha->num_vhosts++;
ha->cur_vport_count++;
vha->vp_idx = vp_id;
list_add_tail(&vha->vp_list, &ha->vp_list);
mutex_unlock(&ha->vport_lock);
@@ -58,7 +58,6 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
mutex_lock(&ha->vport_lock);
vp_id = vha->vp_idx;
ha->num_vhosts--;
ha->cur_vport_count--;
clear_bit(vp_id, ha->vp_idx_map);
list_del(&vha->vp_list);
mutex_unlock(&ha->vport_lock);
@@ -104,8 +103,8 @@ qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha)
"loop_id=0x%04x :%x\n",
vha->host_no, fcport->loop_id, fcport->vp_idx));
atomic_set(&fcport->state, FCS_DEVICE_DEAD);
qla2x00_mark_device_lost(vha, fcport, 0, 0);
atomic_set(&fcport->state, FCS_UNCONFIGURED);
}
}
@@ -277,8 +276,7 @@ qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
clear_bit(RESET_ACTIVE, &vha->dpc_flags);
}
if (atomic_read(&vha->vp_state) == VP_ACTIVE &&
test_and_clear_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) {
if (test_and_clear_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) {
if (!(test_and_set_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags))) {
qla2x00_loop_resync(vha);
clear_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags);
@@ -392,6 +390,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
vha->parent = ha;
vha->fc_vport = fc_vport;
vha->device_flags = 0;
vha->instance = num_hosts;
vha->vp_idx = qla24xx_allocate_vp_id(vha);
if (vha->vp_idx > ha->max_npiv_vports) {
DEBUG15(printk("scsi(%ld): Couldn't allocate vp_id.\n",
@@ -429,7 +428,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
host->max_cmd_len = MAX_CMDSZ;
host->max_channel = MAX_BUSES - 1;
host->max_lun = MAX_LUNS;
host->unique_id = host->host_no;
host->unique_id = vha->instance;
host->max_id = MAX_TARGETS_2200;
host->transportt = qla2xxx_transport_vport_template;
@@ -437,6 +436,12 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
vha->host_no, vha));
vha->flags.init_done = 1;
num_hosts++;
mutex_lock(&ha->vport_lock);
set_bit(vha->vp_idx, ha->vp_idx_map);
ha->cur_vport_count++;
mutex_unlock(&ha->vport_lock);
return vha;
+162 -112
View File
@@ -18,9 +18,7 @@
#include <scsi/scsi_transport.h>
#include <scsi/scsi_transport_fc.h>
#if defined(CONFIG_SCSI_QLA2XXX_TARGET)
#include "qla2x_tgt.h"
#endif
/*
* Driver version
@@ -32,6 +30,7 @@ char qla2x00_version_str[40];
*/
static struct kmem_cache *srb_cachep;
int num_hosts;
int ql2xlogintimeout = 20;
module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR);
MODULE_PARM_DESC(ql2xlogintimeout,
@@ -55,12 +54,18 @@ module_param(ql2xloginretrycount, int, S_IRUGO|S_IRUSR);
MODULE_PARM_DESC(ql2xloginretrycount,
"Specify an alternate value for the NVRAM login retry count.");
int ql2xallocfwdump = 1;
int ql2xenableclass2 = 0;
module_param(ql2xenableclass2, int, S_IRUGO|S_IRUSR);
MODULE_PARM_DESC(ql2xenableclass2,
"Specify if Class 2 operations are supported from the very "
"beginning.");
int ql2xallocfwdump = 0;
module_param(ql2xallocfwdump, int, S_IRUGO|S_IRUSR);
MODULE_PARM_DESC(ql2xallocfwdump,
"Option to enable allocation of memory for a firmware dump "
"during HBA initialization. Memory allocation requirements "
"vary by ISP type. Default is 1 - allocate memory.");
"vary by ISP type. Default is 0 - don't allocate memory.");
int ql2xextended_error_logging;
module_param(ql2xextended_error_logging, int, S_IRUGO|S_IWUSR);
@@ -91,13 +96,6 @@ MODULE_PARM_DESC(ql2xqfullrampup,
"depth for a device after a queue-full condition has been "
"detected. Default is 120 seconds.");
int ql2xiidmaenable=1;
module_param(ql2xiidmaenable, int, S_IRUGO|S_IRUSR);
MODULE_PARM_DESC(ql2xiidmaenable,
"Enables iIDMA settings "
"Default is 1 - perform iIDMA. 0 - no iIDMA.");
/*
* SCSI host template entry points
*/
@@ -149,6 +147,10 @@ static struct scsi_host_template qla2x00_driver_template = {
*/
.max_sectors = 0xFFFF,
.shost_attrs = qla2x00_host_attrs,
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
.supported_mode = MODE_INITIATOR | MODE_TARGET,
#endif
};
struct scsi_host_template qla24xx_driver_template = {
@@ -177,6 +179,10 @@ struct scsi_host_template qla24xx_driver_template = {
.max_sectors = 0xFFFF,
.shost_attrs = qla2x00_host_attrs,
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
.supported_mode = MODE_INITIATOR | MODE_TARGET,
#endif
};
static struct scsi_transport_template *qla2xxx_transport_template = NULL;
@@ -399,7 +405,7 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
}
/* Close window on fcport/rport state-transitioning. */
if (fcport->drport) {
if (!*(fc_port_t **)rport->dd_data) {
cmd->result = DID_IMM_RETRY << 16;
goto qc_fail_command;
}
@@ -454,7 +460,7 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
int rval;
scsi_qla_host_t *pha = to_qla_parent(ha);
if (unlikely(pci_channel_offline(pha->pdev))) {
if (unlikely(pci_channel_offline(ha->pdev))) {
cmd->result = DID_REQUEUE << 16;
goto qc24_fail_command;
}
@@ -466,7 +472,7 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
}
/* Close window on fcport/rport state-transitioning. */
if (fcport->drport) {
if (!*(fc_port_t **)rport->dd_data) {
cmd->result = DID_IMM_RETRY << 16;
goto qc24_fail_command;
}
@@ -602,7 +608,7 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *ha)
* Success (LOOP_READY) : 0
* Failed (LOOP_NOT_READY) : 1
*/
static inline int
int
qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha)
{
int return_status = QLA_SUCCESS;
@@ -628,40 +634,6 @@ qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha)
return (return_status);
}
void
qla2x00_abort_fcport_cmds(fc_port_t *fcport)
{
int cnt;
unsigned long flags;
srb_t *sp;
scsi_qla_host_t *ha = fcport->ha;
scsi_qla_host_t *pha = to_qla_parent(ha);
spin_lock_irqsave(&pha->hardware_lock, flags);
for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
sp = pha->outstanding_cmds[cnt];
if (!sp)
continue;
if (sp->fcport != fcport)
continue;
spin_unlock_irqrestore(&pha->hardware_lock, flags);
if (ha->isp_ops->abort_command(ha, sp)) {
DEBUG2(qla_printk(KERN_WARNING, ha,
"Abort failed -- %lx\n", sp->cmd->serial_number));
} else {
if (qla2x00_eh_wait_on_command(ha, sp->cmd) !=
QLA_SUCCESS)
DEBUG2(qla_printk(KERN_WARNING, ha,
"Abort failed while waiting -- %lx\n",
sp->cmd->serial_number));
}
spin_lock_irqsave(&pha->hardware_lock, flags);
}
spin_unlock_irqrestore(&pha->hardware_lock, flags);
}
static void
qla2x00_block_error_handler(struct scsi_cmnd *cmnd)
{
@@ -769,7 +741,7 @@ enum nexus_wait_type {
WAIT_LUN,
};
static int
int
qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha, unsigned int t,
unsigned int l, enum nexus_wait_type type)
{
@@ -785,8 +757,7 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha, unsigned int t,
sp = pha->outstanding_cmds[cnt];
if (!sp)
continue;
if (ha->vp_idx != sp->fcport->ha->vp_idx)
if (ha->vp_idx != sp->ha->vp_idx)
continue;
match = 0;
switch (type) {
@@ -1086,7 +1057,9 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *ha, int res)
sp = ha->outstanding_cmds[cnt];
if (sp) {
ha->outstanding_cmds[cnt] = NULL;
sp->flags = 0;
sp->cmd->result = res;
sp->cmd->host_scribble = (unsigned char *)NULL;
qla2x00_sp_compl(ha, sp);
}
}
@@ -1117,7 +1090,7 @@ qla2xxx_slave_configure(struct scsi_device *sdev)
else
scsi_deactivate_tcq(sdev, ha->max_q_depth);
rport->dev_loss_tmo = ha->port_down_retry_count;
rport->dev_loss_tmo = ha->port_down_retry_count + 5;
return 0;
}
@@ -1592,13 +1565,19 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
ha = shost_priv(host);
memset(ha, 0, sizeof(scsi_qla_host_t));
ha->enable_class_2 = ql2xenableclass2;
ha->pdev = pdev;
ha->host = host;
ha->host_no = host->host_no;
sprintf(ha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, ha->host_no);
snprintf(ha->host_str, HA_HOST_STR_SIZE, "%s_%ld", QLA2XXX_DRIVER_NAME,
ha->host_no);
ha->parent = NULL;
ha->bars = bars;
ha->mem_only = mem_only;
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
mutex_init(&ha->tgt_mutex);
qla_clear_tgt_mode(ha);
#endif
spin_lock_init(&ha->hardware_lock);
/* Set ISP-type information. */
@@ -1656,6 +1635,9 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
ha->mbx_count = MAILBOX_REGISTER_COUNT;
ha->request_q_length = REQUEST_ENTRY_CNT_24XX;
ha->response_q_length = RESPONSE_ENTRY_CNT_2300;
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
ha->atio_q_length = ATIO_ENTRY_CNT_24XX;
#endif
ha->last_loop_id = SNS_LAST_LOOP_ID_2300;
ha->init_cb_size = sizeof(struct mid_init_cb_24xx);
ha->mgmt_svr_loop_id = 10 + ha->vp_idx;
@@ -1667,6 +1649,9 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
ha->mbx_count = MAILBOX_REGISTER_COUNT;
ha->request_q_length = REQUEST_ENTRY_CNT_24XX;
ha->response_q_length = RESPONSE_ENTRY_CNT_2300;
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
ha->atio_q_length = ATIO_ENTRY_CNT_24XX;
#endif
ha->last_loop_id = SNS_LAST_LOOP_ID_2300;
ha->init_cb_size = sizeof(struct mid_init_cb_24xx);
ha->mgmt_svr_loop_id = 10 + ha->vp_idx;
@@ -1678,6 +1663,9 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
}
host->can_queue = ha->request_q_length + 128;
/* load the F/W, read paramaters, and init the H/W */
ha->instance = num_hosts;
spin_lock_init(&ha->dpc_lock);
mutex_init(&ha->vport_lock);
@@ -1727,7 +1715,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
host->this_id = 255;
host->cmd_per_lun = 3;
host->unique_id = host->host_no;
host->unique_id = ha->instance;
host->max_cmd_len = MAX_CMDSZ;
host->max_channel = MAX_BUSES - 1;
host->max_lun = MAX_LUNS;
@@ -1748,12 +1736,12 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
ha->flags.init_done = 1;
ha->flags.online = 1;
num_hosts++;
ret = scsi_add_host(host, &pdev->dev);
if (ret)
goto probe_failed;
ha->isp_ops->enable_intrs(ha);
scsi_scan_host(host);
qla2x00_alloc_sysfs_attr(ha);
@@ -1786,24 +1774,47 @@ probe_out:
return ret;
}
static void
qla2x00_stop_dpc_thread(scsi_qla_host_t *ha)
{
struct task_struct *t = NULL;
spin_lock_irq(&ha->dpc_lock);
if (ha->dpc_thread != NULL) {
t = ha->dpc_thread;
/*
* qla2xxx_wake_dpc checks for ->dpc_thread
* so we need to zero it out.
*/
ha->dpc_thread = NULL;
}
spin_unlock_irq(&ha->dpc_lock);
if (t != NULL)
kthread_stop(t);
}
static void
qla2x00_remove_one(struct pci_dev *pdev)
{
scsi_qla_host_t *ha, *vha, *temp;
scsi_qla_host_t *ha;
ha = pci_get_drvdata(pdev);
list_for_each_entry_safe(vha, temp, &ha->vp_list, vp_list)
fc_vport_terminate(vha->fc_vport);
set_bit(UNLOADING, &ha->dpc_flags);
#if defined(CONFIG_SCSI_QLA2XXX_TARGET)
ha->flags.host_shutting_down = 1;
if (qla_target.tgt_host_action != NULL)
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
{
unsigned long flags;
spin_lock_irqsave(&ha->hardware_lock, flags);
ha->host_shutting_down = 1;
spin_unlock_irqrestore(&ha->hardware_lock, flags);
}
if (qla_target.tgt_host_action != NULL)
qla_target.tgt_host_action(ha, DISABLE_TARGET_MODE);
#endif
/* Necessary to prevent races with it */
qla2x00_stop_dpc_thread(ha);
qla2x00_dfs_remove(ha);
qla84xx_put_chip(ha);
@@ -1822,26 +1833,6 @@ qla2x00_remove_one(struct pci_dev *pdev)
pci_set_drvdata(pdev, NULL);
}
static void
qla2x00_stop_dpc_thread(scsi_qla_host_t *ha)
{
struct task_struct *t = NULL;
spin_lock_irq(&ha->dpc_lock);
if (ha->dpc_thread != NULL) {
t = ha->dpc_thread;
/*
* qla2xxx_wake_dpc checks for ->dpc_thread
* so we need to zero it out.
*/
ha->dpc_thread = NULL;
}
spin_unlock_irq(&ha->dpc_lock);
if (t != NULL)
kthread_stop(t);
}
static void
qla2x00_free_device(scsi_qla_host_t *ha)
{
@@ -1883,22 +1874,31 @@ static inline void
qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport,
int defer)
{
unsigned long flags;
struct fc_rport *rport;
scsi_qla_host_t *pha = to_qla_parent(ha);
if (!fcport->rport)
return;
rport = fcport->rport;
if (defer) {
unsigned long flags;
spin_lock_irqsave(ha->host->host_lock, flags);
spin_lock_irqsave(&fcport->rport_lock, flags);
fcport->drport = rport;
spin_unlock_irqrestore(ha->host->host_lock, flags);
set_bit(FCPORT_UPDATE_NEEDED, &pha->dpc_flags);
qla2xxx_wake_dpc(pha);
} else
fcport->rport = NULL;
*(fc_port_t **)rport->dd_data = NULL;
spin_unlock_irqrestore(&fcport->rport_lock, flags);
set_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags);
} else {
spin_lock_irqsave(&fcport->rport_lock, flags);
fcport->rport = NULL;
*(fc_port_t **)rport->dd_data = NULL;
spin_unlock_irqrestore(&fcport->rport_lock, flags);
fc_remote_port_delete(rport);
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
if (qla_target.tgt_fc_port_deleted)
qla_target.tgt_fc_port_deleted(ha, fcport);
#endif
}
}
/*
@@ -1968,18 +1968,27 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer)
scsi_qla_host_t *pha = to_qla_parent(ha);
list_for_each_entry_rcu(fcport, &pha->fcports, list) {
if (ha->vp_idx != fcport->vp_idx)
#ifndef CONFIG_SCSI_QLA2XXX_TARGET
if (ha->vp_idx != 0 && ha->vp_idx != fcport->vp_idx)
continue;
#endif
/*
* No point in marking the device as lost, if the device is
* already DEAD.
*/
if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)
continue;
if (atomic_read(&fcport->state) == FCS_ONLINE)
qla2x00_schedule_rport_del(ha, fcport, defer);
if (atomic_read(&fcport->state) == FCS_ONLINE) {
if (defer)
qla2x00_schedule_rport_del(ha, fcport, defer);
else if (ha->vp_idx == fcport->vp_idx)
qla2x00_schedule_rport_del(ha, fcport, defer);
}
atomic_set(&fcport->state, FCS_DEVICE_LOST);
}
if (defer)
qla2xxx_wake_dpc(ha);
}
/*
@@ -2007,10 +2016,20 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha)
if (!ha->response_ring)
goto fail_free_request_ring;
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
if (IS_FWI2_CAPABLE(ha)) {
ha->atio_ring = dma_alloc_coherent(&ha->pdev->dev,
(ha->atio_q_length + 1) * sizeof(atio_t),
&ha->atio_dma, GFP_KERNEL);
if (ha->atio_ring == NULL)
goto fail_free_response_ring;
}
#endif
ha->gid_list = dma_alloc_coherent(&ha->pdev->dev, GID_LIST_SIZE,
&ha->gid_list_dma, GFP_KERNEL);
if (!ha->gid_list)
goto fail_free_response_ring;
goto fail_free_atio_ring;
ha->init_cb = dma_alloc_coherent(&ha->pdev->dev, ha->init_cb_size,
&ha->init_cb_dma, GFP_KERNEL);
@@ -2079,7 +2098,14 @@ fail_free_gid_list:
ha->gid_list_dma);
ha->gid_list = NULL;
ha->gid_list_dma = 0;
fail_free_atio_ring:
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
dma_free_coherent(&ha->pdev->dev, (ha->atio_q_length + 1) *
sizeof(response_t), ha->atio_ring, ha->atio_dma);
ha->atio_ring = NULL;
ha->atio_dma = 0;
fail_free_response_ring:
#endif
dma_free_coherent(&ha->pdev->dev, (ha->response_q_length + 1) *
sizeof(response_t), ha->response_ring, ha->response_dma);
ha->response_ring = NULL;
@@ -2145,6 +2171,13 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list,
ha->gid_list_dma);
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
if (ha->atio_ring)
dma_free_coherent(&ha->pdev->dev,
(ha->atio_q_length + 1) * sizeof(atio_t),
ha->atio_ring, ha->atio_dma);
#endif
if (ha->response_ring)
dma_free_coherent(&ha->pdev->dev,
(ha->response_q_length + 1) * sizeof(response_t),
@@ -2176,6 +2209,10 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
ha->response_dma = 0;
ha->request_ring = NULL;
ha->request_dma = 0;
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
ha->atio_ring = NULL;
ha->atio_dma = 0;
#endif
list_for_each_safe(fcpl, fcptemp, &ha->fcports) {
fcport = list_entry(fcpl, fc_port_t, list);
@@ -2214,7 +2251,7 @@ qla2x00_alloc_work(struct scsi_qla_host *ha, enum qla_work_type type,
static int
qla2x00_post_work(struct scsi_qla_host *ha, struct qla_work_evt *e, int locked)
{
unsigned long uninitialized_var(flags);
unsigned long flags = 0;
scsi_qla_host_t *pha = to_qla_parent(ha);
if (!locked)
@@ -2314,7 +2351,7 @@ qla2x00_do_dpc(void *data)
ha = (scsi_qla_host_t *)data;
set_user_nice(current, -20);
set_user_nice(current, -10);
while (!kthread_should_stop()) {
DEBUG3(printk("qla2x00: DPC handler sleeping\n"));
@@ -2371,10 +2408,8 @@ qla2x00_do_dpc(void *data)
ha->host_no));
}
if (test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags)) {
if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags))
qla2x00_update_fcports(ha);
clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags);
}
if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) &&
(!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) {
@@ -2487,13 +2522,10 @@ qla2x00_do_dpc(void *data)
void
qla2xxx_wake_dpc(scsi_qla_host_t *ha)
{
struct task_struct *t;
unsigned long flags;
spin_lock_irqsave(&ha->dpc_lock, flags);
t = ha->dpc_thread;
if (!test_bit(UNLOADING, &ha->dpc_flags) && t)
wake_up_process(t);
if (ha->dpc_thread)
wake_up_process(ha->dpc_thread);
spin_unlock_irqrestore(&ha->dpc_lock, flags);
}
@@ -2575,11 +2607,11 @@ qla2x00_timer(scsi_qla_host_t *ha)
*/
t = 0;
list_for_each_entry_rcu(fcport, &ha->fcports, list) {
#ifndef CONFIG_SCSI_QLA2XXX_TARGET
if (fcport->port_type != FCT_TARGET)
continue;
#endif
if (atomic_read(&fcport->state) == FCS_DEVICE_LOST) {
if (atomic_read(&fcport->port_down_timer) == 0)
continue;
@@ -2594,7 +2626,6 @@ qla2x00_timer(scsi_qla_host_t *ha)
t++;
} /* End of for fcport */
/* Loop down handler. */
if (atomic_read(&ha->loop_down_timer) > 0 &&
!(test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags)) && ha->flags.online) {
@@ -2905,6 +2936,25 @@ qla2x00_module_init(void)
{
int ret = 0;
#if defined(QL_DEBUG_LEVEL_1) || \
defined(QL_DEBUG_LEVEL_2) || \
defined(QL_DEBUG_LEVEL_3) || \
defined(QL_DEBUG_LEVEL_4) || \
defined(QL_DEBUG_LEVEL_5) || \
defined(QL_DEBUG_LEVEL_6) || \
defined(QL_DEBUG_LEVEL_7) || \
defined(QL_DEBUG_LEVEL_8) || \
defined(QL_DEBUG_LEVEL_9) || \
defined(QL_DEBUG_LEVEL_10) || \
defined(QL_DEBUG_LEVEL_11) || \
defined(QL_DEBUG_LEVEL_12) || \
defined(QL_DEBUG_LEVEL_13) || \
defined(QL_DEBUG_LEVEL_14) || \
defined(QL_DEBUG_LEVEL_15) || \
defined(QL_DEBUG_LEVEL_16)
ql2xextended_error_logging = 1;
#endif
/* Allocate cache for SRBs. */
srb_cachep = kmem_cache_create("qla2xxx_srbs", sizeof(srb_t), 0,
SLAB_HWCACHE_ALIGN, NULL);
@@ -2961,8 +3011,8 @@ module_init(qla2x00_module_init);
module_exit(qla2x00_module_exit);
MODULE_AUTHOR("QLogic Corporation");
#if defined(CONFIG_SCSI_QLA2XXX_TARGET)
MODULE_DESCRIPTION("QLogic Fibre Channel HBA Driver (Target Support)");
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
MODULE_DESCRIPTION("QLogic Fibre Channel HBA Driver (Target Mode Support, including 24xx+ ISP)");
#else
MODULE_DESCRIPTION("QLogic Fibre Channel HBA Driver");
#endif
+3 -45
View File
@@ -869,9 +869,11 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
uint32_t i;
uint32_t *dwptr;
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
unsigned long flags;
ret = QLA_SUCCESS;
spin_lock_irqsave(&ha->hardware_lock, flags);
/* Enable flash write. */
WRT_REG_DWORD(&reg->ctrl_status,
RD_REG_DWORD(&reg->ctrl_status) | CSRX_FLASH_ENABLE);
@@ -905,6 +907,7 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
WRT_REG_DWORD(&reg->ctrl_status,
RD_REG_DWORD(&reg->ctrl_status) & ~CSRX_FLASH_ENABLE);
RD_REG_DWORD(&reg->ctrl_status); /* PCI Posting. */
spin_unlock_irqrestore(&ha->hardware_lock, flags);
return ret;
}
@@ -2302,51 +2305,6 @@ qla24xx_get_flash_version(scsi_qla_host_t *ha, void *mbuf)
return ret;
}
static int
qla2xxx_is_vpd_valid(uint8_t *pos, uint8_t *end)
{
if (pos >= end || *pos != 0x82)
return 0;
pos += 3 + pos[1];
if (pos >= end || *pos != 0x90)
return 0;
pos += 3 + pos[1];
if (pos >= end || *pos != 0x78)
return 0;
return 1;
}
int
qla2xxx_get_vpd_field(scsi_qla_host_t *ha, char *key, char *str, size_t size)
{
uint8_t *pos = ha->vpd;
uint8_t *end = pos + ha->vpd_size;
int len = 0;
if (!IS_FWI2_CAPABLE(ha) || !qla2xxx_is_vpd_valid(pos, end))
return 0;
while (pos < end && *pos != 0x78) {
len = (*pos == 0x82) ? pos[1] : pos[2];
if (!strncmp(pos, key, strlen(key)))
break;
if (*pos != 0x90 && *pos != 0x91)
pos += len;
pos += 3;
}
if (pos < end - len && *pos != 0x78)
return snprintf(str, size, "%.*s", len, pos + 3);
return 0;
}
static int
qla2xxx_hw_event_store(scsi_qla_host_t *ha, uint32_t *fdata)
{
+1 -1
View File
@@ -7,7 +7,7 @@
/*
* Driver version
*/
#define QLA2XXX_VERSION "8.02.01-k7"
#define QLA2XXX_VERSION "8.02.01-k4"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 2
+1 -1
View File
@@ -35,7 +35,7 @@
<h1>Target Drivers</h1>
<ul class="sidemenu">
<li><a href="target_iscsi.html">iSCSI-SCST</a></li>
<li><a href="target_qla22xx_23xx.html">QLogic FC 22xx/23xx</a></li>
<li><a href="target_qla2x00t.html">QLogic FC QLA2X00T</a></li>
<li><a href="target_qla_isp.html">QLogic FC ISP</a></li>
<li><a href="target_srp.html">SCSI RDMA Protocol (SRP)</a></li>
<li><a href="target_mvsas.html">Marvell SAS adapters</a></li>
+2 -2
View File
@@ -59,8 +59,8 @@
SCST core performs all required pre- and post- processing of incoming requests as well as
necessary error recovery.</span></li>
<li><span>SCST core undertakes most problems, related to execution contexts, thus practically eliminating one of the most
complicated problem in the kernel drivers development. For example, target drivers for QLogic
22xx/23xx adapters and for InfiniBand SRP are only about 2300 lines of code long.</span></li>
complicated problem in the kernel drivers development. For example, target drivers for Marvell
SAS adapters or for InfiniBand SRP are less 3000 lines of code long.</span></li>
<li><span>Very low overhead, fine-grained locks and simplest commands processing path allow to reach
maximum possible performance and scalability. Particularly, incoming requests can be processed in
the caller's context or in one of the internal SCST core's tasklets without any
+1 -1
View File
@@ -35,7 +35,7 @@
<h1>Target Drivers</h1>
<ul class="sidemenu">
<li><a href="target_iscsi.html">iSCSI-SCST</a></li>
<li><a href="target_qla22xx_23xx.html">QLogic FC 22xx/23xx</a></li>
<li><a href="target_qla2x00t.html">QLogic FC QLA2X00T</a></li>
<li><a href="target_qla_isp.html">QLogic FC ISP</a></li>
<li><a href="target_srp.html">SCSI RDMA Protocol (SRP)</a></li>
<li><a href="target_mvsas.html">Marvell SAS adapters</a></li>
+2173 -1093
View File
File diff suppressed because it is too large Load Diff
+416 -416
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -35,7 +35,7 @@
<h1>Target Drivers</h1>
<ul class="sidemenu">
<li><a href="target_iscsi.html">iSCSI-SCST</a></li>
<li><a href="target_qla22xx_23xx.html">QLogic FC 22xx/23xx</a></li>
<li><a href="target_qla2x00t.html">QLogic FC QLA2X00T</a></li>
<li><a href="target_qla_isp.html">QLogic FC ISP</a></li>
<li><a href="target_srp.html">SCSI RDMA Protocol (SRP)</a></li>
<li><a href="target_mvsas.html">Marvell SAS adapters</a></li>
+1 -1
View File
@@ -35,7 +35,7 @@
<h1>Target Drivers</h1>
<ul class="sidemenu">
<li><a href="target_iscsi.html">iSCSI-SCST</a></li>
<li><a href="target_qla22xx_23xx.html">QLogic FC 22xx/23xx</a></li>
<li><a href="target_qla2x00t.html">QLogic FC QLA2X00T</a></li>
<li><a href="target_qla_isp.html">QLogic FC ISP</a></li>
<li><a href="target_srp.html">SCSI RDMA Protocol (SRP)</a></li>
<li><a href="target_mvsas.html">Marvell SAS adapters</a></li>
+1 -1
View File
@@ -35,7 +35,7 @@
<h1>Target Drivers</h1>
<ul class="sidemenu">
<li><a href="target_iscsi.html">iSCSI-SCST</a></li>
<li><a href="target_qla22xx_23xx.html">QLogic FC 22xx/23xx</a></li>
<li><a href="target_qla2x00t.html">QLogic FC QLA2X00T</a></li>
<li><a href="target_qla_isp.html">QLogic FC ISP</a></li>
<li><a href="target_srp.html">SCSI RDMA Protocol (SRP)</a></li>
<li><a href="target_mvsas.html">Marvell SAS adapters</a></li>
+1 -1
View File
@@ -35,7 +35,7 @@
<h1>Target Drivers</h1>
<ul class="sidemenu">
<li><a href="target_iscsi.html">iSCSI-SCST</a></li>
<li><a href="target_qla22xx_23xx.html">QLogic FC 22xx/23xx</a></li>
<li><a href="target_qla2x00t.html">QLogic FC QLA2X00T</a></li>
<li><a href="target_qla_isp.html">QLogic FC ISP</a></li>
<li><a href="target_srp.html">SCSI RDMA Protocol (SRP)</a></li>
<li><a href="target_mvsas.html">Marvell SAS adapters</a></li>
+1 -1
View File
@@ -35,7 +35,7 @@
<h1>Target Drivers</h1>
<ul class="sidemenu">
<li><a href="target_iscsi.html">iSCSI-SCST</a></li>
<li><a href="target_qla22xx_23xx.html">QLogic FC 22xx/23xx</a></li>
<li><a href="target_qla2x00t.html">QLogic FC QLA2X00T</a></li>
<li><a href="target_qla_isp.html">QLogic FC ISP</a></li>
<li><a href="target_srp.html">SCSI RDMA Protocol (SRP)</a></li>
<li><a href="target_mvsas.html">Marvell SAS adapters</a></li>
+1 -1
View File
@@ -35,7 +35,7 @@
<h1>Target Drivers</h1>
<ul class="sidemenu">
<li><a href="target_iscsi.html">iSCSI-SCST</a></li>
<li><a href="target_qla22xx_23xx.html">QLogic FC 22xx/23xx</a></li>
<li><a href="target_qla2x00t.html">QLogic FC QLA2X00T</a></li>
<li><a href="target_qla_isp.html">QLogic FC ISP</a></li>
<li><a href="target_srp.html">SCSI RDMA Protocol (SRP)</a></li>
<li><a href="target_mvsas.html">Marvell SAS adapters</a></li>
+3 -3
View File
@@ -35,7 +35,7 @@
<h1>Target Drivers</h1>
<ul class="sidemenu">
<li><a href="target_iscsi.html">iSCSI-SCST</a></li>
<li><a href="target_qla22xx_23xx.html">QLogic FC 22xx/23xx</a></li>
<li><a href="target_qla2x00t.html">QLogic FC QLA2X00T</a></li>
<li><a href="target_qla_isp.html">QLogic FC ISP</a></li>
<li><a href="target_srp.html">SCSI RDMA Protocol (SRP)</a></li>
<li><a href="target_mvsas.html">Marvell SAS adapters</a></li>
@@ -53,9 +53,9 @@
</div>
<div id="main">
<h1>Old target driver for QLogic 22xx/23xx adapters for 2.4 kernels</h1>
<h1>Old target driver for QLogic qla2x00t adapters for 2.4 kernels</h1>
<p><img src="images/t_unsupported.gif" width="100" height="120" class="float-left" />
Old target driver for QLogic 22xx/23xx adapters is capable to work on 2.4 kernels.
Old target driver for QLogic qla2x00t adapters is capable to work on 2.4 kernels.
It has all required features and looks to be quite stable. It is designed to work in conjunction with the
initiator driver, which is intended to perform all the initialization and shutdown tasks. In the current release as
a base for the initiator driver was taken Red Hat's driver from the stock 2.4.20 kernel. Then it was patched to
@@ -35,7 +35,7 @@
<h1>Target Drivers</h1>
<ul class="sidemenu">
<li><a href="target_iscsi.html">iSCSI-SCST</a></li>
<li><a href="target_qla22xx_23xx.html">QLogic FC 22xx/23xx</a></li>
<li><a href="target_qla2x00t.html">QLogic FC QLA2X00T</a></li>
<li><a href="target_qla_isp.html">QLogic FC ISP</a></li>
<li><a href="target_srp.html">SCSI RDMA Protocol (SRP)</a></li>
<li><a href="target_mvsas.html">Marvell SAS adapters</a></li>
@@ -53,16 +53,22 @@
</div>
<div id="main">
<h1>Target driver for QLogic 22xx/23xx adapters</h1>
<h1>Target driver qla2x00t for QLogic FC adapters</h1>
<p><img src="images/t_qlogic.gif" width="100" height="120" class="float-left" />
This is target driver for QLogic 22xx/23xx (qla2200/qla2300) Fibre Channel adapters. It is stable and well tested.</p>
This is target driver for QLogic qla2xxx (qla22xx/qla23xx) Fibre Channel adapters. It is stable and well tested.</p>
<p>The latest stable version is 1.0.1.1. Requires Linux kernel version 2.6.16.x or higher and
SCST version 1.0.1.1 or higher.</p>
<p>You can find the latest development version of this driver in the SCST SVN. See the download page how to setup
<p>The latest development version is 2.0.0. It additionally has support for 24xx/25xx (4/8 Gbps) adapters
as well as several other important improvements, thanks to <a href="http://www.id-7.com/">ID7</a>.
Requires Linux kernel version 2.6.16.x or higher and SCST version 1.0.2 or higher.
You can download it from SCST SVN repository. See the download page how to setup
access to it.</p>
<p>This driver is mainline Linux kernel ready and after cosmetic cleanups going to be pushed to it
together with other SCST patches.</p>
<p class="post-footer align-right">
<a href="qla2x00t-howto.html" class="readmore">HOWTO</a>
<a href="downloads.html" class="readmore">Download</a>
+4 -4
View File
@@ -35,7 +35,7 @@
<h1>Target Drivers</h1>
<ul class="sidemenu">
<li><a href="target_iscsi.html">iSCSI-SCST</a></li>
<li><a href="target_qla22xx_23xx.html">QLogic FC 22xx/23xx</a></li>
<li><a href="target_qla2x00t.html">QLogic FC QLA2X00T</a></li>
<li><a href="target_qla_isp.html">QLogic FC ISP</a></li>
<li><a href="target_srp.html">SCSI RDMA Protocol (SRP)</a></li>
<li><a href="target_mvsas.html">Marvell SAS adapters</a></li>
@@ -61,9 +61,9 @@
<a href="http://www.feral.com/isp.html">http://www.feral.com/isp.html</a>. The update for SCST was made by
Stanislaw Gruszka for Open-E Inc.</p>
<p>This driver operates on the same hardware as the qla2x00t target driver, but has one notable
advantage over it: <strong>support of 24xx (4Gbps) and 25xx (8Gbps) series of QLogic adapters</strong>.
From other side, qla2x00t is simpler, smaller and much better tested on 22xx and 23xx, hence perform more
<p>This driver operates on the same hardware as the qla2x00t target driver, but, comparing to version 1.0.1.1
of it, has two notable advantages: support of 24xx (4Gbps) and 25xx (8Gbps) series of QLogic adapters as well
as NPIV support. From other side, qla2x00t is simpler, smaller and much better tested on 22xx and 23xx, hence perform more
reliable and, thus, is recommended for these adapters.</p>
<p>The latest release is 1.0.1. It does not support 25xx chipsets yet and can be compiled with Linux
+1 -1
View File
@@ -35,7 +35,7 @@
<h1>Target Drivers</h1>
<ul class="sidemenu">
<li><a href="target_iscsi.html">iSCSI-SCST</a></li>
<li><a href="target_qla22xx_23xx.html">QLogic FC 22xx/23xx</a></li>
<li><a href="target_qla2x00t.html">QLogic FC QLA2X00T</a></li>
<li><a href="target_qla_isp.html">QLogic FC ISP</a></li>
<li><a href="target_srp.html">SCSI RDMA Protocol (SRP)</a></li>
<li><a href="target_mvsas.html">Marvell SAS adapters</a></li>
+2 -3
View File
@@ -35,7 +35,7 @@
<h1>Target Drivers</h1>
<ul class="sidemenu">
<li><a href="target_iscsi.html">iSCSI-SCST</a></li>
<li><a href="target_qla22xx_23xx.html">QLogic FC 22xx/23xx</a></li>
<li><a href="target_qla2x00t.html">QLogic FC QLA2X00T</a></li>
<li><a href="target_qla_isp.html">QLogic FC ISP</a></li>
<li><a href="target_srp.html">SCSI RDMA Protocol (SRP)</a></li>
<li><a href="target_mvsas.html">Marvell SAS adapters</a></li>
@@ -58,8 +58,7 @@
<p>SCST has target drivers for:
<ul>
<li><span>Software iSCSI</span></li>
<li><span>Fibre Channel QLogic 22xx/23xx series</span></li>
<li><span>Fibre Channel QLogic ISP Chipsets, including 24xx and 25xx</span></li>
<li><span>Fibre Channel QLogic qla2x00 series (2 drivers)</span></li>
<li><span>Infiniband SCSI RDMA Protocol (SRP)</span></li>
<li><span>Marvell SAS adapters</span></li>
<li><span>Emulex lpfc FC/FCoE adapters</span></li>