[PATCH 42/43] qla2xxx: Serialize session free in qlt_free_session_done

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

Add free_pending flag to serialize queueing of
free_work element onto the work queue

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_def.h|  1 +
 drivers/scsi/qla2xxx/qla_target.c | 13 +
 2 files changed, 14 insertions(+)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 0c31c8ad0c1e..3feb843ef333 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2384,6 +2384,7 @@ typedef struct fc_port {
 
unsigned int conf_compl_supported:1;
unsigned int deleted:2;
+   unsigned int free_pending:1;
unsigned int local:1;
unsigned int logout_on_delete:1;
unsigned int logo_ack_needed:1;
diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 814dfb1036de..225b88c47505 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1105,6 +1105,7 @@ static void qlt_free_session_done(struct work_struct 
*work)
sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN] = NULL;
}
}
+
spin_unlock_irqrestore(>tgt.sess_lock, flags);
 
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf001,
@@ -1118,6 +1119,9 @@ static void qlt_free_session_done(struct work_struct 
*work)
wake_up_all(>fcport_waitQ);
 
base_vha = pci_get_drvdata(ha->pdev);
+
+   sess->free_pending = 0;
+
if (test_bit(PFLG_DRIVER_REMOVING, _vha->pci_flags))
return;
 
@@ -1140,11 +1144,20 @@ static void qlt_free_session_done(struct work_struct 
*work)
 void qlt_unreg_sess(struct fc_port *sess)
 {
struct scsi_qla_host *vha = sess->vha;
+   unsigned long flags;
 
ql_dbg(ql_dbg_disc, sess->vha, 0x210a,
"%s sess %p for deletion %8phC\n",
__func__, sess, sess->port_name);
 
+   spin_lock_irqsave(>vha->work_lock, flags);
+   if (sess->free_pending) {
+   spin_unlock_irqrestore(>vha->work_lock, flags);
+   return;
+   }
+   sess->free_pending = 1;
+   spin_unlock_irqrestore(>vha->work_lock, flags);
+
if (sess->se_sess)
vha->hw->tgt.tgt_ops->clear_nacl_from_fcport_map(sess);
 
-- 
2.12.0



[PATCH 41/43] qla2xxx: Serialize session deletion by using work_lock

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

for session deletion, replace sess_lock with work_lock.
Under certain case sess_lock is not feasiable to acquire.
The lock is needed temporarily to make sure a single
call to schedule of the work element.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_gbl.h|  1 -
 drivers/scsi/qla2xxx/qla_gs.c | 14 ++
 drivers/scsi/qla2xxx/qla_init.c   |  9 +++--
 drivers/scsi/qla2xxx/qla_isr.c|  4 ++--
 drivers/scsi/qla2xxx/qla_mbx.c|  2 +-
 drivers/scsi/qla2xxx/qla_os.c |  5 ++---
 drivers/scsi/qla2xxx/qla_target.c | 29 ++---
 7 files changed, 28 insertions(+), 36 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index ab8ffd7933c9..733906cb6c69 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -889,7 +889,6 @@ void qlt_plogi_ack_link(struct scsi_qla_host *, struct 
qlt_plogi_ack_t *,
struct fc_port *, enum qlt_plogi_link_t);
 void qlt_plogi_ack_unref(struct scsi_qla_host *, struct qlt_plogi_ack_t *);
 extern void qlt_schedule_sess_for_deletion(struct fc_port *);
-extern void qlt_schedule_sess_for_deletion_lock(struct fc_port *);
 extern struct fc_port *qlt_find_sess_invalidate_other(scsi_qla_host_t *,
uint64_t wwn, port_id_t port_id, uint16_t loop_id, struct fc_port **);
 void qla24xx_delete_sess_fn(struct work_struct *);
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index dd02cbfd0fb1..f26d680fe6c1 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -3096,7 +3096,7 @@ void qla24xx_handle_gidpn_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
ql_dbg(ql_dbg_disc, vha, 0x2021,
"%s %d %8phC post del sess\n",
__func__, __LINE__, 
fcport->port_name);
-   
qlt_schedule_sess_for_deletion_lock(fcport);
+   qlt_schedule_sess_for_deletion(fcport);
}
}
} else { /* ea->sp->gen1 != fcport->rscn_gen */
@@ -3113,7 +3113,7 @@ void qla24xx_handle_gidpn_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
ql_dbg(ql_dbg_disc, vha, 0x2042,
"%s %d %8phC post del sess\n", __func__,
__LINE__, fcport->port_name);
-   qlt_schedule_sess_for_deletion_lock(fcport);
+   qlt_schedule_sess_for_deletion(fcport);
} else {
ql_dbg(ql_dbg_disc, vha, 0x2045,
"%s %d %8phC login\n", __func__, __LINE__,
@@ -3485,8 +3485,7 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
"%s %d %8phC post del sess\n",
__func__, __LINE__,
fcport->port_name);
-   qlt_schedule_sess_for_deletion_lock
-   (fcport);
+   qlt_schedule_sess_for_deletion(fcport);
break;
}
}
@@ -3519,7 +3518,7 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
"%s %d %8phC post del 
sess\n",
__func__, __LINE__,
conflict->port_name);
-   
qlt_schedule_sess_for_deletion_lock
+   qlt_schedule_sess_for_deletion
(conflict);
break;
}
@@ -3577,7 +3576,7 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
"%s %d %8phC post del 
sess\n",
__func__, __LINE__,
conflict->port_name);
-   
qlt_schedule_sess_for_deletion_lock
+   qlt_schedule_sess_for_deletion
(conflict);
break;
}
@@ -4008,8 +4007,7 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t 
*sp)
   

[PATCH 35/43] qla2xxx: Add retry limit for fabric scan logic

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

Switch scan is assumed to succeed most of the time.
If the scan failed, then scan is limit 5 retries.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_def.h |  2 ++
 drivers/scsi/qla2xxx/qla_gs.c  | 33 -
 drivers/scsi/qla2xxx/qla_isr.c |  1 +
 3 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index f061483475ce..3811ccd1c60b 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3036,6 +3036,8 @@ struct fab_scan_rp {
 struct fab_scan {
struct fab_scan_rp *l;
u32 size;
+   u16 scan_retry;
+#define MAX_SCAN_RETRIES 5
enum scan_flags_t scan_flags;
struct delayed_work scan_work;
 };
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 903f924f6273..8256b65e9e7a 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -3924,13 +3924,17 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, 
srb_t *sp)
 
rc = sp->rc;
if (rc) {
-   ql_dbg(ql_dbg_disc, vha, 0x,
-   "GPNFT failed. FC4type %x. Rescanning.\n",
-   fc4type);
-   set_bit(LOCAL_LOOP_UPDATE, >dpc_flags);
-   set_bit(LOOP_RESYNC_NEEDED, >dpc_flags);
+   vha->scan.scan_retry++;
+   if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
+   set_bit(LOCAL_LOOP_UPDATE, >dpc_flags);
+   set_bit(LOOP_RESYNC_NEEDED, >dpc_flags);
+   } else {
+   ql_dbg(ql_dbg_disc, vha, 0x,
+   "Fabric scan failed on all retries.\n");
+   }
goto out;
}
+   vha->scan.scan_retry = 0;
 
list_for_each_entry(fcport, >vp_fcports, list)
fcport->scan_state = QLA_FCPORT_SCAN;
@@ -4013,7 +4017,6 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t 
*sp)
 
 out:
qla24xx_sp_unmap(vha, sp);
-
spin_lock_irqsave(>work_lock, flags);
vha->scan.scan_flags &= ~SF_SCANNING;
spin_unlock_irqrestore(>work_lock, flags);
@@ -4041,16 +4044,20 @@ static void qla2x00_async_gpnft_gnnft_sp_done(void *s, 
int res)
if (res) {
unsigned long flags;
 
-   ql_dbg(ql_dbg_disc, sp->vha, 0x,
-   "Async done-%s timed out.\n",
-   sp->name);
sp->free(sp);
spin_lock_irqsave(>work_lock, flags);
vha->scan.scan_flags &= ~SF_SCANNING;
-   spin_unlock_irqrestore(>work_lock, flags);
-   set_bit(LOCAL_LOOP_UPDATE, >dpc_flags);
-   set_bit(LOOP_RESYNC_NEEDED, >dpc_flags);
-   qla2xxx_wake_dpc(vha);
+   vha->scan.scan_retry++;
+
+   if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
+   set_bit(LOCAL_LOOP_UPDATE, >dpc_flags);
+   set_bit(LOOP_RESYNC_NEEDED, >dpc_flags);
+   qla2xxx_wake_dpc(vha);
+   } else {
+   ql_dbg(ql_dbg_disc, sp->vha, 0x,
+   "Async done-%s rescan failed on all retries\n",
+   sp->name);
+   }
return;
}
 
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index f02c98b3e8a7..6974657dd8c6 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1059,6 +1059,7 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que 
*rsp, uint16_t *mb)
 * Mark all devices as missing so we will login again.
 */
atomic_set(>loop_state, LOOP_UP);
+   vha->scan.scan_retry = 0;
 
set_bit(LOOP_RESYNC_NEEDED, >dpc_flags);
set_bit(LOCAL_LOOP_UPDATE, >dpc_flags);
-- 
2.12.0



[PATCH 36/43] qla2xxx: Add counters for Exchange Buffer to debugfs

2017-12-19 Thread Himanshu Madhani
From: Anil Gurumurthy 

Signed-off-by: Anil Gurumurthy 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_dfs.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c
index 4f0415e158cb..c05ebc6ebe78 100644
--- a/drivers/scsi/qla2xxx/qla_dfs.c
+++ b/drivers/scsi/qla2xxx/qla_dfs.c
@@ -143,6 +143,15 @@ qla_dfs_fw_resource_cnt_show(struct seq_file *s, void 
*unused)
seq_printf(s, "Current IOCB count[%d]\n", mb[10]);
seq_printf(s, "MAX VP count[%d]\n", mb[11]);
seq_printf(s, "MAX FCF count[%d]\n", mb[12]);
+   seq_printf(s, "Current free pageable XCB buffer cnt[%d]\n",
+   mb[20]);
+   seq_printf(s, "Original Initiator fast XCB buffer cnt[%d]\n",
+   mb[21]);
+   seq_printf(s, "Current free Initiator fast XCB buffer 
cnt[%d]\n",
+   mb[22]);
+   seq_printf(s, "Original Target fast XCB buffer cnt[%d]\n",
+   mb[23]);
+
}
 
return 0;
-- 
2.12.0



[PATCH 38/43] qla2xxx: Prevent relogin trigger from sending too many commands

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

This patch adds check for pending work event before queueing
relogin work to prevent redundant work to be active at the
same time.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_def.h  |  1 +
 drivers/scsi/qla2xxx/qla_gs.c   |  6 --
 drivers/scsi/qla2xxx/qla_init.c | 14 +-
 drivers/scsi/qla2xxx/qla_os.c   |  4 +++-
 4 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 3811ccd1c60b..0c31c8ad0c1e 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2504,6 +2504,7 @@ static const char * const port_state_str[] = {
 #define FCF_FCP2_DEVICEBIT_2
 #define FCF_ASYNC_SENT BIT_3
 #define FCF_CONF_COMP_SUPPORTED BIT_4
+#define FCF_ASYNC_ACTIVE   BIT_5
 
 /* No loop ID flag. */
 #define FC_NO_LOOP_ID  0x1000
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 29b63c2a380b..dd02cbfd0fb1 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -3137,7 +3137,7 @@ static void qla2x00_async_gidpn_sp_done(void *s, int res)
u8 *id = fcport->ct_desc.ct_sns->p.rsp.rsp.gid_pn.port_id;
struct event_arg ea;
 
-   fcport->flags &= ~FCF_ASYNC_SENT;
+   fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
 
memset(, 0, sizeof(ea));
ea.fcport = fcport;
@@ -3246,6 +3246,7 @@ int qla24xx_post_gidpn_work(struct scsi_qla_host *vha, 
fc_port_t *fcport)
return QLA_FUNCTION_FAILED;
 
e->u.fcport.fcport = fcport;
+   fcport->flags |= FCF_ASYNC_ACTIVE;
return qla2x00_post_work(vha, e);
 }
 
@@ -3258,6 +3259,7 @@ int qla24xx_post_gpsc_work(struct scsi_qla_host *vha, 
fc_port_t *fcport)
return QLA_FUNCTION_FAILED;
 
e->u.fcport.fcport = fcport;
+   fcport->flags |= FCF_ASYNC_ACTIVE;
return qla2x00_post_work(vha, e);
 }
 
@@ -3305,7 +3307,7 @@ static void qla24xx_async_gpsc_sp_done(void *s, int res)
"Async done-%s res %x, WWPN %8phC \n",
sp->name, res, fcport->port_name);
 
-   fcport->flags &= ~FCF_ASYNC_SENT;
+   fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
 
if (res == (DID_ERROR << 16)) {
/* entry status error */
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index f42f2f16343f..85bdb6928ea2 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -109,7 +109,7 @@ qla2x00_async_iocb_timeout(void *data)
"Async-%s timeout - hdl=%x portid=%06x %8phC.\n",
sp->name, sp->handle, fcport->d_id.b24, fcport->port_name);
 
-   fcport->flags &= ~FCF_ASYNC_SENT;
+   fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
} else {
pr_info("Async-%s timeout - hdl=%x.\n",
sp->name, sp->handle);
@@ -154,7 +154,8 @@ qla2x00_async_login_sp_done(void *ptr, int res)
ql_dbg(ql_dbg_disc, vha, 0x20dd,
"%s %8phC res %d \n", __func__, sp->fcport->port_name, res);
 
-   sp->fcport->flags &= ~FCF_ASYNC_SENT;
+   sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
+
if (!test_bit(UNLOADING, >dpc_flags)) {
memset(, 0, sizeof(ea));
ea.event = FCME_PLOGI_DONE;
@@ -231,7 +232,7 @@ qla2x00_async_logout_sp_done(void *ptr, int res)
srb_t *sp = ptr;
struct srb_iocb *lio = >u.iocb_cmd;
 
-   sp->fcport->flags &= ~FCF_ASYNC_SENT;
+   sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
if (!test_bit(UNLOADING, >vha->dpc_flags))
qla2x00_post_async_logout_done_work(sp->vha, sp->fcport,
lio->u.logio.data);
@@ -667,7 +668,7 @@ qla24xx_async_gnl_sp_done(void *s, int res)
 
list_for_each_entry_safe(fcport, tf, , gnl_entry) {
list_del_init(>gnl_entry);
-   fcport->flags &= ~FCF_ASYNC_SENT;
+   fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
ea.fcport = fcport;
 
qla2x00_fcport_event_handler(vha, );
@@ -790,6 +791,7 @@ int qla24xx_post_gnl_work(struct scsi_qla_host *vha, 
fc_port_t *fcport)
return QLA_FUNCTION_FAILED;
 
e->u.fcport.fcport = fcport;
+   fcport->flags |= FCF_ASYNC_ACTIVE;
return qla2x00_post_work(vha, e);
 }
 
@@ -807,7 +809,7 @@ void qla24xx_async_gpdb_sp_done(void *s, int res)
"Async done-%s res %x, WWPN %8phC mb[1]=%x mb[2]=%x \n",
sp->name, res, fcport->port_name, mb[1], mb[2]);
 
-   fcport->flags &= ~FCF_ASYNC_SENT;
+   fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
 
memset(, 0, sizeof(ea));
ea.event = FCME_GPDB_DONE;
@@ -930,6 +932,7 @@ int 

[PATCH 43/43] qla2xxx: Update driver version to 10.00.00.04-k

2017-12-19 Thread Himanshu Madhani
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_version.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/qla2xxx/qla_version.h 
b/drivers/scsi/qla2xxx/qla_version.h
index 911b82226d13..0843def08356 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,7 +7,7 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION  "10.00.00.03-k"
+#define QLA2XXX_VERSION  "10.00.00.04-k"
 
 #define QLA_DRIVER_MAJOR_VER   10
 #define QLA_DRIVER_MINOR_VER   0
-- 
2.12.0



[PATCH 37/43] qla2xxx: Prevent multiple active discovery commands per session

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

Add check to allow single discovery command per session to be sent

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_gs.c   | 16 
 drivers/scsi/qla2xxx/qla_init.c | 11 ++-
 2 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 8256b65e9e7a..29b63c2a380b 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -3176,16 +3176,16 @@ int qla24xx_async_gidpn(scsi_qla_host_t *vha, fc_port_t 
*fcport)
struct ct_sns_req   *ct_req;
srb_t *sp;
 
-   if (!vha->flags.online)
+   if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
goto done;
 
-   fcport->flags |= FCF_ASYNC_SENT;
fcport->disc_state = DSC_GID_PN;
fcport->scan_state = QLA_FCPORT_SCAN;
sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
if (!sp)
goto done;
 
+   fcport->flags |= FCF_ASYNC_SENT;
sp->type = SRB_CT_PTHRU_CMD;
sp->name = sp_to_str(SPCN_GIDPN);
sp->gen1 = fcport->rscn_gen;
@@ -3226,8 +3226,8 @@ int qla24xx_async_gidpn(scsi_qla_host_t *vha, fc_port_t 
*fcport)
 
 done_free_sp:
sp->free(sp);
-done:
fcport->flags &= ~FCF_ASYNC_SENT;
+done:
return rval;
 }
 
@@ -3368,14 +3368,14 @@ int qla24xx_async_gpsc(scsi_qla_host_t *vha, fc_port_t 
*fcport)
struct ct_sns_req   *ct_req;
srb_t *sp;
 
-   if (!vha->flags.online)
+   if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
goto done;
 
-   fcport->flags |= FCF_ASYNC_SENT;
sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
if (!sp)
goto done;
 
+   fcport->flags |= FCF_ASYNC_SENT;
sp->type = SRB_CT_PTHRU_CMD;
sp->name = sp_to_str(SPCN_GPSC);
sp->gen1 = fcport->rscn_gen;
@@ -3415,8 +3415,8 @@ int qla24xx_async_gpsc(scsi_qla_host_t *vha, fc_port_t 
*fcport)
 
 done_free_sp:
sp->free(sp);
-done:
fcport->flags &= ~FCF_ASYNC_SENT;
+done:
return rval;
 }
 
@@ -3829,7 +3829,7 @@ int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t 
*fcport)
struct ct_sns_req   *ct_req;
srb_t *sp;
 
-   if (!vha->flags.online)
+   if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
return rval;
 
sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
@@ -4525,12 +4525,12 @@ int qla24xx_async_gfpnid(scsi_qla_host_t *vha, 
fc_port_t *fcport)
if (!vha->flags.online)
goto done;
 
-   fcport->flags |= FCF_ASYNC_SENT;
fcport->disc_state = DSC_GFPN_ID;
sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
if (!sp)
goto done;
 
+   fcport->flags |= FCF_ASYNC_SENT;
sp->type = SRB_CT_PTHRU_CMD;
sp->name = sp_to_str(SPCN_GFPNID);
sp->gen1 = fcport->rscn_gen;
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 185c106cec0c..f42f2f16343f 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -206,7 +206,6 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t 
*fcport,
lio->u.logio.flags |= SRB_LOGIN_RETRIED;
rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS) {
-   fcport->flags &= ~FCF_ASYNC_SENT;
fcport->flags |= FCF_LOGIN_NEEDED;
set_bit(RELOGIN_NEEDED, >dpc_flags);
goto done_free_sp;
@@ -221,8 +220,8 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t 
*fcport,
 
 done_free_sp:
sp->free(sp);
-done:
fcport->flags &= ~FCF_ASYNC_SENT;
+done:
return rval;
 }
 
@@ -244,9 +243,11 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t 
*fcport)
 {
srb_t *sp;
struct srb_iocb *lio;
-   int rval;
+   int rval = QLA_FUNCTION_FAILED;
+
+   if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
+   return rval;
 
-   rval = QLA_FUNCTION_FAILED;
fcport->flags |= FCF_ASYNC_SENT;
sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
if (!sp)
@@ -717,7 +718,7 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t 
*fcport)
unsigned long flags;
u16 *mb;
 
-   if (!vha->flags.online)
+   if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
goto done;
 
ql_dbg(ql_dbg_disc, vha, 0x20d9,
-- 
2.12.0



[PATCH 24/43] qla2xxx: Reduce the use of terminate exchange

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

reduce usage of terminate exchange when command encounter
resource bottle neck.  Remote initiator view it as command
drop.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_target.c | 140 --
 1 file changed, 74 insertions(+), 66 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index c7c81d5cf69c..e7e0689d9ca5 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -75,7 +75,8 @@ MODULE_PARM_DESC(ql2xuctrlirq,
 
 int ql2x_ini_mode = QLA2XXX_INI_MODE_EXCLUSIVE;
 
-static int temp_sam_status = SAM_STAT_BUSY;
+static int qla_sam_status = SAM_STAT_BUSY;
+static int tc_sam_status = SAM_STAT_TASK_SET_FULL; /* target core */
 
 /*
  * From scsi/fc/fc_fcp.h
@@ -4294,14 +4295,14 @@ static void qlt_create_sess_from_atio(struct 
work_struct *work)
if (op->atio.u.raw.entry_count > 1) {
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf023,
"Dropping multy entry atio %p\n", >atio);
-   goto out_term;
+   goto out_busy;
}
 
sess = qlt_make_local_sess(vha, s_id);
/* sess has an extra creation ref. */
 
if (!sess)
-   goto out_term;
+   goto out_busy;
/*
 * Now obtain a pre-allocated session tag using the original op->atio
 * packet header, and dispatch into __qlt_do_work() using the existing
@@ -4312,7 +4313,7 @@ static void qlt_create_sess_from_atio(struct work_struct 
*work)
struct qla_qpair *qpair = ha->base_qpair;
 
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
-   qlt_send_busy(qpair, >atio, SAM_STAT_BUSY);
+   qlt_send_busy(qpair, >atio, tc_sam_status);
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
 
spin_lock_irqsave(>tgt.sess_lock, flags);
@@ -4332,6 +4333,17 @@ static void qlt_create_sess_from_atio(struct work_struct 
*work)
 out_term:
qlt_send_term_exchange(vha->hw->base_qpair, NULL, >atio, 0, 0);
kfree(op);
+   return;
+out_busy:
+   {
+   struct qla_qpair *qpair = ha->base_qpair;
+
+   spin_lock_irqsave(qpair->qp_lock_ptr, flags);
+   qlt_send_busy(qpair, >atio, qla_sam_status);
+   spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
+   kfree(op);
+   }
+   return;
 }
 
 /* ha->hardware_lock supposed to be held on entry */
@@ -4348,7 +4360,7 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host 
*vha,
if (unlikely(tgt->tgt_stop)) {
ql_dbg(ql_dbg_io, vha, 0x3061,
"New command while device %p is shutting down\n", tgt);
-   return -EFAULT;
+   return -ENODEV;
}
 
id.b.al_pa = atio->u.isp24.fcp_hdr.s_id[2];
@@ -4403,7 +4415,7 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host 
*vha,
spin_lock_irqsave(>tgt.sess_lock, flags);
ha->tgt.tgt_ops->put_sess(sess);
spin_unlock_irqrestore(>tgt.sess_lock, flags);
-   return -ENOMEM;
+   return -EBUSY;
}
 
cmd->cmd_in_wq = 1;
@@ -5504,7 +5516,6 @@ qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha, 
struct qla_qpair *qpair,
struct atio_from_isp *atio, uint8_t ha_locked)
 {
struct qla_hw_data *ha = vha->hw;
-   uint16_t status;
unsigned long flags;
 
if (ha->tgt.num_pend_cmds < Q_FULL_THRESH_HOLD(ha))
@@ -5512,8 +5523,7 @@ qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha, 
struct qla_qpair *qpair,
 
if (!ha_locked)
spin_lock_irqsave(>hardware_lock, flags);
-   status = temp_sam_status;
-   qlt_send_busy(qpair, atio, status);
+   qlt_send_busy(qpair, atio, qla_sam_status);
if (!ha_locked)
spin_unlock_irqrestore(>hardware_lock, flags);
 
@@ -5528,7 +5538,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
struct qla_hw_data *ha = vha->hw;
struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
int rc;
-   unsigned long flags;
+   unsigned long flags = 0;
 
if (unlikely(tgt == NULL)) {
ql_dbg(ql_dbg_tgt, vha, 0x3064,
@@ -5552,8 +5562,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
"sending QUEUE_FULL\n", vha->vp_idx);
if (!ha_locked)
spin_lock_irqsave(>hardware_lock, flags);
-   qlt_send_busy(ha->base_qpair, atio,
-   SAM_STAT_TASK_SET_FULL);
+   qlt_send_busy(ha->base_qpair, atio, qla_sam_status);
if (!ha_locked)
spin_unlock_irqrestore(>hardware_lock,

[PATCH 34/43] qla2xxx: Delay loop id allocation at login

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

Delay loop id allocation to login time

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_init.c | 64 ++---
 1 file changed, 35 insertions(+), 29 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 80e9d80cce2b..185c106cec0c 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -582,36 +582,29 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t 
*vha,
 
if (!found) {
/* fw has no record of this port */
-   if (fcport->loop_id == FC_NO_LOOP_ID) {
-   qla2x00_find_new_loop_id(vha, fcport);
-   fcport->fw_login_state = DSC_LS_PORT_UNAVAIL;
-   } else {
-   for (i = 0; i < n; i++) {
-   e = >gnl.l[i];
-   id.b.domain = e->port_id[0];
-   id.b.area = e->port_id[1];
-   id.b.al_pa = e->port_id[2];
-   id.b.rsvd_1 = 0;
-   loop_id = le16_to_cpu(e->nport_handle);
-
-   if (fcport->d_id.b24 == id.b24) {
-   conflict_fcport =
-   qla2x00_find_fcport_by_wwpn(vha,
-   e->port_name, 0);
-
-   ql_dbg(ql_dbg_disc, vha, 0x20e6,
-   "%s %d %8phC post del sess\n",
-   __func__, __LINE__,
-   conflict_fcport->port_name);
-   qlt_schedule_sess_for_deletion
-   (conflict_fcport, 1);
-   }
-
-   if (fcport->loop_id == loop_id) {
-   /* FW already picked this loop id for 
another fcport */
-   qla2x00_find_new_loop_id(vha, fcport);
-   }
+   for (i = 0; i < n; i++) {
+   e = >gnl.l[i];
+   id.b.domain = e->port_id[0];
+   id.b.area = e->port_id[1];
+   id.b.al_pa = e->port_id[2];
+   id.b.rsvd_1 = 0;
+   loop_id = le16_to_cpu(e->nport_handle);
+
+   if (fcport->d_id.b24 == id.b24) {
+   conflict_fcport =
+   qla2x00_find_fcport_by_wwpn(vha,
+   e->port_name, 0);
+   ql_dbg(ql_dbg_disc, vha, 0x20e6,
+   "%s %d %8phC post del sess\n",
+   __func__, __LINE__,
+   conflict_fcport->port_name);
+   qlt_schedule_sess_for_deletion
+   (conflict_fcport, 1);
}
+
+   /* FW already picked this loop id for another fcport */
+   if (fcport->loop_id == loop_id)
+   fcport->loop_id = FC_NO_LOOP_ID;
}
qla24xx_fcport_handle_login(vha, fcport);
}
@@ -1106,6 +1099,7 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
 static void qla_chk_n2n_b4_login(struct scsi_qla_host *vha, fc_port_t *fcport)
 {
u8 login = 0;
+   int rc;
 
if (qla_tgt_mode_enabled(vha))
return;
@@ -1131,6 +1125,18 @@ static void qla_chk_n2n_b4_login(struct scsi_qla_host 
*vha, fc_port_t *fcport)
}
 
if (login) {
+   if (fcport->loop_id == FC_NO_LOOP_ID) {
+   fcport->fw_login_state = DSC_LS_PORT_UNAVAIL;
+   rc = qla2x00_find_new_loop_id(vha, fcport);
+   if (rc) {
+   ql_dbg(ql_dbg_disc, vha, 0x20e6,
+   "%s %d %8phC post del sess - out of 
loopid\n",
+   __func__, __LINE__, fcport->port_name);
+   fcport->scan_state = 0;
+   qlt_schedule_sess_for_deletion(fcport, true);
+   return;
+   }
+   }
ql_dbg(ql_dbg_disc, vha, 0x20bf,
"%s %d %8phC post login\n",
__func__, __LINE__, fcport->port_name);
-- 
2.12.0



[PATCH 30/43] qla2xxx: Properly extract ADISC error codes

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

This patch fixes issue with extraction of ADISC error codes
for decoding the error returned

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_init.c | 24 
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index e58faa1e984c..bd28a0e6a95c 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -338,16 +338,21 @@ qla2x00_async_prlo(struct scsi_qla_host *vha, fc_port_t 
*fcport)
 static
 void qla24xx_handle_adisc_event(scsi_qla_host_t *vha, struct event_arg *ea)
 {
-   if (ea->rc) {
+   struct fc_port *fcport = ea->fcport;
+
+   ql_dbg(ql_dbg_disc, vha, 0x20d2,
+   "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d lid %d\n",
+   __func__, fcport->port_name, fcport->disc_state,
+   fcport->fw_login_state, ea->rc, fcport->login_gen, ea->sp->gen2,
+   fcport->rscn_gen, ea->sp->gen1, fcport->loop_id);
+
+   if (ea->data[0] != MBS_COMMAND_COMPLETE) {
ql_dbg(ql_dbg_disc, vha, 0x2066,
"%s %8phC: adisc fail: post delete\n",
__func__, ea->fcport->port_name);
qlt_schedule_sess_for_deletion(ea->fcport, 1);
return;
}
-   ql_dbg(ql_dbg_disc, vha, 0x20d2,
-   "%s %8phC DS %d LS %d\n", __func__, ea->fcport->port_name,
-   ea->fcport->disc_state, ea->fcport->fw_login_state);
 
if (ea->fcport->disc_state == DSC_DELETE_PEND)
return;
@@ -355,10 +360,8 @@ void qla24xx_handle_adisc_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
if (ea->sp->gen2 != ea->fcport->login_gen) {
/* target side must have changed it. */
ql_dbg(ql_dbg_disc, vha, 0x20d3,
-   "%s %8phC generation changed rscn %d|%d login %d|%d\n",
-   __func__, ea->fcport->port_name, ea->fcport->last_rscn_gen,
-   ea->fcport->rscn_gen, ea->fcport->last_login_gen,
-   ea->fcport->login_gen);
+   "%s %8phC generation changed\n",
+   __func__, ea->fcport->port_name);
return;
} else if (ea->sp->gen1 != ea->fcport->rscn_gen) {
ql_dbg(ql_dbg_disc, vha, 0x20d4, "%s %d %8phC post gidpn\n",
@@ -376,6 +379,7 @@ qla2x00_async_adisc_sp_done(void *ptr, int res)
srb_t *sp = ptr;
struct scsi_qla_host *vha = sp->vha;
struct event_arg ea;
+   struct srb_iocb *lio = >u.iocb_cmd;
 
ql_dbg(ql_dbg_disc, vha, 0x2066,
"Async done-%s res %x %8phC\n",
@@ -384,6 +388,10 @@ qla2x00_async_adisc_sp_done(void *ptr, int res)
memset(, 0, sizeof(ea));
ea.event = FCME_ADISC_DONE;
ea.rc = res;
+   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.fcport = sp->fcport;
ea.sp = sp;
 
-- 
2.12.0



[PATCH 28/43] qla2xxx: Remove session creation redundant code

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

Current code creates a session when a new port is
discovered, and a PLOGI/PRLI is received. There is
no need to create session when command has arrived.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_target.c | 122 ++
 1 file changed, 5 insertions(+), 117 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 93910e56643d..598ec3481a8c 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -2016,15 +2016,10 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host 
*vha,
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf012,
"qla_target(%d): task abort for non-existant session\n",
vha->vp_idx);
-   rc = qlt_sched_sess_work(vha->vha_tgt.qla_tgt,
-   QLA_TGT_SESS_WORK_ABORT, abts, sizeof(*abts));
-
spin_unlock_irqrestore(>tgt.sess_lock, flags);
 
-   if (rc != 0) {
-   qlt_24xx_send_abts_resp(ha->base_qpair, abts,
-   FCP_TMF_REJECTED, false);
-   }
+   qlt_24xx_send_abts_resp(ha->base_qpair, abts, FCP_TMF_REJECTED,
+   false);
return;
}
spin_unlock_irqrestore(>tgt.sess_lock, flags);
@@ -4265,87 +4260,6 @@ static struct qla_tgt_cmd *qlt_get_tag(scsi_qla_host_t 
*vha,
return cmd;
 }
 
-static void qlt_create_sess_from_atio(struct work_struct *work)
-{
-   struct qla_tgt_sess_op *op = container_of(work,
-   struct qla_tgt_sess_op, work);
-   scsi_qla_host_t *vha = op->vha;
-   struct qla_hw_data *ha = vha->hw;
-   struct fc_port *sess;
-   struct qla_tgt_cmd *cmd;
-   unsigned long flags;
-   uint8_t *s_id = op->atio.u.isp24.fcp_hdr.s_id;
-
-   spin_lock_irqsave(>cmd_list_lock, flags);
-   list_del(>cmd_list);
-   spin_unlock_irqrestore(>cmd_list_lock, flags);
-
-   if (op->aborted) {
-   ql_dbg(ql_dbg_tgt_mgt, vha, 0xf083,
-   "sess_op with tag %u is aborted\n",
-   op->atio.u.isp24.exchange_addr);
-   goto out_term;
-   }
-
-   ql_dbg(ql_dbg_tgt_mgt, vha, 0xf022,
-   "qla_target(%d): Unable to find wwn login"
-   " (s_id %x:%x:%x), trying to create it manually\n",
-   vha->vp_idx, s_id[0], s_id[1], s_id[2]);
-
-   if (op->atio.u.raw.entry_count > 1) {
-   ql_dbg(ql_dbg_tgt_mgt, vha, 0xf023,
-   "Dropping multy entry atio %p\n", >atio);
-   goto out_busy;
-   }
-
-   sess = qlt_make_local_sess(vha, s_id);
-   /* sess has an extra creation ref. */
-
-   if (!sess)
-   goto out_busy;
-   /*
-* Now obtain a pre-allocated session tag using the original op->atio
-* packet header, and dispatch into __qlt_do_work() using the existing
-* process context.
-*/
-   cmd = qlt_get_tag(vha, sess, >atio);
-   if (!cmd) {
-   struct qla_qpair *qpair = ha->base_qpair;
-
-   spin_lock_irqsave(qpair->qp_lock_ptr, flags);
-   qlt_send_busy(qpair, >atio, tc_sam_status);
-   spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
-
-   spin_lock_irqsave(>tgt.sess_lock, flags);
-   ha->tgt.tgt_ops->put_sess(sess);
-   spin_unlock_irqrestore(>tgt.sess_lock, flags);
-   kfree(op);
-   return;
-   }
-
-   /*
-* __qlt_do_work() will call qlt_put_sess() to release
-* the extra reference taken above by qlt_make_local_sess()
-*/
-   __qlt_do_work(cmd);
-   kfree(op);
-   return;
-out_term:
-   qlt_send_term_exchange(vha->hw->base_qpair, NULL, >atio, 0, 0);
-   kfree(op);
-   return;
-out_busy:
-   {
-   struct qla_qpair *qpair = ha->base_qpair;
-
-   spin_lock_irqsave(qpair->qp_lock_ptr, flags);
-   qlt_send_busy(qpair, >atio, qla_sam_status);
-   spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
-   kfree(op);
-   }
-   return;
-}
-
 /* ha->hardware_lock supposed to be held on entry */
 static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
struct atio_from_isp *atio)
@@ -4370,23 +4284,8 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host 
*vha,
return -EBUSY;
 
sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, 
atio->u.isp24.fcp_hdr.s_id);
-   if (unlikely(!sess)) {
-   struct qla_tgt_sess_op *op = kzalloc(sizeof(struct 
qla_tgt_sess_op),
-GFP_ATOMIC);
-   if (!op)
-   return -ENOMEM;
-
-   memcpy(>atio, 

[PATCH 23/43] qla2xxx: Add lock protection around host lookup

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

Host lookup via btree is currently protected by the hardware_lock.
Add hardware_lock when modifying btree to store host pointer.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_init.c   | 3 +++
 drivers/scsi/qla2xxx/qla_mid.c| 9 +
 drivers/scsi/qla2xxx/qla_target.c | 6 --
 3 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index cdcd84278fd0..300cd795dad4 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -3977,6 +3977,7 @@ qla2x00_configure_hba(scsi_qla_host_t *vha)
struct qla_hw_data *ha = vha->hw;
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
port_id_t id;
+   unsigned long flags;
 
/* Get host addresses. */
rval = qla2x00_get_adapter_id(vha,
@@ -4058,7 +4059,9 @@ qla2x00_configure_hba(scsi_qla_host_t *vha)
id.b.area = area;
id.b.al_pa = al_pa;
id.b.rsvd_1 = 0;
+   spin_lock_irqsave(>hardware_lock, flags);
qlt_update_host_map(vha, id);
+   spin_unlock_irqrestore(>hardware_lock, flags);
 
if (!vha->flags.init_done)
ql_log(ql_log_info, vha, 0x2010,
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index a823fa6b7060..12a29eca02e1 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -50,10 +50,11 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha)
 
spin_lock_irqsave(>vport_slock, flags);
list_add_tail(>list, >vp_list);
+   spin_unlock_irqrestore(>vport_slock, flags);
 
+   spin_lock_irqsave(>hardware_lock, flags);
qlt_update_vp_map(vha, SET_VP_IDX);
-
-   spin_unlock_irqrestore(>vport_slock, flags);
+   spin_unlock_irqrestore(>hardware_lock, flags);
 
mutex_unlock(>vport_lock);
return vp_id;
@@ -158,9 +159,9 @@ qla24xx_disable_vp(scsi_qla_host_t *vha)
atomic_set(>loop_down_timer, LOOP_DOWN_TIME);
 
/* Remove port id from vp target map */
-   spin_lock_irqsave(>hw->vport_slock, flags);
+   spin_lock_irqsave(>hw->hardware_lock, flags);
qlt_update_vp_map(vha, RESET_AL_PA);
-   spin_unlock_irqrestore(>hw->vport_slock, flags);
+   spin_unlock_irqrestore(>hw->hardware_lock, flags);
 
qla2x00_mark_vp_devices_dead(vha);
atomic_set(>vp_state, VP_FAILED);
diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 48e0a12dca61..c7c81d5cf69c 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -7206,20 +7206,14 @@ qlt_update_vp_map(struct scsi_qla_host *vha, int cmd)
 
 void qlt_update_host_map(struct scsi_qla_host *vha, port_id_t id)
 {
-   unsigned long flags;
-   struct qla_hw_data *ha = vha->hw;
 
if (!vha->d_id.b24) {
-   spin_lock_irqsave(>vport_slock, flags);
vha->d_id = id;
qlt_update_vp_map(vha, SET_AL_PA);
-   spin_unlock_irqrestore(>vport_slock, flags);
} else if (vha->d_id.b24 != id.b24) {
-   spin_lock_irqsave(>vport_slock, flags);
qlt_update_vp_map(vha, RESET_AL_PA);
vha->d_id = id;
qlt_update_vp_map(vha, SET_AL_PA);
-   spin_unlock_irqrestore(>vport_slock, flags);
}
 }
 
-- 
2.12.0



[PATCH 27/43] qla2xxx: Migrate switch registration commands away from mailbox interface

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

Migrate switch registration commands: RFTID, RFFID, RNNID and RSNN_NN
out of mailbox interface to reduce fabric scan bottle neck.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_def.h|   8 +-
 drivers/scsi/qla2xxx/qla_gbl.h|   2 +-
 drivers/scsi/qla2xxx/qla_gs.c | 454 +++---
 drivers/scsi/qla2xxx/qla_os.c |  20 +-
 drivers/scsi/qla2xxx/qla_target.c |  13 +-
 drivers/scsi/qla2xxx/qla_target.h |   2 +-
 6 files changed, 355 insertions(+), 144 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 3042697b92ae..db1f68c3e074 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -516,6 +516,10 @@ enum {
SPCN_NVME_CMD,
SPCN_CTRL_VP,
SPCN_PRLO,
+   SPCN_RFTID,
+   SPCN_RFFID,
+   SPCN_RNNID,
+   SPCN_RS,
 };
 
 struct sp_name {
@@ -581,6 +585,7 @@ typedef struct srb {
u32 gen1;   /* scratch */
u32 gen2;   /* scratch */
int rc;
+   int retry_count;
struct completion comp;
union {
struct srb_iocb iocb_cmd;
@@ -3234,7 +3239,7 @@ enum qla_work_type {
QLA_EVT_AENFX,
QLA_EVT_GIDPN,
QLA_EVT_GPNID,
-   QLA_EVT_GPNID_DONE,
+   QLA_EVT_UNMAP,
QLA_EVT_NEW_SESS,
QLA_EVT_GPDB,
QLA_EVT_PRLI,
@@ -3250,6 +3255,7 @@ enum qla_work_type {
QLA_EVT_GNNFT_DONE,
QLA_EVT_GNNID,
QLA_EVT_GFPNID,
+   QLA_EVT_SP_RETRY,
 };
 
 
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 43799e8dc68a..650ec54e3255 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -650,7 +650,6 @@ extern void qla2x00_free_fcport(fc_port_t *);
 
 extern int qla24xx_post_gpnid_work(struct scsi_qla_host *, port_id_t *);
 extern int qla24xx_async_gpnid(scsi_qla_host_t *, port_id_t *);
-void qla24xx_async_gpnid_done(scsi_qla_host_t *, srb_t*);
 void qla24xx_handle_gpnid_event(scsi_qla_host_t *, struct event_arg *);
 
 int qla24xx_post_gpsc_work(struct scsi_qla_host *, fc_port_t *);
@@ -669,6 +668,7 @@ int qla24xx_post_gnnid_work(struct scsi_qla_host *, 
fc_port_t *);
 int qla24xx_post_gfpnid_work(struct scsi_qla_host *, fc_port_t *);
 int qla24xx_async_gfpnid(scsi_qla_host_t *, fc_port_t *);
 void qla24xx_handle_gfpnid_event(scsi_qla_host_t *vha, struct event_arg *ea);
+void qla24xx_sp_unmap(scsi_qla_host_t *, srb_t *);
 
 /*
  * Global Function Prototypes in qla_attr.c source file.
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 643ce1578cbe..0e84381e227e 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -14,6 +14,10 @@ static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t 
*);
 static int qla2x00_sns_gnn_id(scsi_qla_host_t *, sw_info_t *);
 static int qla2x00_sns_rft_id(scsi_qla_host_t *);
 static int qla2x00_sns_rnn_id(scsi_qla_host_t *);
+static int qla_async_rftid(scsi_qla_host_t *, port_id_t *);
+static int qla_async_rffid(scsi_qla_host_t *, port_id_t *, u8, u8);
+static int qla_async_rnnid(scsi_qla_host_t *, port_id_t *, u8*);
+static int qla_async_rsnn_nn(scsi_qla_host_t *);
 
 struct sp_name sp_str[] = {
{ SPCN_UNKNOWN, "unknown" },
@@ -43,6 +47,10 @@ struct sp_name sp_str[] = {
{ SPCN_NVME_CMD, "nvme_cmd" },
{ SPCN_CTRL_VP, "ctrl_vp" },
{ SPCN_PRLO, "prlo" },
+   { SPCN_RFTID, "rftid" },
+   { SPCN_RFFID, "rffid" },
+   { SPCN_RNNID, "rnnid" },
+   { SPCN_RS, "rsnn_nn" },
 };
 
 const char *sp_to_str(uint16_t cmd)
@@ -556,6 +564,72 @@ qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
return (rval);
 }
 
+static void qla2x00_async_sns_sp_done(void *s, int rc)
+{
+   struct srb *sp = s;
+   struct scsi_qla_host *vha = sp->vha;
+   struct ct_sns_pkt *ct_sns;
+   struct qla_work_evt *e;
+
+   sp->rc = rc;
+   if (rc == QLA_SUCCESS) {
+   ql_dbg(ql_dbg_disc, vha, 0x204f,
+   "Async done-%s exiting normally.\n",
+   sp->name);
+   } else if (rc == QLA_FUNCTION_TIMEOUT) {
+   ql_dbg(ql_dbg_disc, vha, 0x204f,
+   "Async done-%s timeout\n", sp->name);
+   } else {
+   ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp;
+   memset(ct_sns, 0, sizeof(*ct_sns));
+   sp->retry_count++;
+   if (sp->retry_count > 3)
+   goto err;
+
+   ql_dbg(ql_dbg_disc, vha, 0x204f,
+   "Async done-%s fail rc %x.  Retry count %d\n",
+   sp->name, rc, sp->retry_count);
+
+   e = qla2x00_alloc_work(vha, QLA_EVT_SP_RETRY);
+   if (!e)
+   goto err2;
+
+   

[PATCH 26/43] qla2xxx: Fix login state machine freeze

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

Relogin stop moving forward due to improper check of scan_state flag.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_init.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 300cd795dad4..152c808b272b 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1270,11 +1270,6 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha,
 {
fc_port_t *fcport = ea->fcport;
 
-   if (fcport->scan_state != QLA_FCPORT_FOUND) {
-   fcport->login_retry++;
-   return;
-   }
-
ql_dbg(ql_dbg_disc, vha, 0x2102,
"%s %8phC DS %d LS %d P %d del %d cnfl %p rscn %d|%d login %d|%d fl 
%x\n",
__func__, fcport->port_name, fcport->disc_state,
@@ -1324,7 +1319,6 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, 
struct event_arg *ea)
int rc;
 
switch (ea->event) {
-   case FCME_RELOGIN:
case FCME_RSCN:
case FCME_GIDPN_DONE:
case FCME_GPSC_DONE:
-- 
2.12.0



[PATCH 40/43] qla2xxx: Remove unused argument from qlt_schedule_sess_for_deletion()

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

Immeadiate flag is not used for scheduling session deletion.
Remove it to simplfy session deletion code path.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_gbl.h|  2 +-
 drivers/scsi/qla2xxx/qla_init.c   | 10 +-
 drivers/scsi/qla2xxx/qla_target.c | 16 +++-
 3 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 91db1924ca79..ab8ffd7933c9 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -888,7 +888,7 @@ void qla24xx_do_nack_work(struct scsi_qla_host *, struct 
qla_work_evt *);
 void qlt_plogi_ack_link(struct scsi_qla_host *, struct qlt_plogi_ack_t *,
struct fc_port *, enum qlt_plogi_link_t);
 void qlt_plogi_ack_unref(struct scsi_qla_host *, struct qlt_plogi_ack_t *);
-extern void qlt_schedule_sess_for_deletion(struct fc_port *, bool);
+extern void qlt_schedule_sess_for_deletion(struct fc_port *);
 extern void qlt_schedule_sess_for_deletion_lock(struct fc_port *);
 extern struct fc_port *qlt_find_sess_invalidate_other(scsi_qla_host_t *,
uint64_t wwn, port_id_t port_id, uint16_t loop_id, struct fc_port **);
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 49a8f2666f55..3e03c264f7bd 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -352,7 +352,7 @@ void qla24xx_handle_adisc_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
ql_dbg(ql_dbg_disc, vha, 0x2066,
"%s %8phC: adisc fail: post delete\n",
__func__, ea->fcport->port_name);
-   qlt_schedule_sess_for_deletion(ea->fcport, 1);
+   qlt_schedule_sess_for_deletion(ea->fcport);
return;
}
 
@@ -529,7 +529,7 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t 
*vha,
ql_dbg(ql_dbg_disc, vha, 0x20e3,
"%s %d %8phC post del sess\n",
__func__, __LINE__, fcport->port_name);
-   qlt_schedule_sess_for_deletion(fcport, 1);
+   qlt_schedule_sess_for_deletion(fcport);
return;
}
 
@@ -601,7 +601,7 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t 
*vha,
__func__, __LINE__,
conflict_fcport->port_name);
qlt_schedule_sess_for_deletion
-   (conflict_fcport, 1);
+   (conflict_fcport);
}
 
/* FW already picked this loop id for another fcport */
@@ -1136,7 +1136,7 @@ static void qla_chk_n2n_b4_login(struct scsi_qla_host 
*vha, fc_port_t *fcport)
"%s %d %8phC post del sess - out of 
loopid\n",
__func__, __LINE__, fcport->port_name);
fcport->scan_state = 0;
-   qlt_schedule_sess_for_deletion(fcport, true);
+   qlt_schedule_sess_for_deletion(fcport);
return;
}
}
@@ -1782,7 +1782,7 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host 
*vha, struct event_arg *ea)
set_bit(lid, vha->hw->loop_id_map);
ea->fcport->loop_id = lid;
ea->fcport->keep_nport_handle = 0;
-   qlt_schedule_sess_for_deletion(ea->fcport, false);
+   qlt_schedule_sess_for_deletion(ea->fcport);
}
break;
}
diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 43e210757840..6b16f0dbd588 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1211,8 +1211,7 @@ static void qla24xx_chk_fcp_state(struct fc_port *sess)
 }
 
 /* ha->tgt.sess_lock supposed to be held on entry */
-void qlt_schedule_sess_for_deletion(struct fc_port *sess,
-   bool immediate)
+void qlt_schedule_sess_for_deletion(struct fc_port *sess)
 {
struct qla_tgt *tgt = sess->tgt;
 
@@ -1250,7 +1249,7 @@ void qlt_schedule_sess_for_deletion_lock(struct fc_port 
*sess)
unsigned long flags;
struct qla_hw_data *ha = sess->vha->hw;
spin_lock_irqsave(>tgt.sess_lock, flags);
-   qlt_schedule_sess_for_deletion(sess, 1);
+   qlt_schedule_sess_for_deletion(sess);
spin_unlock_irqrestore(>tgt.sess_lock, flags);
 }
 
@@ -1262,7 +1261,7 @@ static void qlt_clear_tgt_db(struct qla_tgt *tgt)
 
list_for_each_entry(sess, >vp_fcports, list) {
if (sess->se_sess)
-   

[PATCH 33/43] qla2xxx: Increase verbosity of debug messages logged

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

Add verbose bit for debug messages to reduce excessive
log messages

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_target.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 598ec3481a8c..43e210757840 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -209,7 +209,7 @@ struct scsi_qla_host *qlt_find_host_by_d_id(struct 
scsi_qla_host *vha,
 
host = btree_lookup32(>hw->tgt.host_map, key);
if (!host)
-   ql_dbg(ql_dbg_tgt_mgt, vha, 0xf005,
+   ql_dbg(ql_dbg_tgt_mgt + ql_dbg_verbose, vha, 0xf005,
"Unable to find host %06x\n", key);
 
return host;
@@ -310,17 +310,17 @@ static void qlt_try_to_dequeue_unknown_atios(struct 
scsi_qla_host *vha,
 
host = qlt_find_host_by_d_id(vha, u->atio.u.isp24.fcp_hdr.d_id);
if (host != NULL) {
-   ql_dbg(ql_dbg_async, vha, 0x502f,
+   ql_dbg(ql_dbg_async + ql_dbg_verbose, vha, 0x502f,
"Requeuing unknown ATIO_TYPE7 %p\n", u);
qlt_24xx_atio_pkt(host, >atio, ha_locked);
} else if (tgt->tgt_stop) {
-   ql_dbg(ql_dbg_async, vha, 0x503a,
+   ql_dbg(ql_dbg_async + ql_dbg_verbose, vha, 0x503a,
"Freeing unknown %s %p, because tgt is being 
stopped\n",
"ATIO_TYPE7", u);
qlt_send_term_exchange(vha->hw->base_qpair, NULL,
>atio, ha_locked, 0);
} else {
-   ql_dbg(ql_dbg_async, vha, 0x503d,
+   ql_dbg(ql_dbg_async + ql_dbg_verbose, vha, 0x503d,
"Reschedule u %p, vha %p, host %p\n", u, vha, host);
if (!queued) {
queued = 1;
-- 
2.12.0



[PATCH 32/43] qla2xxx: Allow relogin and session creation after reset

2017-12-19 Thread Himanshu Madhani
When any kind of reset is issued, current code was setting
state of LOGIN pending too early. This resulted into driver
not retrying relogin until pervious reloin completes.

Signed-off-by: Himanshu Madhani 
Signed-off-by: Quinn Tran 
---
 drivers/scsi/qla2xxx/qla_init.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index ac3f82340315..80e9d80cce2b 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1134,7 +1134,6 @@ static void qla_chk_n2n_b4_login(struct scsi_qla_host 
*vha, fc_port_t *fcport)
ql_dbg(ql_dbg_disc, vha, 0x20bf,
"%s %d %8phC post login\n",
__func__, __LINE__, fcport->port_name);
-   fcport->disc_state = DSC_LOGIN_PEND;
qla2x00_post_async_login_work(vha, fcport, NULL);
}
 }
-- 
2.12.0



[PATCH 22/43] qla2xxx: Add switch command to simplify fabric discovery

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

- add "async" gpn_ft, gnn_ft, gfpn_id, gnn_id switch commands.
- For 8G and newer adapters, use async commands when it comes to
fabric scan to reduce bottle neck.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_attr.c   |   2 +
 drivers/scsi/qla2xxx/qla_def.h|  73 +++-
 drivers/scsi/qla2xxx/qla_gbl.h|  17 +-
 drivers/scsi/qla2xxx/qla_gs.c | 711 +-
 drivers/scsi/qla2xxx/qla_init.c   | 309 +++--
 drivers/scsi/qla2xxx/qla_mbx.c|   5 +-
 drivers/scsi/qla2xxx/qla_os.c |  47 ++-
 drivers/scsi/qla2xxx/qla_target.c |  62 +++-
 drivers/scsi/qla2xxx/qla_target.h |   2 +-
 9 files changed, 1105 insertions(+), 123 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 9ce28c4f9812..b360df9936ff 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -2170,6 +2170,8 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
dma_free_coherent(>pdev->dev, vha->gnl.size, vha->gnl.l,
vha->gnl.ldma);
 
+   vfree(vha->scan.l);
+
if (vha->qpair && vha->qpair->vp_idx == vha->vp_idx) {
if (qla2xxx_delete_qpair(vha, vha->qpair) != QLA_SUCCESS)
ql_log(ql_log_warn, vha, 0x7087,
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 749f3e457346..3042697b92ae 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -490,6 +490,7 @@ enum {
SPCN_GPSC,
SPCN_GPNID,
SPCN_GPNFT,
+   SPCN_GNNFT,
SPCN_GNNID,
SPCN_GFPNID,
SPCN_LOGIN,
@@ -2315,11 +2316,13 @@ struct ct_sns_desc {
 
 enum discovery_state {
DSC_DELETED,
+   DSC_GNN_ID,
DSC_GID_PN,
DSC_GNL,
DSC_LOGIN_PEND,
DSC_LOGIN_FAILED,
DSC_GPDB,
+   DSC_GFPN_ID,
DSC_GPSC,
DSC_UPD_FCPORT,
DSC_LOGIN_COMPLETE,
@@ -2349,8 +2352,9 @@ enum fcport_mgt_event {
FCME_GPDB_DONE,
FCME_GPNID_DONE,
FCME_GFFID_DONE,
-   FCME_DELETE_DONE,
FCME_ADISC_DONE,
+   FCME_GNNID_DONE,
+   FCME_GFPNID_DONE,
 };
 
 enum rscn_addr_format {
@@ -2383,6 +2387,7 @@ typedef struct fc_port {
unsigned int login_pause:1;
unsigned int login_succ:1;
unsigned int query:1;
+   unsigned int id_changed:1;
 
struct work_struct nvme_del_work;
struct completion nvme_del_done;
@@ -2530,6 +2535,11 @@ static const char * const port_state_str[] = {
 #defineGA_NXT_REQ_SIZE (16 + 4)
 #defineGA_NXT_RSP_SIZE (16 + 620)
 
+#defineGPN_FT_CMD  0x172
+#defineGPN_FT_REQ_SIZE (16 + 4)
+#defineGNN_FT_CMD  0x173
+#defineGNN_FT_REQ_SIZE (16 + 4)
+
 #defineGID_PT_CMD  0x1A1
 #defineGID_PT_REQ_SIZE (16 + 4)
 
@@ -2785,6 +2795,13 @@ struct ct_sns_req {
} port_id;
 
struct {
+   uint8_t reserved;
+   uint8_t domain;
+   uint8_t area;
+   uint8_t port_type;
+   } gpn_ft;
+
+   struct {
uint8_t port_type;
uint8_t domain;
uint8_t area;
@@ -2897,6 +2914,27 @@ struct ct_sns_gid_pt_data {
uint8_t port_id[3];
 };
 
+/* It's the same for both GPN_FT and GNN_FT */
+struct ct_sns_gpnft_rsp {
+   struct {
+   struct ct_cmd_hdr header;
+   uint16_t response;
+   uint16_t residual;
+   uint8_t fragment_id;
+   uint8_t reason_code;
+   uint8_t explanation_code;
+   uint8_t vendor_unique;
+   };
+   /* Assume the largest number of targets for the union */
+   struct ct_sns_gpn_ft_data {
+   u8 control_byte;
+   u8 port_id[3];
+   u32 reserved;
+   u8 port_name[8];
+   } entries[1];
+};
+
+/* CT command response */
 struct ct_sns_rsp {
struct ct_rsp_hdr header;
 
@@ -2972,6 +3010,24 @@ struct ct_sns_pkt {
} p;
 };
 
+struct ct_sns_gpnft_pkt {
+   union {
+   struct ct_sns_req req;
+   struct ct_sns_gpnft_rsp rsp;
+   } p;
+};
+
+struct fab_scan_rp {
+   port_id_t id;
+   u8 port_name[8];
+   u8 node_name[8];
+};
+
+struct fab_scan {
+   struct fab_scan_rp *l;
+   u32 size;
+};
+
 /*
  * SNS command structures -- for 2200 compatibility.
  */
@@ -3189,6 +3245,11 @@ enum qla_work_type {
QLA_EVT_RELOGIN,
QLA_EVT_ASYNC_PRLO,
QLA_EVT_ASYNC_PRLO_DONE,
+   QLA_EVT_GPNFT,
+   QLA_EVT_GPNFT_DONE,
+   QLA_EVT_GNNFT_DONE,
+   QLA_EVT_GNNID,
+   QLA_EVT_GFPNID,
 };
 
 
@@ -3230,7 +3291,9 @@ struct qla_work_evt {

[PATCH 25/43] qla2xxx: Reduce trace noise for Async Events

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

Add NPIV id check to reduce multiple debug messages
of the same RSCN event.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_mid.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index 12a29eca02e1..11a424df5f52 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -265,13 +265,20 @@ qla2x00_alert_all_vps(struct rsp_que *rsp, uint16_t *mb)
case MBA_LIP_RESET:
case MBA_POINT_TO_POINT:
case MBA_CHG_IN_CONNECTION:
-   case MBA_PORT_UPDATE:
-   case MBA_RSCN_UPDATE:
ql_dbg(ql_dbg_async, vha, 0x5024,
"Async_event for VP[%d], mb=0x%x vha=%p.\n",
i, *mb, vha);
qla2x00_async_event(vha, rsp, mb);
break;
+   case MBA_PORT_UPDATE:
+   case MBA_RSCN_UPDATE:
+   if ((mb[3] & 0xff) == vha->vp_idx) {
+   ql_dbg(ql_dbg_async, vha, 0x5024,
+   "Async_event for VP[%d], mb=0x%x 
vha=%p\n",
+   i, *mb, vha);
+   qla2x00_async_event(vha, rsp, mb);
+   }
+   break;
}
 
spin_lock_irqsave(>vport_slock, flags);
-- 
2.12.0



[PATCH 39/43] qla2xxx: Check FCF_ASYNC_SENT flag

2017-12-19 Thread Himanshu Madhani
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_init.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 85bdb6928ea2..49a8f2666f55 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -720,7 +720,7 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t 
*fcport)
u16 *mb;
 
if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
-   goto done;
+   return rval;
 
ql_dbg(ql_dbg_disc, vha, 0x20d9,
"Async-gnlist WWPN %8phC \n", fcport->port_name);
@@ -734,8 +734,7 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t 
*fcport)
list_add_tail(>gnl_entry, >gnl.fcports);
if (vha->gnl.sent) {
spin_unlock_irqrestore(>hw->tgt.sess_lock, flags);
-   rval = QLA_SUCCESS;
-   goto done;
+   return QLA_SUCCESS;
}
vha->gnl.sent = 1;
spin_unlock_irqrestore(>hw->tgt.sess_lock, flags);
-- 
2.12.0



[PATCH 11/43] qla2xxx: Move work element processing out of DPC thread

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

DPC thread can stall during switch scan due to slow switch response.
This will stall other work element that needs attention. Moving work
element processing and relogin logic out of DPC thread and into its
own work queue.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_def.h  |  6 ++--
 drivers/scsi/qla2xxx/qla_gbl.h  |  2 +-
 drivers/scsi/qla2xxx/qla_init.c |  1 +
 drivers/scsi/qla2xxx/qla_mid.c  |  6 +---
 drivers/scsi/qla2xxx/qla_os.c   | 76 +++--
 5 files changed, 63 insertions(+), 28 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 18b393453002..a2c0f3d78b35 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3183,6 +3183,7 @@ enum qla_work_type {
QLA_EVT_UPD_FCPORT,
QLA_EVT_GNL,
QLA_EVT_NACK,
+   QLA_EVT_RELOGIN,
 };
 
 
@@ -3513,10 +3514,6 @@ struct qlt_hw_data {
 
 #define LEAK_EXCHG_THRESH_HOLD_PERCENT 75  /* 75 percent */
 
-#define QLA_EARLY_LINKUP(_ha) \
-   ((_ha->flags.n2n_ae || _ha->flags.lip_ae) && \
-_ha->flags.fw_started && !_ha->flags.fw_init_done)
-
 /*
  * Qlogic host adapter specific data structure.
 */
@@ -4222,6 +4219,7 @@ typedef struct scsi_qla_host {
 #define SET_ZIO_THRESHOLD_NEEDED   28
 #define DETECT_SFP_CHANGE  29
 #define N2N_LOGIN_NEEDED   30
+#define IOCB_WORK_ACTIVE   31
 
unsigned long   pci_flags;
 #define PFLG_DISCONNECTED  0   /* PCI device removed */
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 66dcbdb91244..fb1c9ffdc05a 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -204,7 +204,7 @@ void qla2x00_handle_login_done_event(struct scsi_qla_host 
*, fc_port_t *,
uint16_t *);
 int qla24xx_post_gnl_work(struct scsi_qla_host *, fc_port_t *);
 int qla24xx_async_abort_cmd(srb_t *);
-
+int qla24xx_post_relogin_work(struct scsi_qla_host *vha);
 /*
  * Global Functions in qla_mid.c source file.
  */
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 0a1c287c2d66..61b74fd220a3 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -901,6 +901,7 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct 
event_arg *ea)
__func__, fcport->port_name, fcport->last_rscn_gen,
fcport->rscn_gen, fcport->last_login_gen,
fcport->login_gen);
+   set_bit(RELOGIN_NEEDED, >dpc_flags);
return;
} else if (ea->sp->gen1 != fcport->rscn_gen) {
ql_dbg(ql_dbg_disc, vha, 0x20d4, "%s %d %8phC post gidpn\n",
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index fc61fef5e305..b2fda398a098 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -319,8 +319,6 @@ qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
ql_dbg(ql_dbg_dpc + ql_dbg_verbose, vha, 0x4012,
"Entering %s vp_flags: 0x%lx.\n", __func__, vha->vp_flags);
 
-   qla2x00_do_work(vha);
-
/* Check if Fw is ready to configure VP first */
if (test_bit(VP_CONFIG_OK, _vha->vp_flags)) {
if (test_and_clear_bit(VP_IDX_ACQUIRED, >vp_flags)) {
@@ -354,9 +352,7 @@ qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
 
ql_dbg(ql_dbg_dpc, vha, 0x4018,
"Relogin needed scheduled.\n");
-   qla2x00_relogin(vha);
-   ql_dbg(ql_dbg_dpc, vha, 0x4019,
-   "Relogin needed end.\n");
+   qla24xx_post_relogin_work(vha);
}
}
 
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 4a542a5a976d..66e6fe73a035 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -2683,14 +2683,22 @@ static void qla2x00_iocb_work_fn(struct work_struct 
*work)
 {
struct scsi_qla_host *vha = container_of(work,
struct scsi_qla_host, iocb_work);
-   int cnt = 0;
+   struct qla_hw_data *ha = vha->hw;
+   struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
+   int i = 20;
+   unsigned long flags;
+
+   if (test_bit(UNLOADING, _vha->dpc_flags))
+   return;
 
-   while (!list_empty(>work_list)) {
+   while (!list_empty(>work_list) && i > 0) {
qla2x00_do_work(vha);
-   cnt++;
-   if (cnt > 10)
-   break;
+   i--;
}
+
+   spin_lock_irqsave(>work_lock, flags);
+   clear_bit(IOCB_WORK_ACTIVE, >dpc_flags);
+   spin_unlock_irqrestore(>work_lock, flags);
 }
 
 /*
@@ -3192,7 +3200,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct 
pci_device_id *id)
 

[PATCH 09/43] qla2xxx: Fix Firmware dump size for Extended login and Exchange Offload

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

This patch adjusts and reallocates fw_dump memory for target mode
to save for extended login and exchange offload buffers into
dump captured.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_init.c | 209 +---
 drivers/scsi/qla2xxx/qla_tmpl.c |  40 +++-
 2 files changed, 147 insertions(+), 102 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 429305caef47..5cd04bfa5cae 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -2593,70 +2593,27 @@ qla24xx_chip_diag(scsi_qla_host_t *vha)
return rval;
 }
 
-void
-qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
+static void
+qla2x00_alloc_offload_mem(scsi_qla_host_t *vha)
 {
int rval;
-   uint32_t dump_size, fixed_size, mem_size, req_q_size, rsp_q_size,
-   eft_size, fce_size, mq_size;
dma_addr_t tc_dma;
void *tc;
struct qla_hw_data *ha = vha->hw;
-   struct req_que *req = ha->req_q_map[0];
-   struct rsp_que *rsp = ha->rsp_q_map[0];
 
-   if (ha->fw_dump) {
+   if (ha->eft) {
ql_dbg(ql_dbg_init, vha, 0x00bd,
-   "Firmware dump already allocated.\n");
+   "%s: Offload Mem is already allocated.\n",
+   __func__);
return;
}
 
-   ha->fw_dumped = 0;
-   ha->fw_dump_cap_flags = 0;
-   dump_size = fixed_size = mem_size = eft_size = fce_size = mq_size = 0;
-   req_q_size = rsp_q_size = 0;
-
-   if (IS_QLA27XX(ha))
-   goto try_fce;
-
-   if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
-   fixed_size = sizeof(struct qla2100_fw_dump);
-   } else if (IS_QLA23XX(ha)) {
-   fixed_size = offsetof(struct qla2300_fw_dump, data_ram);
-   mem_size = (ha->fw_memory_size - 0x11000 + 1) *
-   sizeof(uint16_t);
-   } else if (IS_FWI2_CAPABLE(ha)) {
-   if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
-   fixed_size = offsetof(struct qla83xx_fw_dump, ext_mem);
-   else if (IS_QLA81XX(ha))
-   fixed_size = offsetof(struct qla81xx_fw_dump, ext_mem);
-   else if (IS_QLA25XX(ha))
-   fixed_size = offsetof(struct qla25xx_fw_dump, ext_mem);
-   else
-   fixed_size = offsetof(struct qla24xx_fw_dump, ext_mem);
-
-   mem_size = (ha->fw_memory_size - 0x10 + 1) *
-   sizeof(uint32_t);
-   if (ha->mqenable) {
-   if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
-   mq_size = sizeof(struct qla2xxx_mq_chain);
-   /*
-* Allocate maximum buffer size for all queues.
-* Resizing must be done at end-of-dump processing.
-*/
-   mq_size += ha->max_req_queues *
-   (req->length * sizeof(request_t));
-   mq_size += ha->max_rsp_queues *
-   (rsp->length * sizeof(response_t));
-   }
-   if (ha->tgt.atio_ring)
-   mq_size += ha->tgt.atio_q_length * sizeof(request_t);
+   if (IS_FWI2_CAPABLE(ha)) {
/* Allocate memory for Fibre Channel Event Buffer. */
if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) &&
!IS_QLA27XX(ha))
goto try_eft;
 
-try_fce:
if (ha->fce)
dma_free_coherent(>pdev->dev,
FCE_SIZE, ha->fce, ha->fce_dma);
@@ -2684,7 +2641,6 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
ql_dbg(ql_dbg_init, vha, 0x00c0,
"Allocate (%d KB) for FCE...\n", FCE_SIZE / 1024);
 
-   fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE;
ha->flags.fce_enabled = 1;
ha->fce_dma = tc_dma;
ha->fce = tc;
@@ -2701,7 +2657,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
ql_log(ql_log_warn, vha, 0x00c1,
"Unable to allocate (%d KB) for EFT.\n",
EFT_SIZE / 1024);
-   goto cont_alloc;
+   goto eft_err;
}
 
rval = qla2x00_enable_eft_trace(vha, tc_dma, EFT_NUM_BUFFERS);
@@ -2710,17 +2666,76 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
"Unable to initialize EFT (%d).\n", rval);
dma_free_coherent(>pdev->dev, EFT_SIZE, tc,
tc_dma);
-   goto cont_alloc;
+   goto eft_err;
}

[PATCH 31/43] qla2xxx: Add ability to use GPNFT/GNNFT for RSCN handling

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

add ability to use gpnft/gnnft to handle RSCN.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_def.h  |  7 +++
 drivers/scsi/qla2xxx/qla_gbl.h  |  1 +
 drivers/scsi/qla2xxx/qla_gs.c   | 99 -
 drivers/scsi/qla2xxx/qla_init.c | 65 ++-
 drivers/scsi/qla2xxx/qla_os.c   |  1 +
 5 files changed, 113 insertions(+), 60 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index db1f68c3e074..f061483475ce 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3022,6 +3022,11 @@ struct ct_sns_gpnft_pkt {
} p;
 };
 
+enum scan_flags_t {
+   SF_SCANNING = BIT_0,
+   SF_QUEUED = BIT_1,
+};
+
 struct fab_scan_rp {
port_id_t id;
u8 port_name[8];
@@ -3031,6 +3036,8 @@ struct fab_scan_rp {
 struct fab_scan {
struct fab_scan_rp *l;
u32 size;
+   enum scan_flags_t scan_flags;
+   struct delayed_work scan_work;
 };
 
 /*
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 650ec54e3255..91db1924ca79 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -669,6 +669,7 @@ int qla24xx_post_gfpnid_work(struct scsi_qla_host *, 
fc_port_t *);
 int qla24xx_async_gfpnid(scsi_qla_host_t *, fc_port_t *);
 void qla24xx_handle_gfpnid_event(scsi_qla_host_t *vha, struct event_arg *ea);
 void qla24xx_sp_unmap(scsi_qla_host_t *, srb_t *);
+void qla_scan_work_fn(struct work_struct *);
 
 /*
  * Global Function Prototypes in qla_attr.c source file.
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 0fcbdcaba127..903f924f6273 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -3025,8 +3025,10 @@ void qla24xx_handle_gidpn_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
fc_port_t *fcport = ea->fcport;
 
ql_dbg(ql_dbg_disc, vha, 0x201d,
-   "%s %8phC login state %d\n",
-   __func__, fcport->port_name, fcport->fw_login_state);
+   "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d lid %d\n",
+   __func__, fcport->port_name, fcport->disc_state,
+   fcport->fw_login_state, ea->rc, fcport->login_gen, ea->sp->gen2,
+   fcport->rscn_gen, ea->sp->gen1, fcport->loop_id);
 
if (fcport->disc_state == DSC_DELETE_PEND)
return;
@@ -3034,9 +3036,9 @@ void qla24xx_handle_gidpn_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
if (ea->sp->gen2 != fcport->login_gen) {
/* PLOGI/PRLI/LOGO came in while cmd was out.*/
ql_dbg(ql_dbg_disc, vha, 0x201e,
-   "%s %8phC generation changed rscn %d|%d login %d|%d \n",
+   "%s %8phC generation changed rscn %d|%d n",
__func__, fcport->port_name, fcport->last_rscn_gen,
-   fcport->rscn_gen, fcport->last_login_gen, 
fcport->login_gen);
+   fcport->rscn_gen);
return;
}
 
@@ -3264,11 +3266,10 @@ void qla24xx_handle_gpsc_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
struct fc_port *fcport = ea->fcport;
 
ql_dbg(ql_dbg_disc, vha, 0x20d8,
-   "%s %8phC DS %d LS %d rscn %d|%d login %d|%d lid %d\n",
+   "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d lid %d\n",
__func__, fcport->port_name, fcport->disc_state,
-   fcport->fw_login_state, fcport->last_rscn_gen, fcport->rscn_gen,
-   fcport->last_login_gen, fcport->login_gen,
-   fcport->loop_id);
+   fcport->fw_login_state, ea->rc, ea->sp->gen2, fcport->login_gen,
+   ea->sp->gen2, fcport->rscn_gen|ea->sp->gen1, fcport->loop_id);
 
if (fcport->disc_state == DSC_DELETE_PEND)
return;
@@ -3276,10 +3277,8 @@ void qla24xx_handle_gpsc_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
if (ea->sp->gen2 != fcport->login_gen) {
/* target side must have changed it. */
ql_dbg(ql_dbg_disc, vha, 0x20d3,
-   "%s %8phC generation changed rscn %d|%d login %d|%d\n",
-   __func__, fcport->port_name, fcport->last_rscn_gen,
-   fcport->rscn_gen, fcport->last_login_gen,
-   fcport->login_gen);
+   "%s %8phC generation changed\n",
+   __func__, fcport->port_name);
return;
} else if (ea->sp->gen1 != fcport->rscn_gen) {
ql_dbg(ql_dbg_disc, vha, 0x20d4, "%s %d %8phC post gidpn\n",
@@ -3911,6 +3910,7 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t 
*sp)
bool found;
u8 fc4type = sp->gen2;
struct fab_scan_rp *rp;
+   unsigned long flags;
 
ql_dbg(ql_dbg_disc, vha, 0x,
"%s enter\n", __func__);

[PATCH 20/43] qla2xxx: Use known NPort ID for Management Server login

2017-12-19 Thread Himanshu Madhani
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_def.h | 4 ++--
 drivers/scsi/qla2xxx/qla_mid.c | 2 +-
 drivers/scsi/qla2xxx/qla_os.c  | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 9fcc0a5ff8df..749f3e457346 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -246,8 +246,8 @@
  * There is no correspondence between an N-PORT id and an AL_PA.  Therefore the
  * valid range of an N-PORT id is 0 through 0x7ef.
  */
-#define NPH_LAST_HANDLE0x7ef
-#define NPH_MGMT_SERVER0x7fa   /*  FA */
+#define NPH_LAST_HANDLE0x7ee
+#define NPH_MGMT_SERVER0x7ef   /*  EF */
 #define NPH_SNS0x7fc   /*  FC */
 #define NPH_FABRIC_CONTROLLER  0x7fd   /*  FD */
 #define NPH_F_PORT 0x7fe   /*  FE */
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index b2fda398a098..a823fa6b7060 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -477,7 +477,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
"Couldn't allocate vp_id.\n");
goto create_vhost_failed;
}
-   vha->mgmt_svr_loop_id = 10 + vha->vp_idx;
+   vha->mgmt_svr_loop_id = NPH_MGMT_SERVER;
 
vha->dpc_flags = 0L;
 
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 4ba249b9921d..4e7763848d81 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -3036,7 +3036,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct 
pci_device_id *id)
host = base_vha->host;
base_vha->req = req;
if (IS_QLA2XXX_MIDTYPE(ha))
-   base_vha->mgmt_svr_loop_id = 10 + base_vha->vp_idx;
+   base_vha->mgmt_svr_loop_id = NPH_MGMT_SERVER;
else
base_vha->mgmt_svr_loop_id = MANAGEMENT_SERVER +
base_vha->vp_idx;
-- 
2.12.0



[PATCH 19/43] qla2xxx: Fix session cleanup for N2N

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

When connection type is N_Port to N_Port (point-to-point), there
is a possibilty where initiator will not send PLOGI request and
will directly send PRLI. In N2N connection the port has higher
port name sends the PLOGI but not allow to send PRLI if is a
target mode. Only initiator is allowed to send PRLI.

Current driver code deletes old session when it receives PLOGI
request. If we will not receive PLOGI request then we will not
delete old session and create new session. Add check for N2N
with PRLI receive only and trigger cleanup. For this case, the
cleanup requires individual cmd abort instead of using implicit
logout as a broad stroke flush.

Signed-off-by: Krishna Kant 
Signed-off-by: Alexei Potashnik 
Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_def.h|  11 ++
 drivers/scsi/qla2xxx/qla_fw.h |   2 +-
 drivers/scsi/qla2xxx/qla_init.c   | 151 +---
 drivers/scsi/qla2xxx/qla_isr.c|   4 +-
 drivers/scsi/qla2xxx/qla_mbx.c|  38 -
 drivers/scsi/qla2xxx/qla_os.c |  41 +-
 drivers/scsi/qla2xxx/qla_target.c | 286 +-
 7 files changed, 378 insertions(+), 155 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index ba659aa9ae83..9fcc0a5ff8df 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3575,6 +3575,7 @@ struct qla_hw_data {
uint32_tfw_init_done:1;
uint32_tdetected_lr_sfp:1;
uint32_tusing_lr_setting:1;
+   uint32_trida_fmt2:1;
} flags;
 
uint16_t max_exchg;
@@ -4615,6 +4616,16 @@ struct sff_8247_a0 {
 #define USER_CTRL_IRQ(_ha) (ql2xuctrlirq && QLA_TGT_MODE_ENABLED() && \
(IS_QLA27XX(_ha) || IS_QLA83XX(_ha)))
 
+#define SAVE_TOPO(_ha) { \
+   if (_ha->current_topology)  \
+   _ha->prev_topology = _ha->current_topology; \
+}
+
+#define N2N_TOPO(ha) \
+   ((ha->prev_topology == ISP_CFG_N && !ha->current_topology) || \
+ha->current_topology == ISP_CFG_N || \
+!ha->current_topology)
+
 #include "qla_target.h"
 #include "qla_gbl.h"
 #include "qla_dbg.h"
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index d5cef0727e72..5d8688e5bc7c 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -1392,7 +1392,7 @@ struct vp_rpt_id_entry_24xx {
 
uint8_t port_name[8];
uint8_t node_name[8];
-   uint32_t remote_nport_id;
+   uint8_t remote_nport_id[4];
uint32_t reserved_5;
} f2;
} u;
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 7a8c6ead6d0e..b4a96c80853f 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -181,11 +181,6 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t 
*fcport,
if (!vha->flags.online)
goto done;
 
-   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))
-   goto done;
-
sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
if (!sp)
goto done;
@@ -1016,6 +1011,43 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
spin_unlock_irqrestore(>hw->tgt.sess_lock, flags);
 } /* gpdb event */
 
+
+static void qla_chk_n2n_b4_login(struct scsi_qla_host *vha, fc_port_t *fcport)
+{
+   u8 login = 0;
+
+   if (qla_tgt_mode_enabled(vha))
+   return;
+
+   if (qla_dual_mode_enabled(vha)) {
+   if (N2N_TOPO(vha->hw)) {
+   u64 mywwn, wwn;
+
+   mywwn = wwn_to_u64(vha->port_name);
+   wwn = wwn_to_u64(fcport->port_name);
+   if (mywwn > wwn)
+   login = 1;
+   else if ((fcport->fw_login_state == DSC_LS_PLOGI_COMP)
+   && time_after_eq(jiffies,
+   fcport->plogi_nack_done_deadline))
+   login = 1;
+   } else {
+   login = 1;
+   }
+   } else {
+   /* initiator mode */
+   login = 1;
+   }
+
+   if (login) {
+   ql_dbg(ql_dbg_disc, vha, 0x20bf,
+   "%s %d %8phC post login\n",
+   __func__, __LINE__, fcport->port_name);
+   fcport->disc_state = DSC_LOGIN_PEND;
+   qla2x00_post_async_login_work(vha, fcport, NULL);
+   }
+}
+
 int 

[PATCH 13/43] qla2xxx: Use shadow register for ISP27XX

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

For ISP27XX, use shadow register to read FW provided REQQ's consumer
index. The shadow register is dma'ed by firmware.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_iocb.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 417c40f21244..519a0d2920b8 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -2192,7 +2192,9 @@ __qla2x00_alloc_iocbs(struct qla_qpair *qpair, srb_t *sp)
 skip_cmd_array:
/* Check for room on request queue. */
if (req->cnt < req_cnt + 2) {
-   if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha))
+   if (qpair->use_shadow_reg)
+   cnt = *req->out_ptr;
+   else if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha))
cnt = RD_REG_DWORD(>isp25mq.req_q_out);
else if (IS_P3P_TYPE(ha))
cnt = RD_REG_DWORD(>isp82.req_q_out);
-- 
2.12.0



[PATCH 17/43] qla2xxx: Allow target mode to accept PRLI in dual mode

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

For Dual Mode, Initiator side of the driver finish login,
target side receive PRLI, but driver terminates PRLI.
This patch allows target side to go ahead and accept PRLI.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_init.c   |  5 +
 drivers/scsi/qla2xxx/qla_target.c | 16 +---
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 28248adb611d..7a8c6ead6d0e 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1540,6 +1540,7 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host 
*vha, struct event_arg *ea)
port_id_t cid;  /* conflict Nport id */
u16 lid;
struct fc_port *conflict_fcport;
+   unsigned long flags;
 
switch (ea->data[0]) {
case MBS_COMMAND_COMPLETE:
@@ -1560,10 +1561,14 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host 
*vha, struct event_arg *ea)
ea->fcport->loop_id, ea->fcport->d_id.b24);
 
set_bit(ea->fcport->loop_id, vha->hw->loop_id_map);
+   spin_lock_irqsave(>hw->tgt.sess_lock, flags);
ea->fcport->loop_id = FC_NO_LOOP_ID;
ea->fcport->chip_reset = 
vha->hw->base_qpair->chip_reset;
ea->fcport->logout_on_delete = 1;
ea->fcport->send_els_logo = 0;
+   ea->fcport->fw_login_state = DSC_LS_PRLI_COMP;
+   spin_unlock_irqrestore(>hw->tgt.sess_lock, flags);
+
qla24xx_post_gpdb_work(vha, ea->fcport, 0);
}
break;
diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 835721f077f6..eaa43d3d5a91 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -4703,7 +4703,7 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
uint16_t wd3_lo;
int res = 0;
struct qlt_plogi_ack_t *pla;
-   unsigned long flags;
+   unsigned long flags = 0;
 
wwn = wwn_to_u64(iocb->u.isp24.port_name);
 
@@ -4839,8 +4839,14 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
}
 
if (sess != NULL) {
-   if (sess->fw_login_state != DSC_LS_PLOGI_PEND &&
-   sess->fw_login_state != DSC_LS_PLOGI_COMP) {
+   spin_lock_irqsave(>ha->tgt.sess_lock, flags);
+   switch (sess->fw_login_state) {
+   case DSC_LS_PLOGI_COMP:
+   case DSC_LS_PRLI_COMP:
+   break;
+   default:
+   spin_unlock_irqrestore(>ha->tgt.sess_lock,
+   flags);
/*
 * Impatient initiator sent PRLI before last
 * PLOGI could finish. Will force him to re-try,
@@ -4851,6 +4857,8 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
sess);
qlt_send_term_imm_notif(vha, iocb, 1);
res = 0;
+   spin_lock_irqsave(>ha->tgt.sess_lock,
+   flags);
break;
}
 
@@ -4874,6 +4882,8 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
sess->port_type = FCT_INITIATOR;
else
sess->port_type = FCT_TARGET;
+
+   spin_unlock_irqrestore(>ha->tgt.sess_lock, flags);
}
res = 1; /* send notify ack */
 
-- 
2.12.0



[PATCH 08/43] qla2xxx: Chip reset uses wrong lock during IO flush.

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

As part of chip reset, all commands from all QPairs are
flushed. This patch fixes code to use Q Pair lock for flush
instead of using old hardware_lock.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_os.c | 139 +++---
 1 file changed, 64 insertions(+), 75 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 7f361e93c593..4a542a5a976d 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1709,94 +1709,83 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
return QLA_SUCCESS;
 }
 
-void
-qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
+static void
+__qla2x00_abort_all_cmds(struct qla_qpair *qp, int res)
 {
-   int que, cnt, status;
+   int cnt;
unsigned long flags;
srb_t *sp;
+   scsi_qla_host_t *vha = qp->vha;
struct qla_hw_data *ha = vha->hw;
struct req_que *req;
struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
struct qla_tgt_cmd *cmd;
uint8_t trace = 0;
 
-   spin_lock_irqsave(>hardware_lock, flags);
-   for (que = 0; que < ha->max_req_queues; que++) {
-   req = ha->req_q_map[que];
-   if (!req)
-   continue;
-   if (!req->outstanding_cmds)
-   continue;
-   for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
-   sp = req->outstanding_cmds[cnt];
-   if (sp) {
-   req->outstanding_cmds[cnt] = NULL;
-   if (sp->cmd_type == TYPE_SRB) {
-   if (sp->type == SRB_NVME_CMD ||
-   sp->type == SRB_NVME_LS) {
-   sp_get(sp);
-   spin_unlock_irqrestore(
-   >hardware_lock, flags);
-   qla_nvme_abort(ha, sp);
-   spin_lock_irqsave(
-   >hardware_lock, flags);
-   } else if (GET_CMD_SP(sp) &&
-   !ha->flags.eeh_busy &&
-   (!test_bit(ABORT_ISP_ACTIVE,
-   >dpc_flags)) &&
-   (sp->type == SRB_SCSI_CMD)) {
-   /*
-* Don't abort commands in
-* adapter during EEH
-* recovery as it's not
-* accessible/responding.
-*
-* Get a reference to the sp
-* and drop the lock. The
-* reference ensures this
-* sp->done() call and not the
-* call in qla2xxx_eh_abort()
-* ends the SCSI command (with
-* result 'res').
-*/
-   sp_get(sp);
-   spin_unlock_irqrestore(
-   >hardware_lock, flags);
-   status = qla2xxx_eh_abort(
-   GET_CMD_SP(sp));
-   spin_lock_irqsave(
-   >hardware_lock, flags);
-   /*
-* Get rid of extra reference
-* if immediate exit from
-* ql2xxx_eh_abort
-*/
-   if (status == FAILED &&
-   (qla2x00_isp_reg_stat(ha)))
-   atomic_dec(
-   >ref_count);
-   }
-   qla_put_iocbs(sp->qpair, >iores);
-   sp->done(sp, res);
-   } else {
-

[PATCH 14/43] qla2xxx: Add option for use reserve exch for ELS

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

Add option to tell FW to reserve 1/2 of emergency exchanges for ELS.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_gbl.h  | 1 +
 drivers/scsi/qla2xxx/qla_init.c | 6 ++
 drivers/scsi/qla2xxx/qla_os.c   | 6 ++
 3 files changed, 13 insertions(+)

diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index fb1c9ffdc05a..88c7746c023a 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -149,6 +149,7 @@ extern int ql2xnvmeenable;
 extern int ql2xautodetectsfp;
 extern int ql2xenablemsix;
 extern int ql2xtrackfwres;
+extern int qla2xuseresexchforels;
 
 extern int qla2x00_loop_reset(scsi_qla_host_t *);
 extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 61b74fd220a3..6223dfe20767 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -3387,6 +3387,12 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
ha->fw_options[2] |= BIT_4;
else
ha->fw_options[2] &= ~BIT_4;
+
+   /* Reserve 1/2 of emergency exchanges for ELS.*/
+   if (qla2xuseresexchforels)
+   ha->fw_options[2] |= BIT_8;
+   else
+   ha->fw_options[2] &= ~BIT_8;
}
 
ql_dbg(ql_dbg_init, vha, 0x00e8,
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 66e6fe73a035..fd107c4feda5 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -282,6 +282,12 @@ module_param(ql2xtrackfwres, int, 0444);
 MODULE_PARM_DESC(ql2xtrackfwres,
 "Track FW resource.  0(default): disabled");
 
+int qla2xuseresexchforels;
+module_param(qla2xuseresexchforels, int, 0444);
+MODULE_PARM_DESC(qla2xuseresexchforels,
+"Reserve 1/2 of emergency exchanges for ELS.\n"
+" 0 (default): disabled");
+
 /*
  * SCSI host template entry points
  */
-- 
2.12.0



[PATCH 16/43] qla2xxx: Don't call dma_free_coherent with IRQ disabled.

2017-12-19 Thread Himanshu Madhani
From: Giridhar Malavali 

The logo ELS command allocates dma coherent memory for the
data payload and serialize the completions. When this command
times out, the timeout routine completes the thread waiting
for completion which in turn cleanup resources allocated for
this ELS command processing. Don't call generic sp->free
routine when this ELS command times out to avoid to double
freeing of the same resources.

Signed-off-by: Giridhar Malavali 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_init.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 900f6d3f3a3a..28248adb611d 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -59,7 +59,8 @@ qla2x00_sp_timeout(struct timer_list *t)
req->outstanding_cmds[sp->handle] = NULL;
iocb = >u.iocb_cmd;
iocb->timeout(sp);
-   sp->free(sp);
+   if (sp->type != SRB_ELS_DCMD)
+   sp->free(sp);
spin_unlock_irqrestore(>hw->hardware_lock, flags);
 }
 
-- 
2.12.0



[PATCH 10/43] qla2xxx: Replace GPDB with async ADISC command

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

Replace call to Get Port DataBase MB with PDO_FORCE_ADISC
flag with async ADISC command so driver can see ADISC command
has error or not.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_def.h  |  2 ++
 drivers/scsi/qla2xxx/qla_gs.c   | 20 +++-
 drivers/scsi/qla2xxx/qla_init.c | 68 +++--
 3 files changed, 53 insertions(+), 37 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 8fbe1736a1a4..18b393453002 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2320,6 +2320,7 @@ enum discovery_state {
DSC_GPSC,
DSC_UPD_FCPORT,
DSC_LOGIN_COMPLETE,
+   DSC_ADISC,
DSC_DELETE_PEND,
 };
 
@@ -2346,6 +2347,7 @@ enum fcport_mgt_event {
FCME_GPNID_DONE,
FCME_GFFID_DONE,
FCME_DELETE_DONE,
+   FCME_ADISC_DONE,
 };
 
 enum rscn_addr_format {
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 6aa6dd74fe86..b1c6485c307b 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -2867,15 +2867,19 @@ void qla24xx_handle_gidpn_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
"%s %d %8phC post %s\n", __func__,
__LINE__, fcport->port_name,
(atomic_read(>state) ==
-   FCS_ONLINE) ? "gpdb" : "gnl");
+   FCS_ONLINE) ? "adisc" : "gnl");
 
if (atomic_read(>state) ==
-   FCS_ONLINE)
-   qla24xx_post_gpdb_work(vha,
-   fcport, PDO_FORCE_ADISC);
-   else
+   FCS_ONLINE) {
+   u16 data[2];
+
+   data[0] = data[1] = 0;
+   qla2x00_post_async_adisc_work(
+   vha, fcport, data);
+   } else {
qla24xx_post_gnl_work(vha,
fcport);
+   }
break;
}
} else { /* fcport->d_id.b24 != ea->id.b24 */
@@ -3216,6 +3220,7 @@ void qla24xx_async_gpnid_done(scsi_qla_host_t *vha, srb_t 
*sp)
 void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
 {
fc_port_t *fcport, *conflict, *t;
+   u16 data[2];
 
ql_dbg(ql_dbg_disc, vha, 0x,
"%s %d port_id: %06x\n",
@@ -3290,8 +3295,9 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
ql_dbg(ql_dbg_disc, vha, 0x210d,
"%s %d %8phC revalidate session with 
ADISC\n",
__func__, __LINE__, fcport->port_name);
-   qla24xx_post_gpdb_work(vha, fcport,
-   PDO_FORCE_ADISC);
+   data[0] = data[1] = 0;
+   qla2x00_post_async_adisc_work(vha, fcport,
+   data);
break;
case DSC_DELETED:
ql_dbg(ql_dbg_disc, vha, 0x210d,
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 5cd04bfa5cae..0a1c287c2d66 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -41,6 +41,7 @@ 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 *);
+static void qla24xx_handle_gpdb_event(scsi_qla_host_t *, struct event_arg *);
 
 /* SRB Extensions -- */
 
@@ -277,17 +278,31 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t 
*fcport)
fcport->flags &= ~FCF_ASYNC_SENT;
return rval;
 }
+static
+void qla24xx_handle_adisc_event(scsi_qla_host_t *vha, struct event_arg *ea)
+{
+   qla24xx_handle_gpdb_event(vha, ea);
+}
 
 static void
 qla2x00_async_adisc_sp_done(void *ptr, int res)
 {
srb_t *sp = ptr;
struct scsi_qla_host *vha = sp->vha;
-   struct srb_iocb *lio = >u.iocb_cmd;
+   struct event_arg ea;
+
+   ql_dbg(ql_dbg_disc, vha, 0x2066,
+   "Async done-%s res %x %8phC\n",
+  

[PATCH 21/43] qla2xxx: Remove calling cancel_work_sync()

2017-12-19 Thread Himanshu Madhani
From: Sawan Chandak 

This is blocking call and issue is seen, when called in interrupt context.

__cancel_work_timer+0x140/0x210
? ql_dbg+0xcb/0x110 [qla2xxx]
cancel_work_sync+0x10/0x20
qlt_schedule_sess_for_deletion+0x89/0x170 [qla2xxx]
qla24xx_handle_gpnid_event+0x146/0x4a0 [qla2xxx]
qla2x00_fcport_event_handler+0x14b/0x290 [qla2xxx]
qla2x00_async_gpnid_sp_done+0x118/0x240 [qla2xxx]
qla24xx_els_ct_entry.isra.15+0x1df/0x2b0 [qla2xxx]
? qla24xx_msix_rsp_q+0x39/0xf0 [qla2xxx]
qla24xx_process_response_queue+0xae/0x270 [qla2xxx]
qla24xx_msix_rsp_q+0x8a/0xf0 [qla2xxx]
__handle_irq_event_percpu+0x3c/0x350
handle_irq_event_percpu+0x32/0x80
handle_irq_event+0x39/0x60
handle_edge_irq+0x8c/0x140
handle_irq+0xab/0x130
? _local_bh_enable+0x21/0x50
do_IRQ+0x5e/0x120
common_interrupt+0x9d/0x9d
RIP: 0010:cpuidle_enter_state+0xe9/0x320

Signed-off-by: Sawan Chandak 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_target.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 71be1a95ba86..002fe05dd344 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1234,8 +1234,6 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess,
ql_dbg(ql_dbg_tgt, sess->vha, 0xe001,
"Scheduling sess %p for deletion\n", sess);
 
-   /* use cancel to push work element through before re-queue */
-   cancel_work_sync(>del_work);
INIT_WORK(>del_work, qla24xx_delete_sess_fn);
queue_work(sess->vha->hw->wq, >del_work);
 }
-- 
2.12.0



[PATCH 04/43] qla2xxx: Use chip reset to bring down laser on unload.

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

Current code uses Stop Firmware MB cmd to stop the chip before
driver unload.  This will leave the laser in its current state.
This give the illusion of this adapter is still alive.
For 8G & newer adapters, use chip reset to stop the chip and
bring down the laser.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_os.c | 52 ++-
 1 file changed, 17 insertions(+), 35 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 789030c9dd26..987bade1c606 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -294,7 +294,6 @@ static int qla2xxx_eh_host_reset(struct scsi_cmnd *);
 
 static void qla2x00_clear_drv_active(struct qla_hw_data *);
 static void qla2x00_free_device(scsi_qla_host_t *);
-static void qla83xx_disable_laser(scsi_qla_host_t *vha);
 static int qla2xxx_map_queues(struct Scsi_Host *shost);
 static void qla2x00_destroy_deferred_work(struct qla_hw_data *);
 
@@ -3449,8 +3448,13 @@ qla2x00_shutdown(struct pci_dev *pdev)
if (ha->eft)
qla2x00_disable_eft_trace(vha);
 
-   /* Stop currently executing firmware. */
-   qla2x00_try_to_stop_firmware(vha);
+   if (IS_QLA25XX(ha) ||  IS_QLA2031(ha) || IS_QLA27XX(ha)) {
+   if (ha->flags.fw_started)
+   qla2x00_abort_isp_cleanup(vha);
+   } else {
+   /* Stop currently executing firmware. */
+   qla2x00_try_to_stop_firmware(vha);
+   }
 
/* Turn adapter off line */
vha->flags.online = 0;
@@ -3629,10 +3633,6 @@ qla2x00_remove_one(struct pci_dev *pdev)
 
qla84xx_put_chip(base_vha);
 
-   /* Laser should be disabled only for ISP2031 */
-   if (IS_QLA2031(ha))
-   qla83xx_disable_laser(base_vha);
-
/* Disable timer */
if (base_vha->timer_active)
qla2x00_stop_timer(base_vha);
@@ -3693,8 +3693,16 @@ qla2x00_free_device(scsi_qla_host_t *vha)
if (ha->eft)
qla2x00_disable_eft_trace(vha);
 
-   /* Stop currently executing firmware. */
-   qla2x00_try_to_stop_firmware(vha);
+   if (IS_QLA25XX(ha) ||  IS_QLA2031(ha) || IS_QLA27XX(ha)) {
+   if (ha->flags.fw_started)
+   qla2x00_abort_isp_cleanup(vha);
+   } else {
+   if (ha->flags.fw_started) {
+   /* Stop currently executing firmware. */
+   qla2x00_try_to_stop_firmware(vha);
+   ha->flags.fw_started = 0;
+   }
+   }
 
vha->flags.online = 0;
 
@@ -6617,32 +6625,6 @@ qla2xxx_pci_resume(struct pci_dev *pdev)
ha->flags.eeh_busy = 0;
 }
 
-static void
-qla83xx_disable_laser(scsi_qla_host_t *vha)
-{
-   uint32_t reg, data, fn;
-   struct qla_hw_data *ha = vha->hw;
-   struct device_reg_24xx __iomem *isp_reg = >iobase->isp24;
-
-   /* pci func #/port # */
-   ql_dbg(ql_dbg_init, vha, 0x004b,
-   "Disabling Laser for hba: %p\n", vha);
-
-   fn = (RD_REG_DWORD(_reg->ctrl_status) &
-   (BIT_15|BIT_14|BIT_13|BIT_12));
-
-   fn = (fn >> 12);
-
-   if (fn & 1)
-   reg = PORT_1_2031;
-   else
-   reg = PORT_0_2031;
-
-   data = LASER_OFF_2031;
-
-   qla83xx_wr_reg(vha, reg, data);
-}
-
 static int qla2xxx_map_queues(struct Scsi_Host *shost)
 {
int rc;
-- 
2.12.0



[PATCH 18/43] qla2xxx: Tweak resource count dump

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

Fetch actual data from firmware instead of static data
at chip reset time.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_dfs.c | 30 --
 drivers/scsi/qla2xxx/qla_gbl.h |  1 +
 drivers/scsi/qla2xxx/qla_mbx.c | 30 ++
 3 files changed, 47 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c
index 87a18a00d509..4f0415e158cb 100644
--- a/drivers/scsi/qla2xxx/qla_dfs.c
+++ b/drivers/scsi/qla2xxx/qla_dfs.c
@@ -127,21 +127,23 @@ static int
 qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused)
 {
struct scsi_qla_host *vha = s->private;
-   struct qla_hw_data *ha = vha->hw;
+   uint16_t mb[MAX_IOCB_MB_REG];
+   int rc;
 
-   seq_puts(s, "FW Resource count\n\n");
-   seq_printf(s, "Original TGT exchg count[%d]\n",
-   ha->orig_fw_tgt_xcb_count);
-   seq_printf(s, "current TGT exchg count[%d]\n",
-   ha->cur_fw_tgt_xcb_count);
-   seq_printf(s, "original Initiator Exchange count[%d]\n",
-   ha->orig_fw_xcb_count);
-   seq_printf(s, "Current Initiator Exchange count[%d]\n",
-   ha->cur_fw_xcb_count);
-   seq_printf(s, "Original IOCB count[%d]\n", ha->orig_fw_iocb_count);
-   seq_printf(s, "Current IOCB count[%d]\n", ha->cur_fw_iocb_count);
-   seq_printf(s, "MAX VP count[%d]\n", ha->max_npiv_vports);
-   seq_printf(s, "MAX FCF count[%d]\n", ha->fw_max_fcf_count);
+   rc = qla24xx_res_count_wait(vha, mb, SIZEOF_IOCB_MB_REG);
+   if (rc != QLA_SUCCESS) {
+   seq_printf(s, "Mailbox Command failed %d, mb %#x", rc, mb[0]);
+   } else {
+   seq_puts(s, "FW Resource count\n\n");
+   seq_printf(s, "Original TGT exchg count[%d]\n", mb[1]);
+   seq_printf(s, "current TGT exchg count[%d]\n", mb[2]);
+   seq_printf(s, "original Initiator Exchange count[%d]\n", mb[3]);
+   seq_printf(s, "Current Initiator Exchange count[%d]\n", mb[6]);
+   seq_printf(s, "Original IOCB count[%d]\n", mb[7]);
+   seq_printf(s, "Current IOCB count[%d]\n", mb[10]);
+   seq_printf(s, "MAX VP count[%d]\n", mb[11]);
+   seq_printf(s, "MAX FCF count[%d]\n", mb[12]);
+   }
 
return 0;
 }
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index ea8f24e07409..2e0907994579 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -504,6 +504,7 @@ int qla24xx_get_port_login_templ(scsi_qla_host_t *, 
dma_addr_t,
 
 extern int qla27xx_get_zio_threshold(scsi_qla_host_t *, uint16_t *);
 extern int qla27xx_set_zio_threshold(scsi_qla_host_t *, uint16_t);
+int qla24xx_res_count_wait(struct scsi_qla_host *, uint16_t *, int);
 
 /*
  * Global Function Prototypes in qla_isr.c source file.
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 956d121cc396..0c8ad7b31294 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -18,6 +18,7 @@ static struct mb_cmd_name {
{MBC_GET_PORT_DATABASE, "GPDB"},
{MBC_GET_ID_LIST,   "GIDList"},
{MBC_GET_LINK_PRIV_STATS,   "Stats"},
+   {MBC_GET_RESOURCE_COUNTS,   "ResCnt"},
 };
 
 static const char *mb_to_str(uint16_t cmd)
@@ -6273,3 +6274,32 @@ qla2x00_read_sfp_dev(struct scsi_qla_host *vha, char 
*buf, int count)
 
return rval;
 }
+
+int qla24xx_res_count_wait(struct scsi_qla_host *vha,
+uint16_t *out_mb, int out_mb_sz)
+{
+   int rval = QLA_FUNCTION_FAILED;
+   mbx_cmd_t mc;
+
+   if (!vha->hw->flags.fw_started)
+   goto done;
+
+   memset(, 0, sizeof(mc));
+   mc.mb[0] = MBC_GET_RESOURCE_COUNTS;
+
+   rval = qla24xx_send_mb_cmd(vha, );
+   if (rval != QLA_SUCCESS) {
+   ql_dbg(ql_dbg_mbx, vha, 0x,
+   "%s:  fail\n", __func__);
+   } else {
+   if (out_mb_sz <= SIZEOF_IOCB_MB_REG)
+   memcpy(out_mb, mc.mb, out_mb_sz);
+   else
+   memcpy(out_mb, mc.mb, SIZEOF_IOCB_MB_REG);
+
+   ql_dbg(ql_dbg_mbx, vha, 0x,
+   "%s:  done\n", __func__);
+   }
+done:
+   return rval;
+}
-- 
2.12.0



[PATCH 29/43] qla2xxx: Fix GPNFT/GNNFT error handling

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

retry gpnft/gnnft if error is encountered.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_gs.c   | 15 +++
 drivers/scsi/qla2xxx/qla_init.c |  8 
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 0e84381e227e..0fcbdcaba127 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -3927,6 +3927,7 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t 
*sp)
ql_dbg(ql_dbg_disc, vha, 0x,
"GPNFT failed. FC4type %x. Rescanning.\n",
fc4type);
+   set_bit(LOCAL_LOOP_UPDATE, >dpc_flags);
set_bit(LOOP_RESYNC_NEEDED, >dpc_flags);
goto out;
}
@@ -4036,6 +4037,19 @@ static void qla2x00_async_gpnft_gnnft_sp_done(void *s, 
int res)
"Async done-%s res %x FC4Type %x\n",
sp->name, res, sp->gen2);
 
+   if (res) {
+   unsigned long flags;
+
+   ql_dbg(ql_dbg_disc, sp->vha, 0x,
+   "Async done-%s timed out.\n",
+   sp->name);
+   sp->free(sp);
+   set_bit(LOCAL_LOOP_UPDATE, >dpc_flags);
+   set_bit(LOOP_RESYNC_NEEDED, >dpc_flags);
+   qla2xxx_wake_dpc(vha);
+   return;
+   }
+
if (!res) {
port_id_t id;
u64 wwn;
@@ -4097,6 +4111,7 @@ static void qla2x00_async_gpnft_gnnft_sp_done(void *s, 
int res)
"Async done-%s unable to alloc work element\n",
sp->name);
sp->free(sp);
+   set_bit(LOCAL_LOOP_UPDATE, >dpc_flags);
set_bit(LOOP_RESYNC_NEEDED, >dpc_flags);
return;
}
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 152c808b272b..e58faa1e984c 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -683,15 +683,15 @@ qla24xx_async_gnl_sp_done(void *s, int res)
}
}
 
-   id.b.domain = e->port_id[0];
+   id.b.domain = e->port_id[2];
id.b.area = e->port_id[1];
-   id.b.al_pa = e->port_id[2];
+   id.b.al_pa = e->port_id[0];
id.b.rsvd_1 = 0;
 
if (!found && wwn && !IS_SW_RESV_ADDR(id)) {
ql_dbg(ql_dbg_disc, vha, 0x2065,
-   "%s %d %8phC post new sess\n",
-   __func__, __LINE__, (u8 *));
+   "%s %d %8phC %06x post new sess\n",
+   __func__, __LINE__, (u8 *), id.b24);
wwnn = wwn_to_u64(e->node_name);
qla24xx_post_newsess_work(vha, , (u8 *),
(u8 *), NULL, FC4_TYPE_UNKNOWN);
-- 
2.12.0



[PATCH 12/43] qla2xxx: Enable ATIO interrupt handshake for ISP27XX

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

Enable ATIO Q interrupt handshake for ISP27XX. This patch
coalesce ATIO's interrupts for Quad port ISP27XX adapter.
Interrupt coalesce allows performance to scale for this
specific case.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_target.c | 39 +--
 1 file changed, 25 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 0d77b2f67077..835721f077f6 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -6598,7 +6598,9 @@ void
 qlt_24xx_config_rings(struct scsi_qla_host *vha)
 {
struct qla_hw_data *ha = vha->hw;
-   struct init_cb_24xx *icb;
+   struct qla_msix_entry *msix = >msix_entries[2];
+   struct init_cb_24xx *icb = (struct init_cb_24xx *)ha->init_cb;
+
if (!QLA_TGT_MODE_ENABLED())
return;
 
@@ -6606,19 +6608,28 @@ qlt_24xx_config_rings(struct scsi_qla_host *vha)
WRT_REG_DWORD(ISP_ATIO_Q_OUT(vha), 0);
RD_REG_DWORD(ISP_ATIO_Q_OUT(vha));
 
-   icb = (struct init_cb_24xx *)ha->init_cb;
-
-   if ((ql2xenablemsix != 0) && IS_ATIO_MSIX_CAPABLE(ha)) {
-   struct qla_msix_entry *msix = >msix_entries[2];
-
-   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);
-   } else if (ql2xenablemsix == 0) {
-   icb->firmware_options_2 |= cpu_to_le32(BIT_26);
-   ql_dbg(ql_dbg_init, vha, 0xf07f,
-   "Registering INTx vector for ATIO.\n");
+   if (ha->flags.msix_enabled) {
+   if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
+   if (IS_QLA2071(ha)) {
+   /* 4 ports Baker: Enable Interrupt Handshake */
+   icb->msix_atio = 0;
+   icb->firmware_options_2 |= BIT_26;
+   } else {
+   icb->msix_atio = cpu_to_le16(msix->entry);
+   icb->firmware_options_2 &= ~BIT_26;
+   }
+   ql_dbg(ql_dbg_init, vha, 0xf072,
+   "Registering ICB vector 0x%x for atio que.\n",
+   msix->entry);
+   }
+   } else {
+   /* INTx|MSI */
+   if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
+   icb->msix_atio = 0;
+   icb->firmware_options_2 |= BIT_26;
+   ql_dbg(ql_dbg_init, vha, 0xf072,
+   "%s: Use INTx for ATIOQ.\n", __func__);
+   }
}
 }
 
-- 
2.12.0



[PATCH 15/43] qla2xxx: Add ability to send PRLO

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

Add ability to send Implicit PRLO to flush IOs
from FW back to driver.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_def.h  |  5 
 drivers/scsi/qla2xxx/qla_gbl.h  |  8 ++
 drivers/scsi/qla2xxx/qla_gs.c   |  1 +
 drivers/scsi/qla2xxx/qla_init.c | 59 +
 drivers/scsi/qla2xxx/qla_iocb.c | 17 
 drivers/scsi/qla2xxx/qla_os.c   |  9 +++
 6 files changed, 99 insertions(+)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index a2c0f3d78b35..ba659aa9ae83 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -514,6 +514,7 @@ enum {
SPCN_NVME_LS,
SPCN_NVME_CMD,
SPCN_CTRL_VP,
+   SPCN_PRLO,
 };
 
 struct sp_name {
@@ -544,6 +545,8 @@ struct sp_name {
 #define SRB_NVME_LS20
 #define SRB_PRLI_CMD   21
 #define SRB_CTRL_VP22
+#define SRB_PRLO_CMD   23
+
 enum {
TYPE_SRB,
TYPE_TGT_CMD,
@@ -3184,6 +3187,8 @@ enum qla_work_type {
QLA_EVT_GNL,
QLA_EVT_NACK,
QLA_EVT_RELOGIN,
+   QLA_EVT_ASYNC_PRLO,
+   QLA_EVT_ASYNC_PRLO_DONE,
 };
 
 
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 88c7746c023a..ea8f24e07409 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -66,6 +66,7 @@ extern void qla84xx_put_chip(struct scsi_qla_host *);
 extern int qla2x00_async_login(struct scsi_qla_host *, fc_port_t *,
 uint16_t *);
 extern int qla2x00_async_logout(struct scsi_qla_host *, fc_port_t *);
+extern int qla2x00_async_prlo(struct scsi_qla_host *, fc_port_t *);
 extern int qla2x00_async_adisc(struct scsi_qla_host *, fc_port_t *,
 uint16_t *);
 extern int qla2x00_async_tm_cmd(fc_port_t *, uint32_t, uint32_t, uint32_t);
@@ -109,6 +110,13 @@ int qla24xx_post_newsess_work(struct scsi_qla_host *, 
port_id_t *, u8 *,
 int qla24xx_fcport_handle_login(struct scsi_qla_host *, fc_port_t *);
 int qla24xx_detect_sfp(scsi_qla_host_t *vha);
 int qla24xx_post_gpdb_work(struct scsi_qla_host *, fc_port_t *, u8);
+void qla2x00_async_prlo_done(struct scsi_qla_host *, fc_port_t *,
+uint16_t *);
+extern int qla2x00_post_async_prlo_work(struct scsi_qla_host *, fc_port_t *,
+uint16_t *);
+extern int qla2x00_post_async_prlo_done_work(struct scsi_qla_host *,
+fc_port_t *, uint16_t *);
+
 /*
  * Global Data in qla_os.c source file.
  */
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index b1c6485c307b..22702a8f5ce6 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -42,6 +42,7 @@ struct sp_name sp_str[] = {
{ SPCN_NVME_LS, "nvme_ls" },
{ SPCN_NVME_CMD, "nvme_cmd" },
{ SPCN_CTRL_VP, "ctrl_vp" },
+   { SPCN_PRLO, "prlo" },
 };
 
 const char *sp_to_str(uint16_t cmd)
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 6223dfe20767..900f6d3f3a3a 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -278,6 +278,65 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t 
*fcport)
fcport->flags &= ~FCF_ASYNC_SENT;
return rval;
 }
+
+void
+qla2x00_async_prlo_done(struct scsi_qla_host *vha, fc_port_t *fcport,
+uint16_t *data)
+{
+   /* Don't re-login in target mode */
+   if (!fcport->tgt_session)
+   qla2x00_mark_device_lost(vha, fcport, 1, 0);
+   qlt_logo_completion_handler(fcport, data[0]);
+}
+
+static void
+qla2x00_async_prlo_sp_done(void *s, int res)
+{
+   srb_t *sp = (srb_t *)s;
+   struct srb_iocb *lio = >u.iocb_cmd;
+   struct scsi_qla_host *vha = sp->vha;
+
+   if (!test_bit(UNLOADING, >dpc_flags))
+   qla2x00_post_async_prlo_done_work(sp->fcport->vha, sp->fcport,
+   lio->u.logio.data);
+   sp->free(sp);
+}
+
+int
+qla2x00_async_prlo(struct scsi_qla_host *vha, fc_port_t *fcport)
+{
+   srb_t *sp;
+   struct srb_iocb *lio;
+   int rval;
+
+   rval = QLA_FUNCTION_FAILED;
+   sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
+   if (!sp)
+   goto done;
+
+   sp->type = SRB_PRLO_CMD;
+   sp->name = sp_to_str(SPCN_PRLO);
+   qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
+
+   lio = >u.iocb_cmd;
+   lio->timeout = qla2x00_async_iocb_timeout;
+   sp->done = qla2x00_async_prlo_sp_done;
+   rval = qla2x00_start_sp(sp);
+   if (rval != QLA_SUCCESS)
+   goto done_free_sp;
+
+   ql_dbg(ql_dbg_disc, vha, 0x2070,
+   "Async-prlo - hdl=%x loop-id=%x portid=%02x%02x%02x.\n",
+   sp->handle, fcport->loop_id, fcport->d_id.b.domain,
+   fcport->d_id.b.area, fcport->d_id.b.al_pa);
+   return rval;
+
+done_free_sp:
+   sp->free(sp);
+done:
+   return rval;
+}
+
 static
 void 

[PATCH 07/43] qla2xxx: Add ability to track IOCB resource for FW

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

FW has a finite number of IOCB resource. Driver will
track it via the ql2xtrackfwres module parameter. User
will be able to reserve X number of IOCBs for either
the target path or initiator path. The left over IOCBs
are shared between the 2 modes. The shared pool will be
used 1st before tapping into the reserve pool.

usage:
modprobe qla2xxx ql2xtrackfwres=1 qlini_mode=dual
echo 256 > /sys/class/scsi_host/hostX/device/reserve_ini_iocbs
echo 256 > /sys/class/scsi_host/hostX/device/reserve_tgt_iocbs

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_def.h|  50 +-
 drivers/scsi/qla2xxx/qla_dfs.c| 315 ++
 drivers/scsi/qla2xxx/qla_gbl.h|   1 +
 drivers/scsi/qla2xxx/qla_init.c   |  36 +
 drivers/scsi/qla2xxx/qla_inline.h | 102 
 drivers/scsi/qla2xxx/qla_iocb.c   |  45 ++
 drivers/scsi/qla2xxx/qla_isr.c|  10 +-
 drivers/scsi/qla2xxx/qla_os.c |  10 ++
 drivers/scsi/qla2xxx/qla_target.c |  24 +++
 drivers/scsi/qla2xxx/qla_target.h |   3 +-
 10 files changed, 592 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 5e509763a419..8fbe1736a1a4 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -549,6 +549,12 @@ enum {
TYPE_TGT_CMD,
 };
 
+struct iocb_resource {
+   u8 res_type;
+   u8 pad;
+   u16 iocb_cnt;
+};
+
 typedef struct srb {
/*
 * Do not move cmd_type field, it needs to
@@ -556,6 +562,7 @@ typedef struct srb {
 */
uint8_t cmd_type;
uint8_t pad[3];
+   struct iocb_resource iores;
atomic_t ref_count;
wait_queue_head_t nvme_ls_waitq;
struct fc_port *fcport;
@@ -3396,6 +3403,7 @@ struct qla_qpair {
uint32_t fw_started:1;
uint32_t enable_class_2:1;
uint32_t enable_explicit_conf:1;
+   uint32_t fw_res_tracking:1;
uint32_t use_shadow_reg:1;
 
uint16_t id;/* qp number used with FW */
@@ -3433,6 +3441,24 @@ struct scsi_qlt_host {
struct qla_tgt *qla_tgt;
 };
 
+struct qla_fw_resources {
+   spinlock_t rescnt_lock;
+#define DEF_RES_INI_IOCBS 256
+#define DEF_RES_TGT_IOCBS 256
+#define DEF_RES_BUSY_IOCBS 32
+   u32 tgt_iocbs_reserve;
+   u32 ini_iocbs_reserve;
+   u32 busy_iocbs_reserve;
+   u32 tgt_iocbs_max;
+   u32 ini_iocbs_max;
+   u32 share_iocbs_max;
+
+   /* these fields start high */
+   atomic_t share_iocbs_used;
+   atomic_t tgt_iocbs_used;
+   atomic_t ini_iocbs_used;
+};
+
 struct qlt_hw_data {
/* Protected by hw lock */
uint32_t node_name_set:1;
@@ -3461,6 +3487,9 @@ struct qlt_hw_data {
struct dentry *dfs_tgt_sess;
struct dentry *dfs_tgt_port_database;
struct dentry *dfs_naqp;
+   struct dentry *dfs_ini_iocbs;
+   struct dentry *dfs_tgt_iocbs;
+   struct dentry *dfs_busy_iocbs;
 
struct list_head q_full_list;
uint32_t num_pend_cmds;
@@ -3540,7 +3569,6 @@ struct qla_hw_data {
uint32_tn2n_ae:1;
uint32_tfw_started:1;
uint32_tfw_init_done:1;
-
uint32_tdetected_lr_sfp:1;
uint32_tusing_lr_setting:1;
} flags;
@@ -4103,6 +4131,7 @@ struct qla_hw_data {
 
struct qlt_hw_data tgt;
int allow_cna_fw_dump;
+   struct qla_fw_resources fwres;
uint32_t fw_ability_mask;
uint16_t min_link_speed;
uint16_t max_speed_sup;
@@ -4406,7 +4435,6 @@ struct qla2_sgx {
 #define QLA_QPAIR_MARK_NOT_BUSY(__qpair)   \
atomic_dec(&__qpair->ref_count);\
 
-
 #define QLA_ENA_CONF(_ha) {\
 int i;\
 _ha->base_qpair->enable_explicit_conf = 1; \
@@ -4425,6 +4453,24 @@ struct qla2_sgx {
 }  \
 }
 
+#define QLA_ENA_FW_RES_TRACKING(_ha) { \
+   int i; \
+   _ha->base_qpair->fw_res_tracking = 1; \
+   for (i = 0; i < _ha->max_qpairs; i++) { \
+   if (_ha->queue_pair_map[i]) \
+   _ha->queue_pair_map[i]->fw_res_tracking = 1; \
+   } \
+}
+
+#define QLA_DIS_FW_RES_TRACKING(_ha) { \
+   int i; \
+   _ha->base_qpair->fw_res_tracking = 0; \
+   for (i = 0; i < _ha->max_qpairs; i++) { \
+   if (_ha->queue_pair_map[i]) \
+   _ha->queue_pair_map[i]->fw_res_tracking = 0; \
+   } \
+}
+
 /*
  * qla2x00 local function return status codes
  */
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c
index d231e7156134..87a18a00d509 100644
--- a/drivers/scsi/qla2xxx/qla_dfs.c
+++ b/drivers/scsi/qla2xxx/qla_dfs.c
@@ -418,6 +418,278 @@ static const struct file_operations dfs_naqp_ops = {
.write  = 

[PATCH 05/43] qla2xxx: Add boundary checks for exchanges to be offloaded

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

Max boundary for exchange off load is 32k exchanges. If system
is unable to allocate large memory buffer to support this feature,
then driver will reduce the number exchanges down to a value
system can support.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_def.h |  3 +++
 drivers/scsi/qla2xxx/qla_os.c  | 39 ++-
 2 files changed, 33 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 50a570595969..ca3ef9360ab9 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -288,6 +288,8 @@ struct name_list_extended {
 #define ATIO_ENTRY_CNT_24XX4096/* Number of ATIO entries. */
 #define RESPONSE_ENTRY_CNT_FX00256 /* Number of response 
entries.*/
 #define FW_DEF_EXCHANGES_CNT 2048
+#define FW_MAX_EXCHANGES_CNT (32 * 1024)
+#define REDUCE_EXCHANGES_CNT  (8 * 1024)
 
 struct req_que;
 struct qla_tgt_sess;
@@ -3542,6 +3544,7 @@ struct qla_hw_data {
uint32_tusing_lr_setting:1;
} flags;
 
+   uint16_t max_exchg;
uint16_t long_range_distance;   /* 32G & above */
 #define LR_DISTANCE_5K  1
 #define LR_DISTANCE_10K 0
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 987bade1c606..029b95b2bd8a 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -2789,6 +2789,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct 
pci_device_id *id)
ha->init_cb_size = sizeof(init_cb_t);
ha->link_data_rate = PORT_SPEED_UNKNOWN;
ha->optrom_size = OPTROM_SIZE_2300;
+   ha->max_exchg = FW_MAX_EXCHANGES_CNT;
 
/* Assign ISP specific operations. */
if (IS_QLA2100(ha)) {
@@ -4230,6 +4231,9 @@ qla2x00_number_of_exch(scsi_qla_host_t *vha, u32 
*ret_cnt, u16 max_cnt)
u32 temp;
*ret_cnt = FW_DEF_EXCHANGES_CNT;
 
+   if (max_cnt > vha->hw->max_exchg)
+   max_cnt = vha->hw->max_exchg;
+
if (qla_ini_mode_enabled(vha)) {
if (ql2xiniexchg > max_cnt)
ql2xiniexchg = max_cnt;
@@ -4259,8 +4263,8 @@ int
 qla2x00_set_exchoffld_buffer(scsi_qla_host_t *vha)
 {
int rval;
-   u16 size, max_cnt;
-   u32 temp;
+   u16 size, max_cnt;
+   u32 actual_cnt, totsz;
struct qla_hw_data *ha = vha->hw;
 
if (!ha->flags.exchoffld_enabled)
@@ -4277,16 +4281,19 @@ qla2x00_set_exchoffld_buffer(scsi_qla_host_t *vha)
return rval;
}
 
-   qla2x00_number_of_exch(vha, , max_cnt);
-   temp *= size;
+   qla2x00_number_of_exch(vha, _cnt, max_cnt);
+   ql_log(ql_log_info, vha, 0xd014,
+   "Actual exchange offload count: %d.\n", actual_cnt);
+
+   totsz = actual_cnt * size;
 
-   if (temp != ha->exchoffld_size) {
+   if (totsz != ha->exchoffld_size) {
qla2x00_free_exchoffld_buffer(ha);
-   ha->exchoffld_size = temp;
+   ha->exchoffld_size = totsz;
 
ql_log(ql_log_info, vha, 0xd016,
-   "Exchange offload: max_count=%d, buffers=0x%x, total=%d.\n",
-   max_cnt, size, temp);
+   "Exchange offload: max_count=%d, actual count=%d entry 
sz=0x%x, total sz=0x%x\n",
+   max_cnt, actual_cnt, size, totsz);
 
ql_log(ql_log_info, vha, 0xd017,
"Exchange Buffers requested size = 0x%x\n",
@@ -4297,7 +4304,21 @@ qla2x00_set_exchoffld_buffer(scsi_qla_host_t *vha)
ha->exchoffld_size, >exchoffld_buf_dma, GFP_KERNEL);
if (!ha->exchoffld_buf) {
ql_log_pci(ql_log_fatal, ha->pdev, 0xd013,
-   "Failed to allocate memory for exchoffld_buf_dma.\n");
+   "Failed to allocate memory for Exchange Offload.\n");
+
+   if (ha->max_exchg >
+   (FW_DEF_EXCHANGES_CNT + REDUCE_EXCHANGES_CNT)) {
+   ha->max_exchg -= REDUCE_EXCHANGES_CNT;
+   } else if (ha->max_exchg >
+   (FW_DEF_EXCHANGES_CNT + 512)) {
+   ha->max_exchg -= 512;
+   } else {
+   ha->flags.exchoffld_enabled = 0;
+   ql_log_pci(ql_log_fatal, ha->pdev, 0xd013,
+   "Disabling Exchange offload due to lack of 
memory\n");
+   }
+   ha->exchoffld_size = 0;
+
return -ENOMEM;
}
}
-- 
2.12.0



[PATCH 06/43] qla2xxx: Fix stale mem access for IRQ name

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

IRQ name pointer for INTx/MSI was pointing at stale stack frame.
cat /proc/interrupts will trigger stale mem access. Fix it by
creating dedicated space for IRQ name.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_def.h |  4 +++-
 drivers/scsi/qla2xxx/qla_isr.c | 10 +-
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index ca3ef9360ab9..5e509763a419 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3140,12 +3140,13 @@ struct scsi_qla_host;
 
 #define QLA83XX_RSPQ_MSIX_ENTRY_NUMBER 1 /* refer to qla83xx_msix_entries */
 
+#define IRQNAME_SZ 32
 struct qla_msix_entry {
int have_irq;
int in_use;
uint32_t vector;
uint16_t entry;
-   char name[30];
+   char name[IRQNAME_SZ];
void *handle;
int cpuid;
 };
@@ -4025,6 +4026,7 @@ struct qla_hw_data {
uint16_tzio_timer;
 
struct qla_msix_entry *msix_entries;
+   u8 irqname[IRQNAME_SZ]; /* msi/intx */
 
struct list_headvp_list;/* list of VP */
unsigned long   vp_idx_map[(MAX_MULTI_ID_FABRIC / 8) /
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index a265c2d8c9cc..33865e0bb29f 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -3607,9 +3607,17 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct 
rsp_que *rsp)
if (!ha->flags.msi_enabled && IS_QLA82XX(ha))
return QLA_FUNCTION_FAILED;
 
+   memset(ha->irqname, 0, IRQNAME_SZ);
+   if (ha->flags.msi_enabled)
+   scnprintf(ha->irqname, IRQNAME_SZ,
+   "qla2xxx%lu_msi", vha->host_no);
+   else
+   scnprintf(ha->irqname, IRQNAME_SZ,
+   "qla2xxx%lu_intx", vha->host_no);
ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
ha->flags.msi_enabled ? 0 : IRQF_SHARED,
-   QLA2XXX_DRIVER_NAME, rsp);
+   ha->irqname, rsp);
+
if (ret) {
ql_log(ql_log_warn, vha, 0x003a,
"Failed to reserve interrupt %d already in use.\n",
-- 
2.12.0



[PATCH 03/43] qla2xxx: Use IOCB path to submit Control VP MBX command

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

Use IOCB patch to submit Control VP MBX command to reduce
bottle-neck for mbx interface.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_def.h|  9 -
 drivers/scsi/qla2xxx/qla_gs.c |  1 +
 drivers/scsi/qla2xxx/qla_init.c   |  1 +
 drivers/scsi/qla2xxx/qla_inline.h |  1 +
 drivers/scsi/qla2xxx/qla_iocb.c   | 23 +++
 drivers/scsi/qla2xxx/qla_isr.c| 35 
 drivers/scsi/qla2xxx/qla_mbx.c| 77 ---
 drivers/scsi/qla2xxx/qla_mid.c| 85 +++
 8 files changed, 154 insertions(+), 78 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 4d65fd973a12..50a570595969 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -472,6 +472,10 @@ struct srb_iocb {
uint32_t timeout_sec;
struct  list_head   entry;
} nvme;
+   struct {
+   u16 cmd;
+   u16 vp_index;
+   } ctrlvp;
} u;
 
struct timer_list timer;
@@ -507,6 +511,7 @@ enum {
SPCN_PRLI,
SPCN_NVME_LS,
SPCN_NVME_CMD,
+   SPCN_CTRL_VP,
 };
 
 struct sp_name {
@@ -536,7 +541,7 @@ struct sp_name {
 #define SRB_NVME_CMD   19
 #define SRB_NVME_LS20
 #define SRB_PRLI_CMD   21
-
+#define SRB_CTRL_VP22
 enum {
TYPE_SRB,
TYPE_TGT_CMD,
@@ -562,6 +567,8 @@ typedef struct srb {
struct list_head elem;
u32 gen1;   /* scratch */
u32 gen2;   /* scratch */
+   int rc;
+   struct completion comp;
union {
struct srb_iocb iocb_cmd;
struct bsg_job *bsg_job;
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 7e88e8289157..6aa6dd74fe86 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -41,6 +41,7 @@ struct sp_name sp_str[] = {
{ SPCN_PRLI, "prli" },
{ SPCN_NVME_LS, "nvme_ls" },
{ SPCN_NVME_CMD, "nvme_cmd" },
+   { SPCN_CTRL_VP, "ctrl_vp" },
 };
 
 const char *sp_to_str(uint16_t cmd)
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 9d65fbe85e30..24d0f9d419d2 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -135,6 +135,7 @@ qla2x00_async_iocb_timeout(void *data)
case SRB_NACK_PLOGI:
case SRB_NACK_PRLI:
case SRB_NACK_LOGO:
+   case SRB_CTRL_VP:
sp->done(sp, QLA_FUNCTION_TIMEOUT);
break;
}
diff --git a/drivers/scsi/qla2xxx/qla_inline.h 
b/drivers/scsi/qla2xxx/qla_inline.h
index 17d2c20f1f75..4d32426393c7 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -273,6 +273,7 @@ qla2x00_init_timer(srb_t *sp, unsigned long tmo)
sp->u.iocb_cmd.timer.expires = jiffies + tmo * HZ;
add_timer(>u.iocb_cmd.timer);
sp->free = qla2x00_sp_free;
+   init_completion(>comp);
if (IS_QLAFX00(sp->vha->hw) && (sp->type == SRB_FXIOCB_DCMD))
init_completion(>u.iocb_cmd.u.fxiocb.fxiocb_comp);
if (sp->type == SRB_ELS_DCMD)
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index b5d1423f933d..62b3d0a8a961 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -3368,6 +3368,26 @@ qla_nvme_ls(srb_t *sp, struct pt_ls4_request *cmd_pkt)
return rval;
 }
 
+static void
+qla25xx_ctrlvp_iocb(srb_t *sp, struct vp_ctrl_entry_24xx *vce)
+{
+   int map, pos;
+
+   vce->entry_type = VP_CTRL_IOCB_TYPE;
+   vce->handle = sp->handle;
+   vce->entry_count = 1;
+   vce->command = cpu_to_le16(sp->u.iocb_cmd.u.ctrlvp.cmd);
+   vce->vp_count = cpu_to_le16(1);
+
+   /*
+* index map in firmware starts with 1; decrement index
+* this is ok as we never use index 0
+*/
+   map = (sp->u.iocb_cmd.u.ctrlvp.vp_index - 1) / 8;
+   pos = (sp->u.iocb_cmd.u.ctrlvp.vp_index - 1) & 7;
+   vce->vp_idx_map[map] |= 1 << pos;
+}
+
 int
 qla2x00_start_sp(srb_t *sp)
 {
@@ -3446,6 +3466,9 @@ qla2x00_start_sp(srb_t *sp)
case SRB_NACK_LOGO:
qla2x00_send_notify_ack_iocb(sp, pkt);
break;
+   case SRB_CTRL_VP:
+   qla25xx_ctrlvp_iocb(sp, pkt);
+   break;
default:
break;
}
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index a55bfaa790a3..a265c2d8c9cc 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1937,6 +1937,37 @@ qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct 
req_que *req, void *tsk)
sp->done(sp, ret);
 }
 
+static void qla_ctrlvp_completed(scsi_qla_host_t 

[PATCH 02/43] qla2xxx: Fix NULL pointer access for fcport structure

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

when preocessing iocb in a timeout case, driver was trying to log messages
without verifying if the fcport structure could have valid data. This
results in a NULL pointer access.

Fixes: 726b85487067("qla2xxx: Add framework for async fabric discovery")
Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_init.c | 13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 7fa71170d6ff..9d65fbe85e30 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -102,11 +102,16 @@ qla2x00_async_iocb_timeout(void *data)
struct srb_iocb *lio = >u.iocb_cmd;
struct event_arg ea;
 
-   ql_dbg(ql_dbg_disc, fcport->vha, 0x2071,
-   "Async-%s timeout - hdl=%x portid=%06x %8phC.\n",
-   sp->name, sp->handle, fcport->d_id.b24, fcport->port_name);
+   if (fcport) {
+   ql_dbg(ql_dbg_disc, fcport->vha, 0x2071,
+   "Async-%s timeout - hdl=%x portid=%06x %8phC.\n",
+   sp->name, sp->handle, fcport->d_id.b24, fcport->port_name);
 
-   fcport->flags &= ~FCF_ASYNC_SENT;
+   fcport->flags &= ~FCF_ASYNC_SENT;
+   } else {
+   pr_info("Async-%s timeout - hdl=%x.\n",
+   sp->name, sp->handle);
+   }
 
switch (sp->type) {
case SRB_LOGIN_CMD:
-- 
2.12.0



[PATCH 01/43] qla2xxx: Fix stale memory access for name pointer

2017-12-19 Thread Himanshu Madhani
From: Quinn Tran 

Name pointer for sp describing each command is assigned with stack
frame's memory. The stack frame could eventually be re-use, where
name pointer access can get get garbage. This patch designates
static memory for name pointer to fix this problem.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_bsg.c|  7 +++---
 drivers/scsi/qla2xxx/qla_def.h| 36 +++
 drivers/scsi/qla2xxx/qla_gbl.h|  1 +
 drivers/scsi/qla2xxx/qla_gs.c | 51 ---
 drivers/scsi/qla2xxx/qla_init.c   | 16 ++--
 drivers/scsi/qla2xxx/qla_iocb.c   |  4 +--
 drivers/scsi/qla2xxx/qla_mbx.c|  5 ++--
 drivers/scsi/qla2xxx/qla_mr.c |  2 +-
 drivers/scsi/qla2xxx/qla_nvme.c   |  4 +--
 drivers/scsi/qla2xxx/qla_target.c |  2 +-
 10 files changed, 105 insertions(+), 23 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index e3ac7078d2aa..3fc3ae9abb39 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -376,7 +376,8 @@ qla2x00_process_els(struct bsg_job *bsg_job)
 SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST);
sp->name =
(bsg_request->msgcode == FC_BSG_RPT_ELS ?
-"bsg_els_rpt" : "bsg_els_hst");
+sp_to_str(SPCN_BSG_RPT) : sp_to_str(SPCN_BSG_HST));
+
sp->u.bsg_job = bsg_job;
sp->free = qla2x00_bsg_sp_free;
sp->done = qla2x00_bsg_job_done;
@@ -522,7 +523,7 @@ qla2x00_process_ct(struct bsg_job *bsg_job)
}
 
sp->type = SRB_CT_CMD;
-   sp->name = "bsg_ct";
+   sp->name = sp_to_str(SPCN_BSG_CT);
sp->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt);
sp->u.bsg_job = bsg_job;
sp->free = qla2x00_bsg_sp_free;
@@ -2028,7 +2029,7 @@ qlafx00_mgmt_cmd(struct bsg_job *bsg_job)
fcport->loop_id = piocb_rqst->dataword;
 
sp->type = SRB_FXIOCB_BCMD;
-   sp->name = "bsg_fx_mgmt";
+   sp->name = sp_to_str(SPCN_BSG_FX_MGMT);
sp->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt);
sp->u.bsg_job = bsg_job;
sp->free = qla2x00_bsg_sp_free;
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 93ff92e2363f..4d65fd973a12 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -478,6 +478,42 @@ struct srb_iocb {
void (*timeout)(void *);
 };
 
+enum {
+   SPCN_UNKNOWN,
+   SPCN_GIDPN,
+   SPCN_GPSC,
+   SPCN_GPNID,
+   SPCN_GPNFT,
+   SPCN_GNNID,
+   SPCN_GFPNID,
+   SPCN_LOGIN,
+   SPCN_LOGOUT,
+   SPCN_ADISC,
+   SPCN_GNLIST,
+   SPCN_GPDB,
+   SPCN_TMF,
+   SPCN_ABORT,
+   SPCN_NACK,
+   SPCN_BSG_RPT,
+   SPCN_BSG_HST,
+   SPCN_BSG_CT,
+   SPCN_BSG_FX_MGMT,
+   SPCN_ELS_DCMD,
+   SPCN_FXDISC,
+   SPCN_GIDLIST,
+   SPCN_STATS,
+   SPCN_MB_GPDB,
+   SPCN_GFFID,
+   SPCN_PRLI,
+   SPCN_NVME_LS,
+   SPCN_NVME_CMD,
+};
+
+struct sp_name {
+   uint16_t cmd;
+   const char *str;
+};
+
 /* Values for srb_ctx type */
 #define SRB_LOGIN_CMD  1
 #define SRB_LOGOUT_CMD 2
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index fa115c7433e5..bf907386f177 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -647,6 +647,7 @@ int qla24xx_async_gpsc(scsi_qla_host_t *, fc_port_t *);
 int qla2x00_mgmt_svr_login(scsi_qla_host_t *);
 void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea);
 int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport);
+const char *sp_to_str(uint16_t);
 /*
  * Global Function Prototypes in qla_attr.c source file.
  */
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 07fe17a986b0..7e88e8289157 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -15,6 +15,49 @@ static int qla2x00_sns_gnn_id(scsi_qla_host_t *, sw_info_t 
*);
 static int qla2x00_sns_rft_id(scsi_qla_host_t *);
 static int qla2x00_sns_rnn_id(scsi_qla_host_t *);
 
+struct sp_name sp_str[] = {
+   { SPCN_UNKNOWN, "unknown" },
+   { SPCN_GIDPN, "gidpn" },
+   { SPCN_GPSC, "gpsc" },
+   { SPCN_GPNID, "gpnid" },
+   { SPCN_GPNFT, "gpnft" },
+   { SPCN_GNNID, "gnnid" },
+   { SPCN_GFPNID, "gfpnid" },
+   { SPCN_GFFID, "gffid" },
+   { SPCN_LOGIN, "login" },
+   { SPCN_LOGOUT, "logout" },
+   { SPCN_ADISC, "adisc" },
+   { SPCN_GNLIST, "gnlist" },
+   { SPCN_GPDB, "gpdb" },
+   { SPCN_TMF, "tmf" },
+   { SPCN_ABORT, "abort" },
+   { SPCN_NACK, "nack" },
+   { SPCN_BSG_RPT, "bsg_els_rpt" },
+   { SPCN_BSG_HST, "bsg_els_hst" },
+   { SPCN_BSG_CT, "bsg_ct" },
+   { SPCN_BSG_FX_MGMT, "bsg_fx_mgmt" },
+   { SPCN_ELS_DCMD, "ELS_DCMD" },
+ 

[PATCH 00/43] qla2xxx: Driver update

2017-12-19 Thread Himanshu Madhani
Hi Martin, 

This series contains number of improvments in handling of switch 
registration commands in the driver. Switch commands are now submitted
via IOCB patch asynchronously instead of mailbox interface.

Please apply this series to 4.16/scsi-queue branch at your earliest
convenience. 

Thanks,
Himanshu

Anil Gurumurthy (1):
  qla2xxx: Add counters for Exchange Buffer to debugfs

Giridhar Malavali (1):
  qla2xxx: Don't call dma_free_coherent with IRQ disabled.

Himanshu Madhani (4):
  qla2xxx: Use known NPort ID for Management Server login
  qla2xxx: Allow relogin and session creation after reset
  qla2xxx: Check FCF_ASYNC_SENT flag
  qla2xxx: Update driver version to 10.00.00.04-k

Quinn Tran (36):
  qla2xxx: Fix stale memory access for name pointer
  qla2xxx: Fix NULL pointer access for fcport structure
  qla2xxx: Use IOCB path to submit Control VP MBX command
  qla2xxx: Use chip reset to bring down laser on unload.
  qla2xxx: Add boundary checks for exchanges to be offloaded
  qla2xxx: Fix stale mem access for IRQ name
  qla2xxx: Add ability to track IOCB resource for FW
  qla2xxx: Chip reset uses wrong lock during IO flush.
  qla2xxx: Fix Firmware dump size for Extended login and Exchange
Offload
  qla2xxx: Replace GPDB with async ADISC command
  qla2xxx: Move work element processing out of DPC thread
  qla2xxx: Enable ATIO interrupt handshake for ISP27XX
  qla2xxx: Use shadow register for ISP27XX
  qla2xxx: Add option for use reserve exch for ELS
  qla2xxx: Add ability to send PRLO
  qla2xxx: Allow target mode to accept PRLI in dual mode
  qla2xxx: Tweak resource count dump
  qla2xxx: Fix session cleanup for N2N
  qla2xxx: Add switch command to simplify fabric discovery
  qla2xxx: Add lock protection around host lookup
  qla2xxx: Reduce the use of terminate exchange
  qla2xxx: Reduce trace noise for Async Events
  qla2xxx: Fix login state machine freeze
  qla2xxx: Migrate switch registration commands away from mailbox
interface
  qla2xxx: Remove session creation redundant code
  qla2xxx: Fix GPNFT/GNNFT error handling
  qla2xxx: Properly extract ADISC error codes
  qla2xxx: Add ability to use GPNFT/GNNFT for RSCN handling
  qla2xxx: Increase verbosity of debug messages logged
  qla2xxx: Delay loop id allocation at login
  qla2xxx: Add retry limit for fabric scan logic
  qla2xxx: Prevent multiple active discovery commands per session
  qla2xxx: Prevent relogin trigger from sending too many commands
  qla2xxx: Remove unused argument from qlt_schedule_sess_for_deletion()
  qla2xxx: Serialize session deletion by using work_lock
  qla2xxx: Serialize session free in  qlt_free_session_done

Sawan Chandak (1):
  qla2xxx: Remove calling cancel_work_sync()

 drivers/scsi/qla2xxx/qla_attr.c|2 +
 drivers/scsi/qla2xxx/qla_bsg.c |7 +-
 drivers/scsi/qla2xxx/qla_def.h |  220 +-
 drivers/scsi/qla2xxx/qla_dfs.c |  354 +-
 drivers/scsi/qla2xxx/qla_fw.h  |2 +-
 drivers/scsi/qla2xxx/qla_gbl.h |   37 +-
 drivers/scsi/qla2xxx/qla_gs.c  | 1339 +++-
 drivers/scsi/qla2xxx/qla_init.c| 1019 +--
 drivers/scsi/qla2xxx/qla_inline.h  |  103 +++
 drivers/scsi/qla2xxx/qla_iocb.c|   93 ++-
 drivers/scsi/qla2xxx/qla_isr.c |   64 +-
 drivers/scsi/qla2xxx/qla_mbx.c |  153 ++--
 drivers/scsi/qla2xxx/qla_mid.c |  113 ++-
 drivers/scsi/qla2xxx/qla_mr.c  |2 +-
 drivers/scsi/qla2xxx/qla_nvme.c|4 +-
 drivers/scsi/qla2xxx/qla_os.c  |  449 
 drivers/scsi/qla2xxx/qla_target.c  |  728 +++-
 drivers/scsi/qla2xxx/qla_target.h  |7 +-
 drivers/scsi/qla2xxx/qla_tmpl.c|   40 +-
 drivers/scsi/qla2xxx/qla_version.h |2 +-
 20 files changed, 3593 insertions(+), 1145 deletions(-)

-- 
2.12.0



Re: [PATCH 2/2 v2] scsi: ufs: use sysfs entry for health info

2017-12-19 Thread Bart Van Assche
On Tue, 2017-12-19 at 14:46 -0800, Jaegeuk Kim wrote:
> Subject: [PATCH 2/2] scsi: ufs: introduce sysfs entries exposing UFS health
>  info
> 
> This patch adds a new sysfs group, namely health, via:
> 
>/sys/devices/soc/X.ufshc/health/

Thanks for the quick respin. This looks a lot better to me. I will leave
it to a UFS expert to do an in-depth review.

Bart.

Re: [PATCH net-next] qed*: Utilize FW 8.33.1.0

2017-12-19 Thread Jakub Kicinski
On Tue, 19 Dec 2017 16:05:23 +0200, Tomer Tayar wrote:
> Sorry for the very long patch.
> The firmware changes are spread all over w/o a good modularity.

Rings false.  Significant portion of this patch is just whitespace 
and comment changes.


RE: Driver version for PMC Adaptec HBA in Linux and from vendor

2017-12-19 Thread Raghava Aditya Renukunta
Hi Paul,

> -Original Message-
> From: Paul Menzel [mailto:pmen...@molgen.mpg.de]
> Sent: Tuesday, December 19, 2017 3:12 PM
> To: Raghava Aditya Renukunta
> ; dl-esc-Aacraid Linux Driver
> 
> Cc: linux-scsi@vger.kernel.org; it+linux-s...@molgen.mpg.de
> Subject: Re: Driver version for PMC Adaptec HBA in Linux and from vendor
> 
> EXTERNAL EMAIL
> 
> 
> Dear Raghava Aditya,
> 
> 
> Thank you for your answer.
> 
> Am 18.12.2017 um 19:09 schrieb Raghava Aditya Renukunta:
> 
> >> -Original Message-
> >> From: Paul Menzel [mailto:pmen...@molgen.mpg.de]
> >> Sent: Saturday, December 16, 2017 1:39 AM
> >> To: Raghava Aditya Renukunta
> >> ; dl-esc-Aacraid Linux Driver
> >> 
> >> Cc: linux-scsi@vger.kernel.org; it+linux-s...@vger.kernel.org
> >> Subject: Re: Driver version for PMC Adaptec HBA in Linux and from
> vendor
> 
> >> Am 17.02.2017 um 20:29 schrieb Raghava Aditya Renukunta:
> >>
>  Using a PMC Adaptec HBA 1000-8e with latest Linux, it only initializes
>  in sync mode, instead of async mode.
> >>>
> >>> The patches that enable async mode in HBA 1000-8e, have been
> included in
> >> the James Bottomley's linux-scsi Branch and are on track be
> >>> Included into Linux 4.11.
> >>>
> >>> https://git.kernel.org/cgit/linux/kernel/git/jejb/scsi.git/
> >>>
>  ```
>  $ git describe --tag
>  v4.10-rc8-47-g0722f57bf
>  $ dmesg
>  [   21.359635] Adaptec aacraid driver 1.2-1[41066]-ms
>  [   21.360017] aacraid :04:00.0: can't disable ASPM; OS doesn't have
>  ASPM control
>  [   21.363987] AAC0: Async. mode not supported by current driver, sync.
>  mode enforced.
>  [   21.363987] Please update driver to get full performance.
>  [   21.364949] AAC0: kernel 1.2-0[0] Nov  5 2015
>  [   21.365275] AAC0: monitor 0.0-0[0]
>  [   21.371382] AAC0: bios 0.13-209[32000]
>  [   21.371711] AAC0: serial 10F447
>  [   21.372035] AAC0: Non-DASD support enabled.
>  [   21.372360] AAC0: 64bit support enabled.
>  [   21.372688] AAC0: 64 Bit DAC enabled
>  […]
>  $ git grep 'AAC_DRIVER_BUILD 41066'
>  drivers/scsi/aacraid/aacraid.h:# define AAC_DRIVER_BUILD 41066
>  ```
> 
>  Searching the vendor Web site, there is *Linux Driver Source
>  1.2.1-53005* available for download [1].
> >>>
> >>> The latest upstream driver version is 50740. We will be reaching version
> 53005 in couple of patch sets  ( ~ 3).
> >>>
> >>
> http://git.kernel.org/cgit/linux/kernel/git/jejb/scsi.git/commit/?id=96f6a613
> >> 4766de0d42a98c7758736dde16e0add5
> >>
> >> Thank you for the details. At our infrastructure we only want to use LTS
> >> Linux kernels, and the latest in 4.14. So right now, Linux 4.14.6
> >> includes version 50834 [1], which is the same version currently in Linus
> >> master branch (4.15-rc3). Is that save to use with async mode, or are
> >> you aware of problems and we should always use the latest out of tree
> >> driver, which is at version 55022 and can be download from the Microsemi
> >> server [3].
> >
> > Well at this point I am in the process of creating a patch set that solves a
> kdump regression issue(Should be out before the new year), other than that
> the upstream driver is pretty much up to date. If kdump support is a must
> for you I would recommend that  55022 be used.
> 
>  From your answer the state of async support is unclear to me. Could you
> please clarify, if that’s support in 4.14.x? (What source line do I need
> to check?)

It is supported in 4.14, there is no single line specifically, but if the 
variable sa_firmware is set
then async mode is enabled.

>  How does the upstream process work? Is there a git repository
> somewhere
>  from Microsemi? Are the patches already up for review? (I didn’t find
> them.)
> >>>
> >>> We try to push out patch sets to kernel.org for every major  driver
> release we make.  Usually they go into the
> >>> sub component maintainers branch (linux-scsi ) , which is then pushed
> out to Linus when the merge
> >>> window for  opens (currently the merge window for 4.10 is closed ,
> barring fixes). So Linux version 4.11 should have
> >>> full async support and more for HBA1000-8e.
> >>>
> >>> We do not maintain a git repository unfortunately, but we do release the
> >>> source code for every release as you indicated.
> >>>
> >>> For further reference the patches are sent out in the scsi mailing list
> linux-scsi@vger.kernel.org ,
> >>> the archive is here http://marc.info/?l=linux-scsi=1=2 .
> >>>
> >>> Hope I cleared up your doubts. Please do reach out if you have other
> concerns or questions.
> >>
> >> Yes, thank you for your elaborate answer, which cleared up a lot of my
> >> doubts. We would be even more satisfied if you moved your
> development
> >> fully to the Linux kernel tree, so that it always carries the latest
> >> driver. If 

Re: Driver version for PMC Adaptec HBA in Linux and from vendor

2017-12-19 Thread Paul Menzel

Dear Raghava Aditya,


Thank you for your answer.

Am 18.12.2017 um 19:09 schrieb Raghava Aditya Renukunta:


-Original Message-
From: Paul Menzel [mailto:pmen...@molgen.mpg.de]
Sent: Saturday, December 16, 2017 1:39 AM
To: Raghava Aditya Renukunta
; dl-esc-Aacraid Linux Driver

Cc: linux-scsi@vger.kernel.org; it+linux-s...@vger.kernel.org
Subject: Re: Driver version for PMC Adaptec HBA in Linux and from vendor



Am 17.02.2017 um 20:29 schrieb Raghava Aditya Renukunta:


Using a PMC Adaptec HBA 1000-8e with latest Linux, it only initializes
in sync mode, instead of async mode.


The patches that enable async mode in HBA 1000-8e, have been included in

the James Bottomley's linux-scsi Branch and are on track be

Included into Linux 4.11.

https://git.kernel.org/cgit/linux/kernel/git/jejb/scsi.git/


```
$ git describe --tag
v4.10-rc8-47-g0722f57bf
$ dmesg
[   21.359635] Adaptec aacraid driver 1.2-1[41066]-ms
[   21.360017] aacraid :04:00.0: can't disable ASPM; OS doesn't have
ASPM control
[   21.363987] AAC0: Async. mode not supported by current driver, sync.
mode enforced.
[   21.363987] Please update driver to get full performance.
[   21.364949] AAC0: kernel 1.2-0[0] Nov  5 2015
[   21.365275] AAC0: monitor 0.0-0[0]
[   21.371382] AAC0: bios 0.13-209[32000]
[   21.371711] AAC0: serial 10F447
[   21.372035] AAC0: Non-DASD support enabled.
[   21.372360] AAC0: 64bit support enabled.
[   21.372688] AAC0: 64 Bit DAC enabled
[…]
$ git grep 'AAC_DRIVER_BUILD 41066'
drivers/scsi/aacraid/aacraid.h:# define AAC_DRIVER_BUILD 41066
```

Searching the vendor Web site, there is *Linux Driver Source
1.2.1-53005* available for download [1].


The latest upstream driver version is 50740. We will be reaching version 53005 
in couple of patch sets  ( ~ 3).


http://git.kernel.org/cgit/linux/kernel/git/jejb/scsi.git/commit/?id=96f6a613
4766de0d42a98c7758736dde16e0add5

Thank you for the details. At our infrastructure we only want to use LTS
Linux kernels, and the latest in 4.14. So right now, Linux 4.14.6
includes version 50834 [1], which is the same version currently in Linus
master branch (4.15-rc3). Is that save to use with async mode, or are
you aware of problems and we should always use the latest out of tree
driver, which is at version 55022 and can be download from the Microsemi
server [3].


Well at this point I am in the process of creating a patch set that solves a 
kdump regression issue(Should be out before the new year), other than that the 
upstream driver is pretty much up to date. If kdump support is a must  for you 
I would recommend that  55022 be used.


From your answer the state of async support is unclear to me. Could you 
please clarify, if that’s support in 4.14.x? (What source line do I need 
to check?)



How does the upstream process work? Is there a git repository somewhere
from Microsemi? Are the patches already up for review? (I didn’t find them.)


We try to push out patch sets to kernel.org for every major  driver release we 
make.  Usually they go into the
sub component maintainers branch (linux-scsi ) , which is then pushed out to 
Linus when the merge
window for  opens (currently the merge window for 4.10 is closed , barring 
fixes). So Linux version 4.11 should have
full async support and more for HBA1000-8e.

We do not maintain a git repository unfortunately, but we do release the >>> 
source code for every release as you indicated.

For further reference the patches are sent out in the scsi mailing list 
linux-scsi@vger.kernel.org ,
the archive is here http://marc.info/?l=linux-scsi=1=2 .

Hope I cleared up your doubts. Please do reach out if you have other concerns 
or questions.


Yes, thank you for your elaborate answer, which cleared up a lot of my
doubts. We would be even more satisfied if you moved your development
fully to the Linux kernel tree, so that it always carries the latest
driver. If we can help with that by contacting certain people, please
tell us.


We would love to, but  we have lots of customers who are on the older kernel 
versions 2.6.32, 3.10.0 etc and It becomes almost impossible for us to fully 
move our development to the  Linux kernel tree and support our customers at the 
same time.  Hopefully we will start being up to date with the upstream kernel 
in the coming months. Hope that answered your questions.


I understand, but doesn’t it make more sense to adapt the model like 
done for Linux Long Term Support (LTS) series to develop against the 
latest Linux kernel, and then backport the corresponding patches?


Maybe you should talk to Red Hat and SUSE? I guess that’s the systems 
you have to support. Probably you already talk to them.



Kind regards,

Paul



[1] 
https://storage.microsemi.com/en-us/speed/raid/aac/linux/aacraid-linux-src-1_2_1-53005_tgz.php

[2] 
https://elixir.free-electrons.com/linux/v4.14.6/source/drivers/scsi/aacraid/aacraid.h#L100
[3] 

Re: [PATCH 2/2 v2] scsi: ufs: use sysfs entry for health info

2017-12-19 Thread Jaegeuk Kim
>From 3368207da5988b8fed4e41e6c0f49a60ac014222 Mon Sep 17 00:00:00 2001
From: Jaegeuk Kim 
Date: Tue, 26 Sep 2017 20:53:48 -0700
Subject: [PATCH 2/2] scsi: ufs: introduce sysfs entries exposing UFS health
 info

This patch adds a new sysfs group, namely health, via:

   /sys/devices/soc/X.ufshc/health/

This directory contains the below entries, each of which shows an 8-bytes
hex number representing different meanings defined by JEDEC specfication.

Users can simply read these entries to check how their underlying flash
storage is getting reached out to its end of life. For example, if
lifetimeA shows 0xb, it would be the right time to consider device swap.

 - length
   : must be 25h

 - type
   : must be 09h

 - eol
   00h: Not defined
   01h: Normal
   02h: Warning
   03h: Critical

 - lifetimeA/B
   00h: Not defined
   01h:  0% ~ 10% device life time used
   02h: 10% ~ 20% device life time used
   03h: 20% ~ 30% device life time used
   04h: 30% ~ 40% device life time used
   05h: 40% ~ 50% device life time used
   06h: 50% ~ 60% device life time used
   07h: 60% ~ 70% device life time used
   08h: 70% ~ 80% device life time used
   09h: 80% ~ 90% device life time used
   0Ah: 90% ~ 100% device life time used
   0Bh: Exceeded its maximum estimated device life time

Cc: Greg KH 
Signed-off-by: Jaegeuk Kim 
---
 Documentation/ABI/testing/sysfs-devices-soc-ufs | 25 +
 MAINTAINERS |  1 +
 drivers/scsi/ufs/ufs.h  |  2 +
 drivers/scsi/ufs/ufshcd.c   | 69 -
 drivers/scsi/ufs/ufshcd.h   |  1 +
 5 files changed, 97 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ABI/testing/sysfs-devices-soc-ufs

diff --git a/Documentation/ABI/testing/sysfs-devices-soc-ufs 
b/Documentation/ABI/testing/sysfs-devices-soc-ufs
new file mode 100644
index ..313771a383e4
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-devices-soc-ufs
@@ -0,0 +1,25 @@
+What:  /sys/devices/soc/X.ufshc/health
+Date:  September 2017
+contact:   Jaegeuk Kim 
+Description:
+   This directory contains health information reported by UFS.
+   - length must be 25h
+   - type must be 09h
+   - eol represent
+ 00h: Not defined
+ 01h: Normal
+ 02h: Warning
+ 03h: Critical
+   - lifetimeA/B
+ 00h: Not defined
+ 01h:  0% ~ 10% device life time used
+ 02h: 10% ~ 20% device life time used
+ 03h: 20% ~ 30% device life time used
+ 04h: 30% ~ 40% device life time used
+ 05h: 40% ~ 50% device life time used
+ 06h: 50% ~ 60% device life time used
+ 07h: 60% ~ 70% device life time used
+ 08h: 70% ~ 80% device life time used
+ 09h: 80% ~ 90% device life time used
+ 0Ah: 90% ~ 100% device life time used
+ 0Bh: Exceeded its maximum estimated device life time
diff --git a/MAINTAINERS b/MAINTAINERS
index aa71ab52fd76..947034319bb4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13999,6 +13999,7 @@ M:  Vinayak Holikatti 
 L: linux-scsi@vger.kernel.org
 S: Supported
 F: Documentation/scsi/ufs.txt
+F: Documentation/ABI/testing/sysfs-devices-soc-ufs
 F: drivers/scsi/ufs/
 
 UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER DWC HOOKS
diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 54deeb754db5..1af541d56c7d 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -154,6 +154,7 @@ enum desc_idn {
QUERY_DESC_IDN_RFU_1= 0x6,
QUERY_DESC_IDN_GEOMETRY = 0x7,
QUERY_DESC_IDN_POWER= 0x8,
+   QUERY_DESC_IDN_HEALTH   = 0x9,
QUERY_DESC_IDN_MAX,
 };
 
@@ -169,6 +170,7 @@ enum ufs_desc_def_size {
QUERY_DESC_INTERCONNECT_DEF_SIZE= 0x06,
QUERY_DESC_GEOMETRY_DEF_SIZE= 0x44,
QUERY_DESC_POWER_DEF_SIZE   = 0x62,
+   QUERY_DESC_HEALTH_DEF_SIZE  = 0x25,
 };
 
 /* Unit descriptor parameters offsets in bytes*/
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 12ff7daebb00..5cbb08fff0f4 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -2991,6 +2991,9 @@ int ufshcd_map_desc_id_to_length(struct ufs_hba *hba,
case QUERY_DESC_IDN_RFU_1:
*desc_len = 0;
break;
+   case QUERY_DESC_IDN_HEALTH:
+   *desc_len = hba->desc_size.health_desc;
+   break;
default:
*desc_len = 0;
return -EINVAL;
@@ -6298,6 +6301,11 @@ static void ufshcd_init_desc_sizes(struct ufs_hba *hba)
 

Re: [PATCH 2/2 v2] scsi: ufs: use sysfs entry for health info

2017-12-19 Thread Jaegeuk Kim
On 12/19, Bart Van Assche wrote:
> On Tue, 2017-12-19 at 12:02 -0800, Jaegeuk Kim wrote:
> > This patch introduces sysfs entries to show the information.
> 
> What information does "the information" refer to?
> 
> Regarding the patch title: I think this patch introduces new sysfs attributes
> instead of using existing sysfs entries. If so, please reflect this in the 
> patch
> title.
> 
> >  # cat /sys/devices/soc/1da4000.ufshc/health/eol
> >  # cat /sys/devices/soc/1da4000.ufshc/health/length
> >  # cat /sys/devices/soc/1da4000.ufshc/health/lifetimeA
> >  # cat /sys/devices/soc/1da4000.ufshc/health/lifetimeB
> >  # cat /sys/devices/soc/1da4000.ufshc/health/type
> 
> What is the meaning of the above shell commands in the context of the patch
> description?
> 
> > struct desc_field_offset health_desc_field_name[] = {
> > {"bLength", 0x00, BYTE},
> > {"bDescriptorType", 0x01, BYTE},
> > {"bPreEOLInfo", 0x02, BYTE},
> > {"bDeviceLifeTimeEstA", 0x03, BYTE},
> > {"bDeviceLifeTimeEstB", 0x04, BYTE}
> > };
> 
> Why has the above data been mentioned in the patch description?
> 
> > bPreEOLInfo
> >  - 00h: Not defined
> >  - 01h: Normal
> >  - 02h: Warning
> >  - 03h: Critical
> > 
> > bDeviceLifeTimeEstA
> >  - 00h: Not defined
> >  - 01h:  0% ~ 10% device life time used
> >  - 02h: 10% ~ 20% device life time used
> >  - 03h: 20% ~ 30% device life time used
> >  - 04h: 30% ~ 40% device life time used
> >  - 05h: 40% ~ 50% device life time used
> >  - 06h: 50% ~ 60% device life time used
> >  - 07h: 60% ~ 70% device life time used
> >  - 08h: 70% ~ 80% device life time used
> >  - 09h: 80% ~ 90% device life time used
> >  - 0Ah: 90% ~ 100% device life time used
> >  - 0Bh: Exceeded its maximum estimated device life time
> 
> Again, why has the above information been mentioned in the patch description?

Let me send v2.

>  
> > +static ssize_t health_attr_show(struct device *dev,
> > +   struct health_attr *attr, char *buf)
> > +{
> > +   struct ufs_hba *hba = dev_get_drvdata(dev);
> > +   int buff_len = hba->desc_size.health_desc;
> > +   u8 desc_buf[hba->desc_size.health_desc];
> 
> Is desc_buf[] a variable-length array? If so, how big can
> hba->desc_size.health_desc be? Can that number have a negative value?

IIUC, it is given by UFS which must be valid. Otherwise, it should be
QUERY_DESC_HEALTH_DEF_SIZE which is valid again. This is similarly being
done in other sysfs entries here.

> 
> > +   return scnprintf(buf, PAGE_SIZE, "0x%02x", desc_buf[attr->bytes]);
> 
> Please check whether attr->bytes falls inside the bounds of the desc_buf[] 
> array
> before using that value as an index.

Okay.

> 
> > +#define HEALTH_ATTR_RO(_name, _bytes)  
> > \
> > +static struct health_attr ufs_health_##_name = {   \
> > +   .attr = {.name = __stringify(_name), .mode = 0444}, \
> > +   .show = health_attr_show,   \
> > +   .bytes = _bytes,\
> > +}
> > +
> > +HEALTH_ATTR_RO(length, 0);
> > +HEALTH_ATTR_RO(type, 1);
> > +HEALTH_ATTR_RO(eol, 2);
> > +HEALTH_ATTR_RO(lifetimeA, 3);
> > +HEALTH_ATTR_RO(lifetimeB, 4);
> 
> The above makes clear that the value stored in the structure member with the 
> name
> "bytes" represents an array index. Please choose a better name for that 
> structure
> member.

Changed to byte_offset.

> Additionally, since this patch introduces new sysfs attributes, why doesn't it
> add any documentation under Documentation/ABI/?

Added.

Thanks,

> 
> Thanks,
> 
> Bart.


Re: [PATCH 2/2] scsi: ufs: use sysfs entry for health info

2017-12-19 Thread Bart Van Assche
On Tue, 2017-12-19 at 12:02 -0800, Jaegeuk Kim wrote:
> This patch introduces sysfs entries to show the information.

What information does "the information" refer to?

Regarding the patch title: I think this patch introduces new sysfs attributes
instead of using existing sysfs entries. If so, please reflect this in the patch
title.

>  # cat /sys/devices/soc/1da4000.ufshc/health/eol
>  # cat /sys/devices/soc/1da4000.ufshc/health/length
>  # cat /sys/devices/soc/1da4000.ufshc/health/lifetimeA
>  # cat /sys/devices/soc/1da4000.ufshc/health/lifetimeB
>  # cat /sys/devices/soc/1da4000.ufshc/health/type

What is the meaning of the above shell commands in the context of the patch
description?

> struct desc_field_offset health_desc_field_name[] = {
>   {"bLength", 0x00, BYTE},
>   {"bDescriptorType", 0x01, BYTE},
>   {"bPreEOLInfo", 0x02, BYTE},
>   {"bDeviceLifeTimeEstA", 0x03, BYTE},
>   {"bDeviceLifeTimeEstB", 0x04, BYTE}
> };

Why has the above data been mentioned in the patch description?

> bPreEOLInfo
>  - 00h: Not defined
>  - 01h: Normal
>  - 02h: Warning
>  - 03h: Critical
> 
> bDeviceLifeTimeEstA
>  - 00h: Not defined
>  - 01h:  0% ~ 10% device life time used
>  - 02h: 10% ~ 20% device life time used
>  - 03h: 20% ~ 30% device life time used
>  - 04h: 30% ~ 40% device life time used
>  - 05h: 40% ~ 50% device life time used
>  - 06h: 50% ~ 60% device life time used
>  - 07h: 60% ~ 70% device life time used
>  - 08h: 70% ~ 80% device life time used
>  - 09h: 80% ~ 90% device life time used
>  - 0Ah: 90% ~ 100% device life time used
>  - 0Bh: Exceeded its maximum estimated device life time

Again, why has the above information been mentioned in the patch description?
 
> +static ssize_t health_attr_show(struct device *dev,
> + struct health_attr *attr, char *buf)
> +{
> + struct ufs_hba *hba = dev_get_drvdata(dev);
> + int buff_len = hba->desc_size.health_desc;
> + u8 desc_buf[hba->desc_size.health_desc];

Is desc_buf[] a variable-length array? If so, how big can
hba->desc_size.health_desc be? Can that number have a negative value?

> + return scnprintf(buf, PAGE_SIZE, "0x%02x", desc_buf[attr->bytes]);

Please check whether attr->bytes falls inside the bounds of the desc_buf[] array
before using that value as an index.

> +#define HEALTH_ATTR_RO(_name, _bytes)
> \
> +static struct health_attr ufs_health_##_name = { \
> + .attr = {.name = __stringify(_name), .mode = 0444}, \
> + .show = health_attr_show,   \
> + .bytes = _bytes,\
> +}
> +
> +HEALTH_ATTR_RO(length, 0);
> +HEALTH_ATTR_RO(type, 1);
> +HEALTH_ATTR_RO(eol, 2);
> +HEALTH_ATTR_RO(lifetimeA, 3);
> +HEALTH_ATTR_RO(lifetimeB, 4);

The above makes clear that the value stored in the structure member with the 
name
"bytes" represents an array index. Please choose a better name for that 
structure
member.

Additionally, since this patch introduces new sysfs attributes, why doesn't it
add any documentation under Documentation/ABI/?

Thanks,

Bart.

RE: crash in iscsi/scsi initiator with linux-4.15.0-rc1

2017-12-19 Thread Ewan D. Milne
On Tue, 2017-12-19 at 13:31 -0600, Steve Wise wrote:
> > > Hey,
> > >
> > > I'm  seeing this null pointer dereference with linux-4.15.0-rc1.  To 
> > > reproduce
> > > it, I connect two ram disks via iscsi/TCP, and start an fio:
> > >
> > > iscsiadm -m discovery --op update --type sendtargets -p 172.16.1.10:3260
> > > iscsiadm -m node -p 172.16.1.10:3260 -l
> > > ISCSI_DISKS=/dev/sdd:/dev/sde; fio --rw=randrw --name=random --
> > norandommap
> > > --ioengine=libaio --size=400m --group_reporting --exitall 
> > > --fsync_on_close=1
> > > --invalidate=1 --direct=1 --filename=$ISCSI_DISKS --time_based 
> > > --runtime=300
> > > --iodepth=128 --numjobs=8 --unit_base=1 --bs=64k --kb_base=1000
> > >
> > > Then on the initiator node, while the fio test is running, I detach the 
> > > devices:
> > >
> > > iscsiadm -m node -p 172.16.1.10:3260 -I iser -u
> > >
> > > Then I hit this crash.  Has anyone else encountered this issue?  
> > > Wondering if
> > > there is a fix handy. :)
> > >
> > 
> > This is the same problem that is being discussed under the thread:
> > "[PATCH] scsi: fix race condition when removing target".
> > 
> > We had good test results with both Jason Yan's patch and Bart's patch
> > applied, however the ultimate solution is still in progress, see James'
> > comments.
> > 
> > You could also try reverting fbce4d97fd "scsi: fixup kernel warning
> > during rmmod()" if you just need to get past this.
> > 
> > -Ewan
> > 
> 
> Hey Ewan, Yan, Bart, 
> 
> I'm still seeing this issue with 4.15-rc4.  Is the issue still outstanding?  
> 
> Steve.
> 

Please apply the following commit from the 4.15/scsi-fixes branch of

git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git

and advise if it does not fix your issue.  It should.



commit 81b6c999897919d5a16fedc018fe375dbab091c5
Author: Hannes Reinecke 
Date:   Wed Dec 13 14:21:37 2017 +0100

scsi: core: check for device state in __scsi_remove_target()

As it turned out device_get() doesn't use kref_get_unless_zero(), so we
will be always getting a device pointer.  Consequently, we need to check
for the device state in __scsi_remove_target() to avoid tripping over
deleted objects.

Fixes: fbce4d97fd43 ("scsi: fixup kernel warning during rmmod()")
Reported-by: Jason Yan 
Signed-off-by: Hannes Reinecke 
Reviewed-by: Bart Van Assche 
Reviewed-by: Ewan D. Milne 
Signed-off-by: Martin K. Petersen 

> ---
> 
> [ 1002.205103] BUG: unable to handle kernel NULL pointer dereference at   
> (null)
> [ 1002.213022] IP: _raw_spin_lock_irqsave+0x1e/0x40
> [ 1002.217740] PGD 0 P4D 0
> [ 1002.220382] Oops: 0002 [#1] SMP
> [ 1002.223637] Modules linked in: iw_cxgb4 cxgb4 nvme_rdma nvme_fabrics 
> rdma_ktest(O) rpcrdma ib_isert iscsi_target_mod ib_iser libiscsi 
> scsi_transport_iscsi ib_srpt target_core_mod ib_srp scsi_transport_srp 
> ib_ipoib rdma_ucm ib_ucm ib_uverbs ib_umad rdma_cm ib_cm iw_cm mlx4_ib 
> ib_core libcxgb vfat intel_rapl fat iosf_mbi x86_pkg_temp_thermal 
> intel_powerclamp coretemp kvm irqbypass crct10dif_pclmul crc32_pclmul 
> ghash_clmulni_intel pcbc aesni_intel crypto_simd glue_helper cryptd iTCO_wdt 
> iTCO_vendor_support mxm_wmi mei_me ipmi_si lpc_ich mei pcspkr i2c_i801 
> mfd_core ipmi_devintf shpchp sg ipmi_msghandler wmi nfsd auth_rpcgss nfs_acl 
> lockd grace sunrpc ip_tables ext4 mbcache jbd2 mlx4_en mgag200 drm_kms_helper 
> syscopyarea sysfillrect sysimgblt fb_sys_fops ttm sd_mod igb drm ahci libahci 
> dca mlx4_core
> [ 1002.295663]  ptp libata pps_core crc32c_intel nvme i2c_algo_bit i2c_core 
> nvme_core [last unloaded: cxgb4]
> [ 1002.305563] CPU: 4 PID: 5156 Comm: fio Tainted: G   O 
> 4.15.0-rc4 #3
> [ 1002.313223] Hardware name: Supermicro X9DR3-F/X9DR3-F, BIOS 3.2a 07/09/2015
> [ 1002.320555] RIP: 0010:_raw_spin_lock_irqsave+0x1e/0x40
> [ 1002.326077] RSP: 0018:c900070cbd10 EFLAGS: 00010046
> [ 1002.331692] RAX:  RBX: 0246 RCX: 
> 
> [ 1002.339225] RDX: 0001 RSI: 88085fd0e038 RDI: 
> 
> [ 1002.346763] RBP: 880855a65f18 R08:  R09: 
> 0744
> [ 1002.354315] R10: 03ff R11: 0001 R12: 
> 88084992e180
> [ 1002.361873] R13: 880855a67000 R14: 880855a65800 R15: 
> 880856d7d5a8
> [ 1002.369447] FS:  () GS:88085fd0() 
> knlGS:
> [ 1002.377995] CS:  0010 DS:  ES:  CR0: 80050033
> [ 1002.384209] CR2:  CR3: 01c09005 CR4: 
> 000606e0
> [ 1002.391826] Call Trace:
> [ 1002.394774]  scsi_device_dev_release_usercontext+0x40/0x230
> [ 1002.400858]  execute_in_process_context+0x58/0x60
> [ 1002.406085]  device_release+0x2d/0x80
> [ 1002.410277]  kobject_cleanup+0x5e/0x180
> [ 1002.414659]  scsi_disk_put+0x2b/0x40 

[PATCH 2/2] scsi: ufs: use sysfs entry for health info

2017-12-19 Thread Jaegeuk Kim
From: Jaegeuk Kim 

This patch introduces sysfs entries to show the information.

 # cat /sys/devices/soc/1da4000.ufshc/health/eol
 # cat /sys/devices/soc/1da4000.ufshc/health/length
 # cat /sys/devices/soc/1da4000.ufshc/health/lifetimeA
 # cat /sys/devices/soc/1da4000.ufshc/health/lifetimeB
 # cat /sys/devices/soc/1da4000.ufshc/health/type

struct desc_field_offset health_desc_field_name[] = {
{"bLength", 0x00, BYTE},
{"bDescriptorType", 0x01, BYTE},
{"bPreEOLInfo", 0x02, BYTE},
{"bDeviceLifeTimeEstA", 0x03, BYTE},
{"bDeviceLifeTimeEstB", 0x04, BYTE}
};

bPreEOLInfo
 - 00h: Not defined
 - 01h: Normal
 - 02h: Warning
 - 03h: Critical

bDeviceLifeTimeEstA
 - 00h: Not defined
 - 01h:  0% ~ 10% device life time used
 - 02h: 10% ~ 20% device life time used
 - 03h: 20% ~ 30% device life time used
 - 04h: 30% ~ 40% device life time used
 - 05h: 40% ~ 50% device life time used
 - 06h: 50% ~ 60% device life time used
 - 07h: 60% ~ 70% device life time used
 - 08h: 70% ~ 80% device life time used
 - 09h: 80% ~ 90% device life time used
 - 0Ah: 90% ~ 100% device life time used
 - 0Bh: Exceeded its maximum estimated device life time

Cc: Greg KH 
Signed-off-by: Jaegeuk Kim 
---
 drivers/scsi/ufs/ufs.h|  2 ++
 drivers/scsi/ufs/ufshcd.c | 66 ++-
 drivers/scsi/ufs/ufshcd.h |  1 +
 3 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 54deeb754db5..1af541d56c7d 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -154,6 +154,7 @@ enum desc_idn {
QUERY_DESC_IDN_RFU_1= 0x6,
QUERY_DESC_IDN_GEOMETRY = 0x7,
QUERY_DESC_IDN_POWER= 0x8,
+   QUERY_DESC_IDN_HEALTH   = 0x9,
QUERY_DESC_IDN_MAX,
 };
 
@@ -169,6 +170,7 @@ enum ufs_desc_def_size {
QUERY_DESC_INTERCONNECT_DEF_SIZE= 0x06,
QUERY_DESC_GEOMETRY_DEF_SIZE= 0x44,
QUERY_DESC_POWER_DEF_SIZE   = 0x62,
+   QUERY_DESC_HEALTH_DEF_SIZE  = 0x25,
 };
 
 /* Unit descriptor parameters offsets in bytes*/
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 12ff7daebb00..6809f1786efe 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -2991,6 +2991,9 @@ int ufshcd_map_desc_id_to_length(struct ufs_hba *hba,
case QUERY_DESC_IDN_RFU_1:
*desc_len = 0;
break;
+   case QUERY_DESC_IDN_HEALTH:
+   *desc_len = hba->desc_size.health_desc;
+   break;
default:
*desc_len = 0;
return -EINVAL;
@@ -6298,6 +6301,11 @@ static void ufshcd_init_desc_sizes(struct ufs_hba *hba)
>desc_size.geom_desc);
if (err)
hba->desc_size.geom_desc = QUERY_DESC_GEOMETRY_DEF_SIZE;
+
+   err = ufshcd_read_desc_length(hba, QUERY_DESC_IDN_HEALTH, 0,
+   >desc_size.health_desc);
+   if (err)
+   hba->desc_size.health_desc = QUERY_DESC_HEALTH_DEF_SIZE;
 }
 
 static void ufshcd_def_desc_sizes(struct ufs_hba *hba)
@@ -6308,6 +6316,7 @@ static void ufshcd_def_desc_sizes(struct ufs_hba *hba)
hba->desc_size.conf_desc = QUERY_DESC_CONFIGURATION_DEF_SIZE;
hba->desc_size.unit_desc = QUERY_DESC_UNIT_DEF_SIZE;
hba->desc_size.geom_desc = QUERY_DESC_GEOMETRY_DEF_SIZE;
+   hba->desc_size.health_desc = QUERY_DESC_HEALTH_DEF_SIZE;
 }
 
 /**
@@ -7688,14 +7697,69 @@ static const struct attribute_group ufshcd_attr_group = 
{
.attrs = ufshcd_attrs,
 };
 
+struct health_attr {
+   struct attribute attr;
+   ssize_t (*show)(struct device *dev,
+   struct health_attr *attr, char *buf);
+   int bytes;
+};
+
+static ssize_t health_attr_show(struct device *dev,
+   struct health_attr *attr, char *buf)
+{
+   struct ufs_hba *hba = dev_get_drvdata(dev);
+   int buff_len = hba->desc_size.health_desc;
+   u8 desc_buf[hba->desc_size.health_desc];
+   int err;
+
+   pm_runtime_get_sync(hba->dev);
+   err = ufshcd_read_desc(hba, QUERY_DESC_IDN_HEALTH, 0,
+   desc_buf, buff_len);
+   pm_runtime_put_sync(hba->dev);
+   if (err)
+   return 0;
+
+   return scnprintf(buf, PAGE_SIZE, "0x%02x", desc_buf[attr->bytes]);
+}
+
+#define HEALTH_ATTR_RO(_name, _bytes)  \
+static struct health_attr ufs_health_##_name = {   \
+   .attr = {.name = __stringify(_name), .mode = 0444}, \
+   .show = health_attr_show,   \
+   .bytes = _bytes,\
+}
+
+HEALTH_ATTR_RO(length, 0);
+HEALTH_ATTR_RO(type, 1);
+HEALTH_ATTR_RO(eol, 2);

[PATCH 1/2] scsi: ufs: introduce static sysfs entries

2017-12-19 Thread Jaegeuk Kim
From: Jaegeuk Kim 

This patch introduces attribute group to show existing sysfs entries.

Cc: Greg KH 
Signed-off-by: Jaegeuk Kim 
---
 drivers/scsi/ufs/ufshcd.c | 48 +++
 drivers/scsi/ufs/ufshcd.h |  2 --
 2 files changed, 19 insertions(+), 31 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 011c3369082c..12ff7daebb00 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -7605,7 +7605,7 @@ static inline ssize_t ufshcd_pm_lvl_store(struct device 
*dev,
return count;
 }
 
-static ssize_t ufshcd_rpm_lvl_show(struct device *dev,
+static ssize_t rpm_lvl_show(struct device *dev,
struct device_attribute *attr, char *buf)
 {
struct ufs_hba *hba = dev_get_drvdata(dev);
@@ -7634,24 +7634,13 @@ static ssize_t ufshcd_rpm_lvl_show(struct device *dev,
return curr_len;
 }
 
-static ssize_t ufshcd_rpm_lvl_store(struct device *dev,
+static ssize_t rpm_lvl_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
 {
return ufshcd_pm_lvl_store(dev, attr, buf, count, true);
 }
 
-static void ufshcd_add_rpm_lvl_sysfs_nodes(struct ufs_hba *hba)
-{
-   hba->rpm_lvl_attr.show = ufshcd_rpm_lvl_show;
-   hba->rpm_lvl_attr.store = ufshcd_rpm_lvl_store;
-   sysfs_attr_init(>rpm_lvl_attr.attr);
-   hba->rpm_lvl_attr.attr.name = "rpm_lvl";
-   hba->rpm_lvl_attr.attr.mode = 0644;
-   if (device_create_file(hba->dev, >rpm_lvl_attr))
-   dev_err(hba->dev, "Failed to create sysfs for rpm_lvl\n");
-}
-
-static ssize_t ufshcd_spm_lvl_show(struct device *dev,
+static ssize_t spm_lvl_show(struct device *dev,
struct device_attribute *attr, char *buf)
 {
struct ufs_hba *hba = dev_get_drvdata(dev);
@@ -7680,33 +7669,34 @@ static ssize_t ufshcd_spm_lvl_show(struct device *dev,
return curr_len;
 }
 
-static ssize_t ufshcd_spm_lvl_store(struct device *dev,
+static ssize_t spm_lvl_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
 {
return ufshcd_pm_lvl_store(dev, attr, buf, count, false);
 }
 
-static void ufshcd_add_spm_lvl_sysfs_nodes(struct ufs_hba *hba)
-{
-   hba->spm_lvl_attr.show = ufshcd_spm_lvl_show;
-   hba->spm_lvl_attr.store = ufshcd_spm_lvl_store;
-   sysfs_attr_init(>spm_lvl_attr.attr);
-   hba->spm_lvl_attr.attr.name = "spm_lvl";
-   hba->spm_lvl_attr.attr.mode = 0644;
-   if (device_create_file(hba->dev, >spm_lvl_attr))
-   dev_err(hba->dev, "Failed to create sysfs for spm_lvl\n");
-}
+static DEVICE_ATTR_RW(rpm_lvl);
+static DEVICE_ATTR_RW(spm_lvl);
+
+static struct attribute *ufshcd_attrs[] = {
+   _attr_rpm_lvl.attr,
+   _attr_spm_lvl.attr,
+   NULL
+};
+
+static const struct attribute_group ufshcd_attr_group = {
+   .attrs = ufshcd_attrs,
+};
 
 static inline void ufshcd_add_sysfs_nodes(struct ufs_hba *hba)
 {
-   ufshcd_add_rpm_lvl_sysfs_nodes(hba);
-   ufshcd_add_spm_lvl_sysfs_nodes(hba);
+   if (sysfs_create_group(>dev->kobj, _attr_group))
+   dev_err(hba->dev, "Failed to create sysfs group\n");
 }
 
 static inline void ufshcd_remove_sysfs_nodes(struct ufs_hba *hba)
 {
-   device_remove_file(hba->dev, >rpm_lvl_attr);
-   device_remove_file(hba->dev, >spm_lvl_attr);
+   sysfs_remove_group(>dev->kobj, _attr_group);
 }
 
 /**
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 1332e544da92..56e26eb15185 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -526,8 +526,6 @@ struct ufs_hba {
enum ufs_pm_level rpm_lvl;
/* Desired UFS power management level during system PM */
enum ufs_pm_level spm_lvl;
-   struct device_attribute rpm_lvl_attr;
-   struct device_attribute spm_lvl_attr;
int pm_op_in_progress;
 
struct ufshcd_lrb *lrb;
-- 
2.15.0.531.g2ccb3012c9-goog



RE: crash in iscsi/scsi initiator with linux-4.15.0-rc1

2017-12-19 Thread Steve Wise
> > Hey,
> >
> > I'm  seeing this null pointer dereference with linux-4.15.0-rc1.  To 
> > reproduce
> > it, I connect two ram disks via iscsi/TCP, and start an fio:
> >
> > iscsiadm -m discovery --op update --type sendtargets -p 172.16.1.10:3260
> > iscsiadm -m node -p 172.16.1.10:3260 -l
> > ISCSI_DISKS=/dev/sdd:/dev/sde; fio --rw=randrw --name=random --
> norandommap
> > --ioengine=libaio --size=400m --group_reporting --exitall --fsync_on_close=1
> > --invalidate=1 --direct=1 --filename=$ISCSI_DISKS --time_based --runtime=300
> > --iodepth=128 --numjobs=8 --unit_base=1 --bs=64k --kb_base=1000
> >
> > Then on the initiator node, while the fio test is running, I detach the 
> > devices:
> >
> > iscsiadm -m node -p 172.16.1.10:3260 -I iser -u
> >
> > Then I hit this crash.  Has anyone else encountered this issue?  Wondering 
> > if
> > there is a fix handy. :)
> >
> 
> This is the same problem that is being discussed under the thread:
> "[PATCH] scsi: fix race condition when removing target".
> 
> We had good test results with both Jason Yan's patch and Bart's patch
> applied, however the ultimate solution is still in progress, see James'
> comments.
> 
> You could also try reverting fbce4d97fd "scsi: fixup kernel warning
> during rmmod()" if you just need to get past this.
> 
> -Ewan
> 

Hey Ewan, Yan, Bart, 

I'm still seeing this issue with 4.15-rc4.  Is the issue still outstanding?  

Steve.

---

[ 1002.205103] BUG: unable to handle kernel NULL pointer dereference at 
  (null)
[ 1002.213022] IP: _raw_spin_lock_irqsave+0x1e/0x40
[ 1002.217740] PGD 0 P4D 0
[ 1002.220382] Oops: 0002 [#1] SMP
[ 1002.223637] Modules linked in: iw_cxgb4 cxgb4 nvme_rdma nvme_fabrics 
rdma_ktest(O) rpcrdma ib_isert iscsi_target_mod ib_iser libiscsi 
scsi_transport_iscsi ib_srpt target_core_mod ib_srp scsi_transport_srp ib_ipoib 
rdma_ucm ib_ucm ib_uverbs ib_umad rdma_cm ib_cm iw_cm mlx4_ib ib_core libcxgb 
vfat intel_rapl fat iosf_mbi x86_pkg_temp_thermal intel_powerclamp coretemp kvm 
irqbypass crct10dif_pclmul crc32_pclmul ghash_clmulni_intel pcbc aesni_intel 
crypto_simd glue_helper cryptd iTCO_wdt iTCO_vendor_support mxm_wmi mei_me 
ipmi_si lpc_ich mei pcspkr i2c_i801 mfd_core ipmi_devintf shpchp sg 
ipmi_msghandler wmi nfsd auth_rpcgss nfs_acl lockd grace sunrpc ip_tables ext4 
mbcache jbd2 mlx4_en mgag200 drm_kms_helper syscopyarea sysfillrect sysimgblt 
fb_sys_fops ttm sd_mod igb drm ahci libahci dca mlx4_core
[ 1002.295663]  ptp libata pps_core crc32c_intel nvme i2c_algo_bit i2c_core 
nvme_core [last unloaded: cxgb4]
[ 1002.305563] CPU: 4 PID: 5156 Comm: fio Tainted: G   O 4.15.0-rc4 
#3
[ 1002.313223] Hardware name: Supermicro X9DR3-F/X9DR3-F, BIOS 3.2a 07/09/2015
[ 1002.320555] RIP: 0010:_raw_spin_lock_irqsave+0x1e/0x40
[ 1002.326077] RSP: 0018:c900070cbd10 EFLAGS: 00010046
[ 1002.331692] RAX:  RBX: 0246 RCX: 
[ 1002.339225] RDX: 0001 RSI: 88085fd0e038 RDI: 
[ 1002.346763] RBP: 880855a65f18 R08:  R09: 0744
[ 1002.354315] R10: 03ff R11: 0001 R12: 88084992e180
[ 1002.361873] R13: 880855a67000 R14: 880855a65800 R15: 880856d7d5a8
[ 1002.369447] FS:  () GS:88085fd0() 
knlGS:
[ 1002.377995] CS:  0010 DS:  ES:  CR0: 80050033
[ 1002.384209] CR2:  CR3: 01c09005 CR4: 000606e0
[ 1002.391826] Call Trace:
[ 1002.394774]  scsi_device_dev_release_usercontext+0x40/0x230
[ 1002.400858]  execute_in_process_context+0x58/0x60
[ 1002.406085]  device_release+0x2d/0x80
[ 1002.410277]  kobject_cleanup+0x5e/0x180
[ 1002.414659]  scsi_disk_put+0x2b/0x40 [sd_mod]
[ 1002.419559]  __blkdev_put+0x1b5/0x1d0
[ 1002.423777]  ? disk_flush_events+0x24/0x60
[ 1002.428430]  blkdev_close+0x21/0x30
[ 1002.432484]  __fput+0xd5/0x210
[ 1002.436111]  task_work_run+0x82/0xa0
[ 1002.440262]  do_exit+0x2be/0xb20
[ 1002.444074]  ? syscall_trace_enter+0x1af/0x290
[ 1002.449110]  do_group_exit+0x39/0xa0
[ 1002.453287]  SyS_exit_group+0x10/0x10
[ 1002.457557]  do_syscall_64+0x61/0x1a0
[ 1002.461829]  entry_SYSCALL64_slow_path+0x25/0x25
[ 1002.467064] RIP: 0033:0x7f9abb1c8529
[ 1002.471266] RSP: 002b:7ffe53be40d8 EFLAGS: 0206 ORIG_RAX: 
00e7
[ 1002.479482] RAX: ffda RBX: 0010 RCX: 7f9abb1c8529
[ 1002.487279] RDX: 0005 RSI: 000a RDI: 0005
[ 1002.495079] RBP: 7f9a9c9de818 R08: 003c R09: 00e7
[ 1002.502882] R10: ff60 R11: 0206 R12: 0006
[ 1002.510690] R13: 0006 R14:  R15: 0172a440
[ 1002.518497] Code: f4 66 90 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 53 
9c 58 66 66 90 66 90 48 89 c3 fa 66 66 90 66 66 90 31 c0 ba 01 00 00 00  0f 
b1 17 85 c0 75 05 48 89 d8 5b c3 89 c6 e8 77 06 9e ff eb
[ 1002.538742] RIP: 

Re: [-next PATCH 0/4] sysfs and DEVICE_ATTR_

2017-12-19 Thread Corey Minyard

On 12/19/2017 12:15 PM, Joe Perches wrote:

  drivers/char/ipmi/ipmi_msghandler.c| 17 +++---


For ipmi:

Acked-by: Corey Minyard 



[PATCH] lpfc: correct sg_seg_cnt attribute min vs default

2017-12-19 Thread James Smart
Prior patch mixed up what argument in the macro was what, so min
value was placed as the "default" argument, and the default value
was placed as the "min" argument. Thus, when the default was applied,
it looked like the default was smaller than the allowed min.

swap argument postions to correct.

Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_attr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 797bb42a6306..8938c867ed2c 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -5174,7 +5174,7 @@ LPFC_ATTR(delay_discovery, 0, 0, 1,
  * this parameter will be limited to 128 if BlockGuard is enabled under SLI4
  * and will be limited to 512 if BlockGuard is enabled under SLI3.
  */
-LPFC_ATTR_R(sg_seg_cnt, LPFC_MIN_SG_SEG_CNT, LPFC_DEFAULT_SG_SEG_CNT,
+LPFC_ATTR_R(sg_seg_cnt, LPFC_DEFAULT_SG_SEG_CNT, LPFC_MIN_SG_SEG_CNT, 
LPFC_MAX_SG_SEG_CNT, "Max Scatter Gather Segment Count");
 
 /*
-- 
2.13.1



Re: [-next PATCH 0/4] sysfs and DEVICE_ATTR_

2017-12-19 Thread Jani Nikula
On Tue, 19 Dec 2017, Joe Perches  wrote:
>  drivers/gpu/drm/i915/i915_sysfs.c  | 12 ++--

For i915,

Acked-by: Jani Nikula 


-- 
Jani Nikula, Intel Open Source Technology Center


Re: [-next PATCH 4/4] treewide: Use DEVICE_ATTR_WO

2017-12-19 Thread Borislav Petkov
On Tue, Dec 19, 2017 at 10:51:14AM -0800, Joe Perches wrote:
> > The reason for the code churn being?
> 
> Consistency for easier grep by use-type.

Please explain that in the commit message so that we know why it was
changed.

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.


Re: [-next PATCH 4/4] treewide: Use DEVICE_ATTR_WO

2017-12-19 Thread Joe Perches
On Tue, 2017-12-19 at 19:44 +0100, Borislav Petkov wrote:
> On Tue, Dec 19, 2017 at 10:15:09AM -0800, Joe Perches wrote:
> > Convert DEVICE_ATTR uses to DEVICE_ATTR_WO where possible.
> > 
> > Done with perl script:
> > 
> > $ git grep -w --name-only DEVICE_ATTR | \
> >   xargs perl -i -e 'local $/; while (<>) { 
> > s/\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?(?:\s*S_IWUSR\s*|\s*0200\s*)\)?\s*,\s*NULL\s*,\s*\s_store\s*\)/DEVICE_ATTR_WO(\1)/g;
> >  print;}'
[]
> > diff --git a/arch/x86/kernel/cpu/microcode/core.c 
> > b/arch/x86/kernel/cpu/microcode/core.c
[]
> > @@ -560,7 +560,7 @@ static ssize_t pf_show(struct device *dev,
> > return sprintf(buf, "0x%x\n", uci->cpu_sig.pf);
> >  }
> >  
> > -static DEVICE_ATTR(reload, 0200, NULL, reload_store);
> > +static DEVICE_ATTR_WO(reload);
> >  static DEVICE_ATTR(version, 0400, version_show, NULL);
> >  static DEVICE_ATTR(processor_flags, 0400, pf_show, NULL);
> >  
> 
> # cat /sys/devices/system/cpu/microcode/reload
> cat: /sys/devices/system/cpu/microcode/reload: Permission denied

Not different behavior.  It was and remains write only.

> The reason for the code churn being?

Consistency for easier grep by use-type.




Re: [-next PATCH 4/4] treewide: Use DEVICE_ATTR_WO

2017-12-19 Thread Borislav Petkov
On Tue, Dec 19, 2017 at 10:15:09AM -0800, Joe Perches wrote:
> Convert DEVICE_ATTR uses to DEVICE_ATTR_WO where possible.
> 
> Done with perl script:
> 
> $ git grep -w --name-only DEVICE_ATTR | \
>   xargs perl -i -e 'local $/; while (<>) { 
> s/\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?(?:\s*S_IWUSR\s*|\s*0200\s*)\)?\s*,\s*NULL\s*,\s*\s_store\s*\)/DEVICE_ATTR_WO(\1)/g;
>  print;}'
> 
> Signed-off-by: Joe Perches 
> ---
>  arch/s390/kernel/smp.c | 2 +-
>  arch/x86/kernel/cpu/microcode/core.c   | 2 +-
>  drivers/input/touchscreen/elants_i2c.c | 2 +-
>  drivers/net/ethernet/ibm/ibmvnic.c | 2 +-
>  drivers/net/wimax/i2400m/sysfs.c   | 3 +--
>  drivers/scsi/lpfc/lpfc_attr.c  | 3 +--
>  drivers/thermal/thermal_sysfs.c| 2 +-
>  7 files changed, 7 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
> index b8c1a85bcf2d..a919b2f0141d 100644
> --- a/arch/s390/kernel/smp.c
> +++ b/arch/s390/kernel/smp.c
> @@ -1151,7 +1151,7 @@ static ssize_t __ref rescan_store(struct device *dev,
>   rc = smp_rescan_cpus();
>   return rc ? rc : count;
>  }
> -static DEVICE_ATTR(rescan, 0200, NULL, rescan_store);
> +static DEVICE_ATTR_WO(rescan);
>  #endif /* CONFIG_HOTPLUG_CPU */
>  
>  static int __init s390_smp_init(void)
> diff --git a/arch/x86/kernel/cpu/microcode/core.c 
> b/arch/x86/kernel/cpu/microcode/core.c
> index c4fa4a85d4cb..09c74b0560dd 100644
> --- a/arch/x86/kernel/cpu/microcode/core.c
> +++ b/arch/x86/kernel/cpu/microcode/core.c
> @@ -560,7 +560,7 @@ static ssize_t pf_show(struct device *dev,
>   return sprintf(buf, "0x%x\n", uci->cpu_sig.pf);
>  }
>  
> -static DEVICE_ATTR(reload, 0200, NULL, reload_store);
> +static DEVICE_ATTR_WO(reload);
>  static DEVICE_ATTR(version, 0400, version_show, NULL);
>  static DEVICE_ATTR(processor_flags, 0400, pf_show, NULL);
>  

# cat /sys/devices/system/cpu/microcode/reload
cat: /sys/devices/system/cpu/microcode/reload: Permission denied

The reason for the code churn being?

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.


Re: [-next PATCH 2/4] treewide: Use DEVICE_ATTR_RW

2017-12-19 Thread Andy Shevchenko
On Tue, Dec 19, 2017 at 8:15 PM, Joe Perches  wrote:
> Convert DEVICE_ATTR uses to DEVICE_ATTR_RW where possible.
>
> Done with perl script:
>
> $ git grep -w --name-only DEVICE_ATTR | \
>   xargs perl -i -e 'local $/; while (<>) { 
> s/\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?(\s*S_IRUGO\s*\|\s*S_IWUSR|\s*S_IWUSR\s*\|\s*S_IRUGO\s*|\s*0644\s*)\)?\s*,\s*\1_show\s*,\s*\1_store\s*\)/DEVICE_ATTR_RW(\1)/g;
>  print;}'

>  drivers/platform/x86/compal-laptop.c | 18 +--

> --- a/drivers/platform/x86/compal-laptop.c
> +++ b/drivers/platform/x86/compal-laptop.c
> @@ -679,18 +679,12 @@ static int bat_writeable_property(struct power_supply 
> *psy,
>  /* == */
>  /* Driver Globals */
>  /* == */
> -static DEVICE_ATTR(wake_up_pme,
> -   0644, wake_up_pme_show, wake_up_pme_store);
> -static DEVICE_ATTR(wake_up_modem,
> -   0644, wake_up_modem_show,   wake_up_modem_store);
> -static DEVICE_ATTR(wake_up_lan,
> -   0644, wake_up_lan_show, wake_up_lan_store);
> -static DEVICE_ATTR(wake_up_wlan,
> -   0644, wake_up_wlan_show,wake_up_wlan_store);
> -static DEVICE_ATTR(wake_up_key,
> -   0644, wake_up_key_show, wake_up_key_store);
> -static DEVICE_ATTR(wake_up_mouse,
> -   0644, wake_up_mouse_show,   wake_up_mouse_store);
> +static DEVICE_ATTR_RW(wake_up_pme);
> +static DEVICE_ATTR_RW(wake_up_modem);
> +static DEVICE_ATTR_RW(wake_up_lan);
> +static DEVICE_ATTR_RW(wake_up_wlan);
> +static DEVICE_ATTR_RW(wake_up_key);
> +static DEVICE_ATTR_RW(wake_up_mouse);

Acked-by: Andy Shevchenko 

for PDx86 bits.

Have to say that while it doesn't change the attributes here, it might
require still to be revisited by security people, if they wish.

-- 
With Best Regards,
Andy Shevchenko


Re: [PATCH] scsi: storvsc: Fix scsi_cmd error assignments in storvsc_handle_error

2017-12-19 Thread Stephen Hemminger
On Tue, 19 Dec 2017 13:32:48 -0500
Cathy Avery  wrote:

> When an I/O is returned with an srb_status of SRB_STATUS_INVALID_LUN
> which has zero good_bytes it must be assigned an error. Otherwise
> the I/O will be continuously requeued and will cause a deadlock in the
> case where disks are being hot added and removed. sd_probe_async will
> wait forever for its I/O to complete while holding scsi_sd_probe_domain.
> 
> Also returning the default error of DID_TARGET_FAILURE causes
> multipath to not retry the I/O resulting in applications receiving I/O
> errors before a failover can occur.
> 
> Signed-off-by: Cathy Avery 
> Signed-off-by: Long Li 

When working on the DVD probe issue I saw that error handling was
problematic. Thanks for fixing.

Reviewed-by: Stephen Hemminger 


[PATCH] scsi: storvsc: Fix scsi_cmd error assignments in storvsc_handle_error

2017-12-19 Thread Cathy Avery
When an I/O is returned with an srb_status of SRB_STATUS_INVALID_LUN
which has zero good_bytes it must be assigned an error. Otherwise
the I/O will be continuously requeued and will cause a deadlock in the
case where disks are being hot added and removed. sd_probe_async will
wait forever for its I/O to complete while holding scsi_sd_probe_domain.

Also returning the default error of DID_TARGET_FAILURE causes
multipath to not retry the I/O resulting in applications receiving I/O
errors before a failover can occur.

Signed-off-by: Cathy Avery 
Signed-off-by: Long Li 
---
 drivers/scsi/storvsc_drv.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 1b06cf0..3b3d1d0 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -953,10 +953,11 @@ static void storvsc_handle_error(struct vmscsi_request 
*vm_srb,
case TEST_UNIT_READY:
break;
default:
-   set_host_byte(scmnd, DID_TARGET_FAILURE);
+   set_host_byte(scmnd, DID_ERROR);
}
break;
case SRB_STATUS_INVALID_LUN:
+   set_host_byte(scmnd, DID_NO_CONNECT);
do_work = true;
process_err_fn = storvsc_remove_lun;
break;
-- 
2.5.0



[-next PATCH 0/4] sysfs and DEVICE_ATTR_

2017-12-19 Thread Joe Perches
Joe Perches (4):
  sysfs.h: Use octal permissions
  treewide: Use DEVICE_ATTR_RW
  treewide: Use DEVICE_ATTR_RO
  treewide: Use DEVICE_ATTR_WO

 arch/arm/mach-pxa/sharpsl_pm.c |  4 +-
 arch/s390/kernel/smp.c |  2 +-
 arch/s390/kernel/topology.c|  3 +-
 arch/sh/drivers/push-switch.c  |  2 +-
 arch/tile/kernel/sysfs.c   | 12 ++--
 arch/x86/kernel/cpu/microcode/core.c   |  2 +-
 drivers/acpi/device_sysfs.c|  6 +-
 drivers/char/ipmi/ipmi_msghandler.c| 17 +++---
 drivers/gpu/drm/i915/i915_sysfs.c  | 12 ++--
 drivers/input/touchscreen/elants_i2c.c |  2 +-
 drivers/net/ethernet/ibm/ibmvnic.c |  2 +-
 drivers/net/wimax/i2400m/sysfs.c   |  3 +-
 drivers/nvme/host/core.c   | 10 ++--
 drivers/platform/x86/compal-laptop.c   | 18 ++
 drivers/s390/cio/css.c |  8 +--
 drivers/s390/cio/device.c  | 10 ++--
 drivers/s390/crypto/ap_card.c  |  2 +-
 drivers/scsi/hpsa.c| 10 ++--
 drivers/scsi/lpfc/lpfc_attr.c  | 64 --
 .../staging/media/atomisp/pci/atomisp2/hmm/hmm.c   |  8 +--
 drivers/thermal/thermal_sysfs.c| 17 +++---
 drivers/tty/serial/sh-sci.c|  2 +-
 drivers/usb/host/xhci-dbgcap.c |  2 +-
 drivers/usb/phy/phy-tahvo.c|  2 +-
 drivers/video/fbdev/auo_k190x.c|  4 +-
 drivers/video/fbdev/w100fb.c   |  4 +-
 include/linux/sysfs.h  | 14 ++---
 lib/test_firmware.c| 14 ++---
 lib/test_kmod.c| 14 ++---
 sound/soc/omap/mcbsp.c |  4 +-
 sound/soc/soc-core.c   |  2 +-
 sound/soc/soc-dapm.c   |  2 +-
 32 files changed, 120 insertions(+), 158 deletions(-)

-- 
2.15.0



[-next PATCH 4/4] treewide: Use DEVICE_ATTR_WO

2017-12-19 Thread Joe Perches
Convert DEVICE_ATTR uses to DEVICE_ATTR_WO where possible.

Done with perl script:

$ git grep -w --name-only DEVICE_ATTR | \
  xargs perl -i -e 'local $/; while (<>) { 
s/\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?(?:\s*S_IWUSR\s*|\s*0200\s*)\)?\s*,\s*NULL\s*,\s*\s_store\s*\)/DEVICE_ATTR_WO(\1)/g;
 print;}'

Signed-off-by: Joe Perches 
---
 arch/s390/kernel/smp.c | 2 +-
 arch/x86/kernel/cpu/microcode/core.c   | 2 +-
 drivers/input/touchscreen/elants_i2c.c | 2 +-
 drivers/net/ethernet/ibm/ibmvnic.c | 2 +-
 drivers/net/wimax/i2400m/sysfs.c   | 3 +--
 drivers/scsi/lpfc/lpfc_attr.c  | 3 +--
 drivers/thermal/thermal_sysfs.c| 2 +-
 7 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index b8c1a85bcf2d..a919b2f0141d 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -1151,7 +1151,7 @@ static ssize_t __ref rescan_store(struct device *dev,
rc = smp_rescan_cpus();
return rc ? rc : count;
 }
-static DEVICE_ATTR(rescan, 0200, NULL, rescan_store);
+static DEVICE_ATTR_WO(rescan);
 #endif /* CONFIG_HOTPLUG_CPU */
 
 static int __init s390_smp_init(void)
diff --git a/arch/x86/kernel/cpu/microcode/core.c 
b/arch/x86/kernel/cpu/microcode/core.c
index c4fa4a85d4cb..09c74b0560dd 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -560,7 +560,7 @@ static ssize_t pf_show(struct device *dev,
return sprintf(buf, "0x%x\n", uci->cpu_sig.pf);
 }
 
-static DEVICE_ATTR(reload, 0200, NULL, reload_store);
+static DEVICE_ATTR_WO(reload);
 static DEVICE_ATTR(version, 0400, version_show, NULL);
 static DEVICE_ATTR(processor_flags, 0400, pf_show, NULL);
 
diff --git a/drivers/input/touchscreen/elants_i2c.c 
b/drivers/input/touchscreen/elants_i2c.c
index a458e5ec9e41..819213e88f32 100644
--- a/drivers/input/touchscreen/elants_i2c.c
+++ b/drivers/input/touchscreen/elants_i2c.c
@@ -1000,7 +1000,7 @@ static ssize_t show_iap_mode(struct device *dev,
"Normal" : "Recovery");
 }
 
-static DEVICE_ATTR(calibrate, S_IWUSR, NULL, calibrate_store);
+static DEVICE_ATTR_WO(calibrate);
 static DEVICE_ATTR(iap_mode, S_IRUGO, show_iap_mode, NULL);
 static DEVICE_ATTR(update_fw, S_IWUSR, NULL, write_update_fw);
 
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 1dc4aef37d3a..42b96e1a1b13 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -4411,7 +4411,7 @@ static ssize_t failover_store(struct device *dev, struct 
device_attribute *attr,
return count;
 }
 
-static DEVICE_ATTR(failover, 0200, NULL, failover_store);
+static DEVICE_ATTR_WO(failover);
 
 static unsigned long ibmvnic_get_desired_dma(struct vio_dev *vdev)
 {
diff --git a/drivers/net/wimax/i2400m/sysfs.c b/drivers/net/wimax/i2400m/sysfs.c
index 1237109f251a..8c67df11105c 100644
--- a/drivers/net/wimax/i2400m/sysfs.c
+++ b/drivers/net/wimax/i2400m/sysfs.c
@@ -65,8 +65,7 @@ ssize_t i2400m_idle_timeout_store(struct device *dev,
 }
 
 static
-DEVICE_ATTR(i2400m_idle_timeout, S_IWUSR,
-   NULL, i2400m_idle_timeout_store);
+DEVICE_ATTR_WO(i2400m_idle_timeout);
 
 static
 struct attribute *i2400m_dev_attrs[] = {
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 517ff203cfde..6ddaf51a23f6 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -2418,8 +2418,7 @@ lpfc_soft_wwn_enable_store(struct device *dev, struct 
device_attribute *attr,
 
return count;
 }
-static DEVICE_ATTR(lpfc_soft_wwn_enable, S_IWUSR, NULL,
-  lpfc_soft_wwn_enable_store);
+static DEVICE_ATTR_WO(lpfc_soft_wwn_enable);
 
 /**
  * lpfc_soft_wwpn_show - Return the cfg soft ww port name of the adapter
diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c
index 2bc964392924..ba81c9080f6e 100644
--- a/drivers/thermal/thermal_sysfs.c
+++ b/drivers/thermal/thermal_sysfs.c
@@ -317,7 +317,7 @@ emul_temp_store(struct device *dev, struct device_attribute 
*attr,
 
return ret ? ret : count;
 }
-static DEVICE_ATTR(emul_temp, S_IWUSR, NULL, emul_temp_store);
+static DEVICE_ATTR_WO(emul_temp);
 #endif
 
 static ssize_t
-- 
2.15.0



[-next PATCH 2/4] treewide: Use DEVICE_ATTR_RW

2017-12-19 Thread Joe Perches
Convert DEVICE_ATTR uses to DEVICE_ATTR_RW where possible.

Done with perl script:

$ git grep -w --name-only DEVICE_ATTR | \
  xargs perl -i -e 'local $/; while (<>) { 
s/\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?(\s*S_IRUGO\s*\|\s*S_IWUSR|\s*S_IWUSR\s*\|\s*S_IRUGO\s*|\s*0644\s*)\)?\s*,\s*\1_show\s*,\s*\1_store\s*\)/DEVICE_ATTR_RW(\1)/g;
 print;}'

Signed-off-by: Joe Perches 
---
 arch/s390/kernel/topology.c  |  3 +--
 arch/tile/kernel/sysfs.c |  2 +-
 drivers/gpu/drm/i915/i915_sysfs.c|  6 ++---
 drivers/platform/x86/compal-laptop.c | 18 +--
 drivers/s390/cio/device.c|  2 +-
 drivers/scsi/lpfc/lpfc_attr.c| 43 
 drivers/thermal/thermal_sysfs.c  |  9 
 drivers/tty/serial/sh-sci.c  |  2 +-
 drivers/usb/host/xhci-dbgcap.c   |  2 +-
 drivers/usb/phy/phy-tahvo.c  |  2 +-
 drivers/video/fbdev/auo_k190x.c  |  4 ++--
 drivers/video/fbdev/w100fb.c |  4 ++--
 lib/test_firmware.c  | 14 +---
 lib/test_kmod.c  | 14 +---
 sound/soc/omap/mcbsp.c   |  4 ++--
 15 files changed, 49 insertions(+), 80 deletions(-)

diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index 4d5b65e527b5..4b6e0397f66d 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -404,8 +404,7 @@ static ssize_t dispatching_store(struct device *dev,
put_online_cpus();
return rc ? rc : count;
 }
-static DEVICE_ATTR(dispatching, 0644, dispatching_show,
-dispatching_store);
+static DEVICE_ATTR_RW(dispatching);
 
 static ssize_t cpu_polarization_show(struct device *dev,
 struct device_attribute *attr, char *buf)
diff --git a/arch/tile/kernel/sysfs.c b/arch/tile/kernel/sysfs.c
index 825867c53853..af5024f0fb5a 100644
--- a/arch/tile/kernel/sysfs.c
+++ b/arch/tile/kernel/sysfs.c
@@ -184,7 +184,7 @@ static ssize_t hv_stats_store(struct device *dev,
return n < 0 ? n : count;
 }
 
-static DEVICE_ATTR(hv_stats, 0644, hv_stats_show, hv_stats_store);
+static DEVICE_ATTR_RW(hv_stats);
 
 static int hv_stats_device_add(struct device *dev, struct subsys_interface 
*sif)
 {
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c 
b/drivers/gpu/drm/i915/i915_sysfs.c
index c74a20b80182..1d0ab8ff5915 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -447,9 +447,9 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
 
 static DEVICE_ATTR(gt_act_freq_mhz, S_IRUGO, gt_act_freq_mhz_show, NULL);
 static DEVICE_ATTR(gt_cur_freq_mhz, S_IRUGO, gt_cur_freq_mhz_show, NULL);
-static DEVICE_ATTR(gt_boost_freq_mhz, S_IRUGO | S_IWUSR, 
gt_boost_freq_mhz_show, gt_boost_freq_mhz_store);
-static DEVICE_ATTR(gt_max_freq_mhz, S_IRUGO | S_IWUSR, gt_max_freq_mhz_show, 
gt_max_freq_mhz_store);
-static DEVICE_ATTR(gt_min_freq_mhz, S_IRUGO | S_IWUSR, gt_min_freq_mhz_show, 
gt_min_freq_mhz_store);
+static DEVICE_ATTR_RW(gt_boost_freq_mhz);
+static DEVICE_ATTR_RW(gt_max_freq_mhz);
+static DEVICE_ATTR_RW(gt_min_freq_mhz);
 
 static DEVICE_ATTR(vlv_rpe_freq_mhz, S_IRUGO, vlv_rpe_freq_mhz_show, NULL);
 
diff --git a/drivers/platform/x86/compal-laptop.c 
b/drivers/platform/x86/compal-laptop.c
index 6bcb750e1865..4f9bc72f0584 100644
--- a/drivers/platform/x86/compal-laptop.c
+++ b/drivers/platform/x86/compal-laptop.c
@@ -679,18 +679,12 @@ static int bat_writeable_property(struct power_supply 
*psy,
 /* == */
 /* Driver Globals */
 /* == */
-static DEVICE_ATTR(wake_up_pme,
-   0644, wake_up_pme_show, wake_up_pme_store);
-static DEVICE_ATTR(wake_up_modem,
-   0644, wake_up_modem_show,   wake_up_modem_store);
-static DEVICE_ATTR(wake_up_lan,
-   0644, wake_up_lan_show, wake_up_lan_store);
-static DEVICE_ATTR(wake_up_wlan,
-   0644, wake_up_wlan_show,wake_up_wlan_store);
-static DEVICE_ATTR(wake_up_key,
-   0644, wake_up_key_show, wake_up_key_store);
-static DEVICE_ATTR(wake_up_mouse,
-   0644, wake_up_mouse_show,   wake_up_mouse_store);
+static DEVICE_ATTR_RW(wake_up_pme);
+static DEVICE_ATTR_RW(wake_up_modem);
+static DEVICE_ATTR_RW(wake_up_lan);
+static DEVICE_ATTR_RW(wake_up_wlan);
+static DEVICE_ATTR_RW(wake_up_key);
+static DEVICE_ATTR_RW(wake_up_mouse);
 
 static DEVICE_ATTR(fan1_input,  S_IRUGO, fan_show,  NULL);
 static DEVICE_ATTR(temp1_input, S_IRUGO, temp_cpu,  NULL);
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 75a245f38e2e..6eefb67b31f3 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -600,7 +600,7 @@ static ssize_t vpm_show(struct device *dev, struct 
device_attribute *attr,
 static DEVICE_ATTR(devtype, 0444, devtype_show, NULL);
 static DEVICE_ATTR(cutype, 0444, cutype_show, NULL);
 static DEVICE_ATTR(modalias, 0444, modalias_show, 

[-next PATCH 3/4] treewide: Use DEVICE_ATTR_RO

2017-12-19 Thread Joe Perches
Convert DEVICE_ATTR uses to DEVICE_ATTR_RO where possible.

Done with perl script:

$ git grep -w --name-only DEVICE_ATTR | \
  xargs perl -i -e 'local $/; while (<>) { 
s/\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?(?:\s*S_IRUGO\s*|\s*0444\s*)\)?\s*,\s*\1_show\s*,\s*NULL\s*\)/DEVICE_ATTR_RO(\1)/g;
 print;}'

Signed-off-by: Joe Perches 
---
 arch/arm/mach-pxa/sharpsl_pm.c   |  4 ++--
 arch/sh/drivers/push-switch.c|  2 +-
 arch/tile/kernel/sysfs.c | 10 +-
 drivers/acpi/device_sysfs.c  |  6 +++---
 drivers/char/ipmi/ipmi_msghandler.c  | 17 -
 drivers/gpu/drm/i915/i915_sysfs.c|  6 +++---
 drivers/nvme/host/core.c | 10 +-
 drivers/s390/cio/css.c   |  8 
 drivers/s390/cio/device.c|  8 
 drivers/s390/crypto/ap_card.c|  2 +-
 drivers/scsi/hpsa.c  | 10 +-
 drivers/scsi/lpfc/lpfc_attr.c| 18 --
 drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c |  8 
 drivers/thermal/thermal_sysfs.c  |  6 +++---
 sound/soc/soc-core.c |  2 +-
 sound/soc/soc-dapm.c |  2 +-
 16 files changed, 58 insertions(+), 61 deletions(-)

diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
index 398ba9ba2632..ef9fd9b759cb 100644
--- a/arch/arm/mach-pxa/sharpsl_pm.c
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -802,8 +802,8 @@ static ssize_t battery_voltage_show(struct device *dev, 
struct device_attribute
return sprintf(buf, "%d\n", sharpsl_pm.battstat.mainbat_voltage);
 }
 
-static DEVICE_ATTR(battery_percentage, 0444, battery_percentage_show, NULL);
-static DEVICE_ATTR(battery_voltage, 0444, battery_voltage_show, NULL);
+static DEVICE_ATTR_RO(battery_percentage);
+static DEVICE_ATTR_RO(battery_voltage);
 
 extern void (*apm_get_power_status)(struct apm_power_info *);
 
diff --git a/arch/sh/drivers/push-switch.c b/arch/sh/drivers/push-switch.c
index a17181160233..762bc5619910 100644
--- a/arch/sh/drivers/push-switch.c
+++ b/arch/sh/drivers/push-switch.c
@@ -24,7 +24,7 @@ static ssize_t switch_show(struct device *dev,
struct push_switch_platform_info *psw_info = dev->platform_data;
return sprintf(buf, "%s\n", psw_info->name);
 }
-static DEVICE_ATTR(switch, S_IRUGO, switch_show, NULL);
+static DEVICE_ATTR_RO(switch);
 
 static void switch_timer(struct timer_list *t)
 {
diff --git a/arch/tile/kernel/sysfs.c b/arch/tile/kernel/sysfs.c
index af5024f0fb5a..b09456a3d77a 100644
--- a/arch/tile/kernel/sysfs.c
+++ b/arch/tile/kernel/sysfs.c
@@ -38,7 +38,7 @@ static ssize_t chip_width_show(struct device *dev,
 {
return sprintf(page, "%u\n", smp_width);
 }
-static DEVICE_ATTR(chip_width, 0444, chip_width_show, NULL);
+static DEVICE_ATTR_RO(chip_width);
 
 static ssize_t chip_height_show(struct device *dev,
struct device_attribute *attr,
@@ -46,7 +46,7 @@ static ssize_t chip_height_show(struct device *dev,
 {
return sprintf(page, "%u\n", smp_height);
 }
-static DEVICE_ATTR(chip_height, 0444, chip_height_show, NULL);
+static DEVICE_ATTR_RO(chip_height);
 
 static ssize_t chip_serial_show(struct device *dev,
struct device_attribute *attr,
@@ -54,7 +54,7 @@ static ssize_t chip_serial_show(struct device *dev,
 {
return get_hv_confstr(page, HV_CONFSTR_CHIP_SERIAL_NUM);
 }
-static DEVICE_ATTR(chip_serial, 0444, chip_serial_show, NULL);
+static DEVICE_ATTR_RO(chip_serial);
 
 static ssize_t chip_revision_show(struct device *dev,
  struct device_attribute *attr,
@@ -62,7 +62,7 @@ static ssize_t chip_revision_show(struct device *dev,
 {
return get_hv_confstr(page, HV_CONFSTR_CHIP_REV);
 }
-static DEVICE_ATTR(chip_revision, 0444, chip_revision_show, NULL);
+static DEVICE_ATTR_RO(chip_revision);
 
 
 static ssize_t type_show(struct device *dev,
@@ -71,7 +71,7 @@ static ssize_t type_show(struct device *dev,
 {
return sprintf(page, "tilera\n");
 }
-static DEVICE_ATTR(type, 0444, type_show, NULL);
+static DEVICE_ATTR_RO(type);
 
 #define HV_CONF_ATTR(name, conf)   \
static ssize_t name ## _show(struct device *dev,\
diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c
index a041689e5701..545e91420cde 100644
--- a/drivers/acpi/device_sysfs.c
+++ b/drivers/acpi/device_sysfs.c
@@ -357,7 +357,7 @@ static ssize_t real_power_state_show(struct device *dev,
return sprintf(buf, "%s\n", acpi_power_state_string(state));
 }
 
-static DEVICE_ATTR(real_power_state, 0444, real_power_state_show, NULL);
+static DEVICE_ATTR_RO(real_power_state);
 
 static ssize_t 

[PATCH v1] libsas: remove private hex2bin() implementation

2017-12-19 Thread Andy Shevchenko
The function sas_parse_addr() could be easily substituted by hex2bin() which is
in kernel library code.

Cc: Christoph Hellwig 
Signed-off-by: Andy Shevchenko 
---
 drivers/scsi/libsas/sas_scsi_host.c | 20 
 1 file changed, 4 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/libsas/sas_scsi_host.c 
b/drivers/scsi/libsas/sas_scsi_host.c
index 58476b728c57..626727207889 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "sas_internal.h"
 
@@ -946,21 +947,6 @@ void sas_target_destroy(struct scsi_target *starget)
sas_put_device(found_dev);
 }
 
-static void sas_parse_addr(u8 *sas_addr, const char *p)
-{
-   int i;
-   for (i = 0; i < SAS_ADDR_SIZE; i++) {
-   u8 h, l;
-   if (!*p)
-   break;
-   h = isdigit(*p) ? *p-'0' : toupper(*p)-'A'+10;
-   p++;
-   l = isdigit(*p) ? *p-'0' : toupper(*p)-'A'+10;
-   p++;
-   sas_addr[i] = (h<<4) | l;
-   }
-}
-
 #define SAS_STRING_ADDR_SIZE   16
 
 int sas_request_addr(struct Scsi_Host *shost, u8 *addr)
@@ -977,7 +963,9 @@ int sas_request_addr(struct Scsi_Host *shost, u8 *addr)
goto out;
}
 
-   sas_parse_addr(addr, fw->data);
+   res = hex2bin(addr, fw->data, strnlen(fw->data, SAS_ADDR_SIZE * 2) / 2);
+   if (res)
+   goto out;
 
 out:
release_firmware(fw);
-- 
2.15.1



[PATCH v1] scsi: hpsa: Use vsnprintf extension %phN

2017-12-19 Thread Andy Shevchenko
Using this extension reduces the object size.

Signed-off-by: Andy Shevchenko 
---
 drivers/scsi/hpsa.c | 14 +++---
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index b0aa5dc1d54c..4c018b653f18 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -4619,21 +4619,13 @@ static int hpsa_scatter_gather(struct ctlr_info *h,
return 0;
 }
 
-#define BUFLEN 128
 static inline void warn_zero_length_transfer(struct ctlr_info *h,
u8 *cdb, int cdb_len,
const char *func)
 {
-   char buf[BUFLEN];
-   int outlen;
-   int i;
-
-   outlen = scnprintf(buf, BUFLEN,
-   "%s: Blocking zero-length request: CDB:", func);
-   for (i = 0; i < cdb_len; i++)
-   outlen += scnprintf(buf+outlen, BUFLEN - outlen,
-   "%02hhx", cdb[i]);
-   dev_warn(>pdev->dev, "%s\n", buf);
+   dev_warn(>pdev->dev,
+"%s: Blocking zero-length request: CDB:%*phN\n",
+func, cdb_len, cdb);
 }
 
 #define IO_ACCEL_INELIGIBLE 1
-- 
2.15.1



Re: [trivial PATCH] treewide: Align function definition open/close braces

2017-12-19 Thread Mauro Carvalho Chehab
Em Sun, 17 Dec 2017 16:28:44 -0800
Joe Perches  escreveu:

> Some functions definitions have either the initial open brace and/or
> the closing brace outside of column 1.
> 
> Move those braces to column 1.
> 
> This allows various function analyzers like gnu complexity to work
> properly for these modified functions.
> 
> Miscellanea:
> 
> o Remove extra trailing ; and blank line from xfs_agf_verify
> 
> Signed-off-by: Joe Perches 

For the media patch:

Acked-by: Mauro Carvalho Chehab 

> ---
> git diff -w shows no difference other than the above 'Miscellanea'
> 
> (this is against -next, but it applies against Linus' tree
>  with a couple offsets)
> 
>  arch/x86/include/asm/atomic64_32.h   |  2 +-
>  drivers/acpi/custom_method.c |  2 +-
>  drivers/acpi/fan.c   |  2 +-
>  drivers/gpu/drm/amd/display/dc/core/dc.c |  2 +-
>  drivers/media/i2c/msp3400-kthreads.c |  2 +-
>  drivers/message/fusion/mptsas.c  |  2 +-
>  drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c |  2 +-
>  drivers/net/wireless/ath/ath9k/xmit.c|  2 +-
>  drivers/platform/x86/eeepc-laptop.c  |  2 +-
>  drivers/rtc/rtc-ab-b5ze-s3.c |  2 +-
>  drivers/scsi/dpt_i2o.c   |  2 +-
>  drivers/scsi/sym53c8xx_2/sym_glue.c  |  2 +-
>  fs/locks.c   |  2 +-
>  fs/ocfs2/stack_user.c|  2 +-
>  fs/xfs/libxfs/xfs_alloc.c|  5 ++---
>  fs/xfs/xfs_export.c  |  2 +-
>  kernel/audit.c   |  6 +++---
>  kernel/trace/trace_printk.c  |  4 ++--
>  lib/raid6/sse2.c | 14 +++---
>  sound/soc/fsl/fsl_dma.c  |  2 +-
>  20 files changed, 30 insertions(+), 31 deletions(-)
> 
> diff --git a/arch/x86/include/asm/atomic64_32.h 
> b/arch/x86/include/asm/atomic64_32.h
> index 97c46b8169b7..d4d4883080fa 100644
> --- a/arch/x86/include/asm/atomic64_32.h
> +++ b/arch/x86/include/asm/atomic64_32.h
> @@ -122,7 +122,7 @@ static inline long long atomic64_read(const atomic64_t *v)
>   long long r;
>   alternative_atomic64(read, "=" (r), "c" (v) : "memory");
>   return r;
> - }
> +}
>  
>  /**
>   * atomic64_add_return - add and return
> diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c
> index c68e72414a67..e967c1173ba3 100644
> --- a/drivers/acpi/custom_method.c
> +++ b/drivers/acpi/custom_method.c
> @@ -94,7 +94,7 @@ static void __exit acpi_custom_method_exit(void)
>  {
>   if (cm_dentry)
>   debugfs_remove(cm_dentry);
> - }
> +}
>  
>  module_init(acpi_custom_method_init);
>  module_exit(acpi_custom_method_exit);
> diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
> index 6cf4988206f2..3563103590c6 100644
> --- a/drivers/acpi/fan.c
> +++ b/drivers/acpi/fan.c
> @@ -219,7 +219,7 @@ fan_set_cur_state(struct thermal_cooling_device *cdev, 
> unsigned long state)
>   return fan_set_state_acpi4(device, state);
>   else
>   return fan_set_state(device, state);
> - }
> +}
>  
>  static const struct thermal_cooling_device_ops fan_cooling_ops = {
>   .get_max_state = fan_get_max_state,
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
> b/drivers/gpu/drm/amd/display/dc/core/dc.c
> index d1488d5ee028..1e0d1e7c5324 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
> @@ -461,7 +461,7 @@ static void disable_dangling_plane(struct dc *dc, struct 
> dc_state *context)
>   
> **/
>  
>  struct dc *dc_create(const struct dc_init_data *init_params)
> - {
> +{
>   struct dc *dc = kzalloc(sizeof(*dc), GFP_KERNEL);
>   unsigned int full_pipe_count;
>  
> diff --git a/drivers/media/i2c/msp3400-kthreads.c 
> b/drivers/media/i2c/msp3400-kthreads.c
> index 4dd01e9f553b..dc6cb8d475b3 100644
> --- a/drivers/media/i2c/msp3400-kthreads.c
> +++ b/drivers/media/i2c/msp3400-kthreads.c
> @@ -885,7 +885,7 @@ static int msp34xxg_modus(struct i2c_client *client)
>  }
>  
>  static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in)
> - {
> +{
>   struct msp_state *state = to_state(i2c_get_clientdata(client));
>   int source, matrix;
>  
> diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
> index 345f6035599e..69a62d23514b 100644
> --- a/drivers/message/fusion/mptsas.c
> +++ b/drivers/message/fusion/mptsas.c
> @@ -2968,7 +2968,7 @@ mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
>   mutex_unlock(>sas_mgmt.mutex);
>  out:
>   return ret;
> - }
> +}
>  
>  static void
>