Re: [PATCH 3/6] qla2xxx: Enable target mode support for ISP83xx.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Saurav, Arun & Co,

Very exciting to see this code submitted to linux-scsi for-3.8

On Fri, 2012-12-07 at 02:30 -0500, Saurav Kashyap wrote:
> From: Arun Easi <arun.easi@xxxxxxxxxx>
> 
> Signed-off-by: Arun Easi <arun.easi@xxxxxxxxxx>
> Signed-off-by: Saurav Kashyap <saurav.kashyap@xxxxxxxxxx>
> ---
>  drivers/scsi/qla2xxx/qla_dbg.c    |    2 +-
>  drivers/scsi/qla2xxx/qla_def.h    |    8 ++
>  drivers/scsi/qla2xxx/qla_fw.h     |    3 +-
>  drivers/scsi/qla2xxx/qla_init.c   |    6 +-
>  drivers/scsi/qla2xxx/qla_isr.c    |   16 +++-
>  drivers/scsi/qla2xxx/qla_os.c     |    4 +
>  drivers/scsi/qla2xxx/qla_target.c |  159 +++++++++++++++++++++++++++++++++----
>  drivers/scsi/qla2xxx/qla_target.h |   14 +++-
>  8 files changed, 187 insertions(+), 25 deletions(-)
> 

For the 83xx target LLD specific pieces:

Acked-by: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>

Thank you!

> diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
> index f7cdd25..e690d05 100644
> --- a/drivers/scsi/qla2xxx/qla_dbg.c
> +++ b/drivers/scsi/qla2xxx/qla_dbg.c
> @@ -39,7 +39,7 @@
>   * | MultiQ                       |       0xc00c       |		|
>   * | Misc                         |       0xd010       |		|
>   * | Target Mode		  |	  0xe06f       |		|
> - * | Target Mode Management	  |	  0xf071       |		|
> + * | Target Mode Management	  |	  0xf072       |		|
>   * | Target Mode Task Management  |	  0x1000b      |		|
>   * ----------------------------------------------------------------------
>   */
> diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
> index 06c6271..b5fc478 100644
> --- a/drivers/scsi/qla2xxx/qla_def.h
> +++ b/drivers/scsi/qla2xxx/qla_def.h
> @@ -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;
> diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
> index be6d61a..7105d5e 100644
> --- a/drivers/scsi/qla2xxx/qla_fw.h
> +++ b/drivers/scsi/qla2xxx/qla_fw.h
> @@ -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;
> diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
> index 81e8cca..a581c85 100644
> --- a/drivers/scsi/qla2xxx/qla_init.c
> +++ b/drivers/scsi/qla2xxx/qla_init.c
> @@ -1964,7 +1964,7 @@ qla24xx_config_rings(struct scsi_qla_host *vha)
>  		WRT_REG_DWORD(&reg->isp24.rsp_q_in, 0);
>  		WRT_REG_DWORD(&reg->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);
> diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
> index 1b192c8..26a3086 100644
> --- a/drivers/scsi/qla2xxx/qla_isr.c
> +++ b/drivers/scsi/qla2xxx/qla_isr.c
> @@ -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);
> diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
> index 9a826aa0..519e7b8 100644
> --- a/drivers/scsi/qla2xxx/qla_os.c
> +++ b/drivers/scsi/qla2xxx/qla_os.c
> @@ -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;
> diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
> index b57ef31..41c3a40 100644
> --- a/drivers/scsi/qla2xxx/qla_target.c
> +++ b/drivers/scsi/qla2xxx/qla_target.c
> @@ -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;
> @@ -4647,7 +4648,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;
>  
> @@ -4675,26 +4675,28 @@ qlt_24xx_process_atio_queue(struct scsi_qla_host *vha)
>  	}
>  
>  	/* Adjust ring index */
> -	WRT_REG_DWORD(&reg->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(&reg->isp25mq.atio_q_in, 0);
> -		WRT_REG_DWORD(&reg->isp25mq.atio_q_out, 0);
> -		RD_REG_DWORD(&reg->isp25mq.atio_q_out);
> -#endif
> -	} else {
> -		/* Setup APTIO registers for target mode */
> -		WRT_REG_DWORD(&reg->isp24.atio_q_in, 0);
> -		WRT_REG_DWORD(&reg->isp24.atio_q_out, 0);
> -		RD_REG_DWORD(&reg->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);
>  	}
>  }
>  
> @@ -4777,6 +4779,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)
> @@ -4809,11 +4906,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)
>  {
> diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
> index fc61d6a..ff9ccb9 100644
> --- a/drivers/scsi/qla2xxx/qla_target.h
> +++ b/drivers/scsi/qla2xxx/qla_target.h
> @@ -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 */


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux