2020-09-08 15:34:48 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2005-04-17 02:20:36 +04:00
/*
2005-10-27 22:10:08 +04:00
* QLogic Fibre Channel HBA Driver
2014-04-12 00:54:24 +04:00
* Copyright ( c ) 2003 - 2014 QLogic Corporation
2005-04-17 02:20:36 +04:00
*/
2011-07-14 23:00:12 +04:00
/*
* Table for showing the current message id in use for particular level
* Change this table for addition of log / debug messages .
2011-08-16 22:29:23 +04:00
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* | Level | Last Value Used | Holes |
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2020-06-30 13:22:29 +03:00
* | Module Init and Probe | 0x0199 | |
* | Mailbox commands | 0x1206 | 0x11a5 - 0x11ff |
2017-06-21 23:48:43 +03:00
* | Device Discovery | 0x2134 | 0x210e - 0x2116 |
2017-06-21 23:48:41 +03:00
* | | | 0x211a |
* | | | 0x211c - 0x2128 |
2020-09-04 07:51:27 +03:00
* | | | 0x212c - 0x2134 |
2015-12-17 22:57:00 +03:00
* | Queue Command and IO tracing | 0x3074 | 0x300b |
2012-08-22 22:21:31 +04:00
* | | | 0x3027 - 0x3028 |
2013-03-28 16:21:23 +04:00
* | | | 0x303d - 0x3041 |
* | | | 0x302d , 0x3033 |
* | | | 0x3036 , 0x3038 |
* | | | 0x303a |
2013-10-30 11:38:17 +04:00
* | DPC Thread | 0x4023 | 0x4002 , 0x4013 |
2020-06-30 13:22:29 +03:00
* | Async Events | 0x509c | |
2013-08-27 09:37:38 +04:00
* | Timer Routines | 0x6012 | |
2016-01-27 20:03:33 +03:00
* | User Space Interactions | 0x70e3 | 0x7018 , 0x702e |
2014-02-26 13:15:06 +04:00
* | | | 0x7020 , 0x7024 |
* | | | 0x7039 , 0x7045 |
* | | | 0x7073 - 0x7075 |
* | | | 0x70a5 - 0x70a6 |
* | | | 0x70a8 , 0x70ab |
* | | | 0x70ad - 0x70ae |
2016-07-06 18:14:17 +03:00
* | | | 0x70d0 - 0x70d6 |
2014-02-26 13:15:06 +04:00
* | | | 0x70d7 - 0x70db |
2017-08-24 01:05:03 +03:00
* | Task Management | 0x8042 | 0x8000 |
2014-04-12 00:54:46 +04:00
* | | | 0x8019 |
2014-04-12 00:54:45 +04:00
* | | | 0x8025 , 0x8026 |
* | | | 0x8031 , 0x8032 |
* | | | 0x8039 , 0x803c |
2012-05-15 22:34:15 +04:00
* | AER / EEH | 0x9011 | |
2011-08-16 22:29:23 +04:00
* | Virtual Port | 0xa007 | |
2014-04-12 00:54:26 +04:00
* | ISP82XX Specific | 0xb157 | 0xb002 , 0xb024 |
2013-08-27 09:37:28 +04:00
* | | | 0xb09e , 0xb0ae |
2014-04-12 00:54:34 +04:00
* | | | 0xb0c3 , 0xb0c6 |
2013-08-27 09:37:28 +04:00
* | | | 0xb0e0 - 0xb0ef |
* | | | 0xb085 , 0xb0dc |
* | | | 0xb107 , 0xb108 |
* | | | 0xb111 , 0xb11e |
* | | | 0xb12c , 0xb12d |
* | | | 0xb13a , 0xb142 |
* | | | 0xb13c - 0xb140 |
2013-08-27 09:37:53 +04:00
* | | | 0xb149 |
2016-12-13 01:40:07 +03:00
* | MultiQ | 0xc010 | |
2018-03-21 09:09:37 +03:00
* | Misc | 0xd303 | 0xd031 - 0xd0ff |
2014-02-26 13:15:06 +04:00
* | | | 0xd101 - 0xd1fe |
2014-09-25 13:16:36 +04:00
* | | | 0xd214 - 0xd2fe |
2017-06-02 19:12:01 +03:00
* | Target Mode | 0xe081 | |
2015-12-17 22:57:02 +03:00
* | Target Mode Management | 0xf09b | 0xf002 |
2013-08-27 09:37:53 +04:00
* | | | 0xf046 - 0xf049 |
2015-07-14 23:00:44 +03:00
* | Target Mode Task Management | 0x1000d | |
2011-08-16 22:29:23 +04:00
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2011-07-14 23:00:12 +04:00
*/
2005-04-17 02:20:36 +04:00
# include "qla_def.h"
# include <linux/delay.h>
2020-02-13 04:29:28 +03:00
# define CREATE_TRACE_POINTS
# include <trace/events/qla.h>
2005-04-17 02:20:36 +04:00
2011-07-14 23:00:12 +04:00
static uint32_t ql_dbg_offset = 0x800 ;
2006-06-24 03:10:29 +04:00
static inline void
2008-11-06 21:40:19 +03:00
qla2xxx_prep_dump ( struct qla_hw_data * ha , struct qla2xxx_fw_dump * fw_dump )
2006-06-24 03:10:29 +04:00
{
fw_dump - > fw_major_version = htonl ( ha - > fw_major_version ) ;
fw_dump - > fw_minor_version = htonl ( ha - > fw_minor_version ) ;
fw_dump - > fw_subminor_version = htonl ( ha - > fw_subminor_version ) ;
fw_dump - > fw_attributes = htonl ( ha - > fw_attributes ) ;
fw_dump - > vendor = htonl ( ha - > pdev - > vendor ) ;
fw_dump - > device = htonl ( ha - > pdev - > device ) ;
fw_dump - > subsystem_vendor = htonl ( ha - > pdev - > subsystem_vendor ) ;
fw_dump - > subsystem_device = htonl ( ha - > pdev - > subsystem_device ) ;
}
static inline void *
2008-12-10 03:45:39 +03:00
qla2xxx_copy_queues ( struct qla_hw_data * ha , void * ptr )
2006-06-24 03:10:29 +04:00
{
2008-12-10 03:45:39 +03:00
struct req_que * req = ha - > req_q_map [ 0 ] ;
struct rsp_que * rsp = ha - > rsp_q_map [ 0 ] ;
2006-06-24 03:10:29 +04:00
/* Request queue. */
2008-11-06 21:40:19 +03:00
memcpy ( ptr , req - > ring , req - > length *
2006-06-24 03:10:29 +04:00
sizeof ( request_t ) ) ;
/* Response queue. */
2008-11-06 21:40:19 +03:00
ptr + = req - > length * sizeof ( request_t ) ;
memcpy ( ptr , rsp - > ring , rsp - > length *
2006-06-24 03:10:29 +04:00
sizeof ( response_t ) ) ;
2008-11-06 21:40:19 +03:00
return ptr + ( rsp - > length * sizeof ( response_t ) ) ;
2006-06-24 03:10:29 +04:00
}
2005-04-17 02:20:36 +04:00
2014-02-26 13:15:06 +04:00
int
qla27xx_dump_mpi_ram ( struct qla_hw_data * ha , uint32_t addr , uint32_t * ram ,
uint32_t ram_dwords , void * * nxt )
{
struct device_reg_24xx __iomem * reg = & ha - > iobase - > isp24 ;
dma_addr_t dump_dma = ha - > gid_list_dma ;
2020-05-19 00:17:09 +03:00
uint32_t * chunk = ( uint32_t * ) ha - > gid_list ;
2019-03-12 21:08:12 +03:00
uint32_t dwords = qla2x00_gid_list_size ( ha ) / 4 ;
uint32_t stat ;
ulong i , j , timer = 6000000 ;
int rval = QLA_FUNCTION_FAILED ;
2014-02-26 13:15:06 +04:00
clear_bit ( MBX_INTERRUPT , & ha - > mbx_cmd_flags ) ;
2019-03-12 21:08:12 +03:00
for ( i = 0 ; i < ram_dwords ; i + = dwords , addr + = dwords ) {
if ( i + dwords > ram_dwords )
dwords = ram_dwords - i ;
2014-02-26 13:15:06 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > mailbox0 , MBC_LOAD_DUMP_MPI_RAM ) ;
wrt_reg_word ( & reg - > mailbox1 , LSW ( addr ) ) ;
wrt_reg_word ( & reg - > mailbox8 , MSW ( addr ) ) ;
2014-02-26 13:15:06 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > mailbox2 , MSW ( LSD ( dump_dma ) ) ) ;
wrt_reg_word ( & reg - > mailbox3 , LSW ( LSD ( dump_dma ) ) ) ;
wrt_reg_word ( & reg - > mailbox6 , MSW ( MSD ( dump_dma ) ) ) ;
wrt_reg_word ( & reg - > mailbox7 , LSW ( MSD ( dump_dma ) ) ) ;
2014-02-26 13:15:06 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > mailbox4 , MSW ( dwords ) ) ;
wrt_reg_word ( & reg - > mailbox5 , LSW ( dwords ) ) ;
2014-02-26 13:15:06 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > mailbox9 , 0 ) ;
wrt_reg_dword ( & reg - > hccr , HCCRX_SET_HOST_INT ) ;
2014-02-26 13:15:06 +04:00
ha - > flags . mbox_int = 0 ;
2019-03-12 21:08:12 +03:00
while ( timer - - ) {
udelay ( 5 ) ;
2014-02-26 13:15:06 +04:00
2020-05-19 00:17:08 +03:00
stat = rd_reg_dword ( & reg - > host_status ) ;
2019-03-12 21:08:12 +03:00
/* Check for pending interrupts. */
if ( ! ( stat & HSRX_RISC_INT ) )
continue ;
2014-02-26 13:15:06 +04:00
2019-03-12 21:08:12 +03:00
stat & = 0xff ;
if ( stat ! = 0x1 & & stat ! = 0x2 & &
stat ! = 0x10 & & stat ! = 0x11 ) {
2014-02-26 13:15:06 +04:00
/* Clear this intr; it wasn't a mailbox intr */
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > hccr , HCCRX_CLR_RISC_INT ) ;
rd_reg_dword ( & reg - > hccr ) ;
2019-03-12 21:08:12 +03:00
continue ;
2014-02-26 13:15:06 +04:00
}
2019-03-12 21:08:12 +03:00
set_bit ( MBX_INTERRUPT , & ha - > mbx_cmd_flags ) ;
2020-05-19 00:17:08 +03:00
rval = rd_reg_word ( & reg - > mailbox0 ) & MBS_MASK ;
wrt_reg_dword ( & reg - > hccr , HCCRX_CLR_RISC_INT ) ;
rd_reg_dword ( & reg - > hccr ) ;
2019-03-12 21:08:12 +03:00
break ;
2014-02-26 13:15:06 +04:00
}
ha - > flags . mbox_int = 1 ;
2019-03-12 21:08:12 +03:00
* nxt = ram + i ;
2014-02-26 13:15:06 +04:00
2019-03-12 21:08:12 +03:00
if ( ! test_and_clear_bit ( MBX_INTERRUPT , & ha - > mbx_cmd_flags ) ) {
/* no interrupt, timed out*/
return rval ;
}
if ( rval ) {
/* error completion status */
return rval ;
}
for ( j = 0 ; j < dwords ; j + + ) {
2019-03-12 21:08:13 +03:00
ram [ i + j ] =
( IS_QLA27XX ( ha ) | | IS_QLA28XX ( ha ) ) ?
2019-03-12 21:08:12 +03:00
chunk [ j ] : swab32 ( chunk [ j ] ) ;
2014-02-26 13:15:06 +04:00
}
}
2019-03-12 21:08:12 +03:00
* nxt = ram + i ;
return QLA_SUCCESS ;
2014-02-26 13:15:06 +04:00
}
int
2020-05-19 00:17:12 +03:00
qla24xx_dump_ram ( struct qla_hw_data * ha , uint32_t addr , __be32 * ram ,
uint32_t ram_dwords , void * * nxt )
2007-07-20 07:37:34 +04:00
{
2019-03-12 21:08:12 +03:00
int rval = QLA_FUNCTION_FAILED ;
2007-07-20 07:37:34 +04:00
struct device_reg_24xx __iomem * reg = & ha - > iobase - > isp24 ;
2008-04-25 02:21:22 +04:00
dma_addr_t dump_dma = ha - > gid_list_dma ;
2020-05-19 00:17:09 +03:00
uint32_t * chunk = ( uint32_t * ) ha - > gid_list ;
2019-03-12 21:08:12 +03:00
uint32_t dwords = qla2x00_gid_list_size ( ha ) / 4 ;
uint32_t stat ;
ulong i , j , timer = 6000000 ;
2007-07-20 07:37:34 +04:00
clear_bit ( MBX_INTERRUPT , & ha - > mbx_cmd_flags ) ;
2019-03-12 21:08:12 +03:00
for ( i = 0 ; i < ram_dwords ; i + = dwords , addr + = dwords ) {
if ( i + dwords > ram_dwords )
dwords = ram_dwords - i ;
2007-07-20 07:37:34 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > mailbox0 , MBC_DUMP_RISC_RAM_EXTENDED ) ;
wrt_reg_word ( & reg - > mailbox1 , LSW ( addr ) ) ;
wrt_reg_word ( & reg - > mailbox8 , MSW ( addr ) ) ;
2021-01-11 12:31:32 +03:00
wrt_reg_word ( & reg - > mailbox10 , 0 ) ;
2007-07-20 07:37:34 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > mailbox2 , MSW ( LSD ( dump_dma ) ) ) ;
wrt_reg_word ( & reg - > mailbox3 , LSW ( LSD ( dump_dma ) ) ) ;
wrt_reg_word ( & reg - > mailbox6 , MSW ( MSD ( dump_dma ) ) ) ;
wrt_reg_word ( & reg - > mailbox7 , LSW ( MSD ( dump_dma ) ) ) ;
2007-07-20 07:37:34 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > mailbox4 , MSW ( dwords ) ) ;
wrt_reg_word ( & reg - > mailbox5 , LSW ( dwords ) ) ;
wrt_reg_dword ( & reg - > hccr , HCCRX_SET_HOST_INT ) ;
2007-07-20 07:37:34 +04:00
2014-02-26 13:15:06 +04:00
ha - > flags . mbox_int = 0 ;
2019-03-12 21:08:12 +03:00
while ( timer - - ) {
udelay ( 5 ) ;
2020-05-19 00:17:08 +03:00
stat = rd_reg_dword ( & reg - > host_status ) ;
2007-07-20 07:37:34 +04:00
2019-03-12 21:08:12 +03:00
/* Check for pending interrupts. */
if ( ! ( stat & HSRX_RISC_INT ) )
continue ;
2007-07-20 07:37:34 +04:00
2019-03-12 21:08:12 +03:00
stat & = 0xff ;
if ( stat ! = 0x1 & & stat ! = 0x2 & &
stat ! = 0x10 & & stat ! = 0x11 ) {
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > hccr , HCCRX_CLR_RISC_INT ) ;
rd_reg_dword ( & reg - > hccr ) ;
2019-03-12 21:08:12 +03:00
continue ;
2007-07-20 07:37:34 +04:00
}
2019-03-12 21:08:12 +03:00
set_bit ( MBX_INTERRUPT , & ha - > mbx_cmd_flags ) ;
2020-05-19 00:17:08 +03:00
rval = rd_reg_word ( & reg - > mailbox0 ) & MBS_MASK ;
wrt_reg_dword ( & reg - > hccr , HCCRX_CLR_RISC_INT ) ;
rd_reg_dword ( & reg - > hccr ) ;
2019-03-12 21:08:12 +03:00
break ;
2007-07-20 07:37:34 +04:00
}
2014-02-26 13:15:06 +04:00
ha - > flags . mbox_int = 1 ;
2019-03-12 21:08:12 +03:00
* nxt = ram + i ;
2007-07-20 07:37:34 +04:00
2019-03-12 21:08:12 +03:00
if ( ! test_and_clear_bit ( MBX_INTERRUPT , & ha - > mbx_cmd_flags ) ) {
/* no interrupt, timed out*/
return rval ;
}
if ( rval ) {
/* error completion status */
return rval ;
}
for ( j = 0 ; j < dwords ; j + + ) {
2020-05-19 00:17:12 +03:00
ram [ i + j ] = ( __force __be32 )
( ( IS_QLA27XX ( ha ) | | IS_QLA28XX ( ha ) ) ?
chunk [ j ] : swab32 ( chunk [ j ] ) ) ;
2007-07-20 07:37:34 +04:00
}
}
2019-03-12 21:08:12 +03:00
* nxt = ram + i ;
return QLA_SUCCESS ;
2007-07-20 07:37:34 +04:00
}
2008-04-25 02:21:22 +04:00
static int
2020-05-19 00:17:12 +03:00
qla24xx_dump_memory ( struct qla_hw_data * ha , __be32 * code_ram ,
uint32_t cram_size , void * * nxt )
2008-04-25 02:21:22 +04:00
{
int rval ;
/* Code RAM. */
rval = qla24xx_dump_ram ( ha , 0x20000 , code_ram , cram_size / 4 , nxt ) ;
if ( rval ! = QLA_SUCCESS )
return rval ;
2014-04-12 00:54:21 +04:00
set_bit ( RISC_SRAM_DUMP_CMPL , & ha - > fw_dump_cap_flags ) ;
2008-04-25 02:21:22 +04:00
/* External Memory. */
2014-04-12 00:54:21 +04:00
rval = qla24xx_dump_ram ( ha , 0x100000 , * nxt ,
2008-04-25 02:21:22 +04:00
ha - > fw_memory_size - 0x100000 + 1 , nxt ) ;
2014-04-12 00:54:21 +04:00
if ( rval = = QLA_SUCCESS )
set_bit ( RISC_EXT_MEM_DUMP_CMPL , & ha - > fw_dump_cap_flags ) ;
return rval ;
2008-04-25 02:21:22 +04:00
}
2020-05-19 00:17:12 +03:00
static __be32 *
2007-07-26 22:41:13 +04:00
qla24xx_read_window ( struct device_reg_24xx __iomem * reg , uint32_t iobase ,
2020-05-19 00:17:12 +03:00
uint32_t count , __be32 * buf )
2007-07-26 22:41:13 +04:00
{
2020-05-19 00:17:12 +03:00
__le32 __iomem * dmp_reg ;
2007-07-26 22:41:13 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_addr , iobase ) ;
2007-07-26 22:41:13 +04:00
dmp_reg = & reg - > iobase_window ;
2016-01-27 20:03:34 +03:00
for ( ; count - - ; dmp_reg + + )
2020-05-19 00:17:08 +03:00
* buf + + = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2007-07-26 22:41:13 +04:00
return buf ;
}
2014-04-12 00:54:20 +04:00
void
2014-04-12 00:54:21 +04:00
qla24xx_pause_risc ( struct device_reg_24xx __iomem * reg , struct qla_hw_data * ha )
2007-07-26 22:41:13 +04:00
{
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > hccr , HCCRX_SET_RISC_PAUSE ) ;
2007-07-26 22:41:13 +04:00
2014-04-12 00:54:20 +04:00
/* 100 usec delay is sufficient enough for hardware to pause RISC */
udelay ( 100 ) ;
2020-05-19 00:17:08 +03:00
if ( rd_reg_dword ( & reg - > host_status ) & HSRX_RISC_PAUSED )
2014-04-12 00:54:21 +04:00
set_bit ( RISC_PAUSE_CMPL , & ha - > fw_dump_cap_flags ) ;
2007-07-26 22:41:13 +04:00
}
2014-02-26 13:15:06 +04:00
int
2008-11-06 21:40:19 +03:00
qla24xx_soft_reset ( struct qla_hw_data * ha )
2007-07-26 22:41:13 +04:00
{
int rval = QLA_SUCCESS ;
uint32_t cnt ;
2014-04-12 00:54:20 +04:00
uint16_t wd ;
2007-07-26 22:41:13 +04:00
struct device_reg_24xx __iomem * reg = & ha - > iobase - > isp24 ;
2014-04-12 00:54:20 +04:00
/*
* Reset RISC . The delay is dependent on system architecture .
* Driver can proceed with the reset sequence after waiting
* for a timeout period .
*/
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > ctrl_status , CSRX_DMA_SHUTDOWN | MWB_4096_BYTES ) ;
2007-07-26 22:41:13 +04:00
for ( cnt = 0 ; cnt < 30000 ; cnt + + ) {
2020-05-19 00:17:08 +03:00
if ( ( rd_reg_dword ( & reg - > ctrl_status ) & CSRX_DMA_ACTIVE ) = = 0 )
2007-07-26 22:41:13 +04:00
break ;
udelay ( 10 ) ;
}
2020-05-19 00:17:08 +03:00
if ( ! ( rd_reg_dword ( & reg - > ctrl_status ) & CSRX_DMA_ACTIVE ) )
2014-04-12 00:54:21 +04:00
set_bit ( DMA_SHUTDOWN_CMPL , & ha - > fw_dump_cap_flags ) ;
2007-07-26 22:41:13 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > ctrl_status ,
2007-07-26 22:41:13 +04:00
CSRX_ISP_SOFT_RESET | CSRX_DMA_SHUTDOWN | MWB_4096_BYTES ) ;
pci_read_config_word ( ha - > pdev , PCI_COMMAND , & wd ) ;
udelay ( 100 ) ;
/* Wait for soft-reset to complete. */
for ( cnt = 0 ; cnt < 30000 ; cnt + + ) {
2020-05-19 00:17:08 +03:00
if ( ( rd_reg_dword ( & reg - > ctrl_status ) &
2007-07-26 22:41:13 +04:00
CSRX_ISP_SOFT_RESET ) = = 0 )
break ;
udelay ( 10 ) ;
}
2020-05-19 00:17:08 +03:00
if ( ! ( rd_reg_dword ( & reg - > ctrl_status ) & CSRX_ISP_SOFT_RESET ) )
2014-04-12 00:54:21 +04:00
set_bit ( ISP_RESET_CMPL , & ha - > fw_dump_cap_flags ) ;
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > hccr , HCCRX_CLR_RISC_RESET ) ;
rd_reg_dword ( & reg - > hccr ) ; /* PCI Posting. */
2007-07-26 22:41:13 +04:00
2020-05-19 00:17:08 +03:00
for ( cnt = 10000 ; rd_reg_word ( & reg - > mailbox0 ) ! = 0 & &
2007-07-26 22:41:13 +04:00
rval = = QLA_SUCCESS ; cnt - - ) {
if ( cnt )
2014-04-12 00:54:20 +04:00
udelay ( 10 ) ;
2007-07-26 22:41:13 +04:00
else
rval = QLA_FUNCTION_TIMEOUT ;
}
2014-04-12 00:54:21 +04:00
if ( rval = = QLA_SUCCESS )
set_bit ( RISC_RDY_AFT_RESET , & ha - > fw_dump_cap_flags ) ;
2007-07-26 22:41:13 +04:00
return rval ;
}
2008-04-25 02:21:22 +04:00
static int
2020-05-19 00:17:12 +03:00
qla2xxx_dump_ram ( struct qla_hw_data * ha , uint32_t addr , __be16 * ram ,
2009-06-17 21:30:31 +04:00
uint32_t ram_words , void * * nxt )
2008-04-25 02:21:22 +04:00
{
int rval ;
uint32_t cnt , stat , timer , words , idx ;
uint16_t mb0 ;
struct device_reg_2xxx __iomem * reg = & ha - > iobase - > isp ;
dma_addr_t dump_dma = ha - > gid_list_dma ;
2020-05-19 00:17:12 +03:00
__le16 * dump = ( __force __le16 * ) ha - > gid_list ;
2008-04-25 02:21:22 +04:00
rval = QLA_SUCCESS ;
mb0 = 0 ;
WRT_MAILBOX_REG ( ha , reg , 0 , MBC_DUMP_RISC_RAM_EXTENDED ) ;
clear_bit ( MBX_INTERRUPT , & ha - > mbx_cmd_flags ) ;
2012-02-09 23:15:57 +04:00
words = qla2x00_gid_list_size ( ha ) / 2 ;
2008-04-25 02:21:22 +04:00
for ( cnt = 0 ; cnt < ram_words & & rval = = QLA_SUCCESS ;
cnt + = words , addr + = words ) {
if ( cnt + words > ram_words )
words = ram_words - cnt ;
WRT_MAILBOX_REG ( ha , reg , 1 , LSW ( addr ) ) ;
WRT_MAILBOX_REG ( ha , reg , 8 , MSW ( addr ) ) ;
WRT_MAILBOX_REG ( ha , reg , 2 , MSW ( dump_dma ) ) ;
WRT_MAILBOX_REG ( ha , reg , 3 , LSW ( dump_dma ) ) ;
WRT_MAILBOX_REG ( ha , reg , 6 , MSW ( MSD ( dump_dma ) ) ) ;
WRT_MAILBOX_REG ( ha , reg , 7 , LSW ( MSD ( dump_dma ) ) ) ;
WRT_MAILBOX_REG ( ha , reg , 4 , words ) ;
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > hccr , HCCR_SET_HOST_INT ) ;
2008-04-25 02:21:22 +04:00
for ( timer = 6000000 ; timer ; timer - - ) {
/* Check for pending interrupts. */
2020-05-19 00:17:08 +03:00
stat = rd_reg_dword ( & reg - > u . isp2300 . host_status ) ;
2008-04-25 02:21:22 +04:00
if ( stat & HSR_RISC_INT ) {
stat & = 0xff ;
if ( stat = = 0x1 | | stat = = 0x2 ) {
set_bit ( MBX_INTERRUPT ,
& ha - > mbx_cmd_flags ) ;
mb0 = RD_MAILBOX_REG ( ha , reg , 0 ) ;
/* Release mailbox registers. */
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > semaphore , 0 ) ;
wrt_reg_word ( & reg - > hccr ,
2008-04-25 02:21:22 +04:00
HCCR_CLR_RISC_INT ) ;
2020-05-19 00:17:08 +03:00
rd_reg_word ( & reg - > hccr ) ;
2008-04-25 02:21:22 +04:00
break ;
} else if ( stat = = 0x10 | | stat = = 0x11 ) {
set_bit ( MBX_INTERRUPT ,
& ha - > mbx_cmd_flags ) ;
mb0 = RD_MAILBOX_REG ( ha , reg , 0 ) ;
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > hccr ,
2008-04-25 02:21:22 +04:00
HCCR_CLR_RISC_INT ) ;
2020-05-19 00:17:08 +03:00
rd_reg_word ( & reg - > hccr ) ;
2008-04-25 02:21:22 +04:00
break ;
}
/* clear this intr; it wasn't a mailbox intr */
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > hccr , HCCR_CLR_RISC_INT ) ;
rd_reg_word ( & reg - > hccr ) ;
2008-04-25 02:21:22 +04:00
}
udelay ( 5 ) ;
}
if ( test_and_clear_bit ( MBX_INTERRUPT , & ha - > mbx_cmd_flags ) ) {
rval = mb0 & MBS_MASK ;
for ( idx = 0 ; idx < words ; idx + + )
2020-05-19 00:17:12 +03:00
ram [ cnt + idx ] =
cpu_to_be16 ( le16_to_cpu ( dump [ idx ] ) ) ;
2008-04-25 02:21:22 +04:00
} else {
rval = QLA_FUNCTION_FAILED ;
}
}
2019-04-12 00:53:19 +03:00
* nxt = rval = = QLA_SUCCESS ? & ram [ cnt ] : NULL ;
2008-04-25 02:21:22 +04:00
return rval ;
}
2007-07-26 22:41:13 +04:00
static inline void
qla2xxx_read_window ( struct device_reg_2xxx __iomem * reg , uint32_t count ,
2020-05-19 00:17:12 +03:00
__be16 * buf )
2007-07-26 22:41:13 +04:00
{
2020-05-19 00:17:12 +03:00
__le16 __iomem * dmp_reg = & reg - > u . isp2300 . fb_cmd ;
2007-07-26 22:41:13 +04:00
2016-01-27 20:03:34 +03:00
for ( ; count - - ; dmp_reg + + )
2020-05-19 00:17:08 +03:00
* buf + + = htons ( rd_reg_word ( dmp_reg ) ) ;
2007-07-26 22:41:13 +04:00
}
2009-01-05 22:18:08 +03:00
static inline void *
qla24xx_copy_eft ( struct qla_hw_data * ha , void * ptr )
{
if ( ! ha - > eft )
return ptr ;
memcpy ( ptr , ha - > eft , ntohl ( ha - > fw_dump - > eft_size ) ) ;
return ptr + ntohl ( ha - > fw_dump - > eft_size ) ;
}
static inline void *
2020-05-19 00:17:12 +03:00
qla25xx_copy_fce ( struct qla_hw_data * ha , void * ptr , __be32 * * last_chain )
2009-01-05 22:18:08 +03:00
{
uint32_t cnt ;
2020-05-19 00:17:12 +03:00
__be32 * iter_reg ;
2009-01-05 22:18:08 +03:00
struct qla2xxx_fce_chain * fcec = ptr ;
if ( ! ha - > fce )
return ptr ;
* last_chain = & fcec - > type ;
2015-07-09 17:24:08 +03:00
fcec - > type = htonl ( DUMP_CHAIN_FCE ) ;
2009-01-05 22:18:08 +03:00
fcec - > chain_size = htonl ( sizeof ( struct qla2xxx_fce_chain ) +
fce_calc_size ( ha - > fce_bufs ) ) ;
fcec - > size = htonl ( fce_calc_size ( ha - > fce_bufs ) ) ;
fcec - > addr_l = htonl ( LSD ( ha - > fce_dma ) ) ;
fcec - > addr_h = htonl ( MSD ( ha - > fce_dma ) ) ;
iter_reg = fcec - > eregs ;
for ( cnt = 0 ; cnt < 8 ; cnt + + )
* iter_reg + + = htonl ( ha - > fce_mb [ cnt ] ) ;
memcpy ( iter_reg , ha - > fce , ntohl ( fcec - > size ) ) ;
2011-11-18 21:03:11 +04:00
return ( char * ) iter_reg + ntohl ( fcec - > size ) ;
2009-01-05 22:18:08 +03:00
}
2017-06-14 06:47:29 +03:00
static inline void *
2020-05-19 00:17:12 +03:00
qla25xx_copy_exlogin ( struct qla_hw_data * ha , void * ptr , __be32 * * last_chain )
2017-06-14 06:47:29 +03:00
{
struct qla2xxx_offld_chain * c = ptr ;
if ( ! ha - > exlogin_buf )
return ptr ;
* last_chain = & c - > type ;
c - > type = cpu_to_be32 ( DUMP_CHAIN_EXLOGIN ) ;
c - > chain_size = cpu_to_be32 ( sizeof ( struct qla2xxx_offld_chain ) +
ha - > exlogin_size ) ;
c - > size = cpu_to_be32 ( ha - > exlogin_size ) ;
c - > addr = cpu_to_be64 ( ha - > exlogin_buf_dma ) ;
ptr + = sizeof ( struct qla2xxx_offld_chain ) ;
memcpy ( ptr , ha - > exlogin_buf , ha - > exlogin_size ) ;
2020-05-19 00:17:12 +03:00
return ( char * ) ptr + be32_to_cpu ( c - > size ) ;
2017-06-14 06:47:29 +03:00
}
static inline void *
2020-05-19 00:17:12 +03:00
qla81xx_copy_exchoffld ( struct qla_hw_data * ha , void * ptr , __be32 * * last_chain )
2017-06-14 06:47:29 +03:00
{
struct qla2xxx_offld_chain * c = ptr ;
if ( ! ha - > exchoffld_buf )
return ptr ;
* last_chain = & c - > type ;
c - > type = cpu_to_be32 ( DUMP_CHAIN_EXCHG ) ;
c - > chain_size = cpu_to_be32 ( sizeof ( struct qla2xxx_offld_chain ) +
ha - > exchoffld_size ) ;
c - > size = cpu_to_be32 ( ha - > exchoffld_size ) ;
c - > addr = cpu_to_be64 ( ha - > exchoffld_buf_dma ) ;
ptr + = sizeof ( struct qla2xxx_offld_chain ) ;
memcpy ( ptr , ha - > exchoffld_buf , ha - > exchoffld_size ) ;
2020-05-19 00:17:12 +03:00
return ( char * ) ptr + be32_to_cpu ( c - > size ) ;
2017-06-14 06:47:29 +03:00
}
2012-05-15 22:34:28 +04:00
static inline void *
qla2xxx_copy_atioqueues ( struct qla_hw_data * ha , void * ptr ,
2020-05-19 00:17:12 +03:00
__be32 * * last_chain )
2012-05-15 22:34:28 +04:00
{
struct qla2xxx_mqueue_chain * q ;
struct qla2xxx_mqueue_header * qh ;
uint32_t num_queues ;
int que ;
struct {
int length ;
void * ring ;
} aq , * aqp ;
2013-03-25 10:21:37 +04:00
if ( ! ha - > tgt . atio_ring )
2012-05-15 22:34:28 +04:00
return ptr ;
num_queues = 1 ;
aqp = & aq ;
aqp - > length = ha - > tgt . atio_q_length ;
aqp - > ring = ha - > tgt . atio_ring ;
for ( que = 0 ; que < num_queues ; que + + ) {
/* aqp = ha->atio_q_map[que]; */
q = ptr ;
* last_chain = & q - > type ;
2015-07-09 17:24:08 +03:00
q - > type = htonl ( DUMP_CHAIN_QUEUE ) ;
2012-05-15 22:34:28 +04:00
q - > chain_size = htonl (
sizeof ( struct qla2xxx_mqueue_chain ) +
sizeof ( struct qla2xxx_mqueue_header ) +
( aqp - > length * sizeof ( request_t ) ) ) ;
ptr + = sizeof ( struct qla2xxx_mqueue_chain ) ;
/* Add header. */
qh = ptr ;
2015-07-09 17:24:08 +03:00
qh - > queue = htonl ( TYPE_ATIO_QUEUE ) ;
2012-05-15 22:34:28 +04:00
qh - > number = htonl ( que ) ;
qh - > size = htonl ( aqp - > length * sizeof ( request_t ) ) ;
ptr + = sizeof ( struct qla2xxx_mqueue_header ) ;
/* Add data. */
memcpy ( ptr , aqp - > ring , aqp - > length * sizeof ( request_t ) ) ;
ptr + = aqp - > length * sizeof ( request_t ) ;
}
return ptr ;
}
2012-02-09 23:15:33 +04:00
static inline void *
2020-05-19 00:17:12 +03:00
qla25xx_copy_mqueues ( struct qla_hw_data * ha , void * ptr , __be32 * * last_chain )
2012-02-09 23:15:33 +04:00
{
struct qla2xxx_mqueue_chain * q ;
struct qla2xxx_mqueue_header * qh ;
struct req_que * req ;
struct rsp_que * rsp ;
int que ;
if ( ! ha - > mqenable )
return ptr ;
/* Request queues */
for ( que = 1 ; que < ha - > max_req_queues ; que + + ) {
req = ha - > req_q_map [ que ] ;
if ( ! req )
break ;
/* Add chain. */
q = ptr ;
* last_chain = & q - > type ;
2015-07-09 17:24:08 +03:00
q - > type = htonl ( DUMP_CHAIN_QUEUE ) ;
2012-02-09 23:15:33 +04:00
q - > chain_size = htonl (
sizeof ( struct qla2xxx_mqueue_chain ) +
sizeof ( struct qla2xxx_mqueue_header ) +
( req - > length * sizeof ( request_t ) ) ) ;
ptr + = sizeof ( struct qla2xxx_mqueue_chain ) ;
/* Add header. */
qh = ptr ;
2015-07-09 17:24:08 +03:00
qh - > queue = htonl ( TYPE_REQUEST_QUEUE ) ;
2012-02-09 23:15:33 +04:00
qh - > number = htonl ( que ) ;
qh - > size = htonl ( req - > length * sizeof ( request_t ) ) ;
ptr + = sizeof ( struct qla2xxx_mqueue_header ) ;
/* Add data. */
memcpy ( ptr , req - > ring , req - > length * sizeof ( request_t ) ) ;
ptr + = req - > length * sizeof ( request_t ) ;
}
/* Response queues */
for ( que = 1 ; que < ha - > max_rsp_queues ; que + + ) {
rsp = ha - > rsp_q_map [ que ] ;
if ( ! rsp )
break ;
/* Add chain. */
q = ptr ;
* last_chain = & q - > type ;
2015-07-09 17:24:08 +03:00
q - > type = htonl ( DUMP_CHAIN_QUEUE ) ;
2012-02-09 23:15:33 +04:00
q - > chain_size = htonl (
sizeof ( struct qla2xxx_mqueue_chain ) +
sizeof ( struct qla2xxx_mqueue_header ) +
( rsp - > length * sizeof ( response_t ) ) ) ;
ptr + = sizeof ( struct qla2xxx_mqueue_chain ) ;
/* Add header. */
qh = ptr ;
2015-07-09 17:24:08 +03:00
qh - > queue = htonl ( TYPE_RESPONSE_QUEUE ) ;
2012-02-09 23:15:33 +04:00
qh - > number = htonl ( que ) ;
qh - > size = htonl ( rsp - > length * sizeof ( response_t ) ) ;
ptr + = sizeof ( struct qla2xxx_mqueue_header ) ;
/* Add data. */
memcpy ( ptr , rsp - > ring , rsp - > length * sizeof ( response_t ) ) ;
ptr + = rsp - > length * sizeof ( response_t ) ;
}
return ptr ;
}
2009-01-05 22:18:09 +03:00
static inline void *
2020-05-19 00:17:12 +03:00
qla25xx_copy_mq ( struct qla_hw_data * ha , void * ptr , __be32 * * last_chain )
2009-01-05 22:18:09 +03:00
{
uint32_t cnt , que_idx ;
2009-04-07 09:33:40 +04:00
uint8_t que_cnt ;
2009-01-05 22:18:09 +03:00
struct qla2xxx_mq_chain * mq = ptr ;
2015-07-09 17:24:27 +03:00
device_reg_t * reg ;
2009-01-05 22:18:09 +03:00
2019-03-12 21:08:13 +03:00
if ( ! ha - > mqenable | | IS_QLA83XX ( ha ) | | IS_QLA27XX ( ha ) | |
IS_QLA28XX ( ha ) )
2009-01-05 22:18:09 +03:00
return ptr ;
mq = ptr ;
* last_chain = & mq - > type ;
2015-07-09 17:24:08 +03:00
mq - > type = htonl ( DUMP_CHAIN_MQ ) ;
mq - > chain_size = htonl ( sizeof ( struct qla2xxx_mq_chain ) ) ;
2009-01-05 22:18:09 +03:00
2009-04-07 09:33:40 +04:00
que_cnt = ha - > max_req_queues > ha - > max_rsp_queues ?
ha - > max_req_queues : ha - > max_rsp_queues ;
2009-01-05 22:18:09 +03:00
mq - > count = htonl ( que_cnt ) ;
for ( cnt = 0 ; cnt < que_cnt ; cnt + + ) {
2013-08-27 09:37:30 +04:00
reg = ISP_QUE_REG ( ha , cnt ) ;
2009-01-05 22:18:09 +03:00
que_idx = cnt * 4 ;
2013-08-27 09:37:30 +04:00
mq - > qregs [ que_idx ] =
2020-05-19 00:17:08 +03:00
htonl ( rd_reg_dword ( & reg - > isp25mq . req_q_in ) ) ;
2013-08-27 09:37:30 +04:00
mq - > qregs [ que_idx + 1 ] =
2020-05-19 00:17:08 +03:00
htonl ( rd_reg_dword ( & reg - > isp25mq . req_q_out ) ) ;
2013-08-27 09:37:30 +04:00
mq - > qregs [ que_idx + 2 ] =
2020-05-19 00:17:08 +03:00
htonl ( rd_reg_dword ( & reg - > isp25mq . rsp_q_in ) ) ;
2013-08-27 09:37:30 +04:00
mq - > qregs [ que_idx + 3 ] =
2020-05-19 00:17:08 +03:00
htonl ( rd_reg_dword ( & reg - > isp25mq . rsp_q_out ) ) ;
2009-01-05 22:18:09 +03:00
}
return ptr + sizeof ( struct qla2xxx_mq_chain ) ;
}
2011-08-16 22:31:44 +04:00
void
2009-10-14 02:16:45 +04:00
qla2xxx_dump_post_process ( scsi_qla_host_t * vha , int rval )
{
struct qla_hw_data * ha = vha - > hw ;
if ( rval ! = QLA_SUCCESS ) {
2011-07-14 23:00:13 +04:00
ql_log ( ql_log_warn , vha , 0xd000 ,
2014-04-12 00:54:21 +04:00
" Failed to dump firmware (%x), dump status flags (0x%lx). \n " ,
rval , ha - > fw_dump_cap_flags ) ;
2020-04-30 15:18:00 +03:00
ha - > fw_dumped = false ;
2009-10-14 02:16:45 +04:00
} else {
2011-07-14 23:00:13 +04:00
ql_log ( ql_log_info , vha , 0xd001 ,
2014-04-12 00:54:21 +04:00
" Firmware dump saved to temp buffer (%ld/%p), dump status flags (0x%lx). \n " ,
vha - > host_no , ha - > fw_dump , ha - > fw_dump_cap_flags ) ;
2020-04-30 15:18:00 +03:00
ha - > fw_dumped = true ;
2009-10-14 02:16:45 +04:00
qla2x00_post_uevent_work ( vha , QLA_UEVENT_CODE_FW_DUMP ) ;
}
}
2020-05-19 00:17:00 +03:00
void qla2xxx_dump_fw ( scsi_qla_host_t * vha )
{
unsigned long flags ;
spin_lock_irqsave ( & vha - > hw - > hardware_lock , flags ) ;
vha - > hw - > isp_ops - > fw_dump ( vha ) ;
spin_unlock_irqrestore ( & vha - > hw - > hardware_lock , flags ) ;
}
2005-04-17 02:20:36 +04:00
/**
* qla2300_fw_dump ( ) - Dumps binary data from the 2300 firmware .
2018-01-24 03:33:51 +03:00
* @ vha : HA context
2005-04-17 02:20:36 +04:00
*/
void
2020-05-19 00:17:00 +03:00
qla2300_fw_dump ( scsi_qla_host_t * vha )
2005-04-17 02:20:36 +04:00
{
int rval ;
2008-04-25 02:21:22 +04:00
uint32_t cnt ;
2008-11-06 21:40:19 +03:00
struct qla_hw_data * ha = vha - > hw ;
2005-07-06 21:30:26 +04:00
struct device_reg_2xxx __iomem * reg = & ha - > iobase - > isp ;
2020-05-19 00:17:12 +03:00
__le16 __iomem * dmp_reg ;
2005-04-17 02:20:36 +04:00
struct qla2300_fw_dump * fw ;
2008-04-25 02:21:22 +04:00
void * nxt ;
2008-12-10 03:45:39 +03:00
struct scsi_qla_host * base_vha = pci_get_drvdata ( ha - > pdev ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:00 +03:00
lockdep_assert_held ( & ha - > hardware_lock ) ;
2005-04-17 02:20:36 +04:00
2006-05-18 02:09:50 +04:00
if ( ! ha - > fw_dump ) {
2011-07-14 23:00:13 +04:00
ql_log ( ql_log_warn , vha , 0xd002 ,
" No buffer available for dump. \n " ) ;
2020-05-19 00:17:00 +03:00
return ;
2005-04-17 02:20:36 +04:00
}
2006-05-18 02:09:50 +04:00
if ( ha - > fw_dumped ) {
2011-07-14 23:00:13 +04:00
ql_log ( ql_log_warn , vha , 0xd003 ,
" Firmware has been previously dumped (%p) "
" -- ignoring request. \n " ,
ha - > fw_dump ) ;
2020-05-19 00:17:00 +03:00
return ;
2005-04-17 02:20:36 +04:00
}
2006-06-24 03:10:29 +04:00
fw = & ha - > fw_dump - > isp . isp23 ;
qla2xxx_prep_dump ( ha , ha - > fw_dump ) ;
2005-04-17 02:20:36 +04:00
rval = QLA_SUCCESS ;
2020-05-19 00:17:08 +03:00
fw - > hccr = htons ( rd_reg_word ( & reg - > hccr ) ) ;
2005-04-17 02:20:36 +04:00
/* Pause RISC. */
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > hccr , HCCR_PAUSE_RISC ) ;
2005-04-17 02:20:36 +04:00
if ( IS_QLA2300 ( ha ) ) {
for ( cnt = 30000 ;
2020-05-19 00:17:08 +03:00
( rd_reg_word ( & reg - > hccr ) & HCCR_RISC_PAUSE ) = = 0 & &
2005-04-17 02:20:36 +04:00
rval = = QLA_SUCCESS ; cnt - - ) {
if ( cnt )
udelay ( 100 ) ;
else
rval = QLA_FUNCTION_TIMEOUT ;
}
} else {
2020-05-19 00:17:08 +03:00
rd_reg_word ( & reg - > hccr ) ; /* PCI Posting. */
2005-04-17 02:20:36 +04:00
udelay ( 10 ) ;
}
if ( rval = = QLA_SUCCESS ) {
2007-07-26 22:41:13 +04:00
dmp_reg = & reg - > flash_address ;
2020-04-13 05:13:59 +03:00
for ( cnt = 0 ; cnt < ARRAY_SIZE ( fw - > pbiu_reg ) ; cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
fw - > pbiu_reg [ cnt ] = htons ( rd_reg_word ( dmp_reg ) ) ;
2005-04-17 02:20:36 +04:00
2007-07-26 22:41:13 +04:00
dmp_reg = & reg - > u . isp2300 . req_q_in ;
2020-04-13 05:13:59 +03:00
for ( cnt = 0 ; cnt < ARRAY_SIZE ( fw - > risc_host_reg ) ;
2016-01-27 20:03:34 +03:00
cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
fw - > risc_host_reg [ cnt ] = htons ( rd_reg_word ( dmp_reg ) ) ;
2005-04-17 02:20:36 +04:00
2007-07-26 22:41:13 +04:00
dmp_reg = & reg - > u . isp2300 . mailbox0 ;
2020-04-13 05:13:59 +03:00
for ( cnt = 0 ; cnt < ARRAY_SIZE ( fw - > mailbox_reg ) ;
2016-01-27 20:03:34 +03:00
cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
fw - > mailbox_reg [ cnt ] = htons ( rd_reg_word ( dmp_reg ) ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > ctrl_status , 0x40 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 32 , fw - > resp_dma_reg ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > ctrl_status , 0x50 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 48 , fw - > dma_reg ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > ctrl_status , 0x00 ) ;
2007-07-26 22:41:13 +04:00
dmp_reg = & reg - > risc_hw ;
2020-04-13 05:13:59 +03:00
for ( cnt = 0 ; cnt < ARRAY_SIZE ( fw - > risc_hdw_reg ) ;
2016-01-27 20:03:34 +03:00
cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
fw - > risc_hdw_reg [ cnt ] = htons ( rd_reg_word ( dmp_reg ) ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > pcr , 0x2000 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 16 , fw - > risc_gp0_reg ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > pcr , 0x2200 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 16 , fw - > risc_gp1_reg ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > pcr , 0x2400 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 16 , fw - > risc_gp2_reg ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > pcr , 0x2600 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 16 , fw - > risc_gp3_reg ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > pcr , 0x2800 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 16 , fw - > risc_gp4_reg ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > pcr , 0x2A00 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 16 , fw - > risc_gp5_reg ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > pcr , 0x2C00 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 16 , fw - > risc_gp6_reg ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > pcr , 0x2E00 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 16 , fw - > risc_gp7_reg ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > ctrl_status , 0x10 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 64 , fw - > frame_buf_hdw_reg ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > ctrl_status , 0x20 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 64 , fw - > fpm_b0_reg ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > ctrl_status , 0x30 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 64 , fw - > fpm_b1_reg ) ;
2005-04-17 02:20:36 +04:00
/* Reset RISC. */
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > ctrl_status , CSR_ISP_SOFT_RESET ) ;
2005-04-17 02:20:36 +04:00
for ( cnt = 0 ; cnt < 30000 ; cnt + + ) {
2020-05-19 00:17:08 +03:00
if ( ( rd_reg_word ( & reg - > ctrl_status ) &
2005-04-17 02:20:36 +04:00
CSR_ISP_SOFT_RESET ) = = 0 )
break ;
udelay ( 10 ) ;
}
}
if ( ! IS_QLA2300 ( ha ) ) {
for ( cnt = 30000 ; RD_MAILBOX_REG ( ha , reg , 0 ) ! = 0 & &
rval = = QLA_SUCCESS ; cnt - - ) {
if ( cnt )
udelay ( 100 ) ;
else
rval = QLA_FUNCTION_TIMEOUT ;
}
}
2008-04-25 02:21:22 +04:00
/* Get RISC SRAM. */
if ( rval = = QLA_SUCCESS )
rval = qla2xxx_dump_ram ( ha , 0x800 , fw - > risc_ram ,
2020-04-13 05:13:59 +03:00
ARRAY_SIZE ( fw - > risc_ram ) , & nxt ) ;
2005-04-17 02:20:36 +04:00
2008-04-25 02:21:22 +04:00
/* Get stack SRAM. */
if ( rval = = QLA_SUCCESS )
rval = qla2xxx_dump_ram ( ha , 0x10000 , fw - > stack_ram ,
2020-04-13 05:13:59 +03:00
ARRAY_SIZE ( fw - > stack_ram ) , & nxt ) ;
2005-04-17 02:20:36 +04:00
2008-04-25 02:21:22 +04:00
/* Get data SRAM. */
if ( rval = = QLA_SUCCESS )
rval = qla2xxx_dump_ram ( ha , 0x11000 , fw - > data_ram ,
ha - > fw_memory_size - 0x11000 + 1 , & nxt ) ;
2005-04-17 02:20:36 +04:00
2006-06-24 03:10:29 +04:00
if ( rval = = QLA_SUCCESS )
2008-12-10 03:45:39 +03:00
qla2xxx_copy_queues ( ha , nxt ) ;
2006-06-24 03:10:29 +04:00
2009-10-14 02:16:45 +04:00
qla2xxx_dump_post_process ( base_vha , rval ) ;
2005-04-17 02:20:36 +04:00
}
/**
* qla2100_fw_dump ( ) - Dumps binary data from the 2100 / 2200 firmware .
2018-01-24 03:33:51 +03:00
* @ vha : HA context
2005-04-17 02:20:36 +04:00
*/
void
2020-05-19 00:17:00 +03:00
qla2100_fw_dump ( scsi_qla_host_t * vha )
2005-04-17 02:20:36 +04:00
{
int rval ;
uint32_t cnt , timer ;
2020-05-19 00:17:00 +03:00
uint16_t risc_address = 0 ;
uint16_t mb0 = 0 , mb2 = 0 ;
2008-11-06 21:40:19 +03:00
struct qla_hw_data * ha = vha - > hw ;
2005-07-06 21:30:26 +04:00
struct device_reg_2xxx __iomem * reg = & ha - > iobase - > isp ;
2020-05-19 00:17:12 +03:00
__le16 __iomem * dmp_reg ;
2005-04-17 02:20:36 +04:00
struct qla2100_fw_dump * fw ;
2008-12-10 03:45:39 +03:00
struct scsi_qla_host * base_vha = pci_get_drvdata ( ha - > pdev ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:00 +03:00
lockdep_assert_held ( & ha - > hardware_lock ) ;
2005-04-17 02:20:36 +04:00
2006-05-18 02:09:50 +04:00
if ( ! ha - > fw_dump ) {
2011-07-14 23:00:13 +04:00
ql_log ( ql_log_warn , vha , 0xd004 ,
" No buffer available for dump. \n " ) ;
2020-05-19 00:17:00 +03:00
return ;
2005-04-17 02:20:36 +04:00
}
2006-05-18 02:09:50 +04:00
if ( ha - > fw_dumped ) {
2011-07-14 23:00:13 +04:00
ql_log ( ql_log_warn , vha , 0xd005 ,
" Firmware has been previously dumped (%p) "
" -- ignoring request. \n " ,
ha - > fw_dump ) ;
2020-05-19 00:17:00 +03:00
return ;
2005-04-17 02:20:36 +04:00
}
2006-06-24 03:10:29 +04:00
fw = & ha - > fw_dump - > isp . isp21 ;
qla2xxx_prep_dump ( ha , ha - > fw_dump ) ;
2005-04-17 02:20:36 +04:00
rval = QLA_SUCCESS ;
2020-05-19 00:17:08 +03:00
fw - > hccr = htons ( rd_reg_word ( & reg - > hccr ) ) ;
2005-04-17 02:20:36 +04:00
/* Pause RISC. */
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > hccr , HCCR_PAUSE_RISC ) ;
for ( cnt = 30000 ; ( rd_reg_word ( & reg - > hccr ) & HCCR_RISC_PAUSE ) = = 0 & &
2005-04-17 02:20:36 +04:00
rval = = QLA_SUCCESS ; cnt - - ) {
if ( cnt )
udelay ( 100 ) ;
else
rval = QLA_FUNCTION_TIMEOUT ;
}
if ( rval = = QLA_SUCCESS ) {
2007-07-26 22:41:13 +04:00
dmp_reg = & reg - > flash_address ;
2020-04-13 05:13:59 +03:00
for ( cnt = 0 ; cnt < ARRAY_SIZE ( fw - > pbiu_reg ) ; cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
fw - > pbiu_reg [ cnt ] = htons ( rd_reg_word ( dmp_reg ) ) ;
2005-04-17 02:20:36 +04:00
2007-07-26 22:41:13 +04:00
dmp_reg = & reg - > u . isp2100 . mailbox0 ;
2016-01-27 20:03:34 +03:00
for ( cnt = 0 ; cnt < ha - > mbx_count ; cnt + + , dmp_reg + + ) {
2007-07-26 22:41:13 +04:00
if ( cnt = = 8 )
dmp_reg = & reg - > u_end . isp2200 . mailbox8 ;
2020-05-19 00:17:08 +03:00
fw - > mailbox_reg [ cnt ] = htons ( rd_reg_word ( dmp_reg ) ) ;
2005-04-17 02:20:36 +04:00
}
2007-07-26 22:41:13 +04:00
dmp_reg = & reg - > u . isp2100 . unused_2 [ 0 ] ;
2020-04-13 05:13:59 +03:00
for ( cnt = 0 ; cnt < ARRAY_SIZE ( fw - > dma_reg ) ; cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
fw - > dma_reg [ cnt ] = htons ( rd_reg_word ( dmp_reg ) ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > ctrl_status , 0x00 ) ;
2007-07-26 22:41:13 +04:00
dmp_reg = & reg - > risc_hw ;
2020-04-13 05:13:59 +03:00
for ( cnt = 0 ; cnt < ARRAY_SIZE ( fw - > risc_hdw_reg ) ; cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
fw - > risc_hdw_reg [ cnt ] = htons ( rd_reg_word ( dmp_reg ) ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > pcr , 0x2000 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 16 , fw - > risc_gp0_reg ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > pcr , 0x2100 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 16 , fw - > risc_gp1_reg ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > pcr , 0x2200 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 16 , fw - > risc_gp2_reg ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > pcr , 0x2300 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 16 , fw - > risc_gp3_reg ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > pcr , 0x2400 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 16 , fw - > risc_gp4_reg ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > pcr , 0x2500 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 16 , fw - > risc_gp5_reg ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > pcr , 0x2600 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 16 , fw - > risc_gp6_reg ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > pcr , 0x2700 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 16 , fw - > risc_gp7_reg ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > ctrl_status , 0x10 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 16 , fw - > frame_buf_hdw_reg ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > ctrl_status , 0x20 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 64 , fw - > fpm_b0_reg ) ;
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > ctrl_status , 0x30 ) ;
2007-07-26 22:41:13 +04:00
qla2xxx_read_window ( reg , 64 , fw - > fpm_b1_reg ) ;
2005-04-17 02:20:36 +04:00
/* Reset the ISP. */
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > ctrl_status , CSR_ISP_SOFT_RESET ) ;
2005-04-17 02:20:36 +04:00
}
for ( cnt = 30000 ; RD_MAILBOX_REG ( ha , reg , 0 ) ! = 0 & &
rval = = QLA_SUCCESS ; cnt - - ) {
if ( cnt )
udelay ( 100 ) ;
else
rval = QLA_FUNCTION_TIMEOUT ;
}
/* Pause RISC. */
if ( rval = = QLA_SUCCESS & & ( IS_QLA2200 ( ha ) | | ( IS_QLA2100 ( ha ) & &
2020-05-19 00:17:08 +03:00
( rd_reg_word ( & reg - > mctr ) & ( BIT_1 | BIT_0 ) ) ! = 0 ) ) ) {
2005-04-17 02:20:36 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > hccr , HCCR_PAUSE_RISC ) ;
2005-04-17 02:20:36 +04:00
for ( cnt = 30000 ;
2020-05-19 00:17:08 +03:00
( rd_reg_word ( & reg - > hccr ) & HCCR_RISC_PAUSE ) = = 0 & &
2005-04-17 02:20:36 +04:00
rval = = QLA_SUCCESS ; cnt - - ) {
if ( cnt )
udelay ( 100 ) ;
else
rval = QLA_FUNCTION_TIMEOUT ;
}
if ( rval = = QLA_SUCCESS ) {
/* Set memory configuration and timing. */
if ( IS_QLA2100 ( ha ) )
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > mctr , 0xf1 ) ;
2005-04-17 02:20:36 +04:00
else
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > mctr , 0xf2 ) ;
rd_reg_word ( & reg - > mctr ) ; /* PCI Posting. */
2005-04-17 02:20:36 +04:00
/* Release RISC. */
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > hccr , HCCR_RELEASE_RISC ) ;
2005-04-17 02:20:36 +04:00
}
}
if ( rval = = QLA_SUCCESS ) {
/* Get RISC SRAM. */
risc_address = 0x1000 ;
WRT_MAILBOX_REG ( ha , reg , 0 , MBC_READ_RAM_WORD ) ;
clear_bit ( MBX_INTERRUPT , & ha - > mbx_cmd_flags ) ;
}
2020-04-13 05:13:59 +03:00
for ( cnt = 0 ; cnt < ARRAY_SIZE ( fw - > risc_ram ) & & rval = = QLA_SUCCESS ;
2005-04-17 02:20:36 +04:00
cnt + + , risc_address + + ) {
WRT_MAILBOX_REG ( ha , reg , 1 , risc_address ) ;
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > hccr , HCCR_SET_HOST_INT ) ;
2005-04-17 02:20:36 +04:00
for ( timer = 6000000 ; timer ! = 0 ; timer - - ) {
/* Check for pending interrupts. */
2020-05-19 00:17:08 +03:00
if ( rd_reg_word ( & reg - > istatus ) & ISR_RISC_INT ) {
if ( rd_reg_word ( & reg - > semaphore ) & BIT_0 ) {
2005-04-17 02:20:36 +04:00
set_bit ( MBX_INTERRUPT ,
& ha - > mbx_cmd_flags ) ;
mb0 = RD_MAILBOX_REG ( ha , reg , 0 ) ;
mb2 = RD_MAILBOX_REG ( ha , reg , 2 ) ;
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > semaphore , 0 ) ;
wrt_reg_word ( & reg - > hccr ,
2005-04-17 02:20:36 +04:00
HCCR_CLR_RISC_INT ) ;
2020-05-19 00:17:08 +03:00
rd_reg_word ( & reg - > hccr ) ;
2005-04-17 02:20:36 +04:00
break ;
}
2020-05-19 00:17:08 +03:00
wrt_reg_word ( & reg - > hccr , HCCR_CLR_RISC_INT ) ;
rd_reg_word ( & reg - > hccr ) ;
2005-04-17 02:20:36 +04:00
}
udelay ( 5 ) ;
}
if ( test_and_clear_bit ( MBX_INTERRUPT , & ha - > mbx_cmd_flags ) ) {
rval = mb0 & MBS_MASK ;
2006-06-24 03:10:29 +04:00
fw - > risc_ram [ cnt ] = htons ( mb2 ) ;
2005-04-17 02:20:36 +04:00
} else {
rval = QLA_FUNCTION_FAILED ;
}
}
2006-06-24 03:10:29 +04:00
if ( rval = = QLA_SUCCESS )
2020-06-30 01:54:52 +03:00
qla2xxx_copy_queues ( ha , & fw - > queue_dump [ 0 ] ) ;
2006-06-24 03:10:29 +04:00
2009-10-14 02:16:45 +04:00
qla2xxx_dump_post_process ( base_vha , rval ) ;
2005-04-17 02:20:36 +04:00
}
2005-07-06 21:30:36 +04:00
void
2020-05-19 00:17:00 +03:00
qla24xx_fw_dump ( scsi_qla_host_t * vha )
2005-07-06 21:30:36 +04:00
{
int rval ;
2007-07-20 07:37:34 +04:00
uint32_t cnt ;
2008-11-06 21:40:19 +03:00
struct qla_hw_data * ha = vha - > hw ;
2005-07-06 21:30:36 +04:00
struct device_reg_24xx __iomem * reg = & ha - > iobase - > isp24 ;
2020-05-19 00:17:12 +03:00
__le32 __iomem * dmp_reg ;
__be32 * iter_reg ;
__le16 __iomem * mbx_reg ;
2005-07-06 21:30:36 +04:00
struct qla24xx_fw_dump * fw ;
2007-07-20 07:37:34 +04:00
void * nxt ;
2012-05-15 22:34:28 +04:00
void * nxt_chain ;
2020-05-19 00:17:12 +03:00
__be32 * last_chain = NULL ;
2008-12-10 03:45:39 +03:00
struct scsi_qla_host * base_vha = pci_get_drvdata ( ha - > pdev ) ;
2005-07-06 21:30:36 +04:00
2020-05-19 00:17:00 +03:00
lockdep_assert_held ( & ha - > hardware_lock ) ;
2013-08-27 09:37:28 +04:00
if ( IS_P3P_TYPE ( ha ) )
2010-04-13 04:59:55 +04:00
return ;
2014-04-12 00:54:21 +04:00
ha - > fw_dump_cap_flags = 0 ;
2005-07-06 21:30:36 +04:00
2006-05-18 02:09:50 +04:00
if ( ! ha - > fw_dump ) {
2011-07-14 23:00:13 +04:00
ql_log ( ql_log_warn , vha , 0xd006 ,
" No buffer available for dump. \n " ) ;
2020-05-19 00:17:00 +03:00
return ;
2005-07-06 21:30:36 +04:00
}
if ( ha - > fw_dumped ) {
2011-07-14 23:00:13 +04:00
ql_log ( ql_log_warn , vha , 0xd007 ,
" Firmware has been previously dumped (%p) "
" -- ignoring request. \n " ,
ha - > fw_dump ) ;
2020-05-19 00:17:00 +03:00
return ;
2005-07-06 21:30:36 +04:00
}
2018-08-02 23:16:46 +03:00
QLA_FW_STOPPED ( ha ) ;
2006-06-24 03:10:29 +04:00
fw = & ha - > fw_dump - > isp . isp24 ;
qla2xxx_prep_dump ( ha , ha - > fw_dump ) ;
2005-07-06 21:30:36 +04:00
2020-05-19 00:17:08 +03:00
fw - > host_status = htonl ( rd_reg_dword ( & reg - > host_status ) ) ;
2005-07-06 21:30:36 +04:00
2014-04-12 00:54:20 +04:00
/*
* Pause RISC . No need to track timeout , as resetting the chip
* is the right approach incase of pause timeout
*/
2014-04-12 00:54:21 +04:00
qla24xx_pause_risc ( reg , ha ) ;
2007-07-26 22:41:13 +04:00
/* Host interface registers. */
dmp_reg = & reg - > flash_addr ;
2020-04-13 05:13:59 +03:00
for ( cnt = 0 ; cnt < ARRAY_SIZE ( fw - > host_reg ) ; cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
fw - > host_reg [ cnt ] = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2007-07-26 22:41:13 +04:00
/* Disable interrupts. */
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > ictrl , 0 ) ;
rd_reg_dword ( & reg - > ictrl ) ;
2007-07-26 22:41:13 +04:00
/* Shadow registers. */
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_addr , 0x0F70 ) ;
rd_reg_dword ( & reg - > iobase_addr ) ;
wrt_reg_dword ( & reg - > iobase_select , 0xB0000000 ) ;
fw - > shadow_reg [ 0 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2007-07-26 22:41:13 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0100000 ) ;
fw - > shadow_reg [ 1 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2007-07-26 22:41:13 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0200000 ) ;
fw - > shadow_reg [ 2 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2007-07-26 22:41:13 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0300000 ) ;
fw - > shadow_reg [ 3 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2007-07-26 22:41:13 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0400000 ) ;
fw - > shadow_reg [ 4 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2007-07-26 22:41:13 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0500000 ) ;
fw - > shadow_reg [ 5 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2007-07-26 22:41:13 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0600000 ) ;
fw - > shadow_reg [ 6 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2007-07-26 22:41:13 +04:00
/* Mailbox registers. */
mbx_reg = & reg - > mailbox0 ;
2020-04-13 05:13:59 +03:00
for ( cnt = 0 ; cnt < ARRAY_SIZE ( fw - > mailbox_reg ) ; cnt + + , mbx_reg + + )
2020-05-19 00:17:08 +03:00
fw - > mailbox_reg [ cnt ] = htons ( rd_reg_word ( mbx_reg ) ) ;
2007-07-26 22:41:13 +04:00
/* Transfer sequence registers. */
iter_reg = fw - > xseq_gp_reg ;
iter_reg = qla24xx_read_window ( reg , 0xBF00 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF10 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF20 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF30 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF40 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF50 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF60 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xBF70 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xBFE0 , 16 , fw - > xseq_0_reg ) ;
qla24xx_read_window ( reg , 0xBFF0 , 16 , fw - > xseq_1_reg ) ;
/* Receive sequence registers. */
iter_reg = fw - > rseq_gp_reg ;
iter_reg = qla24xx_read_window ( reg , 0xFF00 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF10 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF20 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF30 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF40 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF50 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF60 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xFF70 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xFFD0 , 16 , fw - > rseq_0_reg ) ;
qla24xx_read_window ( reg , 0xFFE0 , 16 , fw - > rseq_1_reg ) ;
qla24xx_read_window ( reg , 0xFFF0 , 16 , fw - > rseq_2_reg ) ;
/* Command DMA registers. */
qla24xx_read_window ( reg , 0x7100 , 16 , fw - > cmd_dma_reg ) ;
/* Queues. */
iter_reg = fw - > req0_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7200 , 8 , iter_reg ) ;
dmp_reg = & reg - > iobase_q ;
2016-01-27 20:03:34 +03:00
for ( cnt = 0 ; cnt < 7 ; cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
* iter_reg + + = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2007-07-26 22:41:13 +04:00
iter_reg = fw - > resp0_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7300 , 8 , iter_reg ) ;
dmp_reg = & reg - > iobase_q ;
2016-01-27 20:03:34 +03:00
for ( cnt = 0 ; cnt < 7 ; cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
* iter_reg + + = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2007-07-26 22:41:13 +04:00
iter_reg = fw - > req1_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7400 , 8 , iter_reg ) ;
dmp_reg = & reg - > iobase_q ;
2016-01-27 20:03:34 +03:00
for ( cnt = 0 ; cnt < 7 ; cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
* iter_reg + + = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2007-07-26 22:41:13 +04:00
/* Transmit DMA registers. */
iter_reg = fw - > xmt0_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7600 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7610 , 16 , iter_reg ) ;
iter_reg = fw - > xmt1_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7620 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7630 , 16 , iter_reg ) ;
iter_reg = fw - > xmt2_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7640 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7650 , 16 , iter_reg ) ;
iter_reg = fw - > xmt3_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7660 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7670 , 16 , iter_reg ) ;
iter_reg = fw - > xmt4_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7680 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7690 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x76A0 , 16 , fw - > xmt_data_dma_reg ) ;
/* Receive DMA registers. */
iter_reg = fw - > rcvt0_data_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7700 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7710 , 16 , iter_reg ) ;
iter_reg = fw - > rcvt1_data_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7720 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7730 , 16 , iter_reg ) ;
/* RISC registers. */
iter_reg = fw - > risc_gp_reg ;
iter_reg = qla24xx_read_window ( reg , 0x0F00 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F10 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F20 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F30 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F40 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F50 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F60 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x0F70 , 16 , iter_reg ) ;
/* Local memory controller registers. */
iter_reg = fw - > lmc_reg ;
iter_reg = qla24xx_read_window ( reg , 0x3000 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3010 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3020 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3030 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3040 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3050 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x3060 , 16 , iter_reg ) ;
/* Fibre Protocol Module registers. */
iter_reg = fw - > fpm_hdw_reg ;
iter_reg = qla24xx_read_window ( reg , 0x4000 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4010 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4020 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4030 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4040 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4050 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4060 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4070 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4080 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4090 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x40A0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x40B0 , 16 , iter_reg ) ;
/* Frame Buffer registers. */
iter_reg = fw - > fb_hdw_reg ;
iter_reg = qla24xx_read_window ( reg , 0x6000 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6010 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6020 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6030 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6040 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6100 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6130 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6150 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6170 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6190 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x61B0 , 16 , iter_reg ) ;
rval = qla24xx_soft_reset ( ha ) ;
if ( rval ! = QLA_SUCCESS )
goto qla24xx_fw_dump_failed_0 ;
rval = qla24xx_dump_memory ( ha , fw - > code_ram , sizeof ( fw - > code_ram ) ,
2008-04-25 02:21:22 +04:00
& nxt ) ;
2007-07-26 22:41:13 +04:00
if ( rval ! = QLA_SUCCESS )
goto qla24xx_fw_dump_failed_0 ;
2008-12-10 03:45:39 +03:00
nxt = qla2xxx_copy_queues ( ha , nxt ) ;
2009-01-05 22:18:08 +03:00
qla24xx_copy_eft ( ha , nxt ) ;
2007-07-26 22:41:13 +04:00
2012-05-15 22:34:28 +04:00
nxt_chain = ( void * ) ha - > fw_dump + ha - > chain_offset ;
nxt_chain = qla2xxx_copy_atioqueues ( ha , nxt_chain , & last_chain ) ;
if ( last_chain ) {
2015-07-09 17:24:08 +03:00
ha - > fw_dump - > version | = htonl ( DUMP_CHAIN_VARIANT ) ;
* last_chain | = htonl ( DUMP_CHAIN_LAST ) ;
2012-05-15 22:34:28 +04:00
}
/* Adjust valid length. */
ha - > fw_dump_len = ( nxt_chain - ( void * ) ha - > fw_dump ) ;
2007-07-26 22:41:13 +04:00
qla24xx_fw_dump_failed_0 :
2009-10-14 02:16:45 +04:00
qla2xxx_dump_post_process ( base_vha , rval ) ;
2007-07-20 07:37:34 +04:00
}
2005-07-06 21:30:36 +04:00
2007-07-20 07:37:34 +04:00
void
2020-05-19 00:17:00 +03:00
qla25xx_fw_dump ( scsi_qla_host_t * vha )
2007-07-20 07:37:34 +04:00
{
int rval ;
uint32_t cnt ;
2008-11-06 21:40:19 +03:00
struct qla_hw_data * ha = vha - > hw ;
2007-07-20 07:37:34 +04:00
struct device_reg_24xx __iomem * reg = & ha - > iobase - > isp24 ;
2020-05-19 00:17:12 +03:00
__le32 __iomem * dmp_reg ;
__be32 * iter_reg ;
__le16 __iomem * mbx_reg ;
2007-07-20 07:37:34 +04:00
struct qla25xx_fw_dump * fw ;
2009-01-05 22:18:09 +03:00
void * nxt , * nxt_chain ;
2020-05-19 00:17:12 +03:00
__be32 * last_chain = NULL ;
2008-12-10 03:45:39 +03:00
struct scsi_qla_host * base_vha = pci_get_drvdata ( ha - > pdev ) ;
2005-07-06 21:30:36 +04:00
2020-05-19 00:17:00 +03:00
lockdep_assert_held ( & ha - > hardware_lock ) ;
2005-07-06 21:30:36 +04:00
2020-05-19 00:17:00 +03:00
ha - > fw_dump_cap_flags = 0 ;
2005-07-06 21:30:36 +04:00
2007-07-20 07:37:34 +04:00
if ( ! ha - > fw_dump ) {
2011-07-14 23:00:13 +04:00
ql_log ( ql_log_warn , vha , 0xd008 ,
" No buffer available for dump. \n " ) ;
2020-05-19 00:17:00 +03:00
return ;
2007-07-20 07:37:34 +04:00
}
2005-07-06 21:30:36 +04:00
2007-07-20 07:37:34 +04:00
if ( ha - > fw_dumped ) {
2011-07-14 23:00:13 +04:00
ql_log ( ql_log_warn , vha , 0xd009 ,
" Firmware has been previously dumped (%p) "
" -- ignoring request. \n " ,
ha - > fw_dump ) ;
2020-05-19 00:17:00 +03:00
return ;
2007-07-20 07:37:34 +04:00
}
2018-08-02 23:16:46 +03:00
QLA_FW_STOPPED ( ha ) ;
2007-07-20 07:37:34 +04:00
fw = & ha - > fw_dump - > isp . isp25 ;
qla2xxx_prep_dump ( ha , ha - > fw_dump ) ;
2015-07-09 17:24:08 +03:00
ha - > fw_dump - > version = htonl ( 2 ) ;
2005-07-06 21:30:36 +04:00
2020-05-19 00:17:08 +03:00
fw - > host_status = htonl ( rd_reg_dword ( & reg - > host_status ) ) ;
2005-07-06 21:30:36 +04:00
2014-04-12 00:54:20 +04:00
/*
* Pause RISC . No need to track timeout , as resetting the chip
* is the right approach incase of pause timeout
*/
2014-04-12 00:54:21 +04:00
qla24xx_pause_risc ( reg , ha ) ;
2007-07-26 22:41:13 +04:00
2007-09-21 01:07:39 +04:00
/* Host/Risc registers. */
iter_reg = fw - > host_risc_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7000 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7010 , 16 , iter_reg ) ;
/* PCIe registers. */
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_addr , 0x7C00 ) ;
rd_reg_dword ( & reg - > iobase_addr ) ;
wrt_reg_dword ( & reg - > iobase_window , 0x01 ) ;
2007-09-21 01:07:39 +04:00
dmp_reg = & reg - > iobase_c4 ;
2020-05-19 00:17:08 +03:00
fw - > pcie_regs [ 0 ] = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2016-01-27 20:03:34 +03:00
dmp_reg + + ;
2020-05-19 00:17:08 +03:00
fw - > pcie_regs [ 1 ] = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2016-01-27 20:03:34 +03:00
dmp_reg + + ;
2020-05-19 00:17:08 +03:00
fw - > pcie_regs [ 2 ] = htonl ( rd_reg_dword ( dmp_reg ) ) ;
fw - > pcie_regs [ 3 ] = htonl ( rd_reg_dword ( & reg - > iobase_window ) ) ;
2008-12-10 03:45:39 +03:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_window , 0x00 ) ;
rd_reg_dword ( & reg - > iobase_window ) ;
2007-09-21 01:07:39 +04:00
2007-07-26 22:41:13 +04:00
/* Host interface registers. */
dmp_reg = & reg - > flash_addr ;
2020-04-13 05:13:59 +03:00
for ( cnt = 0 ; cnt < ARRAY_SIZE ( fw - > host_reg ) ; cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
fw - > host_reg [ cnt ] = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2007-07-26 22:41:13 +04:00
/* Disable interrupts. */
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > ictrl , 0 ) ;
rd_reg_dword ( & reg - > ictrl ) ;
2007-07-26 22:41:13 +04:00
/* Shadow registers. */
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_addr , 0x0F70 ) ;
rd_reg_dword ( & reg - > iobase_addr ) ;
wrt_reg_dword ( & reg - > iobase_select , 0xB0000000 ) ;
fw - > shadow_reg [ 0 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2007-07-26 22:41:13 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0100000 ) ;
fw - > shadow_reg [ 1 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2007-07-26 22:41:13 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0200000 ) ;
fw - > shadow_reg [ 2 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2007-07-26 22:41:13 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0300000 ) ;
fw - > shadow_reg [ 3 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2007-07-26 22:41:13 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0400000 ) ;
fw - > shadow_reg [ 4 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2007-07-26 22:41:13 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0500000 ) ;
fw - > shadow_reg [ 5 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2007-07-26 22:41:13 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0600000 ) ;
fw - > shadow_reg [ 6 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2007-07-26 22:41:13 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0700000 ) ;
fw - > shadow_reg [ 7 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2007-07-26 22:41:13 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0800000 ) ;
fw - > shadow_reg [ 8 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2007-07-26 22:41:13 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0900000 ) ;
fw - > shadow_reg [ 9 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2007-07-26 22:41:13 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0A00000 ) ;
fw - > shadow_reg [ 10 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2007-07-26 22:41:13 +04:00
/* RISC I/O register. */
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_addr , 0x0010 ) ;
fw - > risc_io_reg = htonl ( rd_reg_dword ( & reg - > iobase_window ) ) ;
2007-07-26 22:41:13 +04:00
/* Mailbox registers. */
mbx_reg = & reg - > mailbox0 ;
2020-04-13 05:13:59 +03:00
for ( cnt = 0 ; cnt < ARRAY_SIZE ( fw - > mailbox_reg ) ; cnt + + , mbx_reg + + )
2020-05-19 00:17:08 +03:00
fw - > mailbox_reg [ cnt ] = htons ( rd_reg_word ( mbx_reg ) ) ;
2007-07-26 22:41:13 +04:00
/* Transfer sequence registers. */
iter_reg = fw - > xseq_gp_reg ;
iter_reg = qla24xx_read_window ( reg , 0xBF00 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF10 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF20 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF30 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF40 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF50 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF60 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xBF70 , 16 , iter_reg ) ;
iter_reg = fw - > xseq_0_reg ;
iter_reg = qla24xx_read_window ( reg , 0xBFC0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBFD0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xBFE0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xBFF0 , 16 , fw - > xseq_1_reg ) ;
/* Receive sequence registers. */
iter_reg = fw - > rseq_gp_reg ;
iter_reg = qla24xx_read_window ( reg , 0xFF00 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF10 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF20 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF30 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF40 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF50 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF60 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xFF70 , 16 , iter_reg ) ;
iter_reg = fw - > rseq_0_reg ;
iter_reg = qla24xx_read_window ( reg , 0xFFC0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xFFD0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xFFE0 , 16 , fw - > rseq_1_reg ) ;
qla24xx_read_window ( reg , 0xFFF0 , 16 , fw - > rseq_2_reg ) ;
/* Auxiliary sequence registers. */
iter_reg = fw - > aseq_gp_reg ;
iter_reg = qla24xx_read_window ( reg , 0xB000 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB010 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB020 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB030 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB040 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB050 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB060 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xB070 , 16 , iter_reg ) ;
iter_reg = fw - > aseq_0_reg ;
iter_reg = qla24xx_read_window ( reg , 0xB0C0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xB0D0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xB0E0 , 16 , fw - > aseq_1_reg ) ;
qla24xx_read_window ( reg , 0xB0F0 , 16 , fw - > aseq_2_reg ) ;
/* Command DMA registers. */
qla24xx_read_window ( reg , 0x7100 , 16 , fw - > cmd_dma_reg ) ;
/* Queues. */
iter_reg = fw - > req0_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7200 , 8 , iter_reg ) ;
dmp_reg = & reg - > iobase_q ;
2016-01-27 20:03:34 +03:00
for ( cnt = 0 ; cnt < 7 ; cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
* iter_reg + + = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2007-07-26 22:41:13 +04:00
iter_reg = fw - > resp0_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7300 , 8 , iter_reg ) ;
dmp_reg = & reg - > iobase_q ;
2016-01-27 20:03:34 +03:00
for ( cnt = 0 ; cnt < 7 ; cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
* iter_reg + + = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2007-07-26 22:41:13 +04:00
iter_reg = fw - > req1_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7400 , 8 , iter_reg ) ;
dmp_reg = & reg - > iobase_q ;
2016-01-27 20:03:34 +03:00
for ( cnt = 0 ; cnt < 7 ; cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
* iter_reg + + = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2007-07-26 22:41:13 +04:00
/* Transmit DMA registers. */
iter_reg = fw - > xmt0_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7600 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7610 , 16 , iter_reg ) ;
iter_reg = fw - > xmt1_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7620 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7630 , 16 , iter_reg ) ;
iter_reg = fw - > xmt2_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7640 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7650 , 16 , iter_reg ) ;
iter_reg = fw - > xmt3_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7660 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7670 , 16 , iter_reg ) ;
iter_reg = fw - > xmt4_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7680 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7690 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x76A0 , 16 , fw - > xmt_data_dma_reg ) ;
/* Receive DMA registers. */
iter_reg = fw - > rcvt0_data_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7700 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7710 , 16 , iter_reg ) ;
iter_reg = fw - > rcvt1_data_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7720 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7730 , 16 , iter_reg ) ;
/* RISC registers. */
iter_reg = fw - > risc_gp_reg ;
iter_reg = qla24xx_read_window ( reg , 0x0F00 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F10 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F20 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F30 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F40 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F50 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F60 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x0F70 , 16 , iter_reg ) ;
/* Local memory controller registers. */
iter_reg = fw - > lmc_reg ;
iter_reg = qla24xx_read_window ( reg , 0x3000 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3010 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3020 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3030 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3040 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3050 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3060 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x3070 , 16 , iter_reg ) ;
/* Fibre Protocol Module registers. */
iter_reg = fw - > fpm_hdw_reg ;
iter_reg = qla24xx_read_window ( reg , 0x4000 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4010 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4020 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4030 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4040 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4050 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4060 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4070 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4080 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4090 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x40A0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x40B0 , 16 , iter_reg ) ;
/* Frame Buffer registers. */
iter_reg = fw - > fb_hdw_reg ;
iter_reg = qla24xx_read_window ( reg , 0x6000 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6010 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6020 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6030 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6040 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6100 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6130 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6150 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6170 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6190 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x61B0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x6F00 , 16 , iter_reg ) ;
2009-01-05 22:18:09 +03:00
/* Multi queue registers */
nxt_chain = qla25xx_copy_mq ( ha , ( void * ) ha - > fw_dump + ha - > chain_offset ,
& last_chain ) ;
2007-07-26 22:41:13 +04:00
rval = qla24xx_soft_reset ( ha ) ;
if ( rval ! = QLA_SUCCESS )
goto qla25xx_fw_dump_failed_0 ;
rval = qla24xx_dump_memory ( ha , fw - > code_ram , sizeof ( fw - > code_ram ) ,
2008-04-25 02:21:22 +04:00
& nxt ) ;
2007-07-26 22:41:13 +04:00
if ( rval ! = QLA_SUCCESS )
goto qla25xx_fw_dump_failed_0 ;
2008-12-10 03:45:39 +03:00
nxt = qla2xxx_copy_queues ( ha , nxt ) ;
2007-07-26 22:41:13 +04:00
2013-06-25 19:27:27 +04:00
qla24xx_copy_eft ( ha , nxt ) ;
2008-01-17 20:02:17 +03:00
2009-01-05 22:18:09 +03:00
/* Chain entries -- started with MQ. */
2012-02-09 23:15:33 +04:00
nxt_chain = qla25xx_copy_fce ( ha , nxt_chain , & last_chain ) ;
nxt_chain = qla25xx_copy_mqueues ( ha , nxt_chain , & last_chain ) ;
2012-05-15 22:34:28 +04:00
nxt_chain = qla2xxx_copy_atioqueues ( ha , nxt_chain , & last_chain ) ;
2017-06-14 06:47:29 +03:00
nxt_chain = qla25xx_copy_exlogin ( ha , nxt_chain , & last_chain ) ;
2009-01-05 22:18:08 +03:00
if ( last_chain ) {
2015-07-09 17:24:08 +03:00
ha - > fw_dump - > version | = htonl ( DUMP_CHAIN_VARIANT ) ;
* last_chain | = htonl ( DUMP_CHAIN_LAST ) ;
2009-01-05 22:18:08 +03:00
}
2008-01-17 20:02:17 +03:00
2012-02-09 23:15:33 +04:00
/* Adjust valid length. */
ha - > fw_dump_len = ( nxt_chain - ( void * ) ha - > fw_dump ) ;
2007-07-26 22:41:13 +04:00
qla25xx_fw_dump_failed_0 :
2009-10-14 02:16:45 +04:00
qla2xxx_dump_post_process ( base_vha , rval ) ;
2005-07-06 21:30:36 +04:00
}
2009-01-05 22:18:11 +03:00
void
2020-05-19 00:17:00 +03:00
qla81xx_fw_dump ( scsi_qla_host_t * vha )
2009-01-05 22:18:11 +03:00
{
int rval ;
uint32_t cnt ;
struct qla_hw_data * ha = vha - > hw ;
struct device_reg_24xx __iomem * reg = & ha - > iobase - > isp24 ;
2020-05-19 00:17:12 +03:00
__le32 __iomem * dmp_reg ;
__be32 * iter_reg ;
__le16 __iomem * mbx_reg ;
2009-01-05 22:18:11 +03:00
struct qla81xx_fw_dump * fw ;
void * nxt , * nxt_chain ;
2020-05-19 00:17:12 +03:00
__be32 * last_chain = NULL ;
2009-01-05 22:18:11 +03:00
struct scsi_qla_host * base_vha = pci_get_drvdata ( ha - > pdev ) ;
2020-05-19 00:17:00 +03:00
lockdep_assert_held ( & ha - > hardware_lock ) ;
2009-01-05 22:18:11 +03:00
2020-05-19 00:17:00 +03:00
ha - > fw_dump_cap_flags = 0 ;
2009-01-05 22:18:11 +03:00
if ( ! ha - > fw_dump ) {
2011-07-14 23:00:13 +04:00
ql_log ( ql_log_warn , vha , 0xd00a ,
" No buffer available for dump. \n " ) ;
2020-05-19 00:17:00 +03:00
return ;
2009-01-05 22:18:11 +03:00
}
if ( ha - > fw_dumped ) {
2011-07-14 23:00:13 +04:00
ql_log ( ql_log_warn , vha , 0xd00b ,
" Firmware has been previously dumped (%p) "
" -- ignoring request. \n " ,
ha - > fw_dump ) ;
2020-05-19 00:17:00 +03:00
return ;
2009-01-05 22:18:11 +03:00
}
fw = & ha - > fw_dump - > isp . isp81 ;
qla2xxx_prep_dump ( ha , ha - > fw_dump ) ;
2020-05-19 00:17:08 +03:00
fw - > host_status = htonl ( rd_reg_dword ( & reg - > host_status ) ) ;
2009-01-05 22:18:11 +03:00
2014-04-12 00:54:20 +04:00
/*
* Pause RISC . No need to track timeout , as resetting the chip
* is the right approach incase of pause timeout
*/
2014-04-12 00:54:21 +04:00
qla24xx_pause_risc ( reg , ha ) ;
2009-01-05 22:18:11 +03:00
/* Host/Risc registers. */
iter_reg = fw - > host_risc_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7000 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7010 , 16 , iter_reg ) ;
/* PCIe registers. */
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_addr , 0x7C00 ) ;
rd_reg_dword ( & reg - > iobase_addr ) ;
wrt_reg_dword ( & reg - > iobase_window , 0x01 ) ;
2009-01-05 22:18:11 +03:00
dmp_reg = & reg - > iobase_c4 ;
2020-05-19 00:17:08 +03:00
fw - > pcie_regs [ 0 ] = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2016-01-27 20:03:34 +03:00
dmp_reg + + ;
2020-05-19 00:17:08 +03:00
fw - > pcie_regs [ 1 ] = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2016-01-27 20:03:34 +03:00
dmp_reg + + ;
2020-05-19 00:17:08 +03:00
fw - > pcie_regs [ 2 ] = htonl ( rd_reg_dword ( dmp_reg ) ) ;
fw - > pcie_regs [ 3 ] = htonl ( rd_reg_dword ( & reg - > iobase_window ) ) ;
2009-01-05 22:18:11 +03:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_window , 0x00 ) ;
rd_reg_dword ( & reg - > iobase_window ) ;
2009-01-05 22:18:11 +03:00
/* Host interface registers. */
dmp_reg = & reg - > flash_addr ;
2020-04-13 05:13:59 +03:00
for ( cnt = 0 ; cnt < ARRAY_SIZE ( fw - > host_reg ) ; cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
fw - > host_reg [ cnt ] = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2009-01-05 22:18:11 +03:00
/* Disable interrupts. */
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > ictrl , 0 ) ;
rd_reg_dword ( & reg - > ictrl ) ;
2009-01-05 22:18:11 +03:00
/* Shadow registers. */
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_addr , 0x0F70 ) ;
rd_reg_dword ( & reg - > iobase_addr ) ;
wrt_reg_dword ( & reg - > iobase_select , 0xB0000000 ) ;
fw - > shadow_reg [ 0 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2009-01-05 22:18:11 +03:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0100000 ) ;
fw - > shadow_reg [ 1 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2009-01-05 22:18:11 +03:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0200000 ) ;
fw - > shadow_reg [ 2 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2009-01-05 22:18:11 +03:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0300000 ) ;
fw - > shadow_reg [ 3 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2009-01-05 22:18:11 +03:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0400000 ) ;
fw - > shadow_reg [ 4 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2009-01-05 22:18:11 +03:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0500000 ) ;
fw - > shadow_reg [ 5 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2009-01-05 22:18:11 +03:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0600000 ) ;
fw - > shadow_reg [ 6 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2009-01-05 22:18:11 +03:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0700000 ) ;
fw - > shadow_reg [ 7 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2009-01-05 22:18:11 +03:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0800000 ) ;
fw - > shadow_reg [ 8 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2009-01-05 22:18:11 +03:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0900000 ) ;
fw - > shadow_reg [ 9 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2009-01-05 22:18:11 +03:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0A00000 ) ;
fw - > shadow_reg [ 10 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2009-01-05 22:18:11 +03:00
/* RISC I/O register. */
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_addr , 0x0010 ) ;
fw - > risc_io_reg = htonl ( rd_reg_dword ( & reg - > iobase_window ) ) ;
2009-01-05 22:18:11 +03:00
/* Mailbox registers. */
mbx_reg = & reg - > mailbox0 ;
2020-04-13 05:13:59 +03:00
for ( cnt = 0 ; cnt < ARRAY_SIZE ( fw - > mailbox_reg ) ; cnt + + , mbx_reg + + )
2020-05-19 00:17:08 +03:00
fw - > mailbox_reg [ cnt ] = htons ( rd_reg_word ( mbx_reg ) ) ;
2009-01-05 22:18:11 +03:00
/* Transfer sequence registers. */
iter_reg = fw - > xseq_gp_reg ;
iter_reg = qla24xx_read_window ( reg , 0xBF00 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF10 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF20 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF30 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF40 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF50 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF60 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xBF70 , 16 , iter_reg ) ;
iter_reg = fw - > xseq_0_reg ;
iter_reg = qla24xx_read_window ( reg , 0xBFC0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBFD0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xBFE0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xBFF0 , 16 , fw - > xseq_1_reg ) ;
/* Receive sequence registers. */
iter_reg = fw - > rseq_gp_reg ;
iter_reg = qla24xx_read_window ( reg , 0xFF00 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF10 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF20 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF30 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF40 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF50 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF60 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xFF70 , 16 , iter_reg ) ;
iter_reg = fw - > rseq_0_reg ;
iter_reg = qla24xx_read_window ( reg , 0xFFC0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xFFD0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xFFE0 , 16 , fw - > rseq_1_reg ) ;
qla24xx_read_window ( reg , 0xFFF0 , 16 , fw - > rseq_2_reg ) ;
/* Auxiliary sequence registers. */
iter_reg = fw - > aseq_gp_reg ;
iter_reg = qla24xx_read_window ( reg , 0xB000 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB010 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB020 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB030 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB040 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB050 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB060 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xB070 , 16 , iter_reg ) ;
iter_reg = fw - > aseq_0_reg ;
iter_reg = qla24xx_read_window ( reg , 0xB0C0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xB0D0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xB0E0 , 16 , fw - > aseq_1_reg ) ;
qla24xx_read_window ( reg , 0xB0F0 , 16 , fw - > aseq_2_reg ) ;
/* Command DMA registers. */
qla24xx_read_window ( reg , 0x7100 , 16 , fw - > cmd_dma_reg ) ;
/* Queues. */
iter_reg = fw - > req0_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7200 , 8 , iter_reg ) ;
dmp_reg = & reg - > iobase_q ;
2016-01-27 20:03:34 +03:00
for ( cnt = 0 ; cnt < 7 ; cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
* iter_reg + + = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2009-01-05 22:18:11 +03:00
iter_reg = fw - > resp0_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7300 , 8 , iter_reg ) ;
dmp_reg = & reg - > iobase_q ;
2016-01-27 20:03:34 +03:00
for ( cnt = 0 ; cnt < 7 ; cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
* iter_reg + + = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2009-01-05 22:18:11 +03:00
iter_reg = fw - > req1_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7400 , 8 , iter_reg ) ;
dmp_reg = & reg - > iobase_q ;
2016-01-27 20:03:34 +03:00
for ( cnt = 0 ; cnt < 7 ; cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
* iter_reg + + = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2009-01-05 22:18:11 +03:00
/* Transmit DMA registers. */
iter_reg = fw - > xmt0_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7600 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7610 , 16 , iter_reg ) ;
iter_reg = fw - > xmt1_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7620 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7630 , 16 , iter_reg ) ;
iter_reg = fw - > xmt2_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7640 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7650 , 16 , iter_reg ) ;
iter_reg = fw - > xmt3_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7660 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7670 , 16 , iter_reg ) ;
iter_reg = fw - > xmt4_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7680 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7690 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x76A0 , 16 , fw - > xmt_data_dma_reg ) ;
/* Receive DMA registers. */
iter_reg = fw - > rcvt0_data_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7700 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7710 , 16 , iter_reg ) ;
iter_reg = fw - > rcvt1_data_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7720 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7730 , 16 , iter_reg ) ;
/* RISC registers. */
iter_reg = fw - > risc_gp_reg ;
iter_reg = qla24xx_read_window ( reg , 0x0F00 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F10 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F20 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F30 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F40 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F50 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F60 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x0F70 , 16 , iter_reg ) ;
/* Local memory controller registers. */
iter_reg = fw - > lmc_reg ;
iter_reg = qla24xx_read_window ( reg , 0x3000 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3010 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3020 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3030 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3040 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3050 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3060 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x3070 , 16 , iter_reg ) ;
/* Fibre Protocol Module registers. */
iter_reg = fw - > fpm_hdw_reg ;
iter_reg = qla24xx_read_window ( reg , 0x4000 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4010 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4020 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4030 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4040 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4050 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4060 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4070 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4080 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4090 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x40A0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x40B0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x40C0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x40D0 , 16 , iter_reg ) ;
/* Frame Buffer registers. */
iter_reg = fw - > fb_hdw_reg ;
iter_reg = qla24xx_read_window ( reg , 0x6000 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6010 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6020 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6030 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6040 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6100 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6130 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6150 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6170 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6190 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x61B0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x61C0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x6F00 , 16 , iter_reg ) ;
/* Multi queue registers */
nxt_chain = qla25xx_copy_mq ( ha , ( void * ) ha - > fw_dump + ha - > chain_offset ,
& last_chain ) ;
rval = qla24xx_soft_reset ( ha ) ;
if ( rval ! = QLA_SUCCESS )
goto qla81xx_fw_dump_failed_0 ;
rval = qla24xx_dump_memory ( ha , fw - > code_ram , sizeof ( fw - > code_ram ) ,
& nxt ) ;
if ( rval ! = QLA_SUCCESS )
goto qla81xx_fw_dump_failed_0 ;
nxt = qla2xxx_copy_queues ( ha , nxt ) ;
2013-06-25 19:27:27 +04:00
qla24xx_copy_eft ( ha , nxt ) ;
2009-01-05 22:18:11 +03:00
/* Chain entries -- started with MQ. */
2012-02-09 23:15:33 +04:00
nxt_chain = qla25xx_copy_fce ( ha , nxt_chain , & last_chain ) ;
nxt_chain = qla25xx_copy_mqueues ( ha , nxt_chain , & last_chain ) ;
2012-05-15 22:34:28 +04:00
nxt_chain = qla2xxx_copy_atioqueues ( ha , nxt_chain , & last_chain ) ;
2017-06-14 06:47:29 +03:00
nxt_chain = qla25xx_copy_exlogin ( ha , nxt_chain , & last_chain ) ;
nxt_chain = qla81xx_copy_exchoffld ( ha , nxt_chain , & last_chain ) ;
2009-01-05 22:18:11 +03:00
if ( last_chain ) {
2015-07-09 17:24:08 +03:00
ha - > fw_dump - > version | = htonl ( DUMP_CHAIN_VARIANT ) ;
* last_chain | = htonl ( DUMP_CHAIN_LAST ) ;
2009-01-05 22:18:11 +03:00
}
2012-02-09 23:15:33 +04:00
/* Adjust valid length. */
ha - > fw_dump_len = ( nxt_chain - ( void * ) ha - > fw_dump ) ;
2009-01-05 22:18:11 +03:00
qla81xx_fw_dump_failed_0 :
2009-10-14 02:16:45 +04:00
qla2xxx_dump_post_process ( base_vha , rval ) ;
2009-01-05 22:18:11 +03:00
}
2012-02-09 23:15:34 +04:00
void
2020-05-19 00:17:00 +03:00
qla83xx_fw_dump ( scsi_qla_host_t * vha )
2012-02-09 23:15:34 +04:00
{
int rval ;
2015-07-09 17:23:26 +03:00
uint32_t cnt ;
2012-02-09 23:15:34 +04:00
struct qla_hw_data * ha = vha - > hw ;
struct device_reg_24xx __iomem * reg = & ha - > iobase - > isp24 ;
2020-05-19 00:17:12 +03:00
__le32 __iomem * dmp_reg ;
__be32 * iter_reg ;
__le16 __iomem * mbx_reg ;
2012-02-09 23:15:34 +04:00
struct qla83xx_fw_dump * fw ;
void * nxt , * nxt_chain ;
2020-05-19 00:17:12 +03:00
__be32 * last_chain = NULL ;
2012-02-09 23:15:34 +04:00
struct scsi_qla_host * base_vha = pci_get_drvdata ( ha - > pdev ) ;
2020-05-19 00:17:00 +03:00
lockdep_assert_held ( & ha - > hardware_lock ) ;
2012-02-09 23:15:34 +04:00
2020-05-19 00:17:00 +03:00
ha - > fw_dump_cap_flags = 0 ;
2012-02-09 23:15:34 +04:00
if ( ! ha - > fw_dump ) {
ql_log ( ql_log_warn , vha , 0xd00c ,
" No buffer available for dump!!! \n " ) ;
2020-05-19 00:17:00 +03:00
return ;
2012-02-09 23:15:34 +04:00
}
if ( ha - > fw_dumped ) {
ql_log ( ql_log_warn , vha , 0xd00d ,
" Firmware has been previously dumped (%p) -- ignoring "
" request... \n " , ha - > fw_dump ) ;
2020-05-19 00:17:00 +03:00
return ;
2012-02-09 23:15:34 +04:00
}
2018-08-02 23:16:46 +03:00
QLA_FW_STOPPED ( ha ) ;
2012-02-09 23:15:34 +04:00
fw = & ha - > fw_dump - > isp . isp83 ;
qla2xxx_prep_dump ( ha , ha - > fw_dump ) ;
2020-05-19 00:17:08 +03:00
fw - > host_status = htonl ( rd_reg_dword ( & reg - > host_status ) ) ;
2012-02-09 23:15:34 +04:00
2014-04-12 00:54:20 +04:00
/*
* Pause RISC . No need to track timeout , as resetting the chip
* is the right approach incase of pause timeout
*/
2014-04-12 00:54:21 +04:00
qla24xx_pause_risc ( reg , ha ) ;
2012-02-09 23:15:34 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_addr , 0x6000 ) ;
2012-02-09 23:15:34 +04:00
dmp_reg = & reg - > iobase_window ;
2020-05-19 00:17:08 +03:00
rd_reg_dword ( dmp_reg ) ;
wrt_reg_dword ( dmp_reg , 0 ) ;
2012-02-09 23:15:34 +04:00
dmp_reg = & reg - > unused_4_1 [ 0 ] ;
2020-05-19 00:17:08 +03:00
rd_reg_dword ( dmp_reg ) ;
wrt_reg_dword ( dmp_reg , 0 ) ;
2012-02-09 23:15:34 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_addr , 0x6010 ) ;
2012-02-09 23:15:34 +04:00
dmp_reg = & reg - > unused_4_1 [ 2 ] ;
2020-05-19 00:17:08 +03:00
rd_reg_dword ( dmp_reg ) ;
wrt_reg_dword ( dmp_reg , 0 ) ;
2012-02-09 23:15:34 +04:00
/* select PCR and disable ecc checking and correction */
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_addr , 0x0F70 ) ;
rd_reg_dword ( & reg - > iobase_addr ) ;
wrt_reg_dword ( & reg - > iobase_select , 0x60000000 ) ; /* write to F0h = PCR */
2012-02-09 23:15:34 +04:00
/* Host/Risc registers. */
iter_reg = fw - > host_risc_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7000 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x7010 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7040 , 16 , iter_reg ) ;
/* PCIe registers. */
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_addr , 0x7C00 ) ;
rd_reg_dword ( & reg - > iobase_addr ) ;
wrt_reg_dword ( & reg - > iobase_window , 0x01 ) ;
2012-02-09 23:15:34 +04:00
dmp_reg = & reg - > iobase_c4 ;
2020-05-19 00:17:08 +03:00
fw - > pcie_regs [ 0 ] = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2016-01-27 20:03:34 +03:00
dmp_reg + + ;
2020-05-19 00:17:08 +03:00
fw - > pcie_regs [ 1 ] = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2016-01-27 20:03:34 +03:00
dmp_reg + + ;
2020-05-19 00:17:08 +03:00
fw - > pcie_regs [ 2 ] = htonl ( rd_reg_dword ( dmp_reg ) ) ;
fw - > pcie_regs [ 3 ] = htonl ( rd_reg_dword ( & reg - > iobase_window ) ) ;
2012-02-09 23:15:34 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_window , 0x00 ) ;
rd_reg_dword ( & reg - > iobase_window ) ;
2012-02-09 23:15:34 +04:00
/* Host interface registers. */
dmp_reg = & reg - > flash_addr ;
2020-04-13 05:13:59 +03:00
for ( cnt = 0 ; cnt < ARRAY_SIZE ( fw - > host_reg ) ; cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
fw - > host_reg [ cnt ] = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2012-02-09 23:15:34 +04:00
/* Disable interrupts. */
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > ictrl , 0 ) ;
rd_reg_dword ( & reg - > ictrl ) ;
2012-02-09 23:15:34 +04:00
/* Shadow registers. */
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_addr , 0x0F70 ) ;
rd_reg_dword ( & reg - > iobase_addr ) ;
wrt_reg_dword ( & reg - > iobase_select , 0xB0000000 ) ;
fw - > shadow_reg [ 0 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2012-02-09 23:15:34 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0100000 ) ;
fw - > shadow_reg [ 1 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2012-02-09 23:15:34 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0200000 ) ;
fw - > shadow_reg [ 2 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2012-02-09 23:15:34 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0300000 ) ;
fw - > shadow_reg [ 3 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2012-02-09 23:15:34 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0400000 ) ;
fw - > shadow_reg [ 4 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2012-02-09 23:15:34 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0500000 ) ;
fw - > shadow_reg [ 5 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2012-02-09 23:15:34 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0600000 ) ;
fw - > shadow_reg [ 6 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2012-02-09 23:15:34 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0700000 ) ;
fw - > shadow_reg [ 7 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2012-02-09 23:15:34 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0800000 ) ;
fw - > shadow_reg [ 8 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2012-02-09 23:15:34 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0900000 ) ;
fw - > shadow_reg [ 9 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2012-02-09 23:15:34 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_select , 0xB0A00000 ) ;
fw - > shadow_reg [ 10 ] = htonl ( rd_reg_dword ( & reg - > iobase_sdata ) ) ;
2012-02-09 23:15:34 +04:00
/* RISC I/O register. */
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > iobase_addr , 0x0010 ) ;
fw - > risc_io_reg = htonl ( rd_reg_dword ( & reg - > iobase_window ) ) ;
2012-02-09 23:15:34 +04:00
/* Mailbox registers. */
mbx_reg = & reg - > mailbox0 ;
2020-04-13 05:13:59 +03:00
for ( cnt = 0 ; cnt < ARRAY_SIZE ( fw - > mailbox_reg ) ; cnt + + , mbx_reg + + )
2020-05-19 00:17:08 +03:00
fw - > mailbox_reg [ cnt ] = htons ( rd_reg_word ( mbx_reg ) ) ;
2012-02-09 23:15:34 +04:00
/* Transfer sequence registers. */
iter_reg = fw - > xseq_gp_reg ;
iter_reg = qla24xx_read_window ( reg , 0xBE00 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBE10 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBE20 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBE30 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBE40 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBE50 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBE60 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBE70 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF00 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF10 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF20 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF30 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF40 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF50 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBF60 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xBF70 , 16 , iter_reg ) ;
iter_reg = fw - > xseq_0_reg ;
iter_reg = qla24xx_read_window ( reg , 0xBFC0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xBFD0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xBFE0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xBFF0 , 16 , fw - > xseq_1_reg ) ;
qla24xx_read_window ( reg , 0xBEF0 , 16 , fw - > xseq_2_reg ) ;
/* Receive sequence registers. */
iter_reg = fw - > rseq_gp_reg ;
iter_reg = qla24xx_read_window ( reg , 0xFE00 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFE10 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFE20 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFE30 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFE40 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFE50 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFE60 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFE70 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF00 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF10 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF20 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF30 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF40 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF50 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xFF60 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xFF70 , 16 , iter_reg ) ;
iter_reg = fw - > rseq_0_reg ;
iter_reg = qla24xx_read_window ( reg , 0xFFC0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xFFD0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xFFE0 , 16 , fw - > rseq_1_reg ) ;
qla24xx_read_window ( reg , 0xFFF0 , 16 , fw - > rseq_2_reg ) ;
qla24xx_read_window ( reg , 0xFEF0 , 16 , fw - > rseq_3_reg ) ;
/* Auxiliary sequence registers. */
iter_reg = fw - > aseq_gp_reg ;
iter_reg = qla24xx_read_window ( reg , 0xB000 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB010 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB020 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB030 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB040 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB050 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB060 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB070 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB100 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB110 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB120 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB130 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB140 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB150 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0xB160 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xB170 , 16 , iter_reg ) ;
iter_reg = fw - > aseq_0_reg ;
iter_reg = qla24xx_read_window ( reg , 0xB0C0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xB0D0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0xB0E0 , 16 , fw - > aseq_1_reg ) ;
qla24xx_read_window ( reg , 0xB0F0 , 16 , fw - > aseq_2_reg ) ;
qla24xx_read_window ( reg , 0xB1F0 , 16 , fw - > aseq_3_reg ) ;
/* Command DMA registers. */
iter_reg = fw - > cmd_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7100 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x7120 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x7130 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x71F0 , 16 , iter_reg ) ;
/* Queues. */
iter_reg = fw - > req0_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7200 , 8 , iter_reg ) ;
dmp_reg = & reg - > iobase_q ;
2016-01-27 20:03:34 +03:00
for ( cnt = 0 ; cnt < 7 ; cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
* iter_reg + + = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2012-02-09 23:15:34 +04:00
iter_reg = fw - > resp0_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7300 , 8 , iter_reg ) ;
dmp_reg = & reg - > iobase_q ;
2016-01-27 20:03:34 +03:00
for ( cnt = 0 ; cnt < 7 ; cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
* iter_reg + + = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2012-02-09 23:15:34 +04:00
iter_reg = fw - > req1_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7400 , 8 , iter_reg ) ;
dmp_reg = & reg - > iobase_q ;
2016-01-27 20:03:34 +03:00
for ( cnt = 0 ; cnt < 7 ; cnt + + , dmp_reg + + )
2020-05-19 00:17:08 +03:00
* iter_reg + + = htonl ( rd_reg_dword ( dmp_reg ) ) ;
2012-02-09 23:15:34 +04:00
/* Transmit DMA registers. */
iter_reg = fw - > xmt0_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7600 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7610 , 16 , iter_reg ) ;
iter_reg = fw - > xmt1_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7620 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7630 , 16 , iter_reg ) ;
iter_reg = fw - > xmt2_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7640 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7650 , 16 , iter_reg ) ;
iter_reg = fw - > xmt3_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7660 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7670 , 16 , iter_reg ) ;
iter_reg = fw - > xmt4_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7680 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7690 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x76A0 , 16 , fw - > xmt_data_dma_reg ) ;
/* Receive DMA registers. */
iter_reg = fw - > rcvt0_data_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7700 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7710 , 16 , iter_reg ) ;
iter_reg = fw - > rcvt1_data_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7720 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x7730 , 16 , iter_reg ) ;
/* RISC registers. */
iter_reg = fw - > risc_gp_reg ;
iter_reg = qla24xx_read_window ( reg , 0x0F00 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F10 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F20 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F30 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F40 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F50 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x0F60 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x0F70 , 16 , iter_reg ) ;
/* Local memory controller registers. */
iter_reg = fw - > lmc_reg ;
iter_reg = qla24xx_read_window ( reg , 0x3000 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3010 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3020 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3030 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3040 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3050 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x3060 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x3070 , 16 , iter_reg ) ;
/* Fibre Protocol Module registers. */
iter_reg = fw - > fpm_hdw_reg ;
iter_reg = qla24xx_read_window ( reg , 0x4000 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4010 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4020 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4030 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4040 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4050 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4060 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4070 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4080 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x4090 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x40A0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x40B0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x40C0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x40D0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x40E0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x40F0 , 16 , iter_reg ) ;
/* RQ0 Array registers. */
iter_reg = fw - > rq0_array_reg ;
iter_reg = qla24xx_read_window ( reg , 0x5C00 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5C10 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5C20 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5C30 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5C40 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5C50 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5C60 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5C70 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5C80 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5C90 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5CA0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5CB0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5CC0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5CD0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5CE0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x5CF0 , 16 , iter_reg ) ;
/* RQ1 Array registers. */
iter_reg = fw - > rq1_array_reg ;
iter_reg = qla24xx_read_window ( reg , 0x5D00 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5D10 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5D20 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5D30 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5D40 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5D50 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5D60 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5D70 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5D80 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5D90 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5DA0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5DB0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5DC0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5DD0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5DE0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x5DF0 , 16 , iter_reg ) ;
/* RP0 Array registers. */
iter_reg = fw - > rp0_array_reg ;
iter_reg = qla24xx_read_window ( reg , 0x5E00 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5E10 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5E20 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5E30 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5E40 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5E50 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5E60 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5E70 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5E80 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5E90 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5EA0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5EB0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5EC0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5ED0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5EE0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x5EF0 , 16 , iter_reg ) ;
/* RP1 Array registers. */
iter_reg = fw - > rp1_array_reg ;
iter_reg = qla24xx_read_window ( reg , 0x5F00 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5F10 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5F20 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5F30 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5F40 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5F50 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5F60 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5F70 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5F80 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5F90 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5FA0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5FB0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5FC0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5FD0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x5FE0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x5FF0 , 16 , iter_reg ) ;
iter_reg = fw - > at0_array_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7080 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x7090 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x70A0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x70B0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x70C0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x70D0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x70E0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x70F0 , 16 , iter_reg ) ;
/* I/O Queue Control registers. */
qla24xx_read_window ( reg , 0x7800 , 16 , fw - > queue_control_reg ) ;
/* Frame Buffer registers. */
iter_reg = fw - > fb_hdw_reg ;
iter_reg = qla24xx_read_window ( reg , 0x6000 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6010 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6020 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6030 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6040 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6060 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6070 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6100 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6130 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6150 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6170 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6190 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x61B0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x61C0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6530 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6540 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6550 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6560 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6570 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6580 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x6590 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x65A0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x65B0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x65C0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x65D0 , 16 , iter_reg ) ;
iter_reg = qla24xx_read_window ( reg , 0x65E0 , 16 , iter_reg ) ;
qla24xx_read_window ( reg , 0x6F00 , 16 , iter_reg ) ;
/* Multi queue registers */
nxt_chain = qla25xx_copy_mq ( ha , ( void * ) ha - > fw_dump + ha - > chain_offset ,
& last_chain ) ;
rval = qla24xx_soft_reset ( ha ) ;
if ( rval ! = QLA_SUCCESS ) {
ql_log ( ql_log_warn , vha , 0xd00e ,
" SOFT RESET FAILED, forcing continuation of dump!!! \n " ) ;
rval = QLA_SUCCESS ;
ql_log ( ql_log_warn , vha , 0xd00f , " try a bigger hammer!!! \n " ) ;
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > hccr , HCCRX_SET_RISC_RESET ) ;
rd_reg_dword ( & reg - > hccr ) ;
2012-02-09 23:15:34 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > hccr , HCCRX_REL_RISC_PAUSE ) ;
rd_reg_dword ( & reg - > hccr ) ;
2012-02-09 23:15:34 +04:00
2020-05-19 00:17:08 +03:00
wrt_reg_dword ( & reg - > hccr , HCCRX_CLR_RISC_RESET ) ;
rd_reg_dword ( & reg - > hccr ) ;
2012-02-09 23:15:34 +04:00
2020-05-19 00:17:08 +03:00
for ( cnt = 30000 ; cnt & & ( rd_reg_word ( & reg - > mailbox0 ) ) ; cnt - - )
2012-02-09 23:15:34 +04:00
udelay ( 5 ) ;
if ( ! cnt ) {
nxt = fw - > code_ram ;
2012-11-21 11:40:35 +04:00
nxt + = sizeof ( fw - > code_ram ) ;
2012-02-09 23:15:34 +04:00
nxt + = ( ha - > fw_memory_size - 0x100000 + 1 ) ;
goto copy_queue ;
2014-04-12 00:54:21 +04:00
} else {
set_bit ( RISC_RDY_AFT_RESET , & ha - > fw_dump_cap_flags ) ;
2012-02-09 23:15:34 +04:00
ql_log ( ql_log_warn , vha , 0xd010 ,
" bigger hammer success? \n " ) ;
2014-04-12 00:54:21 +04:00
}
2012-02-09 23:15:34 +04:00
}
rval = qla24xx_dump_memory ( ha , fw - > code_ram , sizeof ( fw - > code_ram ) ,
& nxt ) ;
if ( rval ! = QLA_SUCCESS )
goto qla83xx_fw_dump_failed_0 ;
copy_queue :
nxt = qla2xxx_copy_queues ( ha , nxt ) ;
2013-06-25 19:27:27 +04:00
qla24xx_copy_eft ( ha , nxt ) ;
2012-02-09 23:15:34 +04:00
/* Chain entries -- started with MQ. */
nxt_chain = qla25xx_copy_fce ( ha , nxt_chain , & last_chain ) ;
nxt_chain = qla25xx_copy_mqueues ( ha , nxt_chain , & last_chain ) ;
2012-05-15 22:34:28 +04:00
nxt_chain = qla2xxx_copy_atioqueues ( ha , nxt_chain , & last_chain ) ;
2017-06-14 06:47:29 +03:00
nxt_chain = qla25xx_copy_exlogin ( ha , nxt_chain , & last_chain ) ;
nxt_chain = qla81xx_copy_exchoffld ( ha , nxt_chain , & last_chain ) ;
2012-02-09 23:15:34 +04:00
if ( last_chain ) {
2015-07-09 17:24:08 +03:00
ha - > fw_dump - > version | = htonl ( DUMP_CHAIN_VARIANT ) ;
* last_chain | = htonl ( DUMP_CHAIN_LAST ) ;
2012-02-09 23:15:34 +04:00
}
/* Adjust valid length. */
ha - > fw_dump_len = ( nxt_chain - ( void * ) ha - > fw_dump ) ;
qla83xx_fw_dump_failed_0 :
qla2xxx_dump_post_process ( base_vha , rval ) ;
}
2005-04-17 02:20:36 +04:00
/****************************************************************************/
/* Driver Debug Functions. */
/****************************************************************************/
2011-11-18 21:03:07 +04:00
2020-06-30 01:54:54 +03:00
/* Write the debug message prefix into @pbuf. */
static void ql_dbg_prefix ( char * pbuf , int pbuf_size ,
const scsi_qla_host_t * vha , uint msg_id )
{
if ( vha ) {
const struct pci_dev * pdev = vha - > hw - > pdev ;
/* <module-name> [<dev-name>]-<msg-id>:<host>: */
2020-09-30 05:25:15 +03:00
snprintf ( pbuf , pbuf_size , " %s [%s]-%04x:%lu: " , QL_MSGHDR ,
2020-06-30 01:54:54 +03:00
dev_name ( & ( pdev - > dev ) ) , msg_id , vha - > host_no ) ;
} else {
/* <module-name> [<dev-name>]-<msg-id>: : */
snprintf ( pbuf , pbuf_size , " %s [%s]-%04x: : " , QL_MSGHDR ,
" 0000:00:00.0 " , msg_id ) ;
}
}
2011-07-14 23:00:12 +04:00
/*
* This function is for formatting and logging debug information .
* It is to be used when vha is available . It formats the message
* and logs it to the messages file .
* parameters :
* level : The level of the debug messages to be printed .
* If ql2xextended_error_logging value is correctly set ,
* this message will appear in the messages file .
* vha : Pointer to the scsi_qla_host_t .
* id : This is a unique identifier for the level . It identifies the
* part of the code from where the message originated .
* msg : The message to be displayed .
*/
void
2019-03-12 21:08:16 +03:00
ql_dbg ( uint level , scsi_qla_host_t * vha , uint id , const char * fmt , . . . )
2011-11-18 21:03:05 +04:00
{
va_list va ;
struct va_format vaf ;
2020-06-30 01:54:54 +03:00
char pbuf [ 64 ] ;
2011-07-14 23:00:12 +04:00
2011-11-18 21:03:05 +04:00
va_start ( va , fmt ) ;
2011-07-14 23:00:12 +04:00
2011-11-18 21:03:05 +04:00
vaf . fmt = fmt ;
vaf . va = & va ;
2011-07-14 23:00:12 +04:00
2020-06-30 01:54:54 +03:00
ql_dbg_prefix ( pbuf , ARRAY_SIZE ( pbuf ) , vha , id ) ;
2020-04-03 11:40:17 +03:00
2020-06-30 01:54:54 +03:00
if ( ! ql_mask_match ( level ) )
2020-02-13 04:29:28 +03:00
trace_ql_dbg_log ( pbuf , & vaf ) ;
2020-06-30 01:54:54 +03:00
else
pr_warn ( " %s%pV " , pbuf , & vaf ) ;
2011-07-14 23:00:12 +04:00
2011-11-18 21:03:05 +04:00
va_end ( va ) ;
2011-07-14 23:00:12 +04:00
}
/*
* This function is for formatting and logging debug information .
2012-08-22 22:20:58 +04:00
* It is to be used when vha is not available and pci is available ,
2011-07-14 23:00:12 +04:00
* i . e . , before host allocation . It formats the message and logs it
* to the messages file .
* parameters :
* level : The level of the debug messages to be printed .
* If ql2xextended_error_logging value is correctly set ,
* this message will appear in the messages file .
* pdev : Pointer to the struct pci_dev .
* id : This is a unique id for the level . It identifies the part
* of the code from where the message originated .
* msg : The message to be displayed .
*/
void
2019-03-12 21:08:16 +03:00
ql_dbg_pci ( uint level , struct pci_dev * pdev , uint id , const char * fmt , . . . )
2011-11-18 21:03:05 +04:00
{
va_list va ;
struct va_format vaf ;
2020-06-30 01:54:54 +03:00
char pbuf [ 128 ] ;
2011-07-14 23:00:12 +04:00
if ( pdev = = NULL )
return ;
2011-11-18 21:03:07 +04:00
if ( ! ql_mask_match ( level ) )
2011-11-18 21:03:05 +04:00
return ;
2011-07-14 23:00:12 +04:00
2011-11-18 21:03:05 +04:00
va_start ( va , fmt ) ;
2011-07-14 23:00:12 +04:00
2011-11-18 21:03:05 +04:00
vaf . fmt = fmt ;
vaf . va = & va ;
2011-07-14 23:00:12 +04:00
2020-06-30 01:54:54 +03:00
ql_dbg_prefix ( pbuf , ARRAY_SIZE ( pbuf ) , NULL , id + ql_dbg_offset ) ;
pr_warn ( " %s%pV " , pbuf , & vaf ) ;
2011-07-14 23:00:12 +04:00
2011-11-18 21:03:05 +04:00
va_end ( va ) ;
2011-07-14 23:00:12 +04:00
}
/*
* This function is for formatting and logging log messages .
* It is to be used when vha is available . It formats the message
* and logs it to the messages file . All the messages will be logged
* irrespective of value of ql2xextended_error_logging .
* parameters :
* level : The level of the log messages to be printed in the
* messages file .
* vha : Pointer to the scsi_qla_host_t
* id : This is a unique id for the level . It identifies the
* part of the code from where the message originated .
* msg : The message to be displayed .
*/
void
2019-03-12 21:08:16 +03:00
ql_log ( uint level , scsi_qla_host_t * vha , uint id , const char * fmt , . . . )
2011-11-18 21:03:05 +04:00
{
va_list va ;
struct va_format vaf ;
char pbuf [ 128 ] ;
2011-07-14 23:00:12 +04:00
2011-11-18 21:03:05 +04:00
if ( level > ql_errlev )
return ;
2011-07-14 23:00:12 +04:00
2020-06-30 01:54:54 +03:00
ql_dbg_prefix ( pbuf , ARRAY_SIZE ( pbuf ) , vha , id ) ;
2011-11-18 21:03:05 +04:00
va_start ( va , fmt ) ;
vaf . fmt = fmt ;
vaf . va = & va ;
switch ( level ) {
2012-02-09 23:15:48 +04:00
case ql_log_fatal : /* FATAL LOG */
2011-11-18 21:03:05 +04:00
pr_crit ( " %s%pV " , pbuf , & vaf ) ;
break ;
2012-02-09 23:15:48 +04:00
case ql_log_warn :
2011-11-18 21:03:05 +04:00
pr_err ( " %s%pV " , pbuf , & vaf ) ;
break ;
2012-02-09 23:15:48 +04:00
case ql_log_info :
2011-11-18 21:03:05 +04:00
pr_warn ( " %s%pV " , pbuf , & vaf ) ;
break ;
default :
pr_info ( " %s%pV " , pbuf , & vaf ) ;
break ;
2011-07-14 23:00:12 +04:00
}
2011-11-18 21:03:05 +04:00
va_end ( va ) ;
2011-07-14 23:00:12 +04:00
}
/*
* This function is for formatting and logging log messages .
2012-08-22 22:20:58 +04:00
* It is to be used when vha is not available and pci is available ,
2011-07-14 23:00:12 +04:00
* i . e . , before host allocation . It formats the message and logs
* it to the messages file . All the messages are logged irrespective
* of the value of ql2xextended_error_logging .
* parameters :
* level : The level of the log messages to be printed in the
* messages file .
* pdev : Pointer to the struct pci_dev .
* id : This is a unique id for the level . It identifies the
* part of the code from where the message originated .
* msg : The message to be displayed .
*/
void
2019-03-12 21:08:16 +03:00
ql_log_pci ( uint level , struct pci_dev * pdev , uint id , const char * fmt , . . . )
2011-11-18 21:03:05 +04:00
{
va_list va ;
struct va_format vaf ;
char pbuf [ 128 ] ;
2011-07-14 23:00:12 +04:00
if ( pdev = = NULL )
return ;
2011-11-18 21:03:05 +04:00
if ( level > ql_errlev )
return ;
2011-07-14 23:00:12 +04:00
2020-06-30 01:54:54 +03:00
ql_dbg_prefix ( pbuf , ARRAY_SIZE ( pbuf ) , NULL , id ) ;
2011-11-18 21:03:05 +04:00
va_start ( va , fmt ) ;
vaf . fmt = fmt ;
vaf . va = & va ;
switch ( level ) {
2012-02-09 23:15:48 +04:00
case ql_log_fatal : /* FATAL LOG */
2011-11-18 21:03:05 +04:00
pr_crit ( " %s%pV " , pbuf , & vaf ) ;
break ;
2012-02-09 23:15:48 +04:00
case ql_log_warn :
2011-11-18 21:03:05 +04:00
pr_err ( " %s%pV " , pbuf , & vaf ) ;
break ;
2012-02-09 23:15:48 +04:00
case ql_log_info :
2011-11-18 21:03:05 +04:00
pr_warn ( " %s%pV " , pbuf , & vaf ) ;
break ;
default :
pr_info ( " %s%pV " , pbuf , & vaf ) ;
break ;
2011-07-14 23:00:12 +04:00
}
2011-11-18 21:03:05 +04:00
va_end ( va ) ;
2011-07-14 23:00:12 +04:00
}
void
2019-03-12 21:08:16 +03:00
ql_dump_regs ( uint level , scsi_qla_host_t * vha , uint id )
2011-07-14 23:00:12 +04:00
{
int i ;
struct qla_hw_data * ha = vha - > hw ;
struct device_reg_2xxx __iomem * reg = & ha - > iobase - > isp ;
struct device_reg_24xx __iomem * reg24 = & ha - > iobase - > isp24 ;
struct device_reg_82xx __iomem * reg82 = & ha - > iobase - > isp82 ;
2020-05-19 00:17:12 +03:00
__le16 __iomem * mbx_reg ;
2011-07-14 23:00:12 +04:00
2011-11-18 21:03:07 +04:00
if ( ! ql_mask_match ( level ) )
return ;
2011-07-14 23:00:12 +04:00
2013-08-27 09:37:28 +04:00
if ( IS_P3P_TYPE ( ha ) )
2011-11-18 21:03:07 +04:00
mbx_reg = & reg82 - > mailbox_in [ 0 ] ;
else if ( IS_FWI2_CAPABLE ( ha ) )
mbx_reg = & reg24 - > mailbox0 ;
else
mbx_reg = MAILBOX_REG ( ha , reg , 0 ) ;
ql_dbg ( level , vha , id , " Mailbox registers: \n " ) ;
2017-08-24 01:05:15 +03:00
for ( i = 0 ; i < 6 ; i + + , mbx_reg + + )
2011-11-18 21:03:07 +04:00
ql_dbg ( level , vha , id ,
2020-05-19 00:17:08 +03:00
" mbox[%d] %#04x \n " , i , rd_reg_word ( mbx_reg ) ) ;
2011-07-14 23:00:12 +04:00
}
void
2019-08-09 06:01:29 +03:00
ql_dump_buffer ( uint level , scsi_qla_host_t * vha , uint id , const void * buf ,
uint size )
2011-07-14 23:00:12 +04:00
{
2016-07-06 18:14:22 +03:00
uint cnt ;
2011-11-18 21:03:07 +04:00
if ( ! ql_mask_match ( level ) )
return ;
2016-07-06 18:14:22 +03:00
ql_dbg ( level , vha , id ,
" %-+5d 0 1 2 3 4 5 6 7 8 9 A B C D E F \n " , size ) ;
ql_dbg ( level , vha , id ,
" ----- ----------------------------------------------- \n " ) ;
2017-03-03 04:14:47 +03:00
for ( cnt = 0 ; cnt < size ; cnt + = 16 ) {
ql_dbg ( level , vha , id , " %04x: " , cnt ) ;
print_hex_dump ( KERN_CONT , " " , DUMP_PREFIX_NONE , 16 , 1 ,
buf + cnt , min ( 16U , size - cnt ) , false ) ;
2011-07-14 23:00:12 +04:00
}
}
2017-06-14 06:47:25 +03:00
/*
* This function is for formatting and logging log messages .
* It is to be used when vha is available . It formats the message
* and logs it to the messages file . All the messages will be logged
* irrespective of value of ql2xextended_error_logging .
* parameters :
* level : The level of the log messages to be printed in the
* messages file .
* vha : Pointer to the scsi_qla_host_t
* id : This is a unique id for the level . It identifies the
* part of the code from where the message originated .
* msg : The message to be displayed .
*/
void
ql_log_qp ( uint32_t level , struct qla_qpair * qpair , int32_t id ,
const char * fmt , . . . )
{
va_list va ;
struct va_format vaf ;
char pbuf [ 128 ] ;
if ( level > ql_errlev )
return ;
2020-06-30 01:54:54 +03:00
ql_dbg_prefix ( pbuf , ARRAY_SIZE ( pbuf ) , qpair ? qpair - > vha : NULL , id ) ;
2017-06-14 06:47:25 +03:00
va_start ( va , fmt ) ;
vaf . fmt = fmt ;
vaf . va = & va ;
switch ( level ) {
case ql_log_fatal : /* FATAL LOG */
pr_crit ( " %s%pV " , pbuf , & vaf ) ;
break ;
case ql_log_warn :
pr_err ( " %s%pV " , pbuf , & vaf ) ;
break ;
case ql_log_info :
pr_warn ( " %s%pV " , pbuf , & vaf ) ;
break ;
default :
pr_info ( " %s%pV " , pbuf , & vaf ) ;
break ;
}
va_end ( va ) ;
}
/*
* This function is for formatting and logging debug information .
* It is to be used when vha is available . It formats the message
* and logs it to the messages file .
* parameters :
* level : The level of the debug messages to be printed .
* If ql2xextended_error_logging value is correctly set ,
* this message will appear in the messages file .
* vha : Pointer to the scsi_qla_host_t .
* id : This is a unique identifier for the level . It identifies the
* part of the code from where the message originated .
* msg : The message to be displayed .
*/
void
ql_dbg_qp ( uint32_t level , struct qla_qpair * qpair , int32_t id ,
const char * fmt , . . . )
{
va_list va ;
struct va_format vaf ;
2020-06-30 01:54:54 +03:00
char pbuf [ 128 ] ;
2017-06-14 06:47:25 +03:00
if ( ! ql_mask_match ( level ) )
return ;
va_start ( va , fmt ) ;
vaf . fmt = fmt ;
vaf . va = & va ;
2020-06-30 01:54:54 +03:00
ql_dbg_prefix ( pbuf , ARRAY_SIZE ( pbuf ) , qpair ? qpair - > vha : NULL ,
id + ql_dbg_offset ) ;
pr_warn ( " %s%pV " , pbuf , & vaf ) ;
2017-06-14 06:47:25 +03:00
va_end ( va ) ;
}