Update of the initiator driver to one from kernel 2.6.26. Sorry, the prior kernels not supported anymore, but backport patches are welcome.

git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@473 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2008-07-23 17:41:22 +00:00
parent 84153b23b5
commit c006b05884
35 changed files with 8191 additions and 46262 deletions
+4 -46
View File
@@ -16,7 +16,8 @@ config SCSI_QLA_FC
22xx ql2200_fw.bin
2300, 2312, 6312 ql2300_fw.bin
2322, 6322 ql2322_fw.bin
24xx ql2400_fw.bin
24xx, 54xx ql2400_fw.bin
25xx ql2500_fw.bin
Upon request, the driver caches the firmware image until
the driver is unloaded.
@@ -25,10 +26,6 @@ config SCSI_QLA_FC
ftp://ftp.qlogic.com/outgoing/linux/firmware/
NOTE: The original method of building firmware-loader
modules has been deprecated as the firmware-images will
be removed from the kernel sources.
config SCSI_QLA2XXX_TARGET
bool "QLogic 2xxx target mode support"
depends on SCSI_QLA_FC
@@ -38,45 +35,6 @@ config SCSI_QLA2XXX_TARGET
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_EMBEDDED_FIRMWARE
bool "Use firmware-loader modules (DEPRECATED)"
depends on SCSI_QLA_FC
help
This option offers you the deprecated firmware-loader
modules that have been obsoleted by the usage of the
Firmware Loader interface in the qla2xxx driver.
config SCSI_QLA21XX
tristate "Build QLogic ISP2100 firmware-module"
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
---help---
This driver supports the QLogic 21xx (ISP2100) host adapter family.
config SCSI_QLA22XX
tristate "Build QLogic ISP2200 firmware-module"
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
---help---
This driver supports the QLogic 22xx (ISP2200) host adapter family.
config SCSI_QLA2300
tristate "Build QLogic ISP2300/ISP6312 firmware-module"
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
---help---
This driver supports the QLogic 2300 (ISP2300, ISP2312 and
ISP6312) host adapter family.
config SCSI_QLA2322
tristate "Build QLogic ISP2322/ISP6322 firmware-module"
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
---help---
This driver supports the QLogic 2322 (ISP2322 and ISP6322) host
adapter family.
config SCSI_QLA24XX
tristate "Build QLogic ISP24xx firmware-module"
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
---help---
This driver supports the QLogic 24xx (ISP2422 and ISP2432) host
adapter family.
You will also need to download SCST SCSI middle level drivers from
http://scst.sf.net.
+1 -14
View File
@@ -1,23 +1,10 @@
ifneq ($(KERNELRELEASE),)
EXTRA_CFLAGS += -DUNIQUE_FW_NAME
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_rscn.o qla_attr.o
qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o
obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o
qla2100-y := ql2100.o ql2100_fw.o
qla2200-y := ql2200.o ql2200_fw.o
qla2300-y := ql2300.o ql2300_fw.o
qla2322-y := ql2322.o ql2322_fw.o
qla2400-y := ql2400.o ql2400_fw.o
obj-$(CONFIG_SCSI_QLA21XX) += qla2xxx.o qla2100.o
obj-$(CONFIG_SCSI_QLA22XX) += qla2xxx.o qla2200.o
obj-$(CONFIG_SCSI_QLA2300) += qla2xxx.o qla2300.o
obj-$(CONFIG_SCSI_QLA2322) += qla2xxx.o qla2322.o
obj-$(CONFIG_SCSI_QLA24XX) += qla2xxx.o qla2400.o
else
ifeq ($(KVER),)
ifeq ($(KDIR),)
-91
View File
@@ -1,91 +0,0 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (C) 2003 Christoph Hellwig.
* Copyright (c) 2003-2005 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
#include "qla_def.h"
static char qla_driver_name[] = "qla2100";
extern unsigned char fw2100tp_version[];
extern unsigned char fw2100tp_version_str[];
extern unsigned short fw2100tp_addr01;
extern unsigned short fw2100tp_code01[];
extern unsigned short fw2100tp_length01;
static struct qla_fw_info qla_fw_tbl[] = {
{
.addressing = FW_INFO_ADDR_NORMAL,
.fwcode = &fw2100tp_code01[0],
.fwlen = &fw2100tp_length01,
.fwstart = &fw2100tp_addr01,
},
{ FW_INFO_ADDR_NOMORE, },
};
static struct qla_board_info qla_board_tbl = {
.drv_name = qla_driver_name,
.isp_name = "ISP2100",
.fw_info = qla_fw_tbl,
};
static struct pci_device_id qla2100_pci_tbl[] = {
{
.vendor = PCI_VENDOR_ID_QLOGIC,
.device = PCI_DEVICE_ID_QLOGIC_ISP2100,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = (unsigned long)&qla_board_tbl,
},
{0, 0},
};
MODULE_DEVICE_TABLE(pci, qla2100_pci_tbl);
static int __devinit
qla2100_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
return qla2x00_probe_one(pdev,
(struct qla_board_info *)id->driver_data);
}
static void __devexit
qla2100_remove_one(struct pci_dev *pdev)
{
qla2x00_remove_one(pdev);
}
static struct pci_driver qla2100_pci_driver = {
.name = "qla2100",
.id_table = qla2100_pci_tbl,
.probe = qla2100_probe_one,
.remove = __devexit_p(qla2100_remove_one),
};
static int __init
qla2100_init(void)
{
return pci_register_driver(&qla2100_pci_driver);
}
static void __exit
qla2100_exit(void)
{
pci_unregister_driver(&qla2100_pci_driver);
}
module_init(qla2100_init);
module_exit(qla2100_exit);
MODULE_AUTHOR("QLogic Corporation");
MODULE_DESCRIPTION("QLogic ISP21xx FC-SCSI Host Bus Adapter driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(QLA2XXX_VERSION);
-4848
View File
File diff suppressed because it is too large Load Diff
-91
View File
@@ -1,91 +0,0 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (C) 2003 Christoph Hellwig.
* Copyright (c) 2003-2005 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
#include "qla_def.h"
static char qla_driver_name[] = "qla2200";
extern unsigned char fw2200tp_version[];
extern unsigned char fw2200tp_version_str[];
extern unsigned short fw2200tp_addr01;
extern unsigned short fw2200tp_code01[];
extern unsigned short fw2200tp_length01;
static struct qla_fw_info qla_fw_tbl[] = {
{
.addressing = FW_INFO_ADDR_NORMAL,
.fwcode = &fw2200tp_code01[0],
.fwlen = &fw2200tp_length01,
.fwstart = &fw2200tp_addr01,
},
{ FW_INFO_ADDR_NOMORE, },
};
static struct qla_board_info qla_board_tbl = {
.drv_name = qla_driver_name,
.isp_name = "ISP2200",
.fw_info = qla_fw_tbl,
};
static struct pci_device_id qla2200_pci_tbl[] = {
{
.vendor = PCI_VENDOR_ID_QLOGIC,
.device = PCI_DEVICE_ID_QLOGIC_ISP2200,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = (unsigned long)&qla_board_tbl,
},
{0, 0},
};
MODULE_DEVICE_TABLE(pci, qla2200_pci_tbl);
static int __devinit
qla2200_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
return qla2x00_probe_one(pdev,
(struct qla_board_info *)id->driver_data);
}
static void __devexit
qla2200_remove_one(struct pci_dev *pdev)
{
qla2x00_remove_one(pdev);
}
static struct pci_driver qla2200_pci_driver = {
.name = "qla2200",
.id_table = qla2200_pci_tbl,
.probe = qla2200_probe_one,
.remove = __devexit_p(qla2200_remove_one),
};
static int __init
qla2200_init(void)
{
return pci_register_driver(&qla2200_pci_driver);
}
static void __exit
qla2200_exit(void)
{
pci_unregister_driver(&qla2200_pci_driver);
}
module_init(qla2200_init);
module_exit(qla2200_exit);
MODULE_AUTHOR("QLogic Corporation");
MODULE_DESCRIPTION("QLogic ISP22xx FC-SCSI Host Bus Adapter driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(QLA2XXX_VERSION);
-5333
View File
File diff suppressed because it is too large Load Diff
-114
View File
@@ -1,114 +0,0 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (C) 2003 Christoph Hellwig.
* Copyright (c) 2003-2005 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
#include "qla_def.h"
static char qla_driver_name[] = "qla2300";
extern unsigned char fw2300ipx_version[];
extern unsigned char fw2300ipx_version_str[];
extern unsigned short fw2300ipx_addr01;
extern unsigned short fw2300ipx_code01[];
extern unsigned short fw2300ipx_length01;
static struct qla_fw_info qla_fw_tbl[] = {
{
.addressing = FW_INFO_ADDR_NORMAL,
.fwcode = &fw2300ipx_code01[0],
.fwlen = &fw2300ipx_length01,
.fwstart = &fw2300ipx_addr01,
},
{ FW_INFO_ADDR_NOMORE, },
};
static struct qla_board_info qla_board_tbl[] = {
{
.drv_name = qla_driver_name,
.isp_name = "ISP2300",
.fw_info = qla_fw_tbl,
},
{
.drv_name = qla_driver_name,
.isp_name = "ISP2312",
.fw_info = qla_fw_tbl,
},
{
.drv_name = qla_driver_name,
.isp_name = "ISP6312",
.fw_info = qla_fw_tbl,
},
};
static struct pci_device_id qla2300_pci_tbl[] = {
{
.vendor = PCI_VENDOR_ID_QLOGIC,
.device = PCI_DEVICE_ID_QLOGIC_ISP2300,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = (unsigned long)&qla_board_tbl[0],
},
{
.vendor = PCI_VENDOR_ID_QLOGIC,
.device = PCI_DEVICE_ID_QLOGIC_ISP2312,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = (unsigned long)&qla_board_tbl[1],
},
{
.vendor = PCI_VENDOR_ID_QLOGIC,
.device = PCI_DEVICE_ID_QLOGIC_ISP6312,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = (unsigned long)&qla_board_tbl[2],
},
{0, 0},
};
MODULE_DEVICE_TABLE(pci, qla2300_pci_tbl);
static int __devinit
qla2300_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
return qla2x00_probe_one(pdev,
(struct qla_board_info *)id->driver_data);
}
static void __devexit
qla2300_remove_one(struct pci_dev *pdev)
{
qla2x00_remove_one(pdev);
}
static struct pci_driver qla2300_pci_driver = {
.name = "qla2300",
.id_table = qla2300_pci_tbl,
.probe = qla2300_probe_one,
.remove = __devexit_p(qla2300_remove_one),
};
static int __init
qla2300_init(void)
{
return pci_register_driver(&qla2300_pci_driver);
}
static void __exit
qla2300_exit(void)
{
pci_unregister_driver(&qla2300_pci_driver);
}
module_init(qla2300_init);
module_exit(qla2300_exit);
MODULE_AUTHOR("QLogic Corporation");
MODULE_DESCRIPTION("QLogic ISP23xx FC-SCSI Host Bus Adapter driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(QLA2XXX_VERSION);
-7746
View File
File diff suppressed because it is too large Load Diff
-119
View File
@@ -1,119 +0,0 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2005 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
#include "qla_def.h"
static char qla_driver_name[] = "qla2322";
extern unsigned char fw2322ipx_version[];
extern unsigned char fw2322ipx_version_str[];
extern unsigned short fw2322ipx_addr01;
extern unsigned short fw2322ipx_code01[];
extern unsigned short fw2322ipx_length01;
extern unsigned long rseqipx_code_addr01;
extern unsigned short rseqipx_code01[];
extern unsigned short rseqipx_code_length01;
extern unsigned long xseqipx_code_addr01;
extern unsigned short xseqipx_code01[];
extern unsigned short xseqipx_code_length01;
static struct qla_fw_info qla_fw_tbl[] = {
{
.addressing = FW_INFO_ADDR_NORMAL,
.fwcode = &fw2322ipx_code01[0],
.fwlen = &fw2322ipx_length01,
.fwstart = &fw2322ipx_addr01,
},
{
.addressing = FW_INFO_ADDR_EXTENDED,
.fwcode = &rseqipx_code01[0],
.fwlen = &rseqipx_code_length01,
.lfwstart = &rseqipx_code_addr01,
},
{
.addressing = FW_INFO_ADDR_EXTENDED,
.fwcode = &xseqipx_code01[0],
.fwlen = &xseqipx_code_length01,
.lfwstart = &xseqipx_code_addr01,
},
{ FW_INFO_ADDR_NOMORE, },
};
static struct qla_board_info qla_board_tbl[] = {
{
.drv_name = qla_driver_name,
.isp_name = "ISP2322",
.fw_info = qla_fw_tbl,
},
{
.drv_name = qla_driver_name,
.isp_name = "ISP6322",
.fw_info = qla_fw_tbl,
},
};
static struct pci_device_id qla2322_pci_tbl[] = {
{
.vendor = PCI_VENDOR_ID_QLOGIC,
.device = PCI_DEVICE_ID_QLOGIC_ISP2322,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = (unsigned long)&qla_board_tbl[0],
},
{
.vendor = PCI_VENDOR_ID_QLOGIC,
.device = PCI_DEVICE_ID_QLOGIC_ISP6322,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = (unsigned long)&qla_board_tbl[1],
},
{0, 0},
};
MODULE_DEVICE_TABLE(pci, qla2322_pci_tbl);
static int __devinit
qla2322_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
return qla2x00_probe_one(pdev,
(struct qla_board_info *)id->driver_data);
}
static void __devexit
qla2322_remove_one(struct pci_dev *pdev)
{
qla2x00_remove_one(pdev);
}
static struct pci_driver qla2322_pci_driver = {
.name = "qla2322",
.id_table = qla2322_pci_tbl,
.probe = qla2322_probe_one,
.remove = __devexit_p(qla2322_remove_one),
};
static int __init
qla2322_init(void)
{
return pci_register_driver(&qla2322_pci_driver);
}
static void __exit
qla2322_exit(void)
{
pci_unregister_driver(&qla2322_pci_driver);
}
module_init(qla2322_init);
module_exit(qla2322_exit);
MODULE_AUTHOR("QLogic Corporation");
MODULE_DESCRIPTION("QLogic ISP2322 FC-SCSI Host Bus Adapter driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(QLA2XXX_VERSION);
-8376
View File
File diff suppressed because it is too large Load Diff
-139
View File
@@ -1,139 +0,0 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2005 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
#include "qla_def.h"
static char qla_driver_name[] = "qla2400";
extern uint32_t fw2400_version_str[];
extern uint32_t fw2400_addr01;
extern uint32_t fw2400_code01[];
extern uint32_t fw2400_length01;
extern uint32_t fw2400_addr02;
extern uint32_t fw2400_code02[];
extern uint32_t fw2400_length02;
static struct qla_fw_info qla_fw_tbl[] = {
{
.addressing = FW_INFO_ADDR_EXTENDED,
.fwcode = (unsigned short *)&fw2400_code01[0],
.fwlen = (unsigned short *)&fw2400_length01,
.lfwstart = (unsigned long *)&fw2400_addr01,
},
{
.addressing = FW_INFO_ADDR_EXTENDED,
.fwcode = (unsigned short *)&fw2400_code02[0],
.fwlen = (unsigned short *)&fw2400_length02,
.lfwstart = (unsigned long *)&fw2400_addr02,
},
{ FW_INFO_ADDR_NOMORE, },
};
static struct qla_board_info qla_board_tbl[] = {
{
.drv_name = qla_driver_name,
.isp_name = "ISP2422",
.fw_info = qla_fw_tbl,
.fw_fname = "ql2400_fw.bin",
},
{
.drv_name = qla_driver_name,
.isp_name = "ISP2432",
.fw_info = qla_fw_tbl,
.fw_fname = "ql2400_fw.bin",
},
{
.drv_name = qla_driver_name,
.isp_name = "ISP5422",
.fw_info = qla_fw_tbl,
.fw_fname = "ql2400_fw.bin",
},
{
.drv_name = qla_driver_name,
.isp_name = "ISP5432",
.fw_info = qla_fw_tbl,
.fw_fname = "ql2400_fw.bin",
},
};
static struct pci_device_id qla24xx_pci_tbl[] = {
{
.vendor = PCI_VENDOR_ID_QLOGIC,
.device = PCI_DEVICE_ID_QLOGIC_ISP2422,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = (unsigned long)&qla_board_tbl[0],
},
{
.vendor = PCI_VENDOR_ID_QLOGIC,
.device = PCI_DEVICE_ID_QLOGIC_ISP2432,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = (unsigned long)&qla_board_tbl[1],
},
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
{
.vendor = PCI_VENDOR_ID_QLOGIC,
.device = PCI_DEVICE_ID_QLOGIC_ISP5422,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = (unsigned long)&qla_board_tbl[2],
},
{
.vendor = PCI_VENDOR_ID_QLOGIC,
.device = PCI_DEVICE_ID_QLOGIC_ISP5432,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = (unsigned long)&qla_board_tbl[3],
},
#endif
{0, 0},
};
MODULE_DEVICE_TABLE(pci, qla24xx_pci_tbl);
static int __devinit
qla24xx_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
return qla2x00_probe_one(pdev,
(struct qla_board_info *)id->driver_data);
}
static void __devexit
qla24xx_remove_one(struct pci_dev *pdev)
{
qla2x00_remove_one(pdev);
}
static struct pci_driver qla24xx_pci_driver = {
.name = "qla2400",
.id_table = qla24xx_pci_tbl,
.probe = qla24xx_probe_one,
.remove = __devexit_p(qla24xx_remove_one),
};
static int __init
qla24xx_init(void)
{
return pci_register_driver(&qla24xx_pci_driver);
}
static void __exit
qla24xx_exit(void)
{
pci_unregister_driver(&qla24xx_pci_driver);
}
module_init(qla24xx_init);
module_exit(qla24xx_exit);
MODULE_AUTHOR("QLogic Corporation");
MODULE_DESCRIPTION("QLogic ISP24xx FC-SCSI Host Bus Adapter driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(QLA2XXX_VERSION);
-12346
View File
File diff suppressed because it is too large Load Diff
+9 -4
View File
@@ -1,8 +1,8 @@
Target driver for Qlogic 2200/2300 Fibre Channel cards
======================================================
Version 1.0.1, X XXXX 2008
--------------------------
Version 1.0.1, XX XXXX 2008
---------------------------
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
@@ -14,9 +14,14 @@ 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.0 and higher and
Linux kernel 2.6.16 and higher.
Linux kernel 2.6.26 and higher. Backport patches to kernels earlier than
2.6.26 are welcome.
The original initiator driver was taken from the kernel 2.6.17.8.
The original initiator driver was taken from the kernel 2.6.26.
If you need to use this driver on kernels prior 2.6.26, it is
recommended to use version 1.0.0.x of this driver, taken from branch
1.0.0.x.
See also "ToDo" file for list of known issues and unimplemented
features.
+2 -2
View File
@@ -24,8 +24,8 @@
#ifndef __QLA2X_TGT_H
#define __QLA2X_TGT_H
#ifndef FC_TARGET_SUPPORT
#error __FILE__ " included without FC_TARGET_SUPPORT"
#ifndef CONFIG_SCSI_QLA2XXX_TARGET
#error __FILE__ " included without CONFIG_SCSI_QLA2XXX_TARGET"
#endif
#include "qla2x_tgt_def.h"
+11 -4
View File
@@ -27,8 +27,8 @@
#include "qla_def.h"
#ifndef FC_TARGET_SUPPORT
#error __FILE__ " included without FC_TARGET_SUPPORT"
#ifndef CONFIG_SCSI_QLA2XXX_TARGET
#error __FILE__ " included without CONFIG_SCSI_QLA2XXX_TARGET"
#endif
#ifndef ENTER
@@ -40,7 +40,7 @@
#endif
#define QLA2X_TARGET_MAGIC 153
#define QLA2X_INITIATOR_MAGIC 54205
#define QLA2X_INITIATOR_MAGIC 54207
#define QLA2X00_COMMAND_COUNT_INIT 250
#define QLA2X00_IMMED_NOTIFY_COUNT_INIT 250
@@ -326,6 +326,12 @@ typedef struct
}ctio_ret_entry_t;
#endif
enum nexus_wait_type {
WAIT_HOST = 0,
WAIT_TARGET,
WAIT_LUN,
};
/********************************************************************\
* Type Definitions used by initiator & target halves
\********************************************************************/
@@ -372,6 +378,7 @@ qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha);
int
qla2x00_wait_for_hba_online(scsi_qla_host_t *ha);
int
qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha);
qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha, unsigned int t,
unsigned int l, enum nexus_wait_type type);
#endif
+744 -358
View File
File diff suppressed because it is too large Load Diff
+956 -1765
View File
File diff suppressed because it is too large Load Diff
+142 -97
View File
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2005 QLogic Corporation
* Copyright (c) 2003-2008 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -21,150 +21,93 @@
/* #define QL_DEBUG_LEVEL_12 */ /* Output IP trace msgs */
/* #define QL_DEBUG_LEVEL_13 */ /* Output fdmi function trace msgs */
/* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */
/*
* Local Macro Definitions.
*/
#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)
#define QL_DEBUG_ROUTINES
#endif
/* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */
/* #define QL_DEBUG_LEVEL_16 */ /* Output ISP84XX trace msgs */
/*
* Macros use for debugging the driver.
*/
#undef ENTER_TRACE
#if defined(ENTER_TRACE)
#define ENTER(x) do { printk("qla2100 : Entering %s()\n", x); } while (0)
#define LEAVE(x) do { printk("qla2100 : Leaving %s()\n", x); } while (0)
#define ENTER_INTR(x) do { printk("qla2100 : Entering %s()\n", x); } while (0)
#define LEAVE_INTR(x) do { printk("qla2100 : Leaving %s()\n", x); } while (0)
#else
#define ENTER(x) do {} while (0)
#define LEAVE(x) do {} while (0)
#define ENTER_INTR(x) do {} while (0)
#define LEAVE_INTR(x) do {} while (0)
#endif
#if DEBUG_QLA2100
#define DEBUG(x) do {x;} while (0);
#else
#define DEBUG(x) do {} while (0);
#endif
#define DEBUG(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#if defined(QL_DEBUG_LEVEL_1)
#define DEBUG1(x) do {x;} while (0);
#define DEBUG1(x) do {x;} while (0)
#else
#define DEBUG1(x) do {} while (0);
#define DEBUG1(x) do {} while (0)
#endif
#if defined(QL_DEBUG_LEVEL_2)
#define DEBUG2(x) do {x;} while (0);
#define DEBUG2_3(x) do {x;} while (0);
#define DEBUG2_3_11(x) do {x;} while (0);
#define DEBUG2_9_10(x) do {x;} while (0);
#define DEBUG2_11(x) do {x;} while (0);
#define DEBUG2_13(x) do {x;} while (0);
#else
#define DEBUG2(x) do {} while (0);
#endif
#define DEBUG2(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#define DEBUG2_3(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#define DEBUG2_3_11(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#define DEBUG2_9_10(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#define DEBUG2_11(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#define DEBUG2_13(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#define DEBUG2_16(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#if defined(QL_DEBUG_LEVEL_3)
#define DEBUG3(x) do {x;} while (0);
#define DEBUG2_3(x) do {x;} while (0);
#define DEBUG2_3_11(x) do {x;} while (0);
#define DEBUG3_11(x) do {x;} while (0);
#define DEBUG3(x) do {x;} while (0)
#define DEBUG3_11(x) do {x;} while (0)
#else
#define DEBUG3(x) do {} while (0);
#if !defined(QL_DEBUG_LEVEL_2)
#define DEBUG2_3(x) do {} while (0);
#endif
#define DEBUG3(x) do {} while (0)
#endif
#if defined(QL_DEBUG_LEVEL_4)
#define DEBUG4(x) do {x;} while (0);
#define DEBUG4(x) do {x;} while (0)
#else
#define DEBUG4(x) do {} while (0);
#define DEBUG4(x) do {} while (0)
#endif
#if defined(QL_DEBUG_LEVEL_5)
#define DEBUG5(x) do {x;} while (0);
#define DEBUG5(x) do {x;} while (0)
#else
#define DEBUG5(x) do {} while (0);
#define DEBUG5(x) do {} while (0)
#endif
#if defined(QL_DEBUG_LEVEL_7)
#define DEBUG7(x) do {x;} while (0);
#define DEBUG7(x) do {x;} while (0)
#else
#define DEBUG7(x) do {} while (0);
#define DEBUG7(x) do {} while (0)
#endif
#if defined(QL_DEBUG_LEVEL_9)
#define DEBUG9(x) do {x;} while (0);
#define DEBUG9_10(x) do {x;} while (0);
#define DEBUG2_9_10(x) do {x;} while (0);
#define DEBUG9(x) do {x;} while (0)
#define DEBUG9_10(x) do {x;} while (0)
#else
#define DEBUG9(x) do {} while (0);
#define DEBUG9(x) do {} while (0)
#endif
#if defined(QL_DEBUG_LEVEL_10)
#define DEBUG10(x) do {x;} while (0);
#define DEBUG2_9_10(x) do {x;} while (0);
#define DEBUG9_10(x) do {x;} while (0);
#define DEBUG10(x) do {x;} while (0)
#define DEBUG9_10(x) do {x;} while (0)
#else
#define DEBUG10(x) do {} while (0);
#if !defined(DEBUG2_9_10)
#define DEBUG2_9_10(x) do {} while (0);
#endif
#define DEBUG10(x) do {} while (0)
#if !defined(DEBUG9_10)
#define DEBUG9_10(x) do {} while (0);
#define DEBUG9_10(x) do {} while (0)
#endif
#endif
#if defined(QL_DEBUG_LEVEL_11)
#define DEBUG11(x) do{x;} while (0);
#if !defined(DEBUG2_11)
#define DEBUG2_11(x) do{x;} while (0);
#endif
#if !defined(DEBUG2_3_11)
#define DEBUG2_3_11(x) do{x;} while (0);
#endif
#define DEBUG11(x) do{x;} while(0)
#if !defined(DEBUG3_11)
#define DEBUG3_11(x) do{x;} while (0);
#define DEBUG3_11(x) do{x;} while(0)
#endif
#else
#define DEBUG11(x) do{} while (0);
#if !defined(QL_DEBUG_LEVEL_2)
#define DEBUG2_11(x) do{} while (0);
#if !defined(QL_DEBUG_LEVEL_3)
#define DEBUG2_3_11(x) do{} while (0);
#endif
#endif
#define DEBUG11(x) do{} while(0)
#if !defined(QL_DEBUG_LEVEL_3)
#define DEBUG3_11(x) do{} while (0);
#define DEBUG3_11(x) do{} while(0)
#endif
#endif
#if defined(QL_DEBUG_LEVEL_12)
#define DEBUG12(x) do {x;} while (0);
#define DEBUG12(x) do {x;} while (0)
#else
#define DEBUG12(x) do {} while (0);
#define DEBUG12(x) do {} while (0)
#endif
#if defined(QL_DEBUG_LEVEL_13)
#define DEBUG13(x) do {x;} while (0)
#if !defined(DEBUG2_13)
#define DEBUG2_13(x) do {x;} while (0)
#endif
#else
#define DEBUG13(x) do {} while (0)
#if !defined(QL_DEBUG_LEVEL_2)
#define DEBUG2_13(x) do {} while (0)
#endif
#endif
#if defined(QL_DEBUG_LEVEL_14)
@@ -173,12 +116,21 @@
#define DEBUG14(x) do {} while (0)
#endif
#if defined(QL_DEBUG_LEVEL_15)
#define DEBUG15(x) do {x;} while (0)
#else
#define DEBUG15(x) do {} while (0)
#endif
#if defined(QL_DEBUG_LEVEL_16)
#define DEBUG16(x) do {x;} while (0)
#else
#define DEBUG16(x) do {} while (0)
#endif
/*
* Firmware Dump structure definition
*/
#define FW_DUMP_SIZE_128K 0xBC000
#define FW_DUMP_SIZE_512K 0x2FC000
#define FW_DUMP_SIZE_1M 0x5FC000
struct qla2300_fw_dump {
uint16_t hccr;
@@ -224,8 +176,6 @@ struct qla2100_fw_dump {
uint16_t risc_ram[0xf000];
};
#define FW_DUMP_SIZE_24XX 0x2B0000
struct qla24xx_fw_dump {
uint32_t host_status;
uint32_t host_reg[32];
@@ -257,3 +207,98 @@ struct qla24xx_fw_dump {
uint32_t code_ram[0x2000];
uint32_t ext_mem[1];
};
struct qla25xx_fw_dump {
uint32_t host_status;
uint32_t host_risc_reg[32];
uint32_t pcie_regs[4];
uint32_t host_reg[32];
uint32_t shadow_reg[11];
uint32_t risc_io_reg;
uint16_t mailbox_reg[32];
uint32_t xseq_gp_reg[128];
uint32_t xseq_0_reg[48];
uint32_t xseq_1_reg[16];
uint32_t rseq_gp_reg[128];
uint32_t rseq_0_reg[32];
uint32_t rseq_1_reg[16];
uint32_t rseq_2_reg[16];
uint32_t aseq_gp_reg[128];
uint32_t aseq_0_reg[32];
uint32_t aseq_1_reg[16];
uint32_t aseq_2_reg[16];
uint32_t cmd_dma_reg[16];
uint32_t req0_dma_reg[15];
uint32_t resp0_dma_reg[15];
uint32_t req1_dma_reg[15];
uint32_t xmt0_dma_reg[32];
uint32_t xmt1_dma_reg[32];
uint32_t xmt2_dma_reg[32];
uint32_t xmt3_dma_reg[32];
uint32_t xmt4_dma_reg[32];
uint32_t xmt_data_dma_reg[16];
uint32_t rcvt0_data_dma_reg[32];
uint32_t rcvt1_data_dma_reg[32];
uint32_t risc_gp_reg[128];
uint32_t lmc_reg[128];
uint32_t fpm_hdw_reg[192];
uint32_t fb_hdw_reg[192];
uint32_t code_ram[0x2000];
uint32_t ext_mem[1];
};
#define EFT_NUM_BUFFERS 4
#define EFT_BYTES_PER_BUFFER 0x4000
#define EFT_SIZE ((EFT_BYTES_PER_BUFFER) * (EFT_NUM_BUFFERS))
#define FCE_NUM_BUFFERS 64
#define FCE_BYTES_PER_BUFFER 0x400
#define FCE_SIZE ((FCE_BYTES_PER_BUFFER) * (FCE_NUM_BUFFERS))
#define fce_calc_size(b) ((FCE_BYTES_PER_BUFFER) * (b))
struct qla2xxx_fce_chain {
uint32_t type;
uint32_t chain_size;
uint32_t size;
uint32_t addr_l;
uint32_t addr_h;
uint32_t eregs[8];
};
#define DUMP_CHAIN_VARIANT 0x80000000
#define DUMP_CHAIN_FCE 0x7FFFFAF0
#define DUMP_CHAIN_LAST 0x80000000
struct qla2xxx_fw_dump {
uint8_t signature[4];
uint32_t version;
uint32_t fw_major_version;
uint32_t fw_minor_version;
uint32_t fw_subminor_version;
uint32_t fw_attributes;
uint32_t vendor;
uint32_t device;
uint32_t subsystem_vendor;
uint32_t subsystem_device;
uint32_t fixed_size;
uint32_t mem_size;
uint32_t req_q_size;
uint32_t rsp_q_size;
uint32_t eft_size;
uint32_t eft_addr_l;
uint32_t eft_addr_h;
uint32_t header_size;
union {
struct qla2100_fw_dump isp21;
struct qla2300_fw_dump isp23;
struct qla24xx_fw_dump isp24;
struct qla25xx_fw_dump isp25;
} isp;
};
+313 -250
View File
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2005 QLogic Corporation
* Copyright (c) 2003-2008 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -23,8 +23,9 @@
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/firmware.h>
#include <asm/semaphore.h>
#include <linux/version.h>
#include <linux/aer.h>
#include <linux/mutex.h>
#include <linux/semaphore.h>
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
@@ -32,12 +33,7 @@
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_transport_fc.h>
/* Define local TARGET mode variable if configured */
#if defined(CONFIG_SCSI_QLA2XXX_TARGET)
# ifndef FC_TARGET_SUPPORT
# define FC_TARGET_SUPPORT 1
# endif
#endif
#define QLA2XXX_DRIVER_NAME "qla2xxx"
/*
* We have MAILBOX_REGISTER_COUNT sized arrays in a few places,
@@ -98,13 +94,6 @@
#define LSD(x) ((uint32_t)((uint64_t)(x)))
#define MSD(x) ((uint32_t)((((uint64_t)(x)) >> 16) >> 16))
#ifndef IRQF_DISABLED
#define IRQF_DISABLED SA_INTERRUPT
#endif
#ifndef IRQF_SHARED
#define IRQF_SHARED SA_SHIRQ
#endif
/*
* I/O register
@@ -197,29 +186,15 @@
* SCSI Request Block
*/
typedef struct srb {
struct list_head list;
struct scsi_qla_host *ha; /* HA the SP is queued on */
struct fc_port *fcport;
struct scsi_cmnd *cmd; /* Linux SCSI command pkt */
struct timer_list timer; /* Command timer */
atomic_t ref_count; /* Reference count for this structure */
uint16_t flags;
/* Request state */
uint16_t state;
/* Single transfer DMA context */
dma_addr_t dma_handle;
uint32_t request_sense_length;
uint8_t *request_sense_ptr;
/* SRB magic number */
uint16_t magic;
#define SRB_MAGIC 0x10CB
} srb_t;
/*
@@ -240,21 +215,6 @@ typedef struct srb {
#define SRB_IOCTL BIT_10 /* IOCTL command. */
#define SRB_TAPE BIT_11 /* FCP2 (Tape) command. */
/*
* SRB state definitions
*/
#define SRB_FREE_STATE 0 /* returned back */
#define SRB_PENDING_STATE 1 /* queued in LUN Q */
#define SRB_ACTIVE_STATE 2 /* in Active Array */
#define SRB_DONE_STATE 3 /* queued in Done Queue */
#define SRB_RETRY_STATE 4 /* in Retry Queue */
#define SRB_SUSPENDED_STATE 5 /* in suspended state */
#define SRB_NO_QUEUE_STATE 6 /* is in between states */
#define SRB_ACTIVE_TIMEOUT_STATE 7 /* in Active Array but timed out */
#define SRB_FAILOVER_STATE 8 /* in Failover Queue */
#define SRB_SCSI_RETRY_STATE 9 /* in Scsi Retry Queue */
/*
* ISP I/O Register Set structure definitions.
*/
@@ -285,6 +245,8 @@ struct device_reg_2xxx {
#define NVR_SELECT BIT_1
#define NVR_CLOCK BIT_0
#define NVR_WAIT_CNT 20000
union {
struct {
uint16_t mailbox0;
@@ -351,7 +313,9 @@ struct device_reg_2xxx {
} u;
uint16_t fpm_diag_config;
uint16_t unused_5[0x6]; /* Gap */
uint16_t unused_5[0x4]; /* Gap */
uint16_t risc_hw;
uint16_t unused_5_1; /* Gap */
uint16_t pcr; /* Processor Control Register. */
uint16_t unused_6[0x5]; /* Gap */
uint16_t mctr; /* Memory Configuration and Timing. */
@@ -522,6 +486,7 @@ typedef struct {
#define MBA_IP_RCV_BUFFER_EMPTY 0x8026 /* IP receive buffer queue empty. */
#define MBA_IP_HDR_DATA_SPLIT 0x8027 /* IP header/data splitting feature */
/* used. */
#define MBA_TRACE_NOTIFICATION 0x8028 /* Trace/Diagnostic notification. */
#define MBA_POINT_TO_POINT 0x8030 /* Point to point mode. */
#define MBA_CMPLT_1_16BIT 0x8031 /* Completion 1 16bit IOSB. */
#define MBA_CMPLT_2_16BIT 0x8032 /* Completion 2 16bit IOSB. */
@@ -642,8 +607,11 @@ typedef struct {
*/
#define MBC_SERDES_PARAMS 0x10 /* Serdes Tx Parameters. */
#define MBC_GET_IOCB_STATUS 0x12 /* Get IOCB status command. */
#define MBC_PORT_PARAMS 0x1A /* Port iDMA Parameters. */
#define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */
#define MBC_TRACE_CONTROL 0x27 /* Trace control command. */
#define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */
#define MBC_READ_SFP 0x31 /* Read SFP Data. */
#define MBC_SET_TIMEOUT_PARAMS 0x32 /* Set FW timeouts. */
#define MBC_MID_INITIALIZE_FIRMWARE 0x48 /* MID Initialize firmware. */
#define MBC_MID_GET_VP_DATABASE 0x49 /* MID Get VP Database. */
@@ -889,14 +857,20 @@ typedef struct {
#define GLSO_SEND_RPS BIT_0
#define GLSO_USE_DID BIT_3
typedef struct {
uint32_t link_fail_cnt;
uint32_t loss_sync_cnt;
uint32_t loss_sig_cnt;
uint32_t prim_seq_err_cnt;
uint32_t inval_xmit_word_cnt;
uint32_t inval_crc_cnt;
} link_stat_t;
struct link_statistics {
uint32_t link_fail_cnt;
uint32_t loss_sync_cnt;
uint32_t loss_sig_cnt;
uint32_t prim_seq_err_cnt;
uint32_t inval_xmit_word_cnt;
uint32_t inval_crc_cnt;
uint32_t unused1[0x1b];
uint32_t tx_frames;
uint32_t rx_frames;
uint32_t dumped_frames;
uint32_t unused2[2];
uint32_t nos_rcvd;
};
/*
* NVRAM Command values.
@@ -1506,14 +1480,17 @@ typedef union {
uint32_t b24 : 24;
struct {
uint8_t d_id[3];
uint8_t rsvd_1;
} r;
struct {
#ifdef __BIG_ENDIAN
uint8_t domain;
uint8_t area;
uint8_t al_pa;
#elif __LITTLE_ENDIAN
uint8_t al_pa;
uint8_t area;
uint8_t domain;
#else
#error "__BIG_ENDIAN or __LITTLE_ENDIAN must be defined!"
#endif
uint8_t rsvd_1;
} b;
} port_id_t;
@@ -1526,64 +1503,10 @@ typedef struct {
port_id_t d_id;
uint8_t node_name[WWN_SIZE];
uint8_t port_name[WWN_SIZE];
uint8_t fabric_port_name[WWN_SIZE];
uint16_t fp_speed;
} sw_info_t;
/*
* Inquiry command structure.
*/
#define INQ_DATA_SIZE 36
/*
* Inquiry mailbox IOCB packet definition.
*/
typedef struct {
union {
cmd_a64_entry_t cmd;
sts_entry_t rsp;
struct cmd_type_7 cmd24;
struct sts_entry_24xx rsp24;
} p;
uint8_t inq[INQ_DATA_SIZE];
} inq_cmd_rsp_t;
/*
* Report LUN command structure.
*/
#define CHAR_TO_SHORT(a, b) (uint16_t)((uint8_t)b << 8 | (uint8_t)a)
typedef struct {
uint32_t len;
uint32_t rsrv;
} rpt_hdr_t;
typedef struct {
struct {
uint8_t b : 6;
uint8_t address_method : 2;
} msb;
uint8_t lsb;
uint8_t unused[6];
} rpt_lun_t;
typedef struct {
rpt_hdr_t hdr;
rpt_lun_t lst[MAX_LUNS];
} rpt_lun_lst_t;
/*
* Report Lun mailbox IOCB packet definition.
*/
typedef struct {
union {
cmd_a64_entry_t cmd;
sts_entry_t rsp;
struct cmd_type_7 cmd24;
struct sts_entry_24xx rsp24;
} p;
rpt_lun_lst_t list;
} rpt_lun_cmd_rsp_t;
/*
* Fibre channel port type.
*/
@@ -1602,7 +1525,6 @@ typedef struct {
typedef struct fc_port {
struct list_head list;
struct scsi_qla_host *ha;
struct scsi_qla_host *vis_ha; /* only used when suspending lun */
uint8_t node_name[WWN_SIZE];
uint8_t port_name[WWN_SIZE];
@@ -1610,30 +1532,27 @@ typedef struct fc_port {
uint16_t loop_id;
uint16_t old_loop_id;
uint8_t fabric_port_name[WWN_SIZE];
uint16_t fp_speed;
fc_port_type_t port_type;
atomic_t state;
uint32_t flags;
unsigned int os_target_id;
uint16_t iodesc_idx_sent;
int port_login_retry_count;
int login_retry;
atomic_t port_down_timer;
uint8_t device_type;
uint8_t unused;
uint8_t mp_byte; /* multi-path byte (not used) */
uint8_t cur_path; /* current path id */
spinlock_t rport_lock;
struct fc_rport *rport, *drport;
u32 supported_classes;
struct work_struct rport_add_work;
struct work_struct rport_del_work;
unsigned long last_queue_full;
unsigned long last_ramp_up;
struct list_head vp_fcport;
uint16_t vp_idx;
} fc_port_t;
/*
@@ -1688,7 +1607,9 @@ typedef struct fc_port {
#define CT_REJECT_RESPONSE 0x8001
#define CT_ACCEPT_RESPONSE 0x8002
#define CT_REASON_INVALID_COMMAND_CODE 0x01
#define CT_REASON_CANNOT_PERFORM 0x09
#define CT_REASON_COMMAND_UNSUPPORTED 0x0b
#define CT_EXPL_ALREADY_REGISTERED 0x10
#define NS_N_PORT_TYPE 0x01
@@ -1731,6 +1652,15 @@ typedef struct fc_port {
#define RSNN_NN_REQ_SIZE (16 + 8 + 1 + 255)
#define RSNN_NN_RSP_SIZE 16
#define GFPN_ID_CMD 0x11C
#define GFPN_ID_REQ_SIZE (16 + 4)
#define GFPN_ID_RSP_SIZE (16 + 8)
#define GPSC_CMD 0x127
#define GPSC_REQ_SIZE (16 + 8)
#define GPSC_RSP_SIZE (16 + 2 + 2)
/*
* HBA attribute types.
*/
@@ -1773,7 +1703,7 @@ struct ct_fdmi_hba_attributes {
/*
* Port attribute types.
*/
#define FDMI_PORT_ATTR_COUNT 5
#define FDMI_PORT_ATTR_COUNT 6
#define FDMI_PORT_FC4_TYPES 1
#define FDMI_PORT_SUPPORT_SPEED 2
#define FDMI_PORT_CURRENT_SPEED 3
@@ -1781,6 +1711,14 @@ struct ct_fdmi_hba_attributes {
#define FDMI_PORT_OS_DEVICE_NAME 5
#define FDMI_PORT_HOST_NAME 6
#define FDMI_PORT_SPEED_1GB 0x1
#define FDMI_PORT_SPEED_2GB 0x2
#define FDMI_PORT_SPEED_10GB 0x4
#define FDMI_PORT_SPEED_4GB 0x8
#define FDMI_PORT_SPEED_8GB 0x10
#define FDMI_PORT_SPEED_16GB 0x20
#define FDMI_PORT_SPEED_UNKNOWN 0x8000
struct ct_fdmi_port_attr {
uint16_t type;
uint16_t len;
@@ -1844,7 +1782,7 @@ struct ct_sns_req {
uint8_t reserved[3];
union {
/* GA_NXT, GPN_ID, GNN_ID, GFT_ID */
/* GA_NXT, GPN_ID, GNN_ID, GFT_ID, GFPN_ID */
struct {
uint8_t reserved;
uint8_t port_id[3];
@@ -1919,6 +1857,10 @@ struct ct_sns_req {
struct {
uint8_t port_name[8];
} dpa;
struct {
uint8_t port_name[8];
} gpsc;
} req;
};
@@ -1982,6 +1924,15 @@ struct ct_sns_rsp {
uint8_t port_name[8];
struct ct_fdmi_hba_attributes attrs;
} ghat;
struct {
uint8_t port_name[8];
} gfpn_id;
struct {
uint16_t speeds;
uint16_t speed;
} gpsc;
} rsp;
};
@@ -2042,54 +1993,6 @@ struct sns_cmd_pkt {
} p;
};
/* IO descriptors */
#define MAX_IO_DESCRIPTORS 32
#define ABORT_IOCB_CB 0
#define ADISC_PORT_IOCB_CB 1
#define LOGOUT_PORT_IOCB_CB 2
#define LOGIN_PORT_IOCB_CB 3
#define LAST_IOCB_CB 4
#define IODESC_INVALID_INDEX 0xFFFF
#define IODESC_ADISC_NEEDED 0xFFFE
#define IODESC_LOGIN_NEEDED 0xFFFD
struct io_descriptor {
uint16_t used:1;
uint16_t idx:11;
uint16_t cb_idx:4;
struct timer_list timer;
struct scsi_qla_host *ha;
port_id_t d_id;
fc_port_t *remote_fcport;
uint32_t signature;
};
struct qla_fw_info {
unsigned short addressing; /* addressing method used to load fw */
#define FW_INFO_ADDR_NORMAL 0
#define FW_INFO_ADDR_EXTENDED 1
#define FW_INFO_ADDR_NOMORE 0xffff
unsigned short *fwcode; /* pointer to FW array */
unsigned short *fwlen; /* number of words in array */
unsigned short *fwstart; /* start address for F/W */
unsigned long *lfwstart; /* start address (long) for F/W */
};
struct qla_board_info {
char *drv_name;
char isp_name[8];
struct qla_fw_info *fw_info;
char *fw_fname;
struct scsi_host_template *sht;
};
struct fw_blob {
char *name;
uint32_t segs[4];
@@ -2107,6 +2010,34 @@ struct gid_list_info {
};
#define GID_LIST_SIZE (sizeof(struct gid_list_info) * MAX_FIBRE_DEVICES)
/* NPIV */
typedef struct vport_info {
uint8_t port_name[WWN_SIZE];
uint8_t node_name[WWN_SIZE];
int vp_id;
uint16_t loop_id;
unsigned long host_no;
uint8_t port_id[3];
int loop_state;
} vport_info_t;
typedef struct vport_params {
uint8_t port_name[WWN_SIZE];
uint8_t node_name[WWN_SIZE];
uint32_t options;
#define VP_OPTS_RETRY_ENABLE BIT_0
#define VP_OPTS_VP_DISABLE BIT_1
} vport_params_t;
/* NPIV - return codes of VP create and modify */
#define VP_RET_CODE_OK 0
#define VP_RET_CODE_FATAL 1
#define VP_RET_CODE_WRONG_ID 2
#define VP_RET_CODE_WWPN 3
#define VP_RET_CODE_RESOURCES 4
#define VP_RET_CODE_NO_MEM 5
#define VP_RET_CODE_NOT_FOUND 6
/*
* ISP operations
*/
@@ -2124,16 +2055,13 @@ struct isp_operations {
char * (*pci_info_str) (struct scsi_qla_host *, char *);
char * (*fw_version_str) (struct scsi_qla_host *, char *);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
irqreturn_t (*intr_handler) (int, void *, struct pt_regs *);
#else
irq_handler_t intr_handler;
#endif
void (*enable_intrs) (struct scsi_qla_host *);
void (*disable_intrs) (struct scsi_qla_host *);
int (*abort_command) (struct scsi_qla_host *, srb_t *);
int (*abort_target) (struct fc_port *);
int (*target_reset) (struct fc_port *, unsigned int);
int (*lun_reset) (struct fc_port *, unsigned int);
int (*fabric_login) (struct scsi_qla_host *, uint16_t, uint8_t,
uint8_t, uint8_t, uint16_t *, uint8_t);
int (*fabric_logout) (struct scsi_qla_host *, uint16_t, uint8_t,
@@ -2151,7 +2079,6 @@ struct isp_operations {
uint32_t);
void (*fw_dump) (struct scsi_qla_host *, int);
void (*ascii_fw_dump) (struct scsi_qla_host *);
int (*beacon_on) (struct scsi_qla_host *);
int (*beacon_off) (struct scsi_qla_host *);
@@ -2161,6 +2088,71 @@ struct isp_operations {
uint32_t, uint32_t);
int (*write_optrom) (struct scsi_qla_host *, uint8_t *, uint32_t,
uint32_t);
int (*get_flash_version) (struct scsi_qla_host *, void *);
};
/* MSI-X Support *************************************************************/
#define QLA_MSIX_CHIP_REV_24XX 3
#define QLA_MSIX_FW_MODE(m) (((m) & (BIT_7|BIT_8|BIT_9)) >> 7)
#define QLA_MSIX_FW_MODE_1(m) (QLA_MSIX_FW_MODE(m) == 1)
#define QLA_MSIX_DEFAULT 0x00
#define QLA_MSIX_RSP_Q 0x01
#define QLA_MSIX_ENTRIES 2
#define QLA_MIDX_DEFAULT 0
#define QLA_MIDX_RSP_Q 1
struct scsi_qla_host;
struct qla_msix_entry {
int have_irq;
uint16_t msix_vector;
uint16_t msix_entry;
};
#define WATCH_INTERVAL 1 /* number of seconds */
/* Work events. */
enum qla_work_type {
QLA_EVT_AEN,
QLA_EVT_HWE_LOG,
};
struct qla_work_evt {
struct list_head list;
enum qla_work_type type;
u32 flags;
#define QLA_EVT_FLAG_FREE 0x1
union {
struct {
enum fc_host_event_code code;
u32 data;
} aen;
struct {
uint16_t code;
uint16_t d1, d2, d3;
} hwe;
} u;
};
struct qla_chip_state_84xx {
struct list_head list;
struct kref kref;
void *bus;
spinlock_t access_lock;
struct mutex fw_update_mutex;
uint32_t fw_update;
uint32_t op_fw_version;
uint32_t op_fw_size;
uint32_t op_fw_seq_size;
uint32_t diag_fw_version;
uint32_t gold_fw_version;
};
/*
@@ -2193,9 +2185,16 @@ typedef struct scsi_qla_host {
uint32_t enable_lip_full_login :1;
uint32_t enable_target_reset :1;
uint32_t enable_led_scheme :1;
uint32_t inta_enabled :1;
uint32_t msi_enabled :1;
uint32_t msix_enabled :1;
#ifdef FC_TARGET_SUPPORT
uint32_t disable_serdes :1;
uint32_t gpsc_supported :1;
uint32_t vsan_enabled :1;
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
@@ -2238,6 +2237,7 @@ typedef struct scsi_qla_host {
#define BEACON_BLINK_NEEDED 25
#define REGISTER_FDMI_NEEDED 26
#define FCPORT_UPDATE_NEEDED 27
#define VP_DPC_NEEDED 28 /* wake up for VP dpc handling */
uint32_t device_flags;
#define DFLG_LOCAL_DEVICES BIT_0
@@ -2246,6 +2246,8 @@ typedef struct scsi_qla_host {
#define SWITCH_FOUND BIT_3
#define DFLG_NO_CABLE BIT_4
#define PCI_DEVICE_ID_QLOGIC_ISP2532 0x2532
#define PCI_DEVICE_ID_QLOGIC_ISP8432 0x8432
uint32_t device_type;
#define DT_ISP2100 BIT_0
#define DT_ISP2200 BIT_1
@@ -2258,8 +2260,12 @@ typedef struct scsi_qla_host {
#define DT_ISP2432 BIT_8
#define DT_ISP5422 BIT_9
#define DT_ISP5432 BIT_10
#define DT_ISP_LAST (DT_ISP5432 << 1)
#define DT_ISP2532 BIT_11
#define DT_ISP8432 BIT_12
#define DT_ISP_LAST (DT_ISP8432 << 1)
#define DT_IIDMA BIT_26
#define DT_FWI2 BIT_27
#define DT_ZIO_SUPPORTED BIT_28
#define DT_OEM_001 BIT_29
#define DT_ISP2200A BIT_30
@@ -2277,12 +2283,20 @@ typedef struct scsi_qla_host {
#define IS_QLA2432(ha) (DT_MASK(ha) & DT_ISP2432)
#define IS_QLA5422(ha) (DT_MASK(ha) & DT_ISP5422)
#define IS_QLA5432(ha) (DT_MASK(ha) & DT_ISP5432)
#define IS_QLA2532(ha) (DT_MASK(ha) & DT_ISP2532)
#define IS_QLA8432(ha) (DT_MASK(ha) & DT_ISP8432)
#define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \
IS_QLA6312(ha) || IS_QLA6322(ha))
#define IS_QLA24XX(ha) (IS_QLA2422(ha) || IS_QLA2432(ha))
#define IS_QLA54XX(ha) (IS_QLA5422(ha) || IS_QLA5432(ha))
#define IS_QLA25XX(ha) (IS_QLA2532(ha))
#define IS_QLA84XX(ha) (IS_QLA8432(ha))
#define IS_QLA24XX_TYPE(ha) (IS_QLA24XX(ha) || IS_QLA54XX(ha) || \
IS_QLA84XX(ha))
#define IS_IIDMA_CAPABLE(ha) ((ha)->device_type & DT_IIDMA)
#define IS_FWI2_CAPABLE(ha) ((ha)->device_type & DT_FWI2)
#define IS_ZIO_SUPPORTED(ha) ((ha)->device_type & DT_ZIO_SUPPORTED)
#define IS_OEM_001(ha) ((ha)->device_type & DT_OEM_001)
#define HAS_EXTENDED_IDS(ha) ((ha)->device_type & DT_EXTENDED_IDS)
@@ -2292,7 +2306,7 @@ typedef struct scsi_qla_host {
mempool_t *srb_mempool;
/* This spinlock is used to protect "io transactions", you must
* aquire it before doing any IO to the card, eg with RD_REG*() and
* acquire it before doing any IO to the card, eg with RD_REG*() and
* WRT_REG*() for the duration of your entire commandtransaction.
*
* This spinlock is of lower priority than the io request lock.
@@ -2300,9 +2314,10 @@ typedef struct scsi_qla_host {
spinlock_t hardware_lock ____cacheline_aligned;
int bars;
int mem_only;
device_reg_t __iomem *iobase; /* Base I/O address */
unsigned long pio_address;
unsigned long pio_length;
resource_size_t pio_address;
#define MIN_IOBASE_LEN 0x100
/* ISP ring lock, rings, and indexes */
@@ -2319,29 +2334,32 @@ typedef struct scsi_qla_host {
uint16_t rsp_ring_index; /* Current index. */
uint16_t response_q_length;
struct isp_operations isp_ops;
struct isp_operations *isp_ops;
/* Outstandings ISP commands. */
srb_t *outstanding_cmds[MAX_OUTSTANDING_COMMANDS];
uint32_t current_outstanding_cmd;
srb_t *status_srb; /* Status continuation entry. */
uint16_t revision;
uint8_t ports;
/* ISP configuration data. */
uint16_t loop_id; /* Host adapter loop id */
uint16_t switch_cap;
#define FLOGI_SEQ_DEL BIT_8
#define FLOGI_MID_SUPPORT BIT_10
#define FLOGI_VSAN_SUPPORT BIT_12
#define FLOGI_SP_SUPPORT BIT_13
uint16_t fb_rev;
port_id_t d_id; /* Host adapter port id */
uint16_t max_public_loop_ids;
uint16_t min_external_loopid; /* First external loop Id */
#define PORT_SPEED_UNKNOWN 0xFFFF
#define PORT_SPEED_1GB 0x00
#define PORT_SPEED_2GB 0x01
#define PORT_SPEED_4GB 0x03
#define PORT_SPEED_8GB 0x04
uint16_t link_data_rate; /* F/W operating speed */
#define LDR_1GB 0
#define LDR_2GB 1
#define LDR_4GB 3
#define LDR_UNKNOWN 0xFFFF
uint8_t current_topology;
uint8_t prev_topology;
@@ -2366,10 +2384,14 @@ typedef struct scsi_qla_host {
uint8_t serial2;
/* NVRAM configuration data */
#define MAX_NVRAM_SIZE 4096
#define VPD_OFFSET MAX_NVRAM_SIZE / 2
uint16_t nvram_size;
uint16_t nvram_base;
void *nvram;
uint16_t vpd_size;
uint16_t vpd_base;
void *vpd;
uint16_t loop_reset_delay;
uint8_t retry_count;
@@ -2381,13 +2403,12 @@ typedef struct scsi_qla_host {
uint16_t mgmt_svr_loop_id;
uint32_t login_retry_count;
int max_q_depth;
struct list_head work_list;
/* Fibre Channel Device List. */
struct list_head fcports;
struct list_head rscn_fcports;
struct io_descriptor io_descriptors[MAX_IO_DESCRIPTORS];
uint16_t iodesc_signature;
/* RSCN queue. */
uint32_t rscn_queue[MAX_RSCN_COUNT];
@@ -2403,6 +2424,11 @@ typedef struct scsi_qla_host {
struct sns_cmd_pkt *sns_cmd;
dma_addr_t sns_cmd_dma;
#define SFP_DEV_SIZE 256
#define SFP_BLOCK_SIZE 64
void *sfp_data;
dma_addr_t sfp_data_dma;
spinlock_t dpc_lock;
struct task_struct *dpc_thread;
uint8_t dpc_active; /* DPC routine is active */
@@ -2419,9 +2445,6 @@ typedef struct scsi_qla_host {
struct gid_list_info *gid_list;
int gid_list_info_size;
dma_addr_t rlc_rsp_dma;
rpt_lun_cmd_rsp_t *rlc_rsp;
/* Small DMA pool allocations -- maximum 256 bytes in length. */
#define DMA_POOL_SIZE 256
struct dma_pool *s_dma_pool;
@@ -2430,9 +2453,6 @@ typedef struct scsi_qla_host {
init_cb_t *init_cb;
int init_cb_size;
dma_addr_t iodesc_pd_dma;
port_database_t *iodesc_pd;
/* These are used by mailbox operations. */
volatile uint16_t mailbox_out[MAILBOX_REGISTER_COUNT];
@@ -2442,10 +2462,9 @@ typedef struct scsi_qla_host {
#define MBX_INTR_WAIT 2
#define MBX_UPDATE_FLASH_ACTIVE 3
spinlock_t mbx_reg_lock; /* Mbx Cmd Register Lock */
struct semaphore mbx_cmd_sem; /* Serialialize mbx access */
struct semaphore mbx_intr_sem; /* Used for completion notification */
struct mutex vport_lock; /* Virtual port synchronization */
struct completion mbx_cmd_comp; /* Serialize mbx access */
struct completion mbx_intr_comp; /* Used for completion notification */
uint32_t mbx_flags;
#define MBX_IN_PROGRESS BIT_0
@@ -2456,35 +2475,46 @@ typedef struct scsi_qla_host {
#define MBX_TIMEDOUT BIT_5
#define MBX_ACCESS_TIMEDOUT BIT_6
mbx_cmd_t mc;
/* Basic firmware related information. */
struct qla_board_info *brd_info;
uint16_t fw_major_version;
uint16_t fw_minor_version;
uint16_t fw_subminor_version;
uint16_t fw_attributes;
uint32_t fw_memory_size;
uint32_t fw_transfer_size;
uint32_t fw_srisc_address;
#define RISC_START_ADDRESS_2100 0x1000
#define RISC_START_ADDRESS_2300 0x800
#define RISC_START_ADDRESS_2400 0x100000
uint16_t fw_options[16]; /* slots: 1,2,3,10,11 */
uint8_t fw_seriallink_options[4];
uint16_t fw_seriallink_options24[4];
/* Firmware dump information. */
void *fw_dump;
int fw_dump_order;
int fw_dump_reading;
char *fw_dump_buffer;
int fw_dump_buffer_len;
struct qla2xxx_fw_dump *fw_dump;
uint32_t fw_dump_len;
int fw_dumped;
void *fw_dump24;
int fw_dump24_len;
int fw_dump_reading;
dma_addr_t eft_dma;
void *eft;
#define HA_HOST_STR_SIZE 16
uint8_t host_str[HA_HOST_STR_SIZE];
struct dentry *dfs_dir;
struct dentry *dfs_fce;
dma_addr_t fce_dma;
void *fce;
uint32_t fce_bufs;
uint16_t fce_mb[8];
uint64_t fce_wr, fce_rd;
struct mutex fce_mutex;
uint32_t hw_event_start;
uint32_t hw_event_ptr;
uint32_t hw_event_pause_errors;
uint8_t host_str[16];
uint32_t pci_attr;
uint16_t chip_revision;
uint16_t product_id[4];
@@ -2495,6 +2525,7 @@ typedef struct scsi_qla_host {
uint8_t *node_name;
uint8_t *port_name;
uint8_t fabric_node_name[WWN_SIZE];
uint32_t isp_abort_cnt;
/* Option ROM information. */
@@ -2504,6 +2535,24 @@ typedef struct scsi_qla_host {
#define QLA_SWAITING 0
#define QLA_SREADING 1
#define QLA_SWRITING 2
uint32_t optrom_region_start;
uint32_t optrom_region_size;
/* PCI expansion ROM image information. */
#define ROM_CODE_TYPE_BIOS 0
#define ROM_CODE_TYPE_FCODE 1
#define ROM_CODE_TYPE_EFI 3
uint8_t bios_revision[2];
uint8_t efi_revision[2];
uint8_t fcode_revision[16];
uint32_t fw_revision[4];
uint16_t fdt_odd_index;
uint32_t fdt_wrt_disable;
uint32_t fdt_erase_cmd;
uint32_t fdt_block_size;
uint32_t fdt_unprotect_sec_cmd;
uint32_t fdt_protect_sec_cmd;
/* Needed for BEACON */
uint16_t beacon_blink_led;
@@ -2517,11 +2566,47 @@ typedef struct scsi_qla_host {
uint16_t zio_mode;
uint16_t zio_timer;
struct fc_host_statistics fc_host_stat;
#ifdef FC_TARGET_SUPPORT
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
struct q2t_cmd *cmds[MAX_OUTSTANDING_COMMANDS];
uint16_t current_cmd;
struct q2t_tgt *tgt;
#endif /* FC_TARGET_SUPPORT */
#endif /* CONFIG_SCSI_QLA2XXX_TARGET */
struct qla_msix_entry msix_entries[QLA_MSIX_ENTRIES];
struct list_head vp_list; /* list of VP */
struct fc_vport *fc_vport; /* holds fc_vport * for each vport */
unsigned long vp_idx_map[(MAX_MULTI_ID_FABRIC / 8) / sizeof(unsigned long)];
uint16_t num_vhosts; /* number of vports created */
uint16_t num_vsans; /* number of vsan created */
uint16_t vp_idx; /* vport ID */
struct scsi_qla_host *parent; /* holds pport */
unsigned long vp_flags;
struct list_head vp_fcports; /* list of fcports */
#define VP_IDX_ACQUIRED 0 /* bit no 0 */
#define VP_CREATE_NEEDED 1
#define VP_BIND_NEEDED 2
#define VP_DELETE_NEEDED 3
#define VP_SCR_NEEDED 4 /* State Change Request registration */
atomic_t vp_state;
#define VP_OFFLINE 0
#define VP_ACTIVE 1
#define VP_FAILED 2
// #define VP_DISABLE 3
uint16_t vp_err_state;
uint16_t vp_prev_err_state;
#define VP_ERR_UNKWN 0
#define VP_ERR_PORTDWN 1
#define VP_ERR_FAB_UNSUPPORTED 2
#define VP_ERR_FAB_NORESOURCES 3
#define VP_ERR_FAB_LOGOUT 4
#define VP_ERR_ADAP_NORESOURCES 5
uint16_t max_npiv_vports; /* 63 or 125 per topoloty */
int cur_vport_count;
struct qla_chip_state_84xx *cs84xx;
} scsi_qla_host_t;
@@ -2533,10 +2618,6 @@ typedef struct scsi_qla_host {
test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || \
atomic_read(&ha->loop_state) == LOOP_DOWN)
#define TGT_Q(ha, t) (ha->otgt[t])
#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)
@@ -2567,19 +2648,6 @@ typedef struct scsi_qla_host {
#define QLA_RSCNS_HANDLED 0x108
#define QLA_ALREADY_REGISTERED 0x109
/*
* Stat info for all adpaters
*/
struct _qla2x00stats {
unsigned long mboxtout; /* mailbox timeouts */
unsigned long mboxerr; /* mailbox errors */
unsigned long ispAbort; /* ISP aborts */
unsigned long debugNo;
unsigned long loop_resync;
unsigned long outarray_full;
unsigned long retry_q_cnt;
};
#define NVRAM_DELAY() udelay(10)
#define INVALID_HANDLE (MAX_OUTSTANDING_COMMANDS+1)
@@ -2590,17 +2658,12 @@ struct _qla2x00stats {
#define OPTROM_SIZE_2300 0x20000
#define OPTROM_SIZE_2322 0x100000
#define OPTROM_SIZE_24XX 0x100000
#define OPTROM_SIZE_25XX 0x200000
#include "qla_gbl.h"
#include "qla_dbg.h"
#include "qla_inline.h"
/*
* String arrays
*/
#define LINESIZE 256
#define MAXARGS 26
#define CMD_SP(Cmnd) ((Cmnd)->SCp.ptr)
#define CMD_COMPL_STATUS(Cmnd) ((Cmnd)->SCp.this_residual)
#define CMD_RESID_LEN(Cmnd) ((Cmnd)->SCp.buffers_residual)
@@ -2608,4 +2671,4 @@ struct _qla2x00stats {
#define CMD_ACTUAL_SNSLEN(Cmnd) ((Cmnd)->SCp.Message)
#define CMD_ENTRY_STATUS(Cmnd) ((Cmnd)->SCp.have_data_in)
#endif /* __QLA_DEF_H */
#endif
+20 -2
View File
@@ -1,4 +1,4 @@
#define QLA_MODEL_NAMES 0x4A
#define QLA_MODEL_NAMES 0x5C
/*
* Adapter model names and descriptions.
@@ -76,6 +76,24 @@ static char *qla2x00_model_name[QLA_MODEL_NAMES*2] = {
"QLE2440", "PCI-Express to 4Gb FC, Single Channel", /* 0x145 */
"QLE2464", "PCI-Express to 4Gb FC, Quad Channel", /* 0x146 */
"QLA2440", "PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x147 */
" ", " ", /* 0x148 */
"HP AE369A", "PCI-X 2.0 to 4Gb FC, Dual Channel", /* 0x148 */
"QLA2340", "Sun 133MHz PCI-X to 2Gb FC, Single Channel", /* 0x149 */
" ", " ", /* 0x14a */
" ", " ", /* 0x14b */
"QMC2432M", "IBM eServer BC 4Gb FC Expansion Card CFFE", /* 0x14c */
"QMC2422M", "IBM eServer BC 4Gb FC Expansion Card CFFX", /* 0x14d */
"QLE220", "Sun PCI-Express to 4Gb FC, Single Channel", /* 0x14e */
" ", " ", /* 0x14f */
" ", " ", /* 0x150 */
" ", " ", /* 0x151 */
"QME2462", "PCI-Express to 4Gb FC, Dual Channel Mezz HBA", /* 0x152 */
"QMH2462", "PCI-Express to 4Gb FC, Dual Channel Mezz HBA", /* 0x153 */
" ", " ", /* 0x154 */
"QLE220", "PCI-Express to 4Gb FC, Single Channel", /* 0x155 */
"QLE220", "PCI-Express to 4Gb FC, Single Channel", /* 0x156 */
" ", " ", /* 0x157 */
" ", " ", /* 0x158 */
" ", " ", /* 0x159 */
" ", " ", /* 0x15a */
"QME2472", "Dell BS PCI-Express to 4Gb FC, Dual Channel", /* 0x15b */
};
+175
View File
@@ -0,0 +1,175 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2008 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
#include <linux/debugfs.h>
#include <linux/seq_file.h>
static struct dentry *qla2x00_dfs_root;
static atomic_t qla2x00_dfs_root_count;
static int
qla2x00_dfs_fce_show(struct seq_file *s, void *unused)
{
scsi_qla_host_t *ha = s->private;
uint32_t cnt;
uint32_t *fce;
uint64_t fce_start;
mutex_lock(&ha->fce_mutex);
seq_printf(s, "FCE Trace Buffer\n");
seq_printf(s, "In Pointer = %llx\n\n", (unsigned long long)ha->fce_wr);
seq_printf(s, "Base = %llx\n\n", (unsigned long long) ha->fce_dma);
seq_printf(s, "FCE Enable Registers\n");
seq_printf(s, "%08x %08x %08x %08x %08x %08x\n",
ha->fce_mb[0], ha->fce_mb[2], ha->fce_mb[3], ha->fce_mb[4],
ha->fce_mb[5], ha->fce_mb[6]);
fce = (uint32_t *) ha->fce;
fce_start = (unsigned long long) ha->fce_dma;
for (cnt = 0; cnt < fce_calc_size(ha->fce_bufs) / 4; cnt++) {
if (cnt % 8 == 0)
seq_printf(s, "\n%llx: ",
(unsigned long long)((cnt * 4) + fce_start));
else
seq_printf(s, " ");
seq_printf(s, "%08x", *fce++);
}
seq_printf(s, "\nEnd\n");
mutex_unlock(&ha->fce_mutex);
return 0;
}
static int
qla2x00_dfs_fce_open(struct inode *inode, struct file *file)
{
scsi_qla_host_t *ha = inode->i_private;
int rval;
if (!ha->flags.fce_enabled)
goto out;
mutex_lock(&ha->fce_mutex);
/* Pause tracing to flush FCE buffers. */
rval = qla2x00_disable_fce_trace(ha, &ha->fce_wr, &ha->fce_rd);
if (rval)
qla_printk(KERN_WARNING, ha,
"DebugFS: Unable to disable FCE (%d).\n", rval);
ha->flags.fce_enabled = 0;
mutex_unlock(&ha->fce_mutex);
out:
return single_open(file, qla2x00_dfs_fce_show, ha);
}
static int
qla2x00_dfs_fce_release(struct inode *inode, struct file *file)
{
scsi_qla_host_t *ha = inode->i_private;
int rval;
if (ha->flags.fce_enabled)
goto out;
mutex_lock(&ha->fce_mutex);
/* Re-enable FCE tracing. */
ha->flags.fce_enabled = 1;
memset(ha->fce, 0, fce_calc_size(ha->fce_bufs));
rval = qla2x00_enable_fce_trace(ha, ha->fce_dma, ha->fce_bufs,
ha->fce_mb, &ha->fce_bufs);
if (rval) {
qla_printk(KERN_WARNING, ha,
"DebugFS: Unable to reinitialize FCE (%d).\n", rval);
ha->flags.fce_enabled = 0;
}
mutex_unlock(&ha->fce_mutex);
out:
return single_release(inode, file);
}
static const struct file_operations dfs_fce_ops = {
.open = qla2x00_dfs_fce_open,
.read = seq_read,
.llseek = seq_lseek,
.release = qla2x00_dfs_fce_release,
};
int
qla2x00_dfs_setup(scsi_qla_host_t *ha)
{
if (!IS_QLA25XX(ha))
goto out;
if (!ha->fce)
goto out;
if (qla2x00_dfs_root)
goto create_dir;
atomic_set(&qla2x00_dfs_root_count, 0);
qla2x00_dfs_root = debugfs_create_dir(QLA2XXX_DRIVER_NAME, NULL);
if (!qla2x00_dfs_root) {
qla_printk(KERN_NOTICE, ha,
"DebugFS: Unable to create root directory.\n");
goto out;
}
create_dir:
if (ha->dfs_dir)
goto create_nodes;
mutex_init(&ha->fce_mutex);
ha->dfs_dir = debugfs_create_dir(ha->host_str, qla2x00_dfs_root);
if (!ha->dfs_dir) {
qla_printk(KERN_NOTICE, ha,
"DebugFS: Unable to create ha directory.\n");
goto out;
}
atomic_inc(&qla2x00_dfs_root_count);
create_nodes:
ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, ha,
&dfs_fce_ops);
if (!ha->dfs_fce) {
qla_printk(KERN_NOTICE, ha,
"DebugFS: Unable to fce node.\n");
goto out;
}
out:
return 0;
}
int
qla2x00_dfs_remove(scsi_qla_host_t *ha)
{
if (ha->dfs_fce) {
debugfs_remove(ha->dfs_fce);
ha->dfs_fce = NULL;
}
if (ha->dfs_dir) {
debugfs_remove(ha->dfs_dir);
ha->dfs_dir = NULL;
atomic_dec(&qla2x00_dfs_root_count);
}
if (atomic_read(&qla2x00_dfs_root_count) == 0 &&
qla2x00_dfs_root) {
debugfs_remove(qla2x00_dfs_root);
qla2x00_dfs_root = NULL;
}
return 0;
}
+296 -27
View File
@@ -1,22 +1,24 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2005 QLogic Corporation
* Copyright (c) 2003-2008 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#ifndef __QLA_FW_H
#define __QLA_FW_H
#define RISC_SADDRESS 0x100000
#define MBS_CHECKSUM_ERROR 0x4010
#define MBS_INVALID_PRODUCT_KEY 0x4020
/*
* Firmware Options.
*/
#define FO1_ENABLE_PUREX BIT_10
#define FO1_DISABLE_LED_CTRL BIT_6
#define FO1_ENABLE_8016 BIT_0
#define FO2_ENABLE_SEL_CLASS2 BIT_5
#define FO3_NO_ABTS_ON_LINKDOWN BIT_14
#define FO3_HOLD_STS_IOCB BIT_12
/*
* Port Database structure definition for ISP 24xx.
@@ -70,6 +72,16 @@ struct port_database_24xx {
uint8_t reserved_3[24];
};
struct vp_database_24xx {
uint16_t vp_status;
uint8_t options;
uint8_t id;
uint8_t port_name[WWN_SIZE];
uint8_t node_name[WWN_SIZE];
uint16_t port_id_low;
uint16_t port_id_high;
};
struct nvram_24xx {
/* NVRAM header. */
uint8_t id[4];
@@ -142,7 +154,7 @@ struct nvram_24xx {
* BIT 2 = Enable Memory Map BIOS
* BIT 3 = Enable Selectable Boot
* BIT 4 = Disable RISC code load
* BIT 5 =
* BIT 5 = Disable Serdes
* BIT 6 =
* BIT 7 =
*
@@ -279,7 +291,7 @@ struct init_cb_24xx {
uint16_t response_q_length;
uint16_t request_q_length;
uint16_t link_down_timeout; /* Milliseconds. */
uint16_t link_down_on_nos; /* Milliseconds. */
uint16_t prio_request_q_length;
@@ -332,7 +344,9 @@ struct init_cb_24xx {
* BIT 10 = Reserved
* BIT 11 = Enable FC-SP Security
* BIT 12 = FC Tape Enable
* BIT 13-31 = Reserved
* BIT 13 = Reserved
* BIT 14 = Enable Target PRLI Control
* BIT 15-31 = Reserved
*/
uint32_t firmware_options_2;
@@ -354,7 +368,8 @@ struct init_cb_24xx {
* BIT 13 = Data Rate bit 0
* BIT 14 = Data Rate bit 1
* BIT 15 = Data Rate bit 2
* BIT 16-31 = Reserved
* BIT 16 = Enable 75 ohm Termination Select
* BIT 17-31 = Reserved
*/
uint32_t firmware_options_3;
@@ -426,6 +441,7 @@ struct cmd_type_7 {
#define TMF_LUN_RESET BIT_12
#define TMF_CLEAR_TASK_SET BIT_10
#define TMF_ABORT_TASK_SET BIT_9
#define TMF_DSD_LIST_ENABLE BIT_2
#define TMF_READ_DATA BIT_1
#define TMF_WRITE_DATA BIT_0
@@ -463,7 +479,7 @@ struct sts_entry_24xx {
uint16_t comp_status; /* Completion status. */
uint16_t ox_id; /* OX_ID used by the firmware. */
uint32_t residual_len; /* Residual transfer length. */
uint32_t residual_len; /* FW calc residual transfer length. */
uint16_t reserved_1;
uint16_t state_flags; /* State flags. */
@@ -580,7 +596,7 @@ struct els_entry_24xx {
#define EST_SOFI3 (1 << 4)
#define EST_SOFI2 (3 << 4)
uint32_t rx_xchg_address[2]; /* Receive exchange address. */
uint32_t rx_xchg_address; /* Receive exchange address. */
uint16_t rx_dsd_count;
uint8_t opcode;
@@ -641,6 +657,7 @@ struct logio_entry_24xx {
uint16_t control_flags; /* Control flags. */
/* Modifiers. */
#define LCF_INCLUDE_SNS BIT_10 /* Include SNS (FFFFFC) during LOGO. */
#define LCF_FCP2_OVERRIDE BIT_9 /* Set/Reset word 3 of PRLI. */
#define LCF_CLASS_2 BIT_8 /* Enable class 2 during PLOGI. */
#define LCF_FREE_NPORT BIT_7 /* Release NPORT handle after LOGO. */
@@ -702,7 +719,7 @@ struct tsk_mgmt_entry {
uint16_t timeout; /* Command timeout. */
uint8_t lun[8]; /* FCP LUN (BE). */
struct scsi_lun lun; /* FCP LUN (BE). */
uint32_t control_flags; /* Control Flags. */
#define TCF_NOTMCMD_TO_TARGET BIT_31
@@ -762,6 +779,8 @@ struct device_reg_24xx {
#define FA_NVRAM_VPD_SIZE 0x200
#define FA_NVRAM_VPD0_ADDR 0x00
#define FA_NVRAM_VPD1_ADDR 0x100
#define FA_BOOT_CODE_ADDR 0x00000
/*
* RISC code begins at offset 512KB
* within flash. Consisting of two
@@ -770,6 +789,27 @@ struct device_reg_24xx {
#define FA_RISC_CODE_ADDR 0x20000
#define FA_RISC_CODE_SEGMENTS 2
#define FA_FW_AREA_ADDR 0x40000
#define FA_VPD_NVRAM_ADDR 0x48000
#define FA_FEATURE_ADDR 0x4C000
#define FA_FLASH_DESCR_ADDR 0x50000
#define FA_HW_EVENT0_ADDR 0x54000
#define FA_HW_EVENT1_ADDR 0x54200
#define FA_HW_EVENT_SIZE 0x200
#define FA_HW_EVENT_ENTRY_SIZE 4
/*
* Flash Error Log Event Codes.
*/
#define HW_EVENT_RESET_ERR 0xF00B
#define HW_EVENT_ISP_ERR 0xF020
#define HW_EVENT_PARITY_ERR 0xF022
#define HW_EVENT_NVRAM_CHKSUM_ERR 0xF023
#define HW_EVENT_FLASH_FW_ERR 0xF024
#define FA_BOOT_LOG_ADDR 0x58000
#define FA_FW_DUMP0_ADDR 0x60000
#define FA_FW_DUMP1_ADDR 0x70000
uint32_t flash_data; /* Flash/NVRAM BIOS data. */
uint32_t ctrl_status; /* Control/Status. */
@@ -850,10 +890,13 @@ struct device_reg_24xx {
#define HCCRX_CLR_RISC_INT 0xA0000000
uint32_t gpiod; /* GPIO Data register. */
/* LED update mask. */
#define GPDX_LED_UPDATE_MASK (BIT_20|BIT_19|BIT_18)
/* Data update mask. */
#define GPDX_DATA_UPDATE_MASK (BIT_17|BIT_16)
/* Data update mask. */
#define GPDX_DATA_UPDATE_2_MASK (BIT_28|BIT_27|BIT_26|BIT_17|BIT_16)
/* LED control mask. */
#define GPDX_LED_COLOR_MASK (BIT_4|BIT_3|BIT_2)
/* LED bit values. Color names as
@@ -868,6 +911,8 @@ struct device_reg_24xx {
uint32_t gpioe; /* GPIO Enable register. */
/* Enable update mask. */
#define GPEX_ENABLE_UPDATE_MASK (BIT_17|BIT_16)
/* Enable update mask. */
#define GPEX_ENABLE_UPDATE_2_MASK (BIT_28|BIT_27|BIT_26|BIT_17|BIT_16)
/* Enable. */
#define GPEX_ENABLE (BIT_1|BIT_0)
@@ -907,11 +952,43 @@ struct device_reg_24xx {
uint16_t mailbox29;
uint16_t mailbox30;
uint16_t mailbox31;
uint32_t iobase_window;
uint32_t iobase_c4;
uint32_t iobase_c8;
uint32_t unused_4_1[6]; /* Gap. */
uint32_t iobase_q;
uint32_t unused_5[2]; /* Gap. */
uint32_t iobase_select;
uint32_t unused_6[2]; /* Gap. */
uint32_t iobase_sdata;
};
/* Trace Control *************************************************************/
#define TC_AEN_DISABLE 0
#define TC_EFT_ENABLE 4
#define TC_EFT_DISABLE 5
#define TC_FCE_ENABLE 8
#define TC_FCE_OPTIONS 0
#define TC_FCE_DEFAULT_RX_SIZE 2112
#define TC_FCE_DEFAULT_TX_SIZE 2112
#define TC_FCE_DISABLE 9
#define TC_FCE_DISABLE_TRACE BIT_0
/* MID Support ***************************************************************/
#define MAX_MID_VPS 125
#define MIN_MULTI_ID_FABRIC 64 /* Must be power-of-2. */
#define MAX_MULTI_ID_FABRIC 256 /* ... */
#define for_each_mapped_vp_idx(_ha, _idx) \
for (_idx = find_next_bit((_ha)->vp_idx_map, \
(_ha)->max_npiv_vports + 1, 1); \
_idx <= (_ha)->max_npiv_vports; \
_idx = find_next_bit((_ha)->vp_idx_map, \
(_ha)->max_npiv_vports + 1, _idx + 1)) \
struct mid_conf_entry_24xx {
uint16_t reserved_1;
@@ -939,7 +1016,7 @@ struct mid_init_cb_24xx {
uint16_t count;
uint16_t options;
struct mid_conf_entry_24xx entries[MAX_MID_VPS];
struct mid_conf_entry_24xx entries[MAX_MULTI_ID_FABRIC];
};
@@ -959,10 +1036,9 @@ struct mid_db_entry_24xx {
uint8_t reserved_1;
};
struct mid_db_24xx {
struct mid_db_entry_24xx entries[MAX_MID_VPS];
};
/*
* Virtual Port Control IOCB
*/
#define VP_CTRL_IOCB_TYPE 0x30 /* Vitual Port Control entry. */
struct vp_ctrl_entry_24xx {
uint8_t entry_type; /* Entry type. */
@@ -975,6 +1051,7 @@ struct vp_ctrl_entry_24xx {
uint16_t vp_idx_failed;
uint16_t comp_status; /* Completion status. */
#define CS_VCE_IOCB_ERROR 0x01 /* Error processing IOCB */
#define CS_VCE_ACQ_ID_ERROR 0x02 /* Error while acquireing ID. */
#define CS_VCE_BUSY 0x05 /* Firmware not ready to accept cmd. */
@@ -983,24 +1060,34 @@ struct vp_ctrl_entry_24xx {
#define VCE_COMMAND_DISABLE_VPS 0x08 /* Disable VPs. */
#define VCE_COMMAND_DISABLE_VPS_REINIT 0x09 /* Disable VPs and reinit link. */
#define VCE_COMMAND_DISABLE_VPS_LOGO 0x0a /* Disable VPs and LOGO ports. */
#define VCE_COMMAND_DISABLE_VPS_LOGO_ALL 0x0b /* Disable VPs and LOGO ports. */
uint16_t vp_count;
uint8_t vp_idx_map[16];
uint8_t reserved_4[32];
uint16_t flags;
uint16_t id;
uint16_t reserved_4;
uint16_t hopct;
uint8_t reserved_5[24];
};
/*
* Modify Virtual Port Configuration IOCB
*/
#define VP_CONFIG_IOCB_TYPE 0x31 /* Vitual Port Config entry. */
struct vp_config_entry_24xx {
uint8_t entry_type; /* Entry type. */
uint8_t entry_count; /* Entry count. */
uint8_t sys_define; /* System defined. */
uint8_t handle_count;
uint8_t entry_status; /* Entry Status. */
uint32_t handle; /* System handle. */
uint16_t reserved_1;
uint16_t flags;
#define CS_VF_BIND_VPORTS_TO_VF BIT_0
#define CS_VF_SET_QOS_OF_VPORTS BIT_1
#define CS_VF_SET_HOPS_OF_VPORTS BIT_2
uint16_t comp_status; /* Completion status. */
#define CS_VCT_STS_ERROR 0x01 /* Specified VPs were not disabled. */
@@ -1010,27 +1097,29 @@ struct vp_config_entry_24xx {
#define CS_VCT_BUSY 0x05 /* Firmware not ready to accept cmd. */
uint8_t command;
#define VCT_COMMAND_MOD_VPS 0x00 /* Enable VPs. */
#define VCT_COMMAND_MOD_ENABLE_VPS 0x08 /* Disable VPs. */
#define VCT_COMMAND_MOD_VPS 0x00 /* Modify VP configurations. */
#define VCT_COMMAND_MOD_ENABLE_VPS 0x01 /* Modify configuration & enable VPs. */
uint8_t vp_count;
uint8_t vp_idx1;
uint8_t vp_idx2;
uint8_t vp_index1;
uint8_t vp_index2;
uint8_t options_idx1;
uint8_t hard_address_idx1;
uint16_t reserved_2;
uint16_t reserved_vp1;
uint8_t port_name_idx1[WWN_SIZE];
uint8_t node_name_idx1[WWN_SIZE];
uint8_t options_idx2;
uint8_t hard_address_idx2;
uint16_t reserved_3;
uint16_t reserved_vp2;
uint8_t port_name_idx2[WWN_SIZE];
uint8_t node_name_idx2[WWN_SIZE];
uint8_t reserved_4[8];
uint16_t id;
uint16_t reserved_4;
uint16_t hopct;
uint8_t reserved_5;
};
#define VP_RPT_ID_IOCB_TYPE 0x32 /* Report ID Acquisition entry. */
@@ -1055,5 +1144,185 @@ struct vp_rpt_id_entry_24xx {
uint8_t reserved_4[32];
};
#define VF_EVFP_IOCB_TYPE 0x26 /* Exchange Virtual Fabric Parameters entry. */
struct vf_evfp_entry_24xx {
uint8_t entry_type; /* Entry type. */
uint8_t entry_count; /* Entry count. */
uint8_t sys_define; /* System defined. */
uint8_t entry_status; /* Entry Status. */
uint32_t handle; /* System handle. */
uint16_t comp_status; /* Completion status. */
uint16_t timeout; /* timeout */
uint16_t adim_tagging_mode;
uint16_t vfport_id;
uint32_t exch_addr;
uint16_t nport_handle; /* N_PORT handle. */
uint16_t control_flags;
uint32_t io_parameter_0;
uint32_t io_parameter_1;
uint32_t tx_address[2]; /* Data segment 0 address. */
uint32_t tx_len; /* Data segment 0 length. */
uint32_t rx_address[2]; /* Data segment 1 address. */
uint32_t rx_len; /* Data segment 1 length. */
};
/* END MID Support ***********************************************************/
/* Flash Description Table ***************************************************/
struct qla_fdt_layout {
uint8_t sig[4];
uint16_t version;
uint16_t len;
uint16_t checksum;
uint8_t unused1[2];
uint8_t model[16];
uint16_t man_id;
uint16_t id;
uint8_t flags;
uint8_t erase_cmd;
uint8_t alt_erase_cmd;
uint8_t wrt_enable_cmd;
uint8_t wrt_enable_bits;
uint8_t wrt_sts_reg_cmd;
uint8_t unprotect_sec_cmd;
uint8_t read_man_id_cmd;
uint32_t block_size;
uint32_t alt_block_size;
uint32_t flash_size;
uint32_t wrt_enable_data;
uint8_t read_id_addr_len;
uint8_t wrt_disable_bits;
uint8_t read_dev_id_len;
uint8_t chip_erase_cmd;
uint16_t read_timeout;
uint8_t protect_sec_cmd;
uint8_t unused2[65];
};
/* 84XX Support **************************************************************/
#define MBA_ISP84XX_ALERT 0x800f /* Alert Notification. */
#define A84_PANIC_RECOVERY 0x1
#define A84_OP_LOGIN_COMPLETE 0x2
#define A84_DIAG_LOGIN_COMPLETE 0x3
#define A84_GOLD_LOGIN_COMPLETE 0x4
#define MBC_ISP84XX_RESET 0x3a /* Reset. */
#define FSTATE_REMOTE_FC_DOWN BIT_0
#define FSTATE_NSL_LINK_DOWN BIT_1
#define FSTATE_IS_DIAG_FW BIT_2
#define FSTATE_LOGGED_IN BIT_3
#define FSTATE_WAITING_FOR_VERIFY BIT_4
#define VERIFY_CHIP_IOCB_TYPE 0x1B
struct verify_chip_entry_84xx {
uint8_t entry_type;
uint8_t entry_count;
uint8_t sys_defined;
uint8_t entry_status;
uint32_t handle;
uint16_t options;
#define VCO_DONT_UPDATE_FW BIT_0
#define VCO_FORCE_UPDATE BIT_1
#define VCO_DONT_RESET_UPDATE BIT_2
#define VCO_DIAG_FW BIT_3
#define VCO_END_OF_DATA BIT_14
#define VCO_ENABLE_DSD BIT_15
uint16_t reserved_1;
uint16_t data_seg_cnt;
uint16_t reserved_2[3];
uint32_t fw_ver;
uint32_t exchange_address;
uint32_t reserved_3[3];
uint32_t fw_size;
uint32_t fw_seq_size;
uint32_t relative_offset;
uint32_t dseg_address[2];
uint32_t dseg_length;
};
struct verify_chip_rsp_84xx {
uint8_t entry_type;
uint8_t entry_count;
uint8_t sys_defined;
uint8_t entry_status;
uint32_t handle;
uint16_t comp_status;
#define CS_VCS_CHIP_FAILURE 0x3
#define CS_VCS_BAD_EXCHANGE 0x8
#define CS_VCS_SEQ_COMPLETEi 0x40
uint16_t failure_code;
#define VFC_CHECKSUM_ERROR 0x1
#define VFC_INVALID_LEN 0x2
#define VFC_ALREADY_IN_PROGRESS 0x8
uint16_t reserved_1[4];
uint32_t fw_ver;
uint32_t exchange_address;
uint32_t reserved_2[6];
};
#define ACCESS_CHIP_IOCB_TYPE 0x2B
struct access_chip_84xx {
uint8_t entry_type;
uint8_t entry_count;
uint8_t sys_defined;
uint8_t entry_status;
uint32_t handle;
uint16_t options;
#define ACO_DUMP_MEMORY 0x0
#define ACO_LOAD_MEMORY 0x1
#define ACO_CHANGE_CONFIG_PARAM 0x2
#define ACO_REQUEST_INFO 0x3
uint16_t reserved1;
uint16_t dseg_count;
uint16_t reserved2[3];
uint32_t parameter1;
uint32_t parameter2;
uint32_t parameter3;
uint32_t reserved3[3];
uint32_t total_byte_cnt;
uint32_t reserved4;
uint32_t dseg_address[2];
uint32_t dseg_length;
};
struct access_chip_rsp_84xx {
uint8_t entry_type;
uint8_t entry_count;
uint8_t sys_defined;
uint8_t entry_status;
uint32_t handle;
uint16_t comp_status;
uint16_t failure_code;
uint32_t residual_count;
uint32_t reserved[12];
};
#endif
+111 -87
View File
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2005 QLogic Corporation
* Copyright (c) 2003-2008 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -9,9 +9,6 @@
#include <linux/interrupt.h>
extern void qla2x00_remove_one(struct pci_dev *);
extern int qla2x00_probe_one(struct pci_dev *, struct qla_board_info *);
/*
* Global Function Prototypes in qla_init.c source file.
*/
@@ -20,6 +17,7 @@ extern int qla2x00_initialize_adapter(scsi_qla_host_t *);
extern int qla2100_pci_config(struct scsi_qla_host *);
extern int qla2300_pci_config(struct scsi_qla_host *);
extern int qla24xx_pci_config(scsi_qla_host_t *);
extern int qla25xx_pci_config(scsi_qla_host_t *);
extern void qla2x00_reset_chip(struct scsi_qla_host *);
extern void qla24xx_reset_chip(struct scsi_qla_host *);
extern int qla2x00_chip_diag(struct scsi_qla_host *);
@@ -34,25 +32,22 @@ extern void qla2x00_update_fw_options(struct scsi_qla_host *);
extern void qla24xx_update_fw_options(scsi_qla_host_t *);
extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *);
extern int qla24xx_load_risc(scsi_qla_host_t *, uint32_t *);
extern int qla24xx_load_risc_flash(scsi_qla_host_t *, uint32_t *);
extern fc_port_t *qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t);
extern int qla2x00_loop_resync(scsi_qla_host_t *);
extern int qla2x00_find_new_loop_id(scsi_qla_host_t *, fc_port_t *);
extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *);
extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *);
extern void qla2x00_restart_queues(scsi_qla_host_t *, uint8_t);
extern void qla2x00_rescan_fcports(scsi_qla_host_t *);
extern void qla2x00_update_fcports(scsi_qla_host_t *);
extern int qla2x00_abort_isp(scsi_qla_host_t *);
extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);
extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *);
extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *);
extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *);
extern void qla84xx_put_chip(struct scsi_qla_host *);
/*
* Global Data in qla_os.c source file.
@@ -64,30 +59,59 @@ extern int qlport_down_retry;
extern int ql2xplogiabsentdevice;
extern int ql2xloginretrycount;
extern int ql2xfdmienable;
extern int ql2xprocessrscn;
extern int ql2xallocfwdump;
extern int ql2xextended_error_logging;
extern int ql2xqfullrampup;
extern int num_hosts;
extern int qla2x00_loop_reset(scsi_qla_host_t *);
extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum
fc_host_event_code, u32);
extern int qla2x00_post_hwe_work(struct scsi_qla_host *, uint16_t , uint16_t,
uint16_t, uint16_t);
/*
* Global Functions in qla_mid.c source file.
*/
extern struct scsi_host_template qla24xx_driver_template;
extern struct scsi_transport_template *qla2xxx_transport_vport_template;
extern void qla2x00_timer(scsi_qla_host_t *);
extern void qla2x00_start_timer(scsi_qla_host_t *, void *, unsigned long);
extern void qla24xx_deallocate_vp_id(scsi_qla_host_t *);
extern int qla24xx_disable_vp (scsi_qla_host_t *);
extern int qla24xx_enable_vp (scsi_qla_host_t *);
extern int qla24xx_control_vp(scsi_qla_host_t *, int );
extern int qla24xx_modify_vp_config(scsi_qla_host_t *);
extern int qla2x00_send_change_request(scsi_qla_host_t *, uint16_t, uint16_t);
extern void qla2x00_vp_stop_timer(scsi_qla_host_t *);
extern int qla24xx_configure_vhba (scsi_qla_host_t *);
extern void qla24xx_report_id_acquisition(scsi_qla_host_t *,
struct vp_rpt_id_entry_24xx *);
extern void qla2x00_do_dpc_all_vps(scsi_qla_host_t *);
extern int qla24xx_vport_create_req_sanity_check(struct fc_vport *);
extern scsi_qla_host_t * qla24xx_create_vhost(struct fc_vport *);
extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *);
extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *);
extern void qla2x00_cmd_timeout(srb_t *);
extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int);
extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int);
extern int qla2x00_down_timeout(struct semaphore *, unsigned long);
extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *);
extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *);
extern void qla2xxx_wake_dpc(scsi_qla_host_t *);
extern void qla2x00_alert_all_vps(scsi_qla_host_t *, uint16_t *);
extern void qla2x00_async_event(scsi_qla_host_t *, uint16_t *);
extern void qla2x00_vp_abort_isp(scsi_qla_host_t *);
/*
* 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);
@@ -100,9 +124,15 @@ 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);
extern int
qla2x00_dump_ram(scsi_qla_host_t *, dma_addr_t, uint32_t, uint32_t);
extern int
qla2x00_execute_fw(scsi_qla_host_t *, uint32_t);
@@ -128,14 +158,15 @@ qla2x00_issue_iocb(scsi_qla_host_t *, void *, dma_addr_t, size_t);
extern int
qla2x00_abort_command(scsi_qla_host_t *, srb_t *);
#if USE_ABORT_TGT
extern int
qla2x00_abort_target(fc_port_t *);
#endif
qla2x00_abort_target(struct fc_port *, unsigned int);
extern int
qla2x00_lun_reset(struct fc_port *, unsigned int);
extern int
qla2x00_get_adapter_id(scsi_qla_host_t *, uint16_t *, uint8_t *, uint8_t *,
uint8_t *, uint16_t *);
uint8_t *, uint16_t *, uint16_t *);
extern int
qla2x00_get_retry_cnt(scsi_qla_host_t *, uint8_t *, uint8_t *, uint16_t *);
@@ -182,27 +213,26 @@ extern int
qla2x00_get_id_list(scsi_qla_host_t *, void *, dma_addr_t, uint16_t *);
extern int
qla2x00_get_resource_cnts(scsi_qla_host_t *, uint16_t *, uint16_t *, uint16_t *,
uint16_t *);
qla2x00_get_resource_cnts(scsi_qla_host_t *, uint16_t *, uint16_t *,
uint16_t *, uint16_t *, uint16_t *);
extern int
qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map);
extern int
qla2x00_get_link_status(scsi_qla_host_t *, uint16_t, link_stat_t *,
uint16_t *);
qla2x00_get_link_status(scsi_qla_host_t *, uint16_t, struct link_statistics *,
dma_addr_t);
extern int
qla24xx_get_isp_stats(scsi_qla_host_t *, uint32_t *, uint32_t, uint16_t *);
qla24xx_get_isp_stats(scsi_qla_host_t *, struct link_statistics *,
dma_addr_t);
extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *);
extern int qla24xx_abort_target(fc_port_t *);
extern int qla2x00_system_error(scsi_qla_host_t *);
extern int qla24xx_abort_target(struct fc_port *, unsigned int);
extern int qla24xx_lun_reset(struct fc_port *, unsigned int);
extern int
qla2x00_get_serdes_params(scsi_qla_host_t *, uint16_t *, uint16_t *,
uint16_t *);
qla2x00_system_error(scsi_qla_host_t *);
extern int
qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);
@@ -210,29 +240,42 @@ qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);
extern int
qla2x00_stop_firmware(scsi_qla_host_t *);
extern int
qla2x00_enable_eft_trace(scsi_qla_host_t *, dma_addr_t, uint16_t);
extern int
qla2x00_disable_eft_trace(scsi_qla_host_t *);
extern int
qla2x00_enable_fce_trace(scsi_qla_host_t *, dma_addr_t, uint16_t , uint16_t *,
uint32_t *);
extern int
qla2x00_disable_fce_trace(scsi_qla_host_t *, uint64_t *, uint64_t *);
extern int
qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t);
extern int
qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *);
extern int qla84xx_verify_chip(struct scsi_qla_host *, uint16_t *);
/*
* Global Function Prototypes in qla_isr.c source file.
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
extern irqreturn_t qla2100_intr_handler(int, void *, struct pt_regs *);
extern irqreturn_t qla2300_intr_handler(int, void *, struct pt_regs *);
extern irqreturn_t qla24xx_intr_handler(int, void *, struct pt_regs *);
#else
extern irqreturn_t qla2100_intr_handler(int, void *);
extern irqreturn_t qla2300_intr_handler(int, void *);
extern irqreturn_t qla24xx_intr_handler(int, void *);
#endif
extern void qla2x00_process_response_queue(struct scsi_qla_host *);
extern void qla24xx_process_response_queue(struct scsi_qla_host *);
extern int qla2x00_request_irqs(scsi_qla_host_t *);
extern void qla2x00_free_irqs(scsi_qla_host_t *);
/*
* Global Function Prototypes in qla_sup.c source file.
*/
extern void qla2x00_lock_nvram_access(scsi_qla_host_t *);
extern void qla2x00_unlock_nvram_access(scsi_qla_host_t *);
extern void qla2x00_release_nvram_protection(scsi_qla_host_t *);
extern uint16_t qla2x00_get_nvram_word(scsi_qla_host_t *, uint32_t);
extern void qla2x00_write_nvram_word(scsi_qla_host_t *, uint32_t, uint16_t);
extern uint32_t *qla24xx_read_flash_data(scsi_qla_host_t *, uint32_t *,
uint32_t, uint32_t);
extern uint8_t *qla2x00_read_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
@@ -243,6 +286,10 @@ extern int qla2x00_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
uint32_t);
extern int qla24xx_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
uint32_t);
extern uint8_t *qla25xx_read_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
uint32_t);
extern int qla25xx_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
uint32_t);
extern int qla2x00_beacon_on(struct scsi_qla_host *);
extern int qla2x00_beacon_off(struct scsi_qla_host *);
@@ -259,6 +306,16 @@ extern uint8_t *qla24xx_read_optrom_data(struct scsi_qla_host *, uint8_t *,
uint32_t, uint32_t);
extern int qla24xx_write_optrom_data(struct scsi_qla_host *, uint8_t *,
uint32_t, uint32_t);
extern uint8_t *qla25xx_read_optrom_data(struct scsi_qla_host *, uint8_t *,
uint32_t, uint32_t);
extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *);
extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *);
extern int qla2xxx_hw_event_log(scsi_qla_host_t *, uint16_t , uint16_t,
uint16_t, uint16_t);
extern void qla2xxx_get_flash_info(scsi_qla_host_t *);
/*
* Global Function Prototypes in qla_dbg.c source file.
@@ -266,13 +323,9 @@ extern int qla24xx_write_optrom_data(struct scsi_qla_host *, uint8_t *,
extern void qla2100_fw_dump(scsi_qla_host_t *, int);
extern void qla2300_fw_dump(scsi_qla_host_t *, int);
extern void qla24xx_fw_dump(scsi_qla_host_t *, int);
extern void qla2100_ascii_fw_dump(scsi_qla_host_t *);
extern void qla2300_ascii_fw_dump(scsi_qla_host_t *);
extern void qla24xx_ascii_fw_dump(scsi_qla_host_t *);
extern void qla25xx_fw_dump(scsi_qla_host_t *, int);
extern void qla2x00_dump_regs(scsi_qla_host_t *);
extern void qla2x00_dump_buffer(uint8_t *, uint32_t);
extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *);
extern void qla2x00_dump_pkt(void *);
/*
* Global Function Prototypes in qla_gs.c source file.
@@ -290,56 +343,27 @@ extern int qla2x00_rsnn_nn(scsi_qla_host_t *);
extern void *qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
extern void *qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
extern int qla2x00_fdmi_register(scsi_qla_host_t *);
/*
* Global Function Prototypes in qla_rscn.c source file.
*/
extern fc_port_t *qla2x00_alloc_rscn_fcport(scsi_qla_host_t *, gfp_t);
extern int qla2x00_handle_port_rscn(scsi_qla_host_t *, uint32_t, fc_port_t *,
int);
extern void qla2x00_process_iodesc(scsi_qla_host_t *, struct mbx_entry *);
extern void qla2x00_cancel_io_descriptors(scsi_qla_host_t *);
/*
* Global Function Prototypes in qla_xioctl.c source file.
*/
#define qla2x00_enqueue_aen(ha, cmd, mode) do { } while (0)
#define qla2x00_alloc_ioctl_mem(ha) (0)
#define qla2x00_free_ioctl_mem(ha) do { } while (0)
extern int qla2x00_gfpn_id(scsi_qla_host_t *, sw_info_t *);
extern int qla2x00_gpsc(scsi_qla_host_t *, sw_info_t *);
extern void qla2x00_get_sym_node_name(scsi_qla_host_t *, uint8_t *);
/*
* Global Function Prototypes in qla_attr.c source file.
*/
struct class_device_attribute;
extern struct class_device_attribute *qla2x00_host_attrs[];
struct device_attribute;
extern struct device_attribute *qla2x00_host_attrs[];
struct fc_function_template;
extern struct fc_function_template qla2xxx_transport_functions;
extern struct fc_function_template qla2xxx_transport_vport_functions;
extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *);
extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *);
extern void qla2x00_init_host_attr(scsi_qla_host_t *);
extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *);
extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
static inline void scsi_set_resid(struct scsi_cmnd *cmd, int resid)
{
cmd->resid = resid;
}
static inline struct scatterlist *scsi_sglist(struct scsi_cmnd *cmd)
{
return (struct scatterlist *)cmd->request_buffer;
}
static inline unsigned scsi_bufflen(struct scsi_cmnd *cmd)
{
return cmd->request_bufflen;
}
static inline unsigned scsi_sg_count(struct scsi_cmnd *cmd)
{
return cmd->use_sg;
}
#endif
/*
* Global Function Prototypes in qla_dfs.c source file.
*/
extern int qla2x00_dfs_setup(scsi_qla_host_t *);
extern int qla2x00_dfs_remove(scsi_qla_host_t *);
#endif /* _QLA_GBL_H */
+306 -61
View File
@@ -1,17 +1,11 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2005 QLogic Corporation
* Copyright (c) 2003-2008 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
static inline struct ct_sns_req *
qla2x00_prep_ct_req(struct ct_sns_req *, uint16_t, uint16_t);
static inline struct sns_cmd_pkt *
qla2x00_prep_sns_cmd(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);
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 *);
static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *);
@@ -39,7 +33,7 @@ qla2x00_prep_ms_iocb(scsi_qla_host_t *ha, uint32_t req_size, uint32_t rsp_size)
ms_pkt->entry_count = 1;
SET_TARGET_ID(ha, ms_pkt->loop_id, SIMPLE_NAME_SERVER);
ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG);
ms_pkt->timeout = __constant_cpu_to_le16(25);
ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
ms_pkt->total_dsd_count = __constant_cpu_to_le16(2);
ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
@@ -75,7 +69,7 @@ qla24xx_prep_ms_iocb(scsi_qla_host_t *ha, uint32_t req_size, uint32_t rsp_size)
ct_pkt->entry_type = CT_IOCB_TYPE;
ct_pkt->entry_count = 1;
ct_pkt->nport_handle = __constant_cpu_to_le16(NPH_SNS);
ct_pkt->timeout = __constant_cpu_to_le16(25);
ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
@@ -88,6 +82,7 @@ qla24xx_prep_ms_iocb(scsi_qla_host_t *ha, uint32_t req_size, uint32_t rsp_size)
ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
ct_pkt->vp_index = ha->vp_idx;
return (ct_pkt);
}
@@ -126,9 +121,9 @@ qla2x00_chk_ms_status(scsi_qla_host_t *ha, ms_iocb_entry_t *ms_pkt,
DEBUG2_3(printk("scsi(%ld): %s failed, error status (%x).\n",
ha->host_no, routine, ms_pkt->entry_status));
} else {
if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
comp_status =
((struct ct_entry_24xx *)ms_pkt)->comp_status;
if (IS_FWI2_CAPABLE(ha))
comp_status = le16_to_cpu(
((struct ct_entry_24xx *)ms_pkt)->comp_status);
else
comp_status = le16_to_cpu(ms_pkt->status);
switch (comp_status) {
@@ -143,6 +138,7 @@ qla2x00_chk_ms_status(scsi_qla_host_t *ha, ms_iocb_entry_t *ms_pkt,
DEBUG2_3(qla2x00_dump_buffer(
(uint8_t *)&ct_rsp->header,
sizeof(struct ct_rsp_hdr)));
rval = QLA_INVALID_COMMAND;
} else
rval = QLA_SUCCESS;
break;
@@ -178,7 +174,8 @@ qla2x00_ga_nxt(scsi_qla_host_t *ha, fc_port_t *fcport)
/* Issue GA_NXT */
/* Prepare common MS IOCB */
ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GA_NXT_REQ_SIZE, GA_NXT_RSP_SIZE);
ms_pkt = ha->isp_ops->prep_ms_iocb(ha, GA_NXT_REQ_SIZE,
GA_NXT_RSP_SIZE);
/* Prepare CT request */
ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GA_NXT_CMD,
@@ -264,7 +261,8 @@ qla2x00_gid_pt(scsi_qla_host_t *ha, sw_info_t *list)
/* Issue GID_PT */
/* Prepare common MS IOCB */
ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GID_PT_REQ_SIZE, GID_PT_RSP_SIZE);
ms_pkt = ha->isp_ops->prep_ms_iocb(ha, GID_PT_REQ_SIZE,
GID_PT_RSP_SIZE);
/* Prepare CT request */
ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GID_PT_CMD,
@@ -291,6 +289,8 @@ qla2x00_gid_pt(scsi_qla_host_t *ha, sw_info_t *list)
list[i].d_id.b.domain = gid_data->port_id[0];
list[i].d_id.b.area = gid_data->port_id[1];
list[i].d_id.b.al_pa = gid_data->port_id[2];
memset(list[i].fabric_port_name, 0, WWN_SIZE);
list[i].fp_speed = PORT_SPEED_UNKNOWN;
/* Last one exit. */
if (gid_data->control_byte & BIT_7) {
@@ -336,7 +336,7 @@ qla2x00_gpn_id(scsi_qla_host_t *ha, sw_info_t *list)
for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
/* Issue GPN_ID */
/* Prepare common MS IOCB */
ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GPN_ID_REQ_SIZE,
ms_pkt = ha->isp_ops->prep_ms_iocb(ha, GPN_ID_REQ_SIZE,
GPN_ID_RSP_SIZE);
/* Prepare CT request */
@@ -397,7 +397,7 @@ qla2x00_gnn_id(scsi_qla_host_t *ha, sw_info_t *list)
for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
/* Issue GNN_ID */
/* Prepare common MS IOCB */
ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GNN_ID_REQ_SIZE,
ms_pkt = ha->isp_ops->prep_ms_iocb(ha, GNN_ID_REQ_SIZE,
GNN_ID_RSP_SIZE);
/* Prepare CT request */
@@ -471,7 +471,8 @@ qla2x00_rft_id(scsi_qla_host_t *ha)
/* Issue RFT_ID */
/* Prepare common MS IOCB */
ms_pkt = ha->isp_ops.prep_ms_iocb(ha, RFT_ID_REQ_SIZE, RFT_ID_RSP_SIZE);
ms_pkt = ha->isp_ops->prep_ms_iocb(ha, RFT_ID_REQ_SIZE,
RFT_ID_RSP_SIZE);
/* Prepare CT request */
ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFT_ID_CMD,
@@ -526,7 +527,8 @@ qla2x00_rff_id(scsi_qla_host_t *ha)
/* Issue RFF_ID */
/* Prepare common MS IOCB */
ms_pkt = ha->isp_ops.prep_ms_iocb(ha, RFF_ID_REQ_SIZE, RFF_ID_RSP_SIZE);
ms_pkt = ha->isp_ops->prep_ms_iocb(ha, RFF_ID_REQ_SIZE,
RFF_ID_RSP_SIZE);
/* Prepare CT request */
ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFF_ID_CMD,
@@ -538,7 +540,7 @@ qla2x00_rff_id(scsi_qla_host_t *ha)
ct_req->req.rff_id.port_id[1] = ha->d_id.b.area;
ct_req->req.rff_id.port_id[2] = ha->d_id.b.al_pa;
#ifdef FC_TARGET_SUPPORT
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
/*
* FC-4 Feature bit 0 indicates target functionality to the name server.
*/
@@ -589,7 +591,8 @@ qla2x00_rnn_id(scsi_qla_host_t *ha)
/* Issue RNN_ID */
/* Prepare common MS IOCB */
ms_pkt = ha->isp_ops.prep_ms_iocb(ha, RNN_ID_REQ_SIZE, RNN_ID_RSP_SIZE);
ms_pkt = ha->isp_ops->prep_ms_iocb(ha, RNN_ID_REQ_SIZE,
RNN_ID_RSP_SIZE);
/* Prepare CT request */
ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RNN_ID_CMD,
@@ -621,6 +624,14 @@ qla2x00_rnn_id(scsi_qla_host_t *ha)
return (rval);
}
void
qla2x00_get_sym_node_name(scsi_qla_host_t *ha, uint8_t *snn)
{
sprintf(snn, "%s FW:v%d.%02d.%02d DVR:v%s",ha->model_number,
ha->fw_major_version, ha->fw_minor_version,
ha->fw_subminor_version, qla2x00_version_str);
}
/**
* qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA.
* @ha: HA context
@@ -631,9 +642,6 @@ int
qla2x00_rsnn_nn(scsi_qla_host_t *ha)
{
int rval;
uint8_t *snn;
uint8_t version[20];
ms_iocb_entry_t *ms_pkt;
struct ct_sns_req *ct_req;
struct ct_sns_rsp *ct_rsp;
@@ -647,7 +655,7 @@ qla2x00_rsnn_nn(scsi_qla_host_t *ha)
/* Issue RSNN_NN */
/* Prepare common MS IOCB */
/* Request size adjusted after CT preparation */
ms_pkt = ha->isp_ops.prep_ms_iocb(ha, 0, RSNN_NN_RSP_SIZE);
ms_pkt = ha->isp_ops->prep_ms_iocb(ha, 0, RSNN_NN_RSP_SIZE);
/* Prepare CT request */
ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RSNN_NN_CMD,
@@ -658,20 +666,11 @@ qla2x00_rsnn_nn(scsi_qla_host_t *ha)
memcpy(ct_req->req.rsnn_nn.node_name, ha->node_name, WWN_SIZE);
/* Prepare the Symbolic Node Name */
/* Board type */
snn = ct_req->req.rsnn_nn.sym_node_name;
strcpy(snn, ha->model_number);
/* Firmware version */
strcat(snn, " FW:v");
sprintf(version, "%d.%02d.%02d", ha->fw_major_version,
ha->fw_minor_version, ha->fw_subminor_version);
strcat(snn, version);
/* Driver version */
strcat(snn, " DVR:v");
strcat(snn, qla2x00_version_str);
qla2x00_get_sym_node_name(ha, ct_req->req.rsnn_nn.sym_node_name);
/* Calculate SNN length */
ct_req->req.rsnn_nn.name_len = (uint8_t)strlen(snn);
ct_req->req.rsnn_nn.name_len =
(uint8_t)strlen(ct_req->req.rsnn_nn.sym_node_name);
/* Update MS IOCB request */
ms_pkt->req_bytecount =
@@ -696,7 +695,6 @@ qla2x00_rsnn_nn(scsi_qla_host_t *ha)
return (rval);
}
/**
* qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query.
* @ha: HA context
@@ -1099,7 +1097,7 @@ qla2x00_sns_rnn_id(scsi_qla_host_t *ha)
}
/**
* qla2x00_mgmt_svr_login() - Login to fabric Managment Service.
* qla2x00_mgmt_svr_login() - Login to fabric Management Service.
* @ha: HA context
*
* Returns 0 on success.
@@ -1114,7 +1112,7 @@ qla2x00_mgmt_svr_login(scsi_qla_host_t *ha)
if (ha->flags.management_server_logged_in)
return ret;
ha->isp_ops.fabric_login(ha, ha->mgmt_svr_loop_id, 0xff, 0xff, 0xfa,
ha->isp_ops->fabric_login(ha, ha->mgmt_svr_loop_id, 0xff, 0xff, 0xfa,
mb, BIT_1);
if (mb[0] != MBS_COMMAND_COMPLETE) {
DEBUG2_13(printk("%s(%ld): Failed MANAGEMENT_SERVER login: "
@@ -1149,7 +1147,7 @@ qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size,
ms_pkt->entry_count = 1;
SET_TARGET_ID(ha, ms_pkt->loop_id, ha->mgmt_svr_loop_id);
ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG);
ms_pkt->timeout = __constant_cpu_to_le16(59);
ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
ms_pkt->total_dsd_count = __constant_cpu_to_le16(2);
ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
@@ -1186,7 +1184,7 @@ qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size,
ct_pkt->entry_type = CT_IOCB_TYPE;
ct_pkt->entry_count = 1;
ct_pkt->nport_handle = cpu_to_le16(ha->mgmt_svr_loop_id);
ct_pkt->timeout = __constant_cpu_to_le16(59);
ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
@@ -1199,6 +1197,7 @@ qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size,
ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
ct_pkt->vp_index = ha->vp_idx;
return ct_pkt;
}
@@ -1209,7 +1208,7 @@ qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size)
ms_iocb_entry_t *ms_pkt = ha->ms_iocb;
struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
if (IS_FWI2_CAPABLE(ha)) {
ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
} else {
@@ -1264,7 +1263,7 @@ qla2x00_fdmi_rhba(scsi_qla_host_t *ha)
/* Issue RHBA */
/* Prepare common MS IOCB */
/* Request size adjusted after CT preparation */
ms_pkt = ha->isp_ops.prep_ms_fdmi_iocb(ha, 0, RHBA_RSP_SIZE);
ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(ha, 0, RHBA_RSP_SIZE);
/* Prepare CT request */
ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RHBA_CMD,
@@ -1384,7 +1383,7 @@ qla2x00_fdmi_rhba(scsi_qla_host_t *ha)
/* Firmware version */
eiter = (struct ct_fdmi_hba_attr *) (entries + size);
eiter->type = __constant_cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION);
ha->isp_ops.fw_version_str(ha, eiter->a.fw_version);
ha->isp_ops->fw_version_str(ha, eiter->a.fw_version);
alen = strlen(eiter->a.fw_version);
alen += (alen & 3) ? (4 - (alen & 3)) : 4;
eiter->len = cpu_to_be16(4 + alen);
@@ -1450,7 +1449,7 @@ qla2x00_fdmi_dhba(scsi_qla_host_t *ha)
/* Issue RPA */
/* Prepare common MS IOCB */
ms_pkt = ha->isp_ops.prep_ms_fdmi_iocb(ha, DHBA_REQ_SIZE,
ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(ha, DHBA_REQ_SIZE,
DHBA_RSP_SIZE);
/* Prepare CT request */
@@ -1508,7 +1507,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
/* Issue RPA */
/* Prepare common MS IOCB */
/* Request size adjusted after CT preparation */
ms_pkt = ha->isp_ops.prep_ms_fdmi_iocb(ha, 0, RPA_RSP_SIZE);
ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(ha, 0, RPA_RSP_SIZE);
/* Prepare CT request */
ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RPA_CMD,
@@ -1521,7 +1520,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
/* Attributes */
ct_req->req.rpa.attrs.count =
__constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT);
__constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT - 1);
entries = ct_req->req.rpa.port_name;
/* FC4 types. */
@@ -1538,12 +1537,20 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
eiter = (struct ct_fdmi_port_attr *) (entries + size);
eiter->type = __constant_cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
eiter->len = __constant_cpu_to_be16(4 + 4);
if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
eiter->a.sup_speed = __constant_cpu_to_be32(4);
if (IS_QLA25XX(ha))
eiter->a.sup_speed = __constant_cpu_to_be32(
FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB|
FDMI_PORT_SPEED_4GB|FDMI_PORT_SPEED_8GB);
else if (IS_QLA24XX_TYPE(ha))
eiter->a.sup_speed = __constant_cpu_to_be32(
FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB|
FDMI_PORT_SPEED_4GB);
else if (IS_QLA23XX(ha))
eiter->a.sup_speed = __constant_cpu_to_be32(2);
eiter->a.sup_speed =__constant_cpu_to_be32(
FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB);
else
eiter->a.sup_speed = __constant_cpu_to_be32(1);
eiter->a.sup_speed = __constant_cpu_to_be32(
FDMI_PORT_SPEED_1GB);
size += 4 + 4;
DEBUG13(printk("%s(%ld): SUPPORTED_SPEED=%x.\n", __func__, ha->host_no,
@@ -1554,14 +1561,25 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
eiter->type = __constant_cpu_to_be16(FDMI_PORT_CURRENT_SPEED);
eiter->len = __constant_cpu_to_be16(4 + 4);
switch (ha->link_data_rate) {
case 0:
eiter->a.cur_speed = __constant_cpu_to_be32(1);
case PORT_SPEED_1GB:
eiter->a.cur_speed =
__constant_cpu_to_be32(FDMI_PORT_SPEED_1GB);
break;
case 1:
eiter->a.cur_speed = __constant_cpu_to_be32(2);
case PORT_SPEED_2GB:
eiter->a.cur_speed =
__constant_cpu_to_be32(FDMI_PORT_SPEED_2GB);
break;
case 3:
eiter->a.cur_speed = __constant_cpu_to_be32(4);
case PORT_SPEED_4GB:
eiter->a.cur_speed =
__constant_cpu_to_be32(FDMI_PORT_SPEED_4GB);
break;
case PORT_SPEED_8GB:
eiter->a.cur_speed =
__constant_cpu_to_be32(FDMI_PORT_SPEED_8GB);
break;
default:
eiter->a.cur_speed =
__constant_cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN);
break;
}
size += 4 + 4;
@@ -1573,9 +1591,9 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
eiter = (struct ct_fdmi_port_attr *) (entries + size);
eiter->type = __constant_cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE);
eiter->len = __constant_cpu_to_be16(4 + 4);
max_frame_size = IS_QLA24XX(ha) || IS_QLA54XX(ha) ?
(uint32_t) icb24->frame_payload_size:
(uint32_t) ha->init_cb->frame_payload_size;
max_frame_size = IS_FWI2_CAPABLE(ha) ?
le16_to_cpu(icb24->frame_payload_size):
le16_to_cpu(ha->init_cb->frame_payload_size);
eiter->a.max_frame_size = cpu_to_be32(max_frame_size);
size += 4 + 4;
@@ -1585,7 +1603,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
/* OS device name. */
eiter = (struct ct_fdmi_port_attr *) (entries + size);
eiter->type = __constant_cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME);
sprintf(eiter->a.os_dev_name, "/proc/scsi/qla2xxx/%ld", ha->host_no);
strcpy(eiter->a.os_dev_name, QLA2XXX_DRIVER_NAME);
alen = strlen(eiter->a.os_dev_name);
alen += (alen & 3) ? (4 - (alen & 3)) : 4;
eiter->len = cpu_to_be16(4 + alen);
@@ -1594,6 +1612,23 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
DEBUG13(printk("%s(%ld): OS_DEVICE_NAME=%s.\n", __func__, ha->host_no,
eiter->a.os_dev_name));
/* Hostname. */
if (strlen(fc_host_system_hostname(ha->host))) {
ct_req->req.rpa.attrs.count =
__constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT);
eiter = (struct ct_fdmi_port_attr *) (entries + size);
eiter->type = __constant_cpu_to_be16(FDMI_PORT_HOST_NAME);
snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
"%s", fc_host_system_hostname(ha->host));
alen = strlen(eiter->a.host_name);
alen += (alen & 3) ? (4 - (alen & 3)) : 4;
eiter->len = cpu_to_be16(4 + alen);
size += 4 + alen;
DEBUG13(printk("%s(%ld): HOSTNAME=%s.\n", __func__,
ha->host_no, eiter->a.host_name));
}
/* Update MS request size. */
qla2x00_update_ms_fdmi_iocb(ha, size + 16);
@@ -1656,3 +1691,213 @@ qla2x00_fdmi_register(scsi_qla_host_t *ha)
return rval;
}
/**
* qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query.
* @ha: HA context
* @list: switch info entries to populate
*
* Returns 0 on success.
*/
int
qla2x00_gfpn_id(scsi_qla_host_t *ha, sw_info_t *list)
{
int rval;
uint16_t i;
ms_iocb_entry_t *ms_pkt;
struct ct_sns_req *ct_req;
struct ct_sns_rsp *ct_rsp;
if (!IS_IIDMA_CAPABLE(ha))
return QLA_FUNCTION_FAILED;
for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
/* Issue GFPN_ID */
/* Prepare common MS IOCB */
ms_pkt = ha->isp_ops->prep_ms_iocb(ha, GFPN_ID_REQ_SIZE,
GFPN_ID_RSP_SIZE);
/* Prepare CT request */
ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFPN_ID_CMD,
GFPN_ID_RSP_SIZE);
ct_rsp = &ha->ct_sns->p.rsp;
/* Prepare CT arguments -- port_id */
ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
/* Execute MS IOCB */
rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
sizeof(ms_iocb_entry_t));
if (rval != QLA_SUCCESS) {
/*EMPTY*/
DEBUG2_3(printk("scsi(%ld): GFPN_ID issue IOCB "
"failed (%d).\n", ha->host_no, rval));
} else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp,
"GFPN_ID") != QLA_SUCCESS) {
rval = QLA_FUNCTION_FAILED;
} else {
/* Save fabric portname */
memcpy(list[i].fabric_port_name,
ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE);
}
/* Last device exit. */
if (list[i].d_id.b.rsvd_1 != 0)
break;
}
return (rval);
}
static inline void *
qla24xx_prep_ms_fm_iocb(scsi_qla_host_t *ha, uint32_t req_size,
uint32_t rsp_size)
{
struct ct_entry_24xx *ct_pkt;
ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
ct_pkt->entry_type = CT_IOCB_TYPE;
ct_pkt->entry_count = 1;
ct_pkt->nport_handle = cpu_to_le16(ha->mgmt_svr_loop_id);
ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
ct_pkt->vp_index = ha->vp_idx;
return ct_pkt;
}
static inline struct ct_sns_req *
qla24xx_prep_ct_fm_req(struct ct_sns_req *ct_req, uint16_t cmd,
uint16_t rsp_size)
{
memset(ct_req, 0, sizeof(struct ct_sns_pkt));
ct_req->header.revision = 0x01;
ct_req->header.gs_type = 0xFA;
ct_req->header.gs_subtype = 0x01;
ct_req->command = cpu_to_be16(cmd);
ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
return ct_req;
}
/**
* qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query.
* @ha: HA context
* @list: switch info entries to populate
*
* Returns 0 on success.
*/
int
qla2x00_gpsc(scsi_qla_host_t *ha, sw_info_t *list)
{
int rval;
uint16_t i;
ms_iocb_entry_t *ms_pkt;
struct ct_sns_req *ct_req;
struct ct_sns_rsp *ct_rsp;
if (!IS_IIDMA_CAPABLE(ha))
return QLA_FUNCTION_FAILED;
if (!ha->flags.gpsc_supported)
return QLA_FUNCTION_FAILED;
rval = qla2x00_mgmt_svr_login(ha);
if (rval)
return rval;
for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
/* Issue GFPN_ID */
/* Prepare common MS IOCB */
ms_pkt = qla24xx_prep_ms_fm_iocb(ha, GPSC_REQ_SIZE,
GPSC_RSP_SIZE);
/* Prepare CT request */
ct_req = qla24xx_prep_ct_fm_req(&ha->ct_sns->p.req,
GPSC_CMD, GPSC_RSP_SIZE);
ct_rsp = &ha->ct_sns->p.rsp;
/* Prepare CT arguments -- port_name */
memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name,
WWN_SIZE);
/* Execute MS IOCB */
rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
sizeof(ms_iocb_entry_t));
if (rval != QLA_SUCCESS) {
/*EMPTY*/
DEBUG2_3(printk("scsi(%ld): GPSC issue IOCB "
"failed (%d).\n", ha->host_no, rval));
} else if ((rval = qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp,
"GPSC")) != QLA_SUCCESS) {
/* FM command unsupported? */
if (rval == QLA_INVALID_COMMAND &&
(ct_rsp->header.reason_code ==
CT_REASON_INVALID_COMMAND_CODE ||
ct_rsp->header.reason_code ==
CT_REASON_COMMAND_UNSUPPORTED)) {
DEBUG2(printk("scsi(%ld): GPSC command "
"unsupported, disabling query...\n",
ha->host_no));
ha->flags.gpsc_supported = 0;
rval = QLA_FUNCTION_FAILED;
break;
}
rval = QLA_FUNCTION_FAILED;
} else {
/* Save port-speed */
switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) {
case BIT_15:
list[i].fp_speed = PORT_SPEED_1GB;
break;
case BIT_14:
list[i].fp_speed = PORT_SPEED_2GB;
break;
case BIT_13:
list[i].fp_speed = PORT_SPEED_4GB;
break;
case BIT_11:
list[i].fp_speed = PORT_SPEED_8GB;
break;
}
DEBUG2_3(printk("scsi(%ld): GPSC ext entry - "
"fpn %02x%02x%02x%02x%02x%02x%02x%02x speeds=%04x "
"speed=%04x.\n", ha->host_no,
list[i].fabric_port_name[0],
list[i].fabric_port_name[1],
list[i].fabric_port_name[2],
list[i].fabric_port_name[3],
list[i].fabric_port_name[4],
list[i].fabric_port_name[5],
list[i].fabric_port_name[6],
list[i].fabric_port_name[7],
be16_to_cpu(ct_rsp->rsp.gpsc.speeds),
be16_to_cpu(ct_rsp->rsp.gpsc.speed)));
}
/* Last device exit. */
if (list[i].d_id.b.rsvd_1 != 0)
break;
}
return (rval);
}
+850 -654
View File
File diff suppressed because it is too large Load Diff
+10 -88
View File
@@ -1,11 +1,10 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2005 QLogic Corporation
* Copyright (c) 2003-2008 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
static __inline__ uint16_t qla2x00_debounce_register(volatile uint16_t __iomem *);
/*
* qla2x00_debounce_register
* Debounce register.
@@ -32,95 +31,20 @@ qla2x00_debounce_register(volatile uint16_t __iomem *addr)
return (first);
}
static __inline__ int qla2x00_normalize_dma_addr(
dma_addr_t *e_addr, uint32_t *e_len,
dma_addr_t *ne_addr, uint32_t *ne_len);
/**
* qla2x00_normalize_dma_addr() - Normalize an DMA address.
* @e_addr: Raw DMA address
* @e_len: Raw DMA length
* @ne_addr: Normalized second DMA address
* @ne_len: Normalized second DMA length
*
* If the address does not span a 4GB page boundary, the contents of @ne_addr
* and @ne_len are undefined. @e_len is updated to reflect a normalization.
*
* Example:
*
* ffffabc0ffffeeee (e_addr) start of DMA address
* 0000000020000000 (e_len) length of DMA transfer
* ffffabc11fffeeed end of DMA transfer
*
* Is the 4GB boundary crossed?
*
* ffffabc0ffffeeee (e_addr)
* ffffabc11fffeeed (e_addr + e_len - 1)
* 00000001e0000003 ((e_addr ^ (e_addr + e_len - 1))
* 0000000100000000 ((e_addr ^ (e_addr + e_len - 1)) & ~(0xffffffff)
*
* Compute start of second DMA segment:
*
* ffffabc0ffffeeee (e_addr)
* ffffabc1ffffeeee (0x100000000 + e_addr)
* ffffabc100000000 (0x100000000 + e_addr) & ~(0xffffffff)
* ffffabc100000000 (ne_addr)
*
* Compute length of second DMA segment:
*
* 00000000ffffeeee (e_addr & 0xffffffff)
* 0000000000001112 (0x100000000 - (e_addr & 0xffffffff))
* 000000001fffeeee (e_len - (0x100000000 - (e_addr & 0xffffffff))
* 000000001fffeeee (ne_len)
*
* Adjust length of first DMA segment
*
* 0000000020000000 (e_len)
* 0000000000001112 (e_len - ne_len)
* 0000000000001112 (e_len)
*
* Returns non-zero if the specified address was normalized, else zero.
*/
static __inline__ int
qla2x00_normalize_dma_addr(
dma_addr_t *e_addr, uint32_t *e_len,
dma_addr_t *ne_addr, uint32_t *ne_len)
{
int normalized;
normalized = 0;
if ((*e_addr ^ (*e_addr + *e_len - 1)) & ~(0xFFFFFFFFULL)) {
/* Compute normalized crossed address and len */
*ne_addr = (0x100000000ULL + *e_addr) & ~(0xFFFFFFFFULL);
*ne_len = *e_len - (0x100000000ULL - (*e_addr & 0xFFFFFFFFULL));
*e_len -= *ne_len;
normalized++;
}
return (normalized);
}
static __inline__ void qla2x00_poll(scsi_qla_host_t *);
static inline void
qla2x00_poll(scsi_qla_host_t *ha)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
ha->isp_ops.intr_handler(0, ha, NULL);
#else
ha->isp_ops.intr_handler(0, ha);
#endif
unsigned long flags;
local_irq_save(flags);
ha->isp_ops->intr_handler(0, ha);
local_irq_restore(flags);
}
static __inline__ void qla2x00_check_fabric_devices(scsi_qla_host_t *);
/*
* This routine will wait for fabric devices for
* the reset delay.
*/
static __inline__ void qla2x00_check_fabric_devices(scsi_qla_host_t *ha)
static __inline__ scsi_qla_host_t *
to_qla_parent(scsi_qla_host_t *ha)
{
uint16_t fw_state;
qla2x00_get_firmware_state(ha, &fw_state);
return ha->parent ? ha->parent : ha;
}
/**
@@ -149,7 +73,6 @@ qla2x00_issue_marker(scsi_qla_host_t *ha, int ha_locked)
return (QLA_SUCCESS);
}
static inline uint8_t *host_to_fcp_swap(uint8_t *, uint32_t);
static inline uint8_t *
host_to_fcp_swap(uint8_t *fcp, uint32_t bsize)
{
@@ -163,11 +86,10 @@ host_to_fcp_swap(uint8_t *fcp, uint32_t bsize)
return fcp;
}
static inline int qla2x00_is_reserved_id(scsi_qla_host_t *, uint16_t);
static inline int
qla2x00_is_reserved_id(scsi_qla_host_t *ha, uint16_t loop_id)
{
if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
if (IS_FWI2_CAPABLE(ha))
return (loop_id > NPH_LAST_HANDLE);
return ((loop_id > ha->last_loop_id && loop_id < SNS_FIRST_LOOP_ID) ||
+96 -163
View File
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2005 QLogic Corporation
* Copyright (c) 2003-2008 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -11,10 +11,8 @@
#include <scsi/scsi_tcq.h>
static inline uint16_t qla2x00_get_cmd_direction(struct scsi_cmnd *cmd);
static inline cont_entry_t *qla2x00_prep_cont_type0_iocb(scsi_qla_host_t *);
static inline cont_a64_entry_t *qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *);
request_t *qla2x00_req_pkt(scsi_qla_host_t *ha);
void qla2x00_isp_cmd(scsi_qla_host_t *ha);
/**
* qla2x00_get_cmd_direction() - Determine control_flag data direction.
@@ -154,6 +152,8 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt,
uint32_t *cur_dsd;
scsi_qla_host_t *ha;
struct scsi_cmnd *cmd;
struct scatterlist *sg;
int i;
cmd = sp->cmd;
@@ -162,7 +162,7 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt,
__constant_cpu_to_le32(COMMAND_TYPE);
/* No data transfer */
if (scsi_bufflen(cmd) == 0 || cmd->sc_data_direction == DMA_NONE) {
if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) {
cmd_pkt->byte_count = __constant_cpu_to_le32(0);
return;
}
@@ -176,35 +176,23 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt,
cur_dsd = (uint32_t *)&cmd_pkt->dseg_0_address;
/* Load data segments */
if (scsi_sg_count(cmd) != 0) {
struct scatterlist *cur_seg;
struct scatterlist *end_seg;
scsi_for_each_sg(cmd, sg, tot_dsds, i) {
cont_entry_t *cont_pkt;
cur_seg = scsi_sglist(cmd);
end_seg = cur_seg + tot_dsds;
while (cur_seg < end_seg) {
cont_entry_t *cont_pkt;
/* Allocate additional continuation packets? */
if (avail_dsds == 0) {
/*
* Seven DSDs are available in the Continuation
* Type 0 IOCB.
*/
cont_pkt = qla2x00_prep_cont_type0_iocb(ha);
cur_dsd = (uint32_t *)&cont_pkt->dseg_0_address;
avail_dsds = 7;
}
*cur_dsd++ = cpu_to_le32(sg_dma_address(cur_seg));
*cur_dsd++ = cpu_to_le32(sg_dma_len(cur_seg));
avail_dsds--;
cur_seg++;
/* Allocate additional continuation packets? */
if (avail_dsds == 0) {
/*
* Seven DSDs are available in the Continuation
* Type 0 IOCB.
*/
cont_pkt = qla2x00_prep_cont_type0_iocb(ha);
cur_dsd = (uint32_t *)&cont_pkt->dseg_0_address;
avail_dsds = 7;
}
} else {
*cur_dsd++ = cpu_to_le32(sp->dma_handle);
*cur_dsd++ = cpu_to_le32(scsi_bufflen(cmd));
*cur_dsd++ = cpu_to_le32(sg_dma_address(sg));
*cur_dsd++ = cpu_to_le32(sg_dma_len(sg));
avail_dsds--;
}
}
@@ -223,6 +211,8 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
uint32_t *cur_dsd;
scsi_qla_host_t *ha;
struct scsi_cmnd *cmd;
struct scatterlist *sg;
int i;
cmd = sp->cmd;
@@ -231,7 +221,7 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
__constant_cpu_to_le32(COMMAND_A64_TYPE);
/* No data transfer */
if (scsi_bufflen(cmd) == 0 || cmd->sc_data_direction == DMA_NONE) {
if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) {
cmd_pkt->byte_count = __constant_cpu_to_le32(0);
return;
}
@@ -245,39 +235,26 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
cur_dsd = (uint32_t *)&cmd_pkt->dseg_0_address;
/* Load data segments */
if (scsi_sg_count(cmd) != 0) {
struct scatterlist *cur_seg;
struct scatterlist *end_seg;
scsi_for_each_sg(cmd, sg, tot_dsds, i) {
dma_addr_t sle_dma;
cont_a64_entry_t *cont_pkt;
cur_seg = scsi_sglist(cmd);
end_seg = cur_seg + tot_dsds;
while (cur_seg < end_seg) {
dma_addr_t sle_dma;
cont_a64_entry_t *cont_pkt;
/* Allocate additional continuation packets? */
if (avail_dsds == 0) {
/*
* Five DSDs are available in the Continuation
* Type 1 IOCB.
*/
cont_pkt = qla2x00_prep_cont_type1_iocb(ha);
cur_dsd = (uint32_t *)cont_pkt->dseg_0_address;
avail_dsds = 5;
}
sle_dma = sg_dma_address(cur_seg);
*cur_dsd++ = cpu_to_le32(LSD(sle_dma));
*cur_dsd++ = cpu_to_le32(MSD(sle_dma));
*cur_dsd++ = cpu_to_le32(sg_dma_len(cur_seg));
avail_dsds--;
cur_seg++;
/* Allocate additional continuation packets? */
if (avail_dsds == 0) {
/*
* Five DSDs are available in the Continuation
* Type 1 IOCB.
*/
cont_pkt = qla2x00_prep_cont_type1_iocb(ha);
cur_dsd = (uint32_t *)cont_pkt->dseg_0_address;
avail_dsds = 5;
}
} else {
*cur_dsd++ = cpu_to_le32(LSD(sp->dma_handle));
*cur_dsd++ = cpu_to_le32(MSD(sp->dma_handle));
*cur_dsd++ = cpu_to_le32(scsi_bufflen(cmd));
sle_dma = sg_dma_address(sg);
*cur_dsd++ = cpu_to_le32(LSD(sle_dma));
*cur_dsd++ = cpu_to_le32(MSD(sle_dma));
*cur_dsd++ = cpu_to_le32(sg_dma_len(sg));
avail_dsds--;
}
}
@@ -290,7 +267,7 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
int
qla2x00_start_scsi(srb_t *sp)
{
int ret;
int ret, nseg;
unsigned long flags;
scsi_qla_host_t *ha;
struct scsi_cmnd *cmd;
@@ -298,7 +275,6 @@ qla2x00_start_scsi(srb_t *sp)
uint32_t index;
uint32_t handle;
cmd_entry_t *cmd_pkt;
struct scatterlist *sg;
uint16_t cnt;
uint16_t req_cnt;
uint16_t tot_dsds;
@@ -329,7 +305,7 @@ qla2x00_start_scsi(srb_t *sp)
handle++;
if (handle == MAX_OUTSTANDING_COMMANDS)
handle = 1;
if (ha->outstanding_cmds[handle] == 0)
if (!ha->outstanding_cmds[handle])
break;
}
if (index == MAX_OUTSTANDING_COMMANDS)
@@ -337,25 +313,17 @@ qla2x00_start_scsi(srb_t *sp)
/* Map the sg table so we have an accurate count of sg entries needed */
if (scsi_sg_count(cmd)) {
sg = scsi_sglist(cmd);
tot_dsds = pci_map_sg(ha->pdev, sg, scsi_sg_count(cmd),
cmd->sc_data_direction);
if (tot_dsds == 0)
nseg = dma_map_sg(&ha->pdev->dev, scsi_sglist(cmd),
scsi_sg_count(cmd), cmd->sc_data_direction);
if (unlikely(!nseg))
goto queuing_error;
} else if (scsi_bufflen(cmd)) {
dma_addr_t req_dma;
} else
nseg = 0;
req_dma = pci_map_single(ha->pdev, scsi_sglist(cmd),
scsi_bufflen(cmd), cmd->sc_data_direction);
if (dma_mapping_error(req_dma))
goto queuing_error;
sp->dma_handle = req_dma;
tot_dsds = 1;
}
tot_dsds = nseg;
/* Calculate the number of request entries needed. */
req_cnt = ha->isp_ops.calc_req_entries(tot_dsds);
req_cnt = ha->isp_ops->calc_req_entries(tot_dsds);
if (ha->req_q_cnt < (req_cnt + 2)) {
cnt = RD_REG_WORD_RELAXED(ISP_REQ_Q_OUT(ha, reg));
if (ha->req_ring_index < cnt)
@@ -393,16 +361,12 @@ qla2x00_start_scsi(srb_t *sp)
cmd_pkt->byte_count = cpu_to_le32((uint32_t)scsi_bufflen(cmd));
/* Build IOCB segments */
ha->isp_ops.build_iocbs(sp, cmd_pkt, tot_dsds);
ha->isp_ops->build_iocbs(sp, cmd_pkt, tot_dsds);
/* Set total data segment count. */
cmd_pkt->entry_count = (uint8_t)req_cnt;
wmb();
DEBUG5(printk("%s(): IOCB data:\n", __func__));
DEBUG5(qla2x00_dump_buffer(
(uint8_t *)ha->request_ring_ptr, REQUEST_ENTRY_SIZE));
/* Adjust ring index. */
ha->req_ring_index++;
if (ha->req_ring_index == ha->request_q_length) {
@@ -412,7 +376,6 @@ qla2x00_start_scsi(srb_t *sp)
ha->request_ring_ptr++;
sp->flags |= SRB_DMA_VALID;
sp->state = SRB_ACTIVE_STATE;
/* Set chip new ring index. */
WRT_REG_WORD(ISP_REQ_Q_IN(ha, reg), ha->req_ring_index);
@@ -427,14 +390,9 @@ qla2x00_start_scsi(srb_t *sp)
return (QLA_SUCCESS);
queuing_error:
if (scsi_sg_count(cmd) && tot_dsds) {
sg = scsi_sglist(cmd);
pci_unmap_sg(ha->pdev, sg, scsi_sg_count(cmd),
cmd->sc_data_direction);
} else if (tot_dsds) {
pci_unmap_single(ha->pdev, sp->dma_handle,
scsi_bufflen(cmd), cmd->sc_data_direction);
}
if (tot_dsds)
scsi_dma_unmap(cmd);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
return (QLA_FUNCTION_FAILED);
@@ -457,9 +415,10 @@ __qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun,
{
mrk_entry_t *mrk;
struct mrk_entry_24xx *mrk24;
scsi_qla_host_t *pha = to_qla_parent(ha);
mrk24 = NULL;
mrk = (mrk_entry_t *)qla2x00_req_pkt(ha);
mrk = (mrk_entry_t *)qla2x00_req_pkt(pha);
if (mrk == NULL) {
DEBUG2_3(printk("%s(%ld): failed to allocate Marker IOCB.\n",
__func__, ha->host_no));
@@ -470,11 +429,13 @@ __qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun,
mrk->entry_type = MARKER_TYPE;
mrk->modifier = type;
if (type != MK_SYNC_ALL) {
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
if (IS_FWI2_CAPABLE(ha)) {
mrk24 = (struct mrk_entry_24xx *) mrk;
mrk24->nport_handle = cpu_to_le16(loop_id);
mrk24->lun[1] = LSB(lun);
mrk24->lun[2] = MSB(lun);
host_to_fcp_swap(mrk24->lun, sizeof(mrk24->lun));
mrk24->vp_index = ha->vp_idx;
} else {
SET_TARGET_ID(ha, mrk->target, loop_id);
mrk->lun = cpu_to_le16(lun);
@@ -482,7 +443,7 @@ __qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun,
}
wmb();
qla2x00_isp_cmd(ha);
qla2x00_isp_cmd(pha);
return (QLA_SUCCESS);
}
@@ -523,7 +484,7 @@ qla2x00_req_pkt(scsi_qla_host_t *ha)
for (timer = HZ; timer; timer--) {
if ((req_cnt + 2) >= ha->req_q_cnt) {
/* Calculate number of free request entries. */
if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
if (IS_FWI2_CAPABLE(ha))
cnt = (uint16_t)RD_REG_DWORD(
&reg->isp24.req_q_out);
else
@@ -561,7 +522,7 @@ qla2x00_req_pkt(scsi_qla_host_t *ha)
/* Check for pending interrupts. */
/* During init we issue marker directly */
if (!ha->marker_needed)
if (!ha->marker_needed && !ha->flags.init_done)
qla2x00_poll(ha);
spin_lock_irq(&ha->hardware_lock);
@@ -597,7 +558,7 @@ qla2x00_isp_cmd(scsi_qla_host_t *ha)
ha->request_ring_ptr++;
/* Set chip new ring index. */
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
if (IS_FWI2_CAPABLE(ha)) {
WRT_REG_DWORD(&reg->isp24.req_q_in, ha->req_ring_index);
RD_REG_DWORD_RELAXED(&reg->isp24.req_q_in);
} else {
@@ -645,6 +606,8 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
uint32_t *cur_dsd;
scsi_qla_host_t *ha;
struct scsi_cmnd *cmd;
struct scatterlist *sg;
int i;
cmd = sp->cmd;
@@ -653,7 +616,7 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
__constant_cpu_to_le32(COMMAND_TYPE_7);
/* No data transfer */
if (scsi_bufflen(cmd) == 0 || cmd->sc_data_direction == DMA_NONE) {
if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) {
cmd_pkt->byte_count = __constant_cpu_to_le32(0);
return;
}
@@ -673,39 +636,27 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
cur_dsd = (uint32_t *)&cmd_pkt->dseg_0_address;
/* Load data segments */
if (scsi_sg_count(cmd) != 0) {
struct scatterlist *cur_seg;
struct scatterlist *end_seg;
cur_seg = scsi_sglist(cmd);
end_seg = cur_seg + tot_dsds;
while (cur_seg < end_seg) {
dma_addr_t sle_dma;
cont_a64_entry_t *cont_pkt;
scsi_for_each_sg(cmd, sg, tot_dsds, i) {
dma_addr_t sle_dma;
cont_a64_entry_t *cont_pkt;
/* Allocate additional continuation packets? */
if (avail_dsds == 0) {
/*
* Five DSDs are available in the Continuation
* Type 1 IOCB.
*/
cont_pkt = qla2x00_prep_cont_type1_iocb(ha);
cur_dsd = (uint32_t *)cont_pkt->dseg_0_address;
avail_dsds = 5;
}
sle_dma = sg_dma_address(cur_seg);
*cur_dsd++ = cpu_to_le32(LSD(sle_dma));
*cur_dsd++ = cpu_to_le32(MSD(sle_dma));
*cur_dsd++ = cpu_to_le32(sg_dma_len(cur_seg));
avail_dsds--;
cur_seg++;
/* Allocate additional continuation packets? */
if (avail_dsds == 0) {
/*
* Five DSDs are available in the Continuation
* Type 1 IOCB.
*/
cont_pkt = qla2x00_prep_cont_type1_iocb(ha);
cur_dsd = (uint32_t *)cont_pkt->dseg_0_address;
avail_dsds = 5;
}
} else {
*cur_dsd++ = cpu_to_le32(LSD(sp->dma_handle));
*cur_dsd++ = cpu_to_le32(MSD(sp->dma_handle));
*cur_dsd++ = cpu_to_le32(scsi_bufflen(cmd));
sle_dma = sg_dma_address(sg);
*cur_dsd++ = cpu_to_le32(LSD(sle_dma));
*cur_dsd++ = cpu_to_le32(MSD(sle_dma));
*cur_dsd++ = cpu_to_le32(sg_dma_len(sg));
avail_dsds--;
}
}
@@ -719,7 +670,7 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
int
qla24xx_start_scsi(srb_t *sp)
{
int ret;
int ret, nseg;
unsigned long flags;
scsi_qla_host_t *ha;
struct scsi_cmnd *cmd;
@@ -727,7 +678,6 @@ qla24xx_start_scsi(srb_t *sp)
uint32_t index;
uint32_t handle;
struct cmd_type_7 *cmd_pkt;
struct scatterlist *sg;
uint16_t cnt;
uint16_t req_cnt;
uint16_t tot_dsds;
@@ -758,7 +708,7 @@ qla24xx_start_scsi(srb_t *sp)
handle++;
if (handle == MAX_OUTSTANDING_COMMANDS)
handle = 1;
if (ha->outstanding_cmds[handle] == 0)
if (!ha->outstanding_cmds[handle])
break;
}
if (index == MAX_OUTSTANDING_COMMANDS)
@@ -766,22 +716,14 @@ qla24xx_start_scsi(srb_t *sp)
/* Map the sg table so we have an accurate count of sg entries needed */
if (scsi_sg_count(cmd)) {
sg = scsi_sglist(cmd);
tot_dsds = pci_map_sg(ha->pdev, sg, scsi_sg_count(cmd),
cmd->sc_data_direction);
if (tot_dsds == 0)
nseg = dma_map_sg(&ha->pdev->dev, scsi_sglist(cmd),
scsi_sg_count(cmd), cmd->sc_data_direction);
if (unlikely(!nseg))
goto queuing_error;
} else if (scsi_bufflen(cmd)) {
dma_addr_t req_dma;
} else
nseg = 0;
req_dma = pci_map_single(ha->pdev, scsi_sglist(cmd),
scsi_bufflen(cmd), cmd->sc_data_direction);
if (dma_mapping_error(req_dma))
goto queuing_error;
sp->dma_handle = req_dma;
tot_dsds = 1;
}
tot_dsds = nseg;
req_cnt = qla24xx_calc_iocbs(tot_dsds);
if (ha->req_q_cnt < (req_cnt + 2)) {
@@ -816,6 +758,7 @@ qla24xx_start_scsi(srb_t *sp)
cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa;
cmd_pkt->port_id[1] = sp->fcport->d_id.b.area;
cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain;
cmd_pkt->vp_index = sp->fcport->vp_idx;
int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun);
host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
@@ -833,10 +776,6 @@ qla24xx_start_scsi(srb_t *sp)
cmd_pkt->entry_count = (uint8_t)req_cnt;
wmb();
DEBUG5(printk("%s(): IOCB data:\n", __func__));
DEBUG5(qla2x00_dump_buffer(
(uint8_t *)ha->request_ring_ptr, REQUEST_ENTRY_SIZE));
/* Adjust ring index. */
ha->req_ring_index++;
if (ha->req_ring_index == ha->request_q_length) {
@@ -846,7 +785,6 @@ qla24xx_start_scsi(srb_t *sp)
ha->request_ring_ptr++;
sp->flags |= SRB_DMA_VALID;
sp->state = SRB_ACTIVE_STATE;
/* Set chip new ring index. */
WRT_REG_DWORD(&reg->req_q_in, ha->req_ring_index);
@@ -861,14 +799,9 @@ qla24xx_start_scsi(srb_t *sp)
return QLA_SUCCESS;
queuing_error:
if (scsi_sg_count(cmd) && tot_dsds) {
sg = scsi_sglist(cmd);
pci_unmap_sg(ha->pdev, sg, scsi_sg_count(cmd),
cmd->sc_data_direction);
} else if (tot_dsds) {
pci_unmap_single(ha->pdev, sp->dma_handle,
scsi_bufflen(cmd), cmd->sc_data_direction);
}
if (tot_dsds)
scsi_dma_unmap(cmd);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
return QLA_FUNCTION_FAILED;
+678 -407
View File
File diff suppressed because it is too large Load Diff
+1002 -421
View File
File diff suppressed because it is too large Load Diff
+456
View File
@@ -0,0 +1,456 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2008 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
#include <linux/version.h>
#include <linux/moduleparam.h>
#include <linux/vmalloc.h>
#include <linux/smp_lock.h>
#include <linux/list.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsicam.h>
#include <linux/delay.h>
void
qla2x00_vp_stop_timer(scsi_qla_host_t *vha)
{
if (vha->parent && vha->timer_active) {
del_timer_sync(&vha->timer);
vha->timer_active = 0;
}
}
static uint32_t
qla24xx_allocate_vp_id(scsi_qla_host_t *vha)
{
uint32_t vp_id;
scsi_qla_host_t *ha = vha->parent;
/* Find an empty slot and assign an vp_id */
mutex_lock(&ha->vport_lock);
vp_id = find_first_zero_bit(ha->vp_idx_map, ha->max_npiv_vports + 1);
if (vp_id > ha->max_npiv_vports) {
DEBUG15(printk ("vp_id %d is bigger than max-supported %d.\n",
vp_id, ha->max_npiv_vports));
mutex_unlock(&ha->vport_lock);
return vp_id;
}
set_bit(vp_id, ha->vp_idx_map);
ha->num_vhosts++;
vha->vp_idx = vp_id;
list_add_tail(&vha->vp_list, &ha->vp_list);
mutex_unlock(&ha->vport_lock);
return vp_id;
}
void
qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
{
uint16_t vp_id;
scsi_qla_host_t *ha = vha->parent;
mutex_lock(&ha->vport_lock);
vp_id = vha->vp_idx;
ha->num_vhosts--;
clear_bit(vp_id, ha->vp_idx_map);
list_del(&vha->vp_list);
mutex_unlock(&ha->vport_lock);
}
static scsi_qla_host_t *
qla24xx_find_vhost_by_name(scsi_qla_host_t *ha, uint8_t *port_name)
{
scsi_qla_host_t *vha;
/* Locate matching device in database. */
list_for_each_entry(vha, &ha->vp_list, vp_list) {
if (!memcmp(port_name, vha->port_name, WWN_SIZE))
return vha;
}
return NULL;
}
/*
* qla2x00_mark_vp_devices_dead
* Updates fcport state when device goes offline.
*
* Input:
* ha = adapter block pointer.
* fcport = port structure pointer.
*
* Return:
* None.
*
* Context:
*/
static void
qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha)
{
fc_port_t *fcport;
scsi_qla_host_t *pha = to_qla_parent(vha);
list_for_each_entry(fcport, &pha->fcports, list) {
if (fcport->vp_idx != vha->vp_idx)
continue;
DEBUG15(printk("scsi(%ld): Marking port dead, "
"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);
}
}
int
qla24xx_disable_vp(scsi_qla_host_t *vha)
{
int ret;
ret = qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL);
atomic_set(&vha->loop_state, LOOP_DOWN);
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
/* Delete all vp's fcports from parent's list */
qla2x00_mark_vp_devices_dead(vha);
atomic_set(&vha->vp_state, VP_FAILED);
vha->flags.management_server_logged_in = 0;
if (ret == QLA_SUCCESS) {
fc_vport_set_state(vha->fc_vport, FC_VPORT_DISABLED);
} else {
fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
return -1;
}
return 0;
}
int
qla24xx_enable_vp(scsi_qla_host_t *vha)
{
int ret;
scsi_qla_host_t *ha = vha->parent;
/* Check if physical ha port is Up */
if (atomic_read(&ha->loop_state) == LOOP_DOWN ||
atomic_read(&ha->loop_state) == LOOP_DEAD ) {
vha->vp_err_state = VP_ERR_PORTDWN;
fc_vport_set_state(vha->fc_vport, FC_VPORT_LINKDOWN);
goto enable_failed;
}
/* Initialize the new vport unless it is a persistent port */
mutex_lock(&ha->vport_lock);
ret = qla24xx_modify_vp_config(vha);
mutex_unlock(&ha->vport_lock);
if (ret != QLA_SUCCESS) {
fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
goto enable_failed;
}
DEBUG15(qla_printk(KERN_INFO, ha,
"Virtual port with id: %d - Enabled\n", vha->vp_idx));
return 0;
enable_failed:
DEBUG15(qla_printk(KERN_INFO, ha,
"Virtual port with id: %d - Disabled\n", vha->vp_idx));
return 1;
}
static void
qla24xx_configure_vp(scsi_qla_host_t *vha)
{
struct fc_vport *fc_vport;
int ret;
fc_vport = vha->fc_vport;
DEBUG15(printk("scsi(%ld): %s: change request #3 for this host.\n",
vha->host_no, __func__));
ret = qla2x00_send_change_request(vha, 0x3, vha->vp_idx);
if (ret != QLA_SUCCESS) {
DEBUG15(qla_printk(KERN_ERR, vha, "Failed to enable receiving"
" of RSCN requests: 0x%x\n", ret));
return;
} else {
/* Corresponds to SCR enabled */
clear_bit(VP_SCR_NEEDED, &vha->vp_flags);
}
vha->flags.online = 1;
if (qla24xx_configure_vhba(vha))
return;
atomic_set(&vha->vp_state, VP_ACTIVE);
fc_vport_set_state(fc_vport, FC_VPORT_ACTIVE);
}
void
qla2x00_alert_all_vps(scsi_qla_host_t *ha, uint16_t *mb)
{
int i, vp_idx_matched;
scsi_qla_host_t *vha;
if (ha->parent)
return;
for_each_mapped_vp_idx(ha, i) {
vp_idx_matched = 0;
list_for_each_entry(vha, &ha->vp_list, vp_list) {
if (i == vha->vp_idx) {
vp_idx_matched = 1;
break;
}
}
if (vp_idx_matched) {
switch (mb[0]) {
case MBA_LIP_OCCURRED:
case MBA_LOOP_UP:
case MBA_LOOP_DOWN:
case MBA_LIP_RESET:
case MBA_POINT_TO_POINT:
case MBA_CHG_IN_CONNECTION:
case MBA_PORT_UPDATE:
case MBA_RSCN_UPDATE:
DEBUG15(printk("scsi(%ld)%s: Async_event for"
" VP[%d], mb = 0x%x, vha=%p\n",
vha->host_no, __func__,i, *mb, vha));
qla2x00_async_event(vha, mb);
break;
}
}
}
}
void
qla2x00_vp_abort_isp(scsi_qla_host_t *vha)
{
/*
* Physical port will do most of the abort and recovery work. We can
* just treat it as a loop down
*/
if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
atomic_set(&vha->loop_state, LOOP_DOWN);
qla2x00_mark_all_devices_lost(vha, 0);
} else {
if (!atomic_read(&vha->loop_down_timer))
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
}
DEBUG15(printk("scsi(%ld): Scheduling enable of Vport %d...\n",
vha->host_no, vha->vp_idx));
qla24xx_enable_vp(vha);
}
static int
qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
{
scsi_qla_host_t *ha = vha->parent;
if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) {
/* VP acquired. complete port configuration */
if (atomic_read(&ha->loop_state) == LOOP_READY) {
qla24xx_configure_vp(vha);
} else {
set_bit(VP_IDX_ACQUIRED, &vha->vp_flags);
set_bit(VP_DPC_NEEDED, &ha->dpc_flags);
}
return 0;
}
if (test_and_clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags))
qla2x00_vp_abort_isp(vha);
if (test_and_clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags) &&
(!(test_and_set_bit(RESET_ACTIVE, &vha->dpc_flags)))) {
clear_bit(RESET_ACTIVE, &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);
}
}
return 0;
}
void
qla2x00_do_dpc_all_vps(scsi_qla_host_t *ha)
{
int ret;
int i, vp_idx_matched;
scsi_qla_host_t *vha;
if (ha->parent)
return;
if (list_empty(&ha->vp_list))
return;
clear_bit(VP_DPC_NEEDED, &ha->dpc_flags);
for_each_mapped_vp_idx(ha, i) {
vp_idx_matched = 0;
list_for_each_entry(vha, &ha->vp_list, vp_list) {
if (i == vha->vp_idx) {
vp_idx_matched = 1;
break;
}
}
if (vp_idx_matched)
ret = qla2x00_do_dpc_vp(vha);
}
}
int
qla24xx_vport_create_req_sanity_check(struct fc_vport *fc_vport)
{
scsi_qla_host_t *ha = shost_priv(fc_vport->shost);
scsi_qla_host_t *vha;
uint8_t port_name[WWN_SIZE];
if (fc_vport->roles != FC_PORT_ROLE_FCP_INITIATOR)
return VPCERR_UNSUPPORTED;
/* Check up the F/W and H/W support NPIV */
if (!ha->flags.npiv_supported)
return VPCERR_UNSUPPORTED;
/* Check up whether npiv supported switch presented */
if (!(ha->switch_cap & FLOGI_MID_SUPPORT))
return VPCERR_NO_FABRIC_SUPP;
/* Check up unique WWPN */
u64_to_wwn(fc_vport->port_name, port_name);
if (!memcmp(port_name, ha->port_name, WWN_SIZE))
return VPCERR_BAD_WWN;
vha = qla24xx_find_vhost_by_name(ha, port_name);
if (vha)
return VPCERR_BAD_WWN;
/* Check up max-npiv-supports */
if (ha->num_vhosts > ha->max_npiv_vports) {
DEBUG15(printk("scsi(%ld): num_vhosts %ud is bigger than "
"max_npv_vports %ud.\n", ha->host_no,
ha->num_vhosts, ha->max_npiv_vports));
return VPCERR_UNSUPPORTED;
}
return 0;
}
scsi_qla_host_t *
qla24xx_create_vhost(struct fc_vport *fc_vport)
{
scsi_qla_host_t *ha = shost_priv(fc_vport->shost);
scsi_qla_host_t *vha;
struct Scsi_Host *host;
host = scsi_host_alloc(&qla24xx_driver_template,
sizeof(scsi_qla_host_t));
if (!host) {
printk(KERN_WARNING
"qla2xxx: scsi_host_alloc() failed for vport\n");
return(NULL);
}
vha = shost_priv(host);
/* clone the parent hba */
memcpy(vha, ha, sizeof (scsi_qla_host_t));
fc_vport->dd_data = vha;
vha->node_name = kmalloc(WWN_SIZE * sizeof(char), GFP_KERNEL);
if (!vha->node_name)
goto create_vhost_failed_1;
vha->port_name = kmalloc(WWN_SIZE * sizeof(char), GFP_KERNEL);
if (!vha->port_name)
goto create_vhost_failed_2;
/* New host info */
u64_to_wwn(fc_vport->node_name, vha->node_name);
u64_to_wwn(fc_vport->port_name, vha->port_name);
vha->host = host;
vha->host_no = host->host_no;
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",
vha->host_no));
goto create_vhost_failed_3;
}
vha->mgmt_svr_loop_id = 10 + vha->vp_idx;
init_completion(&vha->mbx_cmd_comp);
complete(&vha->mbx_cmd_comp);
init_completion(&vha->mbx_intr_comp);
INIT_LIST_HEAD(&vha->list);
INIT_LIST_HEAD(&vha->fcports);
INIT_LIST_HEAD(&vha->vp_fcports);
INIT_LIST_HEAD(&vha->work_list);
vha->dpc_flags = 0L;
set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
/*
* To fix the issue of processing a parent's RSCN for the vport before
* its SCR is complete.
*/
set_bit(VP_SCR_NEEDED, &vha->vp_flags);
atomic_set(&vha->loop_state, LOOP_DOWN);
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
qla2x00_start_timer(vha, qla2x00_timer, WATCH_INTERVAL);
host->can_queue = vha->request_q_length + 128;
host->this_id = 255;
host->cmd_per_lun = 3;
host->max_cmd_len = MAX_CMDSZ;
host->max_channel = MAX_BUSES - 1;
host->max_lun = MAX_LUNS;
host->unique_id = vha->instance;
host->max_id = MAX_TARGETS_2200;
host->transportt = qla2xxx_transport_vport_template;
DEBUG15(printk("DEBUG: detect vport hba %ld at address = %p\n",
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;
create_vhost_failed_3:
kfree(vha->port_name);
create_vhost_failed_2:
kfree(vha->node_name);
create_vhost_failed_1:
return NULL;
}
+1151 -1065
View File
File diff suppressed because it is too large Load Diff
-1426
View File
File diff suppressed because it is too large Load Diff
+1 -16
View File
@@ -1,27 +1,12 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2005 QLogic Corporation
* Copyright (c) 2003-2008 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
/*
* Compile time Options:
* 0 - Disable and 1 - Enable
*/
#define DEBUG_QLA2100 0 /* For Debug of qla2x00 */
#define USE_ABORT_TGT 1 /* Use Abort Target mbx cmd */
#define MAX_RETRIES_OF_ISP_ABORT 5
/* Max time to wait for the loop to be in LOOP_READY state */
#define MAX_LOOP_TIMEOUT (60 * 5)
#define EH_ACTIVE 1 /* Error handler active */
/*
* Some vendor subsystems do not recover properly after a device reset. Define
* the following to force a logout after a successful device reset.
*/
#undef LOGOUT_AFTER_DEVICE_RESET
#include "qla_version.h"
+853 -98
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -1,15 +1,15 @@
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2005 QLogic Corporation
* Copyright (c) 2003-2008 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
/*
* Driver version
*/
#define QLA2XXX_VERSION "8.01.04-k"
#define QLA2XXX_VERSION "8.02.01-k4"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 1
#define QLA_DRIVER_PATCH_VER 4
#define QLA_DRIVER_MINOR_VER 2
#define QLA_DRIVER_PATCH_VER 1
#define QLA_DRIVER_BETA_VER 0