Skip to content

Commit

Permalink
[SCSI] qla2xxx: IDC implementation for ISP83xx.
Browse files Browse the repository at this point in the history
Signed-off-by: Santosh Vernekar <santosh.vernekar@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
  • Loading branch information
Santosh Vernekar authored and James Bottomley committed Sep 24, 2012
1 parent 40129a4 commit 7d613ac
Show file tree
Hide file tree
Showing 13 changed files with 1,621 additions and 97 deletions.
60 changes: 49 additions & 11 deletions drivers/scsi/qla2xxx/qla_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,7 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
struct qla_hw_data *ha = vha->hw;
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
int type;
uint32_t idc_control;

if (off != 0)
return -EINVAL;
Expand All @@ -587,22 +588,36 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
scsi_unblock_requests(vha->host);
break;
case 0x2025d:
if (!IS_QLA81XX(ha) || !IS_QLA8031(ha))
if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha))
return -EPERM;

ql_log(ql_log_info, vha, 0x706f,
"Issuing MPI reset.\n");

/* Make sure FC side is not in reset */
qla2x00_wait_for_hba_online(vha);

/* Issue MPI reset */
scsi_block_requests(vha->host);
if (qla81xx_restart_mpi_firmware(vha) != QLA_SUCCESS)
ql_log(ql_log_warn, vha, 0x7070,
"MPI reset failed.\n");
scsi_unblock_requests(vha->host);
break;
if (IS_QLA83XX(ha)) {
uint32_t idc_control;

qla83xx_idc_lock(vha, 0);
__qla83xx_get_idc_control(vha, &idc_control);
idc_control |= QLA83XX_IDC_GRACEFUL_RESET;
__qla83xx_set_idc_control(vha, idc_control);
qla83xx_wr_reg(vha, QLA83XX_IDC_DEV_STATE,
QLA8XXX_DEV_NEED_RESET);
qla83xx_idc_audit(vha, IDC_AUDIT_TIMESTAMP);
qla83xx_idc_unlock(vha, 0);
break;
} else {
/* Make sure FC side is not in reset */
qla2x00_wait_for_hba_online(vha);

/* Issue MPI reset */
scsi_block_requests(vha->host);
if (qla81xx_restart_mpi_firmware(vha) != QLA_SUCCESS)
ql_log(ql_log_warn, vha, 0x7070,
"MPI reset failed.\n");
scsi_unblock_requests(vha->host);
break;
}
case 0x2025e:
if (!IS_QLA82XX(ha) || vha != base_vha) {
ql_log(ql_log_info, vha, 0x7071,
Expand All @@ -616,6 +631,29 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
qla2xxx_wake_dpc(vha);
qla2x00_wait_for_fcoe_ctx_reset(vha);
break;
case 0x2025f:
if (!IS_QLA8031(ha))
return -EPERM;
ql_log(ql_log_info, vha, 0x70bc,
"Disabling Reset by IDC control\n");
qla83xx_idc_lock(vha, 0);
__qla83xx_get_idc_control(vha, &idc_control);
idc_control |= QLA83XX_IDC_RESET_DISABLED;
__qla83xx_set_idc_control(vha, idc_control);
qla83xx_idc_unlock(vha, 0);
break;
case 0x20260:
if (!IS_QLA8031(ha))
return -EPERM;
ql_log(ql_log_info, vha, 0x70bd,
"Enabling Reset by IDC control\n");
qla83xx_idc_lock(vha, 0);
__qla83xx_get_idc_control(vha, &idc_control);
idc_control &= ~QLA83XX_IDC_RESET_DISABLED;
__qla83xx_set_idc_control(vha, idc_control);
qla83xx_idc_unlock(vha, 0);
break;

}
return count;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/qla2xxx/qla_bsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1364,7 +1364,7 @@ qla2x00_read_optrom(struct fc_bsg_job *bsg_job)
struct qla_hw_data *ha = vha->hw;
int rval = 0;

if (ha->flags.isp82xx_reset_hdlr_active)
if (ha->flags.nic_core_reset_hdlr_active)
return -EBUSY;

rval = qla2x00_optrom_setup(bsg_job, vha, 0);
Expand Down
10 changes: 5 additions & 5 deletions drivers/scsi/qla2xxx/qla_dbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@
* ----------------------------------------------------------------------
* | Level | Last Value Used | Holes |
* ----------------------------------------------------------------------
* | Module Init and Probe | 0x0123 | 0x4b,0xba,0xfa |
* | Mailbox commands | 0x1140 | 0x111a-0x111b |
* | Module Init and Probe | 0x0124 | 0x4b,0xba,0xfa |
* | Mailbox commands | 0x114c | 0x111a-0x111b |
* | | | 0x112c-0x112e |
* | | | 0x113a |
* | Device Discovery | 0x2087 | 0x2020-0x2022 |
* | Queue Command and IO tracing | 0x3030 | 0x3006,0x3008 |
* | | | 0x302d-0x302e |
* | DPC Thread | 0x401c | 0x4002,0x4013 |
* | Async Events | 0x505f | 0x502b-0x502f |
* | Async Events | 0x506c | 0x502b-0x502f |
* | | | 0x5047,0x5052 |
* | Timer Routines | 0x6011 | |
* | User Space Interactions | 0x70bb | 0x7018,0x702e, |
* | User Space Interactions | 0x70bd | 0x7018,0x702e, |
* | | | 0x7039,0x7045, |
* | | | 0x7073-0x7075, |
* | | | 0x708c, |
Expand All @@ -33,7 +33,7 @@
* | | | 0x800b,0x8039 |
* | AER/EEH | 0x9011 | |
* | Virtual Port | 0xa007 | |
* | ISP82XX Specific | 0xb055 | 0xb024 |
* | ISP82XX Specific | 0xb080 | 0xb024 |
* | MultiQ | 0xc00c | |
* | Misc | 0xd010 | |
* | Target Mode | 0xe06f | |
Expand Down
101 changes: 97 additions & 4 deletions drivers/scsi/qla2xxx/qla_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,82 @@
#define WRT_REG_WORD(addr, data) writew(data,addr)
#define WRT_REG_DWORD(addr, data) writel(data,addr)

/*
* ISP83XX specific remote register addresses
*/
#define QLA83XX_LED_PORT0 0x00201320
#define QLA83XX_LED_PORT1 0x00201328
#define QLA83XX_IDC_DEV_STATE 0x22102384
#define QLA83XX_IDC_MAJOR_VERSION 0x22102380
#define QLA83XX_IDC_MINOR_VERSION 0x22102398
#define QLA83XX_IDC_DRV_PRESENCE 0x22102388
#define QLA83XX_IDC_DRIVER_ACK 0x2210238c
#define QLA83XX_IDC_CONTROL 0x22102390
#define QLA83XX_IDC_AUDIT 0x22102394
#define QLA83XX_IDC_LOCK_RECOVERY 0x2210239c
#define QLA83XX_DRIVER_LOCKID 0x22102104
#define QLA83XX_DRIVER_LOCK 0x8111c028
#define QLA83XX_DRIVER_UNLOCK 0x8111c02c
#define QLA83XX_FLASH_LOCKID 0x22102100
#define QLA83XX_FLASH_LOCK 0x8111c010
#define QLA83XX_FLASH_UNLOCK 0x8111c014
#define QLA83XX_DEV_PARTINFO1 0x221023e0
#define QLA83XX_DEV_PARTINFO2 0x221023e4
#define QLA83XX_FW_HEARTBEAT 0x221020b0
#define QLA83XX_PEG_HALT_STATUS1 0x221020a8
#define QLA83XX_PEG_HALT_STATUS2 0x221020ac

/* 83XX: Macros defining 8200 AEN Reason codes */
#define IDC_DEVICE_STATE_CHANGE BIT_0
#define IDC_PEG_HALT_STATUS_CHANGE BIT_1
#define IDC_NIC_FW_REPORTED_FAILURE BIT_2
#define IDC_HEARTBEAT_FAILURE BIT_3

/* 83XX: Macros defining 8200 AEN Error-levels */
#define ERR_LEVEL_NON_FATAL 0x1
#define ERR_LEVEL_RECOVERABLE_FATAL 0x2
#define ERR_LEVEL_UNRECOVERABLE_FATAL 0x4

/* 83XX: Macros for IDC Version */
#define QLA83XX_SUPP_IDC_MAJOR_VERSION 0x01
#define QLA83XX_SUPP_IDC_MINOR_VERSION 0x0

/* 83XX: Macros for scheduling dpc tasks */
#define QLA83XX_NIC_CORE_RESET 0x1
#define QLA83XX_IDC_STATE_HANDLER 0x2
#define QLA83XX_NIC_CORE_UNRECOVERABLE 0x3

/* 83XX: Macros for defining IDC-Control bits */
#define QLA83XX_IDC_RESET_DISABLED BIT_0
#define QLA83XX_IDC_GRACEFUL_RESET BIT_1

/* 83XX: Macros for different timeouts */
#define QLA83XX_IDC_INITIALIZATION_TIMEOUT 30
#define QLA83XX_IDC_RESET_ACK_TIMEOUT 10
#define QLA83XX_MAX_LOCK_RECOVERY_WAIT (2 * HZ)

/* 83XX: Macros for defining class in DEV-Partition Info register */
#define QLA83XX_CLASS_TYPE_NONE 0x0
#define QLA83XX_CLASS_TYPE_NIC 0x1
#define QLA83XX_CLASS_TYPE_FCOE 0x2
#define QLA83XX_CLASS_TYPE_ISCSI 0x3

/* 83XX: Macros for IDC Lock-Recovery stages */
#define IDC_LOCK_RECOVERY_STAGE1 0x1 /* Stage1: Intent for
* lock-recovery
*/
#define IDC_LOCK_RECOVERY_STAGE2 0x2 /* Stage2: Perform lock-recovery */

/* 83XX: Macros for IDC Audit type */
#define IDC_AUDIT_TIMESTAMP 0x0 /* IDC-AUDIT: Record timestamp of
* dev-state change to NEED-RESET
* or NEED-QUIESCENT
*/
#define IDC_AUDIT_COMPLETION 0x1 /* IDC-AUDIT: Record duration of
* reset-recovery completion is
* second
*/

/*
* The ISP2312 v2 chip cannot access the FLASH/GPIO registers via MMIO in an
* 133Mhz slot.
Expand Down Expand Up @@ -596,6 +672,9 @@ typedef struct {
#define MBA_DISCARD_RND_FRAME 0x8048 /* discard RND frame due to error. */
#define MBA_REJECTED_FCP_CMD 0x8049 /* rejected FCP_CMD. */

/* 83XX FCoE specific */
#define MBA_IDC_AEN 0x8200 /* FCoE: NIC Core state change AEN */

/* ISP mailbox loopback echo diagnostic error code */
#define MBS_LB_RESET 0x17
/*
Expand Down Expand Up @@ -2523,11 +2602,12 @@ struct qla_hw_data {
uint32_t disable_msix_handshake :1;
uint32_t fcp_prio_enabled :1;
uint32_t isp82xx_fw_hung:1;
uint32_t nic_core_hung:1;

uint32_t quiesce_owner:1;
uint32_t thermal_supported:1;
uint32_t isp82xx_reset_hdlr_active:1;
uint32_t isp82xx_reset_owner:1;
uint32_t nic_core_reset_hdlr_active:1;
uint32_t nic_core_reset_owner:1;
uint32_t isp82xx_no_md_cap:1;
uint32_t host_shutting_down:1;
/* 30 bits */
Expand Down Expand Up @@ -2912,8 +2992,8 @@ struct qla_hw_data {
unsigned long mn_win_crb;
unsigned long ms_win_crb;
int qdr_sn_window;
uint32_t nx_dev_init_timeout;
uint32_t nx_reset_timeout;
uint32_t fcoe_dev_init_timeout;
uint32_t fcoe_reset_timeout;
rwlock_t hw_lock;
uint16_t portnum; /* port number */
int link_width;
Expand All @@ -2935,6 +3015,19 @@ struct qla_hw_data {
uint32_t md_dump_size;

void *loop_id_map;

/* QLA83XX IDC specific fields */
uint32_t idc_audit_ts;

/* DPC low-priority workqueue */
struct workqueue_struct *dpc_lp_wq;
struct work_struct idc_aen;
/* DPC high-priority workqueue */
struct workqueue_struct *dpc_hp_wq;
struct work_struct nic_core_reset;
struct work_struct idc_state_handler;
struct work_struct nic_core_unrecoverable;

struct qlt_hw_data tgt;
};

Expand Down
5 changes: 4 additions & 1 deletion drivers/scsi/qla2xxx/qla_fw.h
Original file line number Diff line number Diff line change
Expand Up @@ -1540,7 +1540,10 @@ struct access_chip_rsp_84xx {
/*
* ISP83xx mailbox commands
*/
#define MBC_WRITE_REMOTE_REG 0x0001 /* Write remote register */
#define MBC_WRITE_REMOTE_REG 0x0001 /* Write remote register */
#define MBC_READ_REMOTE_REG 0x0009 /* Read remote register */
#define MBC_RESTART_NIC_FIRMWARE 0x003d /* Restart NIC firmware */
#define MBC_SET_ACCESS_CONTROL 0x003e /* Access control command */

/* Flash access control option field bit definitions */
#define FAC_OPT_FORCE_SEMAPHORE BIT_15
Expand Down
28 changes: 27 additions & 1 deletion drivers/scsi/qla2xxx/qla_gbl.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ extern int qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *, fc_port_t *);

extern fc_port_t *
qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t );

extern int __qla83xx_set_idc_control(scsi_qla_host_t *, uint32_t);
extern int __qla83xx_get_idc_control(scsi_qla_host_t *, uint32_t *);
extern void qla83xx_idc_audit(scsi_qla_host_t *, int);
extern int qla83xx_nic_core_reset(scsi_qla_host_t *);
extern void qla83xx_reset_ownership(scsi_qla_host_t *);

/*
* Global Data in qla_os.c source file.
*/
Expand Down Expand Up @@ -133,6 +140,20 @@ extern void qla2x00_relogin(struct scsi_qla_host *);
extern void qla2x00_do_work(struct scsi_qla_host *);
extern void qla2x00_free_fcports(struct scsi_qla_host *);

extern void qla83xx_schedule_work(scsi_qla_host_t *, int);
extern void qla83xx_service_idc_aen(struct work_struct *);
extern void qla83xx_nic_core_unrecoverable_work(struct work_struct *);
extern void qla83xx_idc_state_handler_work(struct work_struct *);
extern void qla83xx_nic_core_reset_work(struct work_struct *);

extern void qla83xx_idc_lock(scsi_qla_host_t *, uint16_t);
extern void qla83xx_idc_unlock(scsi_qla_host_t *, uint16_t);
extern int qla83xx_idc_state_handler(scsi_qla_host_t *);
extern int qla83xx_set_drv_presence(scsi_qla_host_t *vha);
extern int __qla83xx_set_drv_presence(scsi_qla_host_t *vha);
extern int qla83xx_clear_drv_presence(scsi_qla_host_t *vha);
extern int __qla83xx_clear_drv_presence(scsi_qla_host_t *vha);

/*
* Global Functions in qla_mid.c source file.
*/
Expand Down Expand Up @@ -421,7 +442,11 @@ extern void qla24xx_beacon_blink(struct scsi_qla_host *);
extern void qla83xx_beacon_blink(struct scsi_qla_host *);
extern int qla82xx_beacon_on(struct scsi_qla_host *);
extern int qla82xx_beacon_off(struct scsi_qla_host *);
extern int qla83xx_write_remote_reg(struct scsi_qla_host *, uint32_t, uint32_t);
extern int qla83xx_wr_reg(scsi_qla_host_t *, uint32_t, uint32_t);
extern int qla83xx_rd_reg(scsi_qla_host_t *, uint32_t, uint32_t *);
extern int qla83xx_restart_nic_firmware(scsi_qla_host_t *);
extern int qla83xx_access_control(scsi_qla_host_t *, uint16_t, uint32_t,
uint32_t, uint16_t *);

extern uint8_t *qla2x00_read_optrom_data(struct scsi_qla_host *, uint8_t *,
uint32_t, uint32_t);
Expand Down Expand Up @@ -582,6 +607,7 @@ extern uint32_t qla82xx_wait_for_state_change(scsi_qla_host_t *, uint32_t);
extern int qla82xx_idc_lock(struct qla_hw_data *);
extern void qla82xx_idc_unlock(struct qla_hw_data *);
extern int qla82xx_device_state_handler(scsi_qla_host_t *);
extern void qla8xxx_dev_failed_handler(scsi_qla_host_t *);
extern void qla82xx_clear_qsnt_ready(scsi_qla_host_t *);

extern void qla2x00_set_model_info(scsi_qla_host_t *, uint8_t *,
Expand Down
Loading

0 comments on commit 7d613ac

Please sign in to comment.