Re: [PATCH V8 5/5] libata: Align DMA buffer todma_get_cache_alignment()

2017-10-19 Thread 陈华才
Hi, Matt,

I found that 4ee34ea3a12396f35b26d90a094c75db ("libata: Align ata_device's id 
on a cacheline") can resolve everything. Because the size of id[ATA_ID_WORDS] 
is already aligned and devslp_timing needn't to be aligned. So, In V9 of this 
series I will drop this patch. Why I had problems before? because I used 
linux-4.4.

Huacai
 
 
-- Original --
From:  "Matt Redfearn";
Date:  Thu, Oct 19, 2017 03:52 PM
To:  "Tejun Heo"; "Huacai Chen"; 
Cc:  "Christoph Hellwig"; "Marek 
Szyprowski"; "Robin Murphy"; 
"AndrewMorton"; "Fuxin Zhang"; 
"linux-kernel"; "Ralf 
Baechle"; "JamesHogan"; 
"linux-mips"; "James E . J 
.Bottomley"; "Martin K . 
Petersen"; 
"linux-scsi"; 
"linux-ide"; "stable"; 
Subject:  Re: [PATCH V8 5/5] libata: Align DMA buffer 
todma_get_cache_alignment()

 


On 18/10/17 14:03, Tejun Heo wrote:
> On Tue, Oct 17, 2017 at 04:05:42PM +0800, Huacai Chen wrote:
>> In non-coherent DMA mode, kernel uses cache flushing operations to
>> maintain I/O coherency, so in ata_do_dev_read_id() the DMA buffer
>> should be aligned to ARCH_DMA_MINALIGN. Otherwise, If a DMA buffer
>> and a kernel structure share a same cache line, and if the kernel
>> structure has dirty data, cache_invalidate (no writeback) will cause
>> data corruption.
>>
>> Cc: sta...@vger.kernel.org
>> Signed-off-by: Huacai Chen 
>> ---
>>   drivers/ata/libata-core.c | 15 +--
>>   1 file changed, 13 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
>> index ee4c1ec..e134955 100644
>> --- a/drivers/ata/libata-core.c
>> +++ b/drivers/ata/libata-core.c
>> @@ -1833,8 +1833,19 @@ static u32 ata_pio_mask_no_iordy(const struct 
>> ata_device *adev)
>>   unsigned int ata_do_dev_read_id(struct ata_device *dev,
>>  struct ata_taskfile *tf, u16 *id)
>>   {
>> -return ata_exec_internal(dev, tf, NULL, DMA_FROM_DEVICE,
>> - id, sizeof(id[0]) * ATA_ID_WORDS, 0);
>> +u16 *devid;
>> +int res, size = sizeof(u16) * ATA_ID_WORDS;
>> +
>> +if (IS_ALIGNED((unsigned long)id, dma_get_cache_alignment(>tdev)))
>> +res = ata_exec_internal(dev, tf, NULL, DMA_FROM_DEVICE, id, 
>> size, 0);
>> +else {
>> +devid = kmalloc(size, GFP_KERNEL);
>> +res = ata_exec_internal(dev, tf, NULL, DMA_FROM_DEVICE, devid, 
>> size, 0);
>> +memcpy(id, devid, size);
>> +kfree(devid);
>> +}
>> +
>> +return res;
> Hmm... I think it'd be a lot better to ensure that the buffers are
> aligned properly to begin with.  There are only two buffers which are
> used for id reading - ata_port->sector_buf and ata_device->id.  Both
> are embedded arrays but making them separately allocated aligned
> buffers shouldn't be difficult.
>
> Thanks.

FWIW, I agree that the buffers used for DMA should be split out from the 
structure. We ran into this problem on MIPS last year, 
4ee34ea3a12396f35b26d90a094c75db95080baa ("libata: Align ata_device's id 
on a cacheline") partially fixed it, but likely should have also 
cacheline aligned the following devslp_timing in the struct such that we 
guarantee that members of the struct not used for DMA do not share the 
same cacheline as the DMA buffer. Not having this means that 
architectures, such as MIPS, which in some cases have to perform manual 
invalidation of DMA buffer can clobber valid adjacent data if it is in 
the same cacheline.

Thanks,
Matt

qla2xxx: New kernel warning

2017-10-19 Thread Bart Van Assche
Hello Himanshu,

If I load the qla2xxx driver 
(git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git,
4.15/scsi-queue) then a new kernel warning appears. This did not happen with 
kernel v4.13.
Can you have a look?

qla2xxx [:00:00.0]-0005: : QLogic Fibre Channel HBA Driver: 10.00.00.02-k.
qla2xxx [:00:09.0]-001d: : Found an ISP2432 irq 10 iobase 
0xc922d000.
BUG: using smp_processor_id() in preemptible [] code: modprobe/1040
caller is debug_smp_processor_id+0x17/0x20
CPU: 7 PID: 1040 Comm: modprobe Not tainted 4.13.0-dbg+ #2
Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
Call Trace:
 dump_stack+0x86/0xcf
 check_preemption_disabled+0xe3/0xf0
 debug_smp_processor_id+0x17/0x20
 qla2x00_probe_one+0xfc8/0x28b0 [qla2xxx]
 ? trace_hardirqs_on_caller+0xf4/0x190
 ? trace_hardirqs_on+0xd/0x10
 ? _raw_spin_unlock_irqrestore+0x45/0x70
 pci_device_probe+0xca/0x140
 driver_probe_device+0x2c5/0x430
 __driver_attach+0xde/0xe0
 ? driver_probe_device+0x430/0x430
 bus_for_each_dev+0x5d/0x90
 driver_attach+0x19/0x20
 bus_add_driver+0x169/0x260
 driver_register+0x5b/0xd0
 __pci_register_driver+0x63/0x70
 qla2x00_module_init+0x1d6/0x222 [qla2xxx]
 ? 0xa0491000
 do_one_initcall+0x3e/0x16c
 ? kmem_cache_alloc+0xfa/0x160
 do_init_module+0x55/0x1eb
 load_module+0x22f5/0x2b30
 ? kernel_read+0x41/0x60
 SYSC_finit_module+0xbc/0xf0
 ? SYSC_finit_module+0xbc/0xf0
 SyS_finit_module+0x9/0x10
 entry_SYSCALL_64_fastpath+0x23/0xc2

(gdb) list *(qla2x00_probe_one+0xfc8)
0x9738 is in qla2x00_probe_one (drivers/scsi/qla2xxx/qla_os.c:400).
395 ha->base_qpair->msix = >msix_entries[QLA_MSIX_RSP_Q];
396 INIT_LIST_HEAD(>base_qpair->hints_list);
397 INIT_LIST_HEAD(>base_qpair->nvme_done_list);
398 ha->base_qpair->enable_class_2 = ql2xenableclass2;
399 /* init qpair to this cpu. Will adjust at run time. */
400 qla_cpu_update(rsp->qpair, smp_processor_id());
401 ha->base_qpair->pdev = ha->pdev;
402
403 if (IS_QLA27XX(ha) || IS_QLA83XX(ha))
404 ha->base_qpair->reqq_start_iocbs = qla_83xx_start_iocbs;

Thanks,

Bart.

Re: [PATCH V8 4/5] libsas: Align SMP req/resp to dma_get_cache_alignment()

2017-10-19 Thread kbuild test robot
Hi Huacai,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.14-rc5 next-20171018]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Huacai-Chen/dma-mapping-Rework-dma_get_cache_alignment/20171020-050317
config: um-allyesconfig (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=um 

All errors (new ones prefixed by >>):

   drivers/scsi/libsas/sas_expander.c: In function 'sas_ex_phy_discover':
>> drivers/scsi/libsas/sas_expander.c:410:10: error: implicit declaration of 
>> function 'dma_get_cache_alignment' [-Werror=implicit-function-declaration]
 align = dma_get_cache_alignment(>phy->dev);
 ^~~
   Cyclomatic Complexity 5 include/linux/compiler.h:__write_once_size
   Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:atomic_set
   Cyclomatic Complexity 2 arch/x86/include/asm/bitops.h:set_bit
   Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:constant_test_bit
   Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:fls64
   Cyclomatic Complexity 1 arch/x86/include/uapi/asm/swab.h:__arch_swab64
   Cyclomatic Complexity 1 include/uapi/linux/swab.h:__fswab16
   Cyclomatic Complexity 1 include/uapi/linux/swab.h:__fswab64
   Cyclomatic Complexity 1 include/linux/log2.h:__ilog2_u64
   Cyclomatic Complexity 1 include/linux/list.h:INIT_LIST_HEAD
   Cyclomatic Complexity 2 include/linux/list.h:__list_add
   Cyclomatic Complexity 1 include/linux/list.h:list_add_tail
   Cyclomatic Complexity 1 include/linux/list.h:__list_del
   Cyclomatic Complexity 2 include/linux/list.h:__list_del_entry
   Cyclomatic Complexity 1 include/linux/list.h:list_del
   Cyclomatic Complexity 1 include/asm-generic/getorder.h:__get_order
   Cyclomatic Complexity 1 include/linux/spinlock.h:spinlock_check
   Cyclomatic Complexity 1 include/linux/spinlock.h:spin_lock_irq
   Cyclomatic Complexity 1 include/linux/spinlock.h:spin_unlock_irq
   Cyclomatic Complexity 1 include/linux/spinlock.h:spin_unlock_irqrestore
   Cyclomatic Complexity 1 include/linux/refcount.h:refcount_set
   Cyclomatic Complexity 28 include/linux/slab.h:kmalloc_index
   Cyclomatic Complexity 68 include/linux/slab.h:kmalloc_large
   Cyclomatic Complexity 5 include/linux/slab.h:kmalloc
   Cyclomatic Complexity 1 include/linux/slab.h:kzalloc
   Cyclomatic Complexity 1 include/linux/kref.h:kref_init
   Cyclomatic Complexity 1 include/linux/kref.h:kref_get
   Cyclomatic Complexity 2 include/linux/kref.h:kref_put
   Cyclomatic Complexity 1 include/scsi/scsi.h:scsi_to_u32
   Cyclomatic Complexity 1 include/scsi/sas_ata.h:dev_is_sata
   Cyclomatic Complexity 5 drivers/scsi/libsas/sas_internal.h:sas_fill_in_rphy
   Cyclomatic Complexity 2 
drivers/scsi/libsas/sas_internal.h:sas_add_parent_port
   Cyclomatic Complexity 2 drivers/scsi/libsas/sas_internal.h:sas_alloc_device
   Cyclomatic Complexity 1 drivers/scsi/libsas/sas_internal.h:sas_put_device
   Cyclomatic Complexity 2 drivers/scsi/libsas/sas_expander.c:alloc_smp_req
   Cyclomatic Complexity 1 drivers/scsi/libsas/sas_expander.c:alloc_smp_resp
   Cyclomatic Complexity 5 drivers/scsi/libsas/sas_expander.c:sas_route_char
   Cyclomatic Complexity 4 drivers/scsi/libsas/sas_expander.c:to_dev_type
   Cyclomatic Complexity 4 drivers/scsi/libsas/sas_expander.c:dev_type_flutter
   Cyclomatic Complexity 3 
drivers/scsi/libsas/sas_expander.c:sas_print_parent_topology_bug
   Cyclomatic Complexity 17 
drivers/scsi/libsas/sas_expander.c:smp_execute_task_sg
   Cyclomatic Complexity 1 drivers/scsi/libsas/sas_expander.c:smp_execute_task
   Cyclomatic Complexity 21 
drivers/scsi/libsas/sas_expander.c:sas_configure_present
   Cyclomatic Complexity 4 
drivers/scsi/libsas/sas_expander.c:sas_get_phy_discover
   Cyclomatic Complexity 3 
drivers/scsi/libsas/sas_expander.c:sas_get_phy_change_count
   Cyclomatic Complexity 6 drivers/scsi/libsas/sas_expander.c:sas_find_bcast_phy
   Cyclomatic Complexity 6 
drivers/scsi/libsas/sas_expander.c:sas_get_ex_change_count
   Cyclomatic Complexity 2 drivers/scsi/libsas/sas_expander.c:smp_task_timedout
   Cyclomatic Complexity 2 drivers/scsi/libsas/sas_expander.c:smp_task_done
   Cyclomatic Complexity 4 
drivers/scsi/libsas/sas_expander.c:ex_assign_report_general
   Cyclomatic Complexity 22 drivers/scsi/libsas/sas_expander.c:sas_check_eeds
   Cyclomatic Complexity 23 
drivers/scsi/libsas/sas_expander.c:sas_check_parent_topology
   Cyclomatic Complexity 11 drivers/scsi/libsas/sas_expander.c:sas_configure_set
   Cyclomatic Complexity 3 drivers/scsi/libsas/sas_expander.c:sas_configure_phy
   Cyclomatic Complexity 11 
drivers/scsi/libsas/sas_expander.c:sas_configure_parent
   Cyclomatic Complexity 2 
drivers/scsi/libsas/sas_expander.c:sas_configure_routing
   Cyclomatic Complexity 2 
drivers/scsi/libsas/sas_expander.c:sas_disable_routing
   Cyclomatic 

RE: [PATCH V2] scsi: storvsc: Allow only one remove lun work item to be issued per lun

2017-10-19 Thread Long Li
> On Tue, Oct 17, 2017 at 01:35:21PM -0400, Cathy Avery wrote:
> > +   /*
> > +* Set the error handler work queue.
> > +*/
> > +   snprintf(host_dev->work_q_name, sizeof(host_dev-
> >work_q_name),
> > +"storvsc_error_wq_%d", host->host_no);
> > +   host_dev->handle_error_wq =
> > +   create_singlethread_workqueue(host_dev-
> >work_q_name);
> 
> If you use alloc_ordered_workqueue directly instead of
> create_singlethread_workqueue you can pass a format string and don't need
> the separate allocation.
> 
> But I'm not sure if Tejun is fine with using __WQ_LEGACY directly..
> 
> Except for this nit this looks fine to me:
> 
> Reviewed-by: Christoph Hellwig 

The work storvsc_host_scan (scheduled from function storvsc_on_receive) should 
also use this workqueue. We can do it in another patch.

Reviewed-by: Long Li 

> ___
> devel mailing list
> de...@linuxdriverproject.org
> https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdriverd
> ev.linuxdriverproject.org%2Fmailman%2Flistinfo%2Fdriverdev-
> devel=02%7C01%7Clongli%40microsoft.com%7C9c303c3630ef490cecc3
> 08d5170702a2%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636440
> 241242573253=tbCBOnKxtRR38rAdsBDa7zA0Jc2XwrySTsH3uyRxHxA%
> 3D=0


Re: [PATCH 9/9] bsg: split handling of SCSI CDBs vs transport requeues

2017-10-19 Thread Benjamin Block
Hey Christoph,

better late than never I guess.

On Tue, Oct 03, 2017 at 12:48:45PM +0200, Christoph Hellwig wrote:
> The current BSG design tries to shoe-horn the transport-specific passthrough
> commands into the overall framework for SCSI passthrough requests.  This
> has a couple problems:
>
>  - each passthrough queue has to set the QUEUE_FLAG_SCSI_PASSTHROUGH flag
>despite not dealing with SCSI commands at all.  Because of that these
>queues could also incorrectly accept SCSI commands from in-kernel
>users or through the legacy SCSI_IOCTL_SEND_COMMAND ioctl.
>  - the real SCSI bsg queues also incorrectly accept bsg requests of the
>BSG_SUB_PROTOCOL_SCSI_TRANSPORT type
>  - the bsg transport code is almost unredable because it tries to reuse
>different SCSI concepts for its own purpose.
>
> This patch instead adds a new bsg_ops structure to handle the two cases
> differently, and thus solves all of the above problems.  Another side
> effect is that the bsg-lib queues also don't need to embedd a
> struct scsi_request anymore.
>
> Signed-off-by: Christoph Hellwig 
> ---
>  block/bsg-lib.c   | 158 +++
>  block/bsg.c   | 257 
> +-
>  drivers/scsi/scsi_lib.c   |   4 +-
>  drivers/scsi/scsi_sysfs.c |   3 +-
>  drivers/scsi/scsi_transport_sas.c |   1 -
>  include/linux/bsg-lib.h   |   4 +-
>  include/linux/bsg.h   |  35 --
>  7 files changed, 251 insertions(+), 211 deletions(-)
>
> diff --git a/block/bsg-lib.c b/block/bsg-lib.c
> index 6299526bd2c3..99b459e21782 100644
> --- a/block/bsg-lib.c
> +++ b/block/bsg-lib.c
> @@ -27,6 +27,94 @@
>  #include 
>  #include 
>  #include 
> +#include 
> +
> +#define ptr64(val) ((void __user *)(uintptr_t)(val))

Better to reflect the special property, that it is a user pointer, in
the name of the macro. Maybe something like user_ptr(64). The same
comment for the same macro in bsg.c.

> +
> +static int bsg_transport_check_proto(struct sg_io_v4 *hdr)
> +{
> + if (hdr->protocol != BSG_PROTOCOL_SCSI  ||
> + hdr->subprotocol != BSG_SUB_PROTOCOL_SCSI_TRANSPORT)
> + return -EINVAL;
> + if (!capable(CAP_SYS_RAWIO))
> + return -EPERM;

Any particular reason why this is not symmetric with bsg_scsi? IOW
permission checking done in bsg_transport_fill_hdr(), like it is done in
bsg_scsi_fill_hdr()?

We might save some time copying memory with this (we also only talk
about ~20 bytes here), but on the other hand the interface would be more
clean otherwise IMO (if we already do restructure the interface) -
similar callbacks have similar responsibilities.

> + return 0;
> +}
> +
> +static int bsg_transport_fill_hdr(struct request *rq, struct sg_io_v4 *hdr,
> + fmode_t mode)
> +{
> + struct bsg_job *job = blk_mq_rq_to_pdu(rq);
> +
> + job->request_len = hdr->request_len;
> + job->request = memdup_user(ptr64(hdr->request), hdr->request_len);
> + if (IS_ERR(job->request))
> + return PTR_ERR(job->request);
> + return 0;
> +}
> +
> +static int bsg_transport_complete_rq(struct request *rq, struct sg_io_v4 
> *hdr)
> +{
> + struct bsg_job *job = blk_mq_rq_to_pdu(rq);
> + int ret = 0;
> +
> + /*
> +  * The assignments below don't make much sense, but are kept for
> +  * bug by bug backwards compatibility:
> +  */
> + hdr->device_status = job->result & 0xff;
> + hdr->transport_status = host_byte(job->result);
> + hdr->driver_status = driver_byte(job->result);
> + hdr->info = 0;
> + if (hdr->device_status || hdr->transport_status || hdr->driver_status)
> + hdr->info |= SG_INFO_CHECK;
> + hdr->response_len = 0;
> +
> + if (job->result < 0) {
> + /* we're only returning the result field in the reply */
> + job->reply_len = sizeof(u32);
> + ret = job->result;
> + }
> +
> + if (job->reply_len && hdr->response) {
> + int len = min(hdr->max_response_len, job->reply_len);
> +
> + if (copy_to_user(ptr64(hdr->response), job->reply, len))
> + ret = -EFAULT;
> + else
> + hdr->response_len = len;

very very minor nitpick: this is reversed with the handling in
bsg_scsi_complete_rq().. could be identical.

> + }
> +
> + /* we assume all request payload was transferred, residual == 0 */
> + hdr->dout_resid = 0;
> +
> + if (rq->next_rq) {
> + unsigned int rsp_len = blk_rq_bytes(rq->next_rq);
> +
> + if (WARN_ON(job->reply_payload_rcv_len > rsp_len))
> + hdr->din_resid = 0;

If I understand this right, the this reflects the old code, if only
written down a little different.

But I wonder why we do that? Wouldn't that be interesting to know for
uspace, if more was received than it allocated space for? Isn't that the
typical 

Re: [PATCH V2] scsi: storvsc: Allow only one remove lun work item to be issued per lun

2017-10-19 Thread Christoph Hellwig
On Tue, Oct 17, 2017 at 01:35:21PM -0400, Cathy Avery wrote:
> + /*
> +  * Set the error handler work queue.
> +  */
> + snprintf(host_dev->work_q_name, sizeof(host_dev->work_q_name),
> +  "storvsc_error_wq_%d", host->host_no);
> + host_dev->handle_error_wq =
> + create_singlethread_workqueue(host_dev->work_q_name);

If you use alloc_ordered_workqueue directly instead of
create_singlethread_workqueue you can pass a format string and don't
need the separate allocation.

But I'm not sure if Tejun is fine with using __WQ_LEGACY directly..

Except for this nit this looks fine to me:

Reviewed-by: Christoph Hellwig 


Re: [PATCH V8 4/5] libsas: Align SMP req/resp to dma_get_cache_alignment()

2017-10-19 Thread Christoph Hellwig
On Tue, Oct 17, 2017 at 01:55:43PM +0200, Marek Szyprowski wrote:
> If I remember correctly, kernel guarantees that each kmalloced buffer is
> always at least aligned to the CPU cache line, so CPU cache can be
> invalidated on the allocated buffer without corrupting anything else.

Yes, from slab.h:

/*
 * Some archs want to perform DMA into kmalloc caches and need a guaranteed
 * alignment larger than the alignment of a 64-bit integer.
 * Setting ARCH_KMALLOC_MINALIGN in arch headers allows that.
 */
#if defined(ARCH_DMA_MINALIGN) && ARCH_DMA_MINALIGN > 8
#define ARCH_KMALLOC_MINALIGN ARCH_DMA_MINALIGN
#define KMALLOC_MIN_SIZE ARCH_DMA_MINALIGN
#define KMALLOC_SHIFT_LOW ilog2(ARCH_DMA_MINALIGN)
#else
#define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long long)
#endif

Mips sets this for a few subarchitectures, but it seems like you need
to set it for yours as well.


Re: [PATCH V8 3/5] scsi: Align block queue to dma_get_cache_alignment()

2017-10-19 Thread Christoph Hellwig
On Tue, Oct 17, 2017 at 04:05:40PM +0800, Huacai Chen wrote:
> In non-coherent DMA mode, kernel uses cache flushing operations to
> maintain I/O coherency, so scsi's block queue should be aligned to
> ARCH_DMA_MINALIGN. Otherwise, If a DMA buffer and a kernel structure
> share a same cache line, and if the kernel structure has dirty data,
> cache_invalidate (no writeback) will cause data corruption.

Looks fine to, and I like cleaning up the arcane 0x03 as wel.


Re: [PATCH V8 1/5] dma-mapping: Rework dma_get_cache_alignment()

2017-10-19 Thread Christoph Hellwig
On Wed, Oct 18, 2017 at 10:23:36AM -0700, Mark Greer wrote:
> >  #defineMPSC_RXR_ENTRIES32
> > -#defineMPSC_RXRE_SIZE  dma_get_cache_alignment()
> > +#defineMPSC_RXRE_SIZE  dma_get_cache_alignment(dma_dev)
> 
> I would much prefer that you add a parameter to the macro to avoid forcing
> a non-flexible and non-obvious variable definition wherever it is used.
> What I mean is something like:
> 
> #define MPSC_RXRE_SIZE(d) dma_get_cache_alignment(d)
> 
> Similarly for all of the other macros and where they're used.

Agreed.  Except for that the patch looks fine to me, though.


Re: [PATCH v2 02/15] usb: gadget: make config_item_type structures const

2017-10-19 Thread Laurent Pinchart
Hi Christoph,

On Thursday, 19 October 2017 17:06:57 EEST Christoph Hellwig wrote:
> > Now we have 9 const instances of the config_item_type structure that are
> > identical, with only the .ct_owner field set. Should they be all merged
> > into a single structure ?
> 
> I think that's a good idea.
> 
> But I'm about to slurp up this whole series into my tree, how about making
> that an incremental patch?

I'm fine with that.

Bhumika, would you like to submit an incremental patch, or should I do it ?

-- 
Regards,

Laurent Pinchart



[PATCH] Added notes to scsi-parameters.txt to show how to pass parameters on kernel line

2017-10-19 Thread Laurence Oberman
---
 Documentation/scsi/scsi-parameters.txt | 8 
 1 file changed, 8 insertions(+)

diff --git a/Documentation/scsi/scsi-parameters.txt 
b/Documentation/scsi/scsi-parameters.txt
index 8477655..5b87a11 100644
--- a/Documentation/scsi/scsi-parameters.txt
+++ b/Documentation/scsi/scsi-parameters.txt
@@ -116,3 +116,11 @@ parameters may be changed at runtime by the command
 
wd33c93=[HW,SCSI]
See header of drivers/scsi/wd33c93.c.
+
+Additional notes on passing parameters on the command line:
+
+It's not intuitively obvious how to pass certain parameters on the boot line.
+For parameters such as scsi_dev_flags, you need to pass these to the scsi_mod 
as 
+the following example for the scsi_dev_flags. 
+
+On kernel line add scsi_mod.dev_flags=LIO-ORG:thin2:0x800
-- 
1.8.3.1



Re: [PATCH v2 02/15] usb: gadget: make config_item_type structures const

2017-10-19 Thread Christoph Hellwig
> 
> Now we have 9 const instances of the config_item_type structure that are 
> identical, with only the .ct_owner field set. Should they be all merged into 
> a 
> single structure ?

I think that's a good idea.

But I'm about to slurp up this whole series into my tree, how about making
that an incremental patch?  


Hello

2017-10-19 Thread Salif Mohammed
Hello,

I need your partnership in this project that requires trust and confidentiality.

An American, Mr. Charles Balassi who worked with the Egyptian General
Petroleum Corporation (EGPC), made a fixed deposit of Twenty Two
Million United States Dollars($22,000,000) for 17 Years in my
bank(Dubai Islamic Bank) branch, upon maturity our department sent a
routine notification to his forwarding address but got no response.

After a month, we sent a reminder and finally we discovered from his
employer, the (EGPC) that he died with his wife in a plane crash on
October 31, 1999, with other passengers on board.

Meanwhile, I just discovered that all his records has no next of kin,
so the funds must be claimed immediately by somebody who would stand
as his Next of Kin. According to the financial laws of United Arab
Emirates, the fund should be reverted to the Government treasury
accounts if nobody applies to claim it.

Please note that I have worked out the perfect modality on how to
claim the fund and I shall provide the relevant information and
documents for the successful claim and transfer of the funds into your
account that you will provide. I assure you that this project is 100%
risk free. Kindly provide your phone number for easy communication.

Awaiting your quick response.

Thanks,
Salif Mohammed
Customer Relations Manager
Dubai Islamic Bank
Abu Dhabi
U.A.E.


[PATCH 17/19] megaraid_sas: Do not limit queue_depth to 1k in non-RDPQ mode

2017-10-19 Thread Shivasharan S
Earlier, driver load fails if memory allocation for request frame pool
fails due to the higher queue_depth requirement. Patch 0016 in this
series allows dynamically reducing queue_depth if memory allocations
fail rather than failing load.
With this, there is no need to limit queue_depth to 1k now.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 8b7a08af275e..745da54c11aa 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -272,10 +272,6 @@ megasas_fusion_update_can_queue(struct megasas_instance 
*instance, int fw_boot_c
instance->max_fw_cmds = cur_max_fw_cmds;
instance->ldio_threshold = ldio_threshold;
 
-   if (!instance->is_rdpq)
-   instance->max_fw_cmds =
-   min_t(u16, instance->max_fw_cmds, 1024);
-
if (reset_devices)
instance->max_fw_cmds = min(instance->max_fw_cmds,
(u16)MEGASAS_KDUMP_QUEUE_DEPTH);
-- 
2.14.1.dirty



[PATCH 18/19] megaraid_sas: Add support for 64bit consistent DMA

2017-10-19 Thread Shivasharan S
The latest MegaRAID Firmware (for Invader series) have support for
64bit DMA for both streaming and consistent DMA buffers.
All Ventura series controller FW always support 64 bit consistent DMA.
Also on few architectures 32bit DMA is not supported.

Current driver always prefers 32bit for consistent DMA and 64bit for
streaming DMA.
This behavior was unintentional and carried forwarded from legacy
controller FW. Need to enhance the driver to support 64bit consistent DMA
buffers based on the firmware capability.

Below is the DMA setting strategy in driver with this patch.
For Ventura series, always try to set 64bit DMA mask. If it fails
fall back to 32bit DMA mask.
For Invader series and earlier generation controllers, first try to set
to 32bit consistent DMA mask irrespective of FW capability. This is
needed to ensure firmware downgrades do not break. If 32bit DMA
setting fails, check FW capability and try seting to 64bit DMA mask.

There are certain restrictions in the hardware for having all sense
buffers and all reply descriptors to be in the same 4GB memory region.
This limitation is h/w dependent and can not be changed in firmware.
This limitation needs to be taken care in driver while allocating the
buffers.
There was a discussion regarding this - find details at below link.
https://www.spinics.net/lists/linux-scsi/msg108251.html

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
---
 drivers/scsi/megaraid/megaraid_sas.h|  12 +-
 drivers/scsi/megaraid/megaraid_sas_base.c   | 245 --
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 384 ++--
 drivers/scsi/megaraid/megaraid_sas_fusion.h |  13 +
 4 files changed, 503 insertions(+), 151 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index 85ef8415640c..b34fc68c14c9 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1508,6 +1508,8 @@ enum FW_BOOT_CONTEXT {
 
 #define MR_CAN_HANDLE_SYNC_CACHE_OFFSET0X0100
 
+#define MR_CAN_HANDLE_64_BIT_DMA_OFFSET(1 << 25)
+
 enum MR_ADAPTER_TYPE {
MFI_SERIES = 1,
THUNDERBOLT_SERIES = 2,
@@ -1628,7 +1630,8 @@ union megasas_sgl_frame {
 typedef union _MFI_CAPABILITIES {
struct {
 #if   defined(__BIG_ENDIAN_BITFIELD)
-   u32 reserved:19;
+   u32 reserved:18;
+   u32 support_64bit_mode:1;
u32 support_pd_map_target_id:1;
u32 support_qd_throttling:1;
u32 support_fp_rlbypass:1;
@@ -1656,7 +1659,8 @@ typedef union _MFI_CAPABILITIES {
u32 support_fp_rlbypass:1;
u32 support_qd_throttling:1;
u32 support_pd_map_target_id:1;
-   u32 reserved:19;
+   u32 support_64bit_mode:1;
+   u32 reserved:18;
 #endif
} mfi_capabilities;
__le32  reg;
@@ -2264,6 +2268,7 @@ struct megasas_instance {
u8  r1_ldio_hint_default;
u32 nvme_page_size;
u8 adapter_type;
+   bool consistent_mask_64bit;
 };
 struct MR_LD_VF_MAP {
u32 size;
@@ -2510,4 +2515,7 @@ int megasas_reset_target_fusion(struct scsi_cmnd *scmd);
 u32 mega_mod64(u64 dividend, u32 divisor);
 int megasas_alloc_fusion_context(struct megasas_instance *instance);
 void megasas_free_fusion_context(struct megasas_instance *instance);
+void megasas_set_dma_settings(struct megasas_instance *instance,
+ struct megasas_dcmd_frame *dcmd,
+ dma_addr_t dma_addr, u32 dma_len);
 #endif /*LSI_MEGARAID_SAS_H */
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 995d70a06cb7..3582ed5261dd 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -207,7 +207,7 @@ void megasas_fusion_ocr_wq(struct work_struct *work);
 static int megasas_get_ld_vf_affiliation(struct megasas_instance *instance,
 int initial);
 static int
-megasas_set_dma_mask(struct pci_dev *pdev);
+megasas_set_dma_mask(struct megasas_instance *instance);
 static int
 megasas_alloc_ctrl_mem(struct megasas_instance *instance);
 static inline void
@@ -219,6 +219,31 @@ megasas_free_ctrl_dma_buffers(struct megasas_instance 
*instance);
 static inline void
 megasas_init_ctrl_params(struct megasas_instance *instance);
 
+/**
+ * megasas_set_dma_settings -  Populate DMA address, length and flags for DCMDs
+ * @instance:  Adapter soft state
+ * @dcmd:  DCMD frame inside MFI command
+ * @dma_addr:  DMA address of buffer to be passed to FW
+ * @dma_len:   Length of DMA buffer to be passed to FW
+ * @return:void
+ */
+void megasas_set_dma_settings(struct megasas_instance *instance,
+ 

[PATCH 15/19] megaraid_sas: Incorrect processing of IOCTL frames for SMP/STP commands

2017-10-19 Thread Shivasharan S
Code fix - cmd->frame->dcmd.opcode will be valid only for MFI_CMD_DCMD
IOCTL frames. Currently driver check for cmd->frame->dcmd.opcode without
checking cmd type. Ensure we check dcmd opcode only for MFI_CMD_DCMD
commands. Separate handling of MFI_CMD_SMP/STP commands from
MFI_CMD_DCMD in completion path.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
---
 drivers/scsi/megaraid/megaraid_sas.h  | 23 +--
 drivers/scsi/megaraid/megaraid_sas_base.c | 22 ++
 2 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index 83427b541629..85ef8415640c 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -187,16 +187,19 @@
 /*
  * MFI command opcodes
  */
-#define MFI_CMD_INIT   0x00
-#define MFI_CMD_LD_READ0x01
-#define MFI_CMD_LD_WRITE   0x02
-#define MFI_CMD_LD_SCSI_IO 0x03
-#define MFI_CMD_PD_SCSI_IO 0x04
-#define MFI_CMD_DCMD   0x05
-#define MFI_CMD_ABORT  0x06
-#define MFI_CMD_SMP0x07
-#define MFI_CMD_STP0x08
-#define MFI_CMD_INVALID0xff
+enum MFI_CMD_OP {
+   MFI_CMD_INIT= 0x0,
+   MFI_CMD_LD_READ = 0x1,
+   MFI_CMD_LD_WRITE= 0x2,
+   MFI_CMD_LD_SCSI_IO  = 0x3,
+   MFI_CMD_PD_SCSI_IO  = 0x4,
+   MFI_CMD_DCMD= 0x5,
+   MFI_CMD_ABORT   = 0x6,
+   MFI_CMD_SMP = 0x7,
+   MFI_CMD_STP = 0x8,
+   MFI_CMD_OP_COUNT,
+   MFI_CMD_INVALID = 0xff
+};
 
 #define MR_DCMD_CTRL_GET_INFO  0x0101
 #define MR_DCMD_LD_GET_LIST0x0301
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 3a179c3fabc0..995d70a06cb7 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -3298,6 +3298,9 @@ megasas_complete_cmd(struct megasas_instance *instance, 
struct megasas_cmd *cmd,
 
case MFI_CMD_SMP:
case MFI_CMD_STP:
+   megasas_complete_int_cmd(instance, cmd);
+   break;
+
case MFI_CMD_DCMD:
opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
/* Check for LD map update */
@@ -3384,6 +3387,7 @@ megasas_complete_cmd(struct megasas_instance *instance, 
struct megasas_cmd *cmd,
default:
dev_info(>pdev->dev, "Unknown command completed! 
[0x%X]\n",
   hdr->cmd);
+   megasas_complete_int_cmd(instance, cmd);
break;
}
 }
@@ -7017,7 +7021,7 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
void *sense = NULL;
dma_addr_t sense_handle;
unsigned long *sense_ptr;
-   u32 opcode;
+   u32 opcode = 0;
 
memset(kbuff_arr, 0, sizeof(kbuff_arr));
 
@@ -7027,6 +7031,13 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
return -EINVAL;
}
 
+   if (ioc->frame.hdr.cmd >= MFI_CMD_OP_COUNT) {
+   dev_err(>pdev->dev,
+   "Received invalid ioctl command 0x%x\n",
+   ioc->frame.hdr.cmd);
+   return -ENOTSUPP;
+   }
+
cmd = megasas_get_cmd(instance);
if (!cmd) {
dev_printk(KERN_DEBUG, >pdev->dev, "Failed to get a 
cmd packet\n");
@@ -7045,7 +7056,9 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
cmd->frame->hdr.flags &= cpu_to_le16(~(MFI_FRAME_IEEE |
   MFI_FRAME_SGL64 |
   MFI_FRAME_SENSE64));
-   opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
+
+   if (cmd->frame->hdr.cmd == MFI_CMD_DCMD)
+   opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
 
if (opcode == MR_DCMD_CTRL_SHUTDOWN) {
if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS) {
@@ -7127,8 +7140,9 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
if (megasas_issue_blocked_cmd(instance, cmd, 0) == DCMD_NOT_FIRED) {
cmd->sync_cmd = 0;
dev_err(>pdev->dev,
-   "return -EBUSY from %s %d opcode 0x%x 
cmd->cmd_status_drv 0x%x\n",
-   __func__, __LINE__, opcode, cmd->cmd_status_drv);
+   "return -EBUSY from %s %d cmd 0x%x opcode 0x%x 
cmd->cmd_status_drv 0x%x\n",
+   __func__, __LINE__, cmd->frame->hdr.cmd, opcode,
+   cmd->cmd_status_drv);
return -EBUSY;
}
 
-- 
2.14.1.dirty



[PATCH 19/19] megaraid_sas: driver version upgrade

2017-10-19 Thread Shivasharan S
Signed-off-by: Shivasharan S 
---
 drivers/scsi/megaraid/megaraid_sas.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index b34fc68c14c9..f5a36ccb8606 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -35,8 +35,8 @@
 /*
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION"07.702.06.00-rc1"
-#define MEGASAS_RELDATE"June 21, 2017"
+#define MEGASAS_VERSION"07.703.05.00-rc1"
+#define MEGASAS_RELDATE"October 5, 2017"
 
 /*
  * Device IDs
-- 
2.14.1.dirty



[PATCH 03/19] megaraid_sas: replace instance->ctrl_context checks with instance->adapter_type

2017-10-19 Thread Shivasharan S
Increase Code readability. No Functional Change

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
---
 drivers/scsi/megaraid/megaraid_sas_base.c | 64 ++-
 1 file changed, 37 insertions(+), 27 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index eba627ccd041..001b075d0dd6 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -2024,7 +2024,7 @@ void megaraid_sas_kill_hba(struct megasas_instance 
*instance)
msleep(1000);
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
-   (instance->ctrl_context)) {
+   (instance->adapter_type != MFI_SERIES)) {
writel(MFI_STOP_ADP, >reg_set->doorbell);
/* Flush */
readl(>reg_set->doorbell);
@@ -2495,7 +2495,8 @@ int megasas_sriov_start_heartbeat(struct megasas_instance 
*instance,
dev_warn(>pdev->dev, "SR-IOV: Starting heartbeat for 
scsi%d\n",
   instance->host->host_no);
 
-   if (instance->ctrl_context && !instance->mask_interrupts)
+   if ((instance->adapter_type != MFI_SERIES) &&
+   !instance->mask_interrupts)
retval = megasas_issue_blocked_cmd(instance, cmd,
MEGASAS_ROUTINE_WAIT_TIME_VF);
else
@@ -2791,7 +2792,9 @@ static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
/*
 * First wait for all commands to complete
 */
-   if (instance->ctrl_context) {
+   if (instance->adapter_type == MFI_SERIES) {
+   ret = megasas_generic_reset(scmd);
+   } else {
struct megasas_cmd_fusion *cmd;
cmd = (struct megasas_cmd_fusion *)scmd->SCp.ptr;
if (cmd)
@@ -2799,8 +2802,7 @@ static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE);
ret = megasas_reset_fusion(scmd->device->host,
SCSIIO_TIMEOUT_OCR);
-   } else
-   ret = megasas_generic_reset(scmd);
+   }
 
return ret;
 }
@@ -2817,7 +2819,7 @@ static int megasas_task_abort(struct scsi_cmnd *scmd)
 
instance = (struct megasas_instance *)scmd->device->host->hostdata;
 
-   if (instance->ctrl_context)
+   if (instance->adapter_type != MFI_SERIES)
ret = megasas_task_abort_fusion(scmd);
else {
sdev_printk(KERN_NOTICE, scmd->device, "TASK ABORT not 
supported\n");
@@ -2839,7 +2841,7 @@ static int megasas_reset_target(struct scsi_cmnd *scmd)
 
instance = (struct megasas_instance *)scmd->device->host->hostdata;
 
-   if (instance->ctrl_context)
+   if (instance->adapter_type != MFI_SERIES)
ret = megasas_reset_target_fusion(scmd);
else {
sdev_printk(KERN_NOTICE, scmd->device, "TARGET RESET not 
supported\n");
@@ -3716,7 +3718,7 @@ megasas_transition_to_ready(struct megasas_instance 
*instance, int ocr)
PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
(instance->pdev->device ==
 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
-   (instance->ctrl_context))
+   (instance->adapter_type != MFI_SERIES))
writel(
  MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
  >reg_set->doorbell);
@@ -3734,7 +3736,7 @@ megasas_transition_to_ready(struct megasas_instance 
*instance, int ocr)
 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
(instance->pdev->device ==
 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
-   (instance->ctrl_context))
+   (instance->adapter_type != MFI_SERIES))
writel(MFI_INIT_HOTPLUG,
   >reg_set->doorbell);
else
@@ -3754,11 +3756,11 @@ megasas_transition_to_ready(struct megasas_instance 
*instance, int ocr)
PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
(instance->pdev->device ==
PCI_DEVICE_ID_LSI_SAS0071SKINNY)  ||
-   (instance->ctrl_context)) {
+   (instance->adapter_type != MFI_SERIES)) {
writel(MFI_RESET_FLAGS,
>reg_set->doorbell);
 
-   if (instance->ctrl_context) {
+   if (instance->adapter_type != 

[PATCH 04/19] megaraid_sas: Remove redundant checks for ctrl_context

2017-10-19 Thread Shivasharan S
Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index cd997ccf5ebf..340079d0bff0 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -991,7 +991,7 @@ megasas_sync_pd_seq_num(struct megasas_instance *instance, 
bool pend) {
dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
 
/* Below code is only for non pended DCMD */
-   if (instance->ctrl_context && !instance->mask_interrupts)
+   if (!instance->mask_interrupts)
ret = megasas_issue_blocked_cmd(instance, cmd,
MFI_IO_TIMEOUT_SECS);
else
@@ -1004,7 +1004,7 @@ megasas_sync_pd_seq_num(struct megasas_instance 
*instance, bool pend) {
ret = -EINVAL;
}
 
-   if (ret == DCMD_TIMEOUT && instance->ctrl_context)
+   if (ret == DCMD_TIMEOUT)
megaraid_sas_kill_hba(instance);
 
if (ret == DCMD_SUCCESS)
@@ -1080,13 +1080,13 @@ megasas_get_ld_map_info(struct megasas_instance 
*instance)
dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h);
dcmd->sgl.sge32[0].length = cpu_to_le32(size_map_info);
 
-   if (instance->ctrl_context && !instance->mask_interrupts)
+   if (!instance->mask_interrupts)
ret = megasas_issue_blocked_cmd(instance, cmd,
MFI_IO_TIMEOUT_SECS);
else
ret = megasas_issue_polled(instance, cmd);
 
-   if (ret == DCMD_TIMEOUT && instance->ctrl_context)
+   if (ret == DCMD_TIMEOUT)
megaraid_sas_kill_hba(instance);
 
megasas_return_cmd(instance, cmd);
-- 
2.14.1.dirty



[PATCH 16/19] megaraid_sas: Retry with reduced queue depth when alloc fails for higher QD

2017-10-19 Thread Shivasharan S
In certain cases, the host memory is limited and with FW supporting higher
queue depths there are increasing chances of IO request frame allocation
failures that we are seeing. In case of request frame allocation failures,
retry allocation with reduced queue depth (in steps of 64) to continue
to configure the controller with a reduced performance rather than failing
load.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 106 ++--
 drivers/scsi/megaraid/megaraid_sas_fusion.h |   1 +
 2 files changed, 68 insertions(+), 39 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 857bdbb0f79d..8b7a08af275e 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -96,6 +96,8 @@ extern unsigned int resetwaittime;
 extern unsigned int dual_qdepth_disable;
 static void megasas_free_rdpq_fusion(struct megasas_instance *instance);
 static void megasas_free_reply_fusion(struct megasas_instance *instance);
+static inline
+void megasas_configure_queue_sizes(struct megasas_instance *instance);
 
 
 
@@ -254,8 +256,8 @@ megasas_fusion_update_can_queue(struct megasas_instance 
*instance, int fw_boot_c
(instance->instancet->read_fw_status_reg(reg_set) & 
0x00) - MEGASAS_FUSION_IOCTL_CMDS;
 
dev_info(>pdev->dev,
-   "Current firmware maximum commands: %d\t LDIO 
threshold: %d\n",
-   cur_max_fw_cmds, ldio_threshold);
+"Current firmware supports maximum commands: %d\t LDIO 
thershold: %d\n",
+cur_max_fw_cmds, ldio_threshold);
 
if (fw_boot_context == OCR_CONTEXT) {
cur_max_fw_cmds = cur_max_fw_cmds - 1;
@@ -283,19 +285,7 @@ megasas_fusion_update_can_queue(struct megasas_instance 
*instance, int fw_boot_c
* does not exceed max cmds that the FW can support
*/
instance->max_fw_cmds = instance->max_fw_cmds-1;
-
-   instance->max_scsi_cmds = instance->max_fw_cmds -
-   (MEGASAS_FUSION_INTERNAL_CMDS +
-   MEGASAS_FUSION_IOCTL_CMDS);
-   instance->cur_can_queue = instance->max_scsi_cmds;
-   instance->host->can_queue = instance->cur_can_queue;
}
-
-   if (instance->adapter_type == VENTURA_SERIES)
-   instance->max_mpt_cmds =
-   instance->max_fw_cmds * RAID_1_PEER_CMDS;
-   else
-   instance->max_mpt_cmds = instance->max_fw_cmds;
 }
 /**
  * megasas_free_cmds_fusion -  Free all the cmds in the free cmd pool
@@ -468,16 +458,7 @@ megasas_alloc_request_fusion(struct megasas_instance 
*instance)
 
fusion = instance->ctrl_context;
 
-   fusion->req_frames_desc =
-   dma_alloc_coherent(>pdev->dev,
-   fusion->request_alloc_sz,
-   >req_frames_desc_phys, GFP_KERNEL);
-   if (!fusion->req_frames_desc) {
-   dev_err(>pdev->dev,
-   "Failed from %s %d\n",  __func__, __LINE__);
-   return -ENOMEM;
-   }
-
+retry_alloc:
fusion->io_request_frames_pool =
dma_pool_create("mr_ioreq", >pdev->dev,
fusion->io_frames_alloc_sz, 16, 0);
@@ -492,10 +473,28 @@ megasas_alloc_request_fusion(struct megasas_instance 
*instance)
dma_pool_alloc(fusion->io_request_frames_pool,
GFP_KERNEL, >io_request_frames_phys);
if (!fusion->io_request_frames) {
+   if (instance->max_fw_cmds >= (MEGASAS_REDUCE_QD_COUNT * 2)) {
+   instance->max_fw_cmds -= MEGASAS_REDUCE_QD_COUNT;
+   dma_pool_destroy(fusion->io_request_frames_pool);
+   megasas_configure_queue_sizes(instance);
+   goto retry_alloc;
+   } else {
+   dev_err(>pdev->dev,
+   "Failed from %s %d\n",  __func__, __LINE__);
+   return -ENOMEM;
+   }
+   }
+
+   fusion->req_frames_desc =
+   dma_alloc_coherent(>pdev->dev,
+  fusion->request_alloc_sz,
+  >req_frames_desc_phys, GFP_KERNEL);
+   if (!fusion->req_frames_desc) {
dev_err(>pdev->dev,
"Failed from %s %d\n",  __func__, __LINE__);
return -ENOMEM;
}
+
return 0;
 }
 
@@ -664,9 +663,6 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance)
 
fusion = instance->ctrl_context;
 
-   if (megasas_alloc_cmdlist_fusion(instance))
-   goto fail_exit;
-
if 

[PATCH 01/19] megaraid_sas: use adapter_type for all gen controllers

2017-10-19 Thread Shivasharan S
No functional change.
Refactor adapter_type to set for all generation controllers, not
just for fusion controllers.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
---
 drivers/scsi/megaraid/megaraid_sas.h|  8 +++
 drivers/scsi/megaraid/megaraid_sas_base.c   | 88 ++---
 drivers/scsi/megaraid/megaraid_sas_fp.c | 10 ++--
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 18 +++---
 drivers/scsi/megaraid/megaraid_sas_fusion.h |  7 ---
 5 files changed, 76 insertions(+), 55 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index a6722c93a295..90b9b5d7f0f8 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1504,6 +1504,13 @@ enum FW_BOOT_CONTEXT {
 
 #define MR_CAN_HANDLE_SYNC_CACHE_OFFSET0X0100
 
+enum MR_ADAPTER_TYPE {
+   MFI_SERIES = 1,
+   THUNDERBOLT_SERIES = 2,
+   INVADER_SERIES = 3,
+   VENTURA_SERIES = 4,
+};
+
 /*
 * register set for both 1068 and 1078 controllers
 * structure extended for 1078 registers
@@ -2242,6 +2249,7 @@ struct megasas_instance {
/* preffered count to send as LDIO irrspective of FP capable.*/
u8  r1_ldio_hint_default;
u32 nvme_page_size;
+   u8 adapter_type;
 };
 struct MR_LD_VF_MAP {
u32 size;
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 518318491899..2f9955c6c2af 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -5229,7 +5229,8 @@ static int megasas_init_fw(struct megasas_instance 
*instance)
(>reg_set->outbound_scratch_pad_2);
/* Check max MSI-X vectors */
if (fusion) {
-   if (fusion->adapter_type == THUNDERBOLT_SERIES) { /* 
Thunderbolt Series*/
+   if (instance->adapter_type == THUNDERBOLT_SERIES) {
+   /* Thunderbolt Series*/
instance->msix_vectors = (scratch_pad_2
& MR_MAX_REPLY_QUEUES_OFFSET) + 1;
fw_msix_count = instance->msix_vectors;
@@ -5965,6 +5966,46 @@ megasas_set_dma_mask(struct pci_dev *pdev)
return 1;
 }
 
+/*
+ * megasas_set_adapter_type -  Set adapter type.
+ * Supported controllers can be divided in
+ * 4 categories-  enum MR_ADAPTER_TYPE {
+ * MFI_SERIES = 1,
+ * THUNDERBOLT_SERIES = 2,
+ * INVADER_SERIES = 3,
+ * VENTURA_SERIES = 4,
+ * };
+ * @instance:  Adapter soft state
+ * return: void
+ */
+static inline void megasas_set_adapter_type(struct megasas_instance *instance)
+{
+   switch (instance->pdev->device) {
+   case PCI_DEVICE_ID_LSI_VENTURA:
+   case PCI_DEVICE_ID_LSI_HARPOON:
+   case PCI_DEVICE_ID_LSI_TOMCAT:
+   case PCI_DEVICE_ID_LSI_VENTURA_4PORT:
+   case PCI_DEVICE_ID_LSI_CRUSADER_4PORT:
+   instance->adapter_type = VENTURA_SERIES;
+   break;
+   case PCI_DEVICE_ID_LSI_FUSION:
+   case PCI_DEVICE_ID_LSI_PLASMA:
+   instance->adapter_type = THUNDERBOLT_SERIES;
+   break;
+   case PCI_DEVICE_ID_LSI_INVADER:
+   case PCI_DEVICE_ID_LSI_INTRUDER:
+   case PCI_DEVICE_ID_LSI_INTRUDER_24:
+   case PCI_DEVICE_ID_LSI_CUTLASS_52:
+   case PCI_DEVICE_ID_LSI_CUTLASS_53:
+   case PCI_DEVICE_ID_LSI_FURY:
+   instance->adapter_type = INVADER_SERIES;
+   break;
+   default: /* For all other supported controllers */
+   instance->adapter_type = MFI_SERIES;
+   break;
+   }
+}
+
 /**
  * megasas_probe_one - PCI hotplug entry point
  * @pdev:  PCI device structure
@@ -5977,7 +6018,6 @@ static int megasas_probe_one(struct pci_dev *pdev,
struct Scsi_Host *host;
struct megasas_instance *instance;
u16 control = 0;
-   struct fusion_context *fusion = NULL;
 
/* Reset MSI-X in the kdump kernel */
if (reset_devices) {
@@ -6022,39 +6062,10 @@ static int megasas_probe_one(struct pci_dev *pdev,
atomic_set(>fw_reset_no_pci_access, 0);
instance->pdev = pdev;
 
-   switch (instance->pdev->device) {
-   case PCI_DEVICE_ID_LSI_VENTURA:
-   case PCI_DEVICE_ID_LSI_HARPOON:
-   case PCI_DEVICE_ID_LSI_TOMCAT:
-   case PCI_DEVICE_ID_LSI_VENTURA_4PORT:
-   case PCI_DEVICE_ID_LSI_CRUSADER_4PORT:
-instance->is_ventura = true;
-   case 

[PATCH 11/19] megaraid_sas: Move initialization of instance parameters inside newly created function megasas_init_ctrl_params

2017-10-19 Thread Shivasharan S
Code refactoring, no functional change - Create new function to initialize
all the controller parameters during load time.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
---
 drivers/scsi/megaraid/megaraid_sas_base.c | 119 +++---
 1 file changed, 61 insertions(+), 58 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 2a68c75b7c4e..86cceb48ba84 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -6225,6 +6225,59 @@ void megasas_free_ctrl_dma_buffers(struct 
megasas_instance *instance)
instance->crash_dump_h);
 }
 
+/*
+ * megasas_init_ctrl_params -  Initialize controller's instance
+ * parameters before FW init
+ * @instance - Adapter soft instance
+ * @return -   void
+ */
+static inline void megasas_init_ctrl_params(struct megasas_instance *instance)
+{
+   instance->fw_crash_state = UNAVAILABLE;
+
+   megasas_poll_wait_aen = 0;
+   instance->issuepend_done = 1;
+   atomic_set(>adprecovery, MEGASAS_HBA_OPERATIONAL);
+
+   /*
+* Initialize locks and queues
+*/
+   INIT_LIST_HEAD(>cmd_pool);
+   INIT_LIST_HEAD(>internal_reset_pending_q);
+
+   atomic_set(>fw_outstanding, 0);
+
+   init_waitqueue_head(>int_cmd_wait_q);
+   init_waitqueue_head(>abort_cmd_wait_q);
+
+   spin_lock_init(>crashdump_lock);
+   spin_lock_init(>mfi_pool_lock);
+   spin_lock_init(>hba_lock);
+   spin_lock_init(>stream_lock);
+   spin_lock_init(>completion_lock);
+
+   mutex_init(>hba_mutex);
+   mutex_init(>reset_mutex);
+
+   if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+   (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY))
+   instance->flag_ieee = 1;
+
+   megasas_dbg_lvl = 0;
+   instance->flag = 0;
+   instance->unload = 1;
+   instance->last_time = 0;
+   instance->disableOnlineCtrlReset = 1;
+   instance->UnevenSpanSupport = 0;
+
+   if (instance->adapter_type != MFI_SERIES) {
+   INIT_WORK(>work_init, megasas_fusion_ocr_wq);
+   INIT_WORK(>crash_init, megasas_fusion_crash_dump_wq);
+   } else {
+   INIT_WORK(>work_init, process_fw_state_change_wq);
+   }
+}
+
 /**
  * megasas_probe_one - PCI hotplug entry point
  * @pdev:  PCI device structure
@@ -6279,74 +6332,24 @@ static int megasas_probe_one(struct pci_dev *pdev,
instance = (struct megasas_instance *)host->hostdata;
memset(instance, 0, sizeof(*instance));
atomic_set(>fw_reset_no_pci_access, 0);
-   instance->pdev = pdev;
-
-   megasas_set_adapter_type(instance);
-
-   if (megasas_alloc_ctrl_mem(instance))
-   goto fail_alloc_dma_buf;
-
-   if (megasas_alloc_ctrl_dma_buffers(instance))
-   goto fail_alloc_dma_buf;
-
-   /* Crash dump feature related initialisation*/
-   instance->drv_buf_index = 0;
-   instance->drv_buf_alloc = 0;
-   instance->crash_dump_fw_support = 0;
-   instance->crash_dump_app_support = 0;
-   instance->fw_crash_state = UNAVAILABLE;
-   spin_lock_init(>crashdump_lock);
-   instance->crash_dump_buf = NULL;
-
-   megasas_poll_wait_aen = 0;
-   instance->flag_ieee = 0;
-   instance->ev = NULL;
-   instance->issuepend_done = 1;
-   atomic_set(>adprecovery, MEGASAS_HBA_OPERATIONAL);
-   instance->is_imr = 0;
-
-   /*
-* Initialize locks and queues
-*/
-   INIT_LIST_HEAD(>cmd_pool);
-   INIT_LIST_HEAD(>internal_reset_pending_q);
-
-   atomic_set(>fw_outstanding,0);
-
-   init_waitqueue_head(>int_cmd_wait_q);
-   init_waitqueue_head(>abort_cmd_wait_q);
-
-   spin_lock_init(>mfi_pool_lock);
-   spin_lock_init(>hba_lock);
-   spin_lock_init(>stream_lock);
-   spin_lock_init(>completion_lock);
-
-   mutex_init(>reset_mutex);
-   mutex_init(>hba_mutex);
 
/*
 * Initialize PCI related and misc parameters
 */
+   instance->pdev = pdev;
instance->host = host;
instance->unique_id = pdev->bus->number << 8 | pdev->devfn;
instance->init_id = MEGASAS_DEFAULT_INIT_ID;
 
-   if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
-   (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY))
-   instance->flag_ieee = 1;
+   megasas_set_adapter_type(instance);
 
-   megasas_dbg_lvl = 0;
-   instance->flag = 0;
-   instance->unload = 1;
-   instance->last_time = 0;
-   instance->disableOnlineCtrlReset = 1;
-   instance->UnevenSpanSupport = 0;
+   megasas_init_ctrl_params(instance);
 
-   if 

[PATCH 06/19] megaraid_sas: reduce size of fusion_context and use kmalloc for allocation

2017-10-19 Thread Shivasharan S
fusion_context structure is very large around 180kB
and most of the size is contributed by log_to_span
array. Move log_to_span out of fusion context and have
separate allocation for log_to_span. And use kmalloc
to allocate fusion_context.
Currently kmemleak reports 1000s of false positives for
fusion->cmd_list[]. kmemleak does not track page allocation
for fusion_context. This change will also fix the false positives
reported by kmemleak.

Ref: https://marc.info/?l=linux-scsi=150545293900917

Reported-by: Shu Wang 
Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
---
 drivers/scsi/megaraid/megaraid_sas.h|  1 -
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 43 +++--
 drivers/scsi/megaraid/megaraid_sas_fusion.h |  3 +-
 3 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index 5b36a0103895..1f34577d8982 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -2218,7 +2218,6 @@ struct megasas_instance {
 
/* Ptr to hba specific information */
void *ctrl_context;
-   u32 ctrl_context_pages;
struct megasas_ctrl_info *ctrl_info;
unsigned int msix_vectors;
struct megasas_irq_context irq_context[MEGASAS_MAX_MSIX_QUEUES];
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 01d42eb6486b..a8055341e875 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -4502,20 +4502,31 @@ megasas_alloc_fusion_context(struct megasas_instance 
*instance)
 {
struct fusion_context *fusion;
 
-   instance->ctrl_context_pages = get_order(sizeof(struct fusion_context));
-   instance->ctrl_context = (void *)__get_free_pages(GFP_KERNEL | 
__GFP_ZERO,
-   instance->ctrl_context_pages);
+   instance->ctrl_context = kzalloc(sizeof(struct fusion_context),
+GFP_KERNEL);
if (!instance->ctrl_context) {
-   /* fall back to using vmalloc for fusion_context */
-   instance->ctrl_context = vzalloc(sizeof(struct fusion_context));
-   if (!instance->ctrl_context) {
-   dev_err(>pdev->dev, "Failed from %s %d\n", 
__func__, __LINE__);
-   return -ENOMEM;
-   }
+   dev_err(>pdev->dev, "Failed from %s %d\n",
+   __func__, __LINE__);
+   return -ENOMEM;
}
 
fusion = instance->ctrl_context;
 
+   fusion->log_to_span_pages = get_order(MAX_LOGICAL_DRIVES_EXT *
+ sizeof(LD_SPAN_INFO));
+   fusion->log_to_span =
+   (PLD_SPAN_INFO)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
+   fusion->log_to_span_pages);
+   if (!fusion->log_to_span) {
+   fusion->log_to_span = vzalloc(MAX_LOGICAL_DRIVES_EXT *
+ sizeof(LD_SPAN_INFO));
+   if (!fusion->log_to_span) {
+   dev_err(>pdev->dev, "Failed from %s %d\n",
+   __func__, __LINE__);
+   return -ENOMEM;
+   }
+   }
+
fusion->load_balance_info_pages = get_order(MAX_LOGICAL_DRIVES_EXT *
sizeof(struct LD_LOAD_BALANCE_INFO));
fusion->load_balance_info =
@@ -4546,11 +4557,15 @@ megasas_free_fusion_context(struct megasas_instance 
*instance)
fusion->load_balance_info_pages);
}
 
-   if (is_vmalloc_addr(fusion))
-   vfree(fusion);
-   else
-   free_pages((ulong)fusion,
-   instance->ctrl_context_pages);
+   if (fusion->log_to_span) {
+   if (is_vmalloc_addr(fusion->log_to_span))
+   vfree(fusion->log_to_span);
+   else
+   free_pages((ulong)fusion->log_to_span,
+  fusion->log_to_span_pages);
+   }
+
+   kfree(fusion);
}
 }
 
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h 
b/drivers/scsi/megaraid/megaraid_sas_fusion.h
index 7c1f7ccf031d..a2b56913f382 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
@@ -1312,7 +1312,8 @@ struct fusion_context {
u8 fast_path_io;
struct LD_LOAD_BALANCE_INFO *load_balance_info;
u32 load_balance_info_pages;
-   LD_SPAN_INFO log_to_span[MAX_LOGICAL_DRIVES_EXT];
+   LD_SPAN_INFO *log_to_span;
+   u32 log_to_span_pages;
struct LD_STREAM_DETECT 

[PATCH 08/19] megaraid_sas: Create separate functions for allocating and freeing controller DMA buffers

2017-10-19 Thread Shivasharan S
Code refactoring - create separate functions to allocate and free
controller DMA buffers

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
---
 drivers/scsi/megaraid/megaraid_sas_base.c | 186 +-
 1 file changed, 103 insertions(+), 83 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 53f01729c6a8..443819747c5d 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -6092,6 +6092,103 @@ static inline void megasas_free_ctrl_mem(struct 
megasas_instance *instance)
}
 }
 
+/**
+ * megasas_alloc_ctrl_dma_buffers -Allocate consistent DMA buffers during
+ * driver load time
+ *
+ * @instance-  Adapter soft instance
+ * @return-O for SUCCESS
+ */
+static inline
+int megasas_alloc_ctrl_dma_buffers(struct megasas_instance *instance)
+{
+   struct pci_dev *pdev = instance->pdev;
+
+   instance->evt_detail =
+   pci_alloc_consistent(pdev,
+sizeof(struct megasas_evt_detail),
+>evt_detail_h);
+
+   if (!instance->evt_detail) {
+   dev_err(>pdev->dev,
+   "Failed to allocate event detail buffer\n");
+   return -ENOMEM;
+   }
+
+   if (!reset_devices) {
+   instance->system_info_buf =
+   pci_alloc_consistent(pdev,
+sizeof(struct MR_DRV_SYSTEM_INFO),
+>system_info_h);
+   instance->pd_info =
+   pci_alloc_consistent(pdev,
+sizeof(struct MR_PD_INFO),
+>pd_info_h);
+   instance->tgt_prop =
+   pci_alloc_consistent(pdev,
+sizeof(struct 
MR_TARGET_PROPERTIES),
+>tgt_prop_h);
+   instance->crash_dump_buf =
+   pci_alloc_consistent(pdev,
+CRASH_DMA_BUF_SIZE,
+>crash_dump_h);
+
+   if (!instance->system_info_buf)
+   dev_err(>pdev->dev,
+   "Failed to allocate system info buffer\n");
+
+   if (!instance->pd_info)
+   dev_err(>pdev->dev,
+   "Failed to allocate pd_info buffer\n");
+
+   if (!instance->tgt_prop)
+   dev_err(>pdev->dev,
+   "Failed to allocate tgt_prop buffer\n");
+
+   if (!instance->crash_dump_buf)
+   dev_err(>pdev->dev,
+   "Failed to allocate crash dump buffer\n");
+   }
+
+   return 0;
+}
+
+/*
+ * megasas_free_ctrl_dma_buffers - Free consistent DMA buffers allocated
+ * during driver load time
+ *
+ * @instance-  Adapter soft instance
+ *
+ */
+static inline
+void megasas_free_ctrl_dma_buffers(struct megasas_instance *instance)
+{
+   struct pci_dev *pdev = instance->pdev;
+
+   if (instance->evt_detail)
+   pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
+   instance->evt_detail,
+   instance->evt_detail_h);
+
+   if (instance->system_info_buf)
+   pci_free_consistent(pdev, sizeof(struct MR_DRV_SYSTEM_INFO),
+   instance->system_info_buf,
+   instance->system_info_h);
+
+   if (instance->pd_info)
+   pci_free_consistent(pdev, sizeof(struct MR_PD_INFO),
+   instance->pd_info, instance->pd_info_h);
+
+   if (instance->tgt_prop)
+   pci_free_consistent(pdev, sizeof(struct MR_TARGET_PROPERTIES),
+   instance->tgt_prop, instance->tgt_prop_h);
+
+   if (instance->crash_dump_buf)
+   pci_free_consistent(pdev, CRASH_DMA_BUF_SIZE,
+   instance->crash_dump_buf,
+   instance->crash_dump_h);
+}
+
 /**
  * megasas_probe_one - PCI hotplug entry point
  * @pdev:  PCI device structure
@@ -6153,6 +6250,9 @@ static int megasas_probe_one(struct pci_dev *pdev,
if (megasas_alloc_ctrl_mem(instance))
goto fail_alloc_dma_buf;
 
+   if (megasas_alloc_ctrl_dma_buffers(instance))
+   goto fail_alloc_dma_buf;
+
/* Crash dump feature related initialisation*/

[PATCH 14/19] megaraid_sas: Resize MFA frame used for IOC INIT to 4k

2017-10-19 Thread Shivasharan S
Older firmware version unconditionally pulls 4k frame for
IOC INIT MFA frame.
But driver allocates 1k or 4k max_chain_frame_sz based on FW capability.
During boot time, this results in DMA read errors.
Workaround fix in driver by allocating separate ioc_init frame of 4k size
to support older firmware.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
Cc: sta...@vger.kernel.org
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 65 +
 drivers/scsi/megaraid/megaraid_sas_fusion.h |  2 +
 2 files changed, 58 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 277fd16305ee..857bdbb0f79d 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -780,13 +780,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
ioc_init_handle = fusion->ioc_init_request_phys;
IOCInitMessage = fusion->ioc_init_request;
 
-   cmd = megasas_get_cmd(instance);
-
-   if (!cmd) {
-   dev_err(>pdev->dev, "Could not allocate cmd for INIT 
Frame\n");
-   ret = 1;
-   goto fail_get_cmd;
-   }
+   cmd = fusion->ioc_init_cmd;
 
scratch_pad_2 = readl
(>reg_set->outbound_scratch_pad_2);
@@ -918,8 +912,6 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
ret = 0;
 
 fail_fw_init:
-   megasas_return_cmd(instance, cmd);
-fail_get_cmd:
dev_err(>pdev->dev,
"Init cmd return status %s for SCSI host %d\n",
ret ? "FAILED" : "SUCCESS", instance->host->host_no);
@@ -1333,6 +1325,56 @@ static inline int megasas_allocate_raid_maps(struct 
megasas_instance *instance)
return -ENOMEM;
 }
 
+static int megasas_alloc_ioc_init_frame(struct megasas_instance *instance)
+{
+   struct fusion_context *fusion;
+   struct megasas_cmd *cmd;
+
+   fusion = instance->ctrl_context;
+
+   cmd = kmalloc(sizeof(struct megasas_cmd), GFP_KERNEL);
+
+   if (!cmd) {
+   dev_err(>pdev->dev, "Failed from func: %s line: %d\n",
+   __func__, __LINE__);
+   return -ENOMEM;
+   }
+
+   cmd->frame = dma_alloc_coherent(>pdev->dev,
+   IOC_INIT_FRAME_SIZE,
+   >frame_phys_addr, GFP_KERNEL);
+
+   if (!cmd->frame) {
+   dev_err(>pdev->dev, "Failed from func: %s line: %d\n",
+   __func__, __LINE__);
+   kfree(cmd);
+   return -ENOMEM;
+   }
+
+   fusion->ioc_init_cmd = cmd;
+   return 0;
+}
+
+/**
+ * megasas_free_ioc_init_cmd - Free IOC INIT command frame
+ * @instance:  Adapter soft state
+ */
+static inline void megasas_free_ioc_init_cmd(struct megasas_instance *instance)
+{
+   struct fusion_context *fusion;
+
+   fusion = instance->ctrl_context;
+
+   if (fusion->ioc_init_cmd && fusion->ioc_init_cmd->frame)
+   dma_free_coherent(>pdev->dev,
+ IOC_INIT_FRAME_SIZE,
+ fusion->ioc_init_cmd->frame,
+ fusion->ioc_init_cmd->frame_phys_addr);
+
+   if (fusion->ioc_init_cmd)
+   kfree(fusion->ioc_init_cmd);
+}
+
 /**
  * megasas_init_adapter_fusion -   Initializes the FW
  * @instance:  Adapter soft state
@@ -1428,6 +1470,9 @@ megasas_init_adapter_fusion(struct megasas_instance 
*instance)
MEGASAS_FUSION_IOCTL_CMDS);
sema_init(>ioctl_sem, MEGASAS_FUSION_IOCTL_CMDS);
 
+   if (megasas_alloc_ioc_init_frame(instance))
+   return 1;
+
/*
 * Allocate memory for descriptors
 * Create a pool of commands
@@ -1465,6 +1510,7 @@ megasas_init_adapter_fusion(struct megasas_instance 
*instance)
 fail_alloc_cmds:
megasas_free_cmds(instance);
 fail_alloc_mfi_cmds:
+   megasas_free_ioc_init_cmd(instance);
return 1;
 }
 
@@ -3383,6 +3429,7 @@ megasas_issue_dcmd_fusion(struct megasas_instance 
*instance,
 void
 megasas_release_fusion(struct megasas_instance *instance)
 {
+   megasas_free_ioc_init_cmd(instance);
megasas_free_cmds(instance);
megasas_free_cmds_fusion(instance);
 
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h 
b/drivers/scsi/megaraid/megaraid_sas_fusion.h
index 5b3f1dba1ab2..549f86b2e871 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
@@ -103,6 +103,7 @@ enum MR_RAID_FLAGS_IO_SUB_TYPE {
 #define THRESHOLD_REPLY_COUNT 50
 #define RAID_1_PEER_CMDS 2
 #define JBOD_MAPS_COUNT2
+#define IOC_INIT_FRAME_SIZE 4096
 
 /*
  * Raid Context structure which describes MegaRAID specific IO Parameters
@@ -1317,6 +1318,7 @@ struct 

[PATCH 05/19] megaraid_sas: replace is_ventura with adapter_type checks

2017-10-19 Thread Shivasharan S
No functional change.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
---
 drivers/scsi/megaraid/megaraid_sas.h|  1 -
 drivers/scsi/megaraid/megaraid_sas_base.c   |  9 -
 drivers/scsi/megaraid/megaraid_sas_fp.c | 10 +-
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 26 +-
 4 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index 3f20273b115b..5b36a0103895 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -2244,7 +2244,6 @@ struct megasas_instance {
bool dev_handle;
bool fw_sync_cache_support;
u32 mfi_frame_size;
-   bool is_ventura;
bool msix_combined;
u16 max_raid_mapsize;
/* preffered count to send as LDIO irrspective of FP capable.*/
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 001b075d0dd6..5691e031112e 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -5221,7 +5221,7 @@ static int megasas_init_fw(struct megasas_instance 
*instance)
goto fail_ready_state;
}
 
-   if (instance->is_ventura) {
+   if (instance->adapter_type == VENTURA_SERIES) {
scratch_pad_3 =
readl(>reg_set->outbound_scratch_pad_3);
instance->max_raid_mapsize = ((scratch_pad_3 >>
@@ -5330,7 +5330,7 @@ static int megasas_init_fw(struct megasas_instance 
*instance)
if (instance->instancet->init_adapter(instance))
goto fail_init_adapter;
 
-   if (instance->is_ventura) {
+   if (instance->adapter_type == VENTURA_SERIES) {
scratch_pad_4 =
readl(>reg_set->outbound_scratch_pad_4);
if ((scratch_pad_4 & MR_NVME_PAGE_SIZE_MASK) >=
@@ -5366,7 +5366,7 @@ static int megasas_init_fw(struct megasas_instance 
*instance)
memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
 
/* stream detection initialization */
-   if (instance->is_ventura && fusion) {
+   if (instance->adapter_type == VENTURA_SERIES) {
fusion->stream_detect_by_ld =
kzalloc(sizeof(struct LD_STREAM_DETECT *)
* MAX_LOGICAL_DRIVES_EXT,
@@ -6101,7 +6101,6 @@ static int megasas_probe_one(struct pci_dev *pdev,
 
break;
case VENTURA_SERIES:
-   instance->is_ventura = 1;
case THUNDERBOLT_SERIES:
case INVADER_SERIES:
if (megasas_alloc_fusion_context(instance)) {
@@ -6693,7 +6692,7 @@ static void megasas_detach_one(struct pci_dev *pdev)
if (instance->msix_vectors)
pci_free_irq_vectors(instance->pdev);
 
-   if (instance->is_ventura) {
+   if (instance->adapter_type == VENTURA_SERIES) {
for (i = 0; i < MAX_LOGICAL_DRIVES_EXT; ++i)
kfree(fusion->stream_detect_by_ld[i]);
kfree(fusion->stream_detect_by_ld);
diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c 
b/drivers/scsi/megaraid/megaraid_sas_fp.c
index 47af0e13b97a..bfad9bfc313f 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fp.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -737,7 +737,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance 
*instance, u32 ld,
*pDevHandle = MR_PdDevHandleGet(pd, map);
*pPdInterface = MR_PdInterfaceTypeGet(pd, map);
/* get second pd also for raid 1/10 fast path writes*/
-   if (instance->is_ventura &&
+   if ((instance->adapter_type == VENTURA_SERIES) &&
(raid->level == 1) &&
!io_info->isRead) {
r1_alt_pd = MR_ArPdGet(arRef, physArm + 1, map);
@@ -762,7 +762,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance 
*instance, u32 ld,
}
 
*pdBlock += stripRef + le64_to_cpu(MR_LdSpanPtrGet(ld, span, 
map)->startBlk);
-   if (instance->is_ventura) {
+   if (instance->adapter_type == VENTURA_SERIES) {
((struct RAID_CONTEXT_G35 *)pRAID_Context)->span_arm =
(span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
io_info->span_arm =
@@ -853,7 +853,7 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 
ld, u64 stripRow,
*pDevHandle = MR_PdDevHandleGet(pd, map);
*pPdInterface = MR_PdInterfaceTypeGet(pd, map);
/* get second pd also for raid 1/10 fast path writes*/
-   if (instance->is_ventura &&
+   if ((instance->adapter_type == VENTURA_SERIES) &&
(raid->level == 1) &&
!io_info->isRead) {
r1_alt_pd = 

[PATCH 02/19] megaraid_sas: Add support for Crusader controllers

2017-10-19 Thread Shivasharan S
Add support for PCI VID/DID 0x1000/0x0015 based MegaRAID controllers.
Since the DID 0x0015 conflicts with DELL PERC5 controllers,
add vendor ID based check specific for DELL PERC5.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
---
 drivers/scsi/megaraid/megaraid_sas.h  |  1 +
 drivers/scsi/megaraid/megaraid_sas_base.c | 51 ++-
 2 files changed, 30 insertions(+), 22 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index 90b9b5d7f0f8..3f20273b115b 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -57,6 +57,7 @@
 #define PCI_DEVICE_ID_LSI_CUTLASS_52   0x0052
 #define PCI_DEVICE_ID_LSI_CUTLASS_53   0x0053
 #define PCI_DEVICE_ID_LSI_VENTURA  0x0014
+#define PCI_DEVICE_ID_LSI_CRUSADER 0x0015
 #define PCI_DEVICE_ID_LSI_HARPOON  0x0016
 #define PCI_DEVICE_ID_LSI_TOMCAT   0x0017
 #define PCI_DEVICE_ID_LSI_VENTURA_4PORT0x001B
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 2f9955c6c2af..eba627ccd041 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -161,6 +161,7 @@ static struct pci_device_id megasas_pci_table[] = {
{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CUTLASS_53)},
/* VENTURA */
{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VENTURA)},
+   {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CRUSADER)},
{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_HARPOON)},
{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_TOMCAT)},
{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VENTURA_4PORT)},
@@ -5980,29 +5981,35 @@ megasas_set_dma_mask(struct pci_dev *pdev)
  */
 static inline void megasas_set_adapter_type(struct megasas_instance *instance)
 {
-   switch (instance->pdev->device) {
-   case PCI_DEVICE_ID_LSI_VENTURA:
-   case PCI_DEVICE_ID_LSI_HARPOON:
-   case PCI_DEVICE_ID_LSI_TOMCAT:
-   case PCI_DEVICE_ID_LSI_VENTURA_4PORT:
-   case PCI_DEVICE_ID_LSI_CRUSADER_4PORT:
-   instance->adapter_type = VENTURA_SERIES;
-   break;
-   case PCI_DEVICE_ID_LSI_FUSION:
-   case PCI_DEVICE_ID_LSI_PLASMA:
-   instance->adapter_type = THUNDERBOLT_SERIES;
-   break;
-   case PCI_DEVICE_ID_LSI_INVADER:
-   case PCI_DEVICE_ID_LSI_INTRUDER:
-   case PCI_DEVICE_ID_LSI_INTRUDER_24:
-   case PCI_DEVICE_ID_LSI_CUTLASS_52:
-   case PCI_DEVICE_ID_LSI_CUTLASS_53:
-   case PCI_DEVICE_ID_LSI_FURY:
-   instance->adapter_type = INVADER_SERIES;
-   break;
-   default: /* For all other supported controllers */
+   if ((instance->pdev->vendor == PCI_VENDOR_ID_DELL) &&
+   (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5)) {
instance->adapter_type = MFI_SERIES;
-   break;
+   } else {
+   switch (instance->pdev->device) {
+   case PCI_DEVICE_ID_LSI_VENTURA:
+   case PCI_DEVICE_ID_LSI_CRUSADER:
+   case PCI_DEVICE_ID_LSI_HARPOON:
+   case PCI_DEVICE_ID_LSI_TOMCAT:
+   case PCI_DEVICE_ID_LSI_VENTURA_4PORT:
+   case PCI_DEVICE_ID_LSI_CRUSADER_4PORT:
+   instance->adapter_type = VENTURA_SERIES;
+   break;
+   case PCI_DEVICE_ID_LSI_FUSION:
+   case PCI_DEVICE_ID_LSI_PLASMA:
+   instance->adapter_type = THUNDERBOLT_SERIES;
+   break;
+   case PCI_DEVICE_ID_LSI_INVADER:
+   case PCI_DEVICE_ID_LSI_INTRUDER:
+   case PCI_DEVICE_ID_LSI_INTRUDER_24:
+   case PCI_DEVICE_ID_LSI_CUTLASS_52:
+   case PCI_DEVICE_ID_LSI_CUTLASS_53:
+   case PCI_DEVICE_ID_LSI_FURY:
+   instance->adapter_type = INVADER_SERIES;
+   break;
+   default: /* For all other supported controllers */
+   instance->adapter_type = MFI_SERIES;
+   break;
+   }
}
 }
 
-- 
2.14.1.dirty



[PATCH 07/19] megaraid_sas: Create separate functions to allocate ctrl memory

2017-10-19 Thread Shivasharan S
No functional change. Code refactoring to improve readability.
Move the code to allocate and free controller memory into
separate functions.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
---
 drivers/scsi/megaraid/megaraid_sas_base.c | 122 +++---
 1 file changed, 76 insertions(+), 46 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 5691e031112e..53f01729c6a8 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -6023,6 +6023,75 @@ static inline void megasas_set_adapter_type(struct 
megasas_instance *instance)
}
 }
 
+static inline int megasas_alloc_mfi_ctrl_mem(struct megasas_instance *instance)
+{
+   instance->producer = pci_alloc_consistent(instance->pdev, sizeof(u32),
+ >producer_h);
+   instance->consumer = pci_alloc_consistent(instance->pdev, sizeof(u32),
+ >consumer_h);
+
+   if (!instance->producer || !instance->consumer) {
+   dev_err(>pdev->dev,
+   "Failed to allocate memory for producer, consumer\n");
+   return -1;
+   }
+
+   *instance->producer = 0;
+   *instance->consumer = 0;
+   return 0;
+}
+
+/**
+ * megasas_alloc_ctrl_mem -Allocate per controller memory for core data
+ * structures which are not common across MFI
+ * adapters and fusion adapters.
+ * For MFI based adapters, allocate producer and
+ * consumer buffers. For fusion adapters, allocate
+ * memory for fusion context.
+ * @instance:  Adapter soft state
+ * return: 0 for SUCCESS
+ */
+static int megasas_alloc_ctrl_mem(struct megasas_instance *instance)
+{
+   switch (instance->adapter_type) {
+   case MFI_SERIES:
+   if (megasas_alloc_mfi_ctrl_mem(instance))
+   return -ENOMEM;
+   break;
+   case VENTURA_SERIES:
+   case THUNDERBOLT_SERIES:
+   case INVADER_SERIES:
+   if (megasas_alloc_fusion_context(instance))
+   return -ENOMEM;
+   break;
+   }
+
+   return 0;
+}
+
+/*
+ * megasas_free_ctrl_mem - Free fusion context for fusion adapters and
+ * producer, consumer buffers for MFI adapters
+ *
+ * @instance - Adapter soft instance
+ *
+ */
+static inline void megasas_free_ctrl_mem(struct megasas_instance *instance)
+{
+   if (instance->adapter_type == MFI_SERIES) {
+   if (instance->producer)
+   pci_free_consistent(instance->pdev, sizeof(u32),
+   instance->producer,
+   instance->producer_h);
+   if (instance->consumer)
+   pci_free_consistent(instance->pdev, sizeof(u32),
+   instance->consumer,
+   instance->consumer_h);
+   } else {
+   megasas_free_fusion_context(instance);
+   }
+}
+
 /**
  * megasas_probe_one - PCI hotplug entry point
  * @pdev:  PCI device structure
@@ -6081,33 +6150,8 @@ static int megasas_probe_one(struct pci_dev *pdev,
 
megasas_set_adapter_type(instance);
 
-   switch (instance->adapter_type) {
-   case MFI_SERIES:
-   instance->producer =
-   pci_alloc_consistent(pdev, sizeof(u32),
->producer_h);
-   instance->consumer =
-   pci_alloc_consistent(pdev, sizeof(u32),
->consumer_h);
-
-   if (!instance->producer || !instance->consumer) {
-   dev_printk(KERN_DEBUG, >dev, "Failed to allocate "
-  "memory for producer, consumer\n");
-   goto fail_alloc_dma_buf;
-   }
-
-   *instance->producer = 0;
-   *instance->consumer = 0;
-
-   break;
-   case VENTURA_SERIES:
-   case THUNDERBOLT_SERIES:
-   case INVADER_SERIES:
-   if (megasas_alloc_fusion_context(instance)) {
-   megasas_free_fusion_context(instance);
-   goto fail_alloc_dma_buf;
-   }
-   }
+   if (megasas_alloc_ctrl_mem(instance))
+   goto fail_alloc_dma_buf;
 
/* Crash dump feature related initialisation*/
instance->drv_buf_index = 0;
@@ -6303,12 +6347,7 @@ static int megasas_probe_one(struct pci_dev *pdev,
pci_free_consistent(pdev, 

[PATCH 10/19] megaraid_sas: remove instance->ctrl_info

2017-10-19 Thread Shivasharan S
Re-use the pre-allocated ctrl_info DMA buffer.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
---
 drivers/scsi/megaraid/megaraid_sas.h  |  1 -
 drivers/scsi/megaraid/megaraid_sas_base.c | 43 ++-
 2 files changed, 14 insertions(+), 30 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index 80ba77b4b9e2..83427b541629 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -2231,7 +2231,6 @@ struct megasas_instance {
 
/* Ptr to hba specific information */
void *ctrl_context;
-   struct megasas_ctrl_info *ctrl_info;
unsigned int msix_vectors;
struct megasas_irq_context irq_context[MEGASAS_MAX_MSIX_QUEUES];
u64 map_id;
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 16a91ce2b2cb..2a68c75b7c4e 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -4545,9 +4545,9 @@ static void megasas_update_ext_vd_details(struct 
megasas_instance *instance)
return;
 
instance->supportmax256vd =
-   instance->ctrl_info->adapterOperations3.supportMaxExtLDs;
+   instance->ctrl_info_buf->adapterOperations3.supportMaxExtLDs;
/* Below is additional check to address future FW enhancement */
-   if (instance->ctrl_info->max_lds > 64)
+   if (instance->ctrl_info_buf->max_lds > 64)
instance->supportmax256vd = 1;
 
instance->drv_supported_vd_count = MEGASAS_MAX_LD_CHANNELS
@@ -4605,11 +4605,8 @@ megasas_get_ctrl_info(struct megasas_instance *instance)
struct megasas_cmd *cmd;
struct megasas_dcmd_frame *dcmd;
struct megasas_ctrl_info *ci;
-   struct megasas_ctrl_info *ctrl_info;
dma_addr_t ci_h = 0;
 
-   ctrl_info = instance->ctrl_info;
-
ci = instance->ctrl_info_buf;
ci_h = instance->ctrl_info_buf_h;
 
@@ -4645,14 +4642,13 @@ megasas_get_ctrl_info(struct megasas_instance *instance)
 
switch (ret) {
case DCMD_SUCCESS:
-   memcpy(ctrl_info, ci, sizeof(struct megasas_ctrl_info));
/* Save required controller information in
 * CPU endianness format.
 */
-   le32_to_cpus((u32 *)_info->properties.OnOffProperties);
-   le32_to_cpus((u32 *)_info->adapterOperations2);
-   le32_to_cpus((u32 *)_info->adapterOperations3);
-   le16_to_cpus((u16 *)_info->adapter_operations4);
+   le32_to_cpus((u32 *)>properties.OnOffProperties);
+   le32_to_cpus((u32 *)>adapterOperations2);
+   le32_to_cpus((u32 *)>adapterOperations3);
+   le16_to_cpus((u16 *)>adapter_operations4);
 
/* Update the latest Ext VD info.
 * From Init path, store current firmware details.
@@ -4661,21 +4657,21 @@ megasas_get_ctrl_info(struct megasas_instance *instance)
 */
megasas_update_ext_vd_details(instance);
instance->use_seqnum_jbod_fp =
-   ctrl_info->adapterOperations3.useSeqNumJbodFP;
+   ci->adapterOperations3.useSeqNumJbodFP;
instance->support_morethan256jbod =
-   ctrl_info->adapter_operations4.support_pd_map_target_id;
+   ci->adapter_operations4.support_pd_map_target_id;
 
/*Check whether controller is iMR or MR */
-   instance->is_imr = (ctrl_info->memory_size ? 0 : 1);
+   instance->is_imr = (ci->memory_size ? 0 : 1);
dev_info(>pdev->dev,
"controller type\t: %s(%dMB)\n",
instance->is_imr ? "iMR" : "MR",
-   le16_to_cpu(ctrl_info->memory_size));
+   le16_to_cpu(ci->memory_size));
 
instance->disableOnlineCtrlReset =
-   
ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset;
+   ci->properties.OnOffProperties.disableOnlineCtrlReset;
instance->secure_jbod_support =
-   ctrl_info->adapterOperations3.supportSecurityonJBOD;
+   ci->adapterOperations3.supportSecurityonJBOD;
dev_info(>pdev->dev, "Online Controller Reset(OCR)\t: 
%s\n",
instance->disableOnlineCtrlReset ? "Disabled" : 
"Enabled");
dev_info(>pdev->dev, "Secure JBOD support\t: %s\n",
@@ -5063,7 +5059,7 @@ megasas_setup_jbod_map(struct megasas_instance *instance)
(sizeof(struct MR_PD_CFG_SEQ) * (MAX_PHYSICAL_DEVICES - 1));
 
if (reset_devices || !fusion ||
-   !instance->ctrl_info->adapterOperations3.useSeqNumJbodFP) {
+

[PATCH 00/19] megaraid_sas: Updates for scsi-next

2017-10-19 Thread Shivasharan S
Shivasharan S (19):
  megaraid_sas: use adapter_type for all gen controllers
  megaraid_sas: Add support for Crusader controllers
  megaraid_sas: replace instance->ctrl_context checks with
instance->adapter_type
  megaraid_sas: Remove redundant checks for ctrl_context
  megaraid_sas: replace is_ventura with adapter_type checks
  megaraid_sas: reduce size of fusion_context and use kmalloc for
allocation
  megaraid_sas: Create separate functions to allocate ctrl memory
  megaraid_sas: Create separate functions for allocating and freeing
controller DMA buffers
  megaraid_sas: Pre-allocate frequently used DMA buffers
  megaraid_sas: remove instance->ctrl_info
  megaraid_sas: Move initialization of instance parameters inside newly
created function megasas_init_ctrl_params
  megaraid_sas: Move controller memory allocations and DMA mask settings
from probe to megasas_init_fw
  megaraid_sas: Update current host time to FW during IOC Init
  megaraid_sas: Resize MFA frame used for IOC INIT to 4k
  megaraid_sas: Incorrect processing of IOCTL frames for SMP/STP
commands
  megaraid_sas: Retry with reduced queue depth when alloc fails for
higher QD
  megaraid_sas: Do not limit queue_depth to 1k in non-RDPQ mode
  megaraid_sas: Add support for 64bit consistent DMA
  megaraid_sas: driver version upgrade

 drivers/scsi/megaraid/megaraid_sas.h|   64 +-
 drivers/scsi/megaraid/megaraid_sas_base.c   | 1023 +--
 drivers/scsi/megaraid/megaraid_sas_fp.c |   20 +-
 drivers/scsi/megaraid/megaraid_sas_fusion.c |  676 +-
 drivers/scsi/megaraid/megaraid_sas_fusion.h |   29 +-
 5 files changed, 1207 insertions(+), 605 deletions(-)

-- 
2.14.1.dirty



[PATCH 09/19] megaraid_sas: Pre-allocate frequently used DMA buffers

2017-10-19 Thread Shivasharan S
Pre-allocate few of the frequently used DMA buffers during load time.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
---
 drivers/scsi/megaraid/megaraid_sas.h|  13 +++
 drivers/scsi/megaraid/megaraid_sas_base.c   | 147 ++--
 drivers/scsi/megaraid/megaraid_sas_fusion.c |  19 +---
 drivers/scsi/megaraid/megaraid_sas_fusion.h |   3 +
 4 files changed, 116 insertions(+), 66 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index 1f34577d8982..80ba77b4b9e2 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -2122,6 +2122,19 @@ struct megasas_instance {
 
u32 *crash_dump_buf;
dma_addr_t crash_dump_h;
+
+   struct MR_PD_LIST *pd_list_buf;
+   dma_addr_t pd_list_buf_h;
+
+   struct megasas_ctrl_info *ctrl_info_buf;
+   dma_addr_t ctrl_info_buf_h;
+
+   struct MR_LD_LIST *ld_list_buf;
+   dma_addr_t ld_list_buf_h;
+
+   struct MR_LD_TARGETID_LIST *ld_targetid_list_buf;
+   dma_addr_t ld_targetid_list_buf_h;
+
void *crash_buf[MAX_CRASH_DUMP_SIZE];
unsigned intfw_crash_buffer_size;
unsigned intfw_crash_state;
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 443819747c5d..16a91ce2b2cb 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -4211,6 +4211,9 @@ megasas_get_pd_list(struct megasas_instance *instance)
return ret;
}
 
+   ci = instance->pd_list_buf;
+   ci_h = instance->pd_list_buf_h;
+
cmd = megasas_get_cmd(instance);
 
if (!cmd) {
@@ -4220,15 +4223,6 @@ megasas_get_pd_list(struct megasas_instance *instance)
 
dcmd = >frame->dcmd;
 
-   ci = pci_alloc_consistent(instance->pdev,
- MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), _h);
-
-   if (!ci) {
-   dev_printk(KERN_DEBUG, >pdev->dev, "Failed to alloc 
mem for pd_list\n");
-   megasas_return_cmd(instance, cmd);
-   return -ENOMEM;
-   }
-
memset(ci, 0, sizeof(*ci));
memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
 
@@ -4314,10 +4308,6 @@ megasas_get_pd_list(struct megasas_instance *instance)
 
}
 
-   pci_free_consistent(instance->pdev,
-   MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST),
-   ci, ci_h);
-
if (ret != DCMD_TIMEOUT)
megasas_return_cmd(instance, cmd);
 
@@ -4343,6 +4333,9 @@ megasas_get_ld_list(struct megasas_instance *instance)
dma_addr_t ci_h = 0;
u32 ld_count;
 
+   ci = instance->ld_list_buf;
+   ci_h = instance->ld_list_buf_h;
+
cmd = megasas_get_cmd(instance);
 
if (!cmd) {
@@ -4352,16 +4345,6 @@ megasas_get_ld_list(struct megasas_instance *instance)
 
dcmd = >frame->dcmd;
 
-   ci = pci_alloc_consistent(instance->pdev,
-   sizeof(struct MR_LD_LIST),
-   _h);
-
-   if (!ci) {
-   dev_printk(KERN_DEBUG, >pdev->dev, "Failed to alloc 
mem in get_ld_list\n");
-   megasas_return_cmd(instance, cmd);
-   return -ENOMEM;
-   }
-
memset(ci, 0, sizeof(*ci));
memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
 
@@ -4433,8 +4416,6 @@ megasas_get_ld_list(struct megasas_instance *instance)
break;
}
 
-   pci_free_consistent(instance->pdev, sizeof(struct MR_LD_LIST), ci, 
ci_h);
-
if (ret != DCMD_TIMEOUT)
megasas_return_cmd(instance, cmd);
 
@@ -4460,6 +4441,9 @@ megasas_ld_list_query(struct megasas_instance *instance, 
u8 query_type)
dma_addr_t ci_h = 0;
u32 tgtid_count;
 
+   ci = instance->ld_targetid_list_buf;
+   ci_h = instance->ld_targetid_list_buf_h;
+
cmd = megasas_get_cmd(instance);
 
if (!cmd) {
@@ -4470,16 +4454,6 @@ megasas_ld_list_query(struct megasas_instance *instance, 
u8 query_type)
 
dcmd = >frame->dcmd;
 
-   ci = pci_alloc_consistent(instance->pdev,
- sizeof(struct MR_LD_TARGETID_LIST), _h);
-
-   if (!ci) {
-   dev_warn(>pdev->dev,
-"Failed to alloc mem for ld_list_query\n");
-   megasas_return_cmd(instance, cmd);
-   return -ENOMEM;
-   }
-
memset(ci, 0, sizeof(*ci));
memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
 
@@ -4550,9 +4524,6 @@ megasas_ld_list_query(struct megasas_instance *instance, 
u8 query_type)
break;
}
 
-   pci_free_consistent(instance->pdev, sizeof(struct MR_LD_TARGETID_LIST),
-   ci, ci_h);
-
if (ret != DCMD_TIMEOUT)
megasas_return_cmd(instance, cmd);
 
@@ -4639,6 +4610,9 @@ 

[PATCH 12/19] megaraid_sas: Move controller memory allocations and DMA mask settings from probe to megasas_init_fw

2017-10-19 Thread Shivasharan S
Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
---
 drivers/scsi/megaraid/megaraid_sas_base.c | 43 ---
 1 file changed, 28 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 86cceb48ba84..3a179c3fabc0 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -206,6 +206,18 @@ wait_and_poll(struct megasas_instance *instance, struct 
megasas_cmd *cmd,
 void megasas_fusion_ocr_wq(struct work_struct *work);
 static int megasas_get_ld_vf_affiliation(struct megasas_instance *instance,
 int initial);
+static int
+megasas_set_dma_mask(struct pci_dev *pdev);
+static int
+megasas_alloc_ctrl_mem(struct megasas_instance *instance);
+static inline void
+megasas_free_ctrl_mem(struct megasas_instance *instance);
+static inline int
+megasas_alloc_ctrl_dma_buffers(struct megasas_instance *instance);
+static inline void
+megasas_free_ctrl_dma_buffers(struct megasas_instance *instance);
+static inline void
+megasas_init_ctrl_params(struct megasas_instance *instance);
 
 void
 megasas_issue_dcmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
@@ -5179,6 +5191,19 @@ static int megasas_init_fw(struct megasas_instance 
*instance)
goto fail_ready_state;
}
 
+   megasas_init_ctrl_params(instance);
+
+   if (megasas_set_dma_mask(instance->pdev))
+   goto fail_ready_state;
+
+   if (megasas_alloc_ctrl_mem(instance))
+   goto fail_alloc_dma_buf;
+
+   if (megasas_alloc_ctrl_dma_buffers(instance))
+   goto fail_alloc_dma_buf;
+
+   fusion = instance->ctrl_context;
+
if (instance->adapter_type == VENTURA_SERIES) {
scratch_pad_3 =
readl(>reg_set->outbound_scratch_pad_3);
@@ -5475,6 +5500,9 @@ static int megasas_init_fw(struct megasas_instance 
*instance)
if (instance->msix_vectors)
pci_free_irq_vectors(instance->pdev);
instance->msix_vectors = 0;
+fail_alloc_dma_buf:
+   megasas_free_ctrl_dma_buffers(instance);
+   megasas_free_ctrl_mem(instance);
 fail_ready_state:
iounmap(instance->reg_set);
 
@@ -6318,9 +6346,6 @@ static int megasas_probe_one(struct pci_dev *pdev,
 
pci_set_master(pdev);
 
-   if (megasas_set_dma_mask(pdev))
-   goto fail_set_dma_mask;
-
host = scsi_host_alloc(_template,
   sizeof(struct megasas_instance));
 
@@ -6343,14 +6368,6 @@ static int megasas_probe_one(struct pci_dev *pdev,
 
megasas_set_adapter_type(instance);
 
-   megasas_init_ctrl_params(instance);
-
-   if (megasas_alloc_ctrl_mem(instance))
-   goto fail_alloc_dma_buf;
-
-   if (megasas_alloc_ctrl_dma_buffers(instance))
-   goto fail_alloc_dma_buf;
-
/*
 * Initialize MFI Firmware
 */
@@ -6432,13 +6449,9 @@ static int megasas_probe_one(struct pci_dev *pdev,
if (instance->msix_vectors)
pci_free_irq_vectors(instance->pdev);
 fail_init_mfi:
-fail_alloc_dma_buf:
-   megasas_free_ctrl_dma_buffers(instance);
-   megasas_free_ctrl_mem(instance);
scsi_host_put(host);
 
 fail_alloc_instance:
-fail_set_dma_mask:
pci_disable_device(pdev);
 
return -ENODEV;
-- 
2.14.1.dirty



[PATCH 13/19] megaraid_sas: Update current host time to FW during IOC Init

2017-10-19 Thread Shivasharan S
Driver needs to send current host time to firmware during init.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index a630a31aecf8..277fd16305ee 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -773,6 +773,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
MFI_CAPABILITIES *drv_ops;
u32 scratch_pad_2;
unsigned long flags;
+   struct timeval tv;
 
fusion = instance->ctrl_context;
 
@@ -821,6 +822,12 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
IOCInitMessage->SystemRequestFrameBaseAddress = 
cpu_to_le64(fusion->io_request_frames_phys);
IOCInitMessage->HostMSIxVectors = instance->msix_vectors;
IOCInitMessage->HostPageSize = MR_DEFAULT_NVME_PAGE_SHIFT;
+
+   do_gettimeofday();
+   /* Convert to milliseconds as per FW requirement */
+   IOCInitMessage->TimeStamp = cpu_to_le64((tv.tv_sec * 1000) +
+   (tv.tv_usec / 1000));
+
init_frame = (struct megasas_init_frame *)cmd->frame;
memset(init_frame, 0, MEGAMFI_FRAME_SIZE);
 
-- 
2.14.1.dirty



Re: [PATCH V8 5/5] libata: Align DMA buffer to dma_get_cache_alignment()

2017-10-19 Thread Matt Redfearn



On 18/10/17 14:03, Tejun Heo wrote:

On Tue, Oct 17, 2017 at 04:05:42PM +0800, Huacai Chen wrote:

In non-coherent DMA mode, kernel uses cache flushing operations to
maintain I/O coherency, so in ata_do_dev_read_id() the DMA buffer
should be aligned to ARCH_DMA_MINALIGN. Otherwise, If a DMA buffer
and a kernel structure share a same cache line, and if the kernel
structure has dirty data, cache_invalidate (no writeback) will cause
data corruption.

Cc: sta...@vger.kernel.org
Signed-off-by: Huacai Chen 
---
  drivers/ata/libata-core.c | 15 +--
  1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index ee4c1ec..e134955 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1833,8 +1833,19 @@ static u32 ata_pio_mask_no_iordy(const struct ata_device 
*adev)
  unsigned int ata_do_dev_read_id(struct ata_device *dev,
struct ata_taskfile *tf, u16 *id)
  {
-   return ata_exec_internal(dev, tf, NULL, DMA_FROM_DEVICE,
-id, sizeof(id[0]) * ATA_ID_WORDS, 0);
+   u16 *devid;
+   int res, size = sizeof(u16) * ATA_ID_WORDS;
+
+   if (IS_ALIGNED((unsigned long)id, dma_get_cache_alignment(>tdev)))
+   res = ata_exec_internal(dev, tf, NULL, DMA_FROM_DEVICE, id, 
size, 0);
+   else {
+   devid = kmalloc(size, GFP_KERNEL);
+   res = ata_exec_internal(dev, tf, NULL, DMA_FROM_DEVICE, devid, 
size, 0);
+   memcpy(id, devid, size);
+   kfree(devid);
+   }
+
+   return res;

Hmm... I think it'd be a lot better to ensure that the buffers are
aligned properly to begin with.  There are only two buffers which are
used for id reading - ata_port->sector_buf and ata_device->id.  Both
are embedded arrays but making them separately allocated aligned
buffers shouldn't be difficult.

Thanks.


FWIW, I agree that the buffers used for DMA should be split out from the 
structure. We ran into this problem on MIPS last year, 
4ee34ea3a12396f35b26d90a094c75db95080baa ("libata: Align ata_device's id 
on a cacheline") partially fixed it, but likely should have also 
cacheline aligned the following devslp_timing in the struct such that we 
guarantee that members of the struct not used for DMA do not share the 
same cacheline as the DMA buffer. Not having this means that 
architectures, such as MIPS, which in some cases have to perform manual 
invalidation of DMA buffer can clobber valid adjacent data if it is in 
the same cacheline.


Thanks,
Matt




Re: [PATCH] sd: Micro-optimize READ / WRITE CDB encoding

2017-10-19 Thread Douglas Gilbert

On 2017-10-17 06:41 PM, Bart Van Assche wrote:

On Tue, 2017-10-17 at 18:17 -0400, Douglas Gilbert wrote:

On 2017-10-17 05:03 PM, Bart Van Assche wrote:

@@ -1025,7 +1025,6 @@ static int sd_setup_read_write_cmnd(struct scsi_cmnd 
*SCpnt)
struct gendisk *disk = rq->rq_disk;
struct scsi_disk *sdkp = scsi_disk(disk);
sector_t block = blk_rq_pos(rq);


s/block/lba/# use the well understood SCSI abbreviation


Since blk_rq_pos() returns the offset in units of 512 bytes, how about renaming
'block' into 'sector' and using the name 'lba' for the number obtained after the
shift operation?




-   sector_t threshold;
unsigned int this_count = blk_rq_sectors(rq);
unsigned int dif, dix;
bool zoned_write = sd_is_zoned(sdkp) && rq_data_dir(rq) == WRITE;
@@ -1071,20 +1070,22 @@ static int sd_setup_read_write_cmnd(struct scsi_cmnd 
*SCpnt)
goto out;
}
   
-	/*

-* Some SD card readers can't handle multi-sector accesses which touch
-* the last one or two hardware sectors.  Split accesses as needed.
-*/
-   threshold = get_capacity(disk) - SD_LAST_BUGGY_SECTORS *
-   (sdp->sector_size / 512);
+   if (unlikely(sdp->last_sector_bug)) {
+   sector_t threshold;


s/threshold/threshold_lba/  # a bit long but more precise


A similar comment applies here - shouldn't this be called 'threshold_sector'?


}
}
if (rq_data_dir(rq) == WRITE) {
@@ -1173,56 +1157,26 @@ static int sd_setup_read_write_cmnd(struct scsi_cmnd 
*SCpnt)
SCpnt->cmnd[7] = 0x18;
SCpnt->cmnd[9] = (rq_data_dir(rq) == READ) ? READ_32 : WRITE_32;


Perhaps rq_data_dir(rq) could be placed in a local variable


I will keep that for a separate patch.


Bart,
Below is a rewrite of that function taking on board your ideas
and adding some of mine. It is inline in this post (but lines
are wrapped) and it is attached. It compiles.

The variable names are a little more descriptive (except
"last_lba" should be "first_lba_beyond_access") and more
state is cached in local variables (e.g. is_write).

Doug Gilbert


static int sd_setup_read_write_cmnd(struct scsi_cmnd *SCpnt)
{
struct request *rq = SCpnt->request;
struct scsi_device *sdp = SCpnt->device;
struct gendisk *disk = rq->rq_disk;
struct scsi_disk *sdkp = scsi_disk(disk);
unsigned int num_blks = blk_rq_sectors(rq);
unsigned int dif, dix;
unsigned int sect_sz;
sector_t lba = blk_rq_pos(rq);
sector_t threshold;
sector_t lu_capacity = get_capacity(disk);
sector_t last_lba = lba + num_blks;
bool is_write = (rq_data_dir(rq) == WRITE);
bool zoned_write = sd_is_zoned(sdkp) && is_write;
int ret;
unsigned char protect;

if (zoned_write) {
ret = sd_zbc_write_lock_zone(SCpnt);
if (ret != BLKPREP_OK)
return ret;
}

ret = scsi_init_io(SCpnt);
if (ret != BLKPREP_OK)
goto out;
SCpnt = rq->special;

/* from here on until we're complete, any goto out
 * is used for a killable error condition */
ret = BLKPREP_KILL;

SCSI_LOG_HLQUEUE(1,
scmd_printk(KERN_INFO, SCpnt,
"%s: lba=%llu, count=%d\n",
__func__, (unsigned long long)lba, num_blks));

if (likely(sdp && scsi_device_online(sdp) &&
   (last_lba <= lu_capacity)))
; /* ok: have device, its online and access fits on medium */
else {
SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt,
"Finishing %u sectors\n",
num_blks));
SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt,
"Retry with 0x%p\n", SCpnt));
goto out;
}
sect_sz = sdp->sector_size;

if (unlikely(sdp->changed)) {
/*
 * quietly refuse to do anything to a changed disc until
 * the changed bit has been reset
 */
/* printk("SCSI disk has been changed or is not present. 
Prohibiting further I/O.\n"); */

goto out;
}

/*
 * Some SD card readers can't handle multi-sector accesses which touch
 * the last one or two hardware sectors.  Split accesses as needed.
 */
if (unlikely(sdp->last_sector_bug)) {
threshold = lu_capacity -
(SD_LAST_BUGGY_SECTORS * (sect_sz / 512));

if (unlikely(last_lba > threshold))
num_blks = (lba < threshold) ? (threshold - lba) :
(sect_sz / 512);