From 203c29102b8e76f088440099af01677cfb1cfdf9 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 3 Apr 2008 13:13:12 -0700 Subject: [SCSI] qla2xxx: Update firmware filenames for new ISP parts. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/scsi/qla2xxx') diff --git a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig index 8c865b9e02b5..6208d562890d 100644 --- a/drivers/scsi/qla2xxx/Kconfig +++ b/drivers/scsi/qla2xxx/Kconfig @@ -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. -- cgit v1.2.3 From 01e58d8eac93f3b73246b8d0bdee071d9fb85661 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 3 Apr 2008 13:13:13 -0700 Subject: [SCSI] qla2xxx: Update copyright banner. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_attr.c | 2 +- drivers/scsi/qla2xxx/qla_dbg.c | 2 +- drivers/scsi/qla2xxx/qla_dbg.h | 2 +- drivers/scsi/qla2xxx/qla_def.h | 2 +- drivers/scsi/qla2xxx/qla_dfs.c | 2 +- drivers/scsi/qla2xxx/qla_fw.h | 2 +- drivers/scsi/qla2xxx/qla_gbl.h | 2 +- drivers/scsi/qla2xxx/qla_gs.c | 2 +- drivers/scsi/qla2xxx/qla_init.c | 2 +- drivers/scsi/qla2xxx/qla_inline.h | 2 +- drivers/scsi/qla2xxx/qla_iocb.c | 2 +- drivers/scsi/qla2xxx/qla_isr.c | 2 +- drivers/scsi/qla2xxx/qla_mbx.c | 2 +- drivers/scsi/qla2xxx/qla_mid.c | 18 +++--------------- drivers/scsi/qla2xxx/qla_os.c | 2 +- drivers/scsi/qla2xxx/qla_settings.h | 2 +- drivers/scsi/qla2xxx/qla_sup.c | 2 +- drivers/scsi/qla2xxx/qla_version.h | 2 +- 18 files changed, 20 insertions(+), 32 deletions(-) (limited to 'drivers/scsi/qla2xxx') diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 4894dc886b62..27111b18cc1b 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -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. */ diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index d88e98c476b0..83dd68bacf2a 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -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. */ diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index 524598afc81c..c30f2fa284f2 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h @@ -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. */ diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 3750319f4968..aa9d2163cdf2 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -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. */ diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c index 2cd899bfe84b..561a4411719d 100644 --- a/drivers/scsi/qla2xxx/qla_dfs.c +++ b/drivers/scsi/qla2xxx/qla_dfs.c @@ -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. */ diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 9337e138ed63..4ae26533fe12 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -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. */ diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 193f688ec3d7..70af95070aed 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -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. */ diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index c1808763d40e..ea8a7d3e9ce5 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -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. */ diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 364be7d06875..9b7ad590eb01 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -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. */ diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h index 5d1a3f7c408f..3e57a3e03dac 100644 --- a/drivers/scsi/qla2xxx/qla_inline.h +++ b/drivers/scsi/qla2xxx/qla_inline.h @@ -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. */ diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 024c662ec34d..9192ad574d99 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -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. */ diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index f0337036c7bb..370fba59dfd2 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -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. */ diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index bb103580e1ba..9d92c02fa3d4 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -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. */ diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index cf784cdafb01..5305ec194239 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -1,20 +1,8 @@ /* - * QLOGIC LINUX SOFTWARE - * - * QLogic ISP2x00 device driver for Linux 2.6.x - * Copyright (C) 2003-2005 QLogic Corporation - * (www.qlogic.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2008 QLogic Corporation * + * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 3c1b43356adb..2d28937d30c7 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -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. */ diff --git a/drivers/scsi/qla2xxx/qla_settings.h b/drivers/scsi/qla2xxx/qla_settings.h index 249e4d90fdc5..44069489225b 100644 --- a/drivers/scsi/qla2xxx/qla_settings.h +++ b/drivers/scsi/qla2xxx/qla_settings.h @@ -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. */ diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 26822c8807ee..317cd8f96340 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -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. */ diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index ea08a129fee9..0281537491cf 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -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. */ -- cgit v1.2.3 From 2ae2b3709542a4b5b691985ecbdf3b79303d9e56 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 3 Apr 2008 13:13:14 -0700 Subject: [SCSI] qla2xxx: Add support for host supported speeds FC transport attribute. Use generic FC transport #defines for speed values. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_attr.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'drivers/scsi/qla2xxx') diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 27111b18cc1b..aee03221ed6e 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -849,20 +849,20 @@ static void qla2x00_get_host_speed(struct Scsi_Host *shost) { scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost)); - uint32_t speed = 0; + u32 speed = FC_PORTSPEED_UNKNOWN; switch (ha->link_data_rate) { case PORT_SPEED_1GB: - speed = 1; + speed = FC_PORTSPEED_1GBIT; break; case PORT_SPEED_2GB: - speed = 2; + speed = FC_PORTSPEED_2GBIT; break; case PORT_SPEED_4GB: - speed = 4; + speed = FC_PORTSPEED_4GBIT; break; case PORT_SPEED_8GB: - speed = 8; + speed = FC_PORTSPEED_8GBIT; break; } fc_host_speed(shost) = speed; @@ -1196,6 +1196,7 @@ struct fc_function_template qla2xxx_transport_functions = { .show_host_node_name = 1, .show_host_port_name = 1, .show_host_supported_classes = 1, + .show_host_supported_speeds = 1, .get_host_port_id = qla2x00_get_host_port_id, .show_host_port_id = 1, @@ -1276,9 +1277,23 @@ struct fc_function_template qla2xxx_transport_vport_functions = { void qla2x00_init_host_attr(scsi_qla_host_t *ha) { + u32 speed = FC_PORTSPEED_UNKNOWN; + fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name); fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name); fc_host_supported_classes(ha->host) = FC_COS_CLASS3; fc_host_max_npiv_vports(ha->host) = ha->max_npiv_vports;; fc_host_npiv_vports_inuse(ha->host) = ha->cur_vport_count; + + if (IS_QLA25XX(ha)) + speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | + FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; + else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) + speed = FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT | + FC_PORTSPEED_1GBIT; + else if (IS_QLA23XX(ha)) + speed = FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; + else + speed = FC_PORTSPEED_1GBIT; + fc_host_supported_speeds(ha->host) = speed; } -- cgit v1.2.3 From 0ddda2d1529f2d01d3b043782d2efcf0499fc3db Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 3 Apr 2008 13:13:15 -0700 Subject: [SCSI] qla2xxx: Remove unused and obsolete #define's. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_gbl.h | 2 -- drivers/scsi/qla2xxx/qla_mbx.c | 2 -- drivers/scsi/qla2xxx/qla_os.c | 9 --------- drivers/scsi/qla2xxx/qla_settings.h | 14 -------------- 4 files changed, 27 deletions(-) (limited to 'drivers/scsi/qla2xxx') diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 70af95070aed..97625d49a43c 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -151,10 +151,8 @@ 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 extern int qla2x00_get_adapter_id(scsi_qla_host_t *, uint16_t *, uint8_t *, uint8_t *, diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 9d92c02fa3d4..898847e4b363 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -776,7 +776,6 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp) return rval; } -#if USE_ABORT_TGT /* * qla2x00_abort_target * Issue abort target mailbox command. @@ -834,7 +833,6 @@ qla2x00_abort_target(fc_port_t *fcport) return rval; } -#endif /* * qla2x00_get_adapter_id diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 2d28937d30c7..661a1596679d 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -816,15 +816,6 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) if (qla2x00_wait_for_loop_ready(ha) == QLA_SUCCESS) { if (qla2x00_device_reset(ha, fcport) == 0) ret = SUCCESS; - -#if defined(LOGOUT_AFTER_DEVICE_RESET) - if (ret == SUCCESS) { - if (fcport->flags & FC_FABRIC_DEVICE) { - ha->isp_ops->fabric_logout(ha, fcport->loop_id); - qla2x00_mark_device_lost(ha, fcport, 0, 0); - } - } -#endif } else { DEBUG2(printk(KERN_INFO "%s failed: loop not ready\n",__func__)); diff --git a/drivers/scsi/qla2xxx/qla_settings.h b/drivers/scsi/qla2xxx/qla_settings.h index 44069489225b..2801c2664b40 100644 --- a/drivers/scsi/qla2xxx/qla_settings.h +++ b/drivers/scsi/qla2xxx/qla_settings.h @@ -4,23 +4,9 @@ * * 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) -/* - * 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" -- cgit v1.2.3 From 5ab5a4dd5444db0715b5748bab916725138d3a32 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 3 Apr 2008 13:13:16 -0700 Subject: [SCSI] qla2xxx: Use an rport's scsi_target_id member consistently throughout driver. Rather than using a duplicate/cached value stored in the driver's internal fcport structure. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_attr.c | 9 ++++++--- drivers/scsi/qla2xxx/qla_def.h | 2 -- drivers/scsi/qla2xxx/qla_init.c | 4 ---- 3 files changed, 6 insertions(+), 9 deletions(-) (limited to 'drivers/scsi/qla2xxx') diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index aee03221ed6e..798cc613c44a 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -900,7 +900,8 @@ qla2x00_get_starget_node_name(struct scsi_target *starget) u64 node_name = 0; list_for_each_entry(fcport, &ha->fcports, list) { - if (starget->id == fcport->os_target_id) { + if (fcport->rport && + starget->id == fcport->rport->scsi_target_id) { node_name = wwn_to_u64(fcport->node_name); break; } @@ -918,7 +919,8 @@ qla2x00_get_starget_port_name(struct scsi_target *starget) u64 port_name = 0; list_for_each_entry(fcport, &ha->fcports, list) { - if (starget->id == fcport->os_target_id) { + if (fcport->rport && + starget->id == fcport->rport->scsi_target_id) { port_name = wwn_to_u64(fcport->port_name); break; } @@ -936,7 +938,8 @@ qla2x00_get_starget_port_id(struct scsi_target *starget) uint32_t port_id = ~0U; list_for_each_entry(fcport, &ha->fcports, list) { - if (starget->id == fcport->os_target_id) { + if (fcport->rport && + starget->id == fcport->rport->scsi_target_id) { port_id = fcport->d_id.b.domain << 16 | fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; break; diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index aa9d2163cdf2..f70c78b6f364 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -1542,8 +1542,6 @@ typedef struct fc_port { atomic_t state; uint32_t flags; - unsigned int os_target_id; - int port_login_retry_count; int login_retry; atomic_t port_down_timer; diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 9b7ad590eb01..e773697cd8d5 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -2251,10 +2251,6 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport) if (fcport->port_type == FCT_TARGET) rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET; fc_remote_port_rolechg(rport, rport_ids.roles); - - if (rport->scsi_target_id != -1 && - rport->scsi_target_id < ha->host->max_id) - fcport->os_target_id = rport->scsi_target_id; } /* -- cgit v1.2.3 From c6952483b070ec8a4f2450d1116be908fe59edcc Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 3 Apr 2008 13:13:17 -0700 Subject: [SCSI] qla2xxx: Simplify interrupt handler locking. There's no need to use the heavier (albiet safer) *_irq[save|restore]() locking primitives within the driver's interrupt handlers, interrupts are guaranteed to be non-reentrant. Use lightweight spin_lock() and spin_unlock() primitives while acquiring the hardware_lock. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_isr.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) (limited to 'drivers/scsi/qla2xxx') diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 370fba59dfd2..4e9f41034466 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -33,7 +33,6 @@ qla2100_intr_handler(int irq, void *dev_id) scsi_qla_host_t *ha; struct device_reg_2xxx __iomem *reg; int status; - unsigned long flags; unsigned long iter; uint16_t hccr; uint16_t mb[4]; @@ -48,7 +47,7 @@ qla2100_intr_handler(int irq, void *dev_id) reg = &ha->iobase->isp; status = 0; - spin_lock_irqsave(&ha->hardware_lock, flags); + spin_lock(&ha->hardware_lock); for (iter = 50; iter--; ) { hccr = RD_REG_WORD(®->hccr); if (hccr & HCCR_RISC_PAUSE) { @@ -99,7 +98,7 @@ qla2100_intr_handler(int irq, void *dev_id) RD_REG_WORD(®->hccr); } } - spin_unlock_irqrestore(&ha->hardware_lock, flags); + spin_unlock(&ha->hardware_lock); if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && (status & MBX_INTERRUPT) && ha->flags.mbox_int) { @@ -125,7 +124,6 @@ qla2300_intr_handler(int irq, void *dev_id) scsi_qla_host_t *ha; struct device_reg_2xxx __iomem *reg; int status; - unsigned long flags; unsigned long iter; uint32_t stat; uint16_t hccr; @@ -141,7 +139,7 @@ qla2300_intr_handler(int irq, void *dev_id) reg = &ha->iobase->isp; status = 0; - spin_lock_irqsave(&ha->hardware_lock, flags); + spin_lock(&ha->hardware_lock); for (iter = 50; iter--; ) { stat = RD_REG_DWORD(®->u.isp2300.host_status); if (stat & HSR_RISC_PAUSED) { @@ -211,7 +209,7 @@ qla2300_intr_handler(int irq, void *dev_id) WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); RD_REG_WORD_RELAXED(®->hccr); } - spin_unlock_irqrestore(&ha->hardware_lock, flags); + spin_unlock(&ha->hardware_lock); if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && (status & MBX_INTERRUPT) && ha->flags.mbox_int) { @@ -1533,7 +1531,6 @@ qla24xx_intr_handler(int irq, void *dev_id) scsi_qla_host_t *ha; struct device_reg_24xx __iomem *reg; int status; - unsigned long flags; unsigned long iter; uint32_t stat; uint32_t hccr; @@ -1549,7 +1546,7 @@ qla24xx_intr_handler(int irq, void *dev_id) reg = &ha->iobase->isp24; status = 0; - spin_lock_irqsave(&ha->hardware_lock, flags); + spin_lock(&ha->hardware_lock); for (iter = 50; iter--; ) { stat = RD_REG_DWORD(®->host_status); if (stat & HSRX_RISC_PAUSED) { @@ -1597,7 +1594,7 @@ qla24xx_intr_handler(int irq, void *dev_id) WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); RD_REG_DWORD_RELAXED(®->hccr); } - spin_unlock_irqrestore(&ha->hardware_lock, flags); + spin_unlock(&ha->hardware_lock); if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && (status & MBX_INTERRUPT) && ha->flags.mbox_int) { @@ -1656,18 +1653,16 @@ qla24xx_msix_rsp_q(int irq, void *dev_id) { scsi_qla_host_t *ha; struct device_reg_24xx __iomem *reg; - unsigned long flags; ha = dev_id; reg = &ha->iobase->isp24; - spin_lock_irqsave(&ha->hardware_lock, flags); + spin_lock(&ha->hardware_lock); qla24xx_process_response_queue(ha); - WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); - spin_unlock_irqrestore(&ha->hardware_lock, flags); + spin_unlock(&ha->hardware_lock); return IRQ_HANDLED; } @@ -1678,7 +1673,6 @@ qla24xx_msix_default(int irq, void *dev_id) scsi_qla_host_t *ha; struct device_reg_24xx __iomem *reg; int status; - unsigned long flags; uint32_t stat; uint32_t hccr; uint16_t mb[4]; @@ -1687,7 +1681,7 @@ qla24xx_msix_default(int irq, void *dev_id) reg = &ha->iobase->isp24; status = 0; - spin_lock_irqsave(&ha->hardware_lock, flags); + spin_lock(&ha->hardware_lock); do { stat = RD_REG_DWORD(®->host_status); if (stat & HSRX_RISC_PAUSED) { @@ -1734,7 +1728,7 @@ qla24xx_msix_default(int irq, void *dev_id) } WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); } while (0); - spin_unlock_irqrestore(&ha->hardware_lock, flags); + spin_unlock(&ha->hardware_lock); if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && (status & MBX_INTERRUPT) && ha->flags.mbox_int) { @@ -1821,7 +1815,6 @@ qla2x00_request_irqs(scsi_qla_host_t *ha) { int ret; device_reg_t __iomem *reg = ha->iobase; - unsigned long flags; /* If possible, enable MSI-X. */ if (!IS_QLA2432(ha) && !IS_QLA2532(ha)) @@ -1882,7 +1875,7 @@ skip_msi: clear_risc_ints: ha->isp_ops->disable_intrs(ha); - spin_lock_irqsave(&ha->hardware_lock, flags); + spin_lock_irq(&ha->hardware_lock); if (IS_FWI2_CAPABLE(ha)) { WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_HOST_INT); WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_RISC_INT); @@ -1891,7 +1884,7 @@ clear_risc_ints: WRT_REG_WORD(®->isp.hccr, HCCR_CLR_RISC_INT); WRT_REG_WORD(®->isp.hccr, HCCR_CLR_HOST_INT); } - spin_unlock_irqrestore(&ha->hardware_lock, flags); + spin_unlock_irq(&ha->hardware_lock); ha->isp_ops->enable_intrs(ha); fail: -- cgit v1.2.3 From 0971de7f56f809f40edae6fd372745e429e970e9 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 3 Apr 2008 13:13:18 -0700 Subject: [SCSI] qla2xxx: Add FC-transport Asynchronous Event Notification support. Supported events include LIP, LIP reset, RSCN, link up, and link down. To support AEN (and additional forthcoming features), we also introduce a simple deferred-work construct to manage events which require a non-atomic sleeping-capable context. This work-list is processed as part of the driver's standard DPC routine. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_def.h | 22 +++++++++++++ drivers/scsi/qla2xxx/qla_gbl.h | 2 ++ drivers/scsi/qla2xxx/qla_isr.c | 5 +++ drivers/scsi/qla2xxx/qla_os.c | 73 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+) (limited to 'drivers/scsi/qla2xxx') diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index f70c78b6f364..35c730a3f0da 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2115,6 +2115,26 @@ struct qla_msix_entry { #define WATCH_INTERVAL 1 /* number of seconds */ +/* Work events. */ +enum qla_work_type { + QLA_EVT_AEN, +}; + + +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; + } u; +}; + /* * Linux Host Adapter structure */ @@ -2354,6 +2374,8 @@ typedef struct scsi_qla_host { uint32_t login_retry_count; int max_q_depth; + struct list_head work_list; + /* Fibre Channel Device List. */ struct list_head fcports; diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 97625d49a43c..ee52f3e51cc6 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -67,6 +67,8 @@ 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); /* * Global Functions in qla_mid.c source file. diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 4e9f41034466..e9d8a79dd6a4 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -408,6 +408,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); ha->flags.management_server_logged_in = 0; + qla2x00_post_aen_work(ha, FCH_EVT_LIP, mb[1]); break; case MBA_LOOP_UP: /* Loop Up Event */ @@ -427,6 +428,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) link_speed); ha->flags.management_server_logged_in = 0; + qla2x00_post_aen_work(ha, FCH_EVT_LINKUP, ha->link_data_rate); break; case MBA_LOOP_DOWN: /* Loop Down Event */ @@ -450,6 +452,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) ha->link_data_rate = PORT_SPEED_UNKNOWN; if (ql2xfdmienable) set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); + qla2x00_post_aen_work(ha, FCH_EVT_LINKDOWN, 0); break; case MBA_LIP_RESET: /* LIP reset occurred */ @@ -473,6 +476,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) ha->operating_mode = LOOP; ha->flags.management_server_logged_in = 0; + qla2x00_post_aen_work(ha, FCH_EVT_LIPRESET, mb[1]); break; case MBA_POINT_TO_POINT: /* Point-to-Point */ @@ -610,6 +614,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); set_bit(RSCN_UPDATE, &ha->dpc_flags); + qla2x00_post_aen_work(ha, FCH_EVT_RSCN, rscn_entry); break; /* case MBA_RIO_RESPONSE: */ diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 661a1596679d..eb77067533ab 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1704,6 +1704,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) INIT_LIST_HEAD(&ha->list); INIT_LIST_HEAD(&ha->fcports); INIT_LIST_HEAD(&ha->vp_list); + INIT_LIST_HEAD(&ha->work_list); set_bit(0, (unsigned long *) ha->vp_idx_map); @@ -2197,6 +2198,76 @@ qla2x00_mem_free(scsi_qla_host_t *ha) kfree(ha->nvram); } +struct qla_work_evt * +qla2x00_alloc_work(struct scsi_qla_host *ha, enum qla_work_type type, + int locked) +{ + struct qla_work_evt *e; + + e = kzalloc(sizeof(struct qla_work_evt), locked ? GFP_ATOMIC: + GFP_KERNEL); + if (!e) + return NULL; + + INIT_LIST_HEAD(&e->list); + e->type = type; + e->flags = QLA_EVT_FLAG_FREE; + return e; +} + +int +qla2x00_post_work(struct scsi_qla_host *ha, struct qla_work_evt *e, int locked) +{ + unsigned long flags; + + if (!locked) + spin_lock_irqsave(&ha->hardware_lock, flags); + list_add_tail(&e->list, &ha->work_list); + qla2xxx_wake_dpc(ha); + if (!locked) + spin_unlock_irqrestore(&ha->hardware_lock, flags); + return QLA_SUCCESS; +} + +int +qla2x00_post_aen_work(struct scsi_qla_host *ha, enum fc_host_event_code code, + u32 data) +{ + struct qla_work_evt *e; + + e = qla2x00_alloc_work(ha, QLA_EVT_AEN, 1); + if (!e) + return QLA_FUNCTION_FAILED; + + e->u.aen.code = code; + e->u.aen.data = data; + return qla2x00_post_work(ha, e, 1); +} + +static void +qla2x00_do_work(struct scsi_qla_host *ha) +{ + struct qla_work_evt *e; + + spin_lock_irq(&ha->hardware_lock); + while (!list_empty(&ha->work_list)) { + e = list_entry(ha->work_list.next, struct qla_work_evt, list); + list_del_init(&e->list); + spin_unlock_irq(&ha->hardware_lock); + + switch (e->type) { + case QLA_EVT_AEN: + fc_host_post_event(ha->host, fc_get_event_number(), + e->u.aen.code, e->u.aen.data); + break; + } + if (e->flags & QLA_EVT_FLAG_FREE) + kfree(e); + spin_lock_irq(&ha->hardware_lock); + } + spin_unlock_irq(&ha->hardware_lock); +} + /************************************************************************** * qla2x00_do_dpc * This kernel thread is a task that is schedule by the interrupt handler @@ -2248,6 +2319,8 @@ qla2x00_do_dpc(void *data) continue; } + qla2x00_do_work(ha); + if (test_and_clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) { DEBUG(printk("scsi(%ld): dpc: sched " -- cgit v1.2.3 From cb8dacbf1110d8bd39413f3116ff1720f757854e Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 3 Apr 2008 13:13:19 -0700 Subject: [SCSI] qla2xxx: Add hardware trace-logging support. Recent ISPs have a region within FLASH which acts as a repository for the logging of serious hardware and software failures. Currently, the region is large enough to support up to 255 entries. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_def.h | 10 +++ drivers/scsi/qla2xxx/qla_fw.h | 14 +++- drivers/scsi/qla2xxx/qla_gbl.h | 5 ++ drivers/scsi/qla2xxx/qla_init.c | 11 +++ drivers/scsi/qla2xxx/qla_isr.c | 15 ++++ drivers/scsi/qla2xxx/qla_mbx.c | 8 ++ drivers/scsi/qla2xxx/qla_os.c | 23 ++++++ drivers/scsi/qla2xxx/qla_sup.c | 168 ++++++++++++++++++++++++++++++++++------ 8 files changed, 229 insertions(+), 25 deletions(-) (limited to 'drivers/scsi/qla2xxx') diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 35c730a3f0da..13ffedaf8cba 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2118,6 +2118,7 @@ struct qla_msix_entry { /* Work events. */ enum qla_work_type { QLA_EVT_AEN, + QLA_EVT_HWE_LOG, }; @@ -2132,6 +2133,10 @@ struct qla_work_evt { enum fc_host_event_code code; u32 data; } aen; + struct { + uint16_t code; + uint16_t d1, d2, d3; + } hwe; } u; }; @@ -2173,6 +2178,7 @@ typedef struct scsi_qla_host { uint32_t vsan_enabled :1; uint32_t npiv_supported :1; uint32_t fce_enabled :1; + uint32_t hw_event_marker_found :1; } flags; atomic_t loop_state; @@ -2478,6 +2484,10 @@ typedef struct scsi_qla_host { 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; diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 4ae26533fe12..5d19b0e49a62 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -793,7 +793,19 @@ struct device_reg_24xx { #define FA_VPD_NVRAM_ADDR 0x48000 #define FA_FEATURE_ADDR 0x4C000 #define FA_FLASH_DESCR_ADDR 0x50000 -#define FA_HW_EVENT_ADDR 0x54000 +#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 diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index ee52f3e51cc6..276bd26c0c8e 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -69,6 +69,8 @@ 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. @@ -298,6 +300,9 @@ extern uint8_t *qla25xx_read_optrom_data(struct scsi_qla_host *, uint8_t *, extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *); extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *); +extern int qla2xxx_hw_event_log(scsi_qla_host_t *, uint16_t , uint16_t, + uint16_t, uint16_t); + /* * Global Function Prototypes in qla_dbg.c source file. */ diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index e773697cd8d5..e9a7c2d13855 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -500,6 +500,7 @@ qla2x00_reset_chip(scsi_qla_host_t *ha) static inline void qla24xx_reset_risc(scsi_qla_host_t *ha) { + int hw_evt = 0; unsigned long flags = 0; struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; uint32_t cnt, d2; @@ -528,6 +529,8 @@ qla24xx_reset_risc(scsi_qla_host_t *ha) d2 = (uint32_t) RD_REG_WORD(®->mailbox0); barrier(); } + if (cnt == 0) + hw_evt = 1; /* Wait for soft-reset to complete. */ d2 = RD_REG_DWORD(®->ctrl_status); @@ -536,6 +539,10 @@ qla24xx_reset_risc(scsi_qla_host_t *ha) d2 = RD_REG_DWORD(®->ctrl_status); barrier(); } + if (cnt == 0 || hw_evt) + qla2xxx_hw_event_log(ha, HW_EVENT_RESET_ERR, + RD_REG_WORD(®->mailbox1), RD_REG_WORD(®->mailbox2), + RD_REG_WORD(®->mailbox3)); WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET); RD_REG_DWORD(®->hccr); @@ -1555,6 +1562,10 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet " "invalid -- WWPN) defaults.\n"); + if (chksum) + qla2xxx_hw_event_log(ha, HW_EVENT_NVRAM_CHKSUM_ERR, 0, + MSW(chksum), LSW(chksum)); + /* * Set default initialization control block. */ diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index e9d8a79dd6a4..088464251d7e 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -349,6 +349,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n", mb[1], mb[2], mb[3]); + qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]); ha->isp_ops->fw_dump(ha, 1); if (IS_FWI2_CAPABLE(ha)) { @@ -373,6 +374,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) ha->host_no)); qla_printk(KERN_WARNING, ha, "ISP Request Transfer Error.\n"); + qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]); set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); break; @@ -381,6 +383,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) ha->host_no)); qla_printk(KERN_WARNING, ha, "ISP Response Transfer Error.\n"); + qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]); set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); break; @@ -1558,6 +1561,12 @@ qla24xx_intr_handler(int irq, void *dev_id) if (pci_channel_offline(ha->pdev)) break; + if (ha->hw_event_pause_errors == 0) + qla2x00_post_hwe_work(ha, HW_EVENT_PARITY_ERR, + 0, MSW(stat), LSW(stat)); + else if (ha->hw_event_pause_errors < 0xffffffff) + ha->hw_event_pause_errors++; + hccr = RD_REG_DWORD(®->hccr); qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " @@ -1693,6 +1702,12 @@ qla24xx_msix_default(int irq, void *dev_id) if (pci_channel_offline(ha->pdev)) break; + if (ha->hw_event_pause_errors == 0) + qla2x00_post_hwe_work(ha, HW_EVENT_PARITY_ERR, + 0, MSW(stat), LSW(stat)); + else if (ha->hw_event_pause_errors < 0xffffffff) + ha->hw_event_pause_errors++; + hccr = RD_REG_DWORD(®->hccr); qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 898847e4b363..b25c15a86c7f 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -587,6 +587,14 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *ha) if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A || mcp->mb[7] != 0x2525) rval = QLA_FUNCTION_FAILED; + if (rval == QLA_FUNCTION_FAILED) { + struct device_reg_24xx __iomem *reg = + &ha->iobase->isp24; + + qla2xxx_hw_event_log(ha, HW_EVENT_ISP_ERR, 0, + LSW(RD_REG_DWORD(®->hccr)), + LSW(RD_REG_DWORD(®->istatus))); + } } if (rval != QLA_SUCCESS) { diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index eb77067533ab..3d290417bfc6 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1690,6 +1690,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ha->gid_list_info_size = 8; ha->optrom_size = OPTROM_SIZE_25XX; ha->isp_ops = &qla25xx_isp_ops; + ha->hw_event_start = PCI_FUNC(pdev->devfn) ? + FA_HW_EVENT1_ADDR: FA_HW_EVENT0_ADDR; } host->can_queue = ha->request_q_length + 128; @@ -2244,6 +2246,23 @@ qla2x00_post_aen_work(struct scsi_qla_host *ha, enum fc_host_event_code code, return qla2x00_post_work(ha, e, 1); } +int +qla2x00_post_hwe_work(struct scsi_qla_host *ha, uint16_t code, uint16_t d1, + uint16_t d2, uint16_t d3) +{ + struct qla_work_evt *e; + + e = qla2x00_alloc_work(ha, QLA_EVT_HWE_LOG, 1); + if (!e) + return QLA_FUNCTION_FAILED; + + e->u.hwe.code = code; + e->u.hwe.d1 = d1; + e->u.hwe.d2 = d2; + e->u.hwe.d3 = d3; + return qla2x00_post_work(ha, e, 1); +} + static void qla2x00_do_work(struct scsi_qla_host *ha) { @@ -2260,6 +2279,10 @@ qla2x00_do_work(struct scsi_qla_host *ha) fc_host_post_event(ha->host, fc_get_event_number(), e->u.aen.code, e->u.aen.data); break; + case QLA_EVT_HWE_LOG: + qla2xxx_hw_event_log(ha, e->u.hwe.code, e->u.hwe.d1, + e->u.hwe.d2, e->u.hwe.d3); + break; } if (e->flags & QLA_EVT_FLAG_FREE) kfree(e); diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 317cd8f96340..c10ccc75c398 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -543,6 +543,43 @@ qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id, } } +static void +qla24xx_unprotect_flash(scsi_qla_host_t *ha) +{ + struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; + + /* Enable flash write. */ + WRT_REG_DWORD(®->ctrl_status, + RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); + RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ + + /* Disable flash write-protection. */ + qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0); + /* Some flash parts need an additional zero-write to clear bits.*/ + qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0); +} + +static void +qla24xx_protect_flash(scsi_qla_host_t *ha) +{ + uint32_t cnt; + struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; + + /* Enable flash write-protection and wait for completion. */ + qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0x9c); + for (cnt = 300; cnt && + qla24xx_read_flash_dword(ha, + flash_conf_to_access_addr(0x005)) & BIT_0; + cnt--) { + udelay(10); + } + + /* Disable flash write. */ + WRT_REG_DWORD(®->ctrl_status, + RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); + RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ +} + static int qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, uint32_t dwords) @@ -550,9 +587,8 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, int ret; uint32_t liter, miter; uint32_t sec_mask, rest_addr, conf_addr; - uint32_t fdata, findex, cnt; + uint32_t fdata, findex; uint8_t man_id, flash_id; - struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; dma_addr_t optrom_dma; void *optrom = NULL; uint32_t *s, *d; @@ -604,15 +640,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, break; } - /* Enable flash write. */ - WRT_REG_DWORD(®->ctrl_status, - RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); - RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ - - /* Disable flash write-protection. */ - qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0); - /* Some flash parts need an additional zero-write to clear bits.*/ - qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0); + qla24xx_unprotect_flash(ha); for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) { if (man_id == 0x1f) { @@ -690,19 +718,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, 0xff0000) | ((fdata >> 16) & 0xff)); } - /* Enable flash write-protection and wait for completion. */ - qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0x9c); - for (cnt = 300; cnt && - qla24xx_read_flash_dword(ha, - flash_conf_to_access_addr(0x005)) & BIT_0; - cnt--) { - udelay(10); - } - - /* Disable flash write. */ - WRT_REG_DWORD(®->ctrl_status, - RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); - RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ + qla24xx_protect_flash(ha); if (optrom) dma_free_coherent(&ha->pdev->dev, @@ -2221,3 +2237,107 @@ qla24xx_get_flash_version(scsi_qla_host_t *ha, void *mbuf) return ret; } + +static int +qla2xxx_hw_event_store(scsi_qla_host_t *ha, uint32_t *fdata) +{ + uint32_t d[2], faddr; + + /* Locate first empty entry. */ + for (;;) { + if (ha->hw_event_ptr >= + ha->hw_event_start + FA_HW_EVENT_SIZE) { + DEBUG2(qla_printk(KERN_WARNING, ha, + "HW event -- Log Full!\n")); + return QLA_MEMORY_ALLOC_FAILED; + } + + qla24xx_read_flash_data(ha, d, ha->hw_event_ptr, 2); + faddr = flash_data_to_access_addr(ha->hw_event_ptr); + ha->hw_event_ptr += FA_HW_EVENT_ENTRY_SIZE; + if (d[0] == __constant_cpu_to_le32(0xffffffff) && + d[1] == __constant_cpu_to_le32(0xffffffff)) { + qla24xx_unprotect_flash(ha); + + qla24xx_write_flash_dword(ha, faddr++, + cpu_to_le32(jiffies)); + qla24xx_write_flash_dword(ha, faddr++, 0); + qla24xx_write_flash_dword(ha, faddr++, *fdata++); + qla24xx_write_flash_dword(ha, faddr++, *fdata); + + qla24xx_protect_flash(ha); + break; + } + } + return QLA_SUCCESS; +} + +int +qla2xxx_hw_event_log(scsi_qla_host_t *ha, uint16_t code, uint16_t d1, + uint16_t d2, uint16_t d3) +{ +#define QMARK(a, b, c, d) \ + cpu_to_le32(LSB(a) << 24 | LSB(b) << 16 | LSB(c) << 8 | LSB(d)) + + int rval; + uint32_t marker[2], fdata[4]; + + if (ha->hw_event_start == 0) + return QLA_FUNCTION_FAILED; + + DEBUG2(qla_printk(KERN_WARNING, ha, + "HW event -- code=%x, d1=%x, d2=%x, d3=%x.\n", code, d1, d2, d3)); + + /* If marker not already found, locate or write. */ + if (!ha->flags.hw_event_marker_found) { + /* Create marker. */ + marker[0] = QMARK('L', ha->fw_major_version, + ha->fw_minor_version, ha->fw_subminor_version); + marker[1] = QMARK(QLA_DRIVER_MAJOR_VER, QLA_DRIVER_MINOR_VER, + QLA_DRIVER_PATCH_VER, QLA_DRIVER_BETA_VER); + + /* Locate marker. */ + ha->hw_event_ptr = ha->hw_event_start; + for (;;) { + qla24xx_read_flash_data(ha, fdata, ha->hw_event_ptr, + 4); + if (fdata[0] == __constant_cpu_to_le32(0xffffffff) && + fdata[1] == __constant_cpu_to_le32(0xffffffff)) + break; + ha->hw_event_ptr += FA_HW_EVENT_ENTRY_SIZE; + if (ha->hw_event_ptr >= + ha->hw_event_start + FA_HW_EVENT_SIZE) { + DEBUG2(qla_printk(KERN_WARNING, ha, + "HW event -- Log Full!\n")); + return QLA_MEMORY_ALLOC_FAILED; + } + if (fdata[2] == marker[0] && fdata[3] == marker[1]) { + ha->flags.hw_event_marker_found = 1; + break; + } + } + /* No marker, write it. */ + if (!ha->flags.hw_event_marker_found) { + rval = qla2xxx_hw_event_store(ha, marker); + if (rval != QLA_SUCCESS) { + DEBUG2(qla_printk(KERN_WARNING, ha, + "HW event -- Failed marker write=%x.!\n", + rval)); + return rval; + } + ha->flags.hw_event_marker_found = 1; + } + } + + /* Store error. */ + fdata[0] = cpu_to_le32(code << 16 | d1); + fdata[1] = cpu_to_le32(d2 << 16 | d3); + rval = qla2xxx_hw_event_store(ha, fdata); + if (rval != QLA_SUCCESS) { + DEBUG2(qla_printk(KERN_WARNING, ha, + "HW event -- Failed error write=%x.!\n", + rval)); + } + + return rval; +} -- cgit v1.2.3 From 587f4cae4a8ce1315c3def2229c2a912637269b6 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 3 Apr 2008 13:13:20 -0700 Subject: [SCSI] qla2xxx: Cruft cleanup of functions and structures. Strip unused (DEBUG-ONLY) enabled functions, inlines, useless wrappers, and unused DPC flags from the code. Another step in the migration towards a cleaner (less-crusty) driver. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_dbg.c | 122 -------------------------------------- drivers/scsi/qla2xxx/qla_dbg.h | 13 ---- drivers/scsi/qla2xxx/qla_def.h | 2 - drivers/scsi/qla2xxx/qla_gbl.h | 4 -- drivers/scsi/qla2xxx/qla_gs.c | 6 -- drivers/scsi/qla2xxx/qla_init.c | 41 ------------- drivers/scsi/qla2xxx/qla_inline.h | 85 -------------------------- drivers/scsi/qla2xxx/qla_iocb.c | 3 - drivers/scsi/qla2xxx/qla_isr.c | 90 ---------------------------- drivers/scsi/qla2xxx/qla_mid.c | 2 - drivers/scsi/qla2xxx/qla_os.c | 62 +------------------ 11 files changed, 2 insertions(+), 428 deletions(-) (limited to 'drivers/scsi/qla2xxx') diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 83dd68bacf2a..9d12d9f26209 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -1410,125 +1410,3 @@ qla2x00_dump_buffer(uint8_t * b, uint32_t size) if (cnt % 16) printk("\n"); } - -/************************************************************************** - * qla2x00_print_scsi_cmd - * Dumps out info about the scsi cmd and srb. - * Input - * cmd : struct scsi_cmnd - **************************************************************************/ -void -qla2x00_print_scsi_cmd(struct scsi_cmnd * cmd) -{ - int i; - struct scsi_qla_host *ha; - srb_t *sp; - - ha = shost_priv(cmd->device->host); - - sp = (srb_t *) cmd->SCp.ptr; - printk("SCSI Command @=0x%p, Handle=0x%p\n", cmd, cmd->host_scribble); - printk(" chan=0x%02x, target=0x%02x, lun=0x%02x, cmd_len=0x%02x\n", - cmd->device->channel, cmd->device->id, cmd->device->lun, - cmd->cmd_len); - printk(" CDB: "); - for (i = 0; i < cmd->cmd_len; i++) { - printk("0x%02x ", cmd->cmnd[i]); - } - printk("\n seg_cnt=%d, allowed=%d, retries=%d\n", - scsi_sg_count(cmd), cmd->allowed, cmd->retries); - printk(" request buffer=0x%p, request buffer len=0x%x\n", - scsi_sglist(cmd), scsi_bufflen(cmd)); - printk(" tag=%d, transfersize=0x%x\n", - cmd->tag, cmd->transfersize); - printk(" serial_number=%lx, SP=%p\n", cmd->serial_number, sp); - printk(" data direction=%d\n", cmd->sc_data_direction); - - if (!sp) - return; - - printk(" sp flags=0x%x\n", sp->flags); -} - -#if defined(QL_DEBUG_ROUTINES) -/* - * qla2x00_formatted_dump_buffer - * Prints string plus buffer. - * - * Input: - * string = Null terminated string (no newline at end). - * buffer = buffer address. - * wd_size = word size 8, 16, 32 or 64 bits - * count = number of words. - */ -void -qla2x00_formatted_dump_buffer(char *string, uint8_t * buffer, - uint8_t wd_size, uint32_t count) -{ - uint32_t cnt; - uint16_t *buf16; - uint32_t *buf32; - - if (strcmp(string, "") != 0) - printk("%s\n",string); - - switch (wd_size) { - case 8: - printk(" 0 1 2 3 4 5 6 7 " - "8 9 Ah Bh Ch Dh Eh Fh\n"); - printk("-----------------------------------------" - "-------------------------------------\n"); - - for (cnt = 1; cnt <= count; cnt++, buffer++) { - printk("%02x",*buffer); - if (cnt % 16 == 0) - printk("\n"); - else - printk(" "); - } - if (cnt % 16 != 0) - printk("\n"); - break; - case 16: - printk(" 0 2 4 6 8 Ah " - " Ch Eh\n"); - printk("-----------------------------------------" - "-------------\n"); - - buf16 = (uint16_t *) buffer; - for (cnt = 1; cnt <= count; cnt++, buf16++) { - printk("%4x",*buf16); - - if (cnt % 8 == 0) - printk("\n"); - else if (*buf16 < 10) - printk(" "); - else - printk(" "); - } - if (cnt % 8 != 0) - printk("\n"); - break; - case 32: - printk(" 0 4 8 Ch\n"); - printk("------------------------------------------\n"); - - buf32 = (uint32_t *) buffer; - for (cnt = 1; cnt <= count; cnt++, buf32++) { - printk("%8x", *buf32); - - if (cnt % 4 == 0) - printk("\n"); - else if (*buf32 < 10) - printk(" "); - else - printk(" "); - } - if (cnt % 4 != 0) - printk("\n"); - break; - default: - break; - } -} -#endif diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index c30f2fa284f2..2a4043b5b145 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h @@ -22,19 +22,6 @@ /* #define QL_DEBUG_LEVEL_13 */ /* Output fdmi function trace msgs */ /* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */ /* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */ -/* - * 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) || \ - defined(QL_DEBUG_LEVEL_15) - #define QL_DEBUG_ROUTINES -#endif /* * Macros use for debugging the driver. diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 13ffedaf8cba..047973f37847 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2449,8 +2449,6 @@ typedef struct scsi_qla_host { #define MBX_TIMEDOUT BIT_5 #define MBX_ACCESS_TIMEDOUT BIT_6 - mbx_cmd_t mc; - /* Basic firmware related information. */ uint16_t fw_major_version; uint16_t fw_minor_version; diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 276bd26c0c8e..10c3f905b711 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -38,9 +38,6 @@ extern int qla2x00_loop_resync(scsi_qla_host_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 *); @@ -312,7 +309,6 @@ extern void qla24xx_fw_dump(scsi_qla_host_t *, int); 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 *); /* * Global Function Prototypes in qla_gs.c source file. diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index ea8a7d3e9ce5..e6578ce34ecd 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -6,12 +6,6 @@ */ #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 *); diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index e9a7c2d13855..d429e2f5c70e 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -15,14 +15,6 @@ #include #endif -/* XXX(hch): this is ugly, but we don't want to pull in exioctl.h */ -#ifndef EXT_IS_LUN_BIT_SET -#define EXT_IS_LUN_BIT_SET(P,L) \ - (((P)->mask[L/8] & (0x80 >> (L%8)))?1:0) -#define EXT_SET_LUN_BIT(P,L) \ - ((P)->mask[L/8] |= (0x80 >> (L%8))) -#endif - /* * QLogic ISP2x00 Hardware Support Function Prototypes. */ @@ -2175,20 +2167,6 @@ cleanup_allocation: return (rval); } -static void -qla2x00_probe_for_all_luns(scsi_qla_host_t *ha) -{ - fc_port_t *fcport; - - qla2x00_mark_all_devices_lost(ha, 0); - list_for_each_entry(fcport, &ha->fcports, list) { - if (fcport->port_type != FCT_TARGET) - continue; - - qla2x00_update_fcport(ha, fcport); - } -} - static void qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) { @@ -3199,25 +3177,6 @@ qla2x00_loop_resync(scsi_qla_host_t *ha) return (rval); } -void -qla2x00_rescan_fcports(scsi_qla_host_t *ha) -{ - int rescan_done; - fc_port_t *fcport; - - rescan_done = 0; - list_for_each_entry(fcport, &ha->fcports, list) { - if ((fcport->flags & FCF_RESCAN_NEEDED) == 0) - continue; - - qla2x00_update_fcport(ha, fcport); - fcport->flags &= ~FCF_RESCAN_NEEDED; - - rescan_done = 1; - } - qla2x00_probe_for_all_luns(ha); -} - void qla2x00_update_fcports(scsi_qla_host_t *ha) { diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h index 3e57a3e03dac..e9bae27737d1 100644 --- a/drivers/scsi/qla2xxx/qla_inline.h +++ b/drivers/scsi/qla2xxx/qla_inline.h @@ -5,7 +5,6 @@ * 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,94 +31,12 @@ 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) { ha->isp_ops->intr_handler(0, ha); } -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) -{ - uint16_t fw_state; - - qla2x00_get_firmware_state(ha, &fw_state); -} - -static __inline__ scsi_qla_host_t * to_qla_parent(scsi_qla_host_t *); static __inline__ scsi_qla_host_t * to_qla_parent(scsi_qla_host_t *ha) { @@ -152,7 +69,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) { @@ -166,7 +82,6 @@ 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) { diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 9192ad574d99..5489d5024673 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -11,9 +11,6 @@ #include -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 *); static request_t *qla2x00_req_pkt(scsi_qla_host_t *ha); static void qla2x00_isp_cmd(scsi_qla_host_t *ha); diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 088464251d7e..e88600082c01 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -14,9 +14,6 @@ static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t); static void qla2x00_status_entry(scsi_qla_host_t *, void *); static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *); static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *); -static void qla2x00_ms_entry(scsi_qla_host_t *, ms_iocb_entry_t *); - -static void qla24xx_ms_entry(scsi_qla_host_t *, struct ct_entry_24xx *); /** * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200. @@ -809,9 +806,6 @@ qla2x00_process_response_queue(struct scsi_qla_host *ha) case STATUS_CONT_TYPE: qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt); break; - case MS_IOCB_TYPE: - qla2x00_ms_entry(ha, (ms_iocb_entry_t *)pkt); - break; default: /* Type Not Supported. */ DEBUG4(printk(KERN_WARNING @@ -1345,44 +1339,6 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt) } } -/** - * qla2x00_ms_entry() - Process a Management Server entry. - * @ha: SCSI driver HA context - * @index: Response queue out pointer - */ -static void -qla2x00_ms_entry(scsi_qla_host_t *ha, ms_iocb_entry_t *pkt) -{ - srb_t *sp; - - DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n", - __func__, ha->host_no, pkt, pkt->handle1)); - - /* Validate handle. */ - if (pkt->handle1 < MAX_OUTSTANDING_COMMANDS) - sp = ha->outstanding_cmds[pkt->handle1]; - else - sp = NULL; - - if (sp == NULL) { - DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n", - ha->host_no)); - qla_printk(KERN_WARNING, ha, "MS entry - invalid handle\n"); - - set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); - return; - } - - CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->status); - CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status; - - /* Free outstanding command slot. */ - ha->outstanding_cmds[pkt->handle1] = NULL; - - qla2x00_sp_compl(ha, sp); -} - - /** * qla24xx_mbx_completion() - Process mailbox command completions. * @ha: SCSI driver HA context @@ -1455,9 +1411,6 @@ qla24xx_process_response_queue(struct scsi_qla_host *ha) case STATUS_CONT_TYPE: qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt); break; - case MS_IOCB_TYPE: - qla24xx_ms_entry(ha, (struct ct_entry_24xx *)pkt); - break; case VP_RPT_ID_IOCB_TYPE: qla24xx_report_id_acquisition(ha, (struct vp_rpt_id_entry_24xx *)pkt); @@ -1619,49 +1572,6 @@ qla24xx_intr_handler(int irq, void *dev_id) return IRQ_HANDLED; } -/** - * qla24xx_ms_entry() - Process a Management Server entry. - * @ha: SCSI driver HA context - * @index: Response queue out pointer - */ -static void -qla24xx_ms_entry(scsi_qla_host_t *ha, struct ct_entry_24xx *pkt) -{ - srb_t *sp; - - DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n", - __func__, ha->host_no, pkt, pkt->handle)); - - DEBUG9(printk("%s: ct pkt dump:\n", __func__)); - DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx))); - - /* Validate handle. */ - if (pkt->handle < MAX_OUTSTANDING_COMMANDS) - sp = ha->outstanding_cmds[pkt->handle]; - else - sp = NULL; - - if (sp == NULL) { - DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n", - ha->host_no)); - DEBUG10(printk("scsi(%ld): MS entry - invalid handle\n", - ha->host_no)); - qla_printk(KERN_WARNING, ha, "MS entry - invalid handle %d\n", - pkt->handle); - - set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); - return; - } - - CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->comp_status); - CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status; - - /* Free outstanding command slot. */ - ha->outstanding_cmds[pkt->handle] = NULL; - - qla2x00_sp_compl(ha, sp); -} - static irqreturn_t qla24xx_msix_rsp_q(int irq, void *dev_id) { diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 5305ec194239..9f48cd46f618 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -16,8 +16,6 @@ #include #include -void qla2x00_vp_stop_timer(scsi_qla_host_t *); - void qla2x00_vp_stop_timer(scsi_qla_host_t *vha) { diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 3d290417bfc6..c0f6f66c358f 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -26,9 +26,6 @@ char qla2x00_version_str[40]; */ static struct kmem_cache *srb_cachep; -/* - * Ioctl related information. - */ int num_hosts; int ql2xlogintimeout = 20; module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR); @@ -105,7 +102,6 @@ static int qla2xxx_eh_abort(struct scsi_cmnd *); static int qla2xxx_eh_device_reset(struct scsi_cmnd *); static int qla2xxx_eh_bus_reset(struct scsi_cmnd *); static int qla2xxx_eh_host_reset(struct scsi_cmnd *); -static int qla2x00_device_reset(scsi_qla_host_t *, fc_port_t *); static int qla2x00_change_queue_depth(struct scsi_device *, int); static int qla2x00_change_queue_type(struct scsi_device *, int); @@ -685,7 +681,6 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld.\n", __func__, ha->host_no, sp, serial)); - DEBUG3(qla2x00_print_scsi_cmd(cmd)); spin_unlock_irqrestore(&pha->hardware_lock, flags); if (ha->isp_ops->abort_command(ha, sp)) { @@ -814,7 +809,7 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) goto eh_dev_reset_done; if (qla2x00_wait_for_loop_ready(ha) == QLA_SUCCESS) { - if (qla2x00_device_reset(ha, fcport) == 0) + if (ha->isp_ops->abort_target(fcport) == 0) ret = SUCCESS; } else { DEBUG2(printk(KERN_INFO @@ -1071,7 +1066,7 @@ qla2x00_loop_reset(scsi_qla_host_t *ha) if (fcport->port_type != FCT_TARGET) continue; - ret = qla2x00_device_reset(ha, fcport); + ret = ha->isp_ops->abort_target(fcport); if (ret != QLA_SUCCESS) { DEBUG2_3(printk("%s(%ld): bus_reset failed: " "target_reset=%d d_id=%x.\n", __func__, @@ -1086,26 +1081,6 @@ qla2x00_loop_reset(scsi_qla_host_t *ha) return QLA_SUCCESS; } -/* - * qla2x00_device_reset - * Issue bus device reset message to the target. - * - * Input: - * ha = adapter block pointer. - * t = SCSI ID. - * TARGET_QUEUE_LOCK must be released. - * ADAPTER_STATE_LOCK must be released. - * - * Context: - * Kernel context. - */ -static int -qla2x00_device_reset(scsi_qla_host_t *ha, fc_port_t *reset_fcport) -{ - /* Abort Target command will clear Reservation */ - return ha->isp_ops->abort_target(reset_fcport); -} - void qla2x00_abort_all_cmds(scsi_qla_host_t *ha, int res) { @@ -2378,12 +2353,6 @@ qla2x00_do_dpc(void *data) if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags)) qla2x00_update_fcports(ha); - if (test_and_clear_bit(LOOP_RESET_NEEDED, &ha->dpc_flags)) { - DEBUG(printk("scsi(%ld): dpc: sched loop_reset()\n", - ha->host_no)); - qla2x00_loop_reset(ha); - } - if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) && (!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) { @@ -2454,19 +2423,6 @@ qla2x00_do_dpc(void *data) ha->host_no)); } - if ((test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags)) && - atomic_read(&ha->loop_state) != LOOP_DOWN) { - - clear_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags); - DEBUG(printk("scsi(%ld): qla2x00_login_retry()\n", - ha->host_no)); - - set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); - - DEBUG(printk("scsi(%ld): qla2x00_login_retry - end\n", - ha->host_no)); - } - if (test_and_clear_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) { DEBUG(printk("scsi(%ld): qla2x00_loop_resync()\n", @@ -2484,18 +2440,6 @@ qla2x00_do_dpc(void *data) ha->host_no)); } - if (test_and_clear_bit(FCPORT_RESCAN_NEEDED, &ha->dpc_flags)) { - - DEBUG(printk("scsi(%ld): Rescan flagged fcports...\n", - ha->host_no)); - - qla2x00_rescan_fcports(ha); - - DEBUG(printk("scsi(%ld): Rescan flagged fcports..." - "end.\n", - ha->host_no)); - } - if (!ha->interrupts_on) ha->isp_ops->enable_intrs(ha); @@ -2697,10 +2641,8 @@ qla2x00_timer(scsi_qla_host_t *ha) /* Schedule the DPC routine if needed */ if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || - test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags) || test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags) || start_dpc || - test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) || test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) || test_bit(VP_DPC_NEEDED, &ha->dpc_flags) || -- cgit v1.2.3 From c87a0d8c8de7e191cd59779560d8df2e935c7dc7 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 3 Apr 2008 13:13:21 -0700 Subject: [SCSI] qla2xxx: Use PCI-SIG nomenclature for PCIe bandwidth units. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_os.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/scsi/qla2xxx') diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index c0f6f66c358f..ba7d2ca3a0e8 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -249,9 +249,9 @@ qla24xx_pci_info_str(struct scsi_qla_host *ha, char *str) strcpy(str, "PCIe ("); if (lspeed == 1) - strcat(str, "2.5Gb/s "); + strcat(str, "2.5GT/s "); else if (lspeed == 2) - strcat(str, "5.0Gb/s "); + strcat(str, "5.0GT/s "); else strcat(str, " "); snprintf(lwstr, sizeof(lwstr), "x%d)", lwidth); -- cgit v1.2.3 From 7d232c745ef2ce141cc9d9538421affa32846fdb Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 3 Apr 2008 13:13:22 -0700 Subject: [SCSI] qla2xxx: Add Flash Descriptor Table layout support. The Flash Descriptor Table (FDT) present on many recent HBAs encodes flash accessing characteristics of the flash-part used on the HBA. Use this information during flash manipulation (writes) rather than using specific hard-coded values based on queried manufacturer and device IDs. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_def.h | 7 ++ drivers/scsi/qla2xxx/qla_fw.h | 32 +++++++++ drivers/scsi/qla2xxx/qla_gbl.h | 2 + drivers/scsi/qla2xxx/qla_init.c | 1 + drivers/scsi/qla2xxx/qla_sup.c | 153 +++++++++++++++++++++++++++++----------- 5 files changed, 152 insertions(+), 43 deletions(-) (limited to 'drivers/scsi/qla2xxx') diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 047973f37847..7e6b6da6a67d 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2521,6 +2521,13 @@ typedef struct scsi_qla_host { 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; uint8_t beacon_color_state; diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 5d19b0e49a62..38adc0f06e93 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -1186,4 +1186,36 @@ struct vf_evfp_entry_24xx { }; /* 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]; +}; #endif diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 10c3f905b711..f25aa63ad191 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -300,6 +300,8 @@ 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. */ diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index d429e2f5c70e..10e6995b39a7 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -106,6 +106,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) rval = qla2x00_setup_chip(ha); if (rval) return (rval); + qla2xxx_get_flash_info(ha); } rval = qla2x00_init_rings(ha); diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index c10ccc75c398..eda11f6f5e52 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -543,6 +543,96 @@ qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id, } } +void +qla2xxx_get_flash_info(scsi_qla_host_t *ha) +{ +#define FLASH_BLK_SIZE_32K 0x8000 +#define FLASH_BLK_SIZE_64K 0x10000 + uint16_t cnt, chksum; + uint16_t *wptr; + struct qla_fdt_layout *fdt; + uint8_t man_id, flash_id; + + if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha)) + return; + + wptr = (uint16_t *)ha->request_ring; + fdt = (struct qla_fdt_layout *)ha->request_ring; + ha->isp_ops->read_optrom(ha, (uint8_t *)ha->request_ring, + FA_FLASH_DESCR_ADDR << 2, OPTROM_BURST_SIZE); + if (*wptr == __constant_cpu_to_le16(0xffff)) + goto no_flash_data; + if (fdt->sig[0] != 'Q' || fdt->sig[1] != 'L' || fdt->sig[2] != 'I' || + fdt->sig[3] != 'D') + goto no_flash_data; + + for (cnt = 0, chksum = 0; cnt < sizeof(struct qla_fdt_layout) >> 1; + cnt++) + chksum += le16_to_cpu(*wptr++); + if (chksum) { + DEBUG2(qla_printk(KERN_INFO, ha, "Inconsistent FDT detected: " + "checksum=0x%x id=%c version=0x%x.\n", chksum, fdt->sig[0], + le16_to_cpu(fdt->version))); + DEBUG9(qla2x00_dump_buffer((uint8_t *)fdt, sizeof(*fdt))); + goto no_flash_data; + } + + ha->fdt_odd_index = le16_to_cpu(fdt->man_id) == 0x1f; + ha->fdt_wrt_disable = fdt->wrt_disable_bits; + ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0300 | fdt->erase_cmd); + ha->fdt_block_size = le32_to_cpu(fdt->block_size); + if (fdt->unprotect_sec_cmd) { + ha->fdt_unprotect_sec_cmd = flash_conf_to_access_addr(0x0300 | + fdt->unprotect_sec_cmd); + ha->fdt_protect_sec_cmd = fdt->protect_sec_cmd ? + flash_conf_to_access_addr(0x0300 | fdt->protect_sec_cmd): + flash_conf_to_access_addr(0x0336); + } + + DEBUG2(qla_printk(KERN_DEBUG, ha, "Flash[FDT]: (0x%x/0x%x) erase=0x%x " + "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n", + le16_to_cpu(fdt->man_id), le16_to_cpu(fdt->id), ha->fdt_erase_cmd, + ha->fdt_protect_sec_cmd, ha->fdt_unprotect_sec_cmd, + ha->fdt_odd_index, ha->fdt_wrt_disable, ha->fdt_block_size)); + return; + +no_flash_data: + qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id); + ha->fdt_wrt_disable = 0x9c; + ha->fdt_erase_cmd = flash_conf_to_access_addr(0x03d8); + switch (man_id) { + case 0xbf: /* STT flash. */ + if (flash_id == 0x8e) + ha->fdt_block_size = FLASH_BLK_SIZE_64K; + else + ha->fdt_block_size = FLASH_BLK_SIZE_32K; + + if (flash_id == 0x80) + ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0352); + break; + case 0x13: /* ST M25P80. */ + ha->fdt_block_size = FLASH_BLK_SIZE_64K; + break; + case 0x1f: /* Atmel 26DF081A. */ + ha->fdt_odd_index = 1; + ha->fdt_block_size = FLASH_BLK_SIZE_64K; + ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0320); + ha->fdt_unprotect_sec_cmd = flash_conf_to_access_addr(0x0339); + ha->fdt_protect_sec_cmd = flash_conf_to_access_addr(0x0336); + break; + default: + /* Default to 64 kb sector size. */ + ha->fdt_block_size = FLASH_BLK_SIZE_64K; + break; + } + + DEBUG2(qla_printk(KERN_DEBUG, ha, "Flash[MID]: (0x%x/0x%x) erase=0x%x " + "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n", man_id, flash_id, + ha->fdt_erase_cmd, ha->fdt_protect_sec_cmd, + ha->fdt_unprotect_sec_cmd, ha->fdt_odd_index, ha->fdt_wrt_disable, + ha->fdt_block_size)); +} + static void qla24xx_unprotect_flash(scsi_qla_host_t *ha) { @@ -553,6 +643,9 @@ qla24xx_unprotect_flash(scsi_qla_host_t *ha) RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ + if (!ha->fdt_wrt_disable) + return; + /* Disable flash write-protection. */ qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0); /* Some flash parts need an additional zero-write to clear bits.*/ @@ -565,8 +658,12 @@ qla24xx_protect_flash(scsi_qla_host_t *ha) uint32_t cnt; struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; + if (!ha->fdt_wrt_disable) + goto skip_wrt_protect; + /* Enable flash write-protection and wait for completion. */ - qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0x9c); + qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), + ha->fdt_wrt_disable); for (cnt = 300; cnt && qla24xx_read_flash_dword(ha, flash_conf_to_access_addr(0x005)) & BIT_0; @@ -574,6 +671,7 @@ qla24xx_protect_flash(scsi_qla_host_t *ha) udelay(10); } +skip_wrt_protect: /* Disable flash write. */ WRT_REG_DWORD(®->ctrl_status, RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); @@ -586,9 +684,8 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, { int ret; uint32_t liter, miter; - uint32_t sec_mask, rest_addr, conf_addr; + uint32_t sec_mask, rest_addr; uint32_t fdata, findex; - uint8_t man_id, flash_id; dma_addr_t optrom_dma; void *optrom = NULL; uint32_t *s, *d; @@ -607,43 +704,13 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, } } - qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id); - DEBUG9(printk("%s(%ld): Flash man_id=%d flash_id=%d\n", __func__, - ha->host_no, man_id, flash_id)); - - conf_addr = flash_conf_to_access_addr(0x03d8); - switch (man_id) { - case 0xbf: /* STT flash. */ - if (flash_id == 0x8e) { - rest_addr = 0x3fff; - sec_mask = 0x7c000; - } else { - rest_addr = 0x1fff; - sec_mask = 0x7e000; - } - if (flash_id == 0x80) - conf_addr = flash_conf_to_access_addr(0x0352); - break; - case 0x13: /* ST M25P80. */ - rest_addr = 0x3fff; - sec_mask = 0x7c000; - break; - case 0x1f: // Atmel 26DF081A - rest_addr = 0x3fff; - sec_mask = 0x7c000; - conf_addr = flash_conf_to_access_addr(0x0320); - break; - default: - /* Default to 64 kb sector size. */ - rest_addr = 0x3fff; - sec_mask = 0x7c000; - break; - } + rest_addr = (ha->fdt_block_size >> 2) - 1; + sec_mask = 0x80000 - (ha->fdt_block_size >> 2); qla24xx_unprotect_flash(ha); for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) { - if (man_id == 0x1f) { + if (ha->fdt_odd_index) { findex = faddr << 2; fdata = findex & sec_mask; } else { @@ -653,13 +720,13 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, /* Are we at the beginning of a sector? */ if ((findex & rest_addr) == 0) { - /* Do sector unprotect at 4K boundry for Atmel part. */ - if (man_id == 0x1f) + /* Do sector unprotect. */ + if (ha->fdt_unprotect_sec_cmd) qla24xx_write_flash_dword(ha, - flash_conf_to_access_addr(0x0339), + ha->fdt_unprotect_sec_cmd, (fdata & 0xff00) | ((fdata << 16) & 0xff0000) | ((fdata >> 16) & 0xff)); - ret = qla24xx_write_flash_dword(ha, conf_addr, + ret = qla24xx_write_flash_dword(ha, ha->fdt_erase_cmd, (fdata & 0xff00) |((fdata << 16) & 0xff0000) | ((fdata >> 16) & 0xff)); if (ret != QLA_SUCCESS) { @@ -709,11 +776,11 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, break; } - /* Do sector protect at 4K boundry for Atmel part. */ - if (man_id == 0x1f && + /* Do sector protect. */ + if (ha->fdt_unprotect_sec_cmd && ((faddr & rest_addr) == rest_addr)) qla24xx_write_flash_dword(ha, - flash_conf_to_access_addr(0x0336), + ha->fdt_protect_sec_cmd, (fdata & 0xff00) | ((fdata << 16) & 0xff0000) | ((fdata >> 16) & 0xff)); } -- cgit v1.2.3 From 3fe7cfb910ea138ae623d1320c71e2a7a0bdc527 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 3 Apr 2008 13:13:23 -0700 Subject: [SCSI] qla2xxx: Check alternate 'reason' code during GPSC status handling. Some switches return 0x09 (Command not supported) as the reason code for GPSC failure. Check for this code, and disable additional GPSC queries if found. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_def.h | 1 + drivers/scsi/qla2xxx/qla_gs.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/scsi/qla2xxx') diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 7e6b6da6a67d..3843eaa3af06 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -1611,6 +1611,7 @@ typedef struct fc_port { #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 diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index e6578ce34ecd..980ccb3eed33 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -1841,8 +1841,10 @@ qla2x00_gpsc(scsi_qla_host_t *ha, sw_info_t *list) "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_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)); -- cgit v1.2.3 From 523ec773b8ffb1c607bc3a54c9526558e3b1eab1 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 3 Apr 2008 13:13:24 -0700 Subject: [SCSI] qla2xxx: Add midlayer target/device reset support. Now that infrastructure is present within the midlayer and there is a clear distinction between what is expected from a device and target reset, convert the current device-reset codes to a target-reset, and add codes to perform a proper device-reset (LUN reset). In the process of adding reset support, collapse and consolidate large sections of mailbox-command (TMF issuance) codes, generalize the two 'wait-for-commands-to-complete' functions, and add a generic-reset routine for use by midlayer reset functions. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_def.h | 3 +- drivers/scsi/qla2xxx/qla_fw.h | 2 +- drivers/scsi/qla2xxx/qla_gbl.h | 8 +- drivers/scsi/qla2xxx/qla_mbx.c | 123 +++++++++++++------- drivers/scsi/qla2xxx/qla_os.c | 254 ++++++++++++++++------------------------- 5 files changed, 192 insertions(+), 198 deletions(-) (limited to 'drivers/scsi/qla2xxx') diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 3843eaa3af06..f7919d348ccd 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2062,7 +2062,8 @@ struct isp_operations { 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, diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 38adc0f06e93..c6a5e49a25be 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -719,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 diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index f25aa63ad191..f2133647bf25 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -153,7 +153,10 @@ extern int qla2x00_abort_command(scsi_qla_host_t *, srb_t *); extern int -qla2x00_abort_target(fc_port_t *); +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 *, @@ -219,7 +222,8 @@ 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 qla24xx_abort_target(struct fc_port *, unsigned int); +extern int qla24xx_lun_reset(struct fc_port *, unsigned int); extern int qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index b25c15a86c7f..c1af56dec4d4 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -784,35 +784,20 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp) return rval; } -/* - * qla2x00_abort_target - * Issue abort target mailbox command. - * - * Input: - * ha = adapter block pointer. - * - * Returns: - * qla2x00 local function return status code. - * - * Context: - * Kernel context. - */ int -qla2x00_abort_target(fc_port_t *fcport) +qla2x00_abort_target(struct fc_port *fcport, unsigned int l) { - int rval; + int rval, rval2; mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; scsi_qla_host_t *ha; - if (fcport == NULL) - return 0; - DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); + l = l; ha = fcport->ha; mcp->mb[0] = MBC_ABORT_TARGET; - mcp->out_mb = MBX_2|MBX_1|MBX_0; + mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0; if (HAS_EXTENDED_IDS(ha)) { mcp->mb[1] = fcport->loop_id; mcp->mb[10] = 0; @@ -821,22 +806,66 @@ qla2x00_abort_target(fc_port_t *fcport) mcp->mb[1] = fcport->loop_id << 8; } mcp->mb[2] = ha->loop_reset_delay; + mcp->mb[9] = ha->vp_idx; mcp->in_mb = MBX_0; mcp->tov = 30; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); + if (rval != QLA_SUCCESS) { + DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, + ha->host_no, rval)); + } + + /* Issue marker IOCB. */ + rval2 = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID); + if (rval2 != QLA_SUCCESS) { + DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " + "(%x).\n", __func__, ha->host_no, rval2)); + } else { + DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); + } + + return rval; +} + +int +qla2x00_lun_reset(struct fc_port *fcport, unsigned int l) +{ + int rval, rval2; + mbx_cmd_t mc; + mbx_cmd_t *mcp = &mc; + scsi_qla_host_t *ha; + + DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); - /* Issue marker command. */ - ha->marker_needed = 1; + ha = fcport->ha; + mcp->mb[0] = MBC_LUN_RESET; + mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0; + if (HAS_EXTENDED_IDS(ha)) + mcp->mb[1] = fcport->loop_id; + else + mcp->mb[1] = fcport->loop_id << 8; + mcp->mb[2] = l; + mcp->mb[3] = 0; + mcp->mb[9] = ha->vp_idx; + mcp->in_mb = MBX_0; + mcp->tov = 30; + mcp->flags = 0; + rval = qla2x00_mailbox_command(ha, mcp); if (rval != QLA_SUCCESS) { - DEBUG2_3_11(printk("qla2x00_abort_target(%ld): failed=%x.\n", + DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, ha->host_no, rval)); + } + + /* Issue marker IOCB. */ + rval2 = qla2x00_marker(ha, fcport->loop_id, l, MK_SYNC_ID_LUN); + if (rval2 != QLA_SUCCESS) { + DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " + "(%x).\n", __func__, ha->host_no, rval2)); } else { - /*EMPTY*/ - DEBUG11(printk("qla2x00_abort_target(%ld): done.\n", - ha->host_no)); + DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); } return rval; @@ -2186,17 +2215,15 @@ struct tsk_mgmt_cmd { } p; }; -int -qla24xx_abort_target(fc_port_t *fcport) +static int +__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport, + unsigned int l) { - int rval; + int rval, rval2; struct tsk_mgmt_cmd *tsk; dma_addr_t tsk_dma; scsi_qla_host_t *ha, *pha; - if (fcport == NULL) - return 0; - DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); ha = fcport->ha; @@ -2213,47 +2240,61 @@ qla24xx_abort_target(fc_port_t *fcport) tsk->p.tsk.entry_count = 1; tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id); tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); - tsk->p.tsk.control_flags = __constant_cpu_to_le32(TCF_TARGET_RESET); + tsk->p.tsk.control_flags = cpu_to_le32(type); tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa; tsk->p.tsk.port_id[1] = fcport->d_id.b.area; tsk->p.tsk.port_id[2] = fcport->d_id.b.domain; tsk->p.tsk.vp_index = fcport->vp_idx; + if (type == TCF_LUN_RESET) { + int_to_scsilun(l, &tsk->p.tsk.lun); + host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun, + sizeof(tsk->p.tsk.lun)); + } rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0); if (rval != QLA_SUCCESS) { - DEBUG2_3_11(printk("%s(%ld): failed to issue Target Reset IOCB " - "(%x).\n", __func__, ha->host_no, rval)); - goto atarget_done; + DEBUG2_3_11(printk("%s(%ld): failed to issue %s Reset IOCB " + "(%x).\n", __func__, ha->host_no, name, rval)); } else if (tsk->p.sts.entry_status != 0) { DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " "-- error status (%x).\n", __func__, ha->host_no, tsk->p.sts.entry_status)); rval = QLA_FUNCTION_FAILED; - goto atarget_done; } else if (tsk->p.sts.comp_status != __constant_cpu_to_le16(CS_COMPLETE)) { DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " "-- completion status (%x).\n", __func__, ha->host_no, le16_to_cpu(tsk->p.sts.comp_status))); rval = QLA_FUNCTION_FAILED; - goto atarget_done; } /* Issue marker IOCB. */ - rval = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID); - if (rval != QLA_SUCCESS) { + rval2 = qla2x00_marker(ha, fcport->loop_id, l, + type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID); + if (rval2 != QLA_SUCCESS) { DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " - "(%x).\n", __func__, ha->host_no, rval)); + "(%x).\n", __func__, ha->host_no, rval2)); } else { DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); } -atarget_done: dma_pool_free(pha->s_dma_pool, tsk, tsk_dma); return rval; } +int +qla24xx_abort_target(struct fc_port *fcport, unsigned int l) +{ + return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l); +} + +int +qla24xx_lun_reset(struct fc_port *fcport, unsigned int l) +{ + return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l); +} + #if 0 int diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index ba7d2ca3a0e8..5cddc503bd2b 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -100,6 +100,7 @@ static int qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *)); static int qla2xxx_eh_abort(struct scsi_cmnd *); static int qla2xxx_eh_device_reset(struct scsi_cmnd *); +static int qla2xxx_eh_target_reset(struct scsi_cmnd *); static int qla2xxx_eh_bus_reset(struct scsi_cmnd *); static int qla2xxx_eh_host_reset(struct scsi_cmnd *); @@ -113,6 +114,7 @@ static struct scsi_host_template qla2x00_driver_template = { .eh_abort_handler = qla2xxx_eh_abort, .eh_device_reset_handler = qla2xxx_eh_device_reset, + .eh_target_reset_handler = qla2xxx_eh_target_reset, .eh_bus_reset_handler = qla2xxx_eh_bus_reset, .eh_host_reset_handler = qla2xxx_eh_host_reset, @@ -144,6 +146,7 @@ struct scsi_host_template qla24xx_driver_template = { .eh_abort_handler = qla2xxx_eh_abort, .eh_device_reset_handler = qla2xxx_eh_device_reset, + .eh_target_reset_handler = qla2xxx_eh_target_reset, .eh_bus_reset_handler = qla2xxx_eh_bus_reset, .eh_host_reset_handler = qla2xxx_eh_host_reset, @@ -566,8 +569,6 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *ha) else return_status = QLA_FUNCTION_FAILED; - DEBUG2(printk("%s return_status=%d\n",__func__,return_status)); - return (return_status); } @@ -714,181 +715,122 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) return ret; } -/************************************************************************** -* qla2x00_eh_wait_for_pending_target_commands -* -* Description: -* Waits for all the commands to come back from the specified target. -* -* Input: -* ha - pointer to scsi_qla_host structure. -* t - target -* Returns: -* Either SUCCESS or FAILED. -* -* Note: -**************************************************************************/ +enum nexus_wait_type { + WAIT_HOST = 0, + WAIT_TARGET, + WAIT_LUN, +}; + static int -qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) +qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha, unsigned int t, + unsigned int l, enum nexus_wait_type type) { - int cnt; - int status; - srb_t *sp; - struct scsi_cmnd *cmd; + int cnt, match, status; + srb_t *sp; unsigned long flags; scsi_qla_host_t *pha = to_qla_parent(ha); - status = 0; - - /* - * Waiting for all commands for the designated target in the active - * array - */ - for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { - spin_lock_irqsave(&pha->hardware_lock, flags); + status = QLA_SUCCESS; + spin_lock_irqsave(&pha->hardware_lock, flags); + for (cnt = 1; status == QLA_SUCCESS && cnt < MAX_OUTSTANDING_COMMANDS; + cnt++) { sp = pha->outstanding_cmds[cnt]; - if (sp) { - cmd = sp->cmd; - spin_unlock_irqrestore(&pha->hardware_lock, flags); - if (cmd->device->id == t && - ha->vp_idx == sp->ha->vp_idx) { - if (!qla2x00_eh_wait_on_command(ha, cmd)) { - status = 1; - break; - } - } - } else { - spin_unlock_irqrestore(&pha->hardware_lock, flags); + if (!sp) + continue; + if (ha->vp_idx != sp->ha->vp_idx) + continue; + match = 0; + switch (type) { + case WAIT_HOST: + match = 1; + break; + case WAIT_TARGET: + match = sp->cmd->device->id == t; + break; + case WAIT_LUN: + match = (sp->cmd->device->id == t && + sp->cmd->device->lun == l); + break; } + if (!match) + continue; + + spin_unlock_irqrestore(&pha->hardware_lock, flags); + status = qla2x00_eh_wait_on_command(ha, sp->cmd); + spin_lock_irqsave(&pha->hardware_lock, flags); } - return (status); + spin_unlock_irqrestore(&pha->hardware_lock, flags); + + return status; } +static char *reset_errors[] = { + "HBA not online", + "HBA not ready", + "Task management failed", + "Waiting for command completions", +}; -/************************************************************************** -* qla2xxx_eh_device_reset -* -* Description: -* The device reset function will reset the target and abort any -* executing commands. -* -* NOTE: The use of SP is undefined within this context. Do *NOT* -* attempt to use this value, even if you determine it is -* non-null. -* -* Input: -* cmd = Linux SCSI command packet of the command that cause the -* bus device reset. -* -* Returns: -* SUCCESS/FAILURE (defined as macro in scsi.h). -* -**************************************************************************/ static int -qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) +__qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type, + struct scsi_cmnd *cmd, int (*do_reset)(struct fc_port *, unsigned int)) { scsi_qla_host_t *ha = shost_priv(cmd->device->host); fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; - int ret = FAILED; - unsigned int id, lun; - unsigned long serial; + int err; qla2x00_block_error_handler(cmd); - id = cmd->device->id; - lun = cmd->device->lun; - serial = cmd->serial_number; - if (!fcport) - return ret; + return FAILED; - qla_printk(KERN_INFO, ha, - "scsi(%ld:%d:%d): DEVICE RESET ISSUED.\n", ha->host_no, id, lun); + qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET ISSUED.\n", + ha->host_no, cmd->device->id, cmd->device->lun, name); + err = 0; if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) - goto eh_dev_reset_done; - - if (qla2x00_wait_for_loop_ready(ha) == QLA_SUCCESS) { - if (ha->isp_ops->abort_target(fcport) == 0) - ret = SUCCESS; - } else { - DEBUG2(printk(KERN_INFO - "%s failed: loop not ready\n",__func__)); - } - - if (ret == FAILED) { - DEBUG3(printk("%s(%ld): device reset failed\n", - __func__, ha->host_no)); - qla_printk(KERN_INFO, ha, "%s: device reset failed\n", - __func__); + goto eh_reset_failed; + err = 1; + if (qla2x00_wait_for_loop_ready(ha) != QLA_SUCCESS) + goto eh_reset_failed; + err = 2; + if (do_reset(fcport, cmd->device->lun) != QLA_SUCCESS) + goto eh_reset_failed; + err = 3; + if (qla2x00_eh_wait_for_pending_commands(ha, cmd->device->id, + cmd->device->lun, type) != QLA_SUCCESS) + goto eh_reset_failed; + + qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET SUCCEEDED.\n", + ha->host_no, cmd->device->id, cmd->device->lun, name); + + return SUCCESS; + + eh_reset_failed: + qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET FAILED: %s.\n", + ha->host_no, cmd->device->id, cmd->device->lun, name, + reset_errors[err]); + return FAILED; +} - goto eh_dev_reset_done; - } +static int +qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) +{ + scsi_qla_host_t *ha = shost_priv(cmd->device->host); - /* Flush outstanding commands. */ - if (qla2x00_eh_wait_for_pending_target_commands(ha, id)) - ret = FAILED; - if (ret == FAILED) { - DEBUG3(printk("%s(%ld): failed while waiting for commands\n", - __func__, ha->host_no)); - qla_printk(KERN_INFO, ha, - "%s: failed while waiting for commands\n", __func__); - } else - qla_printk(KERN_INFO, ha, - "scsi(%ld:%d:%d): DEVICE RESET SUCCEEDED.\n", ha->host_no, - id, lun); - eh_dev_reset_done: - return ret; + return __qla2xxx_eh_generic_reset("DEVICE", WAIT_LUN, cmd, + ha->isp_ops->lun_reset); } -/************************************************************************** -* qla2x00_eh_wait_for_pending_commands -* -* Description: -* Waits for all the commands to come back from the specified host. -* -* Input: -* ha - pointer to scsi_qla_host structure. -* -* Returns: -* 1 : SUCCESS -* 0 : FAILED -* -* Note: -**************************************************************************/ static int -qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha) +qla2xxx_eh_target_reset(struct scsi_cmnd *cmd) { - int cnt; - int status; - srb_t *sp; - struct scsi_cmnd *cmd; - unsigned long flags; - - status = 1; + scsi_qla_host_t *ha = shost_priv(cmd->device->host); - /* - * Waiting for all commands for the designated target in the active - * array - */ - for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { - spin_lock_irqsave(&ha->hardware_lock, flags); - sp = ha->outstanding_cmds[cnt]; - if (sp) { - cmd = sp->cmd; - spin_unlock_irqrestore(&ha->hardware_lock, flags); - status = qla2x00_eh_wait_on_command(ha, cmd); - if (status == 0) - break; - } - else { - spin_unlock_irqrestore(&ha->hardware_lock, flags); - } - } - return (status); + return __qla2xxx_eh_generic_reset("TARGET", WAIT_TARGET, cmd, + ha->isp_ops->target_reset); } - /************************************************************************** * qla2xxx_eh_bus_reset * @@ -939,7 +881,8 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) goto eh_bus_reset_done; /* Flush outstanding commands. */ - if (!qla2x00_eh_wait_for_pending_commands(pha)) + if (qla2x00_eh_wait_for_pending_commands(pha, 0, 0, WAIT_HOST) != + QLA_SUCCESS) ret = FAILED; eh_bus_reset_done: @@ -1010,7 +953,8 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) clear_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags); /* Waiting for our command in done_queue to be returned to OS.*/ - if (qla2x00_eh_wait_for_pending_commands(pha)) + if (qla2x00_eh_wait_for_pending_commands(pha, 0, 0, WAIT_HOST) == + QLA_SUCCESS) ret = SUCCESS; if (ha->parent) @@ -1066,7 +1010,7 @@ qla2x00_loop_reset(scsi_qla_host_t *ha) if (fcport->port_type != FCT_TARGET) continue; - ret = ha->isp_ops->abort_target(fcport); + ret = ha->isp_ops->target_reset(fcport, 0); if (ret != QLA_SUCCESS) { DEBUG2_3(printk("%s(%ld): bus_reset failed: " "target_reset=%d d_id=%x.\n", __func__, @@ -1258,7 +1202,8 @@ static struct isp_operations qla2100_isp_ops = { .enable_intrs = qla2x00_enable_intrs, .disable_intrs = qla2x00_disable_intrs, .abort_command = qla2x00_abort_command, - .abort_target = qla2x00_abort_target, + .target_reset = qla2x00_abort_target, + .lun_reset = qla2x00_lun_reset, .fabric_login = qla2x00_login_fabric, .fabric_logout = qla2x00_fabric_logout, .calc_req_entries = qla2x00_calc_iocbs_32, @@ -1291,7 +1236,8 @@ static struct isp_operations qla2300_isp_ops = { .enable_intrs = qla2x00_enable_intrs, .disable_intrs = qla2x00_disable_intrs, .abort_command = qla2x00_abort_command, - .abort_target = qla2x00_abort_target, + .target_reset = qla2x00_abort_target, + .lun_reset = qla2x00_lun_reset, .fabric_login = qla2x00_login_fabric, .fabric_logout = qla2x00_fabric_logout, .calc_req_entries = qla2x00_calc_iocbs_32, @@ -1324,7 +1270,8 @@ static struct isp_operations qla24xx_isp_ops = { .enable_intrs = qla24xx_enable_intrs, .disable_intrs = qla24xx_disable_intrs, .abort_command = qla24xx_abort_command, - .abort_target = qla24xx_abort_target, + .target_reset = qla24xx_abort_target, + .lun_reset = qla24xx_lun_reset, .fabric_login = qla24xx_login_fabric, .fabric_logout = qla24xx_fabric_logout, .calc_req_entries = NULL, @@ -1357,7 +1304,8 @@ static struct isp_operations qla25xx_isp_ops = { .enable_intrs = qla24xx_enable_intrs, .disable_intrs = qla24xx_disable_intrs, .abort_command = qla24xx_abort_command, - .abort_target = qla24xx_abort_target, + .target_reset = qla24xx_abort_target, + .lun_reset = qla24xx_lun_reset, .fabric_login = qla24xx_login_fabric, .fabric_logout = qla24xx_fabric_logout, .calc_req_entries = NULL, -- cgit v1.2.3 From b93480e319654b8921364b49528532dff4822a45 Mon Sep 17 00:00:00 2001 From: Ravi Anand Date: Thu, 3 Apr 2008 13:13:25 -0700 Subject: [SCSI] qla2xxx: Assign mailbox command timeout values in a consistent manner. Signed-off-by: Ravi Anand Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_mbx.c | 62 +++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 31 deletions(-) (limited to 'drivers/scsi/qla2xxx') diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index c1af56dec4d4..beff743c536b 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -310,7 +310,7 @@ qla2x00_load_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t risc_addr, } mcp->in_mb = MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -367,7 +367,7 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr) } } - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -417,7 +417,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *ha, uint16_t *major, uint16_t *minor, mcp->out_mb = MBX_0; mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; mcp->flags = 0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; rval = qla2x00_mailbox_command(ha, mcp); /* Return mailbox data. */ @@ -466,7 +466,7 @@ qla2x00_get_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts) mcp->mb[0] = MBC_GET_FIRMWARE_OPTION; mcp->out_mb = MBX_0; mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -524,7 +524,7 @@ qla2x00_set_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts) mcp->mb[12] = 0; /* Undocumented, but used */ mcp->out_mb |= MBX_12|MBX_11|MBX_10; } - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -576,7 +576,7 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *ha) mcp->mb[7] = 0x2525; mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -648,7 +648,7 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr) mcp->in_mb |= MBX_1; } - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -697,7 +697,7 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, mcp->mb[7] = LSW(MSD(phys_addr)); mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_2|MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -768,7 +768,7 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp) mcp->mb[6] = (uint16_t)sp->cmd->device->lun; mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -809,7 +809,7 @@ qla2x00_abort_target(struct fc_port *fcport, unsigned int l) mcp->mb[9] = ha->vp_idx; mcp->in_mb = MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); if (rval != QLA_SUCCESS) { @@ -851,7 +851,7 @@ qla2x00_lun_reset(struct fc_port *fcport, unsigned int l) mcp->mb[9] = ha->vp_idx; mcp->in_mb = MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); if (rval != QLA_SUCCESS) { @@ -906,7 +906,7 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa, mcp->mb[9] = ha->vp_idx; mcp->out_mb = MBX_9|MBX_0; mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); if (mcp->mb[0] == MBS_COMMAND_ERROR) @@ -963,7 +963,7 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *ha, uint8_t *retry_cnt, uint8_t *tov, mcp->mb[0] = MBC_GET_RETRY_COUNT; mcp->out_mb = MBX_0; mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -1030,7 +1030,7 @@ qla2x00_init_firmware(scsi_qla_host_t *ha, uint16_t size) mcp->in_mb = MBX_5|MBX_4|MBX_0; mcp->buf_size = size; mcp->flags = MBX_DMA_OUT; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; rval = qla2x00_mailbox_command(ha, mcp); if (rval != QLA_SUCCESS) { @@ -1220,7 +1220,7 @@ qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr) mcp->mb[0] = MBC_GET_FIRMWARE_STATE; mcp->out_mb = MBX_0; mcp->in_mb = MBX_2|MBX_1|MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -1281,7 +1281,7 @@ qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name, } mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -1353,7 +1353,7 @@ qla2x00_lip_reset(scsi_qla_host_t *ha) mcp->mb[3] = 0; } mcp->in_mb = MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -1778,7 +1778,7 @@ qla2x00_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, } mcp->in_mb = MBX_1|MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -1826,7 +1826,7 @@ qla2x00_full_login_lip(scsi_qla_host_t *ha) mcp->mb[3] = 0; mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -1887,7 +1887,7 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma, mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1; } mcp->in_mb = MBX_1|MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -1931,7 +1931,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt, mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; mcp->out_mb = MBX_0; mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -2071,7 +2071,7 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id, mcp->mb[1] = loop_id << 8; mcp->out_mb |= MBX_1; } - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = IOCTL_CMD; rval = qla2x00_mailbox_command(ha, mcp); @@ -2117,7 +2117,7 @@ qla24xx_get_isp_stats(scsi_qla_host_t *ha, struct link_statistics *stats, mcp->mb[10] = 0; mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; mcp->in_mb = MBX_2|MBX_1|MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = IOCTL_CMD; rval = qla2x00_mailbox_command(ha, mcp); @@ -2351,7 +2351,7 @@ qla2x00_set_serdes_params(scsi_qla_host_t *ha, uint16_t sw_em_1g, mcp->mb[4] = sw_em_4g | BIT_15; mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -2419,7 +2419,7 @@ qla2x00_enable_eft_trace(scsi_qla_host_t *ha, dma_addr_t eft_dma, mcp->mb[7] = TC_AEN_DISABLE; mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_1|MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); if (rval != QLA_SUCCESS) { @@ -2448,7 +2448,7 @@ qla2x00_disable_eft_trace(scsi_qla_host_t *ha) mcp->mb[1] = TC_EFT_DISABLE; mcp->out_mb = MBX_1|MBX_0; mcp->in_mb = MBX_1|MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); if (rval != QLA_SUCCESS) { @@ -2488,7 +2488,7 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *ha, dma_addr_t fce_dma, mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2| MBX_1|MBX_0; mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); if (rval != QLA_SUCCESS) { @@ -2524,7 +2524,7 @@ qla2x00_disable_fce_trace(scsi_qla_host_t *ha, uint64_t *wr, uint64_t *rd) mcp->out_mb = MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2| MBX_1|MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); if (rval != QLA_SUCCESS) { @@ -2572,7 +2572,7 @@ qla2x00_read_sfp(scsi_qla_host_t *ha, dma_addr_t sfp_dma, uint16_t addr, mcp->mb[10] = 0; mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -2606,7 +2606,7 @@ qla2x00_set_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id, mcp->mb[4] = mcp->mb[5] = 0; mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -2924,7 +2924,7 @@ qla2x00_dump_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t addr, } mcp->in_mb = MBX_0; - mcp->tov = 30; + mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); -- cgit v1.2.3 From 4d4df1932b6b116aecc81039066fec27f2050762 Mon Sep 17 00:00:00 2001 From: Harihara Kadayam Date: Thu, 3 Apr 2008 13:13:26 -0700 Subject: [SCSI] qla2xxx: Add ISP84XX support. Signed-off-by: Ravi Anand Additional cleanups and Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_attr.c | 2 +- drivers/scsi/qla2xxx/qla_dbg.h | 8 +++ drivers/scsi/qla2xxx/qla_def.h | 26 ++++++++- drivers/scsi/qla2xxx/qla_fw.h | 123 +++++++++++++++++++++++++++++++++++++++ drivers/scsi/qla2xxx/qla_gbl.h | 8 +++ drivers/scsi/qla2xxx/qla_gs.c | 2 +- drivers/scsi/qla2xxx/qla_init.c | 119 +++++++++++++++++++++++++++++++++++--- drivers/scsi/qla2xxx/qla_isr.c | 48 +++++++++++++-- drivers/scsi/qla2xxx/qla_mbx.c | 125 +++++++++++++++++++++++++++++++++++++--- drivers/scsi/qla2xxx/qla_os.c | 17 +++++- drivers/scsi/qla2xxx/qla_sup.c | 2 +- 11 files changed, 454 insertions(+), 26 deletions(-) (limited to 'drivers/scsi/qla2xxx') diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 798cc613c44a..413d8cd6a324 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -1291,7 +1291,7 @@ qla2x00_init_host_attr(scsi_qla_host_t *ha) if (IS_QLA25XX(ha)) speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; - else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) + else if (IS_QLA24XX_TYPE(ha)) speed = FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; else if (IS_QLA23XX(ha)) diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index 2a4043b5b145..2e9c0c097f5e 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h @@ -22,6 +22,7 @@ /* #define QL_DEBUG_LEVEL_13 */ /* Output fdmi function trace msgs */ /* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */ /* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */ +/* #define QL_DEBUG_LEVEL_16 */ /* Output ISP84XX trace msgs */ /* * Macros use for debugging the driver. @@ -41,6 +42,7 @@ #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) @@ -120,6 +122,12 @@ #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 */ diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index f7919d348ccd..b2f07649bd3d 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -2142,6 +2143,21 @@ struct qla_work_evt { } 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; +}; + /* * Linux Host Adapter structure */ @@ -2230,6 +2246,7 @@ typedef struct scsi_qla_host { #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 @@ -2243,7 +2260,8 @@ typedef struct scsi_qla_host { #define DT_ISP5422 BIT_9 #define DT_ISP5432 BIT_10 #define DT_ISP2532 BIT_11 -#define DT_ISP_LAST (DT_ISP2532 << 1) +#define DT_ISP8432 BIT_12 +#define DT_ISP_LAST (DT_ISP8432 << 1) #define DT_IIDMA BIT_26 #define DT_FWI2 BIT_27 @@ -2265,12 +2283,16 @@ typedef struct scsi_qla_host { #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) @@ -2575,6 +2597,8 @@ typedef struct scsi_qla_host { #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; diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index c6a5e49a25be..078f2a15f40b 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -1218,4 +1218,127 @@ struct qla_fdt_layout { 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 diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index f2133647bf25..a9571c214a9e 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -47,6 +47,8 @@ extern void qla2x00_update_fcport(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. */ @@ -149,6 +151,10 @@ qla2x00_verify_checksum(scsi_qla_host_t *, uint32_t); extern int qla2x00_issue_iocb(scsi_qla_host_t *, void *, dma_addr_t, size_t); +extern int +qla2x00_issue_iocb_timeout(scsi_qla_host_t *, void *, dma_addr_t, size_t, + uint32_t); + extern int qla2x00_abort_command(scsi_qla_host_t *, srb_t *); @@ -249,6 +255,8 @@ 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. */ diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 980ccb3eed33..750d7ef83aae 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -1532,7 +1532,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *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(ha) || IS_QLA54XX(ha)) + 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); diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 10e6995b39a7..916462ef1966 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -37,6 +37,9 @@ static int qla2x00_restart_isp(scsi_qla_host_t *); static int qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev); +static struct qla_chip_state_84xx *qla84xx_get_chip(struct scsi_qla_host *); +static int qla84xx_init_chip(scsi_qla_host_t *); + /****************************************************************************/ /* QLogic ISP2x00 Hardware Support Functions. */ /****************************************************************************/ @@ -108,6 +111,14 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) return (rval); qla2xxx_get_flash_info(ha); } + if (IS_QLA84XX(ha)) { + ha->cs84xx = qla84xx_get_chip(ha); + if (!ha->cs84xx) { + qla_printk(KERN_ERR, ha, + "Unable to configure ISP84XX.\n"); + return QLA_FUNCTION_FAILED; + } + } rval = qla2x00_init_rings(ha); return (rval); @@ -1243,10 +1254,10 @@ static int qla2x00_fw_ready(scsi_qla_host_t *ha) { int rval; - unsigned long wtime, mtime; + unsigned long wtime, mtime, cs84xx_time; uint16_t min_wait; /* Minimum wait time if loop is down */ uint16_t wait_time; /* Wait time if loop is coming ready */ - uint16_t fw_state; + uint16_t state[3]; rval = QLA_SUCCESS; @@ -1275,12 +1286,34 @@ qla2x00_fw_ready(scsi_qla_host_t *ha) ha->host_no)); do { - rval = qla2x00_get_firmware_state(ha, &fw_state); + rval = qla2x00_get_firmware_state(ha, state); if (rval == QLA_SUCCESS) { - if (fw_state < FSTATE_LOSS_OF_SYNC) { + if (state[0] < FSTATE_LOSS_OF_SYNC) { ha->device_flags &= ~DFLG_NO_CABLE; } - if (fw_state == FSTATE_READY) { + if (IS_QLA84XX(ha) && state[0] != FSTATE_READY) { + DEBUG16(printk("scsi(%ld): fw_state=%x " + "84xx=%x.\n", ha->host_no, state[0], + state[2])); + if ((state[2] & FSTATE_LOGGED_IN) && + (state[2] & FSTATE_WAITING_FOR_VERIFY)) { + DEBUG16(printk("scsi(%ld): Sending " + "verify iocb.\n", ha->host_no)); + + cs84xx_time = jiffies; + rval = qla84xx_init_chip(ha); + if (rval != QLA_SUCCESS) + break; + + /* Add time taken to initialize. */ + cs84xx_time = jiffies - cs84xx_time; + wtime += cs84xx_time; + mtime += cs84xx_time; + DEBUG16(printk("scsi(%ld): Increasing " + "wait time by %ld. New time %ld\n", + ha->host_no, cs84xx_time, wtime)); + } + } else if (state[0] == FSTATE_READY) { DEBUG(printk("scsi(%ld): F/W Ready - OK \n", ha->host_no)); @@ -1294,7 +1327,7 @@ qla2x00_fw_ready(scsi_qla_host_t *ha) rval = QLA_FUNCTION_FAILED; if (atomic_read(&ha->loop_down_timer) && - fw_state != FSTATE_READY) { + state[0] != FSTATE_READY) { /* Loop down. Timeout on min_wait for states * other than Wait for Login. */ @@ -1319,11 +1352,11 @@ qla2x00_fw_ready(scsi_qla_host_t *ha) msleep(500); DEBUG3(printk("scsi(%ld): fw_state=%x curr time=%lx.\n", - ha->host_no, fw_state, jiffies)); + ha->host_no, state[0], jiffies)); } while (1); DEBUG(printk("scsi(%ld): fw_state=%x curr time=%lx.\n", - ha->host_no, fw_state, jiffies)); + ha->host_no, state[0], jiffies)); if (rval) { DEBUG2_3(printk("scsi(%ld): Firmware ready **** FAILED ****.\n", @@ -4038,3 +4071,73 @@ qla24xx_configure_vhba(scsi_qla_host_t *ha) return rval; } + +/* 84XX Support **************************************************************/ + +static LIST_HEAD(qla_cs84xx_list); +static DEFINE_MUTEX(qla_cs84xx_mutex); + +static struct qla_chip_state_84xx * +qla84xx_get_chip(struct scsi_qla_host *ha) +{ + struct qla_chip_state_84xx *cs84xx; + + mutex_lock(&qla_cs84xx_mutex); + + /* Find any shared 84xx chip. */ + list_for_each_entry(cs84xx, &qla_cs84xx_list, list) { + if (cs84xx->bus == ha->pdev->bus) { + kref_get(&cs84xx->kref); + goto done; + } + } + + cs84xx = kzalloc(sizeof(*cs84xx), GFP_KERNEL); + if (!cs84xx) + goto done; + + kref_init(&cs84xx->kref); + spin_lock_init(&cs84xx->access_lock); + mutex_init(&cs84xx->fw_update_mutex); + cs84xx->bus = ha->pdev->bus; + + list_add_tail(&cs84xx->list, &qla_cs84xx_list); +done: + mutex_unlock(&qla_cs84xx_mutex); + return cs84xx; +} + +static void +__qla84xx_chip_release(struct kref *kref) +{ + struct qla_chip_state_84xx *cs84xx = + container_of(kref, struct qla_chip_state_84xx, kref); + + mutex_lock(&qla_cs84xx_mutex); + list_del(&cs84xx->list); + mutex_unlock(&qla_cs84xx_mutex); + kfree(cs84xx); +} + +void +qla84xx_put_chip(struct scsi_qla_host *ha) +{ + if (ha->cs84xx) + kref_put(&ha->cs84xx->kref, __qla84xx_chip_release); +} + +static int +qla84xx_init_chip(scsi_qla_host_t *ha) +{ + int rval; + uint16_t status[2]; + + mutex_lock(&ha->cs84xx->fw_update_mutex); + + rval = qla84xx_verify_chip(ha, status); + + mutex_unlock(&ha->cs84xx->fw_update_mutex); + + return rval != QLA_SUCCESS || status[0] ? QLA_FUNCTION_FAILED: + QLA_SUCCESS; +} diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index e88600082c01..360af4e09d12 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -271,6 +271,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; uint32_t rscn_entry, host_pid; uint8_t rscn_queue_index; + unsigned long flags; /* Setup to process RIO completion. */ handle_cnt = 0; @@ -432,9 +433,10 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) break; case MBA_LOOP_DOWN: /* Loop Down Event */ - DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN (%x).\n", - ha->host_no, mb[1])); - qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x).\n", mb[1]); + DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN " + "(%x %x %x).\n", ha->host_no, mb[1], mb[2], mb[3])); + qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x %x %x).\n", + mb[1], mb[2], mb[3]); if (atomic_read(&ha->loop_state) != LOOP_DOWN) { atomic_set(&ha->loop_state, LOOP_DOWN); @@ -640,6 +642,42 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) DEBUG2(printk("scsi(%ld): Trace Notification -- %04x %04x.\n", ha->host_no, mb[1], mb[2])); break; + + case MBA_ISP84XX_ALERT: + DEBUG2(printk("scsi(%ld): ISP84XX Alert Notification -- " + "%04x %04x %04x\n", ha->host_no, mb[1], mb[2], mb[3])); + + spin_lock_irqsave(&ha->cs84xx->access_lock, flags); + switch (mb[1]) { + case A84_PANIC_RECOVERY: + qla_printk(KERN_INFO, ha, "Alert 84XX: panic recovery " + "%04x %04x\n", mb[2], mb[3]); + break; + case A84_OP_LOGIN_COMPLETE: + ha->cs84xx->op_fw_version = mb[3] << 16 | mb[2]; + DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX:" + "firmware version %x\n", ha->cs84xx->op_fw_version)); + break; + case A84_DIAG_LOGIN_COMPLETE: + ha->cs84xx->diag_fw_version = mb[3] << 16 | mb[2]; + DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX:" + "diagnostic firmware version %x\n", + ha->cs84xx->diag_fw_version)); + break; + case A84_GOLD_LOGIN_COMPLETE: + ha->cs84xx->diag_fw_version = mb[3] << 16 | mb[2]; + ha->cs84xx->fw_update = 1; + DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX: gold " + "firmware version %x\n", + ha->cs84xx->gold_fw_version)); + break; + default: + qla_printk(KERN_ERR, ha, + "Alert 84xx: Invalid Alert %04x %04x %04x\n", + mb[1], mb[2], mb[3]); + } + spin_unlock_irqrestore(&ha->cs84xx->access_lock, flags); + break; } if (!ha->parent && ha->num_vhosts) @@ -1747,7 +1785,7 @@ qla2x00_request_irqs(scsi_qla_host_t *ha) device_reg_t __iomem *reg = ha->iobase; /* If possible, enable MSI-X. */ - if (!IS_QLA2432(ha) && !IS_QLA2532(ha)) + if (!IS_QLA2432(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha)) goto skip_msix; if (IS_QLA2432(ha) && (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX || @@ -1782,7 +1820,7 @@ qla2x00_request_irqs(scsi_qla_host_t *ha) "MSI-X: Falling back-to INTa mode -- %d.\n", ret); skip_msix: - if (!IS_QLA24XX(ha) && !IS_QLA2532(ha)) + if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha)) goto skip_msi; ret = pci_enable_msi(ha->pdev); diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index beff743c536b..7d0a8a4c7719 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -682,8 +682,8 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr) * Kernel context. */ int -qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, - size_t size) +qla2x00_issue_iocb_timeout(scsi_qla_host_t *ha, void *buffer, + dma_addr_t phys_addr, size_t size, uint32_t tov) { int rval; mbx_cmd_t mc; @@ -697,7 +697,7 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, mcp->mb[7] = LSW(MSD(phys_addr)); mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_2|MBX_0; - mcp->tov = MBX_TOV_SECONDS; + mcp->tov = tov; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -718,6 +718,14 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, return rval; } +int +qla2x00_issue_iocb(scsi_qla_host_t *ha, void *buffer, dma_addr_t phys_addr, + size_t size) +{ + return qla2x00_issue_iocb_timeout(ha, buffer, phys_addr, size, + MBX_TOV_SECONDS); +} + /* * qla2x00_abort_command * Abort command aborts a specified IOCB. @@ -1208,7 +1216,7 @@ gpd_error_out: * Kernel context. */ int -qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr) +qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *states) { int rval; mbx_cmd_t mc; @@ -1219,13 +1227,15 @@ qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr) mcp->mb[0] = MBC_GET_FIRMWARE_STATE; mcp->out_mb = MBX_0; - mcp->in_mb = MBX_2|MBX_1|MBX_0; + mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); - /* Return firmware state. */ - *dptr = mcp->mb[1]; + /* Return firmware states. */ + states[0] = mcp->mb[1]; + states[1] = mcp->mb[2]; + states[2] = mcp->mb[3]; if (rval != QLA_SUCCESS) { /*EMPTY*/ @@ -2937,3 +2947,104 @@ qla2x00_dump_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t addr, return rval; } + +/* 84XX Support **************************************************************/ + +struct cs84xx_mgmt_cmd { + union { + struct verify_chip_entry_84xx req; + struct verify_chip_rsp_84xx rsp; + } p; +}; + +int +qla84xx_verify_chip(struct scsi_qla_host *ha, uint16_t *status) +{ + int rval, retry; + struct cs84xx_mgmt_cmd *mn; + dma_addr_t mn_dma; + uint16_t options; + unsigned long flags; + + DEBUG16(printk("%s(%ld): entered.\n", __func__, ha->host_no)); + + mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma); + if (mn == NULL) { + DEBUG2_3(printk("%s(%ld): failed to allocate Verify ISP84XX " + "IOCB.\n", __func__, ha->host_no)); + return QLA_MEMORY_ALLOC_FAILED; + } + + /* Force Update? */ + options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0; + /* Diagnostic firmware? */ + /* options |= MENLO_DIAG_FW; */ + /* We update the firmware with only one data sequence. */ + options |= VCO_END_OF_DATA; + + retry = 0; + do { + memset(mn, 0, sizeof(*mn)); + mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE; + mn->p.req.entry_count = 1; + mn->p.req.options = cpu_to_le16(options); + + DEBUG16(printk("%s(%ld): Dump of Verify Request.\n", __func__, + ha->host_no)); + DEBUG16(qla2x00_dump_buffer((uint8_t *)mn, + sizeof(*mn))); + + rval = qla2x00_issue_iocb_timeout(ha, mn, mn_dma, 0, 120); + if (rval != QLA_SUCCESS) { + DEBUG2_16(printk("%s(%ld): failed to issue Verify " + "IOCB (%x).\n", __func__, ha->host_no, rval)); + goto verify_done; + } + + DEBUG16(printk("%s(%ld): Dump of Verify Response.\n", __func__, + ha->host_no)); + DEBUG16(qla2x00_dump_buffer((uint8_t *)mn, + sizeof(*mn))); + + status[0] = le16_to_cpu(mn->p.rsp.comp_status); + status[1] = status[0] == CS_VCS_CHIP_FAILURE ? + le16_to_cpu(mn->p.rsp.failure_code) : 0; + DEBUG2_16(printk("%s(%ld): cs=%x fc=%x\n", __func__, + ha->host_no, status[0], status[1])); + + if (status[0] != CS_COMPLETE) { + rval = QLA_FUNCTION_FAILED; + if (!(options & VCO_DONT_UPDATE_FW)) { + DEBUG2_16(printk("%s(%ld): Firmware update " + "failed. Retrying without update " + "firmware.\n", __func__, ha->host_no)); + options |= VCO_DONT_UPDATE_FW; + options &= ~VCO_FORCE_UPDATE; + retry = 1; + } + } else { + DEBUG2_16(printk("%s(%ld): firmware updated to %x.\n", + __func__, ha->host_no, + le32_to_cpu(mn->p.rsp.fw_ver))); + + /* NOTE: we only update OP firmware. */ + spin_lock_irqsave(&ha->cs84xx->access_lock, flags); + ha->cs84xx->op_fw_version = + le32_to_cpu(mn->p.rsp.fw_ver); + spin_unlock_irqrestore(&ha->cs84xx->access_lock, + flags); + } + } while (retry); + +verify_done: + dma_pool_free(ha->s_dma_pool, mn, mn_dma); + + if (rval != QLA_SUCCESS) { + DEBUG2_16(printk("%s(%ld): failed=%x.\n", __func__, + ha->host_no, rval)); + } else { + DEBUG16(printk("%s(%ld): done.\n", __func__, ha->host_no)); + } + + return rval; +} diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 5cddc503bd2b..4c50b9b53d23 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -339,6 +339,8 @@ qla24xx_fw_version_str(struct scsi_qla_host *ha, char *str) strcat(str, "[T10 CRC] "); if (ha->fw_attributes & BIT_5) strcat(str, "[VI] "); + if (ha->fw_attributes & BIT_10) + strcat(str, "[84XX] "); if (ha->fw_attributes & BIT_13) strcat(str, "[Experimental]"); return str; @@ -1378,6 +1380,13 @@ qla2x00_set_isp_flags(scsi_qla_host_t *ha) ha->device_type |= DT_IIDMA; ha->fw_srisc_address = RISC_START_ADDRESS_2400; break; + case PCI_DEVICE_ID_QLOGIC_ISP8432: + ha->device_type |= DT_ISP8432; + ha->device_type |= DT_ZIO_SUPPORTED; + ha->device_type |= DT_FWI2; + ha->device_type |= DT_IIDMA; + ha->fw_srisc_address = RISC_START_ADDRESS_2400; + break; case PCI_DEVICE_ID_QLOGIC_ISP5422: ha->device_type |= DT_ISP5422; ha->device_type |= DT_FWI2; @@ -1501,6 +1510,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) sht = &qla2x00_driver_template; if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 || + pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8432 || pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 || pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 || pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) { @@ -1591,7 +1601,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) if (IS_QLA2322(ha) || IS_QLA6322(ha)) ha->optrom_size = OPTROM_SIZE_2322; ha->isp_ops = &qla2300_isp_ops; - } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + } else if (IS_QLA24XX_TYPE(ha)) { host->max_id = MAX_TARGETS_2200; ha->mbx_count = MAILBOX_REGISTER_COUNT; ha->request_q_length = REQUEST_ENTRY_CNT_24XX; @@ -1736,6 +1746,8 @@ qla2x00_remove_one(struct pci_dev *pdev) qla2x00_dfs_remove(ha); + qla84xx_put_chip(ha); + qla2x00_free_sysfs_attr(ha); fc_remove_host(ha->host); @@ -2642,7 +2654,7 @@ qla2x00_request_firmware(scsi_qla_host_t *ha) blob = &qla_fw_blobs[FW_ISP2300]; } else if (IS_QLA2322(ha) || IS_QLA6322(ha)) { blob = &qla_fw_blobs[FW_ISP2322]; - } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + } else if (IS_QLA24XX_TYPE(ha)) { blob = &qla_fw_blobs[FW_ISP24XX]; } else if (IS_QLA25XX(ha)) { blob = &qla_fw_blobs[FW_ISP25XX]; @@ -2792,6 +2804,7 @@ static struct pci_device_id qla2xxx_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6322) }, { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2422) }, { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432) }, + { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8432) }, { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422) }, { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432) }, { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2532) }, diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index eda11f6f5e52..1728ab3ccb20 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -553,7 +553,7 @@ qla2xxx_get_flash_info(scsi_qla_host_t *ha) struct qla_fdt_layout *fdt; uint8_t man_id, flash_id; - if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha)) + if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha)) return; wptr = (uint16_t *)ha->request_ring; -- cgit v1.2.3 From 73f0f0f24ad898db8316d1c8bf877fbe7b60b015 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 3 Apr 2008 13:13:27 -0700 Subject: [SCSI] qla2xxx: Remove unused member (dma_handle) from srb_t structure. The member is not needed as there's no non-scatter-gather list I/Os submitted by the upper-layers. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_def.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/scsi/qla2xxx') diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index b2f07649bd3d..094d95f0764c 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -193,9 +193,6 @@ typedef struct srb { uint16_t flags; - /* Single transfer DMA context */ - dma_addr_t dma_handle; - uint32_t request_sense_length; uint8_t *request_sense_ptr; } srb_t; -- cgit v1.2.3 From d4486fd6deb3354aa39cfedfcfd114cfe9ff9238 Mon Sep 17 00:00:00 2001 From: Seokmann Ju Date: Thu, 3 Apr 2008 13:13:28 -0700 Subject: [SCSI] qla2xxx: Consistently access the physical HA port. There were several places where referencing ha structure of virtual ports for resources. Among those refereces, certain fields are get up-to-dated only on ha structure of physical port. Signed-off-by: Seokmann Ju Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_init.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers/scsi/qla2xxx') diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 916462ef1966..01e26087c1dd 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -2453,7 +2453,8 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) if (fcport->loop_id == FC_NO_LOOP_ID) { fcport->loop_id = next_loopid; - rval = qla2x00_find_new_loop_id(ha, fcport); + rval = qla2x00_find_new_loop_id( + to_qla_parent(ha), fcport); if (rval != QLA_SUCCESS) { /* Ran out of IDs to use */ break; @@ -2478,7 +2479,8 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) /* Find a new loop ID to use. */ fcport->loop_id = next_loopid; - rval = qla2x00_find_new_loop_id(ha, fcport); + rval = qla2x00_find_new_loop_id(to_qla_parent(ha), + fcport); if (rval != QLA_SUCCESS) { /* Ran out of IDs to use */ break; @@ -4044,16 +4046,16 @@ qla24xx_configure_vhba(scsi_qla_host_t *ha) if (!ha->parent) return -EINVAL; - rval = qla2x00_fw_ready(ha); + rval = qla2x00_fw_ready(ha->parent); if (rval == QLA_SUCCESS) { clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); - qla2x00_marker(ha, 0, 0, MK_SYNC_ALL); + qla2x00_marker(ha->parent, 0, 0, MK_SYNC_ALL); } ha->flags.management_server_logged_in = 0; /* Login to SNS first */ - qla24xx_login_fabric(ha, NPH_SNS, 0xff, 0xff, 0xfc, + qla24xx_login_fabric(ha->parent, NPH_SNS, 0xff, 0xff, 0xfc, mb, BIT_1); if (mb[0] != MBS_COMMAND_COMPLETE) { DEBUG15(qla_printk(KERN_INFO, ha, @@ -4067,7 +4069,7 @@ qla24xx_configure_vhba(scsi_qla_host_t *ha) atomic_set(&ha->loop_state, LOOP_UP); set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); - rval = qla2x00_loop_resync(ha); + rval = qla2x00_loop_resync(ha->parent); return rval; } -- cgit v1.2.3 From 463717edc9d675ead14b02f060425ff7860d1dc1 Mon Sep 17 00:00:00 2001 From: Seokmann Ju Date: Thu, 3 Apr 2008 13:13:29 -0700 Subject: [SCSI] qla2xxx: Check DFLG_NO_CABLE only on physical port. As there is no actual cable connection on vports, made change so that the driver checks DFLG_NO_CABLE against ha->device_flags only for physical port. Signed-off-by: Seokmann Ju Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_os.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/scsi/qla2xxx') diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 4c50b9b53d23..8b33b163b1d4 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -2577,7 +2577,8 @@ qla2x00_timer(scsi_qla_host_t *ha) set_bit(RESTART_QUEUES_NEEDED, &ha->dpc_flags); start_dpc++; - if (!(ha->device_flags & DFLG_NO_CABLE)) { + if (!(ha->device_flags & DFLG_NO_CABLE) && + !ha->parent) { DEBUG(printk("scsi(%ld): Loop down - " "aborting ISP.\n", ha->host_no)); -- cgit v1.2.3 From bd2a1846b2313e32d0270151a31a6b8335384a20 Mon Sep 17 00:00:00 2001 From: Seokmann Ju Date: Thu, 3 Apr 2008 13:13:30 -0700 Subject: [SCSI] qla2xxx: Use proper HA during asynchrounous event handling. Changes are added to the driver so that it can behave properly upon having asynchronous events, for example, addition of target devices to the VPs. Signed-off-by: Seokmann Ju Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_isr.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'drivers/scsi/qla2xxx') diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 360af4e09d12..285479b62d8f 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -272,6 +272,8 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) uint32_t rscn_entry, host_pid; uint8_t rscn_queue_index; unsigned long flags; + scsi_qla_host_t *vha; + int i; /* Setup to process RIO completion. */ handle_cnt = 0; @@ -542,6 +544,18 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) break; case MBA_PORT_UPDATE: /* Port database update */ + if ((ha->flags.npiv_supported) && (ha->num_vhosts)) { + for_each_mapped_vp_idx(ha, i) { + list_for_each_entry(vha, &ha->vp_list, + vp_list) { + if ((mb[3] & 0xff) + == vha->vp_idx) { + ha = vha; + break; + } + } + } + } /* * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET * event etc. earlier indicating loop is down) then process @@ -576,12 +590,18 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) break; case MBA_RSCN_UPDATE: /* State Change Registration */ - /* Check if the Vport has issued a SCR */ - if (ha->parent && test_bit(VP_SCR_NEEDED, &ha->vp_flags)) - break; - /* Only handle SCNs for our Vport index. */ - if (ha->flags.npiv_supported && ha->vp_idx != mb[3]) - break; + if ((ha->flags.npiv_supported) && (ha->num_vhosts)) { + for_each_mapped_vp_idx(ha, i) { + list_for_each_entry(vha, &ha->vp_list, + vp_list) { + if ((mb[3] & 0xff) + == vha->vp_idx) { + ha = vha; + break; + } + } + } + } DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n", ha->host_no)); -- cgit v1.2.3 From 221726d41a6c351fd8ea7d4b11ab13085f7a8647 Mon Sep 17 00:00:00 2001 From: Seokmann Ju Date: Thu, 3 Apr 2008 13:13:31 -0700 Subject: [SCSI] qla2xxx: Correct vport configuration-change handling. Upon having configuration changes on vports only, the driver handles SCR regardless physical port state and, in turn, it results mailbox error as below: Mar 20 11:24:20 dl585 kernel: qla2x00_mailbox_command(9): **** FAILED. mbx0=4005, mbx1=1, mbx2=8100, cmd=70 **** With the changes, driver checks physical port loop_state and make sure the port is ready to take commands. Signed-off-by: Seokmann Ju Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_mid.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/scsi/qla2xxx') diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 9f48cd46f618..f2b04979e5f0 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -254,9 +254,17 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *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 */ - qla24xx_configure_vp(vha); + 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; } -- cgit v1.2.3 From b35c07d00751c3d554dd6e582b661ac2e8ffc162 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 3 Apr 2008 13:13:32 -0700 Subject: [SCSI] qla2xxx: Update version number to 8.02.01-k1. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/scsi/qla2xxx') diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 0281537491cf..f42f17acf2cf 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -7,9 +7,9 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.02.00-k9" +#define QLA2XXX_VERSION "8.02.01-k1" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 2 -#define QLA_DRIVER_PATCH_VER 0 +#define QLA_DRIVER_PATCH_VER 1 #define QLA_DRIVER_BETA_VER 0 -- cgit v1.2.3