[SCSI] qla2xxx: Enable target mode support for ISP83xx.
Signed-off-by: Arun Easi <arun.easi@qlogic.com> Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
3c290d0b5f
commit
aa230bc55c
|
@ -39,7 +39,7 @@
|
|||
* | MultiQ | 0xc00c | |
|
||||
* | Misc | 0xd010 | |
|
||||
* | Target Mode | 0xe06f | |
|
||||
* | Target Mode Management | 0xf071 | |
|
||||
* | Target Mode Management | 0xf072 | |
|
||||
* | Target Mode Task Management | 0x1000b | |
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
|
|
@ -537,6 +537,8 @@ struct device_reg_25xxmq {
|
|||
uint32_t req_q_out;
|
||||
uint32_t rsp_q_in;
|
||||
uint32_t rsp_q_out;
|
||||
uint32_t atio_q_in;
|
||||
uint32_t atio_q_out;
|
||||
};
|
||||
|
||||
typedef union {
|
||||
|
@ -563,6 +565,9 @@ typedef union {
|
|||
&(reg)->u.isp2100.mailbox5 : \
|
||||
&(reg)->u.isp2300.rsp_q_out)
|
||||
|
||||
#define ISP_ATIO_Q_IN(vha) (vha->hw->tgt.atio_q_in)
|
||||
#define ISP_ATIO_Q_OUT(vha) (vha->hw->tgt.atio_q_out)
|
||||
|
||||
#define MAILBOX_REG(ha, reg, num) \
|
||||
(IS_QLA2100(ha) || IS_QLA2200(ha) ? \
|
||||
(num < 8 ? \
|
||||
|
@ -2559,6 +2564,8 @@ struct qlt_hw_data {
|
|||
struct atio *atio_ring_ptr; /* Current address. */
|
||||
uint16_t atio_ring_index; /* Current index. */
|
||||
uint16_t atio_q_length;
|
||||
uint32_t __iomem *atio_q_in;
|
||||
uint32_t __iomem *atio_q_out;
|
||||
|
||||
void *target_lport_ptr;
|
||||
struct qla_tgt_func_tmpl *tgt_ops;
|
||||
|
@ -2790,6 +2797,7 @@ struct qla_hw_data {
|
|||
#define IS_PI_SPLIT_DET_CAPABLE_HBA(ha) (IS_QLA83XX(ha))
|
||||
#define IS_PI_SPLIT_DET_CAPABLE(ha) (IS_PI_SPLIT_DET_CAPABLE_HBA(ha) && \
|
||||
(((ha)->fw_attributes_h << 16 | (ha)->fw_attributes) & BIT_22))
|
||||
#define IS_ATIO_MSIX_CAPABLE(ha) (IS_QLA83XX(ha))
|
||||
|
||||
/* HBA serial number */
|
||||
uint8_t serial0;
|
||||
|
|
|
@ -300,7 +300,8 @@ struct init_cb_24xx {
|
|||
uint32_t prio_request_q_address[2];
|
||||
|
||||
uint16_t msix;
|
||||
uint8_t reserved_2[6];
|
||||
uint16_t msix_atio;
|
||||
uint8_t reserved_2[4];
|
||||
|
||||
uint16_t atio_q_inpointer;
|
||||
uint16_t atio_q_length;
|
||||
|
|
|
@ -1964,7 +1964,7 @@ qla24xx_config_rings(struct scsi_qla_host *vha)
|
|||
WRT_REG_DWORD(®->isp24.rsp_q_in, 0);
|
||||
WRT_REG_DWORD(®->isp24.rsp_q_out, 0);
|
||||
}
|
||||
qlt_24xx_config_rings(vha, reg);
|
||||
qlt_24xx_config_rings(vha);
|
||||
|
||||
/* PCI posting */
|
||||
RD_REG_DWORD(&ioreg->hccr);
|
||||
|
@ -5579,6 +5579,8 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
|
|||
if (IS_T10_PI_CAPABLE(ha))
|
||||
nv->frame_payload_size &= ~7;
|
||||
|
||||
qlt_81xx_config_nvram_stage1(vha, nv);
|
||||
|
||||
/* Reset Initialization control block */
|
||||
memset(icb, 0, ha->init_cb_size);
|
||||
|
||||
|
@ -5619,6 +5621,8 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
|
|||
qla2x00_set_model_info(vha, nv->model_name, sizeof(nv->model_name),
|
||||
"QLE8XXX");
|
||||
|
||||
qlt_81xx_config_nvram_stage2(vha, icb);
|
||||
|
||||
/* Use alternate WWN? */
|
||||
if (nv->host_p & __constant_cpu_to_le32(BIT_15)) {
|
||||
memcpy(icb->node_name, nv->alternate_node_name, WWN_SIZE);
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include <scsi/scsi_bsg_fc.h>
|
||||
#include <scsi/scsi_eh.h>
|
||||
|
||||
#include "qla_target.h"
|
||||
|
||||
static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
|
||||
static void qla2x00_process_completed_request(struct scsi_qla_host *,
|
||||
struct req_que *, uint32_t);
|
||||
|
@ -2751,6 +2753,12 @@ static struct qla_init_msix_entry qla82xx_msix_entries[2] = {
|
|||
{ "qla2xxx (rsp_q)", qla82xx_msix_rsp_q },
|
||||
};
|
||||
|
||||
static struct qla_init_msix_entry qla83xx_msix_entries[3] = {
|
||||
{ "qla2xxx (default)", qla24xx_msix_default },
|
||||
{ "qla2xxx (rsp_q)", qla24xx_msix_rsp_q },
|
||||
{ "qla2xxx (atio_q)", qla83xx_msix_atio_q },
|
||||
};
|
||||
|
||||
static void
|
||||
qla24xx_disable_msix(struct qla_hw_data *ha)
|
||||
{
|
||||
|
@ -2831,9 +2839,13 @@ msix_failed:
|
|||
}
|
||||
|
||||
/* Enable MSI-X vectors for the base queue */
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (i = 0; i < ha->msix_count; i++) {
|
||||
qentry = &ha->msix_entries[i];
|
||||
if (IS_QLA82XX(ha)) {
|
||||
if (QLA_TGT_MODE_ENABLED() && IS_ATIO_MSIX_CAPABLE(ha)) {
|
||||
ret = request_irq(qentry->vector,
|
||||
qla83xx_msix_entries[i].handler,
|
||||
0, qla83xx_msix_entries[i].name, rsp);
|
||||
} else if (IS_QLA82XX(ha)) {
|
||||
ret = request_irq(qentry->vector,
|
||||
qla82xx_msix_entries[i].handler,
|
||||
0, qla82xx_msix_entries[i].name, rsp);
|
||||
|
|
|
@ -1812,6 +1812,9 @@ qla83xx_iospace_config(struct qla_hw_data *ha)
|
|||
|
||||
mqiobase_exit:
|
||||
ha->msix_count = ha->max_rsp_queues + 1;
|
||||
|
||||
qlt_83xx_iospace_config(ha);
|
||||
|
||||
ql_dbg_pci(ql_dbg_init, ha->pdev, 0x011f,
|
||||
"MSIX Count:%d.\n", ha->msix_count);
|
||||
return 0;
|
||||
|
@ -2390,6 +2393,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
ha->mbx_count = MAILBOX_REGISTER_COUNT;
|
||||
req_length = REQUEST_ENTRY_CNT_24XX;
|
||||
rsp_length = RESPONSE_ENTRY_CNT_2300;
|
||||
ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX;
|
||||
ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
|
||||
ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
|
||||
ha->gid_list_info_size = 8;
|
||||
|
|
|
@ -52,7 +52,7 @@ MODULE_PARM_DESC(qlini_mode,
|
|||
"\"disabled\" - initiator mode will never be enabled; "
|
||||
"\"enabled\" (default) - initiator mode will always stay enabled.");
|
||||
|
||||
static int ql2x_ini_mode = QLA2XXX_INI_MODE_EXCLUSIVE;
|
||||
int ql2x_ini_mode = QLA2XXX_INI_MODE_EXCLUSIVE;
|
||||
|
||||
/*
|
||||
* From scsi/fc/fc_fcp.h
|
||||
|
@ -1119,6 +1119,7 @@ static void qlt_send_notify_ack(struct scsi_qla_host *vha,
|
|||
nack->u.isp24.srr_rx_id = ntfy->u.isp24.srr_rx_id;
|
||||
nack->u.isp24.status = ntfy->u.isp24.status;
|
||||
nack->u.isp24.status_subcode = ntfy->u.isp24.status_subcode;
|
||||
nack->u.isp24.fw_handle = ntfy->u.isp24.fw_handle;
|
||||
nack->u.isp24.exchange_address = ntfy->u.isp24.exchange_address;
|
||||
nack->u.isp24.srr_rel_offs = ntfy->u.isp24.srr_rel_offs;
|
||||
nack->u.isp24.srr_ui = ntfy->u.isp24.srr_ui;
|
||||
|
@ -4666,7 +4667,6 @@ void
|
|||
qlt_24xx_process_atio_queue(struct scsi_qla_host *vha)
|
||||
{
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
|
||||
struct atio_from_isp *pkt;
|
||||
int cnt, i;
|
||||
|
||||
|
@ -4694,26 +4694,28 @@ qlt_24xx_process_atio_queue(struct scsi_qla_host *vha)
|
|||
}
|
||||
|
||||
/* Adjust ring index */
|
||||
WRT_REG_DWORD(®->atio_q_out, ha->tgt.atio_ring_index);
|
||||
WRT_REG_DWORD(ISP_ATIO_Q_OUT(vha), ha->tgt.atio_ring_index);
|
||||
}
|
||||
|
||||
void
|
||||
qlt_24xx_config_rings(struct scsi_qla_host *vha, device_reg_t __iomem *reg)
|
||||
qlt_24xx_config_rings(struct scsi_qla_host *vha)
|
||||
{
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
if (!QLA_TGT_MODE_ENABLED())
|
||||
return;
|
||||
|
||||
/* FIXME: atio_q in/out for ha->mqenable=1..? */
|
||||
if (ha->mqenable) {
|
||||
#if 0
|
||||
WRT_REG_DWORD(®->isp25mq.atio_q_in, 0);
|
||||
WRT_REG_DWORD(®->isp25mq.atio_q_out, 0);
|
||||
RD_REG_DWORD(®->isp25mq.atio_q_out);
|
||||
#endif
|
||||
} else {
|
||||
/* Setup APTIO registers for target mode */
|
||||
WRT_REG_DWORD(®->isp24.atio_q_in, 0);
|
||||
WRT_REG_DWORD(®->isp24.atio_q_out, 0);
|
||||
RD_REG_DWORD(®->isp24.atio_q_out);
|
||||
WRT_REG_DWORD(ISP_ATIO_Q_IN(vha), 0);
|
||||
WRT_REG_DWORD(ISP_ATIO_Q_OUT(vha), 0);
|
||||
RD_REG_DWORD(ISP_ATIO_Q_OUT(vha));
|
||||
|
||||
if (IS_ATIO_MSIX_CAPABLE(ha)) {
|
||||
struct qla_msix_entry *msix = &ha->msix_entries[2];
|
||||
struct init_cb_24xx *icb = (struct init_cb_24xx *)ha->init_cb;
|
||||
|
||||
icb->msix_atio = cpu_to_le16(msix->entry);
|
||||
ql_dbg(ql_dbg_init, vha, 0xf072,
|
||||
"Registering ICB vector 0x%x for atio que.\n",
|
||||
msix->entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4796,6 +4798,101 @@ qlt_24xx_config_nvram_stage2(struct scsi_qla_host *vha,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
qlt_81xx_config_nvram_stage1(struct scsi_qla_host *vha, struct nvram_81xx *nv)
|
||||
{
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
|
||||
if (!QLA_TGT_MODE_ENABLED())
|
||||
return;
|
||||
|
||||
if (qla_tgt_mode_enabled(vha)) {
|
||||
if (!ha->tgt.saved_set) {
|
||||
/* We save only once */
|
||||
ha->tgt.saved_exchange_count = nv->exchange_count;
|
||||
ha->tgt.saved_firmware_options_1 =
|
||||
nv->firmware_options_1;
|
||||
ha->tgt.saved_firmware_options_2 =
|
||||
nv->firmware_options_2;
|
||||
ha->tgt.saved_firmware_options_3 =
|
||||
nv->firmware_options_3;
|
||||
ha->tgt.saved_set = 1;
|
||||
}
|
||||
|
||||
nv->exchange_count = __constant_cpu_to_le16(0xFFFF);
|
||||
|
||||
/* Enable target mode */
|
||||
nv->firmware_options_1 |= __constant_cpu_to_le32(BIT_4);
|
||||
|
||||
/* Disable ini mode, if requested */
|
||||
if (!qla_ini_mode_enabled(vha))
|
||||
nv->firmware_options_1 |=
|
||||
__constant_cpu_to_le32(BIT_5);
|
||||
|
||||
/* Disable Full Login after LIP */
|
||||
nv->firmware_options_1 &= __constant_cpu_to_le32(~BIT_13);
|
||||
/* Enable initial LIP */
|
||||
nv->firmware_options_1 &= __constant_cpu_to_le32(~BIT_9);
|
||||
/* Enable FC tapes support */
|
||||
nv->firmware_options_2 |= __constant_cpu_to_le32(BIT_12);
|
||||
/* Disable Full Login after LIP */
|
||||
nv->host_p &= __constant_cpu_to_le32(~BIT_10);
|
||||
/* Enable target PRLI control */
|
||||
nv->firmware_options_2 |= __constant_cpu_to_le32(BIT_14);
|
||||
} else {
|
||||
if (ha->tgt.saved_set) {
|
||||
nv->exchange_count = ha->tgt.saved_exchange_count;
|
||||
nv->firmware_options_1 =
|
||||
ha->tgt.saved_firmware_options_1;
|
||||
nv->firmware_options_2 =
|
||||
ha->tgt.saved_firmware_options_2;
|
||||
nv->firmware_options_3 =
|
||||
ha->tgt.saved_firmware_options_3;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* out-of-order frames reassembly */
|
||||
nv->firmware_options_3 |= BIT_6|BIT_9;
|
||||
|
||||
if (ha->tgt.enable_class_2) {
|
||||
if (vha->flags.init_done)
|
||||
fc_host_supported_classes(vha->host) =
|
||||
FC_COS_CLASS2 | FC_COS_CLASS3;
|
||||
|
||||
nv->firmware_options_2 |= __constant_cpu_to_le32(BIT_8);
|
||||
} else {
|
||||
if (vha->flags.init_done)
|
||||
fc_host_supported_classes(vha->host) = FC_COS_CLASS3;
|
||||
|
||||
nv->firmware_options_2 &= ~__constant_cpu_to_le32(BIT_8);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
qlt_81xx_config_nvram_stage2(struct scsi_qla_host *vha,
|
||||
struct init_cb_81xx *icb)
|
||||
{
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
|
||||
if (!QLA_TGT_MODE_ENABLED())
|
||||
return;
|
||||
|
||||
if (ha->tgt.node_name_set) {
|
||||
memcpy(icb->node_name, ha->tgt.tgt_node_name, WWN_SIZE);
|
||||
icb->firmware_options_1 |= __constant_cpu_to_le32(BIT_14);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
qlt_83xx_iospace_config(struct qla_hw_data *ha)
|
||||
{
|
||||
if (!QLA_TGT_MODE_ENABLED())
|
||||
return;
|
||||
|
||||
ha->msix_count += 1; /* For ATIO Q */
|
||||
}
|
||||
|
||||
int
|
||||
qlt_24xx_process_response_error(struct scsi_qla_host *vha,
|
||||
struct sts_entry_24xx *pkt)
|
||||
|
@ -4828,11 +4925,41 @@ qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha)
|
|||
if (!QLA_TGT_MODE_ENABLED())
|
||||
return;
|
||||
|
||||
if (ha->mqenable || IS_QLA83XX(ha)) {
|
||||
ISP_ATIO_Q_IN(base_vha) = &ha->mqiobase->isp25mq.atio_q_in;
|
||||
ISP_ATIO_Q_OUT(base_vha) = &ha->mqiobase->isp25mq.atio_q_out;
|
||||
} else {
|
||||
ISP_ATIO_Q_IN(base_vha) = &ha->iobase->isp24.atio_q_in;
|
||||
ISP_ATIO_Q_OUT(base_vha) = &ha->iobase->isp24.atio_q_out;
|
||||
}
|
||||
|
||||
mutex_init(&ha->tgt.tgt_mutex);
|
||||
mutex_init(&ha->tgt.tgt_host_action_mutex);
|
||||
qlt_clear_mode(base_vha);
|
||||
}
|
||||
|
||||
irqreturn_t
|
||||
qla83xx_msix_atio_q(int irq, void *dev_id)
|
||||
{
|
||||
struct rsp_que *rsp;
|
||||
scsi_qla_host_t *vha;
|
||||
struct qla_hw_data *ha;
|
||||
unsigned long flags;
|
||||
|
||||
rsp = (struct rsp_que *) dev_id;
|
||||
ha = rsp->hw;
|
||||
vha = pci_get_drvdata(ha->pdev);
|
||||
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
|
||||
qlt_24xx_process_atio_queue(vha);
|
||||
qla24xx_process_response_queue(vha, rsp);
|
||||
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
int
|
||||
qlt_mem_alloc(struct qla_hw_data *ha)
|
||||
{
|
||||
|
|
|
@ -162,7 +162,7 @@ struct imm_ntfy_from_isp {
|
|||
uint16_t srr_rx_id;
|
||||
uint16_t status;
|
||||
uint8_t status_subcode;
|
||||
uint8_t reserved_3;
|
||||
uint8_t fw_handle;
|
||||
uint32_t exchange_address;
|
||||
uint32_t srr_rel_offs;
|
||||
uint16_t srr_ui;
|
||||
|
@ -218,7 +218,7 @@ struct nack_to_isp {
|
|||
uint16_t srr_rx_id;
|
||||
uint16_t status;
|
||||
uint8_t status_subcode;
|
||||
uint8_t reserved_3;
|
||||
uint8_t fw_handle;
|
||||
uint32_t exchange_address;
|
||||
uint32_t srr_rel_offs;
|
||||
uint16_t srr_ui;
|
||||
|
@ -949,6 +949,7 @@ extern void qlt_update_vp_map(struct scsi_qla_host *, int);
|
|||
* is not set. Right now, ha value is ignored.
|
||||
*/
|
||||
#define QLA_TGT_MODE_ENABLED() (ql2x_ini_mode != QLA2XXX_INI_MODE_ENABLED)
|
||||
extern int ql2x_ini_mode;
|
||||
|
||||
static inline bool qla_tgt_mode_enabled(struct scsi_qla_host *ha)
|
||||
{
|
||||
|
@ -986,12 +987,15 @@ extern void qlt_vport_create(struct scsi_qla_host *, struct qla_hw_data *);
|
|||
extern void qlt_rff_id(struct scsi_qla_host *, struct ct_sns_req *);
|
||||
extern void qlt_init_atio_q_entries(struct scsi_qla_host *);
|
||||
extern void qlt_24xx_process_atio_queue(struct scsi_qla_host *);
|
||||
extern void qlt_24xx_config_rings(struct scsi_qla_host *,
|
||||
device_reg_t __iomem *);
|
||||
extern void qlt_24xx_config_rings(struct scsi_qla_host *);
|
||||
extern void qlt_24xx_config_nvram_stage1(struct scsi_qla_host *,
|
||||
struct nvram_24xx *);
|
||||
extern void qlt_24xx_config_nvram_stage2(struct scsi_qla_host *,
|
||||
struct init_cb_24xx *);
|
||||
extern void qlt_81xx_config_nvram_stage2(struct scsi_qla_host *,
|
||||
struct init_cb_81xx *);
|
||||
extern void qlt_81xx_config_nvram_stage1(struct scsi_qla_host *,
|
||||
struct nvram_81xx *);
|
||||
extern int qlt_24xx_process_response_error(struct scsi_qla_host *,
|
||||
struct sts_entry_24xx *);
|
||||
extern void qlt_modify_vp_config(struct scsi_qla_host *,
|
||||
|
@ -1001,5 +1005,7 @@ extern int qlt_mem_alloc(struct qla_hw_data *);
|
|||
extern void qlt_mem_free(struct qla_hw_data *);
|
||||
extern void qlt_stop_phase1(struct qla_tgt *);
|
||||
extern void qlt_stop_phase2(struct qla_tgt *);
|
||||
extern irqreturn_t qla83xx_msix_atio_q(int, void *);
|
||||
extern void qlt_83xx_iospace_config(struct qla_hw_data *);
|
||||
|
||||
#endif /* __QLA_TARGET_H */
|
||||
|
|
Loading…
Reference in a new issue