scsi: qla2xxx: Add FC-NVMe port discovery and PRLI handling
authorDuane Grigsby <duane.grigsby@cavium.com>
Wed, 21 Jun 2017 20:48:41 +0000 (13:48 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 28 Jun 2017 01:21:47 +0000 (21:21 -0400)
Added logic to change the login process into an optional PRIL step for
FC-NVMe ports as a separate operation, such that we can change type to
0x28 (NVMe).

Currently, the driver performs the PLOGI/PRLI together as one operation,
but if the discovered port is an NVMe port then we first issue the PLOGI
and then we issue the PRLI. Also, the fabric discovery logic was changed
to mark each discovered FC NVMe port, so that we can register them with
the FC-NVMe transport later.

Signed-off-by: Darren Trapp <darren.trapp@cavium.com>
Signed-off-by: Duane Grigsby <duane.grigsby@cavium.com>
Signed-off-by: Anil Gurumurthy <anil.gurumurhty@cavium.com>
Signed-off-by: Giridhar Malavali <giridhar.malavali@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/qla2xxx/qla_dbg.c
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_fw.h
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_iocb.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_target.c

index f91ee717202d5ae0999e5dc628e658026300e6ca..c8057c79812571f7652ee90bc006d518607b209f 100644 (file)
  * |                              |                    | 0x015b-0x0160 |
  * |                              |                    | 0x016e                |
  * | Mailbox commands             |       0x1199       | 0x1193                |
- * | Device Discovery             |       0x2004       | 0x2016                |
- * |                              |                    | 0x2011-0x2012, |
- * |                              |                    | 0x2099-0x20a4  |
+ * | Device Discovery             |       0x2131       | 0x210e-0x2116  |
+ * |                             |                    | 0x211a         |
+ * |                              |                    | 0x211c-0x2128  |
+ * |                              |                    | 0x212a-0x2130  |
  * | Queue Command and IO tracing |       0x3074       | 0x300b         |
  * |                              |                    | 0x3027-0x3028  |
  * |                              |                    | 0x303d-0x3041  |
@@ -59,7 +60,7 @@
  * |                              |                    | 0xb13c-0xb140  |
  * |                              |                    | 0xb149                |
  * | MultiQ                       |       0xc010       |               |
- * | Misc                         |       0xd301       | 0xd031-0xd0ff |
+ * | Misc                         |       0xd302       | 0xd031-0xd0ff |
  * |                              |                    | 0xd101-0xd1fe |
  * |                              |                    | 0xd214-0xd2fe |
  * | Target Mode                 |       0xe081       |                |
index e1af9db3691d86f4b916ff9fcc87f6a70828927d..6f8df9cea8ff5fbc18e37f6da1c458f284b6e0f7 100644 (file)
@@ -343,6 +343,7 @@ struct srb_iocb {
 #define SRB_LOGIN_RETRIED      BIT_0
 #define SRB_LOGIN_COND_PLOGI   BIT_1
 #define SRB_LOGIN_SKIP_PRLI    BIT_2
+#define SRB_LOGIN_NVME_PRLI    BIT_3
                        uint16_t data[2];
                        u32 iop[2];
                } logio;
@@ -436,6 +437,7 @@ struct srb_iocb {
 #define SRB_NACK_PLOGI 16
 #define SRB_NACK_PRLI  17
 #define SRB_NACK_LOGO  18
+#define SRB_PRLI_CMD   21
 
 enum {
        TYPE_SRB,
@@ -1088,6 +1090,7 @@ struct mbx_cmd_32 {
 #define        MBX_1           BIT_1
 #define        MBX_0           BIT_0
 
+#define RNID_TYPE_PORT_LOGIN   0x7
 #define RNID_TYPE_SET_VERSION  0x9
 #define RNID_TYPE_ASIC_TEMP    0xC
 
@@ -2152,6 +2155,7 @@ typedef struct {
        uint8_t fabric_port_name[WWN_SIZE];
        uint16_t fp_speed;
        uint8_t fc4_type;
+       uint8_t fc4f_nvme;      /* nvme fc4 feature bits */
 } sw_info_t;
 
 /* FCP-4 types */
@@ -2180,7 +2184,8 @@ typedef enum {
        FCT_SWITCH,
        FCT_BROADCAST,
        FCT_INITIATOR,
-       FCT_TARGET
+       FCT_TARGET,
+       FCT_NVME
 } fc_port_type_t;
 
 enum qla_sess_deletion {
@@ -2237,10 +2242,12 @@ enum fcport_mgt_event {
        FCME_RSCN,
        FCME_GIDPN_DONE,
        FCME_PLOGI_DONE,        /* Initiator side sent LLIOCB */
+       FCME_PRLI_DONE,
        FCME_GNL_DONE,
        FCME_GPSC_DONE,
        FCME_GPDB_DONE,
        FCME_GPNID_DONE,
+       FCME_GFFID_DONE,
        FCME_DELETE_DONE,
 };
 
@@ -2274,6 +2281,16 @@ typedef struct fc_port {
        unsigned int login_pause:1;
        unsigned int login_succ:1;
 
+       struct work_struct nvme_del_work;
+       atomic_t nvme_ref_count;
+       uint32_t nvme_prli_service_param;
+#define NVME_PRLI_SP_CONF       BIT_7
+#define NVME_PRLI_SP_INITIATOR  BIT_5
+#define NVME_PRLI_SP_TARGET     BIT_4
+#define NVME_PRLI_SP_DISCOVERY  BIT_3
+       uint8_t nvme_flag;
+#define NVME_FLAG_REGISTERED 4
+
        struct fc_port *conflict;
        unsigned char logout_completed;
        int generation;
@@ -2306,6 +2323,7 @@ typedef struct fc_port {
        u32 supported_classes;
 
        uint8_t fc4_type;
+       uint8_t fc4f_nvme;
        uint8_t scan_state;
 
        unsigned long last_queue_full;
@@ -2313,6 +2331,8 @@ typedef struct fc_port {
 
        uint16_t port_id;
 
+       struct nvme_fc_remote_port *nvme_remote_port;
+
        unsigned long retry_delay_timestamp;
        struct qla_tgt_sess *tgt_session;
        struct ct_sns_desc ct_desc;
@@ -2745,7 +2765,7 @@ struct ct_sns_req {
 
                struct {
                        uint8_t reserved;
-                       uint8_t port_name[3];
+                       uint8_t port_id[3];
                } gff_id;
 
                struct {
@@ -3052,6 +3072,7 @@ enum qla_work_type {
        QLA_EVT_GPNID_DONE,
        QLA_EVT_NEW_SESS,
        QLA_EVT_GPDB,
+       QLA_EVT_PRLI,
        QLA_EVT_GPSC,
        QLA_EVT_UPD_FCPORT,
        QLA_EVT_GNL,
@@ -4007,6 +4028,7 @@ typedef struct scsi_qla_host {
                uint32_t        qpairs_available:1;
                uint32_t        qpairs_req_created:1;
                uint32_t        qpairs_rsp_created:1;
+               uint32_t        nvme_enabled:1;
        } flags;
 
        atomic_t        loop_state;
@@ -4085,6 +4107,10 @@ typedef struct scsi_qla_host {
        uint8_t         port_name[WWN_SIZE];
        uint8_t         fabric_node_name[WWN_SIZE];
 
+       struct          nvme_fc_local_port *nvme_local_port;
+       atomic_t        nvme_ref_count;
+       struct list_head nvme_rport_list;
+
        uint16_t        fcoe_vlan_id;
        uint16_t        fcoe_fcf_idx;
        uint8_t         fcoe_vn_port_mac[6];
index 1f808928763b4e0348f2e705bba13b7e4162a852..dcae62d4cbeb5126d7609b593785575aad1d8267 100644 (file)
@@ -37,6 +37,12 @@ struct port_database_24xx {
 #define PDF_CLASS_2            BIT_4
 #define PDF_HARD_ADDR          BIT_1
 
+       /*
+        * for NVMe, the login_state field has been
+        * split into nibbles.
+        * The lower nibble is for FCP.
+        * The upper nibble is for NVMe.
+        */
        uint8_t current_login_state;
        uint8_t last_login_state;
 #define PDS_PLOGI_PENDING      0x03
@@ -69,7 +75,11 @@ struct port_database_24xx {
        uint8_t port_name[WWN_SIZE];
        uint8_t node_name[WWN_SIZE];
 
-       uint8_t reserved_3[24];
+       uint8_t reserved_3[4];
+       uint16_t prli_nvme_svc_param_word_0;    /* Bits 15-0 of word 0 */
+       uint16_t prli_nvme_svc_param_word_3;    /* Bits 15-0 of word 3 */
+       uint16_t nvme_first_burst_size;
+       uint8_t reserved_4[14];
 };
 
 /*
@@ -819,6 +829,7 @@ struct logio_entry_24xx {
 #define LCF_CLASS_2            BIT_8   /* Enable class 2 during PLOGI. */
 #define LCF_FREE_NPORT         BIT_7   /* Release NPORT handle after LOGO. */
 #define LCF_EXPL_LOGO          BIT_6   /* Perform an explicit LOGO. */
+#define LCF_NVME_PRLI          BIT_6   /* Perform NVME FC4 PRLI */
 #define LCF_SKIP_PRLI          BIT_5   /* Skip PRLI after PLOGI. */
 #define LCF_IMPL_LOGO_ALL      BIT_5   /* Implicit LOGO to all ports. */
 #define LCF_COND_PLOGI         BIT_4   /* PLOGI only if not logged-in. */
index beebf96c23d4356681dd44dd98aca815115ce165..6fbee11c1a1815a281da975c03a161e7639ed7b2 100644 (file)
@@ -99,6 +99,7 @@ extern struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *,
 extern int qla2xxx_delete_qpair(struct scsi_qla_host *, struct qla_qpair *);
 void qla2x00_fcport_event_handler(scsi_qla_host_t *, struct event_arg *);
 int qla24xx_async_gpdb(struct scsi_qla_host *, fc_port_t *, u8);
+int qla24xx_async_prli(struct scsi_qla_host *, fc_port_t *);
 int qla24xx_async_notify_ack(scsi_qla_host_t *, fc_port_t *,
        struct imm_ntfy_from_isp *, int);
 int qla24xx_post_newsess_work(struct scsi_qla_host *, port_id_t *, u8 *,
index 1d815ab779eadf59deed638f1f63eae166d28606..ed898b7a32c809720453bd17d105eb7bb0df2256 100644 (file)
@@ -37,8 +37,11 @@ static struct qla_chip_state_84xx *qla84xx_get_chip(struct scsi_qla_host *);
 static int qla84xx_init_chip(scsi_qla_host_t *);
 static int qla25xx_init_queues(struct qla_hw_data *);
 static int qla24xx_post_gpdb_work(struct scsi_qla_host *, fc_port_t *, u8);
+static int qla24xx_post_prli_work(struct scsi_qla_host*, fc_port_t *);
 static void qla24xx_handle_plogi_done_event(struct scsi_qla_host *,
     struct event_arg *);
+static void qla24xx_handle_prli_done_event(struct scsi_qla_host *,
+    struct event_arg *);
 
 /* SRB Extensions ---------------------------------------------------------- */
 
@@ -191,6 +194,10 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
        lio->timeout = qla2x00_async_iocb_timeout;
        sp->done = qla2x00_async_login_sp_done;
        lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI;
+
+       if (fcport->fc4f_nvme)
+               lio->u.logio.flags |= SRB_LOGIN_SKIP_PRLI;
+
        if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
                lio->u.logio.flags |= SRB_LOGIN_RETRIED;
        rval = qla2x00_start_sp(sp);
@@ -327,7 +334,7 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
        u16 i, n, found = 0, loop_id;
        port_id_t id;
        u64 wwn;
-       u8 opt = 0;
+       u8 opt = 0, current_login_state;
 
        fcport = ea->fcport;
 
@@ -414,7 +421,12 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
                        fcport->login_pause = 1;
                }
 
-               switch (e->current_login_state) {
+               if  (fcport->fc4f_nvme)
+                       current_login_state = e->current_login_state >> 4;
+               else
+                       current_login_state = e->current_login_state & 0xf;
+
+               switch (current_login_state) {
                case DSC_LS_PRLI_COMP:
                        ql_dbg(ql_dbg_disc, vha, 0x20e4,
                            "%s %d %8phC post gpdb\n",
@@ -422,7 +434,6 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
                        opt = PDO_FORCE_ADISC;
                        qla24xx_post_gpdb_work(vha, fcport, opt);
                        break;
-
                case DSC_LS_PORT_UNAVAIL:
                default:
                        if (fcport->loop_id == FC_NO_LOOP_ID) {
@@ -665,6 +676,104 @@ gpd_error_out:
        sp->free(sp);
 }
 
+static int qla24xx_post_prli_work(struct scsi_qla_host *vha, fc_port_t *fcport)
+{
+       struct qla_work_evt *e;
+
+       e = qla2x00_alloc_work(vha, QLA_EVT_PRLI);
+       if (!e)
+               return QLA_FUNCTION_FAILED;
+
+       e->u.fcport.fcport = fcport;
+
+       return qla2x00_post_work(vha, e);
+}
+
+static void
+qla2x00_async_prli_sp_done(void *ptr, int res)
+{
+       srb_t *sp = ptr;
+       struct scsi_qla_host *vha = sp->vha;
+       struct srb_iocb *lio = &sp->u.iocb_cmd;
+       struct event_arg ea;
+
+       ql_dbg(ql_dbg_disc, vha, 0x2129,
+           "%s %8phC res %d \n", __func__,
+           sp->fcport->port_name, res);
+
+       sp->fcport->flags &= ~FCF_ASYNC_SENT;
+
+       if (!test_bit(UNLOADING, &vha->dpc_flags)) {
+               memset(&ea, 0, sizeof(ea));
+               ea.event = FCME_PRLI_DONE;
+               ea.fcport = sp->fcport;
+               ea.data[0] = lio->u.logio.data[0];
+               ea.data[1] = lio->u.logio.data[1];
+               ea.iop[0] = lio->u.logio.iop[0];
+               ea.iop[1] = lio->u.logio.iop[1];
+               ea.sp = sp;
+
+               qla2x00_fcport_event_handler(vha, &ea);
+       }
+
+       sp->free(sp);
+}
+
+int
+qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport)
+{
+       srb_t *sp;
+       struct srb_iocb *lio;
+       int rval = QLA_FUNCTION_FAILED;
+
+       if (!vha->flags.online)
+               return rval;
+
+       if (fcport->fw_login_state == DSC_LS_PLOGI_PEND ||
+           fcport->fw_login_state == DSC_LS_PLOGI_COMP ||
+           fcport->fw_login_state == DSC_LS_PRLI_PEND)
+               return rval;
+
+       sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
+       if (!sp)
+               return rval;
+
+       fcport->flags |= FCF_ASYNC_SENT;
+       fcport->logout_completed = 0;
+
+       sp->type = SRB_PRLI_CMD;
+       sp->name = "prli";
+       qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
+
+       lio = &sp->u.iocb_cmd;
+       lio->timeout = qla2x00_async_iocb_timeout;
+       sp->done = qla2x00_async_prli_sp_done;
+       lio->u.logio.flags = 0;
+
+       if  (fcport->fc4f_nvme)
+               lio->u.logio.flags |= SRB_LOGIN_NVME_PRLI;
+
+       rval = qla2x00_start_sp(sp);
+       if (rval != QLA_SUCCESS) {
+               fcport->flags &= ~FCF_ASYNC_SENT;
+               fcport->flags |= FCF_LOGIN_NEEDED;
+               set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
+               goto done_free_sp;
+       }
+
+       ql_dbg(ql_dbg_disc, vha, 0x211b,
+           "Async-prli - %8phC hdl=%x, loopid=%x portid=%06x retries=%d.\n",
+           fcport->port_name, sp->handle, fcport->loop_id,
+           fcport->d_id.b24, fcport->login_retry);
+
+       return rval;
+
+done_free_sp:
+       sp->free(sp);
+       fcport->flags &= ~FCF_ASYNC_SENT;
+       return rval;
+}
+
 static int qla24xx_post_gpdb_work(struct scsi_qla_host *vha, fc_port_t *fcport,
     u8 opt)
 {
@@ -1126,6 +1235,9 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
        case FCME_PLOGI_DONE:   /* Initiator side sent LLIOCB */
                qla24xx_handle_plogi_done_event(vha, ea);
                break;
+       case FCME_PRLI_DONE:
+               qla24xx_handle_prli_done_event(vha, ea);
+               break;
        case FCME_GPDB_DONE:
                qla24xx_handle_gpdb_event(vha, ea);
                break;
@@ -1307,6 +1419,27 @@ qla24xx_async_abort_command(srb_t *sp)
        return qla24xx_async_abort_cmd(sp);
 }
 
+static void
+qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
+{
+       switch (ea->data[0]) {
+       case MBS_COMMAND_COMPLETE:
+               ql_dbg(ql_dbg_disc, vha, 0x2118,
+                   "%s %d %8phC post gpdb\n",
+                   __func__, __LINE__, ea->fcport->port_name);
+
+               ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset;
+               ea->fcport->logout_on_delete = 1;
+               qla24xx_post_gpdb_work(vha, ea->fcport, 0);
+               break;
+       default:
+               ql_dbg(ql_dbg_disc, vha, 0x2119,
+                   "%s %d %8phC unhandle event of %x\n",
+                   __func__, __LINE__, ea->fcport->port_name, ea->data[0]);
+               break;
+       }
+}
+
 static void
 qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
 {
@@ -1319,12 +1452,19 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
                 * force a relogin attempt via implicit LOGO, PLOGI, and PRLI
                 * requests.
                 */
-               ql_dbg(ql_dbg_disc, vha, 0x20ea,
-                   "%s %d %8phC post gpdb\n",
-                   __func__, __LINE__, ea->fcport->port_name);
-               ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset;
-               ea->fcport->logout_on_delete = 1;
-               qla24xx_post_gpdb_work(vha, ea->fcport, 0);
+               if (ea->fcport->fc4f_nvme) {
+                       ql_dbg(ql_dbg_disc, vha, 0x2117,
+                               "%s %d %8phC post prli\n",
+                               __func__, __LINE__, ea->fcport->port_name);
+                       qla24xx_post_prli_work(vha, ea->fcport);
+               } else {
+                       ql_dbg(ql_dbg_disc, vha, 0x20ea,
+                               "%s %d %8phC post gpdb\n",
+                               __func__, __LINE__, ea->fcport->port_name);
+                       ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset;
+                       ea->fcport->logout_on_delete = 1;
+                       qla24xx_post_gpdb_work(vha, ea->fcport, 0);
+               }
                break;
        case MBS_COMMAND_ERROR:
                ql_dbg(ql_dbg_disc, vha, 0x20eb, "%s %d %8phC cmd error %x\n",
@@ -4646,6 +4786,16 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
                                new_fcport->fp_speed = swl[swl_idx].fp_speed;
                                new_fcport->fc4_type = swl[swl_idx].fc4_type;
 
+                               new_fcport->nvme_flag = 0;
+                               if (vha->flags.nvme_enabled &&
+                                   swl[swl_idx].fc4f_nvme) {
+                                       new_fcport->fc4f_nvme =
+                                           swl[swl_idx].fc4f_nvme;
+                                       ql_log(ql_log_info, vha, 0x2131,
+                                           "FOUND: NVME port %8phC as FC Type 28h\n",
+                                           new_fcport->port_name);
+                               }
+
                                if (swl[swl_idx].d_id.b.rsvd_1 != 0) {
                                        last_dev = 1;
                                }
index ac49febbac761922183b72a3561c6ee29481a595..daa53235a28a08ad9badb5bc371b4523ffd74484 100644 (file)
@@ -2210,6 +2210,23 @@ qla2x00_alloc_iocbs(struct scsi_qla_host *vha, srb_t *sp)
        return __qla2x00_alloc_iocbs(vha->hw->base_qpair, sp);
 }
 
+static void
+qla24xx_prli_iocb(srb_t *sp, struct logio_entry_24xx *logio)
+{
+       struct srb_iocb *lio = &sp->u.iocb_cmd;
+
+       logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
+       logio->control_flags = cpu_to_le16(LCF_COMMAND_PRLI);
+       if (lio->u.logio.flags & SRB_LOGIN_NVME_PRLI)
+               logio->control_flags |= LCF_NVME_PRLI;
+
+       logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
+       logio->port_id[0] = sp->fcport->d_id.b.al_pa;
+       logio->port_id[1] = sp->fcport->d_id.b.area;
+       logio->port_id[2] = sp->fcport->d_id.b.domain;
+       logio->vp_index = sp->vha->vp_idx;
+}
+
 static void
 qla24xx_login_iocb(srb_t *sp, struct logio_entry_24xx *logio)
 {
@@ -2217,6 +2234,7 @@ qla24xx_login_iocb(srb_t *sp, struct logio_entry_24xx *logio)
 
        logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
        logio->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI);
+
        if (lio->u.logio.flags & SRB_LOGIN_COND_PLOGI)
                logio->control_flags |= cpu_to_le16(LCF_COND_PLOGI);
        if (lio->u.logio.flags & SRB_LOGIN_SKIP_PRLI)
@@ -3162,6 +3180,9 @@ qla2x00_start_sp(srb_t *sp)
                    qla24xx_login_iocb(sp, pkt) :
                    qla2x00_login_iocb(sp, pkt);
                break;
+       case SRB_PRLI_CMD:
+               qla24xx_prli_iocb(sp, pkt);
+               break;
        case SRB_LOGOUT_CMD:
                IS_FWI2_CAPABLE(ha) ?
                    qla24xx_logout_iocb(sp, pkt) :
index f02a2baffb5b4953809d472fb44753f7607fd416..1eac67e8fdfdab8ae9c656c82105d1849990050b 100644 (file)
@@ -5968,14 +5968,22 @@ int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport,
 {
        int rval = QLA_SUCCESS;
        uint64_t zero = 0;
+       u8 current_login_state, last_login_state;
+
+       if (fcport->fc4f_nvme) {
+               current_login_state = pd->current_login_state >> 4;
+               last_login_state = pd->last_login_state >> 4;
+       } else {
+               current_login_state = pd->current_login_state & 0xf;
+               last_login_state = pd->last_login_state & 0xf;
+       }
 
        /* Check for logged in state. */
-       if (pd->current_login_state != PDS_PRLI_COMPLETE &&
-               pd->last_login_state != PDS_PRLI_COMPLETE) {
+       if (current_login_state != PDS_PRLI_COMPLETE &&
+           last_login_state != PDS_PRLI_COMPLETE) {
                ql_dbg(ql_dbg_mbx, vha, 0x119a,
                    "Unable to verify login-state (%x/%x) for loop_id %x.\n",
-                   pd->current_login_state, pd->last_login_state,
-                   fcport->loop_id);
+                   current_login_state, last_login_state, fcport->loop_id);
                rval = QLA_FUNCTION_FAILED;
                goto gpd_error_out;
        }
@@ -5998,12 +6006,17 @@ int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport,
        fcport->d_id.b.al_pa = pd->port_id[2];
        fcport->d_id.b.rsvd_1 = 0;
 
-       /* If not target must be initiator or unknown type. */
-       if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
-               fcport->port_type = FCT_INITIATOR;
-       else
-               fcport->port_type = FCT_TARGET;
-
+       if (fcport->fc4f_nvme) {
+               fcport->nvme_prli_service_param =
+                   pd->prli_nvme_svc_param_word_3;
+               fcport->port_type = FCT_NVME;
+       } else {
+               /* If not target must be initiator or unknown type. */
+               if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
+                       fcport->port_type = FCT_INITIATOR;
+               else
+                       fcport->port_type = FCT_TARGET;
+       }
        /* Passback COS information. */
        fcport->supported_classes = (pd->flags & PDF_CLASS_2) ?
                FC_COS_CLASS2 : FC_COS_CLASS3;
index f7c4f723c4058b69edc798a3fa823e5b37b63078..aee884d63e55a4153fa3bd113453457ae330afbf 100644 (file)
@@ -4428,6 +4428,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht,
        INIT_LIST_HEAD(&vha->plogi_ack_list);
        INIT_LIST_HEAD(&vha->qp_list);
        INIT_LIST_HEAD(&vha->gnl.fcports);
+       INIT_LIST_HEAD(&vha->nvme_rport_list);
 
        spin_lock_init(&vha->work_lock);
        spin_lock_init(&vha->cmd_list_lock);
@@ -4717,6 +4718,9 @@ qla2x00_do_work(struct scsi_qla_host *vha)
                        qla24xx_async_gpdb(vha, e->u.fcport.fcport,
                            e->u.fcport.opt);
                        break;
+               case QLA_EVT_PRLI:
+                       qla24xx_async_prli(vha, e->u.fcport.fcport);
+                       break;
                case QLA_EVT_GPSC:
                        qla24xx_async_gpsc(vha, e->u.fcport.fcport);
                        break;
index 12e76cc37fb066b4afdac1d3568a0a535aea774d..2a0173e5d10e1d6095fd659163aabde34a8dca2f 100644 (file)
@@ -963,7 +963,6 @@ static void qlt_free_session_done(struct work_struct *work)
                sess->logout_on_delete, sess->keep_nport_handle,
                sess->send_els_logo);
 
-
        if (!IS_SW_RESV_ADDR(sess->d_id)) {
                if (sess->send_els_logo) {
                        qlt_port_logo_t logo;
@@ -1118,6 +1117,9 @@ void qlt_unreg_sess(struct fc_port *sess)
        sess->last_rscn_gen = sess->rscn_gen;
        sess->last_login_gen = sess->login_gen;
 
+       if (sess->nvme_flag & NVME_FLAG_REGISTERED)
+               schedule_work(&sess->nvme_del_work);
+
        INIT_WORK(&sess->free_work, qlt_free_session_done);
        schedule_work(&sess->free_work);
 }