Re: [PATCH v4 00/14] mpt3sas driver NVMe support:

2017-08-30 Thread Suganath Prabu Subramani
Hi Martin,
Replied inline.

Thanks,
Suganath Prabu S

On Thu, Aug 31, 2017 at 8:35 AM, Martin K. Petersen
 wrote:
>
> Hi Suganath,
>
>> Theoretically we want to use h/w capability (to translate IEEE to PRP)
>> for smaller IO size to leverage h/w capability.
>
> Nobody says we have to use the capability just because the hardware has
> it.
>
> Unlike some other operating systems, Linux will only submit I/Os to the
> driver that conform to the reported underlying constraints of the
> hardware.

 In general, h/w constraints are handled. What we missed is
Fast Path h/w
which is not exposed to OS.

> I fail to understand how letting the HBA firmware translate an
> SGL to a PRP for a subset of I/Os could do anything but add latency.

 Let me explain - NVME device fast path is possible in two ways.
IEEE SGL and PRP SGL. Due to h/w constraint we choose IEEE SGL only for
smaller IO size.
Both above is true h/w Fast Path and no firmware involvement.

> Plus complexity in the hot path of the driver.

 Agree with you. We are planning to see if we can keep only
simple Fast
Path using only PRP. It will take some time to finalize as we have to
engage h/w and f/w team.  BTW - This area is h/w dependent and we do not
see further changes in this area.

>
>> - If the unmap translation in firmware is slow, why don't you translate
>>   WRITE SAME/w UNMAP set to DSM DEALLOCATE without requiring
>>   applications to do encapsulated passthrough?
>
>> => As of now, current FW supports UNMAP command but not WRITE_SAME for
>> NVME drive. We did some experiment to convert UMAP command in driver,
>> but that is not really giving any performance improvement.
>
> It is imperative that the common use case, Linux' discard
> infrastructure, is working correctly and is as performant as any
> application-driven passthrough workaround.
>
> Unlike SCSI-to-SATA translation you have the benefit of a 1:1 mapping
> between UNMAP and DEALLOCATE. I'm not even sure why there would be a
> significant performance penalty in the firmware?

 I agree. Currently there is no performance issue for UNMAP
translation in
FW.


>> We would like to continue with UNMAP (and all other non-read/write
>> commands) to be handled in FW.
>
> And yet patch 4 circumvents that statement by adding support for
> encapsulated commands to bypass the FW translation...

 This path is not due to performance reason. User wants to
interact with
NVME drive in native NVME command for management.

>
> --
> Martin K. Petersen  Oracle Linux Engineering


Re: [PATCH v4 00/14] mpt3sas driver NVMe support:

2017-08-30 Thread Martin K. Petersen

Hi Suganath,

> Theoretically we want to use h/w capability (to translate IEEE to PRP)
> for smaller IO size to leverage h/w capability.

Nobody says we have to use the capability just because the hardware has
it.

Unlike some other operating systems, Linux will only submit I/Os to the
driver that conform to the reported underlying constraints of the
hardware. I fail to understand how letting the HBA firmware translate an
SGL to a PRP for a subset of I/Os could do anything but add latency.
Plus complexity in the hot path of the driver.

> - If the unmap translation in firmware is slow, why don't you translate
>   WRITE SAME/w UNMAP set to DSM DEALLOCATE without requiring
>   applications to do encapsulated passthrough?

> => As of now, current FW supports UNMAP command but not WRITE_SAME for
> NVME drive. We did some experiment to convert UMAP command in driver,
> but that is not really giving any performance improvement.

It is imperative that the common use case, Linux' discard
infrastructure, is working correctly and is as performant as any
application-driven passthrough workaround.

Unlike SCSI-to-SATA translation you have the benefit of a 1:1 mapping
between UNMAP and DEALLOCATE. I'm not even sure why there would be a
significant performance penalty in the firmware?

> We would like to continue with UNMAP (and all other non-read/write
> commands) to be handled in FW.

And yet patch 4 circumvents that statement by adding support for
encapsulated commands to bypass the FW translation...

-- 
Martin K. Petersen  Oracle Linux Engineering


RE: [PATCH] storvsc: fix memory leak on ring buffer busy

2017-08-30 Thread Long Li
> Long,
> 
> >> Which kernel version is this patch aimed at?
> >
> > Martin, thanks for pointing this out. This should also go to stable
> > trees.
> 
> The reason I asked is that it didn't apply to neither fixes, nor for-next.
> 
> I applied it to 4.13/scsi-fixes by hand and added a stable tag.

Thank you. I'm sorry I misunderstood your question. I just realized I was 
working on an experimental branch. Sorry about that.

> 
> --
> Martin K. PetersenOracle Linux Engineering


Re: [PATCH 0/3] qla2xxx: Fixes for scsi misc

2017-08-30 Thread Martin K. Petersen

Himanshu,

> These patches are small fixes for the driver. Please apply to
> 4.14/scsi-queue at your earliest convenience.

Done, thanks!

-- 
Martin K. Petersen  Oracle Linux Engineering


Re: [PATCH] qla2xxx: add missing includes for qla_isr

2017-08-30 Thread Martin K. Petersen

Johannes,

> Since commit 7401bc18d1ee ("scsi: qla2xxx: Add FC-NVMe command handling")
> we make use of 'struct nvmefc_fcp_req' in qla24xx_nvme_iocb_entry() without
> including linux/nvme-fc-driver.h where it is defined.

Applied to 4.14/scsi-queue. Thank you!

-- 
Martin K. Petersen  Oracle Linux Engineering


Re: [PATCH v2] scsi: qla2xxx: Fix an integer overflow in sysfs code

2017-08-30 Thread Martin K. Petersen

Dan,

> The value of "size" comes from the user.  When we add "start + size"
> it could lead to an integer overflow bug.
>
> It means we vmalloc() a lot more memory than we had intended.  I
> believe that on 64 bit systems vmalloc() can succeed even if we ask it
> to allocate huge 4GB buffers.  So we would get memory corruption and
> likely a crash when we call ha->isp_ops->write_optrom() and
> ->read_optrom().

Applied to 4.13/scsi-fixes. Thank you!

-- 
Martin K. Petersen  Oracle Linux Engineering


Re: [PATCH 3/3] scsi: aacraid: report -ENOMEM to upper layer from aac_convert_sgraw2()

2017-08-30 Thread Martin K. Petersen

Nikola,

> aac_convert_sgraw2() kmalloc memory and return -1 on error, which
> should be -ENOMEM. However, nobody is checking return value, so with
> this change, -ENOMEM is propagated to upper layer.

Applied to 4.14/scsi-queue.

-- 
Martin K. Petersen  Oracle Linux Engineering


Re: [PATCH] storvsc: fix memory leak on ring buffer busy

2017-08-30 Thread Martin K. Petersen

Long,

>> Which kernel version is this patch aimed at?
>
> Martin, thanks for pointing this out. This should also go to stable
> trees.

The reason I asked is that it didn't apply to neither fixes, nor
for-next.

I applied it to 4.13/scsi-fixes by hand and added a stable tag.

-- 
Martin K. Petersen  Oracle Linux Engineering


[PATCH v3 2/4] Improve requeuing behavior

2017-08-30 Thread Bart Van Assche
Requests are unprepared and reprepared when being requeued.
Avoid that requeuing resets .jiffies_at_alloc and .retries by
initializing these two member variables from inside
scsi_initialize_rq() and by preserving both member variables
when preparing a request. This patch affects the requeuing
behavior of both the legacy scsi and the scsi-mq code paths.

Reported-by: Brian King 
References: https://lkml.org/lkml/2017/8/18/923 ("Re: [BUG][bisected 270065e] 
linux-next fails to boot on powerpc")
Signed-off-by: Bart Van Assche 
Cc: Christoph Hellwig 
Cc: Brian King 
Cc: Hannes Reinecke 
Cc: Johannes Thumshirn 
---
 drivers/scsi/scsi_lib.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 4bfe0df35823..6085377643ae 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1112,9 +1112,13 @@ int scsi_init_io(struct scsi_cmnd *cmd)
 EXPORT_SYMBOL(scsi_init_io);
 
 /**
- * scsi_initialize_rq - initialize struct scsi_cmnd.req
+ * scsi_initialize_rq - initialize struct scsi_cmnd partially
  * @rq: Request associated with the SCSI command to be initialized.
  *
+ * This function initializes the members of struct scsi_cmnd that must be
+ * initialized before request processing starts and that won't be
+ * reinitialized if a SCSI command is requeued.
+ *
  * Called from inside blk_get_request() for pass-through requests and from
  * inside scsi_init_command() for filesystem requests.
  */
@@ -1123,6 +1127,8 @@ void scsi_initialize_rq(struct request *rq)
struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
 
scsi_req_init(&cmd->req);
+   cmd->jiffies_at_alloc = jiffies;
+   cmd->retries = 0;
 }
 EXPORT_SYMBOL(scsi_initialize_rq);
 
@@ -1162,12 +1168,16 @@ void scsi_init_command(struct scsi_device *dev, struct 
scsi_cmnd *cmd)
void *prot = cmd->prot_sdb;
struct request *rq = blk_mq_rq_from_pdu(cmd);
unsigned int flags = cmd->flags & SCMD_PRESERVED_FLAGS;
+   unsigned long jiffies_at_alloc;
+   int retries;
 
if (!blk_rq_is_scsi(rq) && !(flags & SCMD_INITIALIZED)) {
flags |= SCMD_INITIALIZED;
scsi_initialize_rq(rq);
}
 
+   jiffies_at_alloc = cmd->jiffies_at_alloc;
+   retries = cmd->retries;
/* zero out the cmd, except for the embedded scsi_request */
memset((char *)cmd + sizeof(cmd->req), 0,
sizeof(*cmd) - sizeof(cmd->req) + dev->host->hostt->cmd_size);
@@ -1177,7 +1187,8 @@ void scsi_init_command(struct scsi_device *dev, struct 
scsi_cmnd *cmd)
cmd->prot_sdb = prot;
cmd->flags = flags;
INIT_DELAYED_WORK(&cmd->abort_work, scmd_eh_abort_handler);
-   cmd->jiffies_at_alloc = jiffies;
+   cmd->jiffies_at_alloc = jiffies_at_alloc;
+   cmd->retries = retries;
 
scsi_add_cmd_to_list(cmd);
 }
-- 
2.14.1



[PATCH v3 3/4] Show .retries and .jiffies_at_alloc in debugfs

2017-08-30 Thread Bart Van Assche
Make these two member variables available in debugfs such that
their value can be verified by kernel developers. An example of
the new output:

8804a513d480 {.op=READ, .cmd_flags=META|PRIO, 
.rq_flags=MQ_INFLIGHT|DONTPREP|IO_STAT|STATS, .atomic_flags=STARTED, .tag=17, 
.internal_tag=-1, .cmd=Read(10) 28 00 08 81 32 38 00 00 08 00, .retries=0, 
allocated 0.010 s ago}

Signed-off-by: Bart Van Assche 
Cc: Hannes Reinecke 
Cc: Christoph Hellwig 
Cc: Johannes Thumshirn 
---
 drivers/scsi/scsi_debugfs.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_debugfs.c b/drivers/scsi/scsi_debugfs.c
index a97c9507103d..5e9755008aed 100644
--- a/drivers/scsi/scsi_debugfs.c
+++ b/drivers/scsi/scsi_debugfs.c
@@ -6,8 +6,10 @@
 void scsi_show_rq(struct seq_file *m, struct request *rq)
 {
struct scsi_cmnd *cmd = container_of(scsi_req(rq), typeof(*cmd), req);
+   int msecs = jiffies_to_msecs(jiffies - cmd->jiffies_at_alloc);
char buf[80];
 
__scsi_format_command(buf, sizeof(buf), cmd->cmnd, cmd->cmd_len);
-   seq_printf(m, ", .cmd=%s", buf);
+   seq_printf(m, ", .cmd=%s, .retries=%d, allocated %d.%03d s ago", buf,
+  cmd->retries, msecs / 1000, msecs % 1000);
 }
-- 
2.14.1



[PATCH v3 4/4] scsi-mq: Always unprepare before requeuing a request

2017-08-30 Thread Bart Van Assche
One of the two scsi-mq functions that requeue a request unprepares a
request before requeueing (scsi_io_completion()) but the other function
not (__scsi_queue_insert()). Make sure that a request is unprepared
before requeuing it.

Fixes: commit d285203cf647 ("scsi: add support for a blk-mq based I/O path.")
Signed-off-by: Bart Van Assche 
Cc: Christoph Hellwig 
Cc: Hannes Reinecke 
Cc: Damien Le Moal 
Cc: Johannes Thumshirn 
---
 drivers/scsi/scsi_lib.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 6085377643ae..9cf6a80fe297 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -44,6 +44,8 @@ static struct kmem_cache *scsi_sense_cache;
 static struct kmem_cache *scsi_sense_isadma_cache;
 static DEFINE_MUTEX(scsi_sense_cache_mutex);
 
+static void scsi_mq_uninit_cmd(struct scsi_cmnd *cmd);
+
 static inline struct kmem_cache *
 scsi_select_sense_cache(bool unchecked_isa_dma)
 {
@@ -140,6 +142,12 @@ static void scsi_mq_requeue_cmd(struct scsi_cmnd *cmd)
 {
struct scsi_device *sdev = cmd->device;
 
+   if (cmd->request->rq_flags & RQF_DONTPREP) {
+   cmd->request->rq_flags &= ~RQF_DONTPREP;
+   scsi_mq_uninit_cmd(cmd);
+   } else {
+   WARN_ON_ONCE(true);
+   }
blk_mq_requeue_request(cmd->request, true);
put_device(&sdev->sdev_gendev);
 }
@@ -982,8 +990,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int 
good_bytes)
 * A new command will be prepared and issued.
 */
if (q->mq_ops) {
-   cmd->request->rq_flags &= ~RQF_DONTPREP;
-   scsi_mq_uninit_cmd(cmd);
scsi_mq_requeue_cmd(cmd);
} else {
scsi_release_buffers(cmd);
-- 
2.14.1



[PATCH v3 1/4] Call scsi_initialize_rq() also for filesystem requests

2017-08-30 Thread Bart Van Assche
If a pass-through request is submitted then blk_get_request()
initializes that request by calling scsi_initialize_rq(). Also
call this function for filesystem requests. Introduce
CMD_INITIALIZED to keep track of whether or not a request has
already been initialized.

Signed-off-by: Bart Van Assche 
Cc: Christoph Hellwig 
Cc: Brian King 
Cc: Hannes Reinecke 
Cc: Johannes Thumshirn 
---
 drivers/scsi/scsi_lib.c  | 26 ++
 include/scsi/scsi_cmnd.h |  3 +++
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 938a7e398cd4..4bfe0df35823 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -642,6 +642,11 @@ static bool scsi_end_request(struct request *req, 
blk_status_t error,
if (blk_queue_add_random(q))
add_disk_randomness(req->rq_disk);
 
+   if (!blk_rq_is_scsi(req)) {
+   WARN_ON_ONCE(!(cmd->flags & SCMD_INITIALIZED));
+   cmd->flags &= ~SCMD_INITIALIZED;
+   }
+
if (req->mq_ctx) {
/*
 * In the MQ case the command gets freed by 
__blk_mq_end_request,
@@ -1110,7 +1115,8 @@ EXPORT_SYMBOL(scsi_init_io);
  * scsi_initialize_rq - initialize struct scsi_cmnd.req
  * @rq: Request associated with the SCSI command to be initialized.
  *
- * Called from inside blk_get_request().
+ * Called from inside blk_get_request() for pass-through requests and from
+ * inside scsi_init_command() for filesystem requests.
  */
 void scsi_initialize_rq(struct request *rq)
 {
@@ -1154,7 +1160,13 @@ void scsi_init_command(struct scsi_device *dev, struct 
scsi_cmnd *cmd)
 {
void *buf = cmd->sense_buffer;
void *prot = cmd->prot_sdb;
-   unsigned int unchecked_isa_dma = cmd->flags & SCMD_UNCHECKED_ISA_DMA;
+   struct request *rq = blk_mq_rq_from_pdu(cmd);
+   unsigned int flags = cmd->flags & SCMD_PRESERVED_FLAGS;
+
+   if (!blk_rq_is_scsi(rq) && !(flags & SCMD_INITIALIZED)) {
+   flags |= SCMD_INITIALIZED;
+   scsi_initialize_rq(rq);
+   }
 
/* zero out the cmd, except for the embedded scsi_request */
memset((char *)cmd + sizeof(cmd->req), 0,
@@ -1163,7 +1175,7 @@ void scsi_init_command(struct scsi_device *dev, struct 
scsi_cmnd *cmd)
cmd->device = dev;
cmd->sense_buffer = buf;
cmd->prot_sdb = prot;
-   cmd->flags = unchecked_isa_dma;
+   cmd->flags = flags;
INIT_DELAYED_WORK(&cmd->abort_work, scmd_eh_abort_handler);
cmd->jiffies_at_alloc = jiffies;
 
@@ -1350,6 +1362,8 @@ static int scsi_prep_fn(struct request_queue *q, struct 
request *req)
 
ret = scsi_setup_cmnd(sdev, req);
 out:
+   if (ret != BLKPREP_OK)
+   cmd->flags &= ~SCMD_INITIALIZED;
return scsi_prep_return(q, req, ret);
 }
 
@@ -1869,6 +1883,7 @@ static int scsi_mq_prep_fn(struct request *req)
struct scsi_device *sdev = req->q->queuedata;
struct Scsi_Host *shost = sdev->host;
struct scatterlist *sg;
+   int ret;
 
scsi_init_command(sdev, cmd);
 
@@ -1902,7 +1917,10 @@ static int scsi_mq_prep_fn(struct request *req)
 
blk_mq_start_request(req);
 
-   return scsi_setup_cmnd(sdev, req);
+   ret = scsi_setup_cmnd(sdev, req);
+   if (ret != BLK_STS_OK)
+   cmd->flags &= ~SCMD_INITIALIZED;
+   return ret;
 }
 
 static void scsi_mq_done(struct scsi_cmnd *cmd)
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index f5afcff8d76f..a9f8f7e79d83 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -57,6 +57,9 @@ struct scsi_pointer {
 /* for scmd->flags */
 #define SCMD_TAGGED(1 << 0)
 #define SCMD_UNCHECKED_ISA_DMA (1 << 1)
+#define SCMD_INITIALIZED   (1 << 3)
+/* flags preserved across unprep / reprep */
+#define SCMD_PRESERVED_FLAGS   (SCMD_UNCHECKED_ISA_DMA | SCMD_INITIALIZED)
 
 struct scsi_cmnd {
struct scsi_request req;
-- 
2.14.1



[PATCH v3 0/4] Improve requeuing behavior

2017-08-30 Thread Bart Van Assche
Hello Martin,

The conclusion of a recent discussion is that .jiffies_at_alloc and .retries
should be set once at the start of a lifetime of a SCSI request instead of
every time a request is requeued. This patch series realizes that and also
ensures that a request is unprepared and reprepared when requeued. Please
consider these patches for kernel v4.14.

Thanks,

Bart.

Changes between v2 and v3:
- Removed a WARN_ON_ONCE() statement from the first patch ("Call
  scsi_initialize_rq() also for filesystem requests".)
- Fixed handling of jiffies_at_alloc in patch 2/3.
- Converted jiffies_at_alloc to seconds in patch 3/3 before printing.
- Added a fourth patch, namely "scsi-mq: Always unprepare before requeuing a
  request".

Changes between v1 and v2:
- Added two more patches next to "Improve requeuing behavior".

Bart Van Assche (4):
  Call scsi_initialize_rq() also for filesystem requests
  Improve requeuing behavior
  Show .retries and .jiffies_at_alloc in debugfs
  scsi-mq: Always unprepare before requeuing a request

 drivers/scsi/scsi_debugfs.c |  4 +++-
 drivers/scsi/scsi_lib.c | 51 ++---
 include/scsi/scsi_cmnd.h|  3 +++
 3 files changed, 49 insertions(+), 9 deletions(-)

-- 
2.14.1



Re: [PATCH v2 1/3] Call scsi_initialize_rq() also for filesystem requests

2017-08-30 Thread Bart Van Assche
On Wed, 2017-08-30 at 17:14 -0500, Brian King wrote:
> On 08/29/2017 07:07 PM, Bart Van Assche wrote:
> > If a pass-through request is submitted then blk_get_request()
> > initializes that request by calling scsi_initialize_rq(). Also
> > call this function for filesystem requests. Introduce
> > CMD_INITIALIZED to keep track of whether or not a request has
> > already been initialized.
> 
> I applied these patches and was able to then re-apply your now reverted patch:
> 
> 270065e92 - scsi-mq: Always unprepare before requeuing a request
> 
> With this combination, I was still able to boot successfully on
> a Power system with ipr.

Hello Brian,

Thanks for testing! Sorry but a few minutes ago I found a bug in this
patch. I will repost this patch series.

Bart.

Re: [PATCH v2 1/3] Call scsi_initialize_rq() also for filesystem requests

2017-08-30 Thread Brian King
On 08/29/2017 07:07 PM, Bart Van Assche wrote:
> If a pass-through request is submitted then blk_get_request()
> initializes that request by calling scsi_initialize_rq(). Also
> call this function for filesystem requests. Introduce
> CMD_INITIALIZED to keep track of whether or not a request has
> already been initialized.

Bart,

I applied these patches and was able to then re-apply your now reverted patch:

270065e92 - scsi-mq: Always unprepare before requeuing a request

With this combination, I was still able to boot successfully on
a Power system with ipr.

Tested-by: Brian King 

Thanks,

Brian

-- 
Brian King
Power Linux I/O
IBM Linux Technology Center



Re: [PATCH v2 1/3] Call scsi_initialize_rq() also for filesystem requests

2017-08-30 Thread Bart Van Assche
On Wed, 2017-08-30 at 10:29 +0200, Christoph Hellwig wrote:
> Looks good except for the subject, which will need a little update:

Hello Christoph,

Thanks for the review. Sorry but I don't see what's wrong with the subject.
Can you clarify your comment?

Bart.

[PATCH 3/3] qla2xxx: Reset the logo flag, after target re-login.

2017-08-30 Thread Himanshu Madhani
From: Quinn Tran 

After relogin is sucessful, "send_els_logo" flag
needs to be reinitialized. This will allow next
re-login to happen successfully.

In target mode, this flag was not reset correctly,
causing IO's failure during reset recovery and port
ON/OFF test cases from initiator.

Signed-off-by: Quinn Tran 
Signed-off-by: Sawan Chandak 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_init.c   | 1 +
 drivers/scsi/qla2xxx/qla_target.c | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 73a6c3abb115..b5b48ddca962 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1464,6 +1464,7 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host 
*vha, struct event_arg *ea)
__func__, __LINE__, ea->fcport->port_name);
ea->fcport->chip_reset = 
vha->hw->base_qpair->chip_reset;
ea->fcport->logout_on_delete = 1;
+   ea->fcport->send_els_logo = 0;
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 192554b1536f..f05cfc83c9c8 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -585,11 +585,13 @@ void qla2x00_async_nack_sp_done(void *s, int res)
sp->fcport->fw_login_state = DSC_LS_PLOGI_COMP;
sp->fcport->logout_on_delete = 1;
sp->fcport->plogi_nack_done_deadline = jiffies + HZ;
+   sp->fcport->send_els_logo = 0;
break;
 
case SRB_NACK_PRLI:
sp->fcport->fw_login_state = DSC_LS_PRLI_COMP;
sp->fcport->deleted = 0;
+   sp->fcport->send_els_logo = 0;
 
if (!sp->fcport->login_succ &&
!IS_SW_RESV_ADDR(sp->fcport->d_id)) {
-- 
2.12.0



[PATCH 1/3] qla2xxx: Clear fc4f_nvme flag

2017-08-30 Thread Himanshu Madhani
From: Darren Trap 

Signed-off-by: Darren Trap 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_init.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 30b3acacbfca..73a6c3abb115 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -4937,6 +4937,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
new_fcport->fc4_type = swl[swl_idx].fc4_type;
 
new_fcport->nvme_flag = 0;
+   new_fcport->fc4f_nvme = 0;
if (vha->flags.nvme_enabled &&
swl[swl_idx].fc4f_nvme) {
new_fcport->fc4f_nvme =
-- 
2.12.0



[PATCH 2/3] qla2xxx: Fix slow mem alloc behind lock

2017-08-30 Thread Himanshu Madhani
From: Quinn Tran 

Call Trace:
 [] dump_stack+0x6b/0xa4
 [] ? print_irqtrace_events+0xd0/0xe0
 [] ___might_sleep+0x183/0x240
 [] __might_sleep+0x52/0x90
 [] kmem_cache_alloc_trace+0x5b/0x300
 [] ? __lock_acquired+0x30b/0x420
 [] qla2x00_alloc_fcport+0x38/0x2a0 [qla2xxx]
 [] ? qla2x00_do_work+0x34/0x2b0 [qla2xxx]
 [] ? _raw_spin_lock_irqsave+0x7b/0x90
 [] ? qla24xx_create_new_sess+0x3a/0x160 [qla2xxx]
 [] qla24xx_create_new_sess+0xc3/0x160 [qla2xxx]
 [] ? trace_hardirqs_on+0xd/0x10
 [] qla2x00_do_work+0x138/0x2b0 [qla2xxx]

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

diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 0b219b3ca653..f852ca60c49f 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -113,6 +113,7 @@ int qla24xx_post_gpdb_work(struct scsi_qla_host *, 
fc_port_t *, u8);
 extern char qla2x00_version_str[];
 
 extern struct kmem_cache *srb_cachep;
+extern struct kmem_cache *qla_tgt_plogi_cachep;
 
 extern int ql2xlogintimeout;
 extern int qlport_down_retry;
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 56bd086b79ea..5b2437a5ea44 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -4677,9 +4677,10 @@ static
 void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
 {
unsigned long flags;
-   fc_port_t *fcport =  NULL;
+   fc_port_t *fcport =  NULL, *tfcp;
struct qlt_plogi_ack_t *pla =
(struct qlt_plogi_ack_t *)e->u.new_sess.pla;
+   uint8_t free_fcport = 0;
 
spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
fcport = qla2x00_find_fcport_by_wwpn(vha, e->u.new_sess.port_name, 1);
@@ -4694,6 +4695,7 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, 
struct qla_work_evt *e)
pla->ref_count--;
}
} else {
+   spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
if (fcport) {
fcport->d_id = e->u.new_sess.id;
@@ -4703,6 +4705,29 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, 
struct qla_work_evt *e)
 
memcpy(fcport->port_name, e->u.new_sess.port_name,
WWN_SIZE);
+   } else {
+   ql_dbg(ql_dbg_disc, vha, 0x,
+  "%s %8phC mem alloc fail.\n",
+  __func__, e->u.new_sess.port_name);
+
+   if (pla)
+   kmem_cache_free(qla_tgt_plogi_cachep, pla);
+   return;
+   }
+
+   spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
+   /* search again to make sure one else got ahead */
+   tfcp = qla2x00_find_fcport_by_wwpn(vha,
+   e->u.new_sess.port_name, 1);
+   if (tfcp) {
+   /* should rarily happen */
+   ql_dbg(ql_dbg_disc, vha, 0x,
+   "%s %8phC found existing fcport b4 add. DS %d LS 
%d\n",
+   __func__, tfcp->port_name, tfcp->disc_state,
+   tfcp->fw_login_state);
+
+   free_fcport = 1;
+   } else {
list_add_tail(&fcport->list, &vha->vp_fcports);
 
if (pla) {
@@ -4720,6 +4745,12 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, 
struct qla_work_evt *e)
else
qla24xx_async_gnl(vha, fcport);
}
+
+   if (free_fcport) {
+   qla2x00_free_fcport(fcport);
+   if (pla)
+   kmem_cache_free(qla_tgt_plogi_cachep, pla);
+   }
 }
 
 void
diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 43113d52893b..192554b1536f 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -145,7 +145,7 @@ static void qlt_send_busy(struct qla_qpair *, struct 
atio_from_isp *,
  * Global Variables
  */
 static struct kmem_cache *qla_tgt_mgmt_cmd_cachep;
-static struct kmem_cache *qla_tgt_plogi_cachep;
+struct kmem_cache *qla_tgt_plogi_cachep;
 static mempool_t *qla_tgt_mgmt_cmd_mempool;
 static struct workqueue_struct *qla_tgt_wq;
 static DEFINE_MUTEX(qla_tgt_mutex);
-- 
2.12.0



[PATCH 0/3] qla2xxx: Fixes for scsi misc

2017-08-30 Thread Himanshu Madhani
Hi Martin, 

These patches are small fixes for the driver. Please apply
to 4.14/scsi-queue at your earliest convenience.

Thanks,
Himanshu

Darren Trap (1):
  qla2xxx: Clear fc4f_nvme flag

Quinn Tran (2):
  qla2xxx: Fix slow mem alloc behind lock
  qla2xxx: Reset the logo flag, after target re-login.

 drivers/scsi/qla2xxx/qla_gbl.h|  1 +
 drivers/scsi/qla2xxx/qla_init.c   |  2 ++
 drivers/scsi/qla2xxx/qla_os.c | 33 -
 drivers/scsi/qla2xxx/qla_target.c |  4 +++-
 4 files changed, 38 insertions(+), 2 deletions(-)

-- 
2.12.0



Re: [PATCH] qla2xxx: add missing includes for qla_isr

2017-08-30 Thread Madhani, Himanshu

> On Aug 30, 2017, at 6:12 AM, Johannes Thumshirn  wrote:
> 
> Since commit 7401bc18d1ee ("scsi: qla2xxx: Add FC-NVMe command handling")
> we make use of 'struct nvmefc_fcp_req' in qla24xx_nvme_iocb_entry() without
> including linux/nvme-fc-driver.h where it is defined.
> 
> Add linux/nvme-fc-driver.h (and scsi/fc/fc_fs.h as nvme-fc-driver.h needs
> the definition of 'struct fc_ba_rjt' from scsi/fc/fc_fs.h) to the header
> files included by qla_isr.c.
> 
> Fixes: 7401bc18d1ee ("scsi: qla2xxx: Add FC-NVMe command handling")
> Signed-off-by: Johannes Thumshirn 
> ---
> drivers/scsi/qla2xxx/qla_isr.c | 2 ++
> 1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
> index 7b3b702ef622..b57cbe4ec32b 100644
> --- a/drivers/scsi/qla2xxx/qla_isr.c
> +++ b/drivers/scsi/qla2xxx/qla_isr.c
> @@ -14,6 +14,8 @@
> #include 
> #include 
> #include 
> +#include 
> +#include 
> 
> static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
> static void qla2x00_status_entry(scsi_qla_host_t *, struct rsp_que *, void *);
> -- 
> 2.12.3
> 
Good catch. 

Acked-by: Himanshu Madhani 

Thanks,
- Himanshu



RE: [PATCH v2] scsi: qla2xxx: Fix an integer overflow in sysfs code

2017-08-30 Thread Carnuccio, Joe
good catch, thanks; I'll propagate this to our various OOB drivers.


-Original Message-
From: Dan Carpenter [mailto:dan.carpen...@oracle.com] 
Sent: Wednesday, August 30, 2017 6:31 AM
To: Dept-Eng QLA2xxx Upstream ; shqking 
; Carnuccio, Joe 
Cc: James E.J. Bottomley ; Martin K. Petersen 
; linux-scsi@vger.kernel.org; secur...@kernel.org
Subject: [PATCH v2] scsi: qla2xxx: Fix an integer overflow in sysfs code

The value of "size" comes from the user.  When we add "start + size"
it could lead to an integer overflow bug.

It means we vmalloc() a lot more memory than we had intended.  I believe that 
on 64 bit systems vmalloc() can succeed even if we ask it to allocate huge 4GB 
buffers.  So we would get memory corruption and likely a crash when we call 
ha->isp_ops->write_optrom() and ->read_optrom().

Only root can trigger this bug.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=194061

Cc: sta...@vger.kernel.org
Fixes: b7cc176c9eb3 ("[SCSI] qla2xxx: Allow region-based flash-part accesses.")
Reported-by: shqking 
Signed-off-by: Dan Carpenter 
---
v2: Add stable and the URL for bugzila

diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c 
index 75c4b312645e..9ce28c4f9812 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -318,6 +318,8 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct 
kobject *kobj,
return -EINVAL;
if (start > ha->optrom_size)
return -EINVAL;
+   if (size > ha->optrom_size - start)
+   size = ha->optrom_size - start;
 
mutex_lock(&ha->optrom_mutex);
switch (val) {
@@ -343,8 +345,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct 
kobject *kobj,
}
 
ha->optrom_region_start = start;
-   ha->optrom_region_size = start + size > ha->optrom_size ?
-   ha->optrom_size - start : size;
+   ha->optrom_region_size = start + size;
 
ha->optrom_state = QLA_SREADING;
ha->optrom_buffer = vmalloc(ha->optrom_region_size); @@ -417,8 
+418,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject 
*kobj,
}
 
ha->optrom_region_start = start;
-   ha->optrom_region_size = start + size > ha->optrom_size ?
-   ha->optrom_size - start : size;
+   ha->optrom_region_size = start + size;
 
ha->optrom_state = QLA_SWRITING;
ha->optrom_buffer = vmalloc(ha->optrom_region_size);


RE: [PATCH 3/6] pm80xx : Different SAS addresses for phys.

2017-08-30 Thread Viswas G
Hi Jack,

This is a customer requirement. Since the SAS addresses of all the phys were 
same , when the attached SAS addresses are different, it was forming only one 
domain.  If we assign different SAS addresses, this will cause duplicate domain 
unless we set the strict_wide_port to 1.

Regards,
Viswas G


> -Original Message-
> From: Jack Wang [mailto:xjtu...@gmail.com]
> Sent: Tuesday, August 29, 2017 4:55 PM
> To: Viswas G 
> Cc: linux-scsi@vger.kernel.org; Vasanthalakshmi Tharmarajan
> 
> Subject: Re: [PATCH 3/6] pm80xx : Different SAS addresses for phys.
> 
> EXTERNAL EMAIL
> 
> 
> 2015-01-30 7:06 GMT+01:00 Viswas G :
> > Different SAS addresses are assigned for each set of phys.
> >
> > Signed-off-by: Viswas G 
> > ---
> >  drivers/scsi/pm8001/pm8001_init.c | 13 +
> >  drivers/scsi/pm8001/pm80xx_hwi.c  |  3 +--
> >  2 files changed, 10 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/scsi/pm8001/pm8001_init.c
> b/drivers/scsi/pm8001/pm8001_init.c
> > index 034b2f7d1135..d282f1562615 100644
> > --- a/drivers/scsi/pm8001/pm8001_init.c
> > +++ b/drivers/scsi/pm8001/pm8001_init.c
> > @@ -132,7 +132,7 @@ static void pm8001_phy_init(struct
> pm8001_hba_info *pm8001_ha, int phy_id)
> > sas_phy->oob_mode = OOB_NOT_CONNECTED;
> > sas_phy->linkrate = SAS_LINK_RATE_UNKNOWN;
> > sas_phy->id = phy_id;
> > -   sas_phy->sas_addr = &pm8001_ha->sas_addr[0];
> > +   sas_phy->sas_addr = (u8 *)&phy->dev_sas_addr;
> > sas_phy->frame_rcvd = &phy->frame_rcvd[0];
> > sas_phy->ha = (struct sas_ha_struct *)pm8001_ha->shost->hostdata;
> > sas_phy->lldd_phy = phy;
> > @@ -593,10 +593,12 @@ static void  pm8001_post_sas_ha_init(struct
> Scsi_Host *shost,
> > for (i = 0; i < chip_info->n_phy; i++) {
> > sha->sas_phy[i] = &pm8001_ha->phy[i].sas_phy;
> > sha->sas_port[i] = &pm8001_ha->port[i].sas_port;
> > +   sha->sas_phy[i]->sas_addr =
> > +   (u8 *)&pm8001_ha->phy[i].dev_sas_addr;
> > }
> > sha->sas_ha_name = DRV_NAME;
> > sha->dev = pm8001_ha->dev;
> > -
> > +   sha->strict_wide_ports = 1;
> > sha->lldd_module = THIS_MODULE;
> > sha->sas_addr = &pm8001_ha->sas_addr[0];
> > sha->num_phys = chip_info->n_phy;
> > @@ -613,6 +615,7 @@ static void  pm8001_post_sas_ha_init(struct
> Scsi_Host *shost,
> >  static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
> >  {
> > u8 i, j;
> > +   u8 sas_add[8];
> >  #ifdef PM8001_READ_VPD
> > /* For new SPC controllers WWN is stored in flash vpd
> > *  For SPC/SPCve controllers WWN is stored in EEPROM
> > @@ -674,10 +677,12 @@ static void pm8001_init_sas_add(struct
> pm8001_hba_info *pm8001_ha)
> > pm8001_ha->sas_addr[j] =
> > payload.func_specific[0x804 + i];
> > }
> > -
> > +   memcpy(sas_add, pm8001_ha->sas_addr, SAS_ADDR_SIZE);
> > for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
> > +   if (i && ((i % 4) == 0))
> > +   sas_add[7] = sas_add[7] + 4;
> > memcpy(&pm8001_ha->phy[i].dev_sas_addr,
> > -   pm8001_ha->sas_addr, SAS_ADDR_SIZE);
> > +   sas_add, SAS_ADDR_SIZE);
> > PM8001_INIT_DBG(pm8001_ha,
> > pm8001_printk("phy %d sas_addr = %016llx\n", i,
> > pm8001_ha->phy[i].dev_sas_addr));
> > diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c
> b/drivers/scsi/pm8001/pm80xx_hwi.c
> > index 8fb5ddf08cc4..a07b023c09bf 100644
> > --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> > +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> > @@ -3041,7 +3041,6 @@ hw_event_phy_down(struct pm8001_hba_info
> *pm8001_ha, void *piomb)
> > port->port_state = portstate;
> > phy->identify.device_type = 0;
> > phy->phy_attached = 0;
> > -   memset(&phy->dev_sas_addr, 0, SAS_ADDR_SIZE);
> > switch (portstate) {
> > case PORT_VALID:
> > break;
> > @@ -4394,7 +4393,7 @@ pm80xx_chip_phy_start_req(struct
> pm8001_hba_info *pm8001_ha, u8 phy_id)
> > payload.sas_identify.dev_type = SAS_END_DEVICE;
> > payload.sas_identify.initiator_bits = SAS_PROTOCOL_ALL;
> > memcpy(payload.sas_identify.sas_addr,
> > -   pm8001_ha->sas_addr, SAS_ADDR_SIZE);
> > +   &pm8001_ha->phy[phy_id].dev_sas_addr, SAS_ADDR_SIZE);
> > payload.sas_identify.phy_id = phy_id;
> > ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode,
> &payload, 0);
> > return ret;
> > --
> > 2.12.3
> >
> This removes the possibility to form a wide port, why do you want to do it?


RE: [PATCH 1/6] pm80xx : redefine sas_identify_frame structure

2017-08-30 Thread Viswas G
Thanks. We will move that to pm80xx_hwi.h.

Regards,
Viswas G

> -Original Message-
> From: Jack Wang [mailto:xjtu...@gmail.com]
> Sent: Wednesday, August 30, 2017 9:34 PM
> To: Viswas G 
> Cc: linux-scsi@vger.kernel.org; Vasanthalakshmi Tharmarajan
> 
> Subject: Re: [PATCH 1/6] pm80xx : redefine sas_identify_frame structure
> 
> EXTERNAL EMAIL
> 
> 
> 2017-08-30 17:41 GMT+02:00 Viswas G :
> > Hi Jack,
> >
> > The firmware expectation is that there is no 4 byte CRC. This causes the
> IOMB to be generated incorrectly for PHY_START. Local structure for SAS
> Identify included in the driver so that it matches the Programmer's Manual
> and Firmware expectations.
> >
> > The sas_identify struct from the kernel includes the checksum word (32-
> bits) . So it is 32 bytes rather than 28 bytes. The changed size for the sas
> identify frame means that the "spasti" field for PHY_START is at a different
> offset than documented, word 11 rather than word 10. We're not changing
> the phy analog settings so this doesn't really matter, but the docs indicate
> that the sas frame's crc isn't included. So having a local definition will be
> better than taking the system definition.
> >
> > Regards,
> > Viswas G
> 
> Hi Viswas,
> 
> The spasti field is only for pm80xx, not for pm8001, I think it's
> better to move sas_identify_frame_local to pm80xx_hwi.h.
> 
> Regards,
> Jack
> 
> 
> >
> >> -Original Message-
> >> From: Jack Wang [mailto:xjtu...@gmail.com]
> >> Sent: Tuesday, August 29, 2017 4:49 PM
> >> To: Viswas G 
> >> Cc: linux-scsi@vger.kernel.org; Vasanthalakshmi Tharmarajan
> >> 
> >> Subject: Re: [PATCH 1/6] pm80xx : redefine sas_identify_frame structure
> >>
> >> EXTERNAL EMAIL
> >>
> >>
> >> 2015-01-30 7:06 GMT+01:00 Viswas G :
> >> > sas_identify structure defined by pm80xx doesn't have CRC field.
> >> > So added a new sas_identify structure without CRC.
> >> >
> >> > Signed-off-by: Raj Dinesh 
> >> > Signed-off-by: Viswas G 
> >> > ---
> >> >  drivers/scsi/pm8001/pm8001_hwi.h |  2 +-
> >> >  drivers/scsi/pm8001/pm8001_sas.h | 95
> >> 
> >> >  drivers/scsi/pm8001/pm80xx_hwi.h |  2 +-
> >> >  3 files changed, 97 insertions(+), 2 deletions(-)
> >> >
> >> > diff --git a/drivers/scsi/pm8001/pm8001_hwi.h
> >> b/drivers/scsi/pm8001/pm8001_hwi.h
> >> > index e4867e690c84..f4331afe9b0b 100644
> >> > --- a/drivers/scsi/pm8001/pm8001_hwi.h
> >> > +++ b/drivers/scsi/pm8001/pm8001_hwi.h
> >> > @@ -157,7 +157,7 @@ struct mpi_msg_hdr{
> >> >  struct phy_start_req {
> >> > __le32  tag;
> >> > __le32  ase_sh_lm_slr_phyid;
> >> > -   struct sas_identify_frame sas_identify;
> >> > +   struct sas_identify_frame_local sas_identify;
> >> > u32 reserved[5];
> >> >  } __attribute__((packed, aligned(4)));
> >> >
> >> > diff --git a/drivers/scsi/pm8001/pm8001_sas.h
> >> b/drivers/scsi/pm8001/pm8001_sas.h
> >> > index e81a8fa7ef1a..2e17505ed5b8 100644
> >> > --- a/drivers/scsi/pm8001/pm8001_sas.h
> >> > +++ b/drivers/scsi/pm8001/pm8001_sas.h
> >> > @@ -118,6 +118,101 @@ extern const struct pm8001_dispatch
> >> pm8001_80xx_dispatch;
> >> >  struct pm8001_hba_info;
> >> >  struct pm8001_ccb_info;
> >> >  struct pm8001_device;
> >> > +#ifdef __LITTLE_ENDIAN_BITFIELD
> >> > +struct sas_identify_frame_local {
> >> > +   /* Byte 0 */
> >> > +   u8  frame_type:4;
> >> > +   u8  dev_type:3;
> >> > +   u8  _un0:1;
> >> > +
> >> > +   /* Byte 1 */
> >> > +   u8  _un1;
> >> > +
> >> > +   /* Byte 2 */
> >> > +   union {
> >> > +   struct {
> >> > +   u8  _un20:1;
> >> > +   u8  smp_iport:1;
> >> > +   u8  stp_iport:1;
> >> > +   u8  ssp_iport:1;
> >> > +   u8  _un247:4;
> >> > +   };
> >> > +   u8 initiator_bits;
> >> > +   };
> >> > +
> >> > +   /* Byte 3 */
> >> > +   union {
> >> > +   struct {
> >> > +   u8  _un30:1;
> >> > +   u8 smp_tport:1;
> >> > +   u8 stp_tport:1;
> >> > +   u8 ssp_tport:1;
> >> > +   u8 _un347:4;
> >> > +   };
> >> > +   u8 target_bits;
> >> > +   };
> >> > +
> >> > +   /* Byte 4 - 11 */
> >> > +   u8 _un4_11[8];
> >> > +
> >> > +   /* Byte 12 - 19 */
> >> > +   u8 sas_addr[SAS_ADDR_SIZE];
> >> > +
> >> > +   /* Byte 20 */
> >> > +   u8 phy_id;
> >> > +
> >> > +   u8 _un21_27[7];
> >> > +
> >> > +} __packed;
> >> > +
> >> > +#elif defined(__BIG_ENDIAN_BITFIELD)
> >> > +struct sas_identify_frame_local {
> >> > +   /* Byte 0 */
> >> > +   u8  _un0:1;
> >> > +   u8  dev_type:3;
> >> > +   u8  frame_type:4;
> >> > +
> >> > +   /* Byte 1 */
> >> > +   u8  _un1;
> >> > +
> >> > +   /* Byte 2 */
> >> > +   union {
> >> > +   struct {
> >> > + 

Re: [PATCH 1/6] pm80xx : redefine sas_identify_frame structure

2017-08-30 Thread Jack Wang
2017-08-30 17:41 GMT+02:00 Viswas G :
> Hi Jack,
>
> The firmware expectation is that there is no 4 byte CRC. This causes the IOMB 
> to be generated incorrectly for PHY_START. Local structure for SAS Identify 
> included in the driver so that it matches the Programmer's Manual and 
> Firmware expectations.
>
> The sas_identify struct from the kernel includes the checksum word (32-bits) 
> . So it is 32 bytes rather than 28 bytes. The changed size for the sas 
> identify frame means that the "spasti" field for PHY_START is at a different 
> offset than documented, word 11 rather than word 10. We're not changing the 
> phy analog settings so this doesn't really matter, but the docs indicate that 
> the sas frame's crc isn't included. So having a local definition will be 
> better than taking the system definition.
>
> Regards,
> Viswas G

Hi Viswas,

The spasti field is only for pm80xx, not for pm8001, I think it's
better to move sas_identify_frame_local to pm80xx_hwi.h.

Regards,
Jack


>
>> -Original Message-
>> From: Jack Wang [mailto:xjtu...@gmail.com]
>> Sent: Tuesday, August 29, 2017 4:49 PM
>> To: Viswas G 
>> Cc: linux-scsi@vger.kernel.org; Vasanthalakshmi Tharmarajan
>> 
>> Subject: Re: [PATCH 1/6] pm80xx : redefine sas_identify_frame structure
>>
>> EXTERNAL EMAIL
>>
>>
>> 2015-01-30 7:06 GMT+01:00 Viswas G :
>> > sas_identify structure defined by pm80xx doesn't have CRC field.
>> > So added a new sas_identify structure without CRC.
>> >
>> > Signed-off-by: Raj Dinesh 
>> > Signed-off-by: Viswas G 
>> > ---
>> >  drivers/scsi/pm8001/pm8001_hwi.h |  2 +-
>> >  drivers/scsi/pm8001/pm8001_sas.h | 95
>> 
>> >  drivers/scsi/pm8001/pm80xx_hwi.h |  2 +-
>> >  3 files changed, 97 insertions(+), 2 deletions(-)
>> >
>> > diff --git a/drivers/scsi/pm8001/pm8001_hwi.h
>> b/drivers/scsi/pm8001/pm8001_hwi.h
>> > index e4867e690c84..f4331afe9b0b 100644
>> > --- a/drivers/scsi/pm8001/pm8001_hwi.h
>> > +++ b/drivers/scsi/pm8001/pm8001_hwi.h
>> > @@ -157,7 +157,7 @@ struct mpi_msg_hdr{
>> >  struct phy_start_req {
>> > __le32  tag;
>> > __le32  ase_sh_lm_slr_phyid;
>> > -   struct sas_identify_frame sas_identify;
>> > +   struct sas_identify_frame_local sas_identify;
>> > u32 reserved[5];
>> >  } __attribute__((packed, aligned(4)));
>> >
>> > diff --git a/drivers/scsi/pm8001/pm8001_sas.h
>> b/drivers/scsi/pm8001/pm8001_sas.h
>> > index e81a8fa7ef1a..2e17505ed5b8 100644
>> > --- a/drivers/scsi/pm8001/pm8001_sas.h
>> > +++ b/drivers/scsi/pm8001/pm8001_sas.h
>> > @@ -118,6 +118,101 @@ extern const struct pm8001_dispatch
>> pm8001_80xx_dispatch;
>> >  struct pm8001_hba_info;
>> >  struct pm8001_ccb_info;
>> >  struct pm8001_device;
>> > +#ifdef __LITTLE_ENDIAN_BITFIELD
>> > +struct sas_identify_frame_local {
>> > +   /* Byte 0 */
>> > +   u8  frame_type:4;
>> > +   u8  dev_type:3;
>> > +   u8  _un0:1;
>> > +
>> > +   /* Byte 1 */
>> > +   u8  _un1;
>> > +
>> > +   /* Byte 2 */
>> > +   union {
>> > +   struct {
>> > +   u8  _un20:1;
>> > +   u8  smp_iport:1;
>> > +   u8  stp_iport:1;
>> > +   u8  ssp_iport:1;
>> > +   u8  _un247:4;
>> > +   };
>> > +   u8 initiator_bits;
>> > +   };
>> > +
>> > +   /* Byte 3 */
>> > +   union {
>> > +   struct {
>> > +   u8  _un30:1;
>> > +   u8 smp_tport:1;
>> > +   u8 stp_tport:1;
>> > +   u8 ssp_tport:1;
>> > +   u8 _un347:4;
>> > +   };
>> > +   u8 target_bits;
>> > +   };
>> > +
>> > +   /* Byte 4 - 11 */
>> > +   u8 _un4_11[8];
>> > +
>> > +   /* Byte 12 - 19 */
>> > +   u8 sas_addr[SAS_ADDR_SIZE];
>> > +
>> > +   /* Byte 20 */
>> > +   u8 phy_id;
>> > +
>> > +   u8 _un21_27[7];
>> > +
>> > +} __packed;
>> > +
>> > +#elif defined(__BIG_ENDIAN_BITFIELD)
>> > +struct sas_identify_frame_local {
>> > +   /* Byte 0 */
>> > +   u8  _un0:1;
>> > +   u8  dev_type:3;
>> > +   u8  frame_type:4;
>> > +
>> > +   /* Byte 1 */
>> > +   u8  _un1;
>> > +
>> > +   /* Byte 2 */
>> > +   union {
>> > +   struct {
>> > +   u8  _un247:4;
>> > +   u8  ssp_iport:1;
>> > +   u8  stp_iport:1;
>> > +   u8  smp_iport:1;
>> > +   u8  _un20:1;
>> > +   };
>> > +   u8 initiator_bits;
>> > +   };
>> > +
>> > +   /* Byte 3 */
>> > +   union {
>> > +   struct {
>> > +   u8 _un347:4;
>> > +   u8 ssp_tport:1;
>> > +   u8 stp_tport:1;
>> > +   u8 smp_tport:1;
>> > +   u8 _un30:1;
>> > +   };
>

RE: [PATCH 4/6] pm80xx : Corrected SATA abort handling.

2017-08-30 Thread Viswas G
Thanks Jack. We will split this patch as you suggested and send V2.

Regards,
Viswas G

> -Original Message-
> From: Jack Wang [mailto:xjtu...@gmail.com]
> Sent: Tuesday, August 29, 2017 5:16 PM
> To: Viswas G 
> Cc: linux-scsi@vger.kernel.org; Vasanthalakshmi Tharmarajan
> 
> Subject: Re: [PATCH 4/6] pm80xx : Corrected SATA abort handling.
> 
> EXTERNAL EMAIL
> 
> 
> 2015-01-30 7:06 GMT+01:00 Viswas G :
> > Modified SATA abort handling with following steps:
> > 1) Set device state as recovery.
> > 2) Send phy reset.
> > 3) Wait for reset completion.
> > 4) After successful reset, abort all IO's to the device.
> > 5) After aborting all IO's to device, set device state as operational.
> >
> > Signed-off-by: Deepak Ukey 
> > Signed-off-by: Viswas G 
> This one includes more than described above.
> Would be good to split it better.
> comments inline.
> 
> > ---
> >  drivers/scsi/pm8001/pm8001_hwi.c |  11 +++-
> >  drivers/scsi/pm8001/pm8001_sas.c | 125
> +++
> >  drivers/scsi/pm8001/pm8001_sas.h |   8 +++
> >  drivers/scsi/pm8001/pm80xx_hwi.c |  52 +---
> >  4 files changed, 148 insertions(+), 48 deletions(-)
> >
> > diff --git a/drivers/scsi/pm8001/pm8001_hwi.c
> b/drivers/scsi/pm8001/pm8001_hwi.c
> > index 10546faac58c..db88a8e7ee0e 100644
> > --- a/drivers/scsi/pm8001/pm8001_hwi.c
> > +++ b/drivers/scsi/pm8001/pm8001_hwi.c
> > @@ -3198,19 +3198,28 @@ pm8001_mpi_get_nvmd_resp(struct
> pm8001_hba_info *pm8001_ha, void *piomb)
> >
> >  int pm8001_mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, void
> *piomb)
> >  {
> > +   u32 tag;
> > struct local_phy_ctl_resp *pPayload =
> > (struct local_phy_ctl_resp *)(piomb + 4);
> > u32 status = le32_to_cpu(pPayload->status);
> > u32 phy_id = le32_to_cpu(pPayload->phyop_phyid) & ID_BITS;
> > u32 phy_op = le32_to_cpu(pPayload->phyop_phyid) & OP_BITS;
> > +   tag = le32_to_cpu(pPayload->tag);
> > if (status != 0) {
> > PM8001_MSG_DBG(pm8001_ha,
> > pm8001_printk("%x phy execute %x phy op failed!\n",
> > phy_id, phy_op));
> > -   } else
> > +   } else {
> > PM8001_MSG_DBG(pm8001_ha,
> > pm8001_printk("%x phy execute %x phy op success!\n",
> > phy_id, phy_op));
> > +   pm8001_ha->phy[phy_id].reset_success = true;
> > +   }
> > +   if (pm8001_ha->phy[phy_id].enable_completion) {
> > +   complete(pm8001_ha->phy[phy_id].enable_completion);
> > +   pm8001_ha->phy[phy_id].enable_completion = NULL;
> > +   }
> > +   pm8001_tag_free(pm8001_ha, tag);
> > return 0;
> >  }
> >
> > diff --git a/drivers/scsi/pm8001/pm8001_sas.c
> b/drivers/scsi/pm8001/pm8001_sas.c
> > index ce584c31d36e..a409d3a6a3cb 100644
> > --- a/drivers/scsi/pm8001/pm8001_sas.c
> > +++ b/drivers/scsi/pm8001/pm8001_sas.c
> > @@ -1159,40 +1159,47 @@ int pm8001_query_task(struct sas_task *task)
> >  int pm8001_abort_task(struct sas_task *task)
> >  {
> > unsigned long flags;
> > -   u32 tag = 0xdeadbeef;
> > +   u32 tag;
> > u32 device_id;
> > struct domain_device *dev ;
> > -   struct pm8001_hba_info *pm8001_ha = NULL;
> > +   struct pm8001_hba_info *pm8001_ha;
> > struct pm8001_ccb_info *ccb;
> > struct scsi_lun lun;
> > struct pm8001_device *pm8001_dev;
> > struct pm8001_tmf_task tmf_task;
> > -   int rc = TMF_RESP_FUNC_FAILED;
> > +   int rc = TMF_RESP_FUNC_FAILED, ret;
> > +   u32 phy_id;
> > +   struct sas_task_slow slow_task;
> > +
> > if (unlikely(!task || !task->lldd_task || !task->dev))
> > -   return rc;
> > +   return TMF_RESP_FUNC_FAILED;
> > +
> > +   dev = task->dev;
> > +   pm8001_dev = dev->lldd_dev;
> > +   pm8001_ha = pm8001_find_ha_by_dev(dev);
> > +   device_id = pm8001_dev->device_id;
> > +   phy_id = pm8001_dev->attached_phy;
> > +   rc = pm8001_find_tag(task, &tag);
> > +   if (rc == 0) {
> > +   pm8001_printk("no tag for task:%p\n", task);
> > +   return TMF_RESP_FUNC_FAILED;
> > +   }
> 
> This part is cleanup.
> > spin_lock_irqsave(&task->task_state_lock, flags);
> > if (task->task_state_flags & SAS_TASK_STATE_DONE) {
> > spin_unlock_irqrestore(&task->task_state_lock, flags);
> > rc = TMF_RESP_FUNC_COMPLETE;
> > -   goto out;
> > +   }
> > +
> > +   task->task_state_flags |= SAS_TASK_STATE_ABORTED;
> > +   if (task->slow_task == NULL) {
> > +   init_completion(&slow_task.completion);
> > +   task->slow_task = &slow_task;
> > }
> > spin_unlock_irqrestore(&task->task_state_lock, flags);
> > +
> > if (task->task_proto & SAS_PROTOCOL_SSP) {
> > struct scsi_cmnd *cmnd = task

RE: [PATCH 1/6] pm80xx : redefine sas_identify_frame structure

2017-08-30 Thread Viswas G
Hi Jack,

The firmware expectation is that there is no 4 byte CRC. This causes the IOMB 
to be generated incorrectly for PHY_START. Local structure for SAS Identify 
included in the driver so that it matches the Programmer's Manual and Firmware 
expectations.

The sas_identify struct from the kernel includes the checksum word (32-bits) . 
So it is 32 bytes rather than 28 bytes. The changed size for the sas identify 
frame means that the "spasti" field for PHY_START is at a different offset than 
documented, word 11 rather than word 10. We're not changing the phy analog 
settings so this doesn't really matter, but the docs indicate that the sas 
frame's crc isn't included. So having a local definition will be better than 
taking the system definition. 

Regards,
Viswas G

> -Original Message-
> From: Jack Wang [mailto:xjtu...@gmail.com]
> Sent: Tuesday, August 29, 2017 4:49 PM
> To: Viswas G 
> Cc: linux-scsi@vger.kernel.org; Vasanthalakshmi Tharmarajan
> 
> Subject: Re: [PATCH 1/6] pm80xx : redefine sas_identify_frame structure
> 
> EXTERNAL EMAIL
> 
> 
> 2015-01-30 7:06 GMT+01:00 Viswas G :
> > sas_identify structure defined by pm80xx doesn't have CRC field.
> > So added a new sas_identify structure without CRC.
> >
> > Signed-off-by: Raj Dinesh 
> > Signed-off-by: Viswas G 
> > ---
> >  drivers/scsi/pm8001/pm8001_hwi.h |  2 +-
> >  drivers/scsi/pm8001/pm8001_sas.h | 95
> 
> >  drivers/scsi/pm8001/pm80xx_hwi.h |  2 +-
> >  3 files changed, 97 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/scsi/pm8001/pm8001_hwi.h
> b/drivers/scsi/pm8001/pm8001_hwi.h
> > index e4867e690c84..f4331afe9b0b 100644
> > --- a/drivers/scsi/pm8001/pm8001_hwi.h
> > +++ b/drivers/scsi/pm8001/pm8001_hwi.h
> > @@ -157,7 +157,7 @@ struct mpi_msg_hdr{
> >  struct phy_start_req {
> > __le32  tag;
> > __le32  ase_sh_lm_slr_phyid;
> > -   struct sas_identify_frame sas_identify;
> > +   struct sas_identify_frame_local sas_identify;
> > u32 reserved[5];
> >  } __attribute__((packed, aligned(4)));
> >
> > diff --git a/drivers/scsi/pm8001/pm8001_sas.h
> b/drivers/scsi/pm8001/pm8001_sas.h
> > index e81a8fa7ef1a..2e17505ed5b8 100644
> > --- a/drivers/scsi/pm8001/pm8001_sas.h
> > +++ b/drivers/scsi/pm8001/pm8001_sas.h
> > @@ -118,6 +118,101 @@ extern const struct pm8001_dispatch
> pm8001_80xx_dispatch;
> >  struct pm8001_hba_info;
> >  struct pm8001_ccb_info;
> >  struct pm8001_device;
> > +#ifdef __LITTLE_ENDIAN_BITFIELD
> > +struct sas_identify_frame_local {
> > +   /* Byte 0 */
> > +   u8  frame_type:4;
> > +   u8  dev_type:3;
> > +   u8  _un0:1;
> > +
> > +   /* Byte 1 */
> > +   u8  _un1;
> > +
> > +   /* Byte 2 */
> > +   union {
> > +   struct {
> > +   u8  _un20:1;
> > +   u8  smp_iport:1;
> > +   u8  stp_iport:1;
> > +   u8  ssp_iport:1;
> > +   u8  _un247:4;
> > +   };
> > +   u8 initiator_bits;
> > +   };
> > +
> > +   /* Byte 3 */
> > +   union {
> > +   struct {
> > +   u8  _un30:1;
> > +   u8 smp_tport:1;
> > +   u8 stp_tport:1;
> > +   u8 ssp_tport:1;
> > +   u8 _un347:4;
> > +   };
> > +   u8 target_bits;
> > +   };
> > +
> > +   /* Byte 4 - 11 */
> > +   u8 _un4_11[8];
> > +
> > +   /* Byte 12 - 19 */
> > +   u8 sas_addr[SAS_ADDR_SIZE];
> > +
> > +   /* Byte 20 */
> > +   u8 phy_id;
> > +
> > +   u8 _un21_27[7];
> > +
> > +} __packed;
> > +
> > +#elif defined(__BIG_ENDIAN_BITFIELD)
> > +struct sas_identify_frame_local {
> > +   /* Byte 0 */
> > +   u8  _un0:1;
> > +   u8  dev_type:3;
> > +   u8  frame_type:4;
> > +
> > +   /* Byte 1 */
> > +   u8  _un1;
> > +
> > +   /* Byte 2 */
> > +   union {
> > +   struct {
> > +   u8  _un247:4;
> > +   u8  ssp_iport:1;
> > +   u8  stp_iport:1;
> > +   u8  smp_iport:1;
> > +   u8  _un20:1;
> > +   };
> > +   u8 initiator_bits;
> > +   };
> > +
> > +   /* Byte 3 */
> > +   union {
> > +   struct {
> > +   u8 _un347:4;
> > +   u8 ssp_tport:1;
> > +   u8 stp_tport:1;
> > +   u8 smp_tport:1;
> > +   u8 _un30:1;
> > +   };
> > +   u8 target_bits;
> > +   };
> > +
> > +   /* Byte 4 - 11 */
> > +   u8 _un4_11[8];
> > +
> > +   /* Byte 12 - 19 */
> > +   u8 sas_addr[SAS_ADDR_SIZE];
> > +
> > +   /* Byte 20 */
> > +   u8 phy_id;
> > +
> > +   u8 _un21_27[7];
> > +} __packed;
> > +#else
> > +#error "Bitfield order not define

Re: [PATCHv4 2/5] scsi: Export blacklist flags to sysfs

2017-08-30 Thread Bart Van Assche
On Wed, 2017-08-30 at 12:50 +0200, Hannes Reinecke wrote:
> On 08/29/2017 06:02 PM, Bart Van Assche wrote:
> > On Tue, 2017-08-29 at 10:49 +0200, Hannes Reinecke wrote:
> > > +} sdev_bflags[] = {
> > > +#include "scsi_devinfo_tbl.c"
> > > +};
> > > +
> > > +static const char *sdev_bflags_name(unsigned int bflags)
> > > +{
> > > + int i;
> > > + const char *name = NULL;
> > > +
> > > + for (i = 0; i < ARRAY_SIZE(sdev_bflags); i++) {
> > > + if (sdev_bflags[i].value == bflags) {
> > > + name = sdev_bflags[i].name;
> > > + break;
> > > + }
> > > + }
> > > + return name;
> > > +}
> > 
> > How about using ilog2() of the BLIST_* values as index of the table such 
> > that
> > an array lookup can be used instead of a for-loop over the entire array?
> 
> Not sure if that'll work. The BLIST_* values in fact form a sparse
> array, so the lookup array 'sdev_bflags' actually an associative array.
> And I dare not convert it to a normal array as then I couldn't to the
> automatice table creation anymore.
> 
> So I'm not sure if ilog2 will save me anything here.

Hello Hannes,

Are you aware that there is already code upstream for converting a bitmask
into a list of names of flags that supports sparse bit definitions? From
block/blk-mq-debugfs.c:

#define HCTX_FLAG_NAME(name) [ilog2(BLK_MQ_F_##name)] = #name
static const char *const hctx_flag_name[] = {
HCTX_FLAG_NAME(SHOULD_MERGE),
HCTX_FLAG_NAME(TAG_SHARED),
HCTX_FLAG_NAME(SG_MERGE),
HCTX_FLAG_NAME(BLOCKING),
HCTX_FLAG_NAME(NO_SCHED),
};
#undef HCTX_FLAG_NAME

static int blk_flags_show(struct seq_file *m, const unsigned long flags,
  const char *const *flag_name, int flag_name_count)
{
bool sep = false;
int i;

for (i = 0; i < sizeof(flags) * BITS_PER_BYTE; i++) {
if (!(flags & BIT(i)))
continue;
if (sep)
seq_puts(m, "|");
sep = true;
if (i < flag_name_count && flag_name[i])
seq_puts(m, flag_name[i]);
else
seq_printf(m, "%d", i);
}
return 0;
}

[ ... ]
blk_flags_show(m, hctx->flags ^ 
BLK_ALLOC_POLICY_TO_MQ_FLAG(alloc_policy),
   hctx_flag_name, ARRAY_SIZE(hctx_flag_name));
[ ... ]

Bart.

Re: [PATCH] storvsc: fix memory leak on ring buffer busy

2017-08-30 Thread Stephen Hemminger
On Tue, 29 Aug 2017 21:31:11 -0400
"Martin K. Petersen"  wrote:

> Long,
> 
> > When storvsc is sending I/O to Hyper-v, it may allocate a bigger
> > buffer descriptor for large data payload that can't fit into a
> > pre-allocated buffer descriptor. This bigger buffer is freed on return
> > path.
> >
> > If I/O request to Hyper-v fails due to ring buffer busy, the storvsc
> > allocated buffer descriptor should also be freed.  
> 
> Which kernel version is this patch aimed at?
> 

Looks like this an old issue. Probably should add

Fixes: be0cf6ca301c ("scsi: storvsc: Set the tablesize based on the information 
given by the host")


[v5 01/14] Update MPI Header

2017-08-30 Thread Suganath Prabu S
Update MPI Files for NVMe support

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpi/mpi2.h  |  43 ++-
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h | 564 +--
 drivers/scsi/mpt3sas/mpi/mpi2_init.h |  11 +-
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  | 282 +-
 drivers/scsi/mpt3sas/mpi/mpi2_pci.h  | 112 +++
 drivers/scsi/mpt3sas/mpi/mpi2_tool.h |  14 +-
 6 files changed, 992 insertions(+), 34 deletions(-)
 create mode 100644 drivers/scsi/mpt3sas/mpi/mpi2_pci.h

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2.h b/drivers/scsi/mpt3sas/mpi/mpi2.h
index a9a659f..bc59058 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2.h
@@ -8,7 +8,7 @@
  * scatter/gather formats.
  * Creation Date:  June 21, 2006
  *
- * mpi2.h Version:  02.00.42
+ * mpi2.h Version:  02.00.48
  *
  * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
  *   prefix are for use only on MPI v2.5 products, and must not be used
@@ -103,6 +103,16 @@
  * 08-25-15  02.00.40  Bumped MPI2_HEADER_VERSION_UNIT.
  * 12-15-15  02.00.41  Bumped MPI_HEADER_VERSION_UNIT
  * 01-01-16  02.00.42  Bumped MPI_HEADER_VERSION_UNIT
+ * 04-05-16  02.00.43  Modified  MPI26_DIAG_BOOT_DEVICE_SELECT defines
+ * to be unique within first 32 characters.
+ * Removed AHCI support.
+ * Removed SOP support.
+ * Bumped MPI2_HEADER_VERSION_UNIT.
+ * 04-10-16  02.00.44  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 07-06-16  02.00.45  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 09-02-16  02.00.46  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 11-23-16  02.00.47  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 02-03-17  02.00.48  Bumped MPI2_HEADER_VERSION_UNIT.
  * --
  */
 
@@ -142,7 +152,7 @@
 #define MPI2_VERSION_02_06 (0x0206)
 
 /*Unit and Dev versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT(0x2A)
+#define MPI2_HEADER_VERSION_UNIT(0x30)
 #define MPI2_HEADER_VERSION_DEV (0x00)
 #define MPI2_HEADER_VERSION_UNIT_MASK   (0xFF00)
 #define MPI2_HEADER_VERSION_UNIT_SHIFT  (8)
@@ -249,6 +259,12 @@ typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS {
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_DEFAULT(0x)
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW   (0x0800)
 
+/* Defines for V7A/V7R HostDiagnostic Register */
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64FLASH  (0x)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64HCDW   (0x0800)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32FLASH  (0x1000)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32HCDW   (0x1800)
+
 #define MPI2_DIAG_CLEAR_FLASH_BAD_SIG   (0x0400)
 #define MPI2_DIAG_FORCE_HCB_ON_RESET(0x0200)
 #define MPI2_DIAG_HCB_MODE  (0x0100)
@@ -367,6 +383,7 @@ typedef struct _MPI2_DEFAULT_REQUEST_DESCRIPTOR {
 #define MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE(0x08)
 #define MPI2_REQ_DESCRIPT_FLAGS_RAID_ACCELERATOR(0x0A)
 #define MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO  (0x0C)
+#define MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED  (0x10)
 
 #define MPI2_REQ_DESCRIPT_FLAGS_IOC_FIFO_MARKER (0x01)
 
@@ -425,6 +442,13 @@ typedef MPI2_SCSI_IO_REQUEST_DESCRIPTOR
Mpi25FastPathSCSIIORequestDescriptor_t,
*pMpi25FastPathSCSIIORequestDescriptor_t;
 
+/*PCIe Encapsulated Request Descriptor */
+typedef MPI2_SCSI_IO_REQUEST_DESCRIPTOR
+   MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR,
+   *PTR_MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR,
+   Mpi26PCIeEncapsulatedRequestDescriptor_t,
+   *pMpi26PCIeEncapsulatedRequestDescriptor_t;
+
 /*union of Request Descriptors */
 typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
MPI2_DEFAULT_REQUEST_DESCRIPTOR Default;
@@ -433,6 +457,7 @@ typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR SCSITarget;
MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR RAIDAccelerator;
MPI25_FP_SCSI_IO_REQUEST_DESCRIPTOR FastPathSCSIIO;
+   MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR PCIeEncapsulated;
U64 Words;
 } MPI2_REQUEST_DESCRIPTOR_UNION,
*PTR_MPI2_REQUEST_DESCRIPTOR_UNION,
@@ -450,6 +475,7 @@ typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
  *  Atomic SCSI Target Request Descriptor
  *  Atomic RAID Accelerator Request Descriptor
  *  Atomic Fast Path SCSI IO Request Descriptor
+ *  Atomic PCIe Encapsulated Request Descriptor
  */
 
 /*Atomic Request Descriptor */
@@ -487,6 +513,7 @@ typedef struct _MPI2_DEFAULT_REPLY_DESCRIPTOR {
 #define MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER   (0x03)
 #define MPI2_RPY_DESCRIPT_FLAGS_RAID_ACCELERATOR_SUCCESS(0x05)
 #define MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS  (0x06)
+#define MPI26_RPY_DESCRIPT_FLAGS_PCIE_ENCAPSULATED_SUCCE

[v5 03/14] mpt3sas: SGL to PRP Translation for I/Os to NVMe devices

2017-08-30 Thread Suganath Prabu S
* Added support for translating the SGLs associated with incoming
commands either to IEE SGL or NVMe PRPs for NVMe devices.

* The hardware translation of IEEE SGL to NVMe PRPs has limitation
and if a command cannot be translated by hardware then it will go
to firmware and the firmware needs to translate it. And this will
have a performance reduction. To avoid that driver proactively
checks whether the translation will be done in hardware or not,
if not then driver try to translate inside the driver.

v1 - v3: no change.
v3 - v4: Removed hole check as suggested by Martin.
With commit-id <5a8d75a1b8c99bdc926ba69b7b7dbe4fae81a5af> "block: 
fix bio_will_gap() for first bvec with offset" driver can always assume
that their won't be any holes in the data buffers pointed by SGE's and no
need to have extra checks for detecting the holes.
v4 - v5: Removed the check to find data transfer length exceeding MDTS,
as we are setting max I/O size to match MDTS in slave_configure.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 590 ++-
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  44 ++-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |   1 +
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  14 +-
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |   2 +-
 5 files changed, 635 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 18039bb..dcf5157 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -59,6 +59,7 @@
 #include 
 #include 
 #include 
+#include /* To get host page size per arch */
 #include 
 
 
@@ -1347,6 +1348,469 @@ _base_build_sg(struct MPT3SAS_ADAPTER *ioc, void *psge,
 /* IEEE format sgls */
 
 /**
+ * _base_build_nvme_prp - This function is called for NVMe end devices to build
+ * a native SGL (NVMe PRP). The native SGL is built starting in the first PRP
+ * entry of the NVMe message (PRP1).  If the data buffer is small enough to be
+ * described entirely using PRP1, then PRP2 is not used.  If needed, PRP2 is
+ * used to describe a larger data buffer.  If the data buffer is too large to
+ * describe using the two PRP entriess inside the NVMe message, then PRP1
+ * describes the first data memory segment, and PRP2 contains a pointer to a 
PRP
+ * list located elsewhere in memory to describe the remaining data memory
+ * segments.  The PRP list will be contiguous.
+
+ * The native SGL for NVMe devices is a Physical Region Page (PRP).  A PRP
+ * consists of a list of PRP entries to describe a number of noncontigous
+ * physical memory segments as a single memory buffer, just as a SGL does.  
Note
+ * however, that this function is only used by the IOCTL call, so the memory
+ * given will be guaranteed to be contiguous.  There is no need to translate
+ * non-contiguous SGL into a PRP in this case.  All PRPs will describe
+ * contiguous space that is one page size each.
+ *
+ * Each NVMe message contains two PRP entries.  The first (PRP1) either 
contains
+ * a PRP list pointer or a PRP element, depending upon the command.  PRP2
+ * contains the second PRP element if the memory being described fits within 2
+ * PRP entries, or a PRP list pointer if the PRP spans more than two entries.
+ *
+ * A PRP list pointer contains the address of a PRP list, structured as a 
linear
+ * array of PRP entries.  Each PRP entry in this list describes a segment of
+ * physical memory.
+ *
+ * Each 64-bit PRP entry comprises an address and an offset field.  The address
+ * always points at the beginning of a 4KB physical memory page, and the offset
+ * describes where within that 4KB page the memory segment begins.  Only the
+ * first element in a PRP list may contain a non-zero offest, implying that all
+ * memory segments following the first begin at the start of a 4KB page.
+ *
+ * Each PRP element normally describes 4KB of physical memory, with exceptions
+ * for the first and last elements in the list.  If the memory being described
+ * by the list begins at a non-zero offset within the first 4KB page, then the
+ * first PRP element will contain a non-zero offset indicating where the region
+ * begins within the 4KB page.  The last memory segment may end before the end
+ * of the 4KB segment, depending upon the overall size of the memory being
+ * described by the PRP list.
+ *
+ * Since PRP entries lack any indication of size, the overall data buffer 
length
+ * is used to determine where the end of the data memory buffer is located, and
+ * how many PRP entries are required to describe it.
+ *
+ * @ioc: per adapter object
+ * @smid: system request message index for getting asscociated SGL
+ * @nvme_encap_request: the NVMe request msg frame pointer
+ * @data_out_dma: physical address for WRITES
+ * @data_out_sz: data xfer size for WRITES
+ * @data_in_dma: physical address for READS
+ * @data_in_sz: data xfer size for READS
+ *
+ * Ret

[v5 05/14] mpt3sas: API 's to support NVMe drive addition to SML

2017-08-30 Thread Suganath Prabu S
Below Functions are added in various paths to support NVMe
drive addition.

_scsih_pcie_add_device
_scsih_pcie_device_add
_scsih_pcie_device_init_add
_scsih_check_pcie_access_status
_scsih_pcie_check_device

mpt3sas_get_pdev_by_handle

mpt3sas_config_get_pcie_device_pg0
mpt3sas_config_get_pcie_device_pg2

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h   |  10 +
 drivers/scsi/mpt3sas/mpt3sas_config.c | 100 +++
 drivers/scsi/mpt3sas/mpt3sas_scsih.c  | 473 +-
 3 files changed, 575 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index c4be9ad..09ad823 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1458,6 +1458,10 @@ struct _sas_device *mpt3sas_get_sdev_by_addr(
 struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
 struct _sas_device *__mpt3sas_get_sdev_by_addr(
 struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
+struct _sas_device *mpt3sas_get_sdev_by_handle(struct MPT3SAS_ADAPTER *ioc,
+   u16 handle);
+struct _pcie_device *mpt3sas_get_pdev_by_handle(struct MPT3SAS_ADAPTER *ioc,
+   u16 handle);
 
 void mpt3sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc);
 struct _raid_device *
@@ -1496,6 +1500,12 @@ int mpt3sas_config_get_sas_device_pg0(struct 
MPT3SAS_ADAPTER *ioc,
 int mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc,
Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page,
u32 form, u32 handle);
+int mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
+   Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
+   u32 form, u32 handle);
+int mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc,
+   Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page,
+   u32 form, u32 handle);
 int mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page,
u16 sz);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c 
b/drivers/scsi/mpt3sas/mpt3sas_config.c
index dd62701..1c747cf 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_config.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_config.c
@@ -150,6 +150,24 @@ _config_display_some_debug(struct MPT3SAS_ADAPTER *ioc, 
u16 smid,
case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING:
desc = "driver_mapping";
break;
+   case MPI2_CONFIG_EXTPAGETYPE_SAS_PORT:
+   desc = "sas_port";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING:
+   desc = "ext_manufacturing";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT:
+   desc = "pcie_io_unit";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_SWITCH:
+   desc = "pcie_switch";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE:
+   desc = "pcie_device";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_LINK:
+   desc = "pcie_link";
+   break;
}
break;
}
@@ -1053,6 +1071,88 @@ mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER 
*ioc,
 }
 
 /**
+ * mpt3sas_config_get_pcie_device_pg0 - obtain pcie device page 0
+ * @ioc: per adapter object
+ * @mpi_reply: reply mf payload returned from firmware
+ * @config_page: contents of the config page
+ * @form: GET_NEXT_HANDLE or HANDLE
+ * @handle: device handle
+ * Context: sleep.
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+int
+mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
+   Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
+   u32 form, u32 handle)
+{
+   Mpi2ConfigRequest_t mpi_request;
+   int r;
+
+   memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
+   mpi_request.Function = MPI2_FUNCTION_CONFIG;
+   mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
+   mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
+   mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
+   mpi_request.Header.PageVersion = MPI26_PCIEDEVICE0_PAGEVERSION;
+   mpi_request.Header.PageNumber = 0;
+   ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
+   r = _config_request(ioc, &mpi_request, mpi_reply,
+   MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
+   if (r)
+   goto out;
+
+   mpi_request.PageAddress = cpu_to_le32(form | handle);
+   mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
+   r = _config_request(ioc, &mpi_request, mpi_reply,
+   MPT3_CONFIG_PAGE

[v5 04/14] mpt3sas: Added support for nvme encapsulated request message.

2017-08-30 Thread Suganath Prabu S
* Mpt3sas driver uses the NVMe Encapsulated Request message to
send an NVMe command to an NVMe device attached to the IOC.

* Normal I/O commands like reads and writes are passed to the
controller as SCSI commands and the controller has the ability
to translate the commands to NVMe equivalent.

* This encapsulated NVMe command is used by applications to send
direct NVMe commands to NVMe drives or for handling unmap where
the translation at controller/firmware level is having
performance issues.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c | 56 +-
 drivers/scsi/mpt3sas/mpt3sas_base.h |  1 +
 drivers/scsi/mpt3sas/mpt3sas_ctl.c  | 69 +
 3 files changed, 119 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index dcf5157..9653cfa 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -557,6 +557,11 @@ _base_sas_ioc_info(struct MPT3SAS_ADAPTER *ioc, 
MPI2DefaultReply_t *mpi_reply,
frame_sz = sizeof(Mpi2SmpPassthroughRequest_t) + ioc->sge_size;
func_str = "smp_passthru";
break;
+   case MPI2_FUNCTION_NVME_ENCAPSULATED:
+   frame_sz = sizeof(Mpi26NVMeEncapsulatedRequest_t) +
+   ioc->sge_size;
+   func_str = "nvme_encapsulated";
+   break;
default:
frame_sz = 32;
func_str = "unknown";
@@ -985,7 +990,9 @@ _base_interrupt(int irq, void *bus_id)
if (request_desript_type ==
MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS ||
request_desript_type ==
-   MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) {
+   MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS ||
+   request_desript_type ==
+   MPI26_RPY_DESCRIPT_FLAGS_PCIE_ENCAPSULATED_SUCCESS) {
cb_idx = _base_get_cb_idx(ioc, smid);
if ((likely(cb_idx < MPT_MAX_CALLBACKS)) &&
(likely(mpt_callbacks[cb_idx] != NULL))) {
@@ -3046,6 +3053,30 @@ _base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, 
u16 smid,
 }
 
 /**
+ * _base_put_smid_nvme_encap - send NVMe encapsulated request to
+ *  firmware
+ * @ioc: per adapter object
+ * @smid: system request message index
+ *
+ * Return nothing.
+ */
+static void
+_base_put_smid_nvme_encap(struct MPT3SAS_ADAPTER *ioc, u16 smid)
+{
+   Mpi2RequestDescriptorUnion_t descriptor;
+   u64 *request = (u64 *)&descriptor;
+
+   descriptor.Default.RequestFlags =
+   MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED;
+   descriptor.Default.MSIxIndex =  _base_get_msix_index(ioc);
+   descriptor.Default.SMID = cpu_to_le16(smid);
+   descriptor.Default.LMID = 0;
+   descriptor.Default.DescriptorTypeDependent = 0;
+   _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
+   &ioc->scsi_lookup_lock);
+}
+
+/**
  * _base_put_smid_default - Default, primarily used for config pages
  * @ioc: per adapter object
  * @smid: system request message index
@@ -3136,6 +3167,27 @@ _base_put_smid_hi_priority_atomic(struct MPT3SAS_ADAPTER 
*ioc, u16 smid,
 }
 
 /**
+ * _base_put_smid_nvme_encap_atomic - send NVMe encapsulated request to
+ *   firmware using Atomic Request Descriptor
+ * @ioc: per adapter object
+ * @smid: system request message index
+ *
+ * Return nothing.
+ */
+static void
+_base_put_smid_nvme_encap_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid)
+{
+   Mpi26AtomicRequestDescriptor_t descriptor;
+   u32 *request = (u32 *)&descriptor;
+
+   descriptor.RequestFlags = MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED;
+   descriptor.MSIxIndex = _base_get_msix_index(ioc);
+   descriptor.SMID = cpu_to_le16(smid);
+
+   writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost);
+}
+
+/**
  * _base_put_smid_default - Default, primarily used for config pages
  * use Atomic Request Descriptor
  * @ioc: per adapter object
@@ -5968,11 +6020,13 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
ioc->put_smid_scsi_io = &_base_put_smid_scsi_io_atomic;
ioc->put_smid_fast_path = &_base_put_smid_fast_path_atomic;
ioc->put_smid_hi_priority = &_base_put_smid_hi_priority_atomic;
+   ioc->put_smid_nvme_encap = &_base_put_smid_nvme_encap_atomic;
} else {
ioc->put_smid_default = &_base_put_smid_default;
ioc->put_smid_scsi_io = &_base_put_smid_scsi_io;
ioc->put_smid_fast_path = &_base_put_smid_fast_path;
ioc->put_smid_hi_priority = &_base_put_smid_hi_priority;
+   ioc->put_smid_nvme_encap = &_base_put_smid_nvme_encap;
}
 
 
diff --git a/drivers/scsi/mpt3sas/mpt3s

[v5 06/14] mpt3sas: API's to remove nvme drive from sml

2017-08-30 Thread Suganath Prabu S
Below API's are included in nvme drive remove path.
_scsih_pcie_device_remove_by_handle
_scsih_pcie_device_remove_from_sml

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 148 ++-
 1 file changed, 145 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 2f257e1..710ea63 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -73,6 +73,8 @@ static void _scsih_remove_device(struct MPT3SAS_ADAPTER *ioc,
 static int _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle,
u8 retry_count, u8 is_pd);
 static int _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle);
+static void _scsih_pcie_device_remove_from_sml(struct MPT3SAS_ADAPTER *ioc,
+   struct _pcie_device *pcie_device);
 static u8 _scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 
 /* global parameters */
@@ -1092,6 +1094,41 @@ _scsih_pcie_device_remove(struct MPT3SAS_ADAPTER *ioc,
pcie_device_put(pcie_device);
}
 }
+
+
+/**
+ * _scsih_pcie_device_remove_by_handle - removing pcie device object by handle
+ * @ioc: per adapter object
+ * @handle: device handle
+ *
+ * Return nothing.
+ */
+static void
+_scsih_pcie_device_remove_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
+{
+   struct _pcie_device *pcie_device;
+   unsigned long flags;
+   int was_on_pcie_device_list = 0;
+
+   if (ioc->shost_recovery)
+   return;
+
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_handle(ioc, handle);
+   if (pcie_device) {
+   if (!list_empty(&pcie_device->list)) {
+   list_del_init(&pcie_device->list);
+   was_on_pcie_device_list = 1;
+   pcie_device_put(pcie_device);
+   }
+   }
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+   if (was_on_pcie_device_list) {
+   _scsih_pcie_device_remove_from_sml(ioc, pcie_device);
+   pcie_device_put(pcie_device);
+   }
+}
+
 /**
  * _scsih_pcie_device_add - add pcie_device object
  * @ioc: per adapter object
@@ -6533,6 +6570,83 @@ _scsih_check_pcie_access_status(struct MPT3SAS_ADAPTER 
*ioc, u64 wwid,
(unsigned long long)wwid, handle);
return rc;
 }
+
+/**
+ * _scsih_pcie_device_remove_from_sml -  removing pcie device
+ * from SML and free up associated memory
+ * @ioc: per adapter object
+ * @pcie_device: the pcie_device object
+ *
+ * Return nothing.
+ */
+static void
+_scsih_pcie_device_remove_from_sml(struct MPT3SAS_ADAPTER *ioc,
+   struct _pcie_device *pcie_device)
+{
+   struct MPT3SAS_TARGET *sas_target_priv_data;
+
+   dewtprintk(ioc, pr_info(MPT3SAS_FMT
+   "%s: enter: handle(0x%04x), wwid(0x%016llx)\n", ioc->name, __func__,
+   pcie_device->handle, (unsigned long long)
+   pcie_device->wwid));
+   if (pcie_device->enclosure_handle != 0)
+   dewtprintk(ioc, pr_info(MPT3SAS_FMT
+   "%s: enter: enclosure logical id(0x%016llx), slot(%d)\n",
+   ioc->name, __func__,
+   (unsigned long long)pcie_device->enclosure_logical_id,
+   pcie_device->slot));
+   if (pcie_device->connector_name[0] != '\0')
+   dewtprintk(ioc, pr_info(MPT3SAS_FMT
+   "%s: enter: enclosure level(0x%04x), connector name( %s)\n",
+   ioc->name, __func__,
+   pcie_device->enclosure_level,
+   pcie_device->connector_name));
+
+   if (pcie_device->starget && pcie_device->starget->hostdata) {
+   sas_target_priv_data = pcie_device->starget->hostdata;
+   sas_target_priv_data->deleted = 1;
+   _scsih_ublock_io_device(ioc, pcie_device->wwid);
+   sas_target_priv_data->handle = MPT3SAS_INVALID_DEVICE_HANDLE;
+   }
+
+   pr_info(MPT3SAS_FMT
+   "removing handle(0x%04x), wwid (0x%016llx)\n",
+   ioc->name, pcie_device->handle,
+   (unsigned long long) pcie_device->wwid);
+   if (pcie_device->enclosure_handle != 0)
+   pr_info(MPT3SAS_FMT
+   "removing : enclosure logical id(0x%016llx), slot(%d)\n",
+   ioc->name,
+   (unsigned long long)pcie_device->enclosure_logical_id,
+   pcie_device->slot);
+   if (pcie_device->connector_name[0] != '\0')
+   pr_info(MPT3SAS_FMT
+   "removing: enclosure level(0x%04x), connector name( %s)\n",
+   ioc->name, pcie_device->enclosure_level,
+   pcie_device->connector_name);
+
+   if (pcie_device->starget)
+   scsi_remove_target(&pcie_device->

[v5 08/14] mpt3sas: Set NVMe device queue depth as 128

2017-08-30 Thread Suganath Prabu S
Sets nvme device queue depth, name and displays device capabilities

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  2 +-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 50 
 2 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 09ad823..51d2668 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -115,7 +115,7 @@
 
 #define MPT3SAS_RAID_MAX_SECTORS   8192
 #define MPT3SAS_HOST_PAGE_SIZE_4K  12
-
+#define MPT3SAS_NVME_QUEUE_DEPTH   128
 #define MPT_NAME_LENGTH32  /* generic length of 
strings */
 #define MPT_STRING_LENGTH  64
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 344f946..8834919 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2290,6 +2290,7 @@ scsih_slave_configure(struct scsi_device *sdev)
struct MPT3SAS_DEVICE *sas_device_priv_data;
struct MPT3SAS_TARGET *sas_target_priv_data;
struct _sas_device *sas_device;
+   struct _pcie_device *pcie_device;
struct _raid_device *raid_device;
unsigned long flags;
int qdepth;
@@ -2420,6 +2421,55 @@ scsih_slave_configure(struct scsi_device *sdev)
}
}
 
+   /* PCIe handling */
+   if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_wwid(ioc,
+   sas_device_priv_data->sas_target->sas_address);
+   if (!pcie_device) {
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+   dfailprintk(ioc, pr_warn(MPT3SAS_FMT
+   "failure at %s:%d/%s()!\n", ioc->name, __FILE__,
+   __LINE__, __func__));
+   return 1;
+   }
+
+   qdepth = MPT3SAS_NVME_QUEUE_DEPTH;
+   ds = "NVMe";
+   sdev_printk(KERN_INFO, sdev,
+   "%s: handle(0x%04x), wwid(0x%016llx), port(%d)\n",
+   ds, handle, (unsigned long long)pcie_device->wwid,
+   pcie_device->port_num);
+   if (pcie_device->enclosure_handle != 0)
+   sdev_printk(KERN_INFO, sdev,
+   "%s: enclosure logical id(0x%016llx), slot(%d)\n",
+   ds,
+   (unsigned long long)pcie_device->enclosure_logical_id,
+   pcie_device->slot);
+   if (pcie_device->connector_name[0] != '\0')
+   sdev_printk(KERN_INFO, sdev,
+   "%s: enclosure level(0x%04x),"
+   "connector name( %s)\n", ds,
+   pcie_device->enclosure_level,
+   pcie_device->connector_name);
+   pcie_device_put(pcie_device);
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+   scsih_change_queue_depth(sdev, qdepth);
+
+   if (pcie_device->nvme_mdts)
+   blk_queue_max_hw_sectors(sdev->request_queue,
+   pcie_device->nvme_mdts/512);
+   /* Enable QUEUE_FLAG_NOMERGES flag, so that IOs won't be
+** merged and can eliminate holes created during merging
+** operation.
+**/
+   queue_flag_set_unlocked(QUEUE_FLAG_NOMERGES,
+   sdev->request_queue);
+   blk_queue_virt_boundary(sdev->request_queue,
+   ioc->page_size - 1);
+   return 0;
+   }
+
spin_lock_irqsave(&ioc->sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_by_addr(ioc,
   sas_device_priv_data->sas_target->sas_address);
-- 
2.5.5



[v5 09/14] mpt3sas: scan and add nvme device after controller reset

2017-08-30 Thread Suganath Prabu S
After Controller reset, Scan and add nvme device back to the topology.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 194 ++-
 1 file changed, 190 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 8834919..a6bb65c 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -4879,6 +4879,7 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct 
scsi_cmnd *scmd,
char *desc_scsi_state = ioc->tmp_string;
u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo);
struct _sas_device *sas_device = NULL;
+   struct _pcie_device *pcie_device = NULL;
struct scsi_target *starget = scmd->device->sdev_target;
struct MPT3SAS_TARGET *priv_target = starget->hostdata;
char *device_str = NULL;
@@ -5011,6 +5012,28 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct 
scsi_cmnd *scmd,
if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) {
pr_warn(MPT3SAS_FMT "\t%s wwid(0x%016llx)\n", ioc->name,
device_str, (unsigned long long)priv_target->sas_address);
+   } else if (priv_target->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
+   pcie_device = mpt3sas_get_pdev_from_target(ioc, priv_target);
+   if (pcie_device) {
+   pr_info(MPT3SAS_FMT "\twwid(0x%016llx), port(%d)\n",
+   ioc->name,
+   (unsigned long long)pcie_device->wwid,
+   pcie_device->port_num);
+   if (pcie_device->enclosure_handle != 0)
+   pr_info(MPT3SAS_FMT
+   "\tenclosure logical id(0x%016llx), "
+   "slot(%d)\n", ioc->name,
+   (unsigned long long)
+   pcie_device->enclosure_logical_id,
+   pcie_device->slot);
+   if (pcie_device->connector_name[0])
+   pr_info(MPT3SAS_FMT
+   "\tenclosure level(0x%04x),"
+   "connector name( %s)\n",
+   ioc->name, pcie_device->enclosure_level,
+   pcie_device->connector_name);
+   pcie_device_put(pcie_device);
+   }
} else {
sas_device = mpt3sas_get_sdev_from_target(ioc, priv_target);
if (sas_device) {
@@ -5057,11 +5080,10 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, 
struct scsi_cmnd *scmd,
struct sense_info data;
_scsih_normalize_sense(scmd->sense_buffer, &data);
pr_warn(MPT3SAS_FMT
-   "\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], 
count(%d)\n",
-   ioc->name, data.skey,
-   data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
+ "\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], count(%d)\n",
+ ioc->name, data.skey,
+ data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
}
-
if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
response_info = le32_to_cpu(mpi_reply->ResponseInfo);
response_bytes = (u8 *)&response_info;
@@ -8522,6 +8544,130 @@ _scsih_search_responding_sas_devices(struct 
MPT3SAS_ADAPTER *ioc)
 }
 
 /**
+ * _scsih_mark_responding_pcie_device - mark a pcie_device as responding
+ * @ioc: per adapter object
+ * @pcie_device_pg0: PCIe Device page 0
+ *
+ * After host reset, find out whether devices are still responding.
+ * Used in _scsih_remove_unresponding_devices.
+ *
+ * Return nothing.
+ */
+static void
+_scsih_mark_responding_pcie_device(struct MPT3SAS_ADAPTER *ioc,
+   Mpi26PCIeDevicePage0_t *pcie_device_pg0)
+{
+   struct MPT3SAS_TARGET *sas_target_priv_data = NULL;
+   struct scsi_target *starget;
+   struct _pcie_device *pcie_device;
+   unsigned long flags;
+
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   list_for_each_entry(pcie_device, &ioc->pcie_device_list, list) {
+   if ((pcie_device->wwid == pcie_device_pg0->WWID) &&
+   (pcie_device->slot == pcie_device_pg0->Slot)) {
+   pcie_device->responding = 1;
+   starget = pcie_device->starget;
+   if (starget && starget->hostdata) {
+   sas_target_priv_data = starget->hostdata;
+   sas_target_priv_data->tm_busy = 0;
+   sas_target_priv_data->deleted = 0;
+   } else
+   sas_target_priv_data = NULL;
+ 

[v5 10/14] mpt3as: Add-Task-management-debug-info-for-NVMe-drives.

2017-08-30 Thread Suganath Prabu S
Added debug information for NVMe/PCIe drives in target rest path.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 83 ++--
 1 file changed, 70 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index a6bb65c..8754ade 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2903,6 +2903,7 @@ _scsih_tm_display_info(struct MPT3SAS_ADAPTER *ioc, 
struct scsi_cmnd *scmd)
struct scsi_target *starget = scmd->device->sdev_target;
struct MPT3SAS_TARGET *priv_target = starget->hostdata;
struct _sas_device *sas_device = NULL;
+   struct _pcie_device *pcie_device = NULL;
unsigned long flags;
char *device_str = NULL;
 
@@ -2919,6 +2920,31 @@ _scsih_tm_display_info(struct MPT3SAS_ADAPTER *ioc, 
struct scsi_cmnd *scmd)
"%s handle(0x%04x), %s wwid(0x%016llx)\n",
device_str, priv_target->handle,
device_str, (unsigned long long)priv_target->sas_address);
+
+   } else if (priv_target->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_from_target(ioc, priv_target);
+   if (pcie_device) {
+   starget_printk(KERN_INFO, starget,
+   "handle(0x%04x), wwid(0x%016llx), port(%d)\n",
+   pcie_device->handle,
+   (unsigned long long)pcie_device->wwid,
+   pcie_device->port_num);
+   if (pcie_device->enclosure_handle != 0)
+   starget_printk(KERN_INFO, starget,
+   "enclosure logical id(0x%016llx), 
slot(%d)\n",
+   (unsigned long long)
+   pcie_device->enclosure_logical_id,
+   pcie_device->slot);
+   if (pcie_device->connector_name[0] != '\0')
+   starget_printk(KERN_INFO, starget,
+   "enclosure level(0x%04x), connector 
name( %s)\n",
+   pcie_device->enclosure_level,
+   pcie_device->connector_name);
+   pcie_device_put(pcie_device);
+   }
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+
} else {
spin_lock_irqsave(&ioc->sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_from_target(ioc, priv_target);
@@ -3662,6 +3688,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
Mpi2SCSITaskManagementRequest_t *mpi_request;
u16 smid;
struct _sas_device *sas_device = NULL;
+   struct _pcie_device *pcie_device = NULL;
struct MPT3SAS_TARGET *sas_target_priv_data = NULL;
u64 sas_address = 0;
unsigned long flags;
@@ -3704,24 +3731,52 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
sas_address = sas_device->sas_address;
}
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-
+   if (!sas_device) {
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_handle(ioc, handle);
+   if (pcie_device && pcie_device->starget &&
+   pcie_device->starget->hostdata) {
+   sas_target_priv_data = pcie_device->starget->hostdata;
+   sas_target_priv_data->deleted = 1;
+   sas_address = pcie_device->wwid;
+   }
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+   }
if (sas_target_priv_data) {
dewtprintk(ioc, pr_info(MPT3SAS_FMT
"setting delete flag: handle(0x%04x), 
sas_addr(0x%016llx)\n",
ioc->name, handle,
(unsigned long long)sas_address));
-   if (sas_device->enclosure_handle != 0)
-   dewtprintk(ioc, pr_info(MPT3SAS_FMT
-"setting delete flag:enclosure logical id(0x%016llx),"
-" slot(%d)\n", ioc->name, (unsigned long long)
- sas_device->enclosure_logical_id,
- sas_device->slot));
-   if (sas_device->connector_name[0] != '\0')
-   dewtprintk(ioc, pr_info(MPT3SAS_FMT
-"setting delete flag: enclosure level(0x%04x),"
-" connector name( %s)\n", ioc->name,
- sas_device->enclosure_level,
- sas_device

[v5 11/14] mpt3sas: NVMe drive support for BTDHMAPPING ioctl command and log info

2017-08-30 Thread Suganath Prabu S
* Added debug prints for pcie devices in ioctl debug path. Which
will be helpful for debugging.
* Added PCIe device support for ioctl BTDHMAPPING ioctl.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_ctl.c | 88 +-
 1 file changed, 58 insertions(+), 30 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c 
b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index 6362d60..99147ad 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -79,32 +79,6 @@ enum block_state {
 };
 
 /**
- * _ctl_sas_device_find_by_handle - sas device search
- * @ioc: per adapter object
- * @handle: sas device handle (assigned by firmware)
- * Context: Calling function should acquire ioc->sas_device_lock
- *
- * This searches for sas_device based on sas_address, then return sas_device
- * object.
- */
-static struct _sas_device *
-_ctl_sas_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
-{
-   struct _sas_device *sas_device, *r;
-
-   r = NULL;
-   list_for_each_entry(sas_device, &ioc->sas_device_list, list) {
-   if (sas_device->handle != handle)
-   continue;
-   r = sas_device;
-   goto out;
-   }
-
- out:
-   return r;
-}
-
-/**
  * _ctl_display_some_debug - debug routine
  * @ioc: per adapter object
  * @smid: system request message index
@@ -229,10 +203,9 @@ _ctl_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 
smid,
Mpi2SCSIIOReply_t *scsi_reply =
(Mpi2SCSIIOReply_t *)mpi_reply;
struct _sas_device *sas_device = NULL;
-   unsigned long flags;
+   struct _pcie_device *pcie_device = NULL;
 
-   spin_lock_irqsave(&ioc->sas_device_lock, flags);
-   sas_device = _ctl_sas_device_find_by_handle(ioc,
+   sas_device = mpt3sas_get_sdev_by_handle(ioc,
le16_to_cpu(scsi_reply->DevHandle));
if (sas_device) {
pr_warn(MPT3SAS_FMT "\tsas_address(0x%016llx), 
phy(%d)\n",
@@ -242,8 +215,25 @@ _ctl_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 
smid,
"\tenclosure_logical_id(0x%016llx), slot(%d)\n",
ioc->name, (unsigned long long)
sas_device->enclosure_logical_id, sas_device->slot);
+   sas_device_put(sas_device);
+   }
+   if (!sas_device) {
+   pcie_device = mpt3sas_get_pdev_by_handle(ioc,
+   le16_to_cpu(scsi_reply->DevHandle));
+   if (pcie_device) {
+   pr_warn(MPT3SAS_FMT
+   "\tWWID(0x%016llx), port(%d)\n", ioc->name,
+   (unsigned long long)pcie_device->wwid,
+   pcie_device->port_num);
+   if (pcie_device->enclosure_handle != 0)
+   pr_warn(MPT3SAS_FMT
+   "\tenclosure_logical_id(0x%016llx), 
slot(%d)\n",
+   ioc->name, (unsigned long long)
+   pcie_device->enclosure_logical_id,
+   pcie_device->slot);
+   pcie_device_put(pcie_device);
+   }
}
-   spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
if (scsi_reply->SCSIState || scsi_reply->SCSIStatus)
pr_info(MPT3SAS_FMT
"\tscsi_state(0x%02x), scsi_status"
@@ -1353,6 +1343,42 @@ _ctl_btdh_search_sas_device(struct MPT3SAS_ADAPTER *ioc,
 }
 
 /**
+ * _ctl_btdh_search_pcie_device - searching for pcie device
+ * @ioc: per adapter object
+ * @btdh: btdh ioctl payload
+ */
+static int
+_ctl_btdh_search_pcie_device(struct MPT3SAS_ADAPTER *ioc,
+   struct mpt3_ioctl_btdh_mapping *btdh)
+{
+   struct _pcie_device *pcie_device;
+   unsigned long flags;
+   int rc = 0;
+
+   if (list_empty(&ioc->pcie_device_list))
+   return rc;
+
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   list_for_each_entry(pcie_device, &ioc->pcie_device_list, list) {
+   if (btdh->bus == 0x && btdh->id == 0x &&
+  btdh->handle == pcie_device->handle) {
+   btdh->bus = pcie_device->channel;
+   btdh->id = pcie_device->id;
+   rc = 1;
+   goto out;
+   } else if (btdh->bus == pcie_device->channel && btdh->id ==
+  pcie_device->id && btdh->handle == 0x) {
+   btdh->handle = pcie_device->handle;
+ 

[v5 12/14] mpt3sas: Fix nvme drives checking for tlr.

2017-08-30 Thread Suganath Prabu S
Check for NVMe drives before enabling or checking tlr.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 22 --
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 8754ade..aece862 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2014,6 +2014,14 @@ scsih_is_raid(struct device *dev)
return (sdev->channel == RAID_CHANNEL) ? 1 : 0;
 }
 
+static int
+scsih_is_nvme(struct device *dev)
+{
+   struct scsi_device *sdev = to_scsi_device(dev);
+
+   return (sdev->channel == PCIE_CHANNEL) ? 1 : 0;
+}
+
 /**
  * scsih_get_resync - get raid volume resync percent complete
  * @dev the device struct object
@@ -4821,8 +4829,9 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd 
*scmd)
/* Make sure Device is not raid volume.
 * We do not expose raid functionality to upper layer for warpdrive.
 */
-   if (!ioc->is_warpdrive && !scsih_is_raid(&scmd->device->sdev_gendev)
-   && sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
+   if (((!ioc->is_warpdrive && !scsih_is_raid(&scmd->device->sdev_gendev))
+   && !scsih_is_nvme(&scmd->device->sdev_gendev))
+   && sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON;
 
smid = mpt3sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd);
@@ -4867,8 +4876,8 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd 
*scmd)
 
raid_device = sas_target_priv_data->raid_device;
if (raid_device && raid_device->direct_io_enabled)
-   mpt3sas_setup_direct_io(ioc, scmd, raid_device, mpi_request,
-   smid);
+   mpt3sas_setup_direct_io(ioc, scmd,
+   raid_device, mpi_request, smid);
 
if (likely(mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)) {
if (sas_target_priv_data->flags & MPT_TARGET_FASTPATH_IO) {
@@ -5416,9 +5425,10 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 
msix_index, u32 reply)
le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF;
if (!sas_device_priv_data->tlr_snoop_check) {
sas_device_priv_data->tlr_snoop_check++;
-   if (!ioc->is_warpdrive &&
+   if ((!ioc->is_warpdrive &&
!scsih_is_raid(&scmd->device->sdev_gendev) &&
-   sas_is_tlr_enabled(scmd->device) &&
+   !scsih_is_nvme(&scmd->device->sdev_gendev))
+   && sas_is_tlr_enabled(scmd->device) &&
response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) {
sas_disable_tlr(scmd->device);
sdev_printk(KERN_INFO, scmd->device, "TLR disabled\n");
-- 
2.5.5



[v5 13/14] mpt3sas: Update mpt3sas driver version.

2017-08-30 Thread Suganath Prabu S
Updated mpt3sas driver version to 15.101.00.00

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 51d2668..2cd1550 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -74,9 +74,9 @@
 #define MPT3SAS_DRIVER_NAME"mpt3sas"
 #define MPT3SAS_AUTHOR "Avago Technologies "
 #define MPT3SAS_DESCRIPTION"LSI MPT Fusion SAS 3.0 Device Driver"
-#define MPT3SAS_DRIVER_VERSION "15.100.00.00"
+#define MPT3SAS_DRIVER_VERSION "15.101.00.00"
 #define MPT3SAS_MAJOR_VERSION  15
-#define MPT3SAS_MINOR_VERSION  100
+#define MPT3SAS_MINOR_VERSION  101
 #define MPT3SAS_BUILD_VERSION  0
 #define MPT3SAS_RELEASE_VERSION00
 
-- 
2.5.5



[v5 14/14] mpt3sas: Fix sparse warnings

2017-08-30 Thread Suganath Prabu S
1) Used variable __le64/__le32 whichever required in
building NVME PRP, which is passed to LE Controller.
2) Remove unused function, Declared functions which are used only
in mpt3sas_scsih.c as static

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 23 +++---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 37 +---
 2 files changed, 16 insertions(+), 44 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 6e0a940..f86c7b2 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -1437,8 +1437,8 @@ _base_build_nvme_prp(struct MPT3SAS_ADAPTER *ioc, u16 
smid,
size_t data_in_sz)
 {
int prp_size = NVME_PRP_SIZE;
-   u64 *prp_entry, *prp1_entry, *prp2_entry, *prp_entry_phys;
-   u64 *prp_page, *prp_page_phys;
+   __le64  *prp_entry, *prp1_entry, *prp2_entry, *prp_entry_phys;
+   __le64  *prp_page, *prp_page_phys;
u32 offset, entry_len;
u32 page_mask_result, page_mask;
dma_addr_t  paddr;
@@ -1455,17 +1455,17 @@ _base_build_nvme_prp(struct MPT3SAS_ADAPTER *ioc, u16 
smid,
 * PRP1 is located at a 24 byte offset from the start of the NVMe
 * command.  Then set the current PRP entry pointer to PRP1.
 */
-   prp1_entry = (u64 *)(nvme_encap_request->NVMe_Command +
+   prp1_entry = (__le64 *)(nvme_encap_request->NVMe_Command +
NVME_CMD_PRP1_OFFSET);
-   prp2_entry = (u64 *)(nvme_encap_request->NVMe_Command +
+   prp2_entry = (__le64 *)(nvme_encap_request->NVMe_Command +
NVME_CMD_PRP2_OFFSET);
prp_entry = prp1_entry;
/*
 * For the PRP entries, use the specially allocated buffer of
 * contiguous memory.
 */
-   prp_page = (u64 *)mpt3sas_base_get_pcie_sgl(ioc, smid);
-   prp_page_phys = (u64 *)mpt3sas_base_get_pcie_sgl_dma(ioc, smid);
+   prp_page = (__le64 *)mpt3sas_base_get_pcie_sgl(ioc, smid);
+   prp_page_phys = (__le64 *)mpt3sas_base_get_pcie_sgl_dma(ioc, smid);
 
/*
 * Check if we are within 1 entry of a page boundary we don't
@@ -1475,8 +1475,8 @@ _base_build_nvme_prp(struct MPT3SAS_ADAPTER *ioc, u16 
smid,
page_mask_result = (uintptr_t)((u8 *)prp_page + prp_size) & page_mask;
if (!page_mask_result) {
/* Bump up to next page boundary. */
-   prp_page = (u64 *)((u8 *)prp_page + prp_size);
-   prp_page_phys = (u64 *)((u8 *)prp_page_phys + prp_size);
+   prp_page = (__le64 *)((u8 *)prp_page + prp_size);
+   prp_page_phys = (__le64 *)((u8 *)prp_page_phys + prp_size);
}
 
/*
@@ -1604,7 +1604,7 @@ _base_build_nvme_prp(struct MPT3SAS_ADAPTER *ioc, u16 
smid,
  * Returns:true: PRPs are built
  * false: IEEE SGLs needs to be built
  */
-void
+static void
 base_make_prp_nvme(struct MPT3SAS_ADAPTER *ioc,
struct scsi_cmnd *scmd,
Mpi25SCSIIORequest_t *mpi_request,
@@ -1612,7 +1612,7 @@ base_make_prp_nvme(struct MPT3SAS_ADAPTER *ioc,
 {
int sge_len, offset, num_prp_in_chain = 0;
Mpi25IeeeSgeChain64_t *main_chain_element, *ptr_first_sgl;
-   u64 *curr_buff;
+   __le64 *curr_buff;
dma_addr_t msg_phys;
u64 sge_addr;
u32 page_mask, page_mask_result;
@@ -1736,7 +1736,6 @@ static bool
 base_is_prp_possible(struct MPT3SAS_ADAPTER *ioc,
struct _pcie_device *pcie_device, struct scsi_cmnd *scmd, int sge_count)
 {
-   u32 i;
u32 data_length = 0;
struct scatterlist *sg_scmd;
bool build_prp = false;
@@ -1746,7 +1745,7 @@ base_is_prp_possible(struct MPT3SAS_ADAPTER *ioc,
 
nvme_pg_size = max_t(u32, ioc->page_size,
NVME_PRP_PAGE_SIZE);
-   data_length = cpu_to_le32(scsi_bufflen(scmd));
+   data_length = scsi_bufflen(scmd);
sg_scmd = scsi_sglist(scmd);
 
/* Create page_mask (to get offset within page) */
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index aece862..6960d69 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -600,7 +600,7 @@ __mpt3sas_get_pdev_from_target(struct MPT3SAS_ADAPTER *ioc,
  *
  * This searches for pcie_device from target, then return pcie_device object.
  */
-struct _pcie_device *
+static struct _pcie_device *
 mpt3sas_get_pdev_from_target(struct MPT3SAS_ADAPTER *ioc,
struct MPT3SAS_TARGET *tgt_priv)
 {
@@ -908,7 +908,7 @@ _scsih_sas_device_init_add(struct MPT3SAS_ADAPTER *ioc,
 }
 
 
-struct _pcie_device *
+static struct _pcie_device *
 __mpt3sas_get_pdev_by_wwid(struct MPT3SAS_ADAPTER *ioc, u64 wwid)
 {
struct _pcie_device *pcie_device;
@@ -941,7 +941,7 @@ found_device:

[v5 07/14] mpt3sas: Handle NVMe PCIe device related events generated from firmware.

2017-08-30 Thread Suganath Prabu S
* The controller firmware sends separate events for NVMe devices and
PCIe switches similar to existing SAS events.

* NVMe device detection, addition and removal are reported by the
firmware through PCIe Topology Change list events.

* The PCIe device state change events are sent when the firmware
detects any abnormal conditions with a NVMe device or switch.

* The enumeration event are sent when the firmware starts PCIe device
enumeration and stops.

* This patch has the code change to handle the events and add/remove
NVMe devices in driver's inventory.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  30 ++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 471 ++-
 2 files changed, 495 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 9653cfa..6e0a940 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -663,6 +663,26 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc,
case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
desc = "Active cable exception";
break;
+   case MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE:
+   desc = "PCIE Device Status Change";
+   break;
+   case MPI2_EVENT_PCIE_ENUMERATION:
+   {
+   Mpi26EventDataPCIeEnumeration_t *event_data =
+   (Mpi26EventDataPCIeEnumeration_t *)mpi_reply->EventData;
+   pr_info(MPT3SAS_FMT "PCIE Enumeration: (%s)", ioc->name,
+  (event_data->ReasonCode ==
+   MPI26_EVENT_PCIE_ENUM_RC_STARTED) ?
+   "start" : "stop");
+   if (event_data->EnumerationStatus)
+   pr_info("enumeration_status(0x%08x)",
+  le32_to_cpu(event_data->EnumerationStatus));
+   pr_info("\n");
+   return;
+   }
+   case MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST:
+   desc = "PCIE Topology Change List";
+   break;
}
 
if (!desc)
@@ -6154,8 +6174,16 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
_base_unmask_events(ioc, MPI2_EVENT_IR_OPERATION_STATUS);
_base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED);
_base_unmask_events(ioc, MPI2_EVENT_TEMP_THRESHOLD);
-   if (ioc->hba_mpi_version_belonged == MPI26_VERSION)
+   if (ioc->hba_mpi_version_belonged == MPI26_VERSION) {
_base_unmask_events(ioc, MPI2_EVENT_ACTIVE_CABLE_EXCEPTION);
+   if (ioc->is_gen35_ioc) {
+   _base_unmask_events(ioc,
+   MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE);
+   _base_unmask_events(ioc, MPI2_EVENT_PCIE_ENUMERATION);
+   _base_unmask_events(ioc,
+   MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST);
+   }
+   }
 
r = _base_make_ioc_operational(ioc);
if (r)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 710ea63..344f946 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -75,6 +75,8 @@ static int _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle,
 static int _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle);
 static void _scsih_pcie_device_remove_from_sml(struct MPT3SAS_ADAPTER *ioc,
struct _pcie_device *pcie_device);
+static void
+_scsih_pcie_check_device(struct MPT3SAS_ADAPTER *ioc, u16 handle);
 static u8 _scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 
 /* global parameters */
@@ -3458,8 +3460,6 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
struct _sas_device *sas_device;
 
sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
-   if (!sas_device)
-   return;
 
shost_for_each_device(sdev, ioc->shost) {
sas_device_priv_data = sdev->hostdata;
@@ -3469,7 +3469,7 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
continue;
if (sas_device_priv_data->block)
continue;
-   if (sas_device->pend_sas_rphy_add)
+   if (sas_device && sas_device->pend_sas_rphy_add)
continue;
if (sas_device_priv_data->ignore_delay_remove) {
sdev_printk(KERN_INFO, sdev,
@@ -3480,7 +3480,8 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
_scsih_internal_device_block(sdev, sas_device_priv_data);
}
 
-   sas_device_put(sas_device);
+   if (sas_device)
+   sas_device_put(sas_device);
 }
 
 /**
@@ -3564,6 +3565,33 @@ _scsih_block_io_to_children_attached_directly(struct 
MPT3SAS_AD

[v5 02/14] mpt3sas: Add nvme device support in slave alloc, target alloc and probe

2017-08-30 Thread Suganath Prabu S
1) Added support for probing pcie device and adding NVMe drives to
SML and driver's internal list pcie_device_list.

2) Added support for determing NVMe as boot device.

3) Added nvme device support for call back functions scan_finished
target_alloc,slave_alloc,target destroy and slave destroy.

 a) During scan, pcie devices are probed and added to SML to drivers
internal list.

 b) target_alloc & slave alloc API's allocates resources for
(MPT3SAS_TARGET & MPT3SAS_DEVICE) private datas and holds
information like handle, target_id etc.

 c) slave_destroy & target_destroy are called when driver unregisters
or removes device. Also frees allocated resources and info.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h  | 110 -
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 431 ---
 2 files changed, 507 insertions(+), 34 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 099ab4c..c522057 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -159,6 +159,7 @@
 #define MPT_TARGET_FLAGS_VOLUME0x02
 #define MPT_TARGET_FLAGS_DELETED   0x04
 #define MPT_TARGET_FASTPATH_IO 0x08
+#define MPT_TARGET_FLAGS_PCIE_DEVICE   0x10
 
 #define SAS2_PCI_DEVICE_B0_REVISION(0x01)
 #define SAS3_PCI_DEVICE_C0_REVISION(0x02)
@@ -357,7 +358,8 @@ struct Mpi2ManufacturingPage11_t {
  * @flags: MPT_TARGET_FLAGS_XXX flags
  * @deleted: target flaged for deletion
  * @tm_busy: target is busy with TM request.
- * @sdev: The sas_device associated with this target
+ * @sas_dev: The sas_device associated with this target
+ * @pcie_dev: The pcie device associated with this target
  */
 struct MPT3SAS_TARGET {
struct scsi_target *starget;
@@ -368,7 +370,8 @@ struct MPT3SAS_TARGET {
u32 flags;
u8  deleted;
u8  tm_busy;
-   struct _sas_device *sdev;
+   struct _sas_device *sas_dev;
+   struct _pcie_device *pcie_dev;
 };
 
 
@@ -508,6 +511,89 @@ static inline void sas_device_put(struct _sas_device *s)
kref_put(&s->refcount, sas_device_free);
 }
 
+/*
+ * struct _pcie_device - attached PCIe device information
+ * @list: pcie device list
+ * @starget: starget object
+ * @wwid: device WWID
+ * @handle: device handle
+ * @device_info: bitfield provides detailed info about the device
+ * @id: target id
+ * @channel: target channel
+ * @slot: slot number
+ * @port_num: port number
+ * @responding: used in _scsih_pcie_device_mark_responding
+ * @fast_path: fast path feature enable bit
+ * @nvme_mdts: MaximumDataTransferSize from PCIe Device Page 2 for
+ * NVMe device only
+ * @enclosure_handle: enclosure handle
+ * @enclosure_logical_id: enclosure logical identifier
+ * @enclosure_level: The level of device's enclosure from the controller
+ * @connector_name: ASCII value of the Connector's name
+ * @serial_number: pointer of serial number string allocated runtime
+ * @refcount: reference count for deletion
+ */
+struct _pcie_device {
+   struct list_head list;
+   struct scsi_target *starget;
+   u64 wwid;
+   u16 handle;
+   u32 device_info;
+   int id;
+   int channel;
+   u16 slot;
+   u8  port_num;
+   u8  responding;
+   u8  fast_path;
+   u32 nvme_mdts;
+   u16 enclosure_handle;
+   u64 enclosure_logical_id;
+   u8  enclosure_level;
+   u8  connector_name[4];
+   u8  *serial_number;
+   struct kref refcount;
+};
+/**
+ * pcie_device_get - Increment the pcie device reference count
+ *
+ * @p: pcie_device object
+ *
+ * When ever this function called it will increment the
+ * reference count of the pcie device for which this function called.
+ *
+ */
+static inline void pcie_device_get(struct _pcie_device *p)
+{
+   kref_get(&p->refcount);
+}
+
+/**
+ * pcie_device_free - Release the pcie device object
+ * @r - kref object
+ *
+ * Free's the pcie device object. It will be called when reference count
+ * reaches to zero.
+ */
+static inline void pcie_device_free(struct kref *r)
+{
+   kfree(container_of(r, struct _pcie_device, refcount));
+}
+
+/**
+ * pcie_device_put - Decrement the pcie device reference count
+ *
+ * @p: pcie_device object
+ *
+ * When ever this function called it will decrement the
+ * reference count of the pcie device for which this function called.
+ *
+ * When refernce count reaches to Zero, this will call pcie_device_free to the
+ * pcie_device object.
+ */
+static inline void pcie_device_put(struct _pcie_device *p)
+{
+   kref_put(&p->refcount, pcie_device_free);
+}
 /**
  * struct _raid_device - raid volume link list
  * @list: sas device list
@@ -556,12 +642,13 @@ struct _raid_device {
 
 /**
  * struct _boot_device - boot device info
- * @is_raid: flag to indicate whether this is volume
- * @devic

[v5 00/14] mpt3sas driver NVMe support:

2017-08-30 Thread Suganath Prabu S
Ventura Series controller are Tri-mode. The controller and
firmware are capable of supporting NVMe devices and
PCIe switches to be connected with the controller. This
patch set adds driver level support for NVMe devices and
PCIe switches.

mpt3sas v5 patset:
1) Removed the check to find data transfer length
exceeding MDTS, Since we are setting max I/O size to
match MDTS, this check is not required.

mpt3sas v4 patset:
1) Removed code which detects gaps/holes in IO data buffers.
With commit-id 5a8d75a1b8c99bdc926ba69b7b7dbe4fae81a5af (block:
fix bio_will_gap() for first bvec with offset) driver can always assume that
their won't be any holes in the data buffers pointed by SGE's

2) Added Patch 14, This has sparse warning fixes.

mpt3sas v3 patset:
Posting version v3. This accommodates below changes
over v2 patch.

1. In the MPI header files patch, Reformatted headers to have type
and variable on one line as suggested.
2. As suggested, started using blk_queue_virt_boundary() API
for NVMe drives and simplified the PRP formation.
3. Removed 'TODO' comments

Suganath Prabu S (14):
  Update MPI Header
  mpt3sas: Add nvme device support in slave alloc,  target  alloc
and probe
  mpt3sas: SGL to PRP Translation for I/Os to NVMe  devices
  mpt3sas: Added support for nvme encapsulated request  message.
  mpt3sas: API 's to support NVMe drive addition to  SML
  mpt3sas: API's to remove nvme drive from sml
  mpt3sas: Handle NVMe PCIe device related events  generated
   from firmware.
  mpt3sas: Set NVMe device queue depth as 128
  mpt3sas: scan and add nvme device after controller  reset
  mpt3as: Add-Task-management-debug-info-for-NVMe-drives.
  mpt3sas: NVMe drive support for BTDHMAPPING ioctl  command  and
log info
  mpt3sas: Fix nvme drives checking for tlr.
  mpt3sas: Update mpt3sas driver version.
  mpt3sas: Fix sparse warnings

 drivers/scsi/mpt3sas/mpi/mpi2.h  |   43 +-
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h |  564 +++-
 drivers/scsi/mpt3sas/mpi/mpi2_init.h |   11 +-
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  |  282 +++-
 drivers/scsi/mpt3sas/mpi/mpi2_pci.h  |  112 ++
 drivers/scsi/mpt3sas/mpi/mpi2_tool.h |   14 +-
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  675 +-
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  171 ++-
 drivers/scsi/mpt3sas/mpt3sas_config.c|  100 ++
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |  158 ++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 2079 +++---
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |2 +-
 12 files changed, 3937 insertions(+), 274 deletions(-)
 create mode 100644 drivers/scsi/mpt3sas/mpi/mpi2_pci.h

-- 
2.5.5



[PATCH] scsi: hpsa: make access_method const

2017-08-30 Thread Bhumika Goyal
Make these const as they are not modified anywhere.

Signed-off-by: Bhumika Goyal 
---
To compile-test hpsa.h, I test-compiled scsi/hpsa.c which
includes this file.

 drivers/scsi/hpsa.h | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index 018f980..4688b8f 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -628,28 +628,28 @@ static unsigned long SA5_ioaccel_mode1_completed(struct 
ctlr_info *h, u8 q)
.command_completed =SA5_completed,
 };
 
-static struct access_method SA5_ioaccel_mode1_access = {
+static const struct access_method SA5_ioaccel_mode1_access = {
.submit_command =   SA5_submit_command,
.set_intr_mask =SA5_performant_intr_mask,
.intr_pending = SA5_ioaccel_mode1_intr_pending,
.command_completed =SA5_ioaccel_mode1_completed,
 };
 
-static struct access_method SA5_ioaccel_mode2_access = {
+static const struct access_method SA5_ioaccel_mode2_access = {
.submit_command =   SA5_submit_command_ioaccel2,
.set_intr_mask =SA5_performant_intr_mask,
.intr_pending = SA5_performant_intr_pending,
.command_completed =SA5_performant_completed,
 };
 
-static struct access_method SA5_performant_access = {
+static const struct access_method SA5_performant_access = {
.submit_command =   SA5_submit_command,
.set_intr_mask =SA5_performant_intr_mask,
.intr_pending = SA5_performant_intr_pending,
.command_completed =SA5_performant_completed,
 };
 
-static struct access_method SA5_performant_access_no_read = {
+static const struct access_method SA5_performant_access_no_read = {
.submit_command =   SA5_submit_command_no_read,
.set_intr_mask =SA5_performant_intr_mask,
.intr_pending = SA5_performant_intr_pending,
-- 
1.9.1



RE: [PATCH] scsi: ufs: reqs and tasks were put in the wrong order

2017-08-30 Thread Avri Altman


> -Original Message-
> From: linux-scsi-ow...@vger.kernel.org [mailto:linux-scsi-
> ow...@vger.kernel.org] On Behalf Of Zang Leigang
> Sent: Thursday, August 24, 2017 5:57 AM
> To: vinholika...@gmail.com; j...@linux.vnet.ibm.com;
> martin.peter...@oracle.com
> Cc: linux-scsi@vger.kernel.org
> Subject: [PATCH] scsi: ufs: reqs and tasks were put in the wrong order
> 
> Signed-off-by: Zang Leigang 
Acked-by: Avri Altman 

> 
> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index
> 5bc9dc14e075..794a4600e952 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -438,7 +438,7 @@ static void ufshcd_print_host_state(struct ufs_hba
> *hba)  {
>   dev_err(hba->dev, "UFS Host state=%d\n", hba->ufshcd_state);
>   dev_err(hba->dev, "lrb in use=0x%lx, outstanding reqs=0x%lx
> tasks=0x%lx\n",
> - hba->lrb_in_use, hba->outstanding_tasks, hba-
> >outstanding_reqs);
> + hba->lrb_in_use, hba->outstanding_reqs, hba-
> >outstanding_tasks);
>   dev_err(hba->dev, "saved_err=0x%x, saved_uic_err=0x%x\n",
>   hba->saved_err, hba->saved_uic_err);
>   dev_err(hba->dev, "Device power mode=%d, UIC link state=%d\n",
> --
> 2.14.1



[PATCH v2] scsi: qla2xxx: Fix an integer overflow in sysfs code

2017-08-30 Thread Dan Carpenter
The value of "size" comes from the user.  When we add "start + size"
it could lead to an integer overflow bug.

It means we vmalloc() a lot more memory than we had intended.  I believe
that on 64 bit systems vmalloc() can succeed even if we ask it to
allocate huge 4GB buffers.  So we would get memory corruption and likely
a crash when we call ha->isp_ops->write_optrom() and ->read_optrom().

Only root can trigger this bug.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=194061

Cc: sta...@vger.kernel.org
Fixes: b7cc176c9eb3 ("[SCSI] qla2xxx: Allow region-based flash-part accesses.")
Reported-by: shqking 
Signed-off-by: Dan Carpenter 
---
v2: Add stable and the URL for bugzila

diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 75c4b312645e..9ce28c4f9812 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -318,6 +318,8 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct 
kobject *kobj,
return -EINVAL;
if (start > ha->optrom_size)
return -EINVAL;
+   if (size > ha->optrom_size - start)
+   size = ha->optrom_size - start;
 
mutex_lock(&ha->optrom_mutex);
switch (val) {
@@ -343,8 +345,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct 
kobject *kobj,
}
 
ha->optrom_region_start = start;
-   ha->optrom_region_size = start + size > ha->optrom_size ?
-   ha->optrom_size - start : size;
+   ha->optrom_region_size = start + size;
 
ha->optrom_state = QLA_SREADING;
ha->optrom_buffer = vmalloc(ha->optrom_region_size);
@@ -417,8 +418,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct 
kobject *kobj,
}
 
ha->optrom_region_start = start;
-   ha->optrom_region_size = start + size > ha->optrom_size ?
-   ha->optrom_size - start : size;
+   ha->optrom_region_size = start + size;
 
ha->optrom_state = QLA_SWRITING;
ha->optrom_buffer = vmalloc(ha->optrom_region_size);


[GIT PULL] SCSI fixes for 4.13-rc6

2017-08-30 Thread James Bottomley
Three minor fixes: a NULL deref in qedf, an off by one in sg and a fix
to IPR to prevent an error on initialisation.

The patch is available here:

git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git scsi-fixes

The short changelog is:

Brian King (1):
  scsi: ipr: Set no_report_opcodes for RAID arrays

Christophe JAILLET (1):
  scsi: qedf: Fix a potential NULL pointer dereference

Dan Carpenter (1):
  scsi: sg: off by one in sg_ioctl()

And the diffstat:

 drivers/scsi/ipr.c   |  1 +
 drivers/scsi/qedf/qedf_els.c | 14 --
 drivers/scsi/sg.c|  2 +-
 3 files changed, 10 insertions(+), 7 deletions(-)

With full diff below.

James

---

diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index da5bdbdcce52..f838bd73befa 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -4945,6 +4945,7 @@ static int ipr_slave_configure(struct scsi_device *sdev)
}
if (ipr_is_vset_device(res)) {
sdev->scsi_level = SCSI_SPC_3;
+   sdev->no_report_opcodes = 1;
blk_queue_rq_timeout(sdev->request_queue,
 IPR_VSET_RW_TIMEOUT);
blk_queue_max_hw_sectors(sdev->request_queue, 
IPR_VSET_MAX_SECTORS);
diff --git a/drivers/scsi/qedf/qedf_els.c b/drivers/scsi/qedf/qedf_els.c
index eb07f1de8afa..59c18ca4cda9 100644
--- a/drivers/scsi/qedf/qedf_els.c
+++ b/drivers/scsi/qedf/qedf_els.c
@@ -489,7 +489,7 @@ static void qedf_srr_compl(struct qedf_els_cb_arg *cb_arg)
 
/* If a SRR times out, simply free resources */
if (srr_req->event == QEDF_IOREQ_EV_ELS_TMO)
-   goto out_free;
+   goto out_put;
 
/* Normalize response data into struct fc_frame */
mp_req = &(srr_req->mp_req);
@@ -501,7 +501,7 @@ static void qedf_srr_compl(struct qedf_els_cb_arg *cb_arg)
if (!fp) {
QEDF_ERR(&(qedf->dbg_ctx),
"fc_frame_alloc failure.\n");
-   goto out_free;
+   goto out_put;
}
 
/* Copy frame header from firmware into fp */
@@ -526,9 +526,10 @@ static void qedf_srr_compl(struct qedf_els_cb_arg *cb_arg)
}
 
fc_frame_free(fp);
-out_free:
+out_put:
/* Put reference for original command since SRR completed */
kref_put(&orig_io_req->refcount, qedf_release_cmd);
+out_free:
kfree(cb_arg);
 }
 
@@ -780,7 +781,7 @@ static void qedf_rec_compl(struct qedf_els_cb_arg *cb_arg)
 
/* If a REC times out, free resources */
if (rec_req->event == QEDF_IOREQ_EV_ELS_TMO)
-   goto out_free;
+   goto out_put;
 
/* Normalize response data into struct fc_frame */
mp_req = &(rec_req->mp_req);
@@ -792,7 +793,7 @@ static void qedf_rec_compl(struct qedf_els_cb_arg *cb_arg)
if (!fp) {
QEDF_ERR(&(qedf->dbg_ctx),
"fc_frame_alloc failure.\n");
-   goto out_free;
+   goto out_put;
}
 
/* Copy frame header from firmware into fp */
@@ -884,9 +885,10 @@ static void qedf_rec_compl(struct qedf_els_cb_arg *cb_arg)
 
 out_free_frame:
fc_frame_free(fp);
-out_free:
+out_put:
/* Put reference for original command since REC completed */
kref_put(&orig_io_req->refcount, qedf_release_cmd);
+out_free:
kfree(cb_arg);
 }
 
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index d7ff71e0c85c..84e782d8e7c3 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1021,7 +1021,7 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned 
long arg)
read_lock_irqsave(&sfp->rq_list_lock, iflags);
val = 0;
list_for_each_entry(srp, &sfp->rq_list, entry) {
-   if (val > SG_MAX_QUEUE)
+   if (val >= SG_MAX_QUEUE)
break;
memset(&rinfo[val], 0, SZ_SG_REQ_INFO);
rinfo[val].req_state = srp->done + 1;


Re: [PATCH] scsi: qla2xxx: Fix an integer overflow in sysfs code

2017-08-30 Thread Eric Dumazet
On Wed, Aug 30, 2017 at 6:12 AM, Greg KH  wrote:
> On Wed, Aug 30, 2017 at 03:21:07PM +0300, Dan Carpenter wrote:
>> The value of "size" comes from the user.  When we add "start + size"
>> it could lead to an integer overflow bug.
>>
>> It means we vmalloc() a lot more memory than we had intended.  I believe
>> that on 64 bit systems vmalloc() can succeed even if we ask it to
>> allocate huge 4GB buffers.  So we would get memory corruption and likely
>> a crash when we call ha->isp_ops->write_optrom() and ->read_optrom().
>>
>> Only root can trigger this bug.
>>
>> Fixes: b7cc176c9eb3 ("[SCSI] qla2xxx: Allow region-based flash-part 
>> accesses.")
>> Reported-by: shqking 
>> Signed-off-by: Dan Carpenter 
>
>
> Cc: stable 
>
> perhaps?
>
> thanks,
>
> greg k-h

Also a link to https://bugzilla.kernel.org/show_bug.cgi?id=194061
since shqking did a fair bit of analysis, not only report the bug.

Thanks.


[PATCH] qla2xxx: add missing includes for qla_isr

2017-08-30 Thread Johannes Thumshirn
Since commit 7401bc18d1ee ("scsi: qla2xxx: Add FC-NVMe command handling")
we make use of 'struct nvmefc_fcp_req' in qla24xx_nvme_iocb_entry() without
including linux/nvme-fc-driver.h where it is defined.

Add linux/nvme-fc-driver.h (and scsi/fc/fc_fs.h as nvme-fc-driver.h needs
the definition of 'struct fc_ba_rjt' from scsi/fc/fc_fs.h) to the header
files included by qla_isr.c.

Fixes: 7401bc18d1ee ("scsi: qla2xxx: Add FC-NVMe command handling")
Signed-off-by: Johannes Thumshirn 
---
 drivers/scsi/qla2xxx/qla_isr.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 7b3b702ef622..b57cbe4ec32b 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -14,6 +14,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
 static void qla2x00_status_entry(scsi_qla_host_t *, struct rsp_que *, void *);
-- 
2.12.3



Re: [PATCH] scsi: qla2xxx: Fix an integer overflow in sysfs code

2017-08-30 Thread Greg KH
On Wed, Aug 30, 2017 at 03:21:07PM +0300, Dan Carpenter wrote:
> The value of "size" comes from the user.  When we add "start + size"
> it could lead to an integer overflow bug.
> 
> It means we vmalloc() a lot more memory than we had intended.  I believe
> that on 64 bit systems vmalloc() can succeed even if we ask it to
> allocate huge 4GB buffers.  So we would get memory corruption and likely
> a crash when we call ha->isp_ops->write_optrom() and ->read_optrom().
> 
> Only root can trigger this bug.
> 
> Fixes: b7cc176c9eb3 ("[SCSI] qla2xxx: Allow region-based flash-part 
> accesses.")
> Reported-by: shqking 
> Signed-off-by: Dan Carpenter 


Cc: stable 

perhaps?

thanks,

greg k-h


Re: [PATCH] scsi: qla2xxx: Fix an integer overflow in sysfs code

2017-08-30 Thread Dan Carpenter
On Wed, Aug 30, 2017 at 08:28:52PM +0800, shqking wrote:
> Hi,
> 
> Glad to see it is fixed.
> 
> Can I apply for a CVE ID for this bug?
> 

We don't handle that on this list.  You'd need to ask on
oss-secur...@lists.openwall.com.

regards,
dan carpenter



Re: [PATCH v4 00/14] mpt3sas driver NVMe support:

2017-08-30 Thread Suganath Prabu Subramani
Hi Martin,

Replied in line.

- I don't understand why you go through all these hoops to decide
  whether to use PRPs or IEEE scatterlists. If the firmware translation
  is slow, why even bother with the SG format in the first place? Set
  the max I/O size to match MDTS and you're done.

=>  We will  set MDTS value as max hw sectors using
blk_queue_max_hw_sectors(). As of now, we see correct MDTS value is
being set to block layer via VPD page 0xb0 (Block limits VPD page )
response from FW for NVME device.
=> I will remove MDTS checks in IO path.


- What's the benefit of using SG for regular I/O commands?

=>  Broadcom's IT Tri-mode HBA hardware has a capability of
translating IEEE SGLs to PRP's only up to ~4 page block size.
If the IO block size is greater than that (along with other condition
described code base_is_prp_possible), driver has to frame the PRP's to
avoid FW intervention. Both the case is a fast path, but for smaller
IO (up to 20K) size will frame IEEE SGL and large IO size will frame
PRP format SGL. Theoretically we want to use h/w capability (to
translate IEEE to PRP) for smaller IO size to leverage h/w capability.
We are investigating if at all we can send all PRP and avoid checks in
driver, but that exercise may take time as we have many different
opinions. We prefer to use existing code as it is stable and in-line
with h/w requirement.


- If the unmap translation in firmware is slow, why don't you translate
  WRITE SAME/w UNMAP set to DSM DEALLOCATE without requiring
  applications to do encapsulated passthrough?

=> As of now, current FW supports UNMAP command but not WRITE_SAME for
NVME drive. We did some experiment to convert UMAP command in driver,
but that is not really giving any performance improvement. We would
like to continue with UNMAP (and all other non-read/write commands) to
be handled in FW.


- Also make sure you attribute your patches correctly (From: root
). And you don't need
that long CC: list. Just send the patch series to
linux-scsi@vger.kernel.org.

=>  I will fix this type of issue going forward

Thanks,
Suganath Prabu S

On Wed, Aug 23, 2017 at 7:48 AM, Martin K. Petersen
 wrote:
>
> Suganath,
>
>>   mpt3sas: SGL to PRP Translation for I/Os to NVMe  devices
>
> I'm still confused about this patch.
>
>  - I don't understand why you go through all these hoops to decide
>whether to use PRPs or IEEE scatterlists. If the firmware translation
>is slow, why even bother with the SG format in the first place? Set
>the max I/O size to match MDTS and you're done.
>
>  - What's the benefit of using SG for regular I/O commands?
>
>  - If the unmap translation in firmware is slow, why don't you translate
>WRITE SAME/w UNMAP set to DSM DEALLOCATE without requiring
>applications to do encapsulated passthrough?
>
> Also make sure you attribute your patches correctly (From: root
> ). And you don't need that
> long CC: list. Just send the patch series to linux-scsi@vger.kernel.org.
>
> Thanks!
>
> --
> Martin K. Petersen  Oracle Linux Engineering


Re: possible circular locking dependency detected [was: linux-next: Tree for Aug 22]

2017-08-30 Thread Sergey Senozhatsky
Hello Peter,

On (08/30/17 10:47), Peter Zijlstra wrote:
[..]
> On Wed, Aug 30, 2017 at 10:42:07AM +0200, Peter Zijlstra wrote:
> > 
> > So the overhead looks to be spread out over all sorts, which makes it
> > harder to find and fix.
> > 
> > stack unwinding is done lots and is fairly expensive, I've not yet
> > checked if crossrelease does too much of that.
> 
> Aah, we do an unconditional stack unwind for every __lock_acquire() now.
> It keeps a trace in the xhlocks[].
> 
> Does the below cure most of that overhead?

thanks.

mostly yes. the kernel is not so dramatically slower now. it's still
seems to be a bit slower, which is expected I suppose, but over all
it's much better

real1m35.209s
user4m12.467s
sys 0m49.457s

// approx 10 seconds slower.

-ss


[PATCH] scsi: qla2xxx: Fix an integer overflow in sysfs code

2017-08-30 Thread Dan Carpenter
The value of "size" comes from the user.  When we add "start + size"
it could lead to an integer overflow bug.

It means we vmalloc() a lot more memory than we had intended.  I believe
that on 64 bit systems vmalloc() can succeed even if we ask it to
allocate huge 4GB buffers.  So we would get memory corruption and likely
a crash when we call ha->isp_ops->write_optrom() and ->read_optrom().

Only root can trigger this bug.

Fixes: b7cc176c9eb3 ("[SCSI] qla2xxx: Allow region-based flash-part accesses.")
Reported-by: shqking 
Signed-off-by: Dan Carpenter 

diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 75c4b312645e..9ce28c4f9812 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -318,6 +318,8 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct 
kobject *kobj,
return -EINVAL;
if (start > ha->optrom_size)
return -EINVAL;
+   if (size > ha->optrom_size - start)
+   size = ha->optrom_size - start;
 
mutex_lock(&ha->optrom_mutex);
switch (val) {
@@ -343,8 +345,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct 
kobject *kobj,
}
 
ha->optrom_region_start = start;
-   ha->optrom_region_size = start + size > ha->optrom_size ?
-   ha->optrom_size - start : size;
+   ha->optrom_region_size = start + size;
 
ha->optrom_state = QLA_SREADING;
ha->optrom_buffer = vmalloc(ha->optrom_region_size);
@@ -417,8 +418,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct 
kobject *kobj,
}
 
ha->optrom_region_start = start;
-   ha->optrom_region_size = start + size > ha->optrom_size ?
-   ha->optrom_size - start : size;
+   ha->optrom_region_size = start + size;
 
ha->optrom_state = QLA_SWRITING;
ha->optrom_buffer = vmalloc(ha->optrom_region_size);


Re: [PATCHv4 2/5] scsi: Export blacklist flags to sysfs

2017-08-30 Thread Hannes Reinecke
On 08/29/2017 06:02 PM, Bart Van Assche wrote:
> On Tue, 2017-08-29 at 10:49 +0200, Hannes Reinecke wrote:
>> [ ... ]
>> +$(obj)/scsi_sysfs.o: $(obj)/scsi_devinfo_tbl.c
>> +
>> +quiet_cmd_bflags = GEN $@
>> +cmd_bflags = $(PERL) -s $(src)/mktbl.pl BLIST $< > $@
> 
> Hello Hannes,
> 
> Is it considered acceptable to require that perl is available to build the
> kernel? People who build the kernel for embedded systems probably won't be
> happy if this is a new requirement. See e.g. "PATCH [0/3]: Simplify the
> kernel build by removing perl" (https://lkml.org/lkml/2009/1/2/20).
> 
> Have you noticed that for other generated files a _shipped version is
> provided?
> 
Ah. Good point. Will be doing so.

>> +
>> +$(obj)/scsi_devinfo_tbl.c: include/scsi/scsi_devinfo.h
>> +$(call if_changed,bflags)
>> +
>>  # If you want to play with the firmware, uncomment
>>  # GENERATE_FIRMWARE := 1
>>  
>> diff --git a/drivers/scsi/mktbl.pl b/drivers/scsi/mktbl.pl
>> [ ... ]
>> +my $prf;
>> +
>> +$prf = $ARGV[0];
>> +open IN_FILE, "<$ARGV[1]" || die;
>> +print "\t/*\n\t * Automatically generated by ", $0, ".\n";
>> +print "\t * Do not edit.\n\t */\n";
>> +while () {
>> +chomp;
>> +if (/^#define ${prf}_([^[:blank:]]*).*/) {
>> +print "\t{ ", $prf, "_", $1, ", \"", $1, "\" },\n";
>> +}
>> +}
>> +close IN_FILE || die;
> 
> Can this be done with sed? Do we really need Perl for this?
> 
In principle, sure. I just failed to stuff everything into a makefile
line, so perl was easier to code.

>> [ ... ]
>> +static const struct {
>> +unsigned intvalue;
>> +char*name;
> 
> Can 'char *' be changed into 'const char *'?
> 
Sure; why not.

>> +} sdev_bflags[] = {
>> +#include "scsi_devinfo_tbl.c"
>> +};
>> +
>> +static const char *sdev_bflags_name(unsigned int bflags)
>> +{
>> +int i;
>> +const char *name = NULL;
>> +
>> +for (i = 0; i < ARRAY_SIZE(sdev_bflags); i++) {
>> +if (sdev_bflags[i].value == bflags) {
>> +name = sdev_bflags[i].name;
>> +break;
>> +}
>> +}
>> +return name;
>> +}
> 
> How about using ilog2() of the BLIST_* values as index of the table such that
> an array lookup can be used instead of a for-loop over the entire array?
> 
Not sure if that'll work. The BLIST_* values in fact form a sparse
array, so the lookup array 'sdev_bflags' actually an associative array.
And I dare not convert it to a normal array as then I couldn't to the
automatice table creation anymore.

So I'm not sure if ilog2 will save me anything here.

>> +
>>  static int check_set(unsigned long long *val, char *src)
>>  {
>>  char *last;
>> @@ -955,6 +977,43 @@ static DEVICE_ATTR(queue_depth, S_IRUGO | S_IWUSR, 
>> sdev_show_queue_depth,
>>  }
>>  static DEVICE_ATTR(wwid, S_IRUGO, sdev_show_wwid, NULL);
>>  
>> +static ssize_t
>> +sdev_show_blacklist(struct device *dev, struct device_attribute *attr,
>> +char *buf)
>> +{
>> +struct scsi_device *sdev = to_scsi_device(dev);
>> +int i;
>> +char *ptr = buf;
>> +ssize_t len = 0;
>> +
>> +for (i = 0; i < sizeof(unsigned int) * 8; i++) {
>> +unsigned int bflags = (unsigned int)1 << i;
> 
> How about using 1U instead of (unsigned int)1?
> 
Yeah, ok.

>> +ssize_t blen;
>> +const char *name = NULL;
>> +
>> +if (!(bflags & sdev->sdev_bflags))
>> +continue;
>> +
>> +if (ptr != buf) {
>> +blen = snprintf(ptr, 2, " ");
>> +ptr += blen;
>> +len += blen;
>> +}
> 
> Should this code check whether or not it overflows the output buffer @buf?
> 
Hmm. In principle, yes.
However, as we're only have a limited number of possible arguments and
hence a fixed upper limit of what we can print into the buffer I'm not
sure if that's required.
But I'll check.

>> +name = sdev_bflags_name(bflags);
>> +if (name)
>> +blen = snprintf(ptr, strlen(name) + 1,
>> +"%s", name);
>> +else
>> +blen = snprintf(ptr, 67, "INVALID_BIT(%d)", i);
>> +ptr += blen;
>> +len += blen;
>> +}
> 
> Should this code check too whether or not it overflows the output buffer @buf?
> 
See above.

Cheers,

Hannes
-- 
Dr. Hannes ReineckeTeamlead Storage & Networking
h...@suse.de   +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)


[PATCH] [SCSI] esas2r: make default_sas_nvram const

2017-08-30 Thread Bhumika Goyal
Make this const as it is never modified.

Signed-off-by: Bhumika Goyal 
---
 drivers/scsi/esas2r/esas2r_flash.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/esas2r/esas2r_flash.c 
b/drivers/scsi/esas2r/esas2r_flash.c
index 7bd376d..f8414b5 100644
--- a/drivers/scsi/esas2r/esas2r_flash.c
+++ b/drivers/scsi/esas2r/esas2r_flash.c
@@ -54,7 +54,7 @@
 
 #define ESAS2R_FS_DRVR_VER 2
 
-static struct esas2r_sas_nvram default_sas_nvram = {
+static const struct esas2r_sas_nvram default_sas_nvram = {
{ 'E',  'S',  'A',  'S'  }, /* signature  */
SASNVR_VERSION, /* version*/
0,  /* checksum   */
-- 
1.9.1



RE: possible circular locking dependency detected [was: linux-next: Tree for Aug 22]

2017-08-30 Thread Byungchul Park
> -Original Message-
> From: Peter Zijlstra [mailto:pet...@infradead.org]
> Sent: Wednesday, August 30, 2017 5:48 PM
> To: Sergey Senozhatsky
> Cc: Byungchul Park; Bart Van Assche; linux-ker...@vger.kernel.org; linux-
> bl...@vger.kernel.org; martin.peter...@oracle.com; ax...@kernel.dk; linux-
> s...@vger.kernel.org; s...@canb.auug.org.au; linux-n...@vger.kernel.org;
> kernel-t...@lge.com
> Subject: Re: possible circular locking dependency detected [was: linux-
> next: Tree for Aug 22]
> 
> On Wed, Aug 30, 2017 at 10:42:07AM +0200, Peter Zijlstra wrote:
> >
> > So the overhead looks to be spread out over all sorts, which makes it
> > harder to find and fix.
> >
> > stack unwinding is done lots and is fairly expensive, I've not yet
> > checked if crossrelease does too much of that.
> 
> Aah, we do an unconditional stack unwind for every __lock_acquire() now.
> It keeps a trace in the xhlocks[].

Yeah.. I also think this is most significant..

> 
> Does the below cure most of that overhead?
> 
> diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
> index 44c8d0d17170..7b872036b72e 100644
> --- a/kernel/locking/lockdep.c
> +++ b/kernel/locking/lockdep.c
> @@ -4872,7 +4872,7 @@ static void add_xhlock(struct held_lock *hlock)
>   xhlock->trace.max_entries = MAX_XHLOCK_TRACE_ENTRIES;
>   xhlock->trace.entries = xhlock->trace_entries;
>   xhlock->trace.skip = 3;
> - save_stack_trace(&xhlock->trace);
> + /* save_stack_trace(&xhlock->trace); */
>  }
> 
>  static inline int same_context_xhlock(struct hist_lock *xhlock)



Re: possible circular locking dependency detected [was: linux-next: Tree for Aug 22]

2017-08-30 Thread Peter Zijlstra
On Wed, Aug 30, 2017 at 10:42:07AM +0200, Peter Zijlstra wrote:
> 
> So the overhead looks to be spread out over all sorts, which makes it
> harder to find and fix.
> 
> stack unwinding is done lots and is fairly expensive, I've not yet
> checked if crossrelease does too much of that.

Aah, we do an unconditional stack unwind for every __lock_acquire() now.
It keeps a trace in the xhlocks[].

Does the below cure most of that overhead?

diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 44c8d0d17170..7b872036b72e 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -4872,7 +4872,7 @@ static void add_xhlock(struct held_lock *hlock)
xhlock->trace.max_entries = MAX_XHLOCK_TRACE_ENTRIES;
xhlock->trace.entries = xhlock->trace_entries;
xhlock->trace.skip = 3;
-   save_stack_trace(&xhlock->trace);
+   /* save_stack_trace(&xhlock->trace); */
 }
 
 static inline int same_context_xhlock(struct hist_lock *xhlock)


Re: possible circular locking dependency detected [was: linux-next: Tree for Aug 22]

2017-08-30 Thread Peter Zijlstra
On Wed, Aug 30, 2017 at 03:15:11PM +0900, Sergey Senozhatsky wrote:
> Hi,
> 
> On (08/30/17 14:43), Byungchul Park wrote:
> [..]
> > > notably slower than earlier 4.13 linux-next. (e.g. scrolling in vim
> > > is irritatingly slow)
> > 
> > To Ingo,
> > 
> > I cannot decide if we have to roll back CONFIG_LOCKDEP_CROSSRELEASE
> > dependency on CONFIG_PROVE_LOCKING in Kconfig. With them enabled,
> > lockdep detection becomes strong but has performance impact. But,
> > it's anyway a debug option so IMHO we don't have to take case of the
> > performance impact. Please let me know your decision.
> 
> well, I expected it :)
> 
> I've been running lockdep enabled kernels for years, and was OK with
> the performance. but now it's just too much and I'm looking at disabling
> lockdep.
> 
> a more relevant test -- compilation of a relatively small project
> 
>   LOCKDEP -CROSSRELEASE -COMPLETIONS LOCKDEP +CROSSRELEASE +COMPLETIONS
> 
>real1m23.722s  real2m9.969s
>user4m11.300s  user4m15.458s
>sys 0m49.386s  sys 2m3.594s
> 
> 
> you don't want to know how much time now it takes to recompile the
> kernel ;)

Right,.. so when I look at perf annotate for __lock_acquire and
lock_release (the two most expensive lockdep functions in a kernel
profile) I don't actually see much cross-release stuff.

So the overhead looks to be spread out over all sorts, which makes it
harder to find and fix.

stack unwinding is done lots and is fairly expensive, I've not yet
checked if crossrelease does too much of that.

The below saved about 50% of my __lock_acquire() time, not sure it made
a significant difference over all though.

---
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 44c8d0d17170..f8db1ead1c48 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -3386,7 +3386,7 @@ static int __lock_acquire(struct lockdep_map *lock, 
unsigned int subclass,
if (!class)
return 0;
}
-   atomic_inc((atomic_t *)&class->ops);
+   /* atomic_inc((atomic_t *)&class->ops); */
if (very_verbose(class)) {
printk("\nacquire class [%p] %s", class->key, class->name);
if (class->name_version > 1)


Re: [PATCH v2 2/3] Improve requeuing behavior

2017-08-30 Thread Christoph Hellwig
Looks good,

Reviewed-by: Christoph Hellwig 


Re: [PATCH v2 3/3] Show .retries and .jiffies_at_alloc in debugfs

2017-08-30 Thread Christoph Hellwig
Looks fine,

Reviewed-by: Christoph Hellwig 


Re: [PATCH v2 1/3] Call scsi_initialize_rq() also for filesystem requests

2017-08-30 Thread Christoph Hellwig
Looks good except for the subject, which will need a little update:

Reviewed-by: Christoph Hellwig 


Business Proposal for you!!

2017-08-30 Thread Mr. Saeed Bin Salem
Assalamualaikum..

I am Mr.Saeed Bin Salem Executive Director and Chief Financial Officer
of the National Commercial Bank Libya.I have a secured business
suggestion for you reply me on my email: saeedbi...@gmail.com