|
@@ -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)
|
|
|
{
|