Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cb69f7de authored by James Smart's avatar James Smart Committed by James Bottomley
Browse files

[SCSI] lpfc 8.3.28: Add support for ABTS failure handling



Add support for ABTS failure handling:

- Add asynchronous ABTS notification event feature to driver (CR 124578)
- Change driver message 3092 and 3116 to KERN_WARNING (CR 124768)
- Alter the SCR ELS command to use the temporary RPI and the
  Destination DID for SLI4-FC (CR 126070)

Signed-off-by: default avatarAlex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: default avatarJames Smart <james.smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent ff78d8f9
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -106,7 +106,7 @@ void lpfc_cleanup(struct lpfc_vport *);
void lpfc_disc_timeout(unsigned long);

struct lpfc_nodelist *__lpfc_findnode_rpi(struct lpfc_vport *, uint16_t);

struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_vport *, uint16_t);
void lpfc_worker_wake_up(struct lpfc_hba *);
int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t);
int lpfc_do_work(void *);
@@ -455,3 +455,5 @@ int lpfc_sli4_queue_create(struct lpfc_hba *);
void lpfc_sli4_queue_destroy(struct lpfc_hba *);
int lpfc_sli4_read_config(struct lpfc_hba *phba);
int lpfc_scsi_buf_update(struct lpfc_hba *phba);
void lpfc_sli4_abts_err_handler(struct lpfc_hba *, struct lpfc_nodelist *,
				struct sli4_wcqe_xri_aborted *);
+0 −50
Original line number Diff line number Diff line
@@ -6595,56 +6595,6 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
	phba->fc_stat.elsRcvDrop++;
}

/**
 * lpfc_find_vport_by_vpid - Find a vport on a HBA through vport identifier
 * @phba: pointer to lpfc hba data structure.
 * @vpi: host virtual N_Port identifier.
 *
 * This routine finds a vport on a HBA (referred by @phba) through a
 * @vpi. The function walks the HBA's vport list and returns the address
 * of the vport with the matching @vpi.
 *
 * Return code
 *    NULL - No vport with the matching @vpi found
 *    Otherwise - Address to the vport with the matching @vpi.
 **/
struct lpfc_vport *
lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi)
{
	struct lpfc_vport *vport;
	unsigned long flags;
	int i = 0;

	/* The physical ports are always vpi 0 - translate is unnecessary. */
	if (vpi > 0) {
		/*
		 * Translate the physical vpi to the logical vpi.  The
		 * vport stores the logical vpi.
		 */
		for (i = 0; i < phba->max_vpi; i++) {
			if (vpi == phba->vpi_ids[i])
				break;
		}

		if (i >= phba->max_vpi) {
			lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
					 "2936 Could not find Vport mapped "
					 "to vpi %d\n", vpi);
			return NULL;
		}
	}

	spin_lock_irqsave(&phba->hbalock, flags);
	list_for_each_entry(vport, &phba->port_list, listentry) {
		if (vport->vpi == i) {
			spin_unlock_irqrestore(&phba->hbalock, flags);
			return vport;
		}
	}
	spin_unlock_irqrestore(&phba->hbalock, flags);
	return NULL;
}

/**
 * lpfc_els_unsol_event - Process an unsolicited event from an els sli ring
 * @phba: pointer to lpfc hba data structure.
+67 −0
Original line number Diff line number Diff line
@@ -5352,6 +5352,73 @@ lpfc_findnode_wwpn(struct lpfc_vport *vport, struct lpfc_name *wwpn)
	return ndlp;
}

/*
 * This routine looks up the ndlp lists for the given RPI. If the rpi
 * is found, the routine returns the node element list pointer else
 * return NULL.
 */
struct lpfc_nodelist *
lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi)
{
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
	struct lpfc_nodelist *ndlp;

	spin_lock_irq(shost->host_lock);
	ndlp = __lpfc_findnode_rpi(vport, rpi);
	spin_unlock_irq(shost->host_lock);
	return ndlp;
}

/**
 * lpfc_find_vport_by_vpid - Find a vport on a HBA through vport identifier
 * @phba: pointer to lpfc hba data structure.
 * @vpi: the physical host virtual N_Port identifier.
 *
 * This routine finds a vport on a HBA (referred by @phba) through a
 * @vpi. The function walks the HBA's vport list and returns the address
 * of the vport with the matching @vpi.
 *
 * Return code
 *    NULL - No vport with the matching @vpi found
 *    Otherwise - Address to the vport with the matching @vpi.
 **/
struct lpfc_vport *
lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi)
{
	struct lpfc_vport *vport;
	unsigned long flags;
	int i = 0;

	/* The physical ports are always vpi 0 - translate is unnecessary. */
	if (vpi > 0) {
		/*
		 * Translate the physical vpi to the logical vpi.  The
		 * vport stores the logical vpi.
		 */
		for (i = 0; i < phba->max_vpi; i++) {
			if (vpi == phba->vpi_ids[i])
				break;
		}

		if (i >= phba->max_vpi) {
			lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
					 "2936 Could not find Vport mapped "
					 "to vpi %d\n", vpi);
			return NULL;
		}
	}

	spin_lock_irqsave(&phba->hbalock, flags);
	list_for_each_entry(vport, &phba->port_list, listentry) {
		if (vport->vpi == i) {
			spin_unlock_irqrestore(&phba->hbalock, flags);
			return vport;
		}
	}
	spin_unlock_irqrestore(&phba->hbalock, flags);
	return NULL;
}

void
lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
	      uint32_t did)
+9 −4
Original line number Diff line number Diff line
@@ -2819,7 +2819,8 @@ typedef struct {
#ifdef __BIG_ENDIAN_BITFIELD
	uint32_t rsvd1     : 19;  /* Reserved                             */
	uint32_t cdss      :  1;  /* Configure Data Security SLI          */
	uint32_t rsvd2     :  3;  /* Reserved                             */
	uint32_t casabt    :  1;  /* Configure async abts status notice   */
	uint32_t rsvd2     :  2;  /* Reserved                             */
	uint32_t cbg       :  1;  /* Configure BlockGuard                 */
	uint32_t cmv       :  1;  /* Configure Max VPIs                   */
	uint32_t ccrp      :  1;  /* Config Command Ring Polling          */
@@ -2839,14 +2840,16 @@ typedef struct {
	uint32_t ccrp      :  1;  /* Config Command Ring Polling          */
	uint32_t cmv	   :  1;  /* Configure Max VPIs                   */
	uint32_t cbg       :  1;  /* Configure BlockGuard                 */
	uint32_t rsvd2     :  3;  /* Reserved                             */
	uint32_t rsvd2     :  2;  /* Reserved                             */
	uint32_t casabt    :  1;  /* Configure async abts status notice   */
	uint32_t cdss      :  1;  /* Configure Data Security SLI          */
	uint32_t rsvd1     : 19;  /* Reserved                             */
#endif
#ifdef __BIG_ENDIAN_BITFIELD
	uint32_t rsvd3     : 19;  /* Reserved                             */
	uint32_t gdss      :  1;  /* Configure Data Security SLI          */
	uint32_t rsvd4     :  3;  /* Reserved                             */
	uint32_t gasabt    :  1;  /* Grant async abts status notice       */
	uint32_t rsvd4     :  2;  /* Reserved                             */
	uint32_t gbg       :  1;  /* Grant BlockGuard                     */
	uint32_t gmv	   :  1;  /* Grant Max VPIs                       */
	uint32_t gcrp	   :  1;  /* Grant Command Ring Polling           */
@@ -2866,7 +2869,8 @@ typedef struct {
	uint32_t gcrp	   :  1;  /* Grant Command Ring Polling           */
	uint32_t gmv	   :  1;  /* Grant Max VPIs                       */
	uint32_t gbg       :  1;  /* Grant BlockGuard                     */
	uint32_t rsvd4     :  3;  /* Reserved                             */
	uint32_t rsvd4     :  2;  /* Reserved                             */
	uint32_t gasabt    :  1;  /* Grant async abts status notice       */
	uint32_t gdss      :  1;  /* Configure Data Security SLI          */
	uint32_t rsvd3     : 19;  /* Reserved                             */
#endif
@@ -3465,6 +3469,7 @@ typedef struct {
} ASYNCSTAT_FIELDS;
#define ASYNC_TEMP_WARN		0x100
#define ASYNC_TEMP_SAFE		0x101
#define ASYNC_STATUS_CN		0x102

/* IOCB Command template for CMD_IOCB_RCV_ELS64_CX (0xB7)
   or CMD_IOCB_RCV_SEQ64_CX (0xB5) */
+4 −0
Original line number Diff line number Diff line
@@ -1293,6 +1293,10 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
		phba->sli_rev = LPFC_SLI_REV2;
	mb->un.varCfgPort.sli_mode = phba->sli_rev;

	/* If this is an SLI3 port, configure async status notification. */
	if (phba->sli_rev == LPFC_SLI_REV3)
		mb->un.varCfgPort.casabt = 1;

	/* Now setup pcb */
	phba->pcb->type = TYPE_NATIVE_SLI2;
	phba->pcb->feature = FEATURE_INITIAL_SLI2;
Loading