2005-04-17 02:20:36 +04:00
/*
2005-10-27 22:10:08 +04:00
* QLogic Fibre Channel HBA Driver
2008-04-04 00:13:13 +04:00
* Copyright ( c ) 2003 - 2008 QLogic Corporation
2005-04-17 02:20:36 +04:00
*
2005-10-27 22:10:08 +04:00
* See LICENSE . qla2xxx for copyright and licensing details .
2005-04-17 02:20:36 +04:00
*/
# include "qla_def.h"
# include <linux/delay.h>
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
2007-07-20 07:37:34 +04:00
static int
2008-11-06 21:40:19 +03:00
qla24xx_dump_ram ( struct qla_hw_data * ha , uint32_t addr , uint32_t * ram ,
2008-04-25 02:21:22 +04:00
uint32_t ram_dwords , void * * nxt )
2007-07-20 07:37:34 +04:00
{
int rval ;
2008-04-25 02:21:22 +04:00
uint32_t cnt , stat , timer , dwords , idx ;
uint16_t mb0 ;
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 ;
uint32_t * dump = ( uint32_t * ) ha - > gid_list ;
2007-07-20 07:37:34 +04:00
rval = QLA_SUCCESS ;
2008-04-25 02:21:22 +04:00
mb0 = 0 ;
2007-07-20 07:37:34 +04:00
2008-04-25 02:21:22 +04:00
WRT_REG_WORD ( & reg - > mailbox0 , MBC_DUMP_RISC_RAM_EXTENDED ) ;
2007-07-20 07:37:34 +04:00
clear_bit ( MBX_INTERRUPT , & ha - > mbx_cmd_flags ) ;
2008-04-25 02:21:22 +04:00
dwords = GID_LIST_SIZE / 4 ;
for ( cnt = 0 ; cnt < ram_dwords & & rval = = QLA_SUCCESS ;
cnt + = dwords , addr + = dwords ) {
if ( cnt + dwords > ram_dwords )
dwords = ram_dwords - cnt ;
2007-07-20 07:37:34 +04:00
2008-04-25 02:21:22 +04:00
WRT_REG_WORD ( & reg - > mailbox1 , LSW ( addr ) ) ;
WRT_REG_WORD ( & reg - > mailbox8 , MSW ( addr ) ) ;
2007-07-20 07:37:34 +04:00
2008-04-25 02:21:22 +04:00
WRT_REG_WORD ( & reg - > mailbox2 , MSW ( dump_dma ) ) ;
WRT_REG_WORD ( & reg - > mailbox3 , LSW ( 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
2008-04-25 02:21:22 +04:00
WRT_REG_WORD ( & reg - > mailbox4 , MSW ( dwords ) ) ;
WRT_REG_WORD ( & reg - > mailbox5 , LSW ( dwords ) ) ;
2007-07-20 07:37:34 +04:00
WRT_REG_DWORD ( & reg - > hccr , HCCRX_SET_HOST_INT ) ;
for ( timer = 6000000 ; timer ; timer - - ) {
/* Check for pending interrupts. */
stat = RD_REG_DWORD ( & reg - > host_status ) ;
if ( stat & HSRX_RISC_INT ) {
stat & = 0xff ;
if ( stat = = 0x1 | | stat = = 0x2 | |
stat = = 0x10 | | stat = = 0x11 ) {
set_bit ( MBX_INTERRUPT ,
& ha - > mbx_cmd_flags ) ;
2008-04-25 02:21:22 +04:00
mb0 = RD_REG_WORD ( & reg - > mailbox0 ) ;
2007-07-20 07:37:34 +04:00
WRT_REG_DWORD ( & reg - > hccr ,
HCCRX_CLR_RISC_INT ) ;
RD_REG_DWORD ( & reg - > hccr ) ;
break ;
}
/* Clear this intr; it wasn't a mailbox intr */
WRT_REG_DWORD ( & reg - > hccr , HCCRX_CLR_RISC_INT ) ;
RD_REG_DWORD ( & reg - > hccr ) ;
}
udelay ( 5 ) ;
}
if ( test_and_clear_bit ( MBX_INTERRUPT , & ha - > mbx_cmd_flags ) ) {
2008-04-25 02:21:22 +04:00
rval = mb0 & MBS_MASK ;
for ( idx = 0 ; idx < dwords ; idx + + )
ram [ cnt + idx ] = swab32 ( dump [ idx ] ) ;
2007-07-20 07:37:34 +04:00
} else {
rval = QLA_FUNCTION_FAILED ;
}
}
2008-04-25 02:21:22 +04:00
* nxt = rval = = QLA_SUCCESS ? & ram [ cnt ] : NULL ;
2007-07-20 07:37:34 +04:00
return rval ;
}
2008-04-25 02:21:22 +04:00
static int
2008-11-06 21:40:19 +03:00
qla24xx_dump_memory ( struct qla_hw_data * ha , uint32_t * code_ram ,
2008-04-25 02:21:22 +04:00
uint32_t cram_size , void * * nxt )
{
int rval ;
/* Code RAM. */
rval = qla24xx_dump_ram ( ha , 0x20000 , code_ram , cram_size / 4 , nxt ) ;
if ( rval ! = QLA_SUCCESS )
return rval ;
/* External Memory. */
return qla24xx_dump_ram ( ha , 0x100000 , * nxt ,
ha - > fw_memory_size - 0x100000 + 1 , nxt ) ;
}
2007-07-26 22:41:13 +04:00
static uint32_t *
qla24xx_read_window ( struct device_reg_24xx __iomem * reg , uint32_t iobase ,
uint32_t count , uint32_t * buf )
{
uint32_t __iomem * dmp_reg ;
WRT_REG_DWORD ( & reg - > iobase_addr , iobase ) ;
dmp_reg = & reg - > iobase_window ;
while ( count - - )
* buf + + = htonl ( RD_REG_DWORD ( dmp_reg + + ) ) ;
return buf ;
}
static inline int
qla24xx_pause_risc ( struct device_reg_24xx __iomem * reg )
{
int rval = QLA_SUCCESS ;
uint32_t cnt ;
2007-09-21 01:07:38 +04:00
WRT_REG_DWORD ( & reg - > hccr , HCCRX_SET_RISC_PAUSE ) ;
2009-06-03 20:55:26 +04:00
for ( cnt = 30000 ;
( ( RD_REG_DWORD ( & reg - > host_status ) & HSRX_RISC_PAUSED ) = = 0 ) & &
2007-09-21 01:07:38 +04:00
rval = = QLA_SUCCESS ; cnt - - ) {
if ( cnt )
udelay ( 100 ) ;
else
rval = QLA_FUNCTION_TIMEOUT ;
2007-07-26 22:41:13 +04:00
}
return rval ;
}
static 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 ;
uint16_t mb0 , wd ;
struct device_reg_24xx __iomem * reg = & ha - > iobase - > isp24 ;
/* Reset RISC. */
WRT_REG_DWORD ( & reg - > ctrl_status , CSRX_DMA_SHUTDOWN | MWB_4096_BYTES ) ;
for ( cnt = 0 ; cnt < 30000 ; cnt + + ) {
if ( ( RD_REG_DWORD ( & reg - > ctrl_status ) & CSRX_DMA_ACTIVE ) = = 0 )
break ;
udelay ( 10 ) ;
}
WRT_REG_DWORD ( & reg - > ctrl_status ,
CSRX_ISP_SOFT_RESET | CSRX_DMA_SHUTDOWN | MWB_4096_BYTES ) ;
pci_read_config_word ( ha - > pdev , PCI_COMMAND , & wd ) ;
udelay ( 100 ) ;
/* Wait for firmware to complete NVRAM accesses. */
mb0 = ( uint32_t ) RD_REG_WORD ( & reg - > mailbox0 ) ;
for ( cnt = 10000 ; cnt & & mb0 ; cnt - - ) {
udelay ( 5 ) ;
mb0 = ( uint32_t ) RD_REG_WORD ( & reg - > mailbox0 ) ;
barrier ( ) ;
}
/* Wait for soft-reset to complete. */
for ( cnt = 0 ; cnt < 30000 ; cnt + + ) {
if ( ( RD_REG_DWORD ( & reg - > ctrl_status ) &
CSRX_ISP_SOFT_RESET ) = = 0 )
break ;
udelay ( 10 ) ;
}
WRT_REG_DWORD ( & reg - > hccr , HCCRX_CLR_RISC_RESET ) ;
RD_REG_DWORD ( & reg - > hccr ) ; /* PCI Posting. */
for ( cnt = 30000 ; RD_REG_WORD ( & reg - > mailbox0 ) ! = 0 & &
rval = = QLA_SUCCESS ; cnt - - ) {
if ( cnt )
udelay ( 100 ) ;
else
rval = QLA_FUNCTION_TIMEOUT ;
}
return rval ;
}
2008-04-25 02:21:22 +04:00
static int
2008-11-06 21:40:19 +03:00
qla2xxx_dump_ram ( struct qla_hw_data * ha , uint32_t addr , uint16_t * ram ,
uint16_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 ;
uint16_t * dump = ( uint16_t * ) ha - > gid_list ;
rval = QLA_SUCCESS ;
mb0 = 0 ;
WRT_MAILBOX_REG ( ha , reg , 0 , MBC_DUMP_RISC_RAM_EXTENDED ) ;
clear_bit ( MBX_INTERRUPT , & ha - > mbx_cmd_flags ) ;
words = GID_LIST_SIZE / 2 ;
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 ) ;
WRT_REG_WORD ( & reg - > hccr , HCCR_SET_HOST_INT ) ;
for ( timer = 6000000 ; timer ; timer - - ) {
/* Check for pending interrupts. */
stat = RD_REG_DWORD ( & reg - > u . isp2300 . host_status ) ;
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. */
WRT_REG_WORD ( & reg - > semaphore , 0 ) ;
WRT_REG_WORD ( & reg - > hccr ,
HCCR_CLR_RISC_INT ) ;
RD_REG_WORD ( & reg - > hccr ) ;
break ;
} else if ( stat = = 0x10 | | stat = = 0x11 ) {
set_bit ( MBX_INTERRUPT ,
& ha - > mbx_cmd_flags ) ;
mb0 = RD_MAILBOX_REG ( ha , reg , 0 ) ;
WRT_REG_WORD ( & reg - > hccr ,
HCCR_CLR_RISC_INT ) ;
RD_REG_WORD ( & reg - > hccr ) ;
break ;
}
/* clear this intr; it wasn't a mailbox intr */
WRT_REG_WORD ( & reg - > hccr , HCCR_CLR_RISC_INT ) ;
RD_REG_WORD ( & reg - > hccr ) ;
}
udelay ( 5 ) ;
}
if ( test_and_clear_bit ( MBX_INTERRUPT , & ha - > mbx_cmd_flags ) ) {
rval = mb0 & MBS_MASK ;
for ( idx = 0 ; idx < words ; idx + + )
ram [ cnt + idx ] = swab16 ( dump [ idx ] ) ;
} else {
rval = QLA_FUNCTION_FAILED ;
}
}
* nxt = rval = = QLA_SUCCESS ? & ram [ cnt ] : NULL ;
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 ,
uint16_t * buf )
{
uint16_t __iomem * dmp_reg = & reg - > u . isp2300 . fb_cmd ;
while ( count - - )
* buf + + = htons ( RD_REG_WORD ( dmp_reg + + ) ) ;
}
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 *
qla25xx_copy_fce ( struct qla_hw_data * ha , void * ptr , uint32_t * * last_chain )
{
uint32_t cnt ;
uint32_t * iter_reg ;
struct qla2xxx_fce_chain * fcec = ptr ;
if ( ! ha - > fce )
return ptr ;
* last_chain = & fcec - > type ;
fcec - > type = __constant_htonl ( DUMP_CHAIN_FCE ) ;
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 ) ) ;
return iter_reg ;
}
2009-01-05 22:18:09 +03:00
static inline void *
qla25xx_copy_mq ( struct qla_hw_data * ha , void * ptr , uint32_t * * last_chain )
{
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 ;
struct device_reg_25xxmq __iomem * reg ;
if ( ! ha - > mqenable )
return ptr ;
mq = ptr ;
* last_chain = & mq - > type ;
mq - > type = __constant_htonl ( DUMP_CHAIN_MQ ) ;
mq - > chain_size = __constant_htonl ( sizeof ( struct qla2xxx_mq_chain ) ) ;
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 + + ) {
reg = ( struct device_reg_25xxmq * ) ( ( void * )
ha - > mqiobase + cnt * QLA_QUE_PAGE ) ;
que_idx = cnt * 4 ;
mq - > qregs [ que_idx ] = htonl ( RD_REG_DWORD ( & reg - > req_q_in ) ) ;
mq - > qregs [ que_idx + 1 ] = htonl ( RD_REG_DWORD ( & reg - > req_q_out ) ) ;
mq - > qregs [ que_idx + 2 ] = htonl ( RD_REG_DWORD ( & reg - > rsp_q_in ) ) ;
mq - > qregs [ que_idx + 3 ] = htonl ( RD_REG_DWORD ( & reg - > rsp_q_out ) ) ;
}
return ptr + sizeof ( struct qla2xxx_mq_chain ) ;
}
2005-04-17 02:20:36 +04:00
/**
* qla2300_fw_dump ( ) - Dumps binary data from the 2300 firmware .
* @ ha : HA context
* @ hardware_locked : Called with the hardware_lock
*/
void
2008-11-06 21:40:19 +03:00
qla2300_fw_dump ( scsi_qla_host_t * vha , int hardware_locked )
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 ;
2005-04-17 02:20:36 +04:00
uint16_t __iomem * dmp_reg ;
unsigned long flags ;
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
flags = 0 ;
if ( ! hardware_locked )
spin_lock_irqsave ( & ha - > hardware_lock , flags ) ;
2006-05-18 02:09:50 +04:00
if ( ! ha - > fw_dump ) {
2005-04-17 02:20:36 +04:00
qla_printk ( KERN_WARNING , ha ,
2006-05-18 02:09:50 +04:00
" No buffer available for dump!!! \n " ) ;
2005-04-17 02:20:36 +04:00
goto qla2300_fw_dump_failed ;
}
2006-05-18 02:09:50 +04:00
if ( ha - > fw_dumped ) {
2005-04-17 02:20:36 +04:00
qla_printk ( KERN_WARNING , ha ,
2006-05-18 02:09:50 +04:00
" Firmware has been previously dumped (%p) -- ignoring "
" request... \n " , ha - > fw_dump ) ;
2005-04-17 02:20:36 +04:00
goto qla2300_fw_dump_failed ;
}
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 ;
2006-06-24 03:10:29 +04:00
fw - > hccr = htons ( RD_REG_WORD ( & reg - > hccr ) ) ;
2005-04-17 02:20:36 +04:00
/* Pause RISC. */
2005-07-06 21:32:07 +04:00
WRT_REG_WORD ( & reg - > hccr , HCCR_PAUSE_RISC ) ;
2005-04-17 02:20:36 +04:00
if ( IS_QLA2300 ( ha ) ) {
for ( cnt = 30000 ;
( RD_REG_WORD ( & reg - > hccr ) & HCCR_RISC_PAUSE ) = = 0 & &
rval = = QLA_SUCCESS ; cnt - - ) {
if ( cnt )
udelay ( 100 ) ;
else
rval = QLA_FUNCTION_TIMEOUT ;
}
} else {
RD_REG_WORD ( & reg - > hccr ) ; /* PCI Posting. */
udelay ( 10 ) ;
}
if ( rval = = QLA_SUCCESS ) {
2007-07-26 22:41:13 +04:00
dmp_reg = & reg - > flash_address ;
2005-07-06 21:32:07 +04:00
for ( cnt = 0 ; cnt < sizeof ( fw - > pbiu_reg ) / 2 ; cnt + + )
2006-06-24 03:10:29 +04: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 ;
2005-07-06 21:32:07 +04:00
for ( cnt = 0 ; cnt < sizeof ( fw - > risc_host_reg ) / 2 ; cnt + + )
2006-06-24 03:10:29 +04: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 ;
2005-07-06 21:32:07 +04:00
for ( cnt = 0 ; cnt < sizeof ( fw - > mailbox_reg ) / 2 ; cnt + + )
2006-06-24 03:10:29 +04:00
fw - > mailbox_reg [ cnt ] = htons ( RD_REG_WORD ( dmp_reg + + ) ) ;
2005-04-17 02:20:36 +04: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
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
WRT_REG_WORD ( & reg - > ctrl_status , 0x00 ) ;
2007-07-26 22:41:13 +04:00
dmp_reg = & reg - > risc_hw ;
2005-07-06 21:32:07 +04:00
for ( cnt = 0 ; cnt < sizeof ( fw - > risc_hdw_reg ) / 2 ; cnt + + )
2006-06-24 03:10:29 +04:00
fw - > risc_hdw_reg [ cnt ] = htons ( RD_REG_WORD ( dmp_reg + + ) ) ;
2005-04-17 02:20:36 +04:00
2005-07-06 21:32:07 +04: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
2005-07-06 21:32:07 +04: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
2005-07-06 21:32:07 +04: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
2005-07-06 21:32:07 +04: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
2005-07-06 21:32:07 +04: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
2005-07-06 21:32:07 +04: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
2005-07-06 21:32:07 +04: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
2005-07-06 21:32:07 +04: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
2005-07-06 21:32:07 +04: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
2005-07-06 21:32:07 +04: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
2005-07-06 21:32:07 +04: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. */
WRT_REG_WORD ( & reg - > ctrl_status , CSR_ISP_SOFT_RESET ) ;
for ( cnt = 0 ; cnt < 30000 ; cnt + + ) {
if ( ( RD_REG_WORD ( & reg - > ctrl_status ) &
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 ,
sizeof ( fw - > risc_ram ) / 2 , & 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 ,
sizeof ( fw - > stack_ram ) / 2 , & 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
2005-04-17 02:20:36 +04:00
if ( rval ! = QLA_SUCCESS ) {
qla_printk ( KERN_WARNING , ha ,
" Failed to dump firmware (%x)!!! \n " , rval ) ;
2006-05-18 02:09:50 +04:00
ha - > fw_dumped = 0 ;
2005-04-17 02:20:36 +04:00
} else {
qla_printk ( KERN_INFO , ha ,
" Firmware dump saved to temp buffer (%ld/%p). \n " ,
2008-12-10 03:45:39 +03:00
base_vha - > host_no , ha - > fw_dump ) ;
2006-05-18 02:09:50 +04:00
ha - > fw_dumped = 1 ;
2005-04-17 02:20:36 +04:00
}
qla2300_fw_dump_failed :
if ( ! hardware_locked )
spin_unlock_irqrestore ( & ha - > hardware_lock , flags ) ;
}
/**
* qla2100_fw_dump ( ) - Dumps binary data from the 2100 / 2200 firmware .
* @ ha : HA context
* @ hardware_locked : Called with the hardware_lock
*/
void
2008-11-06 21:40:19 +03:00
qla2100_fw_dump ( scsi_qla_host_t * vha , int hardware_locked )
2005-04-17 02:20:36 +04:00
{
int rval ;
uint32_t cnt , timer ;
uint16_t risc_address ;
uint16_t mb0 , mb2 ;
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 ;
2005-04-17 02:20:36 +04:00
uint16_t __iomem * dmp_reg ;
unsigned long flags ;
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
risc_address = 0 ;
mb0 = mb2 = 0 ;
flags = 0 ;
if ( ! hardware_locked )
spin_lock_irqsave ( & ha - > hardware_lock , flags ) ;
2006-05-18 02:09:50 +04:00
if ( ! ha - > fw_dump ) {
2005-04-17 02:20:36 +04:00
qla_printk ( KERN_WARNING , ha ,
2006-05-18 02:09:50 +04:00
" No buffer available for dump!!! \n " ) ;
2005-04-17 02:20:36 +04:00
goto qla2100_fw_dump_failed ;
}
2006-05-18 02:09:50 +04:00
if ( ha - > fw_dumped ) {
2005-04-17 02:20:36 +04:00
qla_printk ( KERN_WARNING , ha ,
2006-05-18 02:09:50 +04:00
" Firmware has been previously dumped (%p) -- ignoring "
" request... \n " , ha - > fw_dump ) ;
2005-04-17 02:20:36 +04:00
goto qla2100_fw_dump_failed ;
}
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 ;
2006-06-24 03:10:29 +04:00
fw - > hccr = htons ( RD_REG_WORD ( & reg - > hccr ) ) ;
2005-04-17 02:20:36 +04:00
/* Pause RISC. */
2005-07-06 21:32:07 +04:00
WRT_REG_WORD ( & reg - > hccr , HCCR_PAUSE_RISC ) ;
2005-04-17 02:20:36 +04:00
for ( cnt = 30000 ; ( RD_REG_WORD ( & reg - > hccr ) & HCCR_RISC_PAUSE ) = = 0 & &
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 ;
2005-07-06 21:32:07 +04:00
for ( cnt = 0 ; cnt < sizeof ( fw - > pbiu_reg ) / 2 ; cnt + + )
2006-06-24 03:10:29 +04: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 ;
2005-04-17 02:20:36 +04:00
for ( cnt = 0 ; cnt < ha - > mbx_count ; cnt + + ) {
2007-07-26 22:41:13 +04:00
if ( cnt = = 8 )
dmp_reg = & reg - > u_end . isp2200 . mailbox8 ;
2006-06-24 03:10:29 +04: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 ] ;
2005-07-06 21:32:07 +04:00
for ( cnt = 0 ; cnt < sizeof ( fw - > dma_reg ) / 2 ; cnt + + )
2006-06-24 03:10:29 +04:00
fw - > dma_reg [ cnt ] = htons ( RD_REG_WORD ( dmp_reg + + ) ) ;
2005-04-17 02:20:36 +04:00
WRT_REG_WORD ( & reg - > ctrl_status , 0x00 ) ;
2007-07-26 22:41:13 +04:00
dmp_reg = & reg - > risc_hw ;
2005-07-06 21:32:07 +04:00
for ( cnt = 0 ; cnt < sizeof ( fw - > risc_hdw_reg ) / 2 ; cnt + + )
2006-06-24 03:10:29 +04:00
fw - > risc_hdw_reg [ cnt ] = htons ( RD_REG_WORD ( dmp_reg + + ) ) ;
2005-04-17 02:20:36 +04:00
2005-07-06 21:32:07 +04: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
2005-07-06 21:32:07 +04: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
2005-07-06 21:32:07 +04: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
2005-07-06 21:32:07 +04: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
2005-07-06 21:32:07 +04: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
2005-07-06 21:32:07 +04: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
2005-07-06 21:32:07 +04: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
2005-07-06 21:32:07 +04: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
2005-07-06 21:32:07 +04: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
2005-07-06 21:32:07 +04: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
2005-07-06 21:32:07 +04: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. */
WRT_REG_WORD ( & reg - > ctrl_status , CSR_ISP_SOFT_RESET ) ;
}
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 ) & &
( RD_REG_WORD ( & reg - > mctr ) & ( BIT_1 | BIT_0 ) ) ! = 0 ) ) ) {
2005-07-06 21:32:07 +04:00
WRT_REG_WORD ( & reg - > hccr , HCCR_PAUSE_RISC ) ;
2005-04-17 02:20:36 +04:00
for ( cnt = 30000 ;
( RD_REG_WORD ( & reg - > hccr ) & HCCR_RISC_PAUSE ) = = 0 & &
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 ) )
WRT_REG_WORD ( & reg - > mctr , 0xf1 ) ;
else
WRT_REG_WORD ( & reg - > mctr , 0xf2 ) ;
RD_REG_WORD ( & reg - > mctr ) ; /* PCI Posting. */
/* Release RISC. */
WRT_REG_WORD ( & reg - > hccr , HCCR_RELEASE_RISC ) ;
}
}
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 ) ;
}
for ( cnt = 0 ; cnt < sizeof ( fw - > risc_ram ) / 2 & & rval = = QLA_SUCCESS ;
cnt + + , risc_address + + ) {
WRT_MAILBOX_REG ( ha , reg , 1 , risc_address ) ;
WRT_REG_WORD ( & reg - > hccr , HCCR_SET_HOST_INT ) ;
for ( timer = 6000000 ; timer ! = 0 ; timer - - ) {
/* Check for pending interrupts. */
if ( RD_REG_WORD ( & reg - > istatus ) & ISR_RISC_INT ) {
if ( RD_REG_WORD ( & reg - > semaphore ) & BIT_0 ) {
set_bit ( MBX_INTERRUPT ,
& ha - > mbx_cmd_flags ) ;
mb0 = RD_MAILBOX_REG ( ha , reg , 0 ) ;
mb2 = RD_MAILBOX_REG ( ha , reg , 2 ) ;
WRT_REG_WORD ( & reg - > semaphore , 0 ) ;
WRT_REG_WORD ( & reg - > hccr ,
HCCR_CLR_RISC_INT ) ;
RD_REG_WORD ( & reg - > hccr ) ;
break ;
}
WRT_REG_WORD ( & reg - > hccr , HCCR_CLR_RISC_INT ) ;
RD_REG_WORD ( & reg - > hccr ) ;
}
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 )
2008-12-10 03:45:39 +03:00
qla2xxx_copy_queues ( ha , & fw - > risc_ram [ cnt ] ) ;
2006-06-24 03:10:29 +04:00
2005-04-17 02:20:36 +04:00
if ( rval ! = QLA_SUCCESS ) {
qla_printk ( KERN_WARNING , ha ,
" Failed to dump firmware (%x)!!! \n " , rval ) ;
2006-05-18 02:09:50 +04:00
ha - > fw_dumped = 0 ;
2005-04-17 02:20:36 +04:00
} else {
qla_printk ( KERN_INFO , ha ,
" Firmware dump saved to temp buffer (%ld/%p). \n " ,
2008-12-10 03:45:39 +03:00
base_vha - > host_no , ha - > fw_dump ) ;
2006-05-18 02:09:50 +04:00
ha - > fw_dumped = 1 ;
2005-04-17 02:20:36 +04:00
}
qla2100_fw_dump_failed :
if ( ! hardware_locked )
spin_unlock_irqrestore ( & ha - > hardware_lock , flags ) ;
}
2005-07-06 21:30:36 +04:00
void
2008-11-06 21:40:19 +03:00
qla24xx_fw_dump ( scsi_qla_host_t * vha , int hardware_locked )
2005-07-06 21:30:36 +04:00
{
int rval ;
2007-07-20 07:37:34 +04:00
uint32_t cnt ;
2005-07-06 21:30:36 +04:00
uint32_t risc_address ;
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 ;
uint32_t __iomem * dmp_reg ;
uint32_t * iter_reg ;
uint16_t __iomem * mbx_reg ;
unsigned long flags ;
struct qla24xx_fw_dump * fw ;
uint32_t ext_mem_cnt ;
2007-07-20 07:37:34 +04:00
void * nxt ;
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
risc_address = ext_mem_cnt = 0 ;
flags = 0 ;
if ( ! hardware_locked )
spin_lock_irqsave ( & ha - > hardware_lock , flags ) ;
2006-05-18 02:09:50 +04:00
if ( ! ha - > fw_dump ) {
2005-07-06 21:30:36 +04:00
qla_printk ( KERN_WARNING , ha ,
" No buffer available for dump!!! \n " ) ;
goto qla24xx_fw_dump_failed ;
}
if ( ha - > fw_dumped ) {
qla_printk ( KERN_WARNING , ha ,
" Firmware has been previously dumped (%p) -- ignoring "
2006-05-18 02:09:50 +04:00
" request... \n " , ha - > fw_dump ) ;
2005-07-06 21:30:36 +04:00
goto qla24xx_fw_dump_failed ;
}
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
2006-06-24 03:10:29 +04:00
fw - > host_status = htonl ( RD_REG_DWORD ( & reg - > host_status ) ) ;
2005-07-06 21:30:36 +04:00
/* Pause RISC. */
2007-07-26 22:41:13 +04:00
rval = qla24xx_pause_risc ( reg ) ;
if ( rval ! = QLA_SUCCESS )
goto qla24xx_fw_dump_failed_0 ;
/* Host interface registers. */
dmp_reg = & reg - > flash_addr ;
for ( cnt = 0 ; cnt < sizeof ( fw - > host_reg ) / 4 ; cnt + + )
fw - > host_reg [ cnt ] = htonl ( RD_REG_DWORD ( dmp_reg + + ) ) ;
/* Disable interrupts. */
WRT_REG_DWORD ( & reg - > ictrl , 0 ) ;
RD_REG_DWORD ( & reg - > ictrl ) ;
/* Shadow registers. */
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 ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0100000 ) ;
fw - > shadow_reg [ 1 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0200000 ) ;
fw - > shadow_reg [ 2 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0300000 ) ;
fw - > shadow_reg [ 3 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0400000 ) ;
fw - > shadow_reg [ 4 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0500000 ) ;
fw - > shadow_reg [ 5 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0600000 ) ;
fw - > shadow_reg [ 6 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
/* Mailbox registers. */
mbx_reg = & reg - > mailbox0 ;
for ( cnt = 0 ; cnt < sizeof ( fw - > mailbox_reg ) / 2 ; cnt + + )
fw - > mailbox_reg [ cnt ] = htons ( RD_REG_WORD ( mbx_reg + + ) ) ;
/* 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 ;
for ( cnt = 0 ; cnt < 7 ; cnt + + )
* iter_reg + + = htonl ( RD_REG_DWORD ( dmp_reg + + ) ) ;
iter_reg = fw - > resp0_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7300 , 8 , iter_reg ) ;
dmp_reg = & reg - > iobase_q ;
for ( cnt = 0 ; cnt < 7 ; cnt + + )
* iter_reg + + = htonl ( RD_REG_DWORD ( dmp_reg + + ) ) ;
iter_reg = fw - > req1_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7400 , 8 , iter_reg ) ;
dmp_reg = & reg - > iobase_q ;
for ( cnt = 0 ; cnt < 7 ; cnt + + )
* iter_reg + + = htonl ( RD_REG_DWORD ( dmp_reg + + ) ) ;
/* 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
qla24xx_fw_dump_failed_0 :
2007-07-20 07:37:34 +04:00
if ( rval ! = QLA_SUCCESS ) {
qla_printk ( KERN_WARNING , ha ,
" Failed to dump firmware (%x)!!! \n " , rval ) ;
ha - > fw_dumped = 0 ;
2005-07-06 21:30:36 +04:00
2007-07-20 07:37:34 +04:00
} else {
qla_printk ( KERN_INFO , ha ,
" Firmware dump saved to temp buffer (%ld/%p). \n " ,
2008-12-10 03:45:39 +03:00
base_vha - > host_no , ha - > fw_dump ) ;
2007-07-20 07:37:34 +04:00
ha - > fw_dumped = 1 ;
}
2005-07-06 21:30:36 +04:00
2007-07-20 07:37:34 +04:00
qla24xx_fw_dump_failed :
if ( ! hardware_locked )
spin_unlock_irqrestore ( & ha - > hardware_lock , flags ) ;
}
2005-07-06 21:30:36 +04:00
2007-07-20 07:37:34 +04:00
void
2008-11-06 21:40:19 +03:00
qla25xx_fw_dump ( scsi_qla_host_t * vha , int hardware_locked )
2007-07-20 07:37:34 +04:00
{
int rval ;
uint32_t cnt ;
uint32_t risc_address ;
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 ;
uint32_t __iomem * dmp_reg ;
uint32_t * iter_reg ;
uint16_t __iomem * mbx_reg ;
unsigned long flags ;
struct qla25xx_fw_dump * fw ;
uint32_t ext_mem_cnt ;
2009-01-05 22:18:09 +03:00
void * nxt , * nxt_chain ;
2009-01-05 22:18:08 +03:00
uint32_t * 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
2007-07-20 07:37:34 +04:00
risc_address = ext_mem_cnt = 0 ;
flags = 0 ;
2005-07-06 21:30:36 +04:00
2007-07-20 07:37:34 +04:00
if ( ! hardware_locked )
spin_lock_irqsave ( & ha - > hardware_lock , flags ) ;
2005-07-06 21:30:36 +04:00
2007-07-20 07:37:34 +04:00
if ( ! ha - > fw_dump ) {
qla_printk ( KERN_WARNING , ha ,
" No buffer available for dump!!! \n " ) ;
goto qla25xx_fw_dump_failed ;
}
2005-07-06 21:30:36 +04:00
2007-07-20 07:37:34 +04:00
if ( ha - > fw_dumped ) {
qla_printk ( KERN_WARNING , ha ,
" Firmware has been previously dumped (%p) -- ignoring "
" request... \n " , ha - > fw_dump ) ;
goto qla25xx_fw_dump_failed ;
}
fw = & ha - > fw_dump - > isp . isp25 ;
qla2xxx_prep_dump ( ha , ha - > fw_dump ) ;
2007-09-21 01:07:39 +04:00
ha - > fw_dump - > version = __constant_htonl ( 2 ) ;
2005-07-06 21:30:36 +04:00
2007-07-20 07:37:34 +04:00
fw - > host_status = htonl ( RD_REG_DWORD ( & reg - > host_status ) ) ;
2005-07-06 21:30:36 +04:00
2007-07-20 07:37:34 +04:00
/* Pause RISC. */
2007-07-26 22:41:13 +04:00
rval = qla24xx_pause_risc ( reg ) ;
if ( rval ! = QLA_SUCCESS )
goto qla25xx_fw_dump_failed_0 ;
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. */
WRT_REG_DWORD ( & reg - > iobase_addr , 0x7C00 ) ;
RD_REG_DWORD ( & reg - > iobase_addr ) ;
WRT_REG_DWORD ( & reg - > iobase_window , 0x01 ) ;
dmp_reg = & reg - > iobase_c4 ;
fw - > pcie_regs [ 0 ] = htonl ( RD_REG_DWORD ( dmp_reg + + ) ) ;
fw - > pcie_regs [ 1 ] = htonl ( RD_REG_DWORD ( dmp_reg + + ) ) ;
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
2007-09-21 01:07:39 +04:00
WRT_REG_DWORD ( & reg - > iobase_window , 0x00 ) ;
RD_REG_DWORD ( & reg - > iobase_window ) ;
2007-07-26 22:41:13 +04:00
/* Host interface registers. */
dmp_reg = & reg - > flash_addr ;
for ( cnt = 0 ; cnt < sizeof ( fw - > host_reg ) / 4 ; cnt + + )
fw - > host_reg [ cnt ] = htonl ( RD_REG_DWORD ( dmp_reg + + ) ) ;
/* Disable interrupts. */
WRT_REG_DWORD ( & reg - > ictrl , 0 ) ;
RD_REG_DWORD ( & reg - > ictrl ) ;
/* Shadow registers. */
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 ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0100000 ) ;
fw - > shadow_reg [ 1 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0200000 ) ;
fw - > shadow_reg [ 2 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0300000 ) ;
fw - > shadow_reg [ 3 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0400000 ) ;
fw - > shadow_reg [ 4 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0500000 ) ;
fw - > shadow_reg [ 5 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0600000 ) ;
fw - > shadow_reg [ 6 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0700000 ) ;
fw - > shadow_reg [ 7 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0800000 ) ;
fw - > shadow_reg [ 8 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0900000 ) ;
fw - > shadow_reg [ 9 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0A00000 ) ;
fw - > shadow_reg [ 10 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
/* RISC I/O register. */
WRT_REG_DWORD ( & reg - > iobase_addr , 0x0010 ) ;
fw - > risc_io_reg = htonl ( RD_REG_DWORD ( & reg - > iobase_window ) ) ;
/* Mailbox registers. */
mbx_reg = & reg - > mailbox0 ;
for ( cnt = 0 ; cnt < sizeof ( fw - > mailbox_reg ) / 2 ; cnt + + )
fw - > mailbox_reg [ cnt ] = htons ( RD_REG_WORD ( mbx_reg + + ) ) ;
/* 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 ;
for ( cnt = 0 ; cnt < 7 ; cnt + + )
* iter_reg + + = htonl ( RD_REG_DWORD ( dmp_reg + + ) ) ;
iter_reg = fw - > resp0_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7300 , 8 , iter_reg ) ;
dmp_reg = & reg - > iobase_q ;
for ( cnt = 0 ; cnt < 7 ; cnt + + )
* iter_reg + + = htonl ( RD_REG_DWORD ( dmp_reg + + ) ) ;
iter_reg = fw - > req1_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7400 , 8 , iter_reg ) ;
dmp_reg = & reg - > iobase_q ;
for ( cnt = 0 ; cnt < 7 ; cnt + + )
* iter_reg + + = htonl ( RD_REG_DWORD ( dmp_reg + + ) ) ;
/* 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
2009-01-05 22:18:08 +03:00
nxt = 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. */
qla25xx_copy_fce ( ha , nxt_chain , & last_chain ) ;
2009-01-05 22:18:08 +03:00
if ( last_chain ) {
ha - > fw_dump - > version | = __constant_htonl ( DUMP_CHAIN_VARIANT ) ;
* last_chain | = __constant_htonl ( DUMP_CHAIN_LAST ) ;
}
2008-01-17 20:02:17 +03:00
2007-07-26 22:41:13 +04:00
qla25xx_fw_dump_failed_0 :
2007-07-20 07:37:34 +04:00
if ( rval ! = QLA_SUCCESS ) {
qla_printk ( KERN_WARNING , ha ,
" Failed to dump firmware (%x)!!! \n " , rval ) ;
ha - > fw_dumped = 0 ;
2005-07-06 21:30:36 +04:00
} else {
qla_printk ( KERN_INFO , ha ,
" Firmware dump saved to temp buffer (%ld/%p). \n " ,
2008-12-10 03:45:39 +03:00
base_vha - > host_no , ha - > fw_dump ) ;
2005-07-06 21:30:36 +04:00
ha - > fw_dumped = 1 ;
}
2007-07-20 07:37:34 +04:00
qla25xx_fw_dump_failed :
2005-07-06 21:30:36 +04:00
if ( ! hardware_locked )
spin_unlock_irqrestore ( & ha - > hardware_lock , flags ) ;
}
2009-01-05 22:18:11 +03:00
void
qla81xx_fw_dump ( scsi_qla_host_t * vha , int hardware_locked )
{
int rval ;
uint32_t cnt ;
uint32_t risc_address ;
struct qla_hw_data * ha = vha - > hw ;
struct device_reg_24xx __iomem * reg = & ha - > iobase - > isp24 ;
uint32_t __iomem * dmp_reg ;
uint32_t * iter_reg ;
uint16_t __iomem * mbx_reg ;
unsigned long flags ;
struct qla81xx_fw_dump * fw ;
uint32_t ext_mem_cnt ;
void * nxt , * nxt_chain ;
uint32_t * last_chain = NULL ;
struct scsi_qla_host * base_vha = pci_get_drvdata ( ha - > pdev ) ;
risc_address = ext_mem_cnt = 0 ;
flags = 0 ;
if ( ! hardware_locked )
spin_lock_irqsave ( & ha - > hardware_lock , flags ) ;
if ( ! ha - > fw_dump ) {
qla_printk ( KERN_WARNING , ha ,
" No buffer available for dump!!! \n " ) ;
goto qla81xx_fw_dump_failed ;
}
if ( ha - > fw_dumped ) {
qla_printk ( KERN_WARNING , ha ,
" Firmware has been previously dumped (%p) -- ignoring "
" request... \n " , ha - > fw_dump ) ;
goto qla81xx_fw_dump_failed ;
}
fw = & ha - > fw_dump - > isp . isp81 ;
qla2xxx_prep_dump ( ha , ha - > fw_dump ) ;
fw - > host_status = htonl ( RD_REG_DWORD ( & reg - > host_status ) ) ;
/* Pause RISC. */
rval = qla24xx_pause_risc ( reg ) ;
if ( rval ! = QLA_SUCCESS )
goto qla81xx_fw_dump_failed_0 ;
/* 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. */
WRT_REG_DWORD ( & reg - > iobase_addr , 0x7C00 ) ;
RD_REG_DWORD ( & reg - > iobase_addr ) ;
WRT_REG_DWORD ( & reg - > iobase_window , 0x01 ) ;
dmp_reg = & reg - > iobase_c4 ;
fw - > pcie_regs [ 0 ] = htonl ( RD_REG_DWORD ( dmp_reg + + ) ) ;
fw - > pcie_regs [ 1 ] = htonl ( RD_REG_DWORD ( dmp_reg + + ) ) ;
fw - > pcie_regs [ 2 ] = htonl ( RD_REG_DWORD ( dmp_reg ) ) ;
fw - > pcie_regs [ 3 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_window ) ) ;
WRT_REG_DWORD ( & reg - > iobase_window , 0x00 ) ;
RD_REG_DWORD ( & reg - > iobase_window ) ;
/* Host interface registers. */
dmp_reg = & reg - > flash_addr ;
for ( cnt = 0 ; cnt < sizeof ( fw - > host_reg ) / 4 ; cnt + + )
fw - > host_reg [ cnt ] = htonl ( RD_REG_DWORD ( dmp_reg + + ) ) ;
/* Disable interrupts. */
WRT_REG_DWORD ( & reg - > ictrl , 0 ) ;
RD_REG_DWORD ( & reg - > ictrl ) ;
/* Shadow registers. */
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 ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0100000 ) ;
fw - > shadow_reg [ 1 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0200000 ) ;
fw - > shadow_reg [ 2 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0300000 ) ;
fw - > shadow_reg [ 3 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0400000 ) ;
fw - > shadow_reg [ 4 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0500000 ) ;
fw - > shadow_reg [ 5 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0600000 ) ;
fw - > shadow_reg [ 6 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0700000 ) ;
fw - > shadow_reg [ 7 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0800000 ) ;
fw - > shadow_reg [ 8 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0900000 ) ;
fw - > shadow_reg [ 9 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
WRT_REG_DWORD ( & reg - > iobase_select , 0xB0A00000 ) ;
fw - > shadow_reg [ 10 ] = htonl ( RD_REG_DWORD ( & reg - > iobase_sdata ) ) ;
/* RISC I/O register. */
WRT_REG_DWORD ( & reg - > iobase_addr , 0x0010 ) ;
fw - > risc_io_reg = htonl ( RD_REG_DWORD ( & reg - > iobase_window ) ) ;
/* Mailbox registers. */
mbx_reg = & reg - > mailbox0 ;
for ( cnt = 0 ; cnt < sizeof ( fw - > mailbox_reg ) / 2 ; cnt + + )
fw - > mailbox_reg [ cnt ] = htons ( RD_REG_WORD ( mbx_reg + + ) ) ;
/* 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 ;
for ( cnt = 0 ; cnt < 7 ; cnt + + )
* iter_reg + + = htonl ( RD_REG_DWORD ( dmp_reg + + ) ) ;
iter_reg = fw - > resp0_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7300 , 8 , iter_reg ) ;
dmp_reg = & reg - > iobase_q ;
for ( cnt = 0 ; cnt < 7 ; cnt + + )
* iter_reg + + = htonl ( RD_REG_DWORD ( dmp_reg + + ) ) ;
iter_reg = fw - > req1_dma_reg ;
iter_reg = qla24xx_read_window ( reg , 0x7400 , 8 , iter_reg ) ;
dmp_reg = & reg - > iobase_q ;
for ( cnt = 0 ; cnt < 7 ; cnt + + )
* iter_reg + + = htonl ( RD_REG_DWORD ( dmp_reg + + ) ) ;
/* 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 ) ;
nxt = qla24xx_copy_eft ( ha , nxt ) ;
/* Chain entries -- started with MQ. */
qla25xx_copy_fce ( ha , nxt_chain , & last_chain ) ;
if ( last_chain ) {
ha - > fw_dump - > version | = __constant_htonl ( DUMP_CHAIN_VARIANT ) ;
* last_chain | = __constant_htonl ( DUMP_CHAIN_LAST ) ;
}
qla81xx_fw_dump_failed_0 :
if ( rval ! = QLA_SUCCESS ) {
qla_printk ( KERN_WARNING , ha ,
" Failed to dump firmware (%x)!!! \n " , rval ) ;
ha - > fw_dumped = 0 ;
} else {
qla_printk ( KERN_INFO , ha ,
" Firmware dump saved to temp buffer (%ld/%p). \n " ,
base_vha - > host_no , ha - > fw_dump ) ;
ha - > fw_dumped = 1 ;
}
qla81xx_fw_dump_failed :
if ( ! hardware_locked )
spin_unlock_irqrestore ( & ha - > hardware_lock , flags ) ;
}
2005-04-17 02:20:36 +04:00
/****************************************************************************/
/* Driver Debug Functions. */
/****************************************************************************/
2005-07-06 21:32:07 +04:00
void
2008-11-06 21:40:19 +03:00
qla2x00_dump_regs ( scsi_qla_host_t * vha )
2005-04-17 02:20:36 +04:00
{
2007-08-13 05:22:56 +04:00
int i ;
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 ;
2007-08-13 05:22:56 +04:00
struct device_reg_24xx __iomem * reg24 = & ha - > iobase - > isp24 ;
uint16_t __iomem * mbx_reg ;
mbx_reg = IS_FWI2_CAPABLE ( ha ) ? & reg24 - > mailbox0 :
MAILBOX_REG ( ha , reg , 0 ) ;
2005-04-17 02:20:36 +04:00
printk ( " Mailbox registers: \n " ) ;
2007-08-13 05:22:56 +04:00
for ( i = 0 ; i < 6 ; i + + )
2008-11-06 21:40:19 +03:00
printk ( " scsi(%ld): mbox %d 0x%04x \n " , vha - > host_no , i ,
2007-08-13 05:22:56 +04:00
RD_REG_WORD ( mbx_reg + + ) ) ;
2005-04-17 02:20:36 +04:00
}
void
2005-07-06 21:32:07 +04:00
qla2x00_dump_buffer ( uint8_t * b , uint32_t size )
2005-04-17 02:20:36 +04:00
{
uint32_t cnt ;
uint8_t c ;
printk ( " 0 1 2 3 4 5 6 7 8 9 "
" Ah Bh Ch Dh Eh Fh \n " ) ;
printk ( " ---------------------------------------- "
" ---------------------- \n " ) ;
for ( cnt = 0 ; cnt < size ; ) {
c = * b + + ;
printk ( " %02x " , ( uint32_t ) c ) ;
cnt + + ;
if ( ! ( cnt % 16 ) )
printk ( " \n " ) ;
else
printk ( " " ) ;
}
if ( cnt % 16 )
printk ( " \n " ) ;
}
2008-12-10 03:45:39 +03:00