Re: [PATCH 1/3] dt/bindings: arm-pl330: add description of arm,pl330-periph-burst

2016-08-21 Thread Vinod Koul
On Sun, Aug 21, 2016 at 09:00:58AM +0800, Shawn Lin wrote:
> Hi Vinod,
> 
> 在 2016/8/19 10:45, Vinod Koul 写道:
> >On Wed, Aug 17, 2016 at 04:11:03PM +0800, Shawn Lin wrote:
> >>Hi, Vinod and Lars-Peter
> >>
> >>Ping.. Any better idea to share :)
> >>
> >>On 2016/8/9 17:12, Shawn Lin wrote:
> >>>Hi Lars-Peter,
> >>>
> >>>在 2016/8/9 16:39, Lars-Peter Clausen 写道:
> On 08/05/2016 09:25 AM, Shawn Lin wrote:
> >Hi Vinod,
> >
> >在 2016/8/5 11:34, Vinod Koul 写道:
> >>On Fri, Aug 05, 2016 at 10:53:20AM +0800, Shawn Lin wrote:
> >>>This patch adds the "arm,pl330-periph-burst" for arm-pl330 to
> >>>support busrt mode.
> >>
> >>why should this be DT property. Only reason I can think of if some hw
> >>versions support this and some won't.
> >
> >yes, if we want to support burst mode, both of the master(pl330) and
> >client(several peripherals) should implement it, otherwise it will
> >be broken when enabling.
> 
> As you said, it is up to the consumer peripheral whether it supports
> BURST,
> SINGLE or both. So this is a per client property, but you specify this
> as a
> a global property on the producer side.
> >>>
> >>>Thanks for comment.
> >>>
> >>>yup, but what is the proper way to add it ? :)
> >>>
> >>>
> >>>a) If pl330 support BURST as well as all the peripherals, we could
> >>>enable it.
> >>>
> >>>b) If pl300 support BURST, but all the peripherals don't support it,
> >>>we could not enable it.
> >>>
> >>>c) If pl300 support BURST, but not all the peripherals support it,
> >>>we also could not enable it.
> >>>
> >>>the burst feature of peripheral IP may be vendor-specific, but the
> >>>common driver for this peripheral are used for many many vendors which
> >>>means we could not check all of this info. It's very likely to break
> >>>them... I couldn't figure out how many upstreamed peripheral drivers
> >>>who are using pl300 either.
> >>>
> >>>So this check should be done by all this vendors but we could make
> >>>sure we don't break them before they check a), b), c), right?
> >
> >Since support for BURST needs to be from peripheral too, we should have
> >that as a property for peripheral not for controller.
> >
> >The peripheral drivers can communicate the burst to be used to pl330
> >using src_maxburst/dst_maxburst in dma_slave_config. We can use this
> >value to indicate the DMA should be single (a value of 0) or burst with
> >"burst" value.
> 
> Thanks for sharing this.
> 
> But this is really a difficult trade-off decision to add this new
> property for pl330 only.
> 
> Burst mode was supported by Boojin Kim's patch by default(commit
> 848e9776fee42 ("dmaengine: pl330: support burst mode for dev-to-mem and
> mem-to-dev transmit")).  But we found it will break SoCFPGA or
> Exynos4412 reported by Dinh Nguyen and Bartlomiej Zolnierkiewicz[0].
> So finally Caesar Wang contributed a patch, commit 0a18f9b268 ("
> dmaengine: pl330: fix to support the burst mode") to fix it, but what
> it actually did is to use single burst for any case, namely some kind
> of regression for Boojin Kim's improvement.
> 
> So we can see these drivers which was broken by enabling burst mode
> had already set src_maxburst/dst_maxburst. It looks to me so unfortunate
> that the driver like 8250_dw.c was using so widely that we couldn't
> set scr/dst_maxburst as this is really vendor specific for whether it
> supports burst for 8250_dw or not..
> 
> So it is quite painful that we probably will get dozens of regression
> reports when enabling burst mode by default. But without this, we have
> been suffering from low performance quite a long time due to this
> roadblock.

well in that case I would suggest fixing client first. Make all users of
pl330 not to use burst mode and then enable them one by one after testing

> 
> Two possible paths to land this patch are:
> (1) Keep this property for pl330 only, so we have no chance to
> break others and we could make the platforms enjoy it if adding this
> property for their own dts.
> 
> (2) Figuer out all the broken platfroms if enabling burst and fix them
> one by one for the src/dst_maxburst(maybe by enabling burst mode and
> get regression reports). If we could not solve any one of them, then we
> have to give up all the effort we do, and let this pain keep on
> stalling people's expectation of better performance.
> 
> 
> I would appreciate it if you could share your thought more, as I
> really want more platforms benefit from it(at least don't break
> them)  :)
> 
> 
> [0] http://www.gossamer-threads.com/lists/linux/kernel/2374171
> 
> >
> 
> 
> -- 
> Best Regards
> Shawn Lin
> 

-- 
~Vinod


Re: [PATCH 1/3] dt/bindings: arm-pl330: add description of arm,pl330-periph-burst

2016-08-21 Thread Vinod Koul
On Sun, Aug 21, 2016 at 09:00:58AM +0800, Shawn Lin wrote:
> Hi Vinod,
> 
> 在 2016/8/19 10:45, Vinod Koul 写道:
> >On Wed, Aug 17, 2016 at 04:11:03PM +0800, Shawn Lin wrote:
> >>Hi, Vinod and Lars-Peter
> >>
> >>Ping.. Any better idea to share :)
> >>
> >>On 2016/8/9 17:12, Shawn Lin wrote:
> >>>Hi Lars-Peter,
> >>>
> >>>在 2016/8/9 16:39, Lars-Peter Clausen 写道:
> On 08/05/2016 09:25 AM, Shawn Lin wrote:
> >Hi Vinod,
> >
> >在 2016/8/5 11:34, Vinod Koul 写道:
> >>On Fri, Aug 05, 2016 at 10:53:20AM +0800, Shawn Lin wrote:
> >>>This patch adds the "arm,pl330-periph-burst" for arm-pl330 to
> >>>support busrt mode.
> >>
> >>why should this be DT property. Only reason I can think of if some hw
> >>versions support this and some won't.
> >
> >yes, if we want to support burst mode, both of the master(pl330) and
> >client(several peripherals) should implement it, otherwise it will
> >be broken when enabling.
> 
> As you said, it is up to the consumer peripheral whether it supports
> BURST,
> SINGLE or both. So this is a per client property, but you specify this
> as a
> a global property on the producer side.
> >>>
> >>>Thanks for comment.
> >>>
> >>>yup, but what is the proper way to add it ? :)
> >>>
> >>>
> >>>a) If pl330 support BURST as well as all the peripherals, we could
> >>>enable it.
> >>>
> >>>b) If pl300 support BURST, but all the peripherals don't support it,
> >>>we could not enable it.
> >>>
> >>>c) If pl300 support BURST, but not all the peripherals support it,
> >>>we also could not enable it.
> >>>
> >>>the burst feature of peripheral IP may be vendor-specific, but the
> >>>common driver for this peripheral are used for many many vendors which
> >>>means we could not check all of this info. It's very likely to break
> >>>them... I couldn't figure out how many upstreamed peripheral drivers
> >>>who are using pl300 either.
> >>>
> >>>So this check should be done by all this vendors but we could make
> >>>sure we don't break them before they check a), b), c), right?
> >
> >Since support for BURST needs to be from peripheral too, we should have
> >that as a property for peripheral not for controller.
> >
> >The peripheral drivers can communicate the burst to be used to pl330
> >using src_maxburst/dst_maxburst in dma_slave_config. We can use this
> >value to indicate the DMA should be single (a value of 0) or burst with
> >"burst" value.
> 
> Thanks for sharing this.
> 
> But this is really a difficult trade-off decision to add this new
> property for pl330 only.
> 
> Burst mode was supported by Boojin Kim's patch by default(commit
> 848e9776fee42 ("dmaengine: pl330: support burst mode for dev-to-mem and
> mem-to-dev transmit")).  But we found it will break SoCFPGA or
> Exynos4412 reported by Dinh Nguyen and Bartlomiej Zolnierkiewicz[0].
> So finally Caesar Wang contributed a patch, commit 0a18f9b268 ("
> dmaengine: pl330: fix to support the burst mode") to fix it, but what
> it actually did is to use single burst for any case, namely some kind
> of regression for Boojin Kim's improvement.
> 
> So we can see these drivers which was broken by enabling burst mode
> had already set src_maxburst/dst_maxburst. It looks to me so unfortunate
> that the driver like 8250_dw.c was using so widely that we couldn't
> set scr/dst_maxburst as this is really vendor specific for whether it
> supports burst for 8250_dw or not..
> 
> So it is quite painful that we probably will get dozens of regression
> reports when enabling burst mode by default. But without this, we have
> been suffering from low performance quite a long time due to this
> roadblock.

well in that case I would suggest fixing client first. Make all users of
pl330 not to use burst mode and then enable them one by one after testing

> 
> Two possible paths to land this patch are:
> (1) Keep this property for pl330 only, so we have no chance to
> break others and we could make the platforms enjoy it if adding this
> property for their own dts.
> 
> (2) Figuer out all the broken platfroms if enabling burst and fix them
> one by one for the src/dst_maxburst(maybe by enabling burst mode and
> get regression reports). If we could not solve any one of them, then we
> have to give up all the effort we do, and let this pain keep on
> stalling people's expectation of better performance.
> 
> 
> I would appreciate it if you could share your thought more, as I
> really want more platforms benefit from it(at least don't break
> them)  :)
> 
> 
> [0] http://www.gossamer-threads.com/lists/linux/kernel/2374171
> 
> >
> 
> 
> -- 
> Best Regards
> Shawn Lin
> 

-- 
~Vinod


Re: [PATCH 3.10 098/180] wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel

2016-08-21 Thread Willy Tarreau
On Mon, Aug 22, 2016 at 07:35:18AM +0200, Johannes Berg wrote:
> On Sun, 2016-08-21 at 15:30 +, Willy Tarreau wrote:
> > From: Prasun Maiti 
> > 
> > commit 3d5fdff46c4b2b9534fa2f9fc78e90a48e0ff724 upstream.
> > 
> > iwpriv app uses iw_point structure to send data to Kernel. The
> > iw_point structure holds a pointer.
> 
> Ben Hutchings pointed out that while the commit actually is a bugfix,
> and I thought it was important, it actually breaks other things and
> isn't important since nothing uses this.
> 
> I've reverted it and you should just drop it.

OK now dropped, thanks Johannes.

Willy


Re: [PATCH 3.10 098/180] wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel

2016-08-21 Thread Willy Tarreau
On Mon, Aug 22, 2016 at 07:35:18AM +0200, Johannes Berg wrote:
> On Sun, 2016-08-21 at 15:30 +, Willy Tarreau wrote:
> > From: Prasun Maiti 
> > 
> > commit 3d5fdff46c4b2b9534fa2f9fc78e90a48e0ff724 upstream.
> > 
> > iwpriv app uses iw_point structure to send data to Kernel. The
> > iw_point structure holds a pointer.
> 
> Ben Hutchings pointed out that while the commit actually is a bugfix,
> and I thought it was important, it actually breaks other things and
> isn't important since nothing uses this.
> 
> I've reverted it and you should just drop it.

OK now dropped, thanks Johannes.

Willy


Re: [PATCH] usb: chipidea: support generic phy in PM code path

2016-08-21 Thread Peter Chen
On Fri, Aug 19, 2016 at 08:10:13PM +0800, Jisheng Zhang wrote:
> Support generic phy in PM code path: call phy_power_off/phy_power_on
> in ci_controller_suspend/ci_controller_resume.
> 
> Signed-off-by: Jisheng Zhang 
> ---
>  drivers/usb/chipidea/core.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> index ae12595..ef9fb0b 100644
> --- a/drivers/usb/chipidea/core.c
> +++ b/drivers/usb/chipidea/core.c
> @@ -1116,6 +1116,7 @@ static void ci_controller_suspend(struct ci_hdrc *ci)
>   usleep_range(ci->platdata->phy_clkgate_delay_us,
>ci->platdata->phy_clkgate_delay_us + 50);
>   usb_phy_set_suspend(ci->usb_phy, 1);
> + phy_power_off(ci->phy);

How could you support USB wakeup after PHY is powered off?

Peter

>   ci->in_lpm = true;
>   enable_irq(ci->irq);
>  }
> @@ -1132,9 +1133,10 @@ static int ci_controller_resume(struct device *dev)
>   }
>  
>   ci_hdrc_enter_lpm(ci, false);
> - if (ci->usb_phy) {
> + if (ci->usb_phy || ci->phy) {
>   usb_phy_set_suspend(ci->usb_phy, 0);
>   usb_phy_set_wakeup(ci->usb_phy, false);
> + phy_power_on(ci->phy);
>   hw_wait_phy_stable();
>   }
>  
> -- 
> 2.9.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Best Regards,
Peter Chen


Re: [PATCH] usb: chipidea: support generic phy in PM code path

2016-08-21 Thread Peter Chen
On Fri, Aug 19, 2016 at 08:10:13PM +0800, Jisheng Zhang wrote:
> Support generic phy in PM code path: call phy_power_off/phy_power_on
> in ci_controller_suspend/ci_controller_resume.
> 
> Signed-off-by: Jisheng Zhang 
> ---
>  drivers/usb/chipidea/core.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> index ae12595..ef9fb0b 100644
> --- a/drivers/usb/chipidea/core.c
> +++ b/drivers/usb/chipidea/core.c
> @@ -1116,6 +1116,7 @@ static void ci_controller_suspend(struct ci_hdrc *ci)
>   usleep_range(ci->platdata->phy_clkgate_delay_us,
>ci->platdata->phy_clkgate_delay_us + 50);
>   usb_phy_set_suspend(ci->usb_phy, 1);
> + phy_power_off(ci->phy);

How could you support USB wakeup after PHY is powered off?

Peter

>   ci->in_lpm = true;
>   enable_irq(ci->irq);
>  }
> @@ -1132,9 +1133,10 @@ static int ci_controller_resume(struct device *dev)
>   }
>  
>   ci_hdrc_enter_lpm(ci, false);
> - if (ci->usb_phy) {
> + if (ci->usb_phy || ci->phy) {
>   usb_phy_set_suspend(ci->usb_phy, 0);
>   usb_phy_set_wakeup(ci->usb_phy, false);
> + phy_power_on(ci->phy);
>   hw_wait_phy_stable();
>   }
>  
> -- 
> 2.9.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Best Regards,
Peter Chen


Re: [PATCH 3.10 098/180] wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel

2016-08-21 Thread Johannes Berg
On Sun, 2016-08-21 at 15:30 +, Willy Tarreau wrote:
> From: Prasun Maiti 
> 
> commit 3d5fdff46c4b2b9534fa2f9fc78e90a48e0ff724 upstream.
> 
> iwpriv app uses iw_point structure to send data to Kernel. The
> iw_point structure holds a pointer.

Ben Hutchings pointed out that while the commit actually is a bugfix,
and I thought it was important, it actually breaks other things and
isn't important since nothing uses this.

I've reverted it and you should just drop it.

johannes


Re: [PATCH 3.10 098/180] wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel

2016-08-21 Thread Johannes Berg
On Sun, 2016-08-21 at 15:30 +, Willy Tarreau wrote:
> From: Prasun Maiti 
> 
> commit 3d5fdff46c4b2b9534fa2f9fc78e90a48e0ff724 upstream.
> 
> iwpriv app uses iw_point structure to send data to Kernel. The
> iw_point structure holds a pointer.

Ben Hutchings pointed out that while the commit actually is a bugfix,
and I thought it was important, it actually breaks other things and
isn't important since nothing uses this.

I've reverted it and you should just drop it.

johannes


Re: [PATCH 3.10 090/180] xfs: xfs_iflush_cluster fails to abort on error

2016-08-21 Thread Willy Tarreau
On Mon, Aug 22, 2016 at 07:18:26AM +0200, Willy Tarreau wrote:
> > Seriously, guys, pick up your act a bit and start talking between
> > yourselvesi and tracking regressions and fixes so the burden of
> > catching known reported and fixed problems with backports doesn't
> > rely on the upstream developers noticing the problem when hundreds
> > of patches for random stable kernels go past on lkml every week...
> 
> We definitely do exchange quite a bit and I pick patches from 3.14 for
> 3.10, but sometimes I can simply pick the original one for various
> reasons (eg: I if had queued its upstream ID earlier). That's also why
> the review process helps. I'm sincerely sorry that I failed on this one
> and that you had to deal with it again, I'm going to fix it now.

I've just checked, and this time I correctly picked the patches from
3.14, so much that I have the faulty one (this one) and its fix (patch
100/180). Admittedly I can merge them together so that if someone wants
to pick it alone they're not left with a broken patch.

Willy



Re: [PATCH 2/2] tun: Rename a jump label in update_filter()

2016-08-21 Thread Mike Rapoport
On Mon, Aug 22, 2016 at 04:41:11AM +0300, Michael S. Tsirkin wrote:
> On Sat, Aug 20, 2016 at 09:37:16AM +0200, SF Markus Elfring wrote:
> > From: Markus Elfring 
> > Date: Sat, 20 Aug 2016 09:00:34 +0200
> > 
> > Adjust a jump target according to the Linux coding style convention.
> > 
> > Signed-off-by: Markus Elfring 
> 
> I don't have an opinion of this one. Which convention do you refer to?

Citing Documentation/CodingStyle:

Choose label names which say what the goto does or why the goto exists.  An
example of a good name could be "out_buffer:" if the goto frees "buffer".
Avoid using GW-BASIC names like "err1:" and "err2:".  Also don't name them after
the goto location like "err_kmalloc_failed:"

> 
> > ---
> >  drivers/net/tun.c | 5 ++---
> >  1 file changed, 2 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/net/tun.c b/drivers/net/tun.c
> > index a1aeccb..e249428 100644
> > --- a/drivers/net/tun.c
> > +++ b/drivers/net/tun.c
> > @@ -753,7 +753,7 @@ static int update_filter(struct tap_filter *filter, 
> > void __user *arg)
> > for (; n < uf.count; n++) {
> > if (!is_multicast_ether_addr(addr[n].u)) {
> > err = 0; /* no filter */
> > -   goto done;
> > +   goto free_addr;
> > }
> > addr_hash_set(filter->mask, addr[n].u);
> > }
> > @@ -769,8 +769,7 @@ static int update_filter(struct tap_filter *filter, 
> > void __user *arg)
> >  
> > /* Return the number of exact filters */
> > err = nexact;
> > -
> > -done:
> > +free_addr:
> > kfree(addr);
> > return err;
> >  }
> > -- 
> > 2.9.3
> 



Re: [PATCH 3.10 090/180] xfs: xfs_iflush_cluster fails to abort on error

2016-08-21 Thread Willy Tarreau
On Mon, Aug 22, 2016 at 07:18:26AM +0200, Willy Tarreau wrote:
> > Seriously, guys, pick up your act a bit and start talking between
> > yourselvesi and tracking regressions and fixes so the burden of
> > catching known reported and fixed problems with backports doesn't
> > rely on the upstream developers noticing the problem when hundreds
> > of patches for random stable kernels go past on lkml every week...
> 
> We definitely do exchange quite a bit and I pick patches from 3.14 for
> 3.10, but sometimes I can simply pick the original one for various
> reasons (eg: I if had queued its upstream ID earlier). That's also why
> the review process helps. I'm sincerely sorry that I failed on this one
> and that you had to deal with it again, I'm going to fix it now.

I've just checked, and this time I correctly picked the patches from
3.14, so much that I have the faulty one (this one) and its fix (patch
100/180). Admittedly I can merge them together so that if someone wants
to pick it alone they're not left with a broken patch.

Willy



Re: [PATCH 2/2] tun: Rename a jump label in update_filter()

2016-08-21 Thread Mike Rapoport
On Mon, Aug 22, 2016 at 04:41:11AM +0300, Michael S. Tsirkin wrote:
> On Sat, Aug 20, 2016 at 09:37:16AM +0200, SF Markus Elfring wrote:
> > From: Markus Elfring 
> > Date: Sat, 20 Aug 2016 09:00:34 +0200
> > 
> > Adjust a jump target according to the Linux coding style convention.
> > 
> > Signed-off-by: Markus Elfring 
> 
> I don't have an opinion of this one. Which convention do you refer to?

Citing Documentation/CodingStyle:

Choose label names which say what the goto does or why the goto exists.  An
example of a good name could be "out_buffer:" if the goto frees "buffer".
Avoid using GW-BASIC names like "err1:" and "err2:".  Also don't name them after
the goto location like "err_kmalloc_failed:"

> 
> > ---
> >  drivers/net/tun.c | 5 ++---
> >  1 file changed, 2 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/net/tun.c b/drivers/net/tun.c
> > index a1aeccb..e249428 100644
> > --- a/drivers/net/tun.c
> > +++ b/drivers/net/tun.c
> > @@ -753,7 +753,7 @@ static int update_filter(struct tap_filter *filter, 
> > void __user *arg)
> > for (; n < uf.count; n++) {
> > if (!is_multicast_ether_addr(addr[n].u)) {
> > err = 0; /* no filter */
> > -   goto done;
> > +   goto free_addr;
> > }
> > addr_hash_set(filter->mask, addr[n].u);
> > }
> > @@ -769,8 +769,7 @@ static int update_filter(struct tap_filter *filter, 
> > void __user *arg)
> >  
> > /* Return the number of exact filters */
> > err = nexact;
> > -
> > -done:
> > +free_addr:
> > kfree(addr);
> > return err;
> >  }
> > -- 
> > 2.9.3
> 



Re: [PATCH 2/2] Migrate zone cache from RB-Tree to arrays of descriptors

2016-08-21 Thread Shaun Tancheff
On Sun, Aug 21, 2016 at 11:34 PM, Shaun Tancheff  wrote:
> Currently the RB-Tree zone cache is fast and flexible. It does
> use a rather largish amount of ram. This model reduces the ram
> required from 120 bytes per zone to 16 bytes per zone with a
> moderate transformation of the blk_zone_lookup() api.
>
> This model is predicated on the belief that most variations
> on zoned media will follow a pattern of using collections of same
> sized zones on a single device. Similar to the pattern of erase
> blocks on flash devices being progressivly larger 16K, 64K, ...
>
> The goal is to be able to build a descriptor which is both memory
> efficient, performant, and flexible.
>
> Signed-off-by: Shaun Tancheff 
> ---
>  block/blk-core.c   |2 +-
>  block/blk-sysfs.c  |   31 +-
>  block/blk-zoned.c  |  103 +++--
>  drivers/scsi/sd.c  |5 +-
>  drivers/scsi/sd.h  |4 +-
>  drivers/scsi/sd_zbc.c  | 1025 
> +++-
>  include/linux/blkdev.h |   82 +++-
>  7 files changed, 716 insertions(+), 536 deletions(-)
>
> diff --git a/block/blk-core.c b/block/blk-core.c
> index 3a9caf7..3b084a8 100644
> --- a/block/blk-core.c
> +++ b/block/blk-core.c
> @@ -727,7 +727,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t 
> gfp_mask, int node_id)
> INIT_LIST_HEAD(>blkg_list);
>  #endif
>  #ifdef CONFIG_BLK_DEV_ZONED
> -   q->zones = RB_ROOT;
> +   q->zones = NULL;
>  #endif
> INIT_DELAYED_WORK(>delay_work, blk_delay_work);
>
> diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
> index 43f441f..ecbd434 100644
> --- a/block/blk-sysfs.c
> +++ b/block/blk-sysfs.c
> @@ -232,36 +232,7 @@ static ssize_t queue_max_hw_sectors_show(struct 
> request_queue *q, char *page)
>  #ifdef CONFIG_BLK_DEV_ZONED
>  static ssize_t queue_zoned_show(struct request_queue *q, char *page)
>  {
> -   struct rb_node *node;
> -   struct blk_zone *zone;
> -   ssize_t offset = 0, end = 0;
> -   size_t size = 0, num = 0;
> -   enum blk_zone_type type = BLK_ZONE_TYPE_UNKNOWN;
> -
> -   for (node = rb_first(>zones); node; node = rb_next(node)) {
> -   zone = rb_entry(node, struct blk_zone, node);
> -   if (zone->type != type ||
> -   zone->len != size ||
> -   end != zone->start) {
> -   if (size != 0)
> -   offset += sprintf(page + offset, "%zu\n", 
> num);
> -   /* We can only store one page ... */
> -   if (offset + 42 > PAGE_SIZE) {
> -   offset += sprintf(page + offset, "...\n");
> -   return offset;
> -   }
> -   size = zone->len;
> -   type = zone->type;
> -   offset += sprintf(page + offset, "%zu %zu %d ",
> - zone->start, size, type);
> -   num = 0;
> -   end = zone->start + size;
> -   } else
> -   end += zone->len;
> -   num++;
> -   }
> -   offset += sprintf(page + offset, "%zu\n", num);
> -   return offset;
> +   return sprintf(page, "%u\n", q->zones ? 1 : 0);
>  }
>  #endif
>
> diff --git a/block/blk-zoned.c b/block/blk-zoned.c
> index 975e863..338a1af 100644
> --- a/block/blk-zoned.c
> +++ b/block/blk-zoned.c
> @@ -8,63 +8,84 @@
>  #include 
>  #include 
>  #include 
> -#include 
> +#include 
>
> -struct blk_zone *blk_lookup_zone(struct request_queue *q, sector_t lba)
> +/**
> + * blk_lookup_zone() - Lookup zones
> + * @q: Request Queue
> + * @sector: Location to lookup
> + * @start: Pointer to starting location zone (OUT)
> + * @len: Pointer to length of zone (OUT)
> + * @lock: Pointer to spinlock of zones in owning descriptor (OUT)
> + */
> +struct blk_zone *blk_lookup_zone(struct request_queue *q, sector_t sector,
> +sector_t *start, sector_t *len,
> +spinlock_t **lock)
>  {
> -   struct rb_root *root = >zones;
> -   struct rb_node *node = root->rb_node;
> +   int iter;
> +   struct blk_zone *bzone = NULL;
> +   struct zone_wps *zi = q->zones;
> +
> +   *start = 0;
> +   *len = 0;
> +   *lock = NULL;
> +
> +   if (!q->zones)
> +   goto out;
>
> -   while (node) {
> -   struct blk_zone *zone = container_of(node, struct blk_zone,
> -node);
> +   for (iter = 0; iter < zi->wps_count; iter++) {
> +   if (sector >= zi->wps[iter]->start_lba &&
> +   sector <  zi->wps[iter]->last_lba) {
> +   struct contiguous_wps *wp = zi->wps[iter];
> +   u64 index = (sector - wp->start_lba) / wp->zone_size;
>
> -   if (lba < 

Re: [PATCH 2/2] Migrate zone cache from RB-Tree to arrays of descriptors

2016-08-21 Thread Shaun Tancheff
On Sun, Aug 21, 2016 at 11:34 PM, Shaun Tancheff  wrote:
> Currently the RB-Tree zone cache is fast and flexible. It does
> use a rather largish amount of ram. This model reduces the ram
> required from 120 bytes per zone to 16 bytes per zone with a
> moderate transformation of the blk_zone_lookup() api.
>
> This model is predicated on the belief that most variations
> on zoned media will follow a pattern of using collections of same
> sized zones on a single device. Similar to the pattern of erase
> blocks on flash devices being progressivly larger 16K, 64K, ...
>
> The goal is to be able to build a descriptor which is both memory
> efficient, performant, and flexible.
>
> Signed-off-by: Shaun Tancheff 
> ---
>  block/blk-core.c   |2 +-
>  block/blk-sysfs.c  |   31 +-
>  block/blk-zoned.c  |  103 +++--
>  drivers/scsi/sd.c  |5 +-
>  drivers/scsi/sd.h  |4 +-
>  drivers/scsi/sd_zbc.c  | 1025 
> +++-
>  include/linux/blkdev.h |   82 +++-
>  7 files changed, 716 insertions(+), 536 deletions(-)
>
> diff --git a/block/blk-core.c b/block/blk-core.c
> index 3a9caf7..3b084a8 100644
> --- a/block/blk-core.c
> +++ b/block/blk-core.c
> @@ -727,7 +727,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t 
> gfp_mask, int node_id)
> INIT_LIST_HEAD(>blkg_list);
>  #endif
>  #ifdef CONFIG_BLK_DEV_ZONED
> -   q->zones = RB_ROOT;
> +   q->zones = NULL;
>  #endif
> INIT_DELAYED_WORK(>delay_work, blk_delay_work);
>
> diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
> index 43f441f..ecbd434 100644
> --- a/block/blk-sysfs.c
> +++ b/block/blk-sysfs.c
> @@ -232,36 +232,7 @@ static ssize_t queue_max_hw_sectors_show(struct 
> request_queue *q, char *page)
>  #ifdef CONFIG_BLK_DEV_ZONED
>  static ssize_t queue_zoned_show(struct request_queue *q, char *page)
>  {
> -   struct rb_node *node;
> -   struct blk_zone *zone;
> -   ssize_t offset = 0, end = 0;
> -   size_t size = 0, num = 0;
> -   enum blk_zone_type type = BLK_ZONE_TYPE_UNKNOWN;
> -
> -   for (node = rb_first(>zones); node; node = rb_next(node)) {
> -   zone = rb_entry(node, struct blk_zone, node);
> -   if (zone->type != type ||
> -   zone->len != size ||
> -   end != zone->start) {
> -   if (size != 0)
> -   offset += sprintf(page + offset, "%zu\n", 
> num);
> -   /* We can only store one page ... */
> -   if (offset + 42 > PAGE_SIZE) {
> -   offset += sprintf(page + offset, "...\n");
> -   return offset;
> -   }
> -   size = zone->len;
> -   type = zone->type;
> -   offset += sprintf(page + offset, "%zu %zu %d ",
> - zone->start, size, type);
> -   num = 0;
> -   end = zone->start + size;
> -   } else
> -   end += zone->len;
> -   num++;
> -   }
> -   offset += sprintf(page + offset, "%zu\n", num);
> -   return offset;
> +   return sprintf(page, "%u\n", q->zones ? 1 : 0);
>  }
>  #endif
>
> diff --git a/block/blk-zoned.c b/block/blk-zoned.c
> index 975e863..338a1af 100644
> --- a/block/blk-zoned.c
> +++ b/block/blk-zoned.c
> @@ -8,63 +8,84 @@
>  #include 
>  #include 
>  #include 
> -#include 
> +#include 
>
> -struct blk_zone *blk_lookup_zone(struct request_queue *q, sector_t lba)
> +/**
> + * blk_lookup_zone() - Lookup zones
> + * @q: Request Queue
> + * @sector: Location to lookup
> + * @start: Pointer to starting location zone (OUT)
> + * @len: Pointer to length of zone (OUT)
> + * @lock: Pointer to spinlock of zones in owning descriptor (OUT)
> + */
> +struct blk_zone *blk_lookup_zone(struct request_queue *q, sector_t sector,
> +sector_t *start, sector_t *len,
> +spinlock_t **lock)
>  {
> -   struct rb_root *root = >zones;
> -   struct rb_node *node = root->rb_node;
> +   int iter;
> +   struct blk_zone *bzone = NULL;
> +   struct zone_wps *zi = q->zones;
> +
> +   *start = 0;
> +   *len = 0;
> +   *lock = NULL;
> +
> +   if (!q->zones)
> +   goto out;
>
> -   while (node) {
> -   struct blk_zone *zone = container_of(node, struct blk_zone,
> -node);
> +   for (iter = 0; iter < zi->wps_count; iter++) {
> +   if (sector >= zi->wps[iter]->start_lba &&
> +   sector <  zi->wps[iter]->last_lba) {
> +   struct contiguous_wps *wp = zi->wps[iter];
> +   u64 index = (sector - wp->start_lba) / wp->zone_size;
>
> -   if (lba < zone->start)
> -   node = 

RE: [PATCH 3/3] drivers: Add visorbus to the drivers/virt directory

2016-08-21 Thread Sell, Timothy C
> -Original Message-
> From: Greg KH [mailto:gre...@linuxfoundation.org]
> Sent: Sunday, August 21, 2016 2:05 PM
> To: Kershner, David A 
> Cc: cor...@lwn.net; t...@linutronix.de; mi...@redhat.com;
> h...@zytor.com; Arfvidson, Erik ; Sell, Timothy
> C ; hof...@osadl.org; dzic...@redhat.com;
> jes.soren...@redhat.com; Curtin, Alexander Paul
> ; janani.rvchn...@gmail.com;
> sudipm.mukher...@gmail.com; pra...@redhat.com; Binder, David Anthony
> ; nhor...@redhat.com;
> dan.j.willi...@intel.com; linux-kernel@vger.kernel.org; linux-
> d...@vger.kernel.org; driverdev-de...@linuxdriverproject.org; *S-Par-
> Maintainer 
> Subject: Re: [PATCH 3/3] drivers: Add visorbus to the drivers/virt directory
> 
> On Fri, Jun 10, 2016 at 11:23:56PM -0400, David Kershner wrote:
> > visorbus is currently located at drivers/staging/visorbus,
> > this patch moves it to drivers/virt.
> >
> > Signed-off-by: David Kershner 
> > Reviewed-by: Tim Sell 
> > ---
> >  drivers/staging/unisys/Kconfig| 3 
> > +--
> >  drivers/staging/unisys/Makefile   | 1 -
> >  drivers/virt/Kconfig  | 2 
> > ++
> >  drivers/virt/Makefile | 1 +
> >  drivers/{staging/unisys => virt}/visorbus/Kconfig | 0
> >  drivers/{staging/unisys => virt}/visorbus/Makefile| 0
> >  drivers/{staging/unisys => virt}/visorbus/controlvmchannel.h  | 0
> >  drivers/{staging/unisys => virt}/visorbus/controlvmcompletionstatus.h | 0
> >  drivers/{staging/unisys => virt}/visorbus/iovmcall_gnuc.h | 0
> >  drivers/{staging/unisys => virt}/visorbus/vbuschannel.h   | 0
> >  drivers/{staging/unisys => virt}/visorbus/vbusdeviceinfo.h| 0
> >  drivers/{staging/unisys => virt}/visorbus/vbushelper.h| 0
> >  drivers/{staging/unisys => virt}/visorbus/visorbus_main.c | 0
> >  drivers/{staging/unisys => virt}/visorbus/visorbus_private.h  | 0
> >  drivers/{staging/unisys => virt}/visorbus/visorchannel.c  | 0
> >  drivers/{staging/unisys => virt}/visorbus/visorchipset.c  | 0
> 
> I picked one random file here, this last one, and found a number of
> "odd" things in it.
> 
> So, given that I can't really comment on the patch itself, I'm going to
> include the file below, quote it, and then provide some comments, ok?
> > /* visorchipset_main.c
> > ...
> > static void
> > controlvm_init_response(struct controlvm_message *msg,
> > struct controlvm_message_header *msg_hdr, int response)
> > {
> > memset(msg, 0, sizeof(struct controlvm_message));
> > memcpy(>hdr, msg_hdr, sizeof(struct controlvm_message_header));
> > msg->hdr.payload_bytes = 0;
> > msg->hdr.payload_vm_offset = 0;
> > msg->hdr.payload_max_bytes = 0;
> > if (response < 0) {
> > msg->hdr.flags.failed = 1;
> > msg->hdr.completion_status = (u32)(-response);
> > }
> > }
> > 
> > static void
> > Billy(struct controlvm_message_header *msg_hdr, int response)
> 
> Not John?  Bob?  Sally?  Alice?  Bernise?  Jean?  Molly?

Huh? What version of source code are you looking at??

The file being moved by this patch should be
drivers/staging/unisys/visorbus/visorchipset.c in your staging-next branch  
(https://git.kernel.org/cgit/linux/kernel/git/gregkh/staging.git/tree/drivers/staging/unisys/visorbus/visorchipset.c?h=staging-next).
If you look there, you will NOT find "Billy()", but instead 
"controlvm_respond()", i.e.:

static void
controlvm_init_response(struct controlvm_message *msg,
struct controlvm_message_header *msg_hdr, int response)
{
memset(msg, 0, sizeof(struct controlvm_message));
memcpy(>hdr, msg_hdr, sizeof(struct controlvm_message_header));
msg->hdr.payload_bytes = 0;
msg->hdr.payload_vm_offset = 0;
msg->hdr.payload_max_bytes = 0;
if (response < 0) {
msg->hdr.flags.failed = 1;
msg->hdr.completion_status = (u32)(-response);
}
}

static void
controlvm_respond(struct controlvm_message_header *msg_hdr, int response)
{
struct controlvm_message outmsg;

controlvm_init_response(, msg_hdr, response);
if (outmsg.hdr.flags.test_message == 1)
return;

if (!visorchannel_signalinsert(controlvm_channel,
   CONTROLVM_QUEUE_REQUEST, )) {
return;
}
}

One (or both) of us is confused.

Tim Sell



RE: [PATCH 3/3] drivers: Add visorbus to the drivers/virt directory

2016-08-21 Thread Sell, Timothy C
> -Original Message-
> From: Greg KH [mailto:gre...@linuxfoundation.org]
> Sent: Sunday, August 21, 2016 2:05 PM
> To: Kershner, David A 
> Cc: cor...@lwn.net; t...@linutronix.de; mi...@redhat.com;
> h...@zytor.com; Arfvidson, Erik ; Sell, Timothy
> C ; hof...@osadl.org; dzic...@redhat.com;
> jes.soren...@redhat.com; Curtin, Alexander Paul
> ; janani.rvchn...@gmail.com;
> sudipm.mukher...@gmail.com; pra...@redhat.com; Binder, David Anthony
> ; nhor...@redhat.com;
> dan.j.willi...@intel.com; linux-kernel@vger.kernel.org; linux-
> d...@vger.kernel.org; driverdev-de...@linuxdriverproject.org; *S-Par-
> Maintainer 
> Subject: Re: [PATCH 3/3] drivers: Add visorbus to the drivers/virt directory
> 
> On Fri, Jun 10, 2016 at 11:23:56PM -0400, David Kershner wrote:
> > visorbus is currently located at drivers/staging/visorbus,
> > this patch moves it to drivers/virt.
> >
> > Signed-off-by: David Kershner 
> > Reviewed-by: Tim Sell 
> > ---
> >  drivers/staging/unisys/Kconfig| 3 
> > +--
> >  drivers/staging/unisys/Makefile   | 1 -
> >  drivers/virt/Kconfig  | 2 
> > ++
> >  drivers/virt/Makefile | 1 +
> >  drivers/{staging/unisys => virt}/visorbus/Kconfig | 0
> >  drivers/{staging/unisys => virt}/visorbus/Makefile| 0
> >  drivers/{staging/unisys => virt}/visorbus/controlvmchannel.h  | 0
> >  drivers/{staging/unisys => virt}/visorbus/controlvmcompletionstatus.h | 0
> >  drivers/{staging/unisys => virt}/visorbus/iovmcall_gnuc.h | 0
> >  drivers/{staging/unisys => virt}/visorbus/vbuschannel.h   | 0
> >  drivers/{staging/unisys => virt}/visorbus/vbusdeviceinfo.h| 0
> >  drivers/{staging/unisys => virt}/visorbus/vbushelper.h| 0
> >  drivers/{staging/unisys => virt}/visorbus/visorbus_main.c | 0
> >  drivers/{staging/unisys => virt}/visorbus/visorbus_private.h  | 0
> >  drivers/{staging/unisys => virt}/visorbus/visorchannel.c  | 0
> >  drivers/{staging/unisys => virt}/visorbus/visorchipset.c  | 0
> 
> I picked one random file here, this last one, and found a number of
> "odd" things in it.
> 
> So, given that I can't really comment on the patch itself, I'm going to
> include the file below, quote it, and then provide some comments, ok?
> > /* visorchipset_main.c
> > ...
> > static void
> > controlvm_init_response(struct controlvm_message *msg,
> > struct controlvm_message_header *msg_hdr, int response)
> > {
> > memset(msg, 0, sizeof(struct controlvm_message));
> > memcpy(>hdr, msg_hdr, sizeof(struct controlvm_message_header));
> > msg->hdr.payload_bytes = 0;
> > msg->hdr.payload_vm_offset = 0;
> > msg->hdr.payload_max_bytes = 0;
> > if (response < 0) {
> > msg->hdr.flags.failed = 1;
> > msg->hdr.completion_status = (u32)(-response);
> > }
> > }
> > 
> > static void
> > Billy(struct controlvm_message_header *msg_hdr, int response)
> 
> Not John?  Bob?  Sally?  Alice?  Bernise?  Jean?  Molly?

Huh? What version of source code are you looking at??

The file being moved by this patch should be
drivers/staging/unisys/visorbus/visorchipset.c in your staging-next branch  
(https://git.kernel.org/cgit/linux/kernel/git/gregkh/staging.git/tree/drivers/staging/unisys/visorbus/visorchipset.c?h=staging-next).
If you look there, you will NOT find "Billy()", but instead 
"controlvm_respond()", i.e.:

static void
controlvm_init_response(struct controlvm_message *msg,
struct controlvm_message_header *msg_hdr, int response)
{
memset(msg, 0, sizeof(struct controlvm_message));
memcpy(>hdr, msg_hdr, sizeof(struct controlvm_message_header));
msg->hdr.payload_bytes = 0;
msg->hdr.payload_vm_offset = 0;
msg->hdr.payload_max_bytes = 0;
if (response < 0) {
msg->hdr.flags.failed = 1;
msg->hdr.completion_status = (u32)(-response);
}
}

static void
controlvm_respond(struct controlvm_message_header *msg_hdr, int response)
{
struct controlvm_message outmsg;

controlvm_init_response(, msg_hdr, response);
if (outmsg.hdr.flags.test_message == 1)
return;

if (!visorchannel_signalinsert(controlvm_channel,
   CONTROLVM_QUEUE_REQUEST, )) {
return;
}
}

One (or both) of us is confused.

Tim Sell



linux-next: Tree for Aug 22

2016-08-21 Thread Stephen Rothwell
Hi all,

Changes since 20160819:

The samsung-krzk tree gained a conflict against the imx-mxs tree.

The net-next tree gained a conflict against the net tree.

The kbuild tree still had its build warnings for PowerPC, for which I
reverted a commit.

Non-merge commits (relative to Linus' tree): 2676
 2870 files changed, 125212 insertions(+), 46601 deletions(-)



I have created today's linux-next tree at
git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
(patches at http://www.kernel.org/pub/linux/kernel/next/ ).  If you
are tracking the linux-next tree using git, you should not use "git pull"
to do so as that will try to merge the new linux-next release with the
old one.  You should use "git fetch" and checkout or reset to the new
master.

You can see which trees have been included by looking in the Next/Trees
file in the source.  There are also quilt-import.log and merge.log
files in the Next directory.  Between each merge, the tree was built
with a ppc64_defconfig for powerpc and an allmodconfig (with
CONFIG_BUILD_DOCSRC=n) for x86_64, a multi_v7_defconfig for arm and a
native build of tools/perf. After the final fixups (if any), I do an
x86_64 modules_install followed by builds for x86_64 allnoconfig,
powerpc allnoconfig (32 and 64 bit), ppc44x_defconfig, allyesconfig
(this fails its final link) and pseries_le_defconfig and i386, sparc
and sparc64 defconfig.

Below is a summary of the state of the merge.

I am currently merging 240 trees (counting Linus' and 34 trees of patches
pending for Linus' tree).

Stats about the size of the tree over time can be seen at
http://neuling.org/linux-next-size.html .

Status of my local build tests will be at
http://kisskb.ellerman.id.au/linux-next .  If maintainers want to give
advice about cross compilers/configs that work, we are always open to add
more builds.

Thanks to Randy Dunlap for doing many randconfig builds.  And to Paul
Gortmaker for triage and bug fixes.

-- 
Cheers,
Stephen Rothwell

$ git checkout master
$ git reset --hard stable
Merging origin/master (fa8410b35525 Linux 4.8-rc3)
Merging fixes/master (d3396e1e4ec4 Merge tag 'fixes-for-linus' of 
git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc)
Merging kbuild-current/rc-fixes (d3e2773c4ede builddeb: Skip gcc-plugins when 
not configured)
Merging arc-current/for-curr (c57653dc94d0 ARC: export __udivdi3 for modules)
Merging arm-current/fixes (87eed3c74d7c ARM: fix address limit restoration for 
undefined instructions)
Merging m68k-current/for-linus (6bd80f372371 m68k/defconfig: Update defconfigs 
for v4.7-rc2)
Merging metag-fixes/fixes (97b1d23f7bcb metag: Drop show_mem() from mem_init())
Merging powerpc-fixes/fixes (ca49e64f0cb1 selftests/powerpc: Specify we expect 
to build with std=gnu99)
Merging sparc/master (4620a06e4b3c shmem: Fix link error if huge pages support 
is disabled)
Merging net/master (d524d84b588e net: tehuti: fix typo: "eneble" -> "enable")
Merging ipsec/master (1625f4529957 net/xfrm_input: fix possible NULL deref of 
tunnel.ip6->parms.i_key)
Merging netfilter/master (b75911b66ad5 netfilter: cttimeout: fix use after free 
error when delete netns)
Merging ipvs/master (ea43f860d984 Merge branch 'ethoc-fixes')
Merging wireless-drivers/master (c81396f3da22 mwifiex: fix large amsdu packets 
causing firmware hang)
Merging mac80211/master (4d0bd46a4d55 Revert "wext: Fix 32 bit iwpriv 
compatibility issue with 64 bit Kernel")
Merging sound-current/for-linus (a52ff34e5ec6 ALSA: hda - Manage power well 
properly for resume)
Merging pci-current/for-linus (5d0bdf286782 PCI: Call pci_intx() when using 
legacy interrupts in pci_alloc_irq_vectors())
Merging driver-core.current/driver-core-linus (694d0d0bb203 Linux 4.8-rc2)
Merging tty.current/tty-linus (87a713c8ffca 8250/fintek: rename IRQ_MODE macro)
Merging usb.current/usb-linus (6040e57658ee Make the hardened user-copy code 
depend on having a hardened allocator)
Merging usb-gadget-fixes/fixes (a0ad85ae866f usb: dwc3: gadget: stop processing 
on HWO set)
Merging usb-serial-fixes/usb-linus (6695593e4a76 USB: serial: option: add 
WeTelecom WM-D200)
Merging usb-chipidea-fixes/ci-for-usb-stable (c4e94174983a usb: chipidea: udc: 
don't touch DP when controller is in host mode)
Merging staging.current/staging-linus (c0678b2d6648 include/linux: fix excess 
fence.h kernel-doc notation)
Merging char-misc.current/char-misc-linus (51c70261b257 Revert "android: 
binder: fix dangling pointer comparison")
Merging input-current/for-linus (47af45d684b5 Input: i8042 - set up shared 
ps2_cmd_mutex for AUX ports)
Merging crypto-current/master (e67479b13ede crypto: sha512-mb - fix ctx pointer)
Merging ide/master (797cee982eef Merge branch 'stable-4.8' of 
git://git.infradead.org/users/pcmoore/audit)
Merging rr-fixes/fixes (8244062ef1e5 modules: fix longstanding /proc/kallsyms 
vs module insertion race.)
Merging vfio-fixes/for-linus (c8952a707556 vfio/pci: Fix NULL 

linux-next: Tree for Aug 22

2016-08-21 Thread Stephen Rothwell
Hi all,

Changes since 20160819:

The samsung-krzk tree gained a conflict against the imx-mxs tree.

The net-next tree gained a conflict against the net tree.

The kbuild tree still had its build warnings for PowerPC, for which I
reverted a commit.

Non-merge commits (relative to Linus' tree): 2676
 2870 files changed, 125212 insertions(+), 46601 deletions(-)



I have created today's linux-next tree at
git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
(patches at http://www.kernel.org/pub/linux/kernel/next/ ).  If you
are tracking the linux-next tree using git, you should not use "git pull"
to do so as that will try to merge the new linux-next release with the
old one.  You should use "git fetch" and checkout or reset to the new
master.

You can see which trees have been included by looking in the Next/Trees
file in the source.  There are also quilt-import.log and merge.log
files in the Next directory.  Between each merge, the tree was built
with a ppc64_defconfig for powerpc and an allmodconfig (with
CONFIG_BUILD_DOCSRC=n) for x86_64, a multi_v7_defconfig for arm and a
native build of tools/perf. After the final fixups (if any), I do an
x86_64 modules_install followed by builds for x86_64 allnoconfig,
powerpc allnoconfig (32 and 64 bit), ppc44x_defconfig, allyesconfig
(this fails its final link) and pseries_le_defconfig and i386, sparc
and sparc64 defconfig.

Below is a summary of the state of the merge.

I am currently merging 240 trees (counting Linus' and 34 trees of patches
pending for Linus' tree).

Stats about the size of the tree over time can be seen at
http://neuling.org/linux-next-size.html .

Status of my local build tests will be at
http://kisskb.ellerman.id.au/linux-next .  If maintainers want to give
advice about cross compilers/configs that work, we are always open to add
more builds.

Thanks to Randy Dunlap for doing many randconfig builds.  And to Paul
Gortmaker for triage and bug fixes.

-- 
Cheers,
Stephen Rothwell

$ git checkout master
$ git reset --hard stable
Merging origin/master (fa8410b35525 Linux 4.8-rc3)
Merging fixes/master (d3396e1e4ec4 Merge tag 'fixes-for-linus' of 
git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc)
Merging kbuild-current/rc-fixes (d3e2773c4ede builddeb: Skip gcc-plugins when 
not configured)
Merging arc-current/for-curr (c57653dc94d0 ARC: export __udivdi3 for modules)
Merging arm-current/fixes (87eed3c74d7c ARM: fix address limit restoration for 
undefined instructions)
Merging m68k-current/for-linus (6bd80f372371 m68k/defconfig: Update defconfigs 
for v4.7-rc2)
Merging metag-fixes/fixes (97b1d23f7bcb metag: Drop show_mem() from mem_init())
Merging powerpc-fixes/fixes (ca49e64f0cb1 selftests/powerpc: Specify we expect 
to build with std=gnu99)
Merging sparc/master (4620a06e4b3c shmem: Fix link error if huge pages support 
is disabled)
Merging net/master (d524d84b588e net: tehuti: fix typo: "eneble" -> "enable")
Merging ipsec/master (1625f4529957 net/xfrm_input: fix possible NULL deref of 
tunnel.ip6->parms.i_key)
Merging netfilter/master (b75911b66ad5 netfilter: cttimeout: fix use after free 
error when delete netns)
Merging ipvs/master (ea43f860d984 Merge branch 'ethoc-fixes')
Merging wireless-drivers/master (c81396f3da22 mwifiex: fix large amsdu packets 
causing firmware hang)
Merging mac80211/master (4d0bd46a4d55 Revert "wext: Fix 32 bit iwpriv 
compatibility issue with 64 bit Kernel")
Merging sound-current/for-linus (a52ff34e5ec6 ALSA: hda - Manage power well 
properly for resume)
Merging pci-current/for-linus (5d0bdf286782 PCI: Call pci_intx() when using 
legacy interrupts in pci_alloc_irq_vectors())
Merging driver-core.current/driver-core-linus (694d0d0bb203 Linux 4.8-rc2)
Merging tty.current/tty-linus (87a713c8ffca 8250/fintek: rename IRQ_MODE macro)
Merging usb.current/usb-linus (6040e57658ee Make the hardened user-copy code 
depend on having a hardened allocator)
Merging usb-gadget-fixes/fixes (a0ad85ae866f usb: dwc3: gadget: stop processing 
on HWO set)
Merging usb-serial-fixes/usb-linus (6695593e4a76 USB: serial: option: add 
WeTelecom WM-D200)
Merging usb-chipidea-fixes/ci-for-usb-stable (c4e94174983a usb: chipidea: udc: 
don't touch DP when controller is in host mode)
Merging staging.current/staging-linus (c0678b2d6648 include/linux: fix excess 
fence.h kernel-doc notation)
Merging char-misc.current/char-misc-linus (51c70261b257 Revert "android: 
binder: fix dangling pointer comparison")
Merging input-current/for-linus (47af45d684b5 Input: i8042 - set up shared 
ps2_cmd_mutex for AUX ports)
Merging crypto-current/master (e67479b13ede crypto: sha512-mb - fix ctx pointer)
Merging ide/master (797cee982eef Merge branch 'stable-4.8' of 
git://git.infradead.org/users/pcmoore/audit)
Merging rr-fixes/fixes (8244062ef1e5 modules: fix longstanding /proc/kallsyms 
vs module insertion race.)
Merging vfio-fixes/for-linus (c8952a707556 vfio/pci: Fix NULL 

Re: [PATCH 3.10 090/180] xfs: xfs_iflush_cluster fails to abort on error

2016-08-21 Thread Willy Tarreau
Hi Dave,

On Mon, Aug 22, 2016 at 02:21:08PM +1000, Dave Chinner wrote:
> > -   if (error || !bp) {
> > +   if (error == -EAGAIN) {
> 
> Wrong. Errors changed sign in XFS in 3.17.

Ah my bad, sorry for this.

> /rant
> 
> So, after just having to point this out (again!) for a different
> stable kernel patchset review, and this specific problem causing
> user-reported stable kernel regression and filesystem corruption
> *months ago*. That resulted in discussion and new stable commits to
> fix the problem. So now I'm left to wonder about the process of
> stable kernels.

Yep I remember this discussion now, I'm sorry.

> AFAICT, stable kernel maintainers are not watching what happens with
> other stable kernels, nor are they talking to other stable kernel
> maintainers. I should not have to tell every single stable kernel
> maintainer that a specific patch needs to be changed after it's
> already been reported broken, triaged and fixed in other stable
> kernels. You've all got a record that the patch needs to be included
> in a stable kernel, but nobody is seems to notice when it comes to
> fixing problems with a stable patch even when that all happens on
> sta...@vger.kernel.org.
> 
> Seriously, guys, pick up your act a bit and start talking between
> yourselvesi and tracking regressions and fixes so the burden of
> catching known reported and fixed problems with backports doesn't
> rely on the upstream developers noticing the problem when hundreds
> of patches for random stable kernels go past on lkml every week...

We definitely do exchange quite a bit and I pick patches from 3.14 for
3.10, but sometimes I can simply pick the original one for various
reasons (eg: I if had queued its upstream ID earlier). That's also why
the review process helps. I'm sincerely sorry that I failed on this one
and that you had to deal with it again, I'm going to fix it now.

Thanks,
Willy


Re: [PATCH 3.10 090/180] xfs: xfs_iflush_cluster fails to abort on error

2016-08-21 Thread Willy Tarreau
Hi Dave,

On Mon, Aug 22, 2016 at 02:21:08PM +1000, Dave Chinner wrote:
> > -   if (error || !bp) {
> > +   if (error == -EAGAIN) {
> 
> Wrong. Errors changed sign in XFS in 3.17.

Ah my bad, sorry for this.

> /rant
> 
> So, after just having to point this out (again!) for a different
> stable kernel patchset review, and this specific problem causing
> user-reported stable kernel regression and filesystem corruption
> *months ago*. That resulted in discussion and new stable commits to
> fix the problem. So now I'm left to wonder about the process of
> stable kernels.

Yep I remember this discussion now, I'm sorry.

> AFAICT, stable kernel maintainers are not watching what happens with
> other stable kernels, nor are they talking to other stable kernel
> maintainers. I should not have to tell every single stable kernel
> maintainer that a specific patch needs to be changed after it's
> already been reported broken, triaged and fixed in other stable
> kernels. You've all got a record that the patch needs to be included
> in a stable kernel, but nobody is seems to notice when it comes to
> fixing problems with a stable patch even when that all happens on
> sta...@vger.kernel.org.
> 
> Seriously, guys, pick up your act a bit and start talking between
> yourselvesi and tracking regressions and fixes so the burden of
> catching known reported and fixed problems with backports doesn't
> rely on the upstream developers noticing the problem when hundreds
> of patches for random stable kernels go past on lkml every week...

We definitely do exchange quite a bit and I pick patches from 3.14 for
3.10, but sometimes I can simply pick the original one for various
reasons (eg: I if had queued its upstream ID earlier). That's also why
the review process helps. I'm sincerely sorry that I failed on this one
and that you had to deal with it again, I'm going to fix it now.

Thanks,
Willy


Re: [PATCH 2/2] ALSA: compress: Reduce the scope for two variables in snd_compr_set_params()

2016-08-21 Thread Vinod Koul
On Sun, Aug 21, 2016 at 04:36:22PM -0400, Julia Lawall wrote:
> 
> 
> On Sun, 21 Aug 2016, SF Markus Elfring wrote:
> 
> > From: Markus Elfring 
> > Date: Sun, 21 Aug 2016 21:26:18 +0200
> >
> > Reduce the scope for the local variables to an if branch.
> >
> > Signed-off-by: Markus Elfring 
> > ---
> >  sound/core/compress_offload.c | 12 ++--
> >  1 file changed, 6 insertions(+), 6 deletions(-)
> >
> > diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
> > index 583d407..b43aec5 100644
> > --- a/sound/core/compress_offload.c
> > +++ b/sound/core/compress_offload.c
> > @@ -545,14 +545,14 @@ static int snd_compress_check_input(struct 
> > snd_compr_params *params)
> >  static int
> >  snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)
> >  {
> > -   struct snd_compr_params *params;
> > -   int retval;
> > -
> > if (stream->runtime->state == SNDRV_PCM_STATE_OPEN) {
> > /*
> >  * we should allow parameter change only when stream has been
> >  * opened not in other cases
> >  */
> > +   int retval;
> > +   struct snd_compr_params *params;
> 
> I don't like this at all.  Local variables should be at the top of the
> function, not hiding under 4 lines of comments in the middle of the code.

I agree with you this, it doesn't help IMO as well

-- 
~Vinod


Re: [PATCH 2/2] ALSA: compress: Reduce the scope for two variables in snd_compr_set_params()

2016-08-21 Thread Vinod Koul
On Sun, Aug 21, 2016 at 04:36:22PM -0400, Julia Lawall wrote:
> 
> 
> On Sun, 21 Aug 2016, SF Markus Elfring wrote:
> 
> > From: Markus Elfring 
> > Date: Sun, 21 Aug 2016 21:26:18 +0200
> >
> > Reduce the scope for the local variables to an if branch.
> >
> > Signed-off-by: Markus Elfring 
> > ---
> >  sound/core/compress_offload.c | 12 ++--
> >  1 file changed, 6 insertions(+), 6 deletions(-)
> >
> > diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
> > index 583d407..b43aec5 100644
> > --- a/sound/core/compress_offload.c
> > +++ b/sound/core/compress_offload.c
> > @@ -545,14 +545,14 @@ static int snd_compress_check_input(struct 
> > snd_compr_params *params)
> >  static int
> >  snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)
> >  {
> > -   struct snd_compr_params *params;
> > -   int retval;
> > -
> > if (stream->runtime->state == SNDRV_PCM_STATE_OPEN) {
> > /*
> >  * we should allow parameter change only when stream has been
> >  * opened not in other cases
> >  */
> > +   int retval;
> > +   struct snd_compr_params *params;
> 
> I don't like this at all.  Local variables should be at the top of the
> function, not hiding under 4 lines of comments in the middle of the code.

I agree with you this, it doesn't help IMO as well

-- 
~Vinod


Re: [PATCH 1/2] ALSA: compress: Use memdup_user() rather than duplicating its implementation

2016-08-21 Thread Vinod Koul
On Sun, Aug 21, 2016 at 09:43:22PM +0200, SF Markus Elfring wrote:
> From: Markus Elfring 
> Date: Sun, 21 Aug 2016 21:02:06 +0200
> 
> Reuse existing functionality from memdup_user() instead of keeping
> duplicate source code.
> 
> This issue was detected by using the Coccinelle software.

It usually helps to have Coccinelle script in changelog.

But nevertheless

Acked-by: Vinod Koul 

> 
> Signed-off-by: Markus Elfring 
> ---
>  sound/core/compress_offload.c | 10 +++---
>  1 file changed, 3 insertions(+), 7 deletions(-)
> 
> diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
> index 2c49848..583d407 100644
> --- a/sound/core/compress_offload.c
> +++ b/sound/core/compress_offload.c
> @@ -553,13 +553,9 @@ snd_compr_set_params(struct snd_compr_stream *stream, 
> unsigned long arg)
>* we should allow parameter change only when stream has been
>* opened not in other cases
>*/
> - params = kmalloc(sizeof(*params), GFP_KERNEL);
> - if (!params)
> - return -ENOMEM;
> - if (copy_from_user(params, (void __user *)arg, 
> sizeof(*params))) {
> - retval = -EFAULT;
> - goto out;
> - }
> + params = memdup_user((void __user *)arg, sizeof(*params));
> + if (IS_ERR(params))
> + return PTR_ERR(params);
>  
>   retval = snd_compress_check_input(params);
>   if (retval)
> -- 
> 2.9.3
> 

-- 
~Vinod


Re: [PATCH 1/2] ALSA: compress: Use memdup_user() rather than duplicating its implementation

2016-08-21 Thread Vinod Koul
On Sun, Aug 21, 2016 at 09:43:22PM +0200, SF Markus Elfring wrote:
> From: Markus Elfring 
> Date: Sun, 21 Aug 2016 21:02:06 +0200
> 
> Reuse existing functionality from memdup_user() instead of keeping
> duplicate source code.
> 
> This issue was detected by using the Coccinelle software.

It usually helps to have Coccinelle script in changelog.

But nevertheless

Acked-by: Vinod Koul 

> 
> Signed-off-by: Markus Elfring 
> ---
>  sound/core/compress_offload.c | 10 +++---
>  1 file changed, 3 insertions(+), 7 deletions(-)
> 
> diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
> index 2c49848..583d407 100644
> --- a/sound/core/compress_offload.c
> +++ b/sound/core/compress_offload.c
> @@ -553,13 +553,9 @@ snd_compr_set_params(struct snd_compr_stream *stream, 
> unsigned long arg)
>* we should allow parameter change only when stream has been
>* opened not in other cases
>*/
> - params = kmalloc(sizeof(*params), GFP_KERNEL);
> - if (!params)
> - return -ENOMEM;
> - if (copy_from_user(params, (void __user *)arg, 
> sizeof(*params))) {
> - retval = -EFAULT;
> - goto out;
> - }
> + params = memdup_user((void __user *)arg, sizeof(*params));
> + if (IS_ERR(params))
> + return PTR_ERR(params);
>  
>   retval = snd_compress_check_input(params);
>   if (retval)
> -- 
> 2.9.3
> 

-- 
~Vinod


Re: [v13 PATCH 2/5] phy: Add USB Type-C PHY driver for rk3399

2016-08-21 Thread Chris

Hi Guenter

On 08/22/2016 12:40 PM, Guenter Roeck wrote:

On Sun, Aug 21, 2016 at 9:23 PM, Chris Zhong  wrote:

Add a PHY provider driver for the rk3399 SoC Type-c PHY. The USB
Type-C PHY is designed to support the USB3 and DP applications. The
PHY basically has two main components: USB3 and DisplyPort. USB3
operates in SuperSpeed mode and the DP can operate at RBR, HBR and
HBR2 data rates. Hence, create 2 PHY deivces, the phy[0] for DP,
and phy[1] for USB3.

Signed-off-by: Chris Zhong 
Signed-off-by: Kever Yang 
Reviewed-by: Guenter Roeck 
Tested-by: Guenter Roeck 

---

Changes in v13:
- do not return err if nothing connected with Type-C, when usb phy power on,
   since the USB core driver will call phy power without USB3 device connected.

Changes in v12:
- enable DP+USB3 mode, only when EXTCON_PROP_USB_SUPERSPEED equal 1
   and DP is attached

Changes in v11:
- make a clearer demarcation between usb phy and dp phy.

Changes in v10:
- do not control dp select and hpd config in phy driver

Changes in v9:
- the new_mode should be int not u8
- move mutex_lock(>lock); to earlier place. in
   rockchip_usb3_phy_power_off
- better mutex lock for phy mode and flip
- split the Type-C PHY into two PHYs: USB3 and DP

Changes in v8:
- set the default cable id to EXTCON_USB_HOST
- optimization Error log

Changes in v7:
- support new API of extcon

Changes in v6:
- delete the support of PIN_ASSIGN_A/B
- set the default mode to MODE_DFP_USB
- disable DP PLL at USB3 only mode

Changes in v5:
- support get property from extcon
- remove PIN ASSIGN A/B support

Changes in v4:
- select EXTCON
- use phy framework to control the USB3 and DP function
- rename PIN_MAP_ to PIN_ASSIGN_

Changes in v3:
- remove the phy framework(Kishon Vijay Abraham I)
- add parentheses around the macro
- use a single space between type and name
- add spaces after opening and before closing braces.
- use u16 for register value
- remove type-c phy header file
- CodingStyle optimization
- use some cable extcon to get type-c port information
- add a extcon to notify Display Port

Changes in v2:
- select RESET_CONTROLLER
- alphabetic order
- modify some spelling mistakes
- make mode cleaner
- use bool for enable/disable
- check all of the return value
- return a better err number
- use more readx_poll_timeout()
- clk_disable_unprepare(tcphy->clk_ref);
- remove unuse functions, rockchip_typec_phy_power_on/off
- remove unnecessary typecast from void *
- use dts node to distinguish between phys.

Changes in v1:
- update the licence note
- init core clock to 50MHz
- use extcon API
- remove unused global
- add some comments for magic num
- change usleep_range(1000, 2000) tousleep_range(1000, 1050)
- remove __func__ from dev_err
- return err number when get clk failed
- remove ADDR_ADJ define
- use devm_clk_get(>dev, "tcpdcore")

  drivers/phy/Kconfig  |   9 +
  drivers/phy/Makefile |   1 +
  drivers/phy/phy-rockchip-typec.c | 977 +++
  3 files changed, 987 insertions(+)
  create mode 100644 drivers/phy/phy-rockchip-typec.c

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 42f3e30..c775fd7 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -348,6 +348,15 @@ config PHY_ROCKCHIP_PCIE
 help
   Enable this to support the Rockchip PCIe PHY.

+config PHY_ROCKCHIP_TYPEC
+   tristate "Rockchip TYPEC PHY Driver"
+   depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
+   select EXTCON
+   select GENERIC_PHY
+   select RESET_CONTROLLER
+   help
+ Enable this to support the Rockchip USB TYPEC PHY.
+
  config PHY_ST_SPEAR1310_MIPHY
 tristate "ST SPEAR1310-MIPHY driver"
 select GENERIC_PHY
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index fbb91e7..5d58b63 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2)  += 
phy-rockchip-inno-usb2.o
  obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o
  obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o
  obj-$(CONFIG_PHY_ROCKCHIP_DP)  += phy-rockchip-dp.o
+obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o
  obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA)+= phy-qcom-ipq806x-sata.o
  obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY)   += phy-spear1310-miphy.o
  obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY)   += phy-spear1340-miphy.o
diff --git a/drivers/phy/phy-rockchip-typec.c b/drivers/phy/phy-rockchip-typec.c
new file mode 100644
index 000..6edeae6
--- /dev/null
+++ b/drivers/phy/phy-rockchip-typec.c
@@ -0,0 +1,977 @@
+/*
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ * Author: Chris Zhong 
+ * Kever Yang 
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software 

Re: [v13 PATCH 2/5] phy: Add USB Type-C PHY driver for rk3399

2016-08-21 Thread Chris

Hi Guenter

On 08/22/2016 12:40 PM, Guenter Roeck wrote:

On Sun, Aug 21, 2016 at 9:23 PM, Chris Zhong  wrote:

Add a PHY provider driver for the rk3399 SoC Type-c PHY. The USB
Type-C PHY is designed to support the USB3 and DP applications. The
PHY basically has two main components: USB3 and DisplyPort. USB3
operates in SuperSpeed mode and the DP can operate at RBR, HBR and
HBR2 data rates. Hence, create 2 PHY deivces, the phy[0] for DP,
and phy[1] for USB3.

Signed-off-by: Chris Zhong 
Signed-off-by: Kever Yang 
Reviewed-by: Guenter Roeck 
Tested-by: Guenter Roeck 

---

Changes in v13:
- do not return err if nothing connected with Type-C, when usb phy power on,
   since the USB core driver will call phy power without USB3 device connected.

Changes in v12:
- enable DP+USB3 mode, only when EXTCON_PROP_USB_SUPERSPEED equal 1
   and DP is attached

Changes in v11:
- make a clearer demarcation between usb phy and dp phy.

Changes in v10:
- do not control dp select and hpd config in phy driver

Changes in v9:
- the new_mode should be int not u8
- move mutex_lock(>lock); to earlier place. in
   rockchip_usb3_phy_power_off
- better mutex lock for phy mode and flip
- split the Type-C PHY into two PHYs: USB3 and DP

Changes in v8:
- set the default cable id to EXTCON_USB_HOST
- optimization Error log

Changes in v7:
- support new API of extcon

Changes in v6:
- delete the support of PIN_ASSIGN_A/B
- set the default mode to MODE_DFP_USB
- disable DP PLL at USB3 only mode

Changes in v5:
- support get property from extcon
- remove PIN ASSIGN A/B support

Changes in v4:
- select EXTCON
- use phy framework to control the USB3 and DP function
- rename PIN_MAP_ to PIN_ASSIGN_

Changes in v3:
- remove the phy framework(Kishon Vijay Abraham I)
- add parentheses around the macro
- use a single space between type and name
- add spaces after opening and before closing braces.
- use u16 for register value
- remove type-c phy header file
- CodingStyle optimization
- use some cable extcon to get type-c port information
- add a extcon to notify Display Port

Changes in v2:
- select RESET_CONTROLLER
- alphabetic order
- modify some spelling mistakes
- make mode cleaner
- use bool for enable/disable
- check all of the return value
- return a better err number
- use more readx_poll_timeout()
- clk_disable_unprepare(tcphy->clk_ref);
- remove unuse functions, rockchip_typec_phy_power_on/off
- remove unnecessary typecast from void *
- use dts node to distinguish between phys.

Changes in v1:
- update the licence note
- init core clock to 50MHz
- use extcon API
- remove unused global
- add some comments for magic num
- change usleep_range(1000, 2000) tousleep_range(1000, 1050)
- remove __func__ from dev_err
- return err number when get clk failed
- remove ADDR_ADJ define
- use devm_clk_get(>dev, "tcpdcore")

  drivers/phy/Kconfig  |   9 +
  drivers/phy/Makefile |   1 +
  drivers/phy/phy-rockchip-typec.c | 977 +++
  3 files changed, 987 insertions(+)
  create mode 100644 drivers/phy/phy-rockchip-typec.c

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 42f3e30..c775fd7 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -348,6 +348,15 @@ config PHY_ROCKCHIP_PCIE
 help
   Enable this to support the Rockchip PCIe PHY.

+config PHY_ROCKCHIP_TYPEC
+   tristate "Rockchip TYPEC PHY Driver"
+   depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
+   select EXTCON
+   select GENERIC_PHY
+   select RESET_CONTROLLER
+   help
+ Enable this to support the Rockchip USB TYPEC PHY.
+
  config PHY_ST_SPEAR1310_MIPHY
 tristate "ST SPEAR1310-MIPHY driver"
 select GENERIC_PHY
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index fbb91e7..5d58b63 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2)  += 
phy-rockchip-inno-usb2.o
  obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o
  obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o
  obj-$(CONFIG_PHY_ROCKCHIP_DP)  += phy-rockchip-dp.o
+obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o
  obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA)+= phy-qcom-ipq806x-sata.o
  obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY)   += phy-spear1310-miphy.o
  obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY)   += phy-spear1340-miphy.o
diff --git a/drivers/phy/phy-rockchip-typec.c b/drivers/phy/phy-rockchip-typec.c
new file mode 100644
index 000..6edeae6
--- /dev/null
+++ b/drivers/phy/phy-rockchip-typec.c
@@ -0,0 +1,977 @@
+/*
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ * Author: Chris Zhong 
+ * Kever Yang 
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but 

[PATCH v2] CLK: Add Loongson1C clock support

2016-08-21 Thread Yang Ling
This patch adds clock support to Loongson1C SoC.

Signed-off-by: Yang Ling 

---
V2:
  Use loongson1 generic clock interface.
---
 drivers/clk/loongson1/Makefile |   1 +
 drivers/clk/loongson1/clk-loongson1c.c | 102 +
 2 files changed, 103 insertions(+)
 create mode 100644 drivers/clk/loongson1/clk-loongson1c.c

diff --git a/drivers/clk/loongson1/Makefile b/drivers/clk/loongson1/Makefile
index 5a162a1..b7f6a16 100644
--- a/drivers/clk/loongson1/Makefile
+++ b/drivers/clk/loongson1/Makefile
@@ -1,2 +1,3 @@
 obj-y  += clk.o
 obj-$(CONFIG_LOONGSON1_LS1B)   += clk-loongson1b.o
+obj-$(CONFIG_LOONGSON1_LS1C)   += clk-loongson1c.o
diff --git a/drivers/clk/loongson1/clk-loongson1c.c 
b/drivers/clk/loongson1/clk-loongson1c.c
new file mode 100644
index 000..7e7e5ff
--- /dev/null
+++ b/drivers/clk/loongson1/clk-loongson1c.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016 Yang Ling 
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include 
+#include 
+
+#include 
+#include "clk.h"
+
+#define OSC(24 * 100)
+#define DIV_APB1
+
+static DEFINE_SPINLOCK(_lock);
+
+static unsigned long ls1x_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+   u32 pll, rate;
+
+   pll = __raw_readl(LS1X_CLK_PLL_FREQ);
+   rate = ((pll >> 8) & 0xff) + ((pll >> 16) & 0xff);
+   rate *= OSC;
+   rate >>= 2;
+
+   return rate;
+}
+
+static const struct clk_ops ls1x_pll_clk_ops = {
+   .enable = ls1x_pll_clk_enable,
+   .disable = ls1x_pll_clk_disable,
+   .recalc_rate = ls1x_pll_recalc_rate,
+};
+
+static const char *const cpu_parents[] = { "cpu_clk_div", "osc_clk", };
+static const char *const ahb_parents[] = { "ahb_clk_div", "osc_clk", };
+static const char *const dc_parents[] = { "dc_clk_div", "osc_clk", };
+
+static const struct clk_div_table ahb_div_table[] = {
+   [0] = { .val = 0, .div = 2 },
+   [1] = { .val = 1, .div = 4 },
+   [2] = { .val = 2, .div = 3 },
+   [3] = { .val = 3, .div = 3 },
+};
+
+void __init ls1x_clk_init(void)
+{
+   struct clk *clk;
+
+   clk = clk_register_fixed_rate(NULL, "osc_clk", NULL, 0, OSC);
+   clk_register_clkdev(clk, "osc_clk", NULL);
+
+   /* clock derived from 24 MHz OSC clk */
+   clk = clk_register_pll(NULL, "pll_clk", "osc_clk",
+   _pll_clk_ops, 0);
+   clk_register_clkdev(clk, "pll_clk", NULL);
+
+   clk = clk_register_divider(NULL, "cpu_clk_div", "pll_clk",
+  CLK_GET_RATE_NOCACHE, LS1X_CLK_PLL_DIV,
+  DIV_CPU_SHIFT, DIV_CPU_WIDTH,
+  CLK_DIVIDER_ONE_BASED |
+  CLK_DIVIDER_ROUND_CLOSEST, &_lock);
+   clk_register_clkdev(clk, "cpu_clk_div", NULL);
+   clk = clk_register_fixed_factor(NULL, "cpu_clk", "cpu_clk_div",
+   0, 1, 1);
+   clk_register_clkdev(clk, "cpu_clk", NULL);
+
+   clk = clk_register_divider(NULL, "dc_clk_div", "pll_clk",
+  0, LS1X_CLK_PLL_DIV, DIV_DC_SHIFT,
+  DIV_DC_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock);
+   clk_register_clkdev(clk, "dc_clk_div", NULL);
+   clk = clk_register_fixed_factor(NULL, "dc_clk", "dc_clk_div", 0, 1, 1);
+   clk_register_clkdev(clk, "dc_clk", NULL);
+
+   clk = clk_register_divider_table(NULL, "ahb_clk_div", "cpu_clk_div",
+   0, LS1X_CLK_PLL_FREQ, DIV_DDR_SHIFT,
+   DIV_DDR_WIDTH, CLK_DIVIDER_ALLOW_ZERO,
+   ahb_div_table, &_lock);
+   clk_register_clkdev(clk, "ahb_clk_div", NULL);
+   clk = clk_register_fixed_factor(NULL, "ahb_clk", "ahb_clk_div",
+   0, 1, 1);
+   clk_register_clkdev(clk, "ahb_clk", NULL);
+   clk_register_clkdev(clk, "ls1x-dma", NULL);
+   clk_register_clkdev(clk, "stmmaceth", NULL);
+
+   /* clock derived from AHB clk */
+   clk = clk_register_fixed_factor(NULL, "apb_clk", "ahb_clk", 0, 1,
+   DIV_APB);
+   clk_register_clkdev(clk, "apb_clk", NULL);
+   clk_register_clkdev(clk, "ls1x-ac97", NULL);
+   clk_register_clkdev(clk, "ls1x-i2c", NULL);
+   clk_register_clkdev(clk, "ls1x-nand", NULL);
+   clk_register_clkdev(clk, "ls1x-pwmtimer", NULL);
+   clk_register_clkdev(clk, "ls1x-spi", NULL);
+   clk_register_clkdev(clk, "ls1x-wdt", NULL);
+   clk_register_clkdev(clk, "serial8250", NULL);
+}
-- 
1.9.1



[PATCH v2] CLK: Add Loongson1C clock support

2016-08-21 Thread Yang Ling
This patch adds clock support to Loongson1C SoC.

Signed-off-by: Yang Ling 

---
V2:
  Use loongson1 generic clock interface.
---
 drivers/clk/loongson1/Makefile |   1 +
 drivers/clk/loongson1/clk-loongson1c.c | 102 +
 2 files changed, 103 insertions(+)
 create mode 100644 drivers/clk/loongson1/clk-loongson1c.c

diff --git a/drivers/clk/loongson1/Makefile b/drivers/clk/loongson1/Makefile
index 5a162a1..b7f6a16 100644
--- a/drivers/clk/loongson1/Makefile
+++ b/drivers/clk/loongson1/Makefile
@@ -1,2 +1,3 @@
 obj-y  += clk.o
 obj-$(CONFIG_LOONGSON1_LS1B)   += clk-loongson1b.o
+obj-$(CONFIG_LOONGSON1_LS1C)   += clk-loongson1c.o
diff --git a/drivers/clk/loongson1/clk-loongson1c.c 
b/drivers/clk/loongson1/clk-loongson1c.c
new file mode 100644
index 000..7e7e5ff
--- /dev/null
+++ b/drivers/clk/loongson1/clk-loongson1c.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016 Yang Ling 
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include 
+#include 
+
+#include 
+#include "clk.h"
+
+#define OSC(24 * 100)
+#define DIV_APB1
+
+static DEFINE_SPINLOCK(_lock);
+
+static unsigned long ls1x_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+   u32 pll, rate;
+
+   pll = __raw_readl(LS1X_CLK_PLL_FREQ);
+   rate = ((pll >> 8) & 0xff) + ((pll >> 16) & 0xff);
+   rate *= OSC;
+   rate >>= 2;
+
+   return rate;
+}
+
+static const struct clk_ops ls1x_pll_clk_ops = {
+   .enable = ls1x_pll_clk_enable,
+   .disable = ls1x_pll_clk_disable,
+   .recalc_rate = ls1x_pll_recalc_rate,
+};
+
+static const char *const cpu_parents[] = { "cpu_clk_div", "osc_clk", };
+static const char *const ahb_parents[] = { "ahb_clk_div", "osc_clk", };
+static const char *const dc_parents[] = { "dc_clk_div", "osc_clk", };
+
+static const struct clk_div_table ahb_div_table[] = {
+   [0] = { .val = 0, .div = 2 },
+   [1] = { .val = 1, .div = 4 },
+   [2] = { .val = 2, .div = 3 },
+   [3] = { .val = 3, .div = 3 },
+};
+
+void __init ls1x_clk_init(void)
+{
+   struct clk *clk;
+
+   clk = clk_register_fixed_rate(NULL, "osc_clk", NULL, 0, OSC);
+   clk_register_clkdev(clk, "osc_clk", NULL);
+
+   /* clock derived from 24 MHz OSC clk */
+   clk = clk_register_pll(NULL, "pll_clk", "osc_clk",
+   _pll_clk_ops, 0);
+   clk_register_clkdev(clk, "pll_clk", NULL);
+
+   clk = clk_register_divider(NULL, "cpu_clk_div", "pll_clk",
+  CLK_GET_RATE_NOCACHE, LS1X_CLK_PLL_DIV,
+  DIV_CPU_SHIFT, DIV_CPU_WIDTH,
+  CLK_DIVIDER_ONE_BASED |
+  CLK_DIVIDER_ROUND_CLOSEST, &_lock);
+   clk_register_clkdev(clk, "cpu_clk_div", NULL);
+   clk = clk_register_fixed_factor(NULL, "cpu_clk", "cpu_clk_div",
+   0, 1, 1);
+   clk_register_clkdev(clk, "cpu_clk", NULL);
+
+   clk = clk_register_divider(NULL, "dc_clk_div", "pll_clk",
+  0, LS1X_CLK_PLL_DIV, DIV_DC_SHIFT,
+  DIV_DC_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock);
+   clk_register_clkdev(clk, "dc_clk_div", NULL);
+   clk = clk_register_fixed_factor(NULL, "dc_clk", "dc_clk_div", 0, 1, 1);
+   clk_register_clkdev(clk, "dc_clk", NULL);
+
+   clk = clk_register_divider_table(NULL, "ahb_clk_div", "cpu_clk_div",
+   0, LS1X_CLK_PLL_FREQ, DIV_DDR_SHIFT,
+   DIV_DDR_WIDTH, CLK_DIVIDER_ALLOW_ZERO,
+   ahb_div_table, &_lock);
+   clk_register_clkdev(clk, "ahb_clk_div", NULL);
+   clk = clk_register_fixed_factor(NULL, "ahb_clk", "ahb_clk_div",
+   0, 1, 1);
+   clk_register_clkdev(clk, "ahb_clk", NULL);
+   clk_register_clkdev(clk, "ls1x-dma", NULL);
+   clk_register_clkdev(clk, "stmmaceth", NULL);
+
+   /* clock derived from AHB clk */
+   clk = clk_register_fixed_factor(NULL, "apb_clk", "ahb_clk", 0, 1,
+   DIV_APB);
+   clk_register_clkdev(clk, "apb_clk", NULL);
+   clk_register_clkdev(clk, "ls1x-ac97", NULL);
+   clk_register_clkdev(clk, "ls1x-i2c", NULL);
+   clk_register_clkdev(clk, "ls1x-nand", NULL);
+   clk_register_clkdev(clk, "ls1x-pwmtimer", NULL);
+   clk_register_clkdev(clk, "ls1x-spi", NULL);
+   clk_register_clkdev(clk, "ls1x-wdt", NULL);
+   clk_register_clkdev(clk, "serial8250", NULL);
+}
-- 
1.9.1



Re: [PATCH 2/4] cpu: expose pm_qos_resume_latency for each cpu

2016-08-21 Thread Alex Shi
Add a pr_debug for failure output.


>From dc5111ed3974f994a9f1d88fdd8dc813359a3b6c Mon Sep 17 00:00:00 2001
From: Alex Shi 
Date: Tue, 16 Aug 2016 15:29:01 +0800
Subject: [PATCH 2/4] cpu: expose pm_qos_resume_latency for each cpu

The cpu-dma PM QoS constraint impacts all the cpus in the system. There
is no way to let the user to choose a PM QoS constraint per cpu.

The following patch exposes to the userspace a per cpu based sysfs file
in order to let the userspace to change the value of the PM QoS latency
constraint.

This change is inoperative in its form and the cpuidle governors have to
take into account the per cpu latency constraint in addition to the
global cpu-dma latency constraint in order to operate properly.

BTW
The pm_qos_resume_latency usage defined in
Documentation/ABI/testing/sysfs-devices-power
The /sys/devices/.../power/pm_qos_resume_latency_us attribute
contains the PM QoS resume latency limit for the given device,
which is the maximum allowed time it can take to resume the
device, after it has been suspended at run time, from a resume
request to the moment the device will be ready to process I/O,
in microseconds.  If it is equal to 0, however, this means that
the PM QoS resume latency may be arbitrary.

Signed-off-by: Alex Shi 
---
 drivers/base/cpu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 4c28e1a..ba11e23 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "base.h"
 
@@ -376,6 +377,8 @@ int register_cpu(struct cpu *cpu, int num)
 
per_cpu(cpu_sys_devices, num) = >dev;
register_cpu_under_node(num, cpu_to_node(num));
+   if (dev_pm_qos_expose_latency_limit(>dev, 0))
+   pr_debug("CPU%d: add resume latency failed\n", num);
 
return 0;
 }
-- 
2.8.1.101.g72d917a



Re: [PATCH 2/4] cpu: expose pm_qos_resume_latency for each cpu

2016-08-21 Thread Alex Shi
Add a pr_debug for failure output.


>From dc5111ed3974f994a9f1d88fdd8dc813359a3b6c Mon Sep 17 00:00:00 2001
From: Alex Shi 
Date: Tue, 16 Aug 2016 15:29:01 +0800
Subject: [PATCH 2/4] cpu: expose pm_qos_resume_latency for each cpu

The cpu-dma PM QoS constraint impacts all the cpus in the system. There
is no way to let the user to choose a PM QoS constraint per cpu.

The following patch exposes to the userspace a per cpu based sysfs file
in order to let the userspace to change the value of the PM QoS latency
constraint.

This change is inoperative in its form and the cpuidle governors have to
take into account the per cpu latency constraint in addition to the
global cpu-dma latency constraint in order to operate properly.

BTW
The pm_qos_resume_latency usage defined in
Documentation/ABI/testing/sysfs-devices-power
The /sys/devices/.../power/pm_qos_resume_latency_us attribute
contains the PM QoS resume latency limit for the given device,
which is the maximum allowed time it can take to resume the
device, after it has been suspended at run time, from a resume
request to the moment the device will be ready to process I/O,
in microseconds.  If it is equal to 0, however, this means that
the PM QoS resume latency may be arbitrary.

Signed-off-by: Alex Shi 
---
 drivers/base/cpu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 4c28e1a..ba11e23 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "base.h"
 
@@ -376,6 +377,8 @@ int register_cpu(struct cpu *cpu, int num)
 
per_cpu(cpu_sys_devices, num) = >dev;
register_cpu_under_node(num, cpu_to_node(num));
+   if (dev_pm_qos_expose_latency_limit(>dev, 0))
+   pr_debug("CPU%d: add resume latency failed\n", num);
 
return 0;
 }
-- 
2.8.1.101.g72d917a



Re: [v13 PATCH 2/5] phy: Add USB Type-C PHY driver for rk3399

2016-08-21 Thread Guenter Roeck
On Sun, Aug 21, 2016 at 9:23 PM, Chris Zhong  wrote:
> Add a PHY provider driver for the rk3399 SoC Type-c PHY. The USB
> Type-C PHY is designed to support the USB3 and DP applications. The
> PHY basically has two main components: USB3 and DisplyPort. USB3
> operates in SuperSpeed mode and the DP can operate at RBR, HBR and
> HBR2 data rates. Hence, create 2 PHY deivces, the phy[0] for DP,
> and phy[1] for USB3.
>
> Signed-off-by: Chris Zhong 
> Signed-off-by: Kever Yang 
> Reviewed-by: Guenter Roeck 
> Tested-by: Guenter Roeck 
>
> ---
>
> Changes in v13:
> - do not return err if nothing connected with Type-C, when usb phy power on,
>   since the USB core driver will call phy power without USB3 device connected.
>
> Changes in v12:
> - enable DP+USB3 mode, only when EXTCON_PROP_USB_SUPERSPEED equal 1
>   and DP is attached
>
> Changes in v11:
> - make a clearer demarcation between usb phy and dp phy.
>
> Changes in v10:
> - do not control dp select and hpd config in phy driver
>
> Changes in v9:
> - the new_mode should be int not u8
> - move mutex_lock(>lock); to earlier place. in
>   rockchip_usb3_phy_power_off
> - better mutex lock for phy mode and flip
> - split the Type-C PHY into two PHYs: USB3 and DP
>
> Changes in v8:
> - set the default cable id to EXTCON_USB_HOST
> - optimization Error log
>
> Changes in v7:
> - support new API of extcon
>
> Changes in v6:
> - delete the support of PIN_ASSIGN_A/B
> - set the default mode to MODE_DFP_USB
> - disable DP PLL at USB3 only mode
>
> Changes in v5:
> - support get property from extcon
> - remove PIN ASSIGN A/B support
>
> Changes in v4:
> - select EXTCON
> - use phy framework to control the USB3 and DP function
> - rename PIN_MAP_ to PIN_ASSIGN_
>
> Changes in v3:
> - remove the phy framework(Kishon Vijay Abraham I)
> - add parentheses around the macro
> - use a single space between type and name
> - add spaces after opening and before closing braces.
> - use u16 for register value
> - remove type-c phy header file
> - CodingStyle optimization
> - use some cable extcon to get type-c port information
> - add a extcon to notify Display Port
>
> Changes in v2:
> - select RESET_CONTROLLER
> - alphabetic order
> - modify some spelling mistakes
> - make mode cleaner
> - use bool for enable/disable
> - check all of the return value
> - return a better err number
> - use more readx_poll_timeout()
> - clk_disable_unprepare(tcphy->clk_ref);
> - remove unuse functions, rockchip_typec_phy_power_on/off
> - remove unnecessary typecast from void *
> - use dts node to distinguish between phys.
>
> Changes in v1:
> - update the licence note
> - init core clock to 50MHz
> - use extcon API
> - remove unused global
> - add some comments for magic num
> - change usleep_range(1000, 2000) tousleep_range(1000, 1050)
> - remove __func__ from dev_err
> - return err number when get clk failed
> - remove ADDR_ADJ define
> - use devm_clk_get(>dev, "tcpdcore")
>
>  drivers/phy/Kconfig  |   9 +
>  drivers/phy/Makefile |   1 +
>  drivers/phy/phy-rockchip-typec.c | 977 
> +++
>  3 files changed, 987 insertions(+)
>  create mode 100644 drivers/phy/phy-rockchip-typec.c
>
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index 42f3e30..c775fd7 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -348,6 +348,15 @@ config PHY_ROCKCHIP_PCIE
> help
>   Enable this to support the Rockchip PCIe PHY.
>
> +config PHY_ROCKCHIP_TYPEC
> +   tristate "Rockchip TYPEC PHY Driver"
> +   depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
> +   select EXTCON
> +   select GENERIC_PHY
> +   select RESET_CONTROLLER
> +   help
> + Enable this to support the Rockchip USB TYPEC PHY.
> +
>  config PHY_ST_SPEAR1310_MIPHY
> tristate "ST SPEAR1310-MIPHY driver"
> select GENERIC_PHY
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index fbb91e7..5d58b63 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -39,6 +39,7 @@ obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2)  += 
> phy-rockchip-inno-usb2.o
>  obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o
>  obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o
>  obj-$(CONFIG_PHY_ROCKCHIP_DP)  += phy-rockchip-dp.o
> +obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o
>  obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA)+= phy-qcom-ipq806x-sata.o
>  obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY)   += phy-spear1310-miphy.o
>  obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY)   += phy-spear1340-miphy.o
> diff --git a/drivers/phy/phy-rockchip-typec.c 
> b/drivers/phy/phy-rockchip-typec.c
> new file mode 100644
> index 000..6edeae6
> --- /dev/null
> +++ b/drivers/phy/phy-rockchip-typec.c
> @@ -0,0 +1,977 @@
> +/*
> + * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
> + * Author: Chris Zhong 

Re: [v13 PATCH 2/5] phy: Add USB Type-C PHY driver for rk3399

2016-08-21 Thread Guenter Roeck
On Sun, Aug 21, 2016 at 9:23 PM, Chris Zhong  wrote:
> Add a PHY provider driver for the rk3399 SoC Type-c PHY. The USB
> Type-C PHY is designed to support the USB3 and DP applications. The
> PHY basically has two main components: USB3 and DisplyPort. USB3
> operates in SuperSpeed mode and the DP can operate at RBR, HBR and
> HBR2 data rates. Hence, create 2 PHY deivces, the phy[0] for DP,
> and phy[1] for USB3.
>
> Signed-off-by: Chris Zhong 
> Signed-off-by: Kever Yang 
> Reviewed-by: Guenter Roeck 
> Tested-by: Guenter Roeck 
>
> ---
>
> Changes in v13:
> - do not return err if nothing connected with Type-C, when usb phy power on,
>   since the USB core driver will call phy power without USB3 device connected.
>
> Changes in v12:
> - enable DP+USB3 mode, only when EXTCON_PROP_USB_SUPERSPEED equal 1
>   and DP is attached
>
> Changes in v11:
> - make a clearer demarcation between usb phy and dp phy.
>
> Changes in v10:
> - do not control dp select and hpd config in phy driver
>
> Changes in v9:
> - the new_mode should be int not u8
> - move mutex_lock(>lock); to earlier place. in
>   rockchip_usb3_phy_power_off
> - better mutex lock for phy mode and flip
> - split the Type-C PHY into two PHYs: USB3 and DP
>
> Changes in v8:
> - set the default cable id to EXTCON_USB_HOST
> - optimization Error log
>
> Changes in v7:
> - support new API of extcon
>
> Changes in v6:
> - delete the support of PIN_ASSIGN_A/B
> - set the default mode to MODE_DFP_USB
> - disable DP PLL at USB3 only mode
>
> Changes in v5:
> - support get property from extcon
> - remove PIN ASSIGN A/B support
>
> Changes in v4:
> - select EXTCON
> - use phy framework to control the USB3 and DP function
> - rename PIN_MAP_ to PIN_ASSIGN_
>
> Changes in v3:
> - remove the phy framework(Kishon Vijay Abraham I)
> - add parentheses around the macro
> - use a single space between type and name
> - add spaces after opening and before closing braces.
> - use u16 for register value
> - remove type-c phy header file
> - CodingStyle optimization
> - use some cable extcon to get type-c port information
> - add a extcon to notify Display Port
>
> Changes in v2:
> - select RESET_CONTROLLER
> - alphabetic order
> - modify some spelling mistakes
> - make mode cleaner
> - use bool for enable/disable
> - check all of the return value
> - return a better err number
> - use more readx_poll_timeout()
> - clk_disable_unprepare(tcphy->clk_ref);
> - remove unuse functions, rockchip_typec_phy_power_on/off
> - remove unnecessary typecast from void *
> - use dts node to distinguish between phys.
>
> Changes in v1:
> - update the licence note
> - init core clock to 50MHz
> - use extcon API
> - remove unused global
> - add some comments for magic num
> - change usleep_range(1000, 2000) tousleep_range(1000, 1050)
> - remove __func__ from dev_err
> - return err number when get clk failed
> - remove ADDR_ADJ define
> - use devm_clk_get(>dev, "tcpdcore")
>
>  drivers/phy/Kconfig  |   9 +
>  drivers/phy/Makefile |   1 +
>  drivers/phy/phy-rockchip-typec.c | 977 
> +++
>  3 files changed, 987 insertions(+)
>  create mode 100644 drivers/phy/phy-rockchip-typec.c
>
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index 42f3e30..c775fd7 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -348,6 +348,15 @@ config PHY_ROCKCHIP_PCIE
> help
>   Enable this to support the Rockchip PCIe PHY.
>
> +config PHY_ROCKCHIP_TYPEC
> +   tristate "Rockchip TYPEC PHY Driver"
> +   depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
> +   select EXTCON
> +   select GENERIC_PHY
> +   select RESET_CONTROLLER
> +   help
> + Enable this to support the Rockchip USB TYPEC PHY.
> +
>  config PHY_ST_SPEAR1310_MIPHY
> tristate "ST SPEAR1310-MIPHY driver"
> select GENERIC_PHY
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index fbb91e7..5d58b63 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -39,6 +39,7 @@ obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2)  += 
> phy-rockchip-inno-usb2.o
>  obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o
>  obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o
>  obj-$(CONFIG_PHY_ROCKCHIP_DP)  += phy-rockchip-dp.o
> +obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o
>  obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA)+= phy-qcom-ipq806x-sata.o
>  obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY)   += phy-spear1310-miphy.o
>  obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY)   += phy-spear1340-miphy.o
> diff --git a/drivers/phy/phy-rockchip-typec.c 
> b/drivers/phy/phy-rockchip-typec.c
> new file mode 100644
> index 000..6edeae6
> --- /dev/null
> +++ b/drivers/phy/phy-rockchip-typec.c
> @@ -0,0 +1,977 @@
> +/*
> + * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
> + * Author: Chris Zhong 
> + * Kever Yang 
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, 

acpi: out-of-bounds access in acpi_ds_create_operand

2016-08-21 Thread Dmitry Vyukov
Hello,

I am booting a kernel with CONFIG_UBSAN and during boot I see the
following error message:


UBSAN: Undefined behaviour in drivers/acpi/acpica/dsutils.c:641:16
index -1 is out of range for type 'acpi_operand_object *[9]'
CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.8.0-rc2+ #13
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
  88006bcd7308 81db32c0 41b58ab3
 83e0a194 81db31c0 88006bcd7330 88006bcd72d0
  85181560 0001 88006bcd7398
Call Trace:
 [< inline >] __dump_stack lib/dump_stack.c:15
 [] dump_stack+0x100/0x180 lib/dump_stack.c:51
 [] ubsan_epilogue+0x12/0x8f lib/ubsan.c:164
 [] __ubsan_handle_out_of_bounds+0x164/0x19c lib/ubsan.c:382
 [] acpi_ds_create_operand+0x6d9/0x7fa
drivers/acpi/acpica/dsutils.c:641
 [] acpi_ds_create_operands+0x2f2/0x37c
drivers/acpi/acpica/dsutils.c:751
 [] acpi_ds_exec_end_op+0x941/0xed4
drivers/acpi/acpica/dswexec.c:529
 [] acpi_ps_parse_loop+0x156a/0x1620
drivers/acpi/acpica/psloop.c:609
 [] acpi_ps_parse_aml+0x266/0x83a
drivers/acpi/acpica/psparse.c:508
 [] acpi_ps_execute_method+0x58c/0x5fb
drivers/acpi/acpica/psxface.c:221
 [] acpi_ns_evaluate+0x706/0x91f
drivers/acpi/acpica/nseval.c:238
 [] acpi_evaluate_object+0x3dd/0x7e7
drivers/acpi/acpica/nsxfeval.c:366
 [< inline >] map_mat_entry drivers/acpi/processor_core.c:173
 [] acpi_get_phys_id+0xbb/0x5be
drivers/acpi/processor_core.c:204
 [] acpi_get_cpuid+0x25/0x33 drivers/acpi/processor_core.c:261
 [< inline >] processor_physically_present
drivers/acpi/processor_pdc.c:53
 [] early_init_pdc+0x156/0x198
drivers/acpi/processor_pdc.c:161
 [] acpi_ns_walk_namespace+0x216/0x38f
drivers/acpi/acpica/nswalk.c:270
 [] acpi_walk_namespace+0xb5/0xef
drivers/acpi/acpica/nsxfeval.c:618
 [] acpi_early_processor_set_pdc+0x35/0x4f
drivers/acpi/processor_pdc.c:199
 [< inline >] acpi_bus_init drivers/acpi/bus.c:1116
 [] acpi_init+0x339/0x61e drivers/acpi/bus.c:1182
 [] do_one_initcall+0xb6/0x2b0 init/main.c:778
 [< inline >] do_initcall_level init/main.c:843
 [< inline >] do_initcalls init/main.c:851
 [< inline >] do_basic_setup init/main.c:869
 [] kernel_init_freeable+0x5d5/0x69c init/main.c:1016
 [] kernel_init+0x13/0x1b0 init/main.c:942
 [] ret_from_fork+0x1f/0x40 arch/x86/entry/entry_64.S:393



I am on 6040e57658eee6eb1315a26119101ca832d1f854 (Aug 19).
Config is defconfig+kvmconfig + the following configs (but that's
probably irrelevant):

CONFIG_KCOV=y
CONFIG_KCOV_INSTRUMENT_ALL=y
CONFIG_DEBUG_FS=y
CONFIG_DEBUG_INFO=y
CONFIG_KALLSYMS=y
CONFIG_KASAN=y
CONFIG_KASAN_INLINE=y
CONFIG_UBSAN=y
CONFIG_UBSAN_SANITIZE_ALL=y
CONFIG_DEBUG_KMEMLEAK=y
CONFIG_PROVE_RCU=y
CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y
CONFIG_LOCKUP_DETECTOR=y
CONFIG_BOOTPARAM_HARDLOCKUP_PANIC=y
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_WQ_WATCHDOG=y
CONFIG_PROVE_LOCKING=y
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_DEBUG_LIST=y
CONFIG_DEBUG_PI_LIST=y

I boot kernel as:
$ qemu-system-x86_64 -m 2048 -net nic -net user -display none -serial
stdio -no-reboot -enable-kvm -smp 2 -kernel arch/x86/boot/bzImage
-append "console=ttyS0 root=/dev/sda debug earlyprintk=serial
slub_debug=UZ rootfstype=9p root=/dev/root
rootflags=trans=virtio,version=9p2000.L,cache=loose
init=/init-syzkaller.sh" -fsdev
local,id=fsdev0,path=/,security_model=none -device
virtio-9p-pci,fsdev=fsdev0,mount_tag=/dev/root


acpi: out-of-bounds access in acpi_ds_create_operand

2016-08-21 Thread Dmitry Vyukov
Hello,

I am booting a kernel with CONFIG_UBSAN and during boot I see the
following error message:


UBSAN: Undefined behaviour in drivers/acpi/acpica/dsutils.c:641:16
index -1 is out of range for type 'acpi_operand_object *[9]'
CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.8.0-rc2+ #13
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
  88006bcd7308 81db32c0 41b58ab3
 83e0a194 81db31c0 88006bcd7330 88006bcd72d0
  85181560 0001 88006bcd7398
Call Trace:
 [< inline >] __dump_stack lib/dump_stack.c:15
 [] dump_stack+0x100/0x180 lib/dump_stack.c:51
 [] ubsan_epilogue+0x12/0x8f lib/ubsan.c:164
 [] __ubsan_handle_out_of_bounds+0x164/0x19c lib/ubsan.c:382
 [] acpi_ds_create_operand+0x6d9/0x7fa
drivers/acpi/acpica/dsutils.c:641
 [] acpi_ds_create_operands+0x2f2/0x37c
drivers/acpi/acpica/dsutils.c:751
 [] acpi_ds_exec_end_op+0x941/0xed4
drivers/acpi/acpica/dswexec.c:529
 [] acpi_ps_parse_loop+0x156a/0x1620
drivers/acpi/acpica/psloop.c:609
 [] acpi_ps_parse_aml+0x266/0x83a
drivers/acpi/acpica/psparse.c:508
 [] acpi_ps_execute_method+0x58c/0x5fb
drivers/acpi/acpica/psxface.c:221
 [] acpi_ns_evaluate+0x706/0x91f
drivers/acpi/acpica/nseval.c:238
 [] acpi_evaluate_object+0x3dd/0x7e7
drivers/acpi/acpica/nsxfeval.c:366
 [< inline >] map_mat_entry drivers/acpi/processor_core.c:173
 [] acpi_get_phys_id+0xbb/0x5be
drivers/acpi/processor_core.c:204
 [] acpi_get_cpuid+0x25/0x33 drivers/acpi/processor_core.c:261
 [< inline >] processor_physically_present
drivers/acpi/processor_pdc.c:53
 [] early_init_pdc+0x156/0x198
drivers/acpi/processor_pdc.c:161
 [] acpi_ns_walk_namespace+0x216/0x38f
drivers/acpi/acpica/nswalk.c:270
 [] acpi_walk_namespace+0xb5/0xef
drivers/acpi/acpica/nsxfeval.c:618
 [] acpi_early_processor_set_pdc+0x35/0x4f
drivers/acpi/processor_pdc.c:199
 [< inline >] acpi_bus_init drivers/acpi/bus.c:1116
 [] acpi_init+0x339/0x61e drivers/acpi/bus.c:1182
 [] do_one_initcall+0xb6/0x2b0 init/main.c:778
 [< inline >] do_initcall_level init/main.c:843
 [< inline >] do_initcalls init/main.c:851
 [< inline >] do_basic_setup init/main.c:869
 [] kernel_init_freeable+0x5d5/0x69c init/main.c:1016
 [] kernel_init+0x13/0x1b0 init/main.c:942
 [] ret_from_fork+0x1f/0x40 arch/x86/entry/entry_64.S:393



I am on 6040e57658eee6eb1315a26119101ca832d1f854 (Aug 19).
Config is defconfig+kvmconfig + the following configs (but that's
probably irrelevant):

CONFIG_KCOV=y
CONFIG_KCOV_INSTRUMENT_ALL=y
CONFIG_DEBUG_FS=y
CONFIG_DEBUG_INFO=y
CONFIG_KALLSYMS=y
CONFIG_KASAN=y
CONFIG_KASAN_INLINE=y
CONFIG_UBSAN=y
CONFIG_UBSAN_SANITIZE_ALL=y
CONFIG_DEBUG_KMEMLEAK=y
CONFIG_PROVE_RCU=y
CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y
CONFIG_LOCKUP_DETECTOR=y
CONFIG_BOOTPARAM_HARDLOCKUP_PANIC=y
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_WQ_WATCHDOG=y
CONFIG_PROVE_LOCKING=y
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_DEBUG_LIST=y
CONFIG_DEBUG_PI_LIST=y

I boot kernel as:
$ qemu-system-x86_64 -m 2048 -net nic -net user -display none -serial
stdio -no-reboot -enable-kvm -smp 2 -kernel arch/x86/boot/bzImage
-append "console=ttyS0 root=/dev/sda debug earlyprintk=serial
slub_debug=UZ rootfstype=9p root=/dev/root
rootflags=trans=virtio,version=9p2000.L,cache=loose
init=/init-syzkaller.sh" -fsdev
local,id=fsdev0,path=/,security_model=none -device
virtio-9p-pci,fsdev=fsdev0,mount_tag=/dev/root


[PATCH] rtl8712: pwrctrl_priv: Replace semaphore lock with mutex

2016-08-21 Thread Binoy Jayan
The semaphore 'lock' in 'pwrctrl_priv' is used as a simple mutex, so it
should be written as one. Semaphores are going away in the future.
_enter_pwrlock was using down_interruptible(), so the lock could be broken
by sending a signal. This could be a bug, because nothing checks the return
code here. Hence, using mutex_lock instead of the interruptible version.
Removing the now unused _enter_pwrlock and _down_sema.

Signed-off-by: Binoy Jayan 
Reviewed-by: Arnd Bergmann 
Tested-by: Larry Finger 
---
 drivers/staging/rtl8712/osdep_service.h   |  7 ---
 drivers/staging/rtl8712/rtl8712_cmd.c | 10 +-
 drivers/staging/rtl8712/rtl871x_pwrctrl.c | 22 +++---
 drivers/staging/rtl8712/rtl871x_pwrctrl.h |  7 +--
 4 files changed, 17 insertions(+), 29 deletions(-)

diff --git a/drivers/staging/rtl8712/osdep_service.h 
b/drivers/staging/rtl8712/osdep_service.h
index ad041c9..c9ea50d 100644
--- a/drivers/staging/rtl8712/osdep_service.h
+++ b/drivers/staging/rtl8712/osdep_service.h
@@ -57,13 +57,6 @@ struct   __queue {
spin_lock_init(&((pqueue)->lock));  \
} while (0)
 
-static inline u32 _down_sema(struct semaphore *sema)
-{
-   if (down_interruptible(sema))
-   return _FAIL;
-   return _SUCCESS;
-}
-
 static inline u32 end_of_queue_search(struct list_head *head,
struct list_head *plist)
 {
diff --git a/drivers/staging/rtl8712/rtl8712_cmd.c 
b/drivers/staging/rtl8712/rtl8712_cmd.c
index 3877fcf..9f61583 100644
--- a/drivers/staging/rtl8712/rtl8712_cmd.c
+++ b/drivers/staging/rtl8712/rtl8712_cmd.c
@@ -264,9 +264,9 @@ static struct cmd_obj *cmd_hdl_filter(struct _adapter 
*padapter,
 */
if (padapter->pwrctrlpriv.pwr_mode > PS_MODE_ACTIVE) {
padapter->pwrctrlpriv.pwr_mode = PS_MODE_ACTIVE;
-   _enter_pwrlock(&(padapter->pwrctrlpriv.lock));
+   mutex_lock(>pwrctrlpriv.mutex_lock);
r8712_set_rpwm(padapter, PS_STATE_S4);
-   up(&(padapter->pwrctrlpriv.lock));
+   mutex_unlock(>pwrctrlpriv.mutex_lock);
}
pcmd_r = pcmd;
break;
@@ -395,10 +395,10 @@ _next:
}
if (pcmd->cmdcode == GEN_CMD_CODE(_SetPwrMode)) {
if (padapter->pwrctrlpriv.bSleep) {
-   _enter_pwrlock(&(padapter->
-  pwrctrlpriv.lock));
+   mutex_lock(>
+  pwrctrlpriv.mutex_lock);
r8712_set_rpwm(padapter, PS_STATE_S2);
-   up(>pwrctrlpriv.lock);
+   
mutex_unlock(>pwrctrlpriv.mutex_lock);
}
}
r8712_free_cmd_obj(pcmd);
diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.c 
b/drivers/staging/rtl8712/rtl871x_pwrctrl.c
index 98a5e74..8d7ead6 100644
--- a/drivers/staging/rtl8712/rtl871x_pwrctrl.c
+++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.c
@@ -103,14 +103,14 @@ void r8712_cpwm_int_hdl(struct _adapter *padapter,
if (pwrpriv->cpwm_tog == ((preportpwrstate->state) & 0x80))
return;
del_timer(>pwrctrlpriv.rpwm_check_timer);
-   _enter_pwrlock(>lock);
+   mutex_lock(>mutex_lock);
pwrpriv->cpwm = (preportpwrstate->state) & 0xf;
if (pwrpriv->cpwm >= PS_STATE_S2) {
if (pwrpriv->alives & CMD_ALIVE)
complete(&(pcmdpriv->cmd_queue_comp));
}
pwrpriv->cpwm_tog = (preportpwrstate->state) & 0x80;
-   up(>lock);
+   mutex_unlock(>mutex_lock);
 }
 
 static inline void register_task_alive(struct pwrctrl_priv *pwrctrl, uint tag)
@@ -141,10 +141,10 @@ static void SetPSModeWorkItemCallback(struct work_struct 
*work)
struct _adapter *padapter = container_of(pwrpriv,
struct _adapter, pwrctrlpriv);
if (!pwrpriv->bSleep) {
-   _enter_pwrlock(>lock);
+   mutex_lock(>mutex_lock);
if (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
r8712_set_rpwm(padapter, PS_STATE_S4);
-   up(>lock);
+   mutex_lock(>mutex_lock);
}
 }
 
@@ -155,11 +155,11 @@ static void rpwm_workitem_callback(struct work_struct 
*work)
struct _adapter *padapter = container_of(pwrpriv,
struct _adapter, pwrctrlpriv);
if (pwrpriv->cpwm != pwrpriv->rpwm) {
-   _enter_pwrlock(>lock);
+   mutex_lock(>mutex_lock);
r8712_read8(padapter, SDIO_HCPWM);
pwrpriv->rpwm_retry = 

[PATCH] rtl8712: pwrctrl_priv: Replace semaphore lock with mutex

2016-08-21 Thread Binoy Jayan
The semaphore 'lock' in 'pwrctrl_priv' is used as a simple mutex, so it
should be written as one. Semaphores are going away in the future.
_enter_pwrlock was using down_interruptible(), so the lock could be broken
by sending a signal. This could be a bug, because nothing checks the return
code here. Hence, using mutex_lock instead of the interruptible version.
Removing the now unused _enter_pwrlock and _down_sema.

Signed-off-by: Binoy Jayan 
Reviewed-by: Arnd Bergmann 
Tested-by: Larry Finger 
---
 drivers/staging/rtl8712/osdep_service.h   |  7 ---
 drivers/staging/rtl8712/rtl8712_cmd.c | 10 +-
 drivers/staging/rtl8712/rtl871x_pwrctrl.c | 22 +++---
 drivers/staging/rtl8712/rtl871x_pwrctrl.h |  7 +--
 4 files changed, 17 insertions(+), 29 deletions(-)

diff --git a/drivers/staging/rtl8712/osdep_service.h 
b/drivers/staging/rtl8712/osdep_service.h
index ad041c9..c9ea50d 100644
--- a/drivers/staging/rtl8712/osdep_service.h
+++ b/drivers/staging/rtl8712/osdep_service.h
@@ -57,13 +57,6 @@ struct   __queue {
spin_lock_init(&((pqueue)->lock));  \
} while (0)
 
-static inline u32 _down_sema(struct semaphore *sema)
-{
-   if (down_interruptible(sema))
-   return _FAIL;
-   return _SUCCESS;
-}
-
 static inline u32 end_of_queue_search(struct list_head *head,
struct list_head *plist)
 {
diff --git a/drivers/staging/rtl8712/rtl8712_cmd.c 
b/drivers/staging/rtl8712/rtl8712_cmd.c
index 3877fcf..9f61583 100644
--- a/drivers/staging/rtl8712/rtl8712_cmd.c
+++ b/drivers/staging/rtl8712/rtl8712_cmd.c
@@ -264,9 +264,9 @@ static struct cmd_obj *cmd_hdl_filter(struct _adapter 
*padapter,
 */
if (padapter->pwrctrlpriv.pwr_mode > PS_MODE_ACTIVE) {
padapter->pwrctrlpriv.pwr_mode = PS_MODE_ACTIVE;
-   _enter_pwrlock(&(padapter->pwrctrlpriv.lock));
+   mutex_lock(>pwrctrlpriv.mutex_lock);
r8712_set_rpwm(padapter, PS_STATE_S4);
-   up(&(padapter->pwrctrlpriv.lock));
+   mutex_unlock(>pwrctrlpriv.mutex_lock);
}
pcmd_r = pcmd;
break;
@@ -395,10 +395,10 @@ _next:
}
if (pcmd->cmdcode == GEN_CMD_CODE(_SetPwrMode)) {
if (padapter->pwrctrlpriv.bSleep) {
-   _enter_pwrlock(&(padapter->
-  pwrctrlpriv.lock));
+   mutex_lock(>
+  pwrctrlpriv.mutex_lock);
r8712_set_rpwm(padapter, PS_STATE_S2);
-   up(>pwrctrlpriv.lock);
+   
mutex_unlock(>pwrctrlpriv.mutex_lock);
}
}
r8712_free_cmd_obj(pcmd);
diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.c 
b/drivers/staging/rtl8712/rtl871x_pwrctrl.c
index 98a5e74..8d7ead6 100644
--- a/drivers/staging/rtl8712/rtl871x_pwrctrl.c
+++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.c
@@ -103,14 +103,14 @@ void r8712_cpwm_int_hdl(struct _adapter *padapter,
if (pwrpriv->cpwm_tog == ((preportpwrstate->state) & 0x80))
return;
del_timer(>pwrctrlpriv.rpwm_check_timer);
-   _enter_pwrlock(>lock);
+   mutex_lock(>mutex_lock);
pwrpriv->cpwm = (preportpwrstate->state) & 0xf;
if (pwrpriv->cpwm >= PS_STATE_S2) {
if (pwrpriv->alives & CMD_ALIVE)
complete(&(pcmdpriv->cmd_queue_comp));
}
pwrpriv->cpwm_tog = (preportpwrstate->state) & 0x80;
-   up(>lock);
+   mutex_unlock(>mutex_lock);
 }
 
 static inline void register_task_alive(struct pwrctrl_priv *pwrctrl, uint tag)
@@ -141,10 +141,10 @@ static void SetPSModeWorkItemCallback(struct work_struct 
*work)
struct _adapter *padapter = container_of(pwrpriv,
struct _adapter, pwrctrlpriv);
if (!pwrpriv->bSleep) {
-   _enter_pwrlock(>lock);
+   mutex_lock(>mutex_lock);
if (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
r8712_set_rpwm(padapter, PS_STATE_S4);
-   up(>lock);
+   mutex_lock(>mutex_lock);
}
 }
 
@@ -155,11 +155,11 @@ static void rpwm_workitem_callback(struct work_struct 
*work)
struct _adapter *padapter = container_of(pwrpriv,
struct _adapter, pwrctrlpriv);
if (pwrpriv->cpwm != pwrpriv->rpwm) {
-   _enter_pwrlock(>lock);
+   mutex_lock(>mutex_lock);
r8712_read8(padapter, SDIO_HCPWM);
pwrpriv->rpwm_retry = 1;
r8712_set_rpwm(padapter, pwrpriv->rpwm);
- 

[PATCH 2/2] Migrate zone cache from RB-Tree to arrays of descriptors

2016-08-21 Thread Shaun Tancheff
Currently the RB-Tree zone cache is fast and flexible. It does
use a rather largish amount of ram. This model reduces the ram
required from 120 bytes per zone to 16 bytes per zone with a
moderate transformation of the blk_zone_lookup() api.

This model is predicated on the belief that most variations
on zoned media will follow a pattern of using collections of same
sized zones on a single device. Similar to the pattern of erase
blocks on flash devices being progressivly larger 16K, 64K, ...

The goal is to be able to build a descriptor which is both memory
efficient, performant, and flexible.

Signed-off-by: Shaun Tancheff 
---
 block/blk-core.c   |2 +-
 block/blk-sysfs.c  |   31 +-
 block/blk-zoned.c  |  103 +++--
 drivers/scsi/sd.c  |5 +-
 drivers/scsi/sd.h  |4 +-
 drivers/scsi/sd_zbc.c  | 1025 +++-
 include/linux/blkdev.h |   82 +++-
 7 files changed, 716 insertions(+), 536 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index 3a9caf7..3b084a8 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -727,7 +727,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, 
int node_id)
INIT_LIST_HEAD(>blkg_list);
 #endif
 #ifdef CONFIG_BLK_DEV_ZONED
-   q->zones = RB_ROOT;
+   q->zones = NULL;
 #endif
INIT_DELAYED_WORK(>delay_work, blk_delay_work);
 
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 43f441f..ecbd434 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -232,36 +232,7 @@ static ssize_t queue_max_hw_sectors_show(struct 
request_queue *q, char *page)
 #ifdef CONFIG_BLK_DEV_ZONED
 static ssize_t queue_zoned_show(struct request_queue *q, char *page)
 {
-   struct rb_node *node;
-   struct blk_zone *zone;
-   ssize_t offset = 0, end = 0;
-   size_t size = 0, num = 0;
-   enum blk_zone_type type = BLK_ZONE_TYPE_UNKNOWN;
-
-   for (node = rb_first(>zones); node; node = rb_next(node)) {
-   zone = rb_entry(node, struct blk_zone, node);
-   if (zone->type != type ||
-   zone->len != size ||
-   end != zone->start) {
-   if (size != 0)
-   offset += sprintf(page + offset, "%zu\n", num);
-   /* We can only store one page ... */
-   if (offset + 42 > PAGE_SIZE) {
-   offset += sprintf(page + offset, "...\n");
-   return offset;
-   }
-   size = zone->len;
-   type = zone->type;
-   offset += sprintf(page + offset, "%zu %zu %d ",
- zone->start, size, type);
-   num = 0;
-   end = zone->start + size;
-   } else
-   end += zone->len;
-   num++;
-   }
-   offset += sprintf(page + offset, "%zu\n", num);
-   return offset;
+   return sprintf(page, "%u\n", q->zones ? 1 : 0);
 }
 #endif
 
diff --git a/block/blk-zoned.c b/block/blk-zoned.c
index 975e863..338a1af 100644
--- a/block/blk-zoned.c
+++ b/block/blk-zoned.c
@@ -8,63 +8,84 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
-struct blk_zone *blk_lookup_zone(struct request_queue *q, sector_t lba)
+/**
+ * blk_lookup_zone() - Lookup zones
+ * @q: Request Queue
+ * @sector: Location to lookup
+ * @start: Pointer to starting location zone (OUT)
+ * @len: Pointer to length of zone (OUT)
+ * @lock: Pointer to spinlock of zones in owning descriptor (OUT)
+ */
+struct blk_zone *blk_lookup_zone(struct request_queue *q, sector_t sector,
+sector_t *start, sector_t *len,
+spinlock_t **lock)
 {
-   struct rb_root *root = >zones;
-   struct rb_node *node = root->rb_node;
+   int iter;
+   struct blk_zone *bzone = NULL;
+   struct zone_wps *zi = q->zones;
+
+   *start = 0;
+   *len = 0;
+   *lock = NULL;
+
+   if (!q->zones)
+   goto out;
 
-   while (node) {
-   struct blk_zone *zone = container_of(node, struct blk_zone,
-node);
+   for (iter = 0; iter < zi->wps_count; iter++) {
+   if (sector >= zi->wps[iter]->start_lba &&
+   sector <  zi->wps[iter]->last_lba) {
+   struct contiguous_wps *wp = zi->wps[iter];
+   u64 index = (sector - wp->start_lba) / wp->zone_size;
 
-   if (lba < zone->start)
-   node = node->rb_left;
-   else if (lba >= zone->start + zone->len)
-   node = node->rb_right;
-   else
-   return zone;
+   if (index >= wp->zone_count) {
+   WARN(1, "Impossible 

[PATCH 2/2] Migrate zone cache from RB-Tree to arrays of descriptors

2016-08-21 Thread Shaun Tancheff
Currently the RB-Tree zone cache is fast and flexible. It does
use a rather largish amount of ram. This model reduces the ram
required from 120 bytes per zone to 16 bytes per zone with a
moderate transformation of the blk_zone_lookup() api.

This model is predicated on the belief that most variations
on zoned media will follow a pattern of using collections of same
sized zones on a single device. Similar to the pattern of erase
blocks on flash devices being progressivly larger 16K, 64K, ...

The goal is to be able to build a descriptor which is both memory
efficient, performant, and flexible.

Signed-off-by: Shaun Tancheff 
---
 block/blk-core.c   |2 +-
 block/blk-sysfs.c  |   31 +-
 block/blk-zoned.c  |  103 +++--
 drivers/scsi/sd.c  |5 +-
 drivers/scsi/sd.h  |4 +-
 drivers/scsi/sd_zbc.c  | 1025 +++-
 include/linux/blkdev.h |   82 +++-
 7 files changed, 716 insertions(+), 536 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index 3a9caf7..3b084a8 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -727,7 +727,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, 
int node_id)
INIT_LIST_HEAD(>blkg_list);
 #endif
 #ifdef CONFIG_BLK_DEV_ZONED
-   q->zones = RB_ROOT;
+   q->zones = NULL;
 #endif
INIT_DELAYED_WORK(>delay_work, blk_delay_work);
 
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 43f441f..ecbd434 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -232,36 +232,7 @@ static ssize_t queue_max_hw_sectors_show(struct 
request_queue *q, char *page)
 #ifdef CONFIG_BLK_DEV_ZONED
 static ssize_t queue_zoned_show(struct request_queue *q, char *page)
 {
-   struct rb_node *node;
-   struct blk_zone *zone;
-   ssize_t offset = 0, end = 0;
-   size_t size = 0, num = 0;
-   enum blk_zone_type type = BLK_ZONE_TYPE_UNKNOWN;
-
-   for (node = rb_first(>zones); node; node = rb_next(node)) {
-   zone = rb_entry(node, struct blk_zone, node);
-   if (zone->type != type ||
-   zone->len != size ||
-   end != zone->start) {
-   if (size != 0)
-   offset += sprintf(page + offset, "%zu\n", num);
-   /* We can only store one page ... */
-   if (offset + 42 > PAGE_SIZE) {
-   offset += sprintf(page + offset, "...\n");
-   return offset;
-   }
-   size = zone->len;
-   type = zone->type;
-   offset += sprintf(page + offset, "%zu %zu %d ",
- zone->start, size, type);
-   num = 0;
-   end = zone->start + size;
-   } else
-   end += zone->len;
-   num++;
-   }
-   offset += sprintf(page + offset, "%zu\n", num);
-   return offset;
+   return sprintf(page, "%u\n", q->zones ? 1 : 0);
 }
 #endif
 
diff --git a/block/blk-zoned.c b/block/blk-zoned.c
index 975e863..338a1af 100644
--- a/block/blk-zoned.c
+++ b/block/blk-zoned.c
@@ -8,63 +8,84 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
-struct blk_zone *blk_lookup_zone(struct request_queue *q, sector_t lba)
+/**
+ * blk_lookup_zone() - Lookup zones
+ * @q: Request Queue
+ * @sector: Location to lookup
+ * @start: Pointer to starting location zone (OUT)
+ * @len: Pointer to length of zone (OUT)
+ * @lock: Pointer to spinlock of zones in owning descriptor (OUT)
+ */
+struct blk_zone *blk_lookup_zone(struct request_queue *q, sector_t sector,
+sector_t *start, sector_t *len,
+spinlock_t **lock)
 {
-   struct rb_root *root = >zones;
-   struct rb_node *node = root->rb_node;
+   int iter;
+   struct blk_zone *bzone = NULL;
+   struct zone_wps *zi = q->zones;
+
+   *start = 0;
+   *len = 0;
+   *lock = NULL;
+
+   if (!q->zones)
+   goto out;
 
-   while (node) {
-   struct blk_zone *zone = container_of(node, struct blk_zone,
-node);
+   for (iter = 0; iter < zi->wps_count; iter++) {
+   if (sector >= zi->wps[iter]->start_lba &&
+   sector <  zi->wps[iter]->last_lba) {
+   struct contiguous_wps *wp = zi->wps[iter];
+   u64 index = (sector - wp->start_lba) / wp->zone_size;
 
-   if (lba < zone->start)
-   node = node->rb_left;
-   else if (lba >= zone->start + zone->len)
-   node = node->rb_right;
-   else
-   return zone;
+   if (index >= wp->zone_count) {
+   WARN(1, "Impossible index for zone\n");
+

[PATCH 1/2] Move ZBC core setup to sd_zbc

2016-08-21 Thread Shaun Tancheff
Move the remaining ZBC specific code to sd_zbc.c

Signed-off-by: Shaun Tancheff 
---
 drivers/scsi/sd.c |  65 +--
 drivers/scsi/sd.h |  20 ++
 drivers/scsi/sd_zbc.c | 170 +++---
 3 files changed, 126 insertions(+), 129 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 9a649fa..f144df4 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -2244,68 +2244,6 @@ static int sd_read_protection_type(struct scsi_disk 
*sdkp, unsigned char *buffer
return ret;
 }
 
-static void sd_read_zones(struct scsi_disk *sdkp, unsigned char *buffer)
-{
-   int retval;
-   unsigned char *desc;
-   u32 rep_len;
-   u8 same;
-   u64 zone_len, lba;
-
-   if (sdkp->zoned != 1 && sdkp->device->type != TYPE_ZBC)
-   /*
-* Device managed or normal SCSI disk,
-* no special handling required
-*/
-   return;
-
-   retval = sd_zbc_report_zones(sdkp, buffer, SD_BUF_SIZE,
-0, ZBC_ZONE_REPORTING_OPTION_ALL, false);
-   if (retval < 0)
-   return;
-
-   rep_len = get_unaligned_be32([0]);
-   if (rep_len < 64) {
-   sd_printk(KERN_WARNING, sdkp,
- "REPORT ZONES report invalid length %u\n",
- rep_len);
-   return;
-   }
-
-   if (sdkp->rc_basis == 0) {
-   /* The max_lba field is the capacity of a zoned device */
-   lba = get_unaligned_be64([8]);
-   if (lba + 1 > sdkp->capacity) {
-   if (sdkp->first_scan)
-   sd_printk(KERN_WARNING, sdkp,
- "Changing capacity from %zu to Max 
LBA+1 %zu\n",
- sdkp->capacity, (sector_t) lba + 1);
-   sdkp->capacity = lba + 1;
-   }
-   }
-
-   /*
-* Adjust 'chunk_sectors' to the zone length if the device
-* supports equal zone sizes.
-*/
-   same = buffer[4] & 0xf;
-   if (same > 3) {
-   sd_printk(KERN_WARNING, sdkp,
- "REPORT ZONES SAME type %d not supported\n", same);
-   return;
-   }
-   /* Read the zone length from the first zone descriptor */
-   desc = [64];
-   zone_len = get_unaligned_be64([8]);
-   sdkp->unmap_alignment = zone_len;
-   sdkp->unmap_granularity = zone_len;
-   blk_queue_chunk_sectors(sdkp->disk->queue,
-   logical_to_sectors(sdkp->device, zone_len));
-
-   sd_zbc_setup(sdkp, zone_len, buffer, SD_BUF_SIZE);
-   sd_config_discard(sdkp, SD_ZBC_RESET_WP);
-}
-
 static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device 
*sdp,
struct scsi_sense_hdr *sshdr, int sense_valid,
int the_result)
@@ -2611,7 +2549,8 @@ got_data:
  sdkp->physical_block_size);
sdkp->device->sector_size = sector_size;
 
-   sd_read_zones(sdkp, buffer);
+   if (sd_zbc_config(sdkp, buffer, SD_BUF_SIZE))
+   sd_config_discard(sdkp, SD_ZBC_RESET_WP);
 
{
char cap_str_2[10], cap_str_10[10];
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index adbf3e0..fc766db 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -289,10 +289,6 @@ static inline void sd_dif_complete(struct scsi_cmnd *cmd, 
unsigned int a)
 #define SD_ZBC_WRITE_ERR   2
 
 #ifdef CONFIG_SCSI_ZBC
-
-extern int sd_zbc_report_zones(struct scsi_disk *, unsigned char *, int,
-  sector_t, enum zbc_zone_reporting_options, bool);
-extern int sd_zbc_setup(struct scsi_disk *, u64 zlen, char *buf, int buf_len);
 extern int sd_zbc_setup_zone_report_cmnd(struct scsi_cmnd *cmd, u8 rpt_opt);
 extern int sd_zbc_setup_zone_action(struct scsi_cmnd *cmd);
 extern int sd_zbc_setup_discard(struct scsi_cmnd *cmd);
@@ -303,23 +299,15 @@ extern void sd_zbc_uninit_command(struct scsi_cmnd *cmd);
 extern void sd_zbc_remove(struct scsi_disk *);
 extern void sd_zbc_reset_zones(struct scsi_disk *);
 extern void sd_zbc_update_zones(struct scsi_disk *, sector_t, int, int reason);
+extern bool sd_zbc_config(struct scsi_disk *, void *, size_t);
+
 extern unsigned int sd_zbc_discard_granularity(struct scsi_disk *sdkp);
 
 #else /* CONFIG_SCSI_ZBC */
 
-static inline int sd_zbc_report_zones(struct scsi_disk *sdkp,
- unsigned char *buf, int buf_len,
- sector_t start_sector,
- enum zbc_zone_reporting_options option,
- bool partial)
-{
-   return -EOPNOTSUPP;
-}
-
-static inline int sd_zbc_setup(struct scsi_disk *sdkp, u64 zlen,
- 

[PATCH 1/2] Move ZBC core setup to sd_zbc

2016-08-21 Thread Shaun Tancheff
Move the remaining ZBC specific code to sd_zbc.c

Signed-off-by: Shaun Tancheff 
---
 drivers/scsi/sd.c |  65 +--
 drivers/scsi/sd.h |  20 ++
 drivers/scsi/sd_zbc.c | 170 +++---
 3 files changed, 126 insertions(+), 129 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 9a649fa..f144df4 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -2244,68 +2244,6 @@ static int sd_read_protection_type(struct scsi_disk 
*sdkp, unsigned char *buffer
return ret;
 }
 
-static void sd_read_zones(struct scsi_disk *sdkp, unsigned char *buffer)
-{
-   int retval;
-   unsigned char *desc;
-   u32 rep_len;
-   u8 same;
-   u64 zone_len, lba;
-
-   if (sdkp->zoned != 1 && sdkp->device->type != TYPE_ZBC)
-   /*
-* Device managed or normal SCSI disk,
-* no special handling required
-*/
-   return;
-
-   retval = sd_zbc_report_zones(sdkp, buffer, SD_BUF_SIZE,
-0, ZBC_ZONE_REPORTING_OPTION_ALL, false);
-   if (retval < 0)
-   return;
-
-   rep_len = get_unaligned_be32([0]);
-   if (rep_len < 64) {
-   sd_printk(KERN_WARNING, sdkp,
- "REPORT ZONES report invalid length %u\n",
- rep_len);
-   return;
-   }
-
-   if (sdkp->rc_basis == 0) {
-   /* The max_lba field is the capacity of a zoned device */
-   lba = get_unaligned_be64([8]);
-   if (lba + 1 > sdkp->capacity) {
-   if (sdkp->first_scan)
-   sd_printk(KERN_WARNING, sdkp,
- "Changing capacity from %zu to Max 
LBA+1 %zu\n",
- sdkp->capacity, (sector_t) lba + 1);
-   sdkp->capacity = lba + 1;
-   }
-   }
-
-   /*
-* Adjust 'chunk_sectors' to the zone length if the device
-* supports equal zone sizes.
-*/
-   same = buffer[4] & 0xf;
-   if (same > 3) {
-   sd_printk(KERN_WARNING, sdkp,
- "REPORT ZONES SAME type %d not supported\n", same);
-   return;
-   }
-   /* Read the zone length from the first zone descriptor */
-   desc = [64];
-   zone_len = get_unaligned_be64([8]);
-   sdkp->unmap_alignment = zone_len;
-   sdkp->unmap_granularity = zone_len;
-   blk_queue_chunk_sectors(sdkp->disk->queue,
-   logical_to_sectors(sdkp->device, zone_len));
-
-   sd_zbc_setup(sdkp, zone_len, buffer, SD_BUF_SIZE);
-   sd_config_discard(sdkp, SD_ZBC_RESET_WP);
-}
-
 static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device 
*sdp,
struct scsi_sense_hdr *sshdr, int sense_valid,
int the_result)
@@ -2611,7 +2549,8 @@ got_data:
  sdkp->physical_block_size);
sdkp->device->sector_size = sector_size;
 
-   sd_read_zones(sdkp, buffer);
+   if (sd_zbc_config(sdkp, buffer, SD_BUF_SIZE))
+   sd_config_discard(sdkp, SD_ZBC_RESET_WP);
 
{
char cap_str_2[10], cap_str_10[10];
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index adbf3e0..fc766db 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -289,10 +289,6 @@ static inline void sd_dif_complete(struct scsi_cmnd *cmd, 
unsigned int a)
 #define SD_ZBC_WRITE_ERR   2
 
 #ifdef CONFIG_SCSI_ZBC
-
-extern int sd_zbc_report_zones(struct scsi_disk *, unsigned char *, int,
-  sector_t, enum zbc_zone_reporting_options, bool);
-extern int sd_zbc_setup(struct scsi_disk *, u64 zlen, char *buf, int buf_len);
 extern int sd_zbc_setup_zone_report_cmnd(struct scsi_cmnd *cmd, u8 rpt_opt);
 extern int sd_zbc_setup_zone_action(struct scsi_cmnd *cmd);
 extern int sd_zbc_setup_discard(struct scsi_cmnd *cmd);
@@ -303,23 +299,15 @@ extern void sd_zbc_uninit_command(struct scsi_cmnd *cmd);
 extern void sd_zbc_remove(struct scsi_disk *);
 extern void sd_zbc_reset_zones(struct scsi_disk *);
 extern void sd_zbc_update_zones(struct scsi_disk *, sector_t, int, int reason);
+extern bool sd_zbc_config(struct scsi_disk *, void *, size_t);
+
 extern unsigned int sd_zbc_discard_granularity(struct scsi_disk *sdkp);
 
 #else /* CONFIG_SCSI_ZBC */
 
-static inline int sd_zbc_report_zones(struct scsi_disk *sdkp,
- unsigned char *buf, int buf_len,
- sector_t start_sector,
- enum zbc_zone_reporting_options option,
- bool partial)
-{
-   return -EOPNOTSUPP;
-}
-
-static inline int sd_zbc_setup(struct scsi_disk *sdkp, u64 zlen,
-  unsigned char *buf, int 

[PATCH 0/2] Change zone cache format to use less memory

2016-08-21 Thread Shaun Tancheff
Currently the RB-Tree zone cache is fast and flexible. It does
use a rather largish amount of ram. This model reduces the ram
required from 120 bytes per zone to 16 bytes per zone with a
moderate transformation of the blk_zone_lookup() api.

This model is predicated on the belief that most variations
on zoned media will follow a pattern of using collections of same
sized zones on a single device. Similar to the pattern of erase
blocks on flash devices being progressivly larger 16K, 64K, ...

The goal is to be able to build a descriptor which is both memory
efficient, performant, and flexible.

Shaun Tancheff (2):
  Move ZBC core setup to sd_zbc
  Migrate zone cache from RB-Tree to arrays of descriptors

 block/blk-core.c   |2 +-
 block/blk-sysfs.c  |   31 +-
 block/blk-zoned.c  |  103 +++--
 drivers/scsi/sd.c  |   66 +--
 drivers/scsi/sd.h  |   20 +-
 drivers/scsi/sd_zbc.c  | 1037 +---
 include/linux/blkdev.h |   82 +++-
 7 files changed, 759 insertions(+), 582 deletions(-)

-- 
2.9.3



[PATCH 0/2] Change zone cache format to use less memory

2016-08-21 Thread Shaun Tancheff
Currently the RB-Tree zone cache is fast and flexible. It does
use a rather largish amount of ram. This model reduces the ram
required from 120 bytes per zone to 16 bytes per zone with a
moderate transformation of the blk_zone_lookup() api.

This model is predicated on the belief that most variations
on zoned media will follow a pattern of using collections of same
sized zones on a single device. Similar to the pattern of erase
blocks on flash devices being progressivly larger 16K, 64K, ...

The goal is to be able to build a descriptor which is both memory
efficient, performant, and flexible.

Shaun Tancheff (2):
  Move ZBC core setup to sd_zbc
  Migrate zone cache from RB-Tree to arrays of descriptors

 block/blk-core.c   |2 +-
 block/blk-sysfs.c  |   31 +-
 block/blk-zoned.c  |  103 +++--
 drivers/scsi/sd.c  |   66 +--
 drivers/scsi/sd.h  |   20 +-
 drivers/scsi/sd_zbc.c  | 1037 +---
 include/linux/blkdev.h |   82 +++-
 7 files changed, 759 insertions(+), 582 deletions(-)

-- 
2.9.3



[PATCH v2 4/4] Integrate ZBC command requests with zone cache.

2016-08-21 Thread Shaun Tancheff
Block layer (bio/request) commands can use or update the
sd_zbc zone cache as appropriate for each command.

Report Zones [REQ_OP_ZONE_REPORT] by default uses the current
zone cache data to generate a device (ZBC spec) formatted response.
REQ_META can also be specified to force the command to the device
and the result will be used to refresh the zone cache.

Reset WP [REQ_OP_ZONE_RESET] by default will attempt to translate
the request into a discard following the SD_ZBC_RESET_WP provisioning
mode. REQ_META can also be specified to force the command to be sent
to the device.

Open, Close and Finish zones having no other analog are sent directly
to the device.

On successful completion each zone action will update the zone cache
as appropriate.

Signed-off-by: Shaun Tancheff 
---
 block/blk-lib.c   |  16 --
 drivers/scsi/sd.c |  42 +++-
 drivers/scsi/sd.h |  22 +-
 drivers/scsi/sd_zbc.c | 672 +++---
 4 files changed, 698 insertions(+), 54 deletions(-)

diff --git a/block/blk-lib.c b/block/blk-lib.c
index 67b9258..8cc5893 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -307,22 +307,6 @@ int blkdev_issue_zone_report(struct block_device *bdev, 
unsigned int op_flags,
bio_set_op_attrs(bio, REQ_OP_ZONE_REPORT, op_flags);
ret = submit_bio_wait(bio);
 
-   /*
-* When our request it nak'd the underlying device maybe conventional
-* so ... report a single conventional zone the size of the device.
-*/
-   if (ret == -EIO && conv->descriptor_count) {
-   /* Adjust the conventional to the size of the partition ... */
-   __be64 blksz = cpu_to_be64(bdev->bd_part->nr_sects);
-
-   conv->maximum_lba = blksz;
-   conv->descriptors[0].type = BLK_ZONE_TYPE_CONVENTIONAL;
-   conv->descriptors[0].flags = BLK_ZONE_NO_WP << 4;
-   conv->descriptors[0].length = blksz;
-   conv->descriptors[0].lba_start = 0;
-   conv->descriptors[0].lba_wptr = blksz;
-   ret = 0;
-   }
bio_put(bio);
return ret;
 }
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index b76ffbb..9a649fa 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1181,9 +1181,10 @@ static int sd_setup_zone_report_cmnd(struct scsi_cmnd 
*cmd)
struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
struct bio *bio = rq->bio;
sector_t sector = blk_rq_pos(rq);
-   struct gendisk *disk = rq->rq_disk;
unsigned int nr_bytes = blk_rq_bytes(rq);
int ret = BLKPREP_KILL;
+   bool is_fua = (rq->cmd_flags & REQ_META) ? true : false;
+   u8 rpt_opt = ZBC_ZONE_REPORTING_OPTION_ALL;
 
WARN_ON(nr_bytes == 0);
 
@@ -1194,18 +1195,35 @@ static int sd_setup_zone_report_cmnd(struct scsi_cmnd 
*cmd)
if (sdkp->zoned != 1 && sdkp->device->type != TYPE_ZBC) {
void *src;
struct bdev_zone_report *conv;
+   __be64 blksz = cpu_to_be64(sdkp->capacity);
 
-   if (nr_bytes < sizeof(struct bdev_zone_report))
+   if (nr_bytes < 512)
goto out;
 
src = kmap_atomic(bio->bi_io_vec->bv_page);
conv = src + bio->bi_io_vec->bv_offset;
conv->descriptor_count = cpu_to_be32(1);
conv->same_field = BLK_ZONE_SAME_ALL;
-   conv->maximum_lba = cpu_to_be64(disk->part0.nr_sects);
+   conv->maximum_lba = blksz;
+   conv->descriptors[0].type = BLK_ZONE_TYPE_CONVENTIONAL;
+   conv->descriptors[0].flags = BLK_ZONE_NO_WP << 4;
+   conv->descriptors[0].length = blksz;
+   conv->descriptors[0].lba_start = 0;
+   conv->descriptors[0].lba_wptr = blksz;
kunmap_atomic(src);
+   ret = BLKPREP_DONE;
goto out;
}
+   /* FUTURE ... when streamid is available */
+   /* rpt_opt = bio_get_streamid(bio); */
+
+   if (!is_fua) {
+   ret = sd_zbc_setup_zone_report_cmnd(cmd, rpt_opt);
+   if (ret == BLKPREP_DONE || ret == BLKPREP_DEFER)
+   goto out;
+   if (ret == BLKPREP_KILL)
+   pr_err("No Zone Cache, query media.\n");
+   }
 
ret = scsi_init_io(cmd);
if (ret != BLKPREP_OK)
@@ -1224,8 +1242,7 @@ static int sd_setup_zone_report_cmnd(struct scsi_cmnd 
*cmd)
cmd->cmnd[1] = ZI_REPORT_ZONES;
put_unaligned_be64(sector, >cmnd[2]);
put_unaligned_be32(nr_bytes, >cmnd[10]);
-   /* FUTURE ... when streamid is available */
-   /* cmd->cmnd[14] = bio_get_streamid(bio); */
+   cmd->cmnd[14] = rpt_opt;
 
cmd->sc_data_direction = DMA_FROM_DEVICE;
cmd->sdb.length = nr_bytes;
@@ -1243,11 +1260,22 @@ static int sd_setup_zone_action_cmnd(struct scsi_cmnd 
*cmd)
struct scsi_disk *sdkp 

[PATCH v2 4/4] Integrate ZBC command requests with zone cache.

2016-08-21 Thread Shaun Tancheff
Block layer (bio/request) commands can use or update the
sd_zbc zone cache as appropriate for each command.

Report Zones [REQ_OP_ZONE_REPORT] by default uses the current
zone cache data to generate a device (ZBC spec) formatted response.
REQ_META can also be specified to force the command to the device
and the result will be used to refresh the zone cache.

Reset WP [REQ_OP_ZONE_RESET] by default will attempt to translate
the request into a discard following the SD_ZBC_RESET_WP provisioning
mode. REQ_META can also be specified to force the command to be sent
to the device.

Open, Close and Finish zones having no other analog are sent directly
to the device.

On successful completion each zone action will update the zone cache
as appropriate.

Signed-off-by: Shaun Tancheff 
---
 block/blk-lib.c   |  16 --
 drivers/scsi/sd.c |  42 +++-
 drivers/scsi/sd.h |  22 +-
 drivers/scsi/sd_zbc.c | 672 +++---
 4 files changed, 698 insertions(+), 54 deletions(-)

diff --git a/block/blk-lib.c b/block/blk-lib.c
index 67b9258..8cc5893 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -307,22 +307,6 @@ int blkdev_issue_zone_report(struct block_device *bdev, 
unsigned int op_flags,
bio_set_op_attrs(bio, REQ_OP_ZONE_REPORT, op_flags);
ret = submit_bio_wait(bio);
 
-   /*
-* When our request it nak'd the underlying device maybe conventional
-* so ... report a single conventional zone the size of the device.
-*/
-   if (ret == -EIO && conv->descriptor_count) {
-   /* Adjust the conventional to the size of the partition ... */
-   __be64 blksz = cpu_to_be64(bdev->bd_part->nr_sects);
-
-   conv->maximum_lba = blksz;
-   conv->descriptors[0].type = BLK_ZONE_TYPE_CONVENTIONAL;
-   conv->descriptors[0].flags = BLK_ZONE_NO_WP << 4;
-   conv->descriptors[0].length = blksz;
-   conv->descriptors[0].lba_start = 0;
-   conv->descriptors[0].lba_wptr = blksz;
-   ret = 0;
-   }
bio_put(bio);
return ret;
 }
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index b76ffbb..9a649fa 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1181,9 +1181,10 @@ static int sd_setup_zone_report_cmnd(struct scsi_cmnd 
*cmd)
struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
struct bio *bio = rq->bio;
sector_t sector = blk_rq_pos(rq);
-   struct gendisk *disk = rq->rq_disk;
unsigned int nr_bytes = blk_rq_bytes(rq);
int ret = BLKPREP_KILL;
+   bool is_fua = (rq->cmd_flags & REQ_META) ? true : false;
+   u8 rpt_opt = ZBC_ZONE_REPORTING_OPTION_ALL;
 
WARN_ON(nr_bytes == 0);
 
@@ -1194,18 +1195,35 @@ static int sd_setup_zone_report_cmnd(struct scsi_cmnd 
*cmd)
if (sdkp->zoned != 1 && sdkp->device->type != TYPE_ZBC) {
void *src;
struct bdev_zone_report *conv;
+   __be64 blksz = cpu_to_be64(sdkp->capacity);
 
-   if (nr_bytes < sizeof(struct bdev_zone_report))
+   if (nr_bytes < 512)
goto out;
 
src = kmap_atomic(bio->bi_io_vec->bv_page);
conv = src + bio->bi_io_vec->bv_offset;
conv->descriptor_count = cpu_to_be32(1);
conv->same_field = BLK_ZONE_SAME_ALL;
-   conv->maximum_lba = cpu_to_be64(disk->part0.nr_sects);
+   conv->maximum_lba = blksz;
+   conv->descriptors[0].type = BLK_ZONE_TYPE_CONVENTIONAL;
+   conv->descriptors[0].flags = BLK_ZONE_NO_WP << 4;
+   conv->descriptors[0].length = blksz;
+   conv->descriptors[0].lba_start = 0;
+   conv->descriptors[0].lba_wptr = blksz;
kunmap_atomic(src);
+   ret = BLKPREP_DONE;
goto out;
}
+   /* FUTURE ... when streamid is available */
+   /* rpt_opt = bio_get_streamid(bio); */
+
+   if (!is_fua) {
+   ret = sd_zbc_setup_zone_report_cmnd(cmd, rpt_opt);
+   if (ret == BLKPREP_DONE || ret == BLKPREP_DEFER)
+   goto out;
+   if (ret == BLKPREP_KILL)
+   pr_err("No Zone Cache, query media.\n");
+   }
 
ret = scsi_init_io(cmd);
if (ret != BLKPREP_OK)
@@ -1224,8 +1242,7 @@ static int sd_setup_zone_report_cmnd(struct scsi_cmnd 
*cmd)
cmd->cmnd[1] = ZI_REPORT_ZONES;
put_unaligned_be64(sector, >cmnd[2]);
put_unaligned_be32(nr_bytes, >cmnd[10]);
-   /* FUTURE ... when streamid is available */
-   /* cmd->cmnd[14] = bio_get_streamid(bio); */
+   cmd->cmnd[14] = rpt_opt;
 
cmd->sc_data_direction = DMA_FROM_DEVICE;
cmd->sdb.length = nr_bytes;
@@ -1243,11 +1260,22 @@ static int sd_setup_zone_action_cmnd(struct scsi_cmnd 
*cmd)
struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
  

[PATCH v2 2/4] On Discard either do Reset WP or Write Same

2016-08-21 Thread Shaun Tancheff
Based on the type of zone either perform a Reset WP
for Sequential zones or a Write Same for Conventional zones.

Also detect and handle the runt zone, if there is one.

One additional check is added to error on discard requests
that do not include all the active data in zone.
By way of example when the WP indicates that 2000 blocks
in the zone are in use and the discard indicated 1000 blocks
can be unmapped the discard should fail as a Reset WP will
unmap all the 2000 blocks in the zone.

Signed-off-by: Shaun Tancheff 
---
 drivers/scsi/sd.c |  45 ++---
 drivers/scsi/sd.h |   9 ++--
 drivers/scsi/sd_zbc.c | 135 +++---
 3 files changed, 114 insertions(+), 75 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 7903e21..d5ef6d8 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -729,21 +729,19 @@ static int sd_setup_discard_cmnd(struct scsi_cmnd *cmd)
sector_t sector = blk_rq_pos(rq);
unsigned int nr_sectors = blk_rq_sectors(rq);
unsigned int nr_bytes = blk_rq_bytes(rq);
-   unsigned int len;
-   int ret = 0;
+   int ret;
char *buf;
-   struct page *page = NULL;
+   struct page *page;
 
sector >>= ilog2(sdp->sector_size) - 9;
nr_sectors >>= ilog2(sdp->sector_size) - 9;
 
-   if (sdkp->provisioning_mode != SD_ZBC_RESET_WP) {
-   page = alloc_page(GFP_ATOMIC | __GFP_ZERO);
-   if (!page)
-   return BLKPREP_DEFER;
-   }
+   page = alloc_page(GFP_ATOMIC | __GFP_ZERO);
+   if (!page)
+   return BLKPREP_DEFER;
 
rq->completion_data = page;
+   rq->timeout = SD_TIMEOUT;
 
switch (sdkp->provisioning_mode) {
case SD_LBP_UNMAP:
@@ -758,7 +756,7 @@ static int sd_setup_discard_cmnd(struct scsi_cmnd *cmd)
put_unaligned_be64(sector, [8]);
put_unaligned_be32(nr_sectors, [16]);
 
-   len = 24;
+   cmd->transfersize = 24;
break;
 
case SD_LBP_WS16:
@@ -768,7 +766,7 @@ static int sd_setup_discard_cmnd(struct scsi_cmnd *cmd)
put_unaligned_be64(sector, >cmnd[2]);
put_unaligned_be32(nr_sectors, >cmnd[10]);
 
-   len = sdkp->device->sector_size;
+   cmd->transfersize = sdp->sector_size;
break;
 
case SD_LBP_WS10:
@@ -777,35 +775,24 @@ static int sd_setup_discard_cmnd(struct scsi_cmnd *cmd)
cmd->cmnd[0] = WRITE_SAME;
if (sdkp->provisioning_mode == SD_LBP_WS10)
cmd->cmnd[1] = 0x8; /* UNMAP */
+   else
+   rq->timeout = SD_WRITE_SAME_TIMEOUT;
put_unaligned_be32(sector, >cmnd[2]);
put_unaligned_be16(nr_sectors, >cmnd[7]);
 
-   len = sdkp->device->sector_size;
+   cmd->transfersize = sdp->sector_size;
break;
 
case SD_ZBC_RESET_WP:
-   /* sd_zbc_setup_discard uses block layer sector units */
-   ret = sd_zbc_setup_discard(sdkp, rq, blk_rq_pos(rq),
-  blk_rq_sectors(rq));
+   ret = sd_zbc_setup_discard(cmd);
if (ret != BLKPREP_OK)
goto out;
-   cmd->cmd_len = 16;
-   cmd->cmnd[0] = ZBC_OUT;
-   cmd->cmnd[1] = ZO_RESET_WRITE_POINTER;
-   put_unaligned_be64(sector, >cmnd[2]);
-   /* Reset Write Pointer doesn't have a payload */
-   len = 0;
-   cmd->sc_data_direction = DMA_NONE;
break;
-
default:
ret = BLKPREP_INVALID;
goto out;
}
 
-   rq->timeout = SD_TIMEOUT;
-
-   cmd->transfersize = len;
cmd->allowed = SD_MAX_RETRIES;
 
/*
@@ -816,17 +803,15 @@ static int sd_setup_discard_cmnd(struct scsi_cmnd *cmd)
 * discarded on disk. This allows us to report completion on the full
 * amount of blocks described by the request.
 */
-   if (len) {
-   blk_add_request_payload(rq, page, 0, len);
+   if (cmd->transfersize) {
+   blk_add_request_payload(rq, page, 0, cmd->transfersize);
ret = scsi_init_io(cmd);
}
rq->__data_len = nr_bytes;
 
 out:
-   if (page && ret != BLKPREP_OK) {
-   rq->completion_data = NULL;
+   if (ret != BLKPREP_OK)
__free_page(page);
-   }
return ret;
 }
 
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index ef6c132..2792c10 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -295,8 +295,7 @@ extern int sd_zbc_report_zones(struct scsi_disk *, unsigned 
char *, int,
 extern int sd_zbc_setup(struct scsi_disk *, u64 zlen, char *buf, int buf_len);
 extern void sd_zbc_remove(struct scsi_disk *);
 

[PATCH v2 3/4] Merge ZBC constants

2016-08-21 Thread Shaun Tancheff
Dedupe ZBC/ZAC constants used for reporting options, same code,
zone condition and zone type.

These are all useful to programs consuming zone information from
user space as well so include them in a uapi header.

Signed-off-by: Shaun Tancheff 
---
 block/blk-lib.c   |   4 +-
 drivers/scsi/sd.c |   2 +-
 include/linux/blkdev.h|  20 -
 include/scsi/scsi_proto.h |  17 
 include/uapi/linux/blkzoned_api.h | 167 +++---
 5 files changed, 103 insertions(+), 107 deletions(-)

diff --git a/block/blk-lib.c b/block/blk-lib.c
index e92bd56..67b9258 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -316,8 +316,8 @@ int blkdev_issue_zone_report(struct block_device *bdev, 
unsigned int op_flags,
__be64 blksz = cpu_to_be64(bdev->bd_part->nr_sects);
 
conv->maximum_lba = blksz;
-   conv->descriptors[0].type = ZTYP_CONVENTIONAL;
-   conv->descriptors[0].flags = ZCOND_CONVENTIONAL << 4;
+   conv->descriptors[0].type = BLK_ZONE_TYPE_CONVENTIONAL;
+   conv->descriptors[0].flags = BLK_ZONE_NO_WP << 4;
conv->descriptors[0].length = blksz;
conv->descriptors[0].lba_start = 0;
conv->descriptors[0].lba_wptr = blksz;
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index d5ef6d8..b76ffbb 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1201,7 +1201,7 @@ static int sd_setup_zone_report_cmnd(struct scsi_cmnd 
*cmd)
src = kmap_atomic(bio->bi_io_vec->bv_page);
conv = src + bio->bi_io_vec->bv_offset;
conv->descriptor_count = cpu_to_be32(1);
-   conv->same_field = ZS_ALL_SAME;
+   conv->same_field = BLK_ZONE_SAME_ALL;
conv->maximum_lba = cpu_to_be64(disk->part0.nr_sects);
kunmap_atomic(src);
goto out;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 68198eb..d5cdb5d 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -263,26 +263,6 @@ struct blk_queue_tag {
 #define BLK_SCSI_CMD_PER_LONG  (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8))
 
 #ifdef CONFIG_BLK_DEV_ZONED
-enum blk_zone_type {
-   BLK_ZONE_TYPE_UNKNOWN,
-   BLK_ZONE_TYPE_CONVENTIONAL,
-   BLK_ZONE_TYPE_SEQWRITE_REQ,
-   BLK_ZONE_TYPE_SEQWRITE_PREF,
-   BLK_ZONE_TYPE_RESERVED,
-};
-
-enum blk_zone_state {
-   BLK_ZONE_NO_WP,
-   BLK_ZONE_EMPTY,
-   BLK_ZONE_OPEN,
-   BLK_ZONE_OPEN_EXPLICIT,
-   BLK_ZONE_CLOSED,
-   BLK_ZONE_UNKNOWN = 5,
-   BLK_ZONE_READONLY = 0xd,
-   BLK_ZONE_FULL,
-   BLK_ZONE_OFFLINE,
-   BLK_ZONE_BUSY = 0x20,
-};
 
 struct blk_zone {
struct rb_node node;
diff --git a/include/scsi/scsi_proto.h b/include/scsi/scsi_proto.h
index 6ba66e0..d1defd1 100644
--- a/include/scsi/scsi_proto.h
+++ b/include/scsi/scsi_proto.h
@@ -299,21 +299,4 @@ struct scsi_lun {
 #define SCSI_ACCESS_STATE_MASK0x0f
 #define SCSI_ACCESS_STATE_PREFERRED   0x80
 
-/* Reporting options for REPORT ZONES */
-enum zbc_zone_reporting_options {
-   ZBC_ZONE_REPORTING_OPTION_ALL = 0,
-   ZBC_ZONE_REPORTING_OPTION_EMPTY,
-   ZBC_ZONE_REPORTING_OPTION_IMPLICIT_OPEN,
-   ZBC_ZONE_REPORTING_OPTION_EXPLICIT_OPEN,
-   ZBC_ZONE_REPORTING_OPTION_CLOSED,
-   ZBC_ZONE_REPORTING_OPTION_FULL,
-   ZBC_ZONE_REPORTING_OPTION_READONLY,
-   ZBC_ZONE_REPORTING_OPTION_OFFLINE,
-   ZBC_ZONE_REPORTING_OPTION_NEED_RESET_WP = 0x10,
-   ZBC_ZONE_REPORTING_OPTION_NON_SEQWRITE,
-   ZBC_ZONE_REPORTING_OPTION_NON_WP = 0x3f,
-};
-
-#define ZBC_REPORT_ZONE_PARTIAL 0x80
-
 #endif /* _SCSI_PROTO_H_ */
diff --git a/include/uapi/linux/blkzoned_api.h 
b/include/uapi/linux/blkzoned_api.h
index cd81a9f..fa12976 100644
--- a/include/uapi/linux/blkzoned_api.h
+++ b/include/uapi/linux/blkzoned_api.h
@@ -16,97 +16,123 @@
 
 #include 
 
+#define ZBC_REPORT_OPTION_MASK  0x3f
+#define ZBC_REPORT_ZONE_PARTIAL 0x80
+
 /**
  * enum zone_report_option - Report Zones types to be included.
  *
- * @ZOPT_NON_SEQ_AND_RESET: Default (all zones).
- * @ZOPT_ZC1_EMPTY: Zones which are empty.
- * @ZOPT_ZC2_OPEN_IMPLICIT: Zones open but not explicitly opened
- * @ZOPT_ZC3_OPEN_EXPLICIT: Zones opened explicitly
- * @ZOPT_ZC4_CLOSED: Zones closed for writing.
- * @ZOPT_ZC5_FULL: Zones that are full.
- * @ZOPT_ZC6_READ_ONLY: Zones that are read-only
- * @ZOPT_ZC7_OFFLINE: Zones that are offline
- * @ZOPT_RESET: Zones that are empty
- * @ZOPT_NON_SEQ: Zones that have HA media-cache writes pending
- * @ZOPT_NON_WP_ZONES: Zones that do not have Write Pointers (conventional)
- * @ZOPT_PARTIAL_FLAG: Modifies the definition of the Zone List Length field.
+ * @ZBC_ZONE_REPORTING_OPTION_ALL: Default (all zones).
+ * @ZBC_ZONE_REPORTING_OPTION_EMPTY: Zones which are empty.
+ * @ZBC_ZONE_REPORTING_OPTION_IMPLICIT_OPEN:
+ * Zones open but not 

[PATCH v2 2/4] On Discard either do Reset WP or Write Same

2016-08-21 Thread Shaun Tancheff
Based on the type of zone either perform a Reset WP
for Sequential zones or a Write Same for Conventional zones.

Also detect and handle the runt zone, if there is one.

One additional check is added to error on discard requests
that do not include all the active data in zone.
By way of example when the WP indicates that 2000 blocks
in the zone are in use and the discard indicated 1000 blocks
can be unmapped the discard should fail as a Reset WP will
unmap all the 2000 blocks in the zone.

Signed-off-by: Shaun Tancheff 
---
 drivers/scsi/sd.c |  45 ++---
 drivers/scsi/sd.h |   9 ++--
 drivers/scsi/sd_zbc.c | 135 +++---
 3 files changed, 114 insertions(+), 75 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 7903e21..d5ef6d8 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -729,21 +729,19 @@ static int sd_setup_discard_cmnd(struct scsi_cmnd *cmd)
sector_t sector = blk_rq_pos(rq);
unsigned int nr_sectors = blk_rq_sectors(rq);
unsigned int nr_bytes = blk_rq_bytes(rq);
-   unsigned int len;
-   int ret = 0;
+   int ret;
char *buf;
-   struct page *page = NULL;
+   struct page *page;
 
sector >>= ilog2(sdp->sector_size) - 9;
nr_sectors >>= ilog2(sdp->sector_size) - 9;
 
-   if (sdkp->provisioning_mode != SD_ZBC_RESET_WP) {
-   page = alloc_page(GFP_ATOMIC | __GFP_ZERO);
-   if (!page)
-   return BLKPREP_DEFER;
-   }
+   page = alloc_page(GFP_ATOMIC | __GFP_ZERO);
+   if (!page)
+   return BLKPREP_DEFER;
 
rq->completion_data = page;
+   rq->timeout = SD_TIMEOUT;
 
switch (sdkp->provisioning_mode) {
case SD_LBP_UNMAP:
@@ -758,7 +756,7 @@ static int sd_setup_discard_cmnd(struct scsi_cmnd *cmd)
put_unaligned_be64(sector, [8]);
put_unaligned_be32(nr_sectors, [16]);
 
-   len = 24;
+   cmd->transfersize = 24;
break;
 
case SD_LBP_WS16:
@@ -768,7 +766,7 @@ static int sd_setup_discard_cmnd(struct scsi_cmnd *cmd)
put_unaligned_be64(sector, >cmnd[2]);
put_unaligned_be32(nr_sectors, >cmnd[10]);
 
-   len = sdkp->device->sector_size;
+   cmd->transfersize = sdp->sector_size;
break;
 
case SD_LBP_WS10:
@@ -777,35 +775,24 @@ static int sd_setup_discard_cmnd(struct scsi_cmnd *cmd)
cmd->cmnd[0] = WRITE_SAME;
if (sdkp->provisioning_mode == SD_LBP_WS10)
cmd->cmnd[1] = 0x8; /* UNMAP */
+   else
+   rq->timeout = SD_WRITE_SAME_TIMEOUT;
put_unaligned_be32(sector, >cmnd[2]);
put_unaligned_be16(nr_sectors, >cmnd[7]);
 
-   len = sdkp->device->sector_size;
+   cmd->transfersize = sdp->sector_size;
break;
 
case SD_ZBC_RESET_WP:
-   /* sd_zbc_setup_discard uses block layer sector units */
-   ret = sd_zbc_setup_discard(sdkp, rq, blk_rq_pos(rq),
-  blk_rq_sectors(rq));
+   ret = sd_zbc_setup_discard(cmd);
if (ret != BLKPREP_OK)
goto out;
-   cmd->cmd_len = 16;
-   cmd->cmnd[0] = ZBC_OUT;
-   cmd->cmnd[1] = ZO_RESET_WRITE_POINTER;
-   put_unaligned_be64(sector, >cmnd[2]);
-   /* Reset Write Pointer doesn't have a payload */
-   len = 0;
-   cmd->sc_data_direction = DMA_NONE;
break;
-
default:
ret = BLKPREP_INVALID;
goto out;
}
 
-   rq->timeout = SD_TIMEOUT;
-
-   cmd->transfersize = len;
cmd->allowed = SD_MAX_RETRIES;
 
/*
@@ -816,17 +803,15 @@ static int sd_setup_discard_cmnd(struct scsi_cmnd *cmd)
 * discarded on disk. This allows us to report completion on the full
 * amount of blocks described by the request.
 */
-   if (len) {
-   blk_add_request_payload(rq, page, 0, len);
+   if (cmd->transfersize) {
+   blk_add_request_payload(rq, page, 0, cmd->transfersize);
ret = scsi_init_io(cmd);
}
rq->__data_len = nr_bytes;
 
 out:
-   if (page && ret != BLKPREP_OK) {
-   rq->completion_data = NULL;
+   if (ret != BLKPREP_OK)
__free_page(page);
-   }
return ret;
 }
 
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index ef6c132..2792c10 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -295,8 +295,7 @@ extern int sd_zbc_report_zones(struct scsi_disk *, unsigned 
char *, int,
 extern int sd_zbc_setup(struct scsi_disk *, u64 zlen, char *buf, int buf_len);
 extern void sd_zbc_remove(struct scsi_disk *);
 extern void 

[PATCH v2 3/4] Merge ZBC constants

2016-08-21 Thread Shaun Tancheff
Dedupe ZBC/ZAC constants used for reporting options, same code,
zone condition and zone type.

These are all useful to programs consuming zone information from
user space as well so include them in a uapi header.

Signed-off-by: Shaun Tancheff 
---
 block/blk-lib.c   |   4 +-
 drivers/scsi/sd.c |   2 +-
 include/linux/blkdev.h|  20 -
 include/scsi/scsi_proto.h |  17 
 include/uapi/linux/blkzoned_api.h | 167 +++---
 5 files changed, 103 insertions(+), 107 deletions(-)

diff --git a/block/blk-lib.c b/block/blk-lib.c
index e92bd56..67b9258 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -316,8 +316,8 @@ int blkdev_issue_zone_report(struct block_device *bdev, 
unsigned int op_flags,
__be64 blksz = cpu_to_be64(bdev->bd_part->nr_sects);
 
conv->maximum_lba = blksz;
-   conv->descriptors[0].type = ZTYP_CONVENTIONAL;
-   conv->descriptors[0].flags = ZCOND_CONVENTIONAL << 4;
+   conv->descriptors[0].type = BLK_ZONE_TYPE_CONVENTIONAL;
+   conv->descriptors[0].flags = BLK_ZONE_NO_WP << 4;
conv->descriptors[0].length = blksz;
conv->descriptors[0].lba_start = 0;
conv->descriptors[0].lba_wptr = blksz;
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index d5ef6d8..b76ffbb 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1201,7 +1201,7 @@ static int sd_setup_zone_report_cmnd(struct scsi_cmnd 
*cmd)
src = kmap_atomic(bio->bi_io_vec->bv_page);
conv = src + bio->bi_io_vec->bv_offset;
conv->descriptor_count = cpu_to_be32(1);
-   conv->same_field = ZS_ALL_SAME;
+   conv->same_field = BLK_ZONE_SAME_ALL;
conv->maximum_lba = cpu_to_be64(disk->part0.nr_sects);
kunmap_atomic(src);
goto out;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 68198eb..d5cdb5d 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -263,26 +263,6 @@ struct blk_queue_tag {
 #define BLK_SCSI_CMD_PER_LONG  (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8))
 
 #ifdef CONFIG_BLK_DEV_ZONED
-enum blk_zone_type {
-   BLK_ZONE_TYPE_UNKNOWN,
-   BLK_ZONE_TYPE_CONVENTIONAL,
-   BLK_ZONE_TYPE_SEQWRITE_REQ,
-   BLK_ZONE_TYPE_SEQWRITE_PREF,
-   BLK_ZONE_TYPE_RESERVED,
-};
-
-enum blk_zone_state {
-   BLK_ZONE_NO_WP,
-   BLK_ZONE_EMPTY,
-   BLK_ZONE_OPEN,
-   BLK_ZONE_OPEN_EXPLICIT,
-   BLK_ZONE_CLOSED,
-   BLK_ZONE_UNKNOWN = 5,
-   BLK_ZONE_READONLY = 0xd,
-   BLK_ZONE_FULL,
-   BLK_ZONE_OFFLINE,
-   BLK_ZONE_BUSY = 0x20,
-};
 
 struct blk_zone {
struct rb_node node;
diff --git a/include/scsi/scsi_proto.h b/include/scsi/scsi_proto.h
index 6ba66e0..d1defd1 100644
--- a/include/scsi/scsi_proto.h
+++ b/include/scsi/scsi_proto.h
@@ -299,21 +299,4 @@ struct scsi_lun {
 #define SCSI_ACCESS_STATE_MASK0x0f
 #define SCSI_ACCESS_STATE_PREFERRED   0x80
 
-/* Reporting options for REPORT ZONES */
-enum zbc_zone_reporting_options {
-   ZBC_ZONE_REPORTING_OPTION_ALL = 0,
-   ZBC_ZONE_REPORTING_OPTION_EMPTY,
-   ZBC_ZONE_REPORTING_OPTION_IMPLICIT_OPEN,
-   ZBC_ZONE_REPORTING_OPTION_EXPLICIT_OPEN,
-   ZBC_ZONE_REPORTING_OPTION_CLOSED,
-   ZBC_ZONE_REPORTING_OPTION_FULL,
-   ZBC_ZONE_REPORTING_OPTION_READONLY,
-   ZBC_ZONE_REPORTING_OPTION_OFFLINE,
-   ZBC_ZONE_REPORTING_OPTION_NEED_RESET_WP = 0x10,
-   ZBC_ZONE_REPORTING_OPTION_NON_SEQWRITE,
-   ZBC_ZONE_REPORTING_OPTION_NON_WP = 0x3f,
-};
-
-#define ZBC_REPORT_ZONE_PARTIAL 0x80
-
 #endif /* _SCSI_PROTO_H_ */
diff --git a/include/uapi/linux/blkzoned_api.h 
b/include/uapi/linux/blkzoned_api.h
index cd81a9f..fa12976 100644
--- a/include/uapi/linux/blkzoned_api.h
+++ b/include/uapi/linux/blkzoned_api.h
@@ -16,97 +16,123 @@
 
 #include 
 
+#define ZBC_REPORT_OPTION_MASK  0x3f
+#define ZBC_REPORT_ZONE_PARTIAL 0x80
+
 /**
  * enum zone_report_option - Report Zones types to be included.
  *
- * @ZOPT_NON_SEQ_AND_RESET: Default (all zones).
- * @ZOPT_ZC1_EMPTY: Zones which are empty.
- * @ZOPT_ZC2_OPEN_IMPLICIT: Zones open but not explicitly opened
- * @ZOPT_ZC3_OPEN_EXPLICIT: Zones opened explicitly
- * @ZOPT_ZC4_CLOSED: Zones closed for writing.
- * @ZOPT_ZC5_FULL: Zones that are full.
- * @ZOPT_ZC6_READ_ONLY: Zones that are read-only
- * @ZOPT_ZC7_OFFLINE: Zones that are offline
- * @ZOPT_RESET: Zones that are empty
- * @ZOPT_NON_SEQ: Zones that have HA media-cache writes pending
- * @ZOPT_NON_WP_ZONES: Zones that do not have Write Pointers (conventional)
- * @ZOPT_PARTIAL_FLAG: Modifies the definition of the Zone List Length field.
+ * @ZBC_ZONE_REPORTING_OPTION_ALL: Default (all zones).
+ * @ZBC_ZONE_REPORTING_OPTION_EMPTY: Zones which are empty.
+ * @ZBC_ZONE_REPORTING_OPTION_IMPLICIT_OPEN:
+ * Zones open but not explicitly opened
+ * 

[PATCH v2 0/4] Integrate bio/request ZBC ops with zone cache

2016-08-21 Thread Shaun Tancheff
Hi,

As per Christoph's request this patch incorporates Hannes' cache of zone
information.

This approach is to have REQ_OP_ZONE_REPORT return data in the same
format regardless of the availability of the zone cache. So if the
is kernel being built with or without BLK_DEV_ZONED [and SCSI_ZBC]
users of blkdev_issue_zone_report() and/or REQ_OP_ZONE_REPORT bio's
will have a consistent data format to digest.

Additionally it seems reasonable to allow the REQ_OP_ZONE_* to
be able to indicate if the command *must* be delivered to the
device [and update the zone cache] accordingly. Here REQ_META is
being used as REQ_FUA can be dropped causing sd_done to be skipped.
Rather than special case the current code I chose to pick an otherwise
non-applicable flag.

This series is based off of Linus's v4.8-rc2 and builds on top of the
previous series of block layer support:
Add ioctl to issue ZBC/ZAC commands via block layer
Add bio/request flags to issue ZBC/ZAC commands
as well as the series posted by Hannes
sd_zbc: Fix handling of ZBC read after write pointer
sd: Limit messages for ZBC disks capacity change
sd: Implement support for ZBC devices
sd: Implement new RESET_WP provisioning mode
sd: configure ZBC devices
...

Patches for util-linux can be found here:
g...@github.com:stancheff/util-linux.git v2.28.1+biof

https://github.com/stancheff/util-linux/tree/v2.28.1%2Bbiof

This patch is available here:
https://github.com/stancheff/linux/tree/v4.8-rc2%2Bbiof.v9

g...@github.com:stancheff/linux.git v4.8-rc2+biof.v9

v2:
 - Fully integrated bio <-> zone cache [<-> device]
 - Added discard -> write same for conventional zones.
 - Merged disparate constants into a canonical set.

Shaun Tancheff (4):
  Enable support for Seagate HostAware drives (testing).
  On Discard either do Reset WP or Write Same
  Merge ZBC constants
  Integrate ZBC command requests with zone cache.

 block/blk-lib.c   |  16 -
 drivers/scsi/sd.c | 111 +++--
 drivers/scsi/sd.h |  49 ++-
 drivers/scsi/sd_zbc.c | 904 ++
 include/linux/blkdev.h|  22 +-
 include/scsi/scsi_proto.h |  17 -
 include/uapi/linux/blkzoned_api.h | 167 ---
 7 files changed, 1032 insertions(+), 254 deletions(-)

-- 
2.9.3



[PATCH v2 0/4] Integrate bio/request ZBC ops with zone cache

2016-08-21 Thread Shaun Tancheff
Hi,

As per Christoph's request this patch incorporates Hannes' cache of zone
information.

This approach is to have REQ_OP_ZONE_REPORT return data in the same
format regardless of the availability of the zone cache. So if the
is kernel being built with or without BLK_DEV_ZONED [and SCSI_ZBC]
users of blkdev_issue_zone_report() and/or REQ_OP_ZONE_REPORT bio's
will have a consistent data format to digest.

Additionally it seems reasonable to allow the REQ_OP_ZONE_* to
be able to indicate if the command *must* be delivered to the
device [and update the zone cache] accordingly. Here REQ_META is
being used as REQ_FUA can be dropped causing sd_done to be skipped.
Rather than special case the current code I chose to pick an otherwise
non-applicable flag.

This series is based off of Linus's v4.8-rc2 and builds on top of the
previous series of block layer support:
Add ioctl to issue ZBC/ZAC commands via block layer
Add bio/request flags to issue ZBC/ZAC commands
as well as the series posted by Hannes
sd_zbc: Fix handling of ZBC read after write pointer
sd: Limit messages for ZBC disks capacity change
sd: Implement support for ZBC devices
sd: Implement new RESET_WP provisioning mode
sd: configure ZBC devices
...

Patches for util-linux can be found here:
g...@github.com:stancheff/util-linux.git v2.28.1+biof

https://github.com/stancheff/util-linux/tree/v2.28.1%2Bbiof

This patch is available here:
https://github.com/stancheff/linux/tree/v4.8-rc2%2Bbiof.v9

g...@github.com:stancheff/linux.git v4.8-rc2+biof.v9

v2:
 - Fully integrated bio <-> zone cache [<-> device]
 - Added discard -> write same for conventional zones.
 - Merged disparate constants into a canonical set.

Shaun Tancheff (4):
  Enable support for Seagate HostAware drives (testing).
  On Discard either do Reset WP or Write Same
  Merge ZBC constants
  Integrate ZBC command requests with zone cache.

 block/blk-lib.c   |  16 -
 drivers/scsi/sd.c | 111 +++--
 drivers/scsi/sd.h |  49 ++-
 drivers/scsi/sd_zbc.c | 904 ++
 include/linux/blkdev.h|  22 +-
 include/scsi/scsi_proto.h |  17 -
 include/uapi/linux/blkzoned_api.h | 167 ---
 7 files changed, 1032 insertions(+), 254 deletions(-)

-- 
2.9.3



[PATCH v2 1/4] Enable support for Seagate HostAware drives

2016-08-21 Thread Shaun Tancheff
Seagate drives report a SAME code of 0 due to having:
  - Zones of different types (CMR zones at the low LBA space).
  - Zones of different size (A terminating 'runt' zone in the high
lba space).

Support loading the zone topology into the zone cache.

Signed-off-by: Shaun Tancheff 
---
 drivers/scsi/sd.c  |  22 +++---
 drivers/scsi/sd.h  |  20 --
 drivers/scsi/sd_zbc.c  | 183 +++--
 include/linux/blkdev.h |  16 +++--
 4 files changed, 170 insertions(+), 71 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 059a57f..7903e21 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -693,8 +693,13 @@ static void sd_config_discard(struct scsi_disk *sdkp, 
unsigned int mode)
break;
 
case SD_ZBC_RESET_WP:
-   max_blocks = sdkp->unmap_granularity;
q->limits.discard_zeroes_data = 1;
+   q->limits.discard_granularity =
+   sd_zbc_discard_granularity(sdkp);
+
+   max_blocks = min_not_zero(sdkp->unmap_granularity,
+ q->limits.discard_granularity >>
+   ilog2(logical_block_size));
break;
 
case SD_LBP_ZERO:
@@ -1955,13 +1960,12 @@ static int sd_done(struct scsi_cmnd *SCpnt)
good_bytes = blk_rq_bytes(req);
scsi_set_resid(SCpnt, 0);
} else {
-#ifdef CONFIG_SCSI_ZBC
if (op == ZBC_OUT)
/* RESET WRITE POINTER failed */
sd_zbc_update_zones(sdkp,
blk_rq_pos(req),
-   512, true);
-#endif
+   512, SD_ZBC_RESET_WP_ERR);
+
good_bytes = 0;
scsi_set_resid(SCpnt, blk_rq_bytes(req));
}
@@ -2034,7 +2038,6 @@ static int sd_done(struct scsi_cmnd *SCpnt)
good_bytes = blk_rq_bytes(req);
scsi_set_resid(SCpnt, 0);
}
-#ifdef CONFIG_SCSI_ZBC
/*
 * ZBC: Unaligned write command.
 * Write did not start a write pointer position.
@@ -2042,8 +2045,7 @@ static int sd_done(struct scsi_cmnd *SCpnt)
if (sshdr.ascq == 0x04)
sd_zbc_update_zones(sdkp,
blk_rq_pos(req),
-   512, true);
-#endif
+   512, SD_ZBC_WRITE_ERR);
}
break;
default:
@@ -2270,7 +2272,7 @@ static void sd_read_zones(struct scsi_disk *sdkp, 
unsigned char *buffer)
 * supports equal zone sizes.
 */
same = buffer[4] & 0xf;
-   if (same == 0 || same > 3) {
+   if (same > 3) {
sd_printk(KERN_WARNING, sdkp,
  "REPORT ZONES SAME type %d not supported\n", same);
return;
@@ -2282,9 +2284,9 @@ static void sd_read_zones(struct scsi_disk *sdkp, 
unsigned char *buffer)
sdkp->unmap_granularity = zone_len;
blk_queue_chunk_sectors(sdkp->disk->queue,
logical_to_sectors(sdkp->device, zone_len));
-   sd_config_discard(sdkp, SD_ZBC_RESET_WP);
 
-   sd_zbc_setup(sdkp, buffer, SD_BUF_SIZE);
+   sd_zbc_setup(sdkp, zone_len, buffer, SD_BUF_SIZE);
+   sd_config_discard(sdkp, SD_ZBC_RESET_WP);
 }
 
 static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device 
*sdp,
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index 6ae4505..ef6c132 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -283,19 +283,24 @@ static inline void sd_dif_complete(struct scsi_cmnd *cmd, 
unsigned int a)
 
 #endif /* CONFIG_BLK_DEV_INTEGRITY */
 
+
+#define SD_ZBC_INIT0
+#define SD_ZBC_RESET_WP_ERR1
+#define SD_ZBC_WRITE_ERR   2
+
 #ifdef CONFIG_SCSI_ZBC
 
 extern int sd_zbc_report_zones(struct scsi_disk *, unsigned char *, int,
   sector_t, enum zbc_zone_reporting_options, bool);
-extern int sd_zbc_setup(struct scsi_disk *, char *, int);
+extern int sd_zbc_setup(struct scsi_disk *, u64 zlen, char *buf, int buf_len);
 extern void sd_zbc_remove(struct scsi_disk *);
 extern void sd_zbc_reset_zones(struct scsi_disk *);
 extern int sd_zbc_setup_discard(struct scsi_disk *, struct request *,
sector_t, unsigned int);
 extern int sd_zbc_setup_read_write(struct scsi_disk *, struct request *,
   sector_t, unsigned int *);
-extern void sd_zbc_update_zones(struct scsi_disk *, sector_t, int, bool);
-extern 

[PATCH v2 1/4] Enable support for Seagate HostAware drives

2016-08-21 Thread Shaun Tancheff
Seagate drives report a SAME code of 0 due to having:
  - Zones of different types (CMR zones at the low LBA space).
  - Zones of different size (A terminating 'runt' zone in the high
lba space).

Support loading the zone topology into the zone cache.

Signed-off-by: Shaun Tancheff 
---
 drivers/scsi/sd.c  |  22 +++---
 drivers/scsi/sd.h  |  20 --
 drivers/scsi/sd_zbc.c  | 183 +++--
 include/linux/blkdev.h |  16 +++--
 4 files changed, 170 insertions(+), 71 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 059a57f..7903e21 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -693,8 +693,13 @@ static void sd_config_discard(struct scsi_disk *sdkp, 
unsigned int mode)
break;
 
case SD_ZBC_RESET_WP:
-   max_blocks = sdkp->unmap_granularity;
q->limits.discard_zeroes_data = 1;
+   q->limits.discard_granularity =
+   sd_zbc_discard_granularity(sdkp);
+
+   max_blocks = min_not_zero(sdkp->unmap_granularity,
+ q->limits.discard_granularity >>
+   ilog2(logical_block_size));
break;
 
case SD_LBP_ZERO:
@@ -1955,13 +1960,12 @@ static int sd_done(struct scsi_cmnd *SCpnt)
good_bytes = blk_rq_bytes(req);
scsi_set_resid(SCpnt, 0);
} else {
-#ifdef CONFIG_SCSI_ZBC
if (op == ZBC_OUT)
/* RESET WRITE POINTER failed */
sd_zbc_update_zones(sdkp,
blk_rq_pos(req),
-   512, true);
-#endif
+   512, SD_ZBC_RESET_WP_ERR);
+
good_bytes = 0;
scsi_set_resid(SCpnt, blk_rq_bytes(req));
}
@@ -2034,7 +2038,6 @@ static int sd_done(struct scsi_cmnd *SCpnt)
good_bytes = blk_rq_bytes(req);
scsi_set_resid(SCpnt, 0);
}
-#ifdef CONFIG_SCSI_ZBC
/*
 * ZBC: Unaligned write command.
 * Write did not start a write pointer position.
@@ -2042,8 +2045,7 @@ static int sd_done(struct scsi_cmnd *SCpnt)
if (sshdr.ascq == 0x04)
sd_zbc_update_zones(sdkp,
blk_rq_pos(req),
-   512, true);
-#endif
+   512, SD_ZBC_WRITE_ERR);
}
break;
default:
@@ -2270,7 +2272,7 @@ static void sd_read_zones(struct scsi_disk *sdkp, 
unsigned char *buffer)
 * supports equal zone sizes.
 */
same = buffer[4] & 0xf;
-   if (same == 0 || same > 3) {
+   if (same > 3) {
sd_printk(KERN_WARNING, sdkp,
  "REPORT ZONES SAME type %d not supported\n", same);
return;
@@ -2282,9 +2284,9 @@ static void sd_read_zones(struct scsi_disk *sdkp, 
unsigned char *buffer)
sdkp->unmap_granularity = zone_len;
blk_queue_chunk_sectors(sdkp->disk->queue,
logical_to_sectors(sdkp->device, zone_len));
-   sd_config_discard(sdkp, SD_ZBC_RESET_WP);
 
-   sd_zbc_setup(sdkp, buffer, SD_BUF_SIZE);
+   sd_zbc_setup(sdkp, zone_len, buffer, SD_BUF_SIZE);
+   sd_config_discard(sdkp, SD_ZBC_RESET_WP);
 }
 
 static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device 
*sdp,
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index 6ae4505..ef6c132 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -283,19 +283,24 @@ static inline void sd_dif_complete(struct scsi_cmnd *cmd, 
unsigned int a)
 
 #endif /* CONFIG_BLK_DEV_INTEGRITY */
 
+
+#define SD_ZBC_INIT0
+#define SD_ZBC_RESET_WP_ERR1
+#define SD_ZBC_WRITE_ERR   2
+
 #ifdef CONFIG_SCSI_ZBC
 
 extern int sd_zbc_report_zones(struct scsi_disk *, unsigned char *, int,
   sector_t, enum zbc_zone_reporting_options, bool);
-extern int sd_zbc_setup(struct scsi_disk *, char *, int);
+extern int sd_zbc_setup(struct scsi_disk *, u64 zlen, char *buf, int buf_len);
 extern void sd_zbc_remove(struct scsi_disk *);
 extern void sd_zbc_reset_zones(struct scsi_disk *);
 extern int sd_zbc_setup_discard(struct scsi_disk *, struct request *,
sector_t, unsigned int);
 extern int sd_zbc_setup_read_write(struct scsi_disk *, struct request *,
   sector_t, unsigned int *);
-extern void sd_zbc_update_zones(struct scsi_disk *, sector_t, int, bool);
-extern void 

[PATCH v6 4/4] SCT Write Same handle ATA_DFLAG_PIO

2016-08-21 Thread Shaun Tancheff
Use non DMA write log when ATA_DFLAG_PIO is set.

Signed-off-by: Shaun Tancheff 
---
v6: Added check for ATA_DFLAG_PIO and fallback to non DMA write log for
SCT Write Same

 drivers/ata/libata-scsi.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 37f456e..e50b7a7 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3485,6 +3485,8 @@ static unsigned int ata_scsi_write_same_xlat(struct 
ata_queued_cmd *qc)
tf->device = ATA_CMD_STANDBYNOW1;
tf->protocol = ATA_PROT_DMA;
tf->command = ATA_CMD_WRITE_LOG_DMA_EXT;
+   if (unlikely(dev->flags & ATA_DFLAG_PIO))
+   tf->command = ATA_CMD_WRITE_LOG_EXT;
}
 
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 |
-- 
2.9.3



[PATCH v6 4/4] SCT Write Same handle ATA_DFLAG_PIO

2016-08-21 Thread Shaun Tancheff
Use non DMA write log when ATA_DFLAG_PIO is set.

Signed-off-by: Shaun Tancheff 
---
v6: Added check for ATA_DFLAG_PIO and fallback to non DMA write log for
SCT Write Same

 drivers/ata/libata-scsi.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 37f456e..e50b7a7 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3485,6 +3485,8 @@ static unsigned int ata_scsi_write_same_xlat(struct 
ata_queued_cmd *qc)
tf->device = ATA_CMD_STANDBYNOW1;
tf->protocol = ATA_PROT_DMA;
tf->command = ATA_CMD_WRITE_LOG_DMA_EXT;
+   if (unlikely(dev->flags & ATA_DFLAG_PIO))
+   tf->command = ATA_CMD_WRITE_LOG_EXT;
}
 
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 |
-- 
2.9.3



[PATCH v6 3/4] SCT Write Same / DSM Trim

2016-08-21 Thread Shaun Tancheff
Correct handling of devices with sector_size other that 512 bytes.

Signed-off-by: Shaun Tancheff 
---
In the case of a 4Kn device sector_size it is possible to describe a much
larger DSM Trim than the current fixed default of 512 bytes.

This patch assumes the minimum descriptor is sector_size and fills out
the descriptor accordingly.

The ACS-2 specification is quite clear that the DSM command payload is
sized as number of 512 byte transfers so a 4Kn device will operate
correctly without this patch.

v5:
 - Added support for a sector_size descriptor other than 512 bytes.

 drivers/ata/libata-scsi.c | 85 +++
 1 file changed, 57 insertions(+), 28 deletions(-)

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index ebf1a04..37f456e 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3283,7 +3283,7 @@ static unsigned int ata_scsi_pass_thru(struct 
ata_queued_cmd *qc)
 /**
  * ata_format_dsm_trim_descr() - SATL Write Same to DSM Trim
  * @cmd: SCSI command being translated
- * @num: Maximum number of entries (nominally 64).
+ * @trmax: Maximum number of entries that will fit in sector_size bytes.
  * @sector: Starting sector
  * @count: Total Range of request in logical sectors
  *
@@ -3298,63 +3298,80 @@ static unsigned int ata_scsi_pass_thru(struct 
ata_queued_cmd *qc)
  *  LBA's should be sorted order and not overlap.
  *
  * NOTE: this is the same format as ADD LBA(S) TO NV CACHE PINNED SET
+ *
+ * Return: Number of bytes copied into sglist.
  */
-static unsigned int ata_format_dsm_trim_descr(struct scsi_cmnd *cmd, u32 num,
- u64 sector, u32 count)
+static size_t ata_format_dsm_trim_descr(struct scsi_cmnd *cmd, u32 trmax,
+   u64 sector, u32 count)
 {
-   __le64 *buffer;
-   u32 i = 0, used_bytes;
+   struct scsi_device *sdp = cmd->device;
+   size_t len = sdp->sector_size;
+   size_t r;
+   __le64 *buf;
+   u32 i = 0;
unsigned long flags;
 
-   BUILD_BUG_ON(512 > ATA_SCSI_RBUF_SIZE);
+   WARN_ON(len > ATA_SCSI_RBUF_SIZE);
+
+   if (len > ATA_SCSI_RBUF_SIZE)
+   len = ATA_SCSI_RBUF_SIZE;
 
spin_lock_irqsave(_scsi_rbuf_lock, flags);
-   buffer = ((void *)ata_scsi_rbuf);
-   while (i < num) {
+   buf = ((void *)ata_scsi_rbuf);
+   memset(buf, 0, len);
+   while (i < trmax) {
u64 entry = sector |
((u64)(count > 0x ? 0x : count) << 48);
-   buffer[i++] = __cpu_to_le64(entry);
+   buf[i++] = __cpu_to_le64(entry);
if (count <= 0x)
break;
count -= 0x;
sector += 0x;
}
-
-   used_bytes = ALIGN(i * 8, 512);
-   memset(buffer + i, 0, used_bytes - i * 8);
-   sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buffer, 512);
+   r = sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buf, len);
spin_unlock_irqrestore(_scsi_rbuf_lock, flags);
 
-   return used_bytes;
+   return r;
 }
 
 /**
  * ata_format_dsm_trim_descr() - SATL Write Same to ATA SCT Write Same
  * @cmd: SCSI command being translated
  * @lba: Starting sector
- * @num: Number of logical sectors to be zero'd.
+ * @num: Number of sectors to be zero'd.
  *
- * Rewrite the WRITE SAME descriptor to be an SCT Write Same formatted
+ * Rewrite the WRITE SAME payload to be an SCT Write Same formatted
  * descriptor.
  * NOTE: Writes a pattern (0's) in the foreground.
- *   Large write-same requents can timeout.
+ *
+ * Return: Number of bytes copied into sglist.
  */
-static void ata_format_sct_write_same(struct scsi_cmnd *cmd, u64 lba, u64 num)
+static size_t ata_format_sct_write_same(struct scsi_cmnd *cmd, u64 lba, u64 
num)
 {
-   u16 *sctpg;
+   struct scsi_device *sdp = cmd->device;
+   size_t len = sdp->sector_size;
+   size_t r;
+   u16 *buf;
unsigned long flags;
 
spin_lock_irqsave(_scsi_rbuf_lock, flags);
-   sctpg = ((void *)ata_scsi_rbuf);
+   buf = ((void *)ata_scsi_rbuf);
+
+   put_unaligned_le16(0x0002,  [0]); /* SCT_ACT_WRITE_SAME */
+   put_unaligned_le16(0x0101,  [1]); /* WRITE PTRN FG */
+   put_unaligned_le64(lba, [2]);
+   put_unaligned_le64(num, [6]);
+   put_unaligned_le32(0u,  [10]); /* pattern */
+
+   WARN_ON(len > ATA_SCSI_RBUF_SIZE);
 
-   put_unaligned_le16(0x0002,  [0]); /* SCT_ACT_WRITE_SAME */
-   put_unaligned_le16(0x0101,  [1]); /* WRITE PTRN FG */
-   put_unaligned_le64(lba, [2]);
-   put_unaligned_le64(num, [6]);
-   put_unaligned_le32(0u,  [10]);
+   if (len > ATA_SCSI_RBUF_SIZE)
+   len = ATA_SCSI_RBUF_SIZE;
 
-   sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), sctpg, 512);
+   r = 

[PATCH v6 2/4] Add support for SCT Write Same

2016-08-21 Thread Shaun Tancheff
SATA drives may support write same via SCT. This is useful
for setting the drive contents to a specific pattern (0's).

Translate a SCSI WRITE SAME 16 command to be either a DSM TRIM
command or an SCT Write Same command.

Based on the UNMAP flag:
  - When set translate to DSM TRIM
  - When not set translate to SCT Write Same

Signed-off-by: Shaun Tancheff 
---
v6:
 - Change to use sg_copy_from_buffer as per Christoph Hellwig 
v5:
 - Addressed review comments
 - Report support for ZBC only for zoned devices.
 - kmap page during rewrite
 - Fix unmap set to require trim or error, if not unmap then sct write
   same or error.
v4:
 - Added partial MAINTENANCE_IN opcode simulation
 - Dropped all changes in drivers/scsi/*
 - Changed to honor the UNMAP flag -> TRIM, no UNMAP -> SCT.
v3:
 - Demux UNMAP/TRIM from WRITE SAME
v2:
 - Remove fugly ata hacking from sd.c

 drivers/ata/libata-scsi.c | 199 +++---
 include/linux/ata.h   |  43 ++
 2 files changed, 213 insertions(+), 29 deletions(-)

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 7990cb2..ebf1a04 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1159,8 +1159,6 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev)
 {
sdev->use_10_for_rw = 1;
sdev->use_10_for_ms = 1;
-   sdev->no_report_opcodes = 1;
-   sdev->no_write_same = 1;
 
/* Schedule policy is determined by ->qc_defer() callback and
 * it needs to see every deferred qc.  Set dev_blocked to 1 to
@@ -3287,7 +3285,7 @@ static unsigned int ata_scsi_pass_thru(struct 
ata_queued_cmd *qc)
  * @cmd: SCSI command being translated
  * @num: Maximum number of entries (nominally 64).
  * @sector: Starting sector
- * @count: Total Range of request
+ * @count: Total Range of request in logical sectors
  *
  * Rewrite the WRITE SAME descriptor to be a DSM TRIM little-endian formatted
  * descriptor.
@@ -3330,6 +3328,45 @@ static unsigned int ata_format_dsm_trim_descr(struct 
scsi_cmnd *cmd, u32 num,
return used_bytes;
 }
 
+/**
+ * ata_format_dsm_trim_descr() - SATL Write Same to ATA SCT Write Same
+ * @cmd: SCSI command being translated
+ * @lba: Starting sector
+ * @num: Number of logical sectors to be zero'd.
+ *
+ * Rewrite the WRITE SAME descriptor to be an SCT Write Same formatted
+ * descriptor.
+ * NOTE: Writes a pattern (0's) in the foreground.
+ *   Large write-same requents can timeout.
+ */
+static void ata_format_sct_write_same(struct scsi_cmnd *cmd, u64 lba, u64 num)
+{
+   u16 *sctpg;
+   unsigned long flags;
+
+   spin_lock_irqsave(_scsi_rbuf_lock, flags);
+   sctpg = ((void *)ata_scsi_rbuf);
+
+   put_unaligned_le16(0x0002,  [0]); /* SCT_ACT_WRITE_SAME */
+   put_unaligned_le16(0x0101,  [1]); /* WRITE PTRN FG */
+   put_unaligned_le64(lba, [2]);
+   put_unaligned_le64(num, [6]);
+   put_unaligned_le32(0u,  [10]);
+
+   sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), sctpg, 512);
+   spin_unlock_irqrestore(_scsi_rbuf_lock, flags);
+}
+
+/**
+ * ata_scsi_write_same_xlat() - SATL Write Same to ATA SCT Write Same
+ * @qc: Command to be translated
+ *
+ * Translate a SCSI WRITE SAME command to be either a DSM TRIM command or
+ * an SCT Write Same command.
+ * Based on WRITE SAME has the UNMAP flag
+ *   When set translate to DSM TRIM
+ *   When clear translate to SCT Write Same
+ */
 static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
 {
struct ata_taskfile *tf = >tf;
@@ -3342,6 +3379,7 @@ static unsigned int ata_scsi_write_same_xlat(struct 
ata_queued_cmd *qc)
u32 size;
u16 fp;
u8 bp = 0xff;
+   u8 unmap = cdb[1] & 0x8;
 
/* we may not issue DMA commands if no DMA mode is set */
if (unlikely(!dev->dma_mode))
@@ -3353,11 +3391,26 @@ static unsigned int ata_scsi_write_same_xlat(struct 
ata_queued_cmd *qc)
}
scsi_16_lba_len(cdb, , _block);
 
-   /* for now we only support WRITE SAME with the unmap bit set */
-   if (unlikely(!(cdb[1] & 0x8))) {
-   fp = 1;
-   bp = 3;
-   goto invalid_fld;
+   if (unmap) {
+   /* If trim is not enabled the cmd is invalid. */
+   if ((dev->horkage & ATA_HORKAGE_NOTRIM) ||
+   !ata_id_has_trim(dev->id)) {
+   fp = 1;
+   bp = 3;
+   goto invalid_fld;
+   }
+   /* If the request is too large the cmd is invalid */
+   if (n_block > 0x * trmax) {
+   fp = 2;
+   goto invalid_fld;
+   }
+   } else {
+   /* If write same is not available the cmd is invalid */
+   if (!ata_id_sct_write_same(dev->id)) {
+   fp = 1;
+   bp = 3;
+   

[v13 PATCH 3/5] arm64: dts: rockchip: add Type-C phy for RK3399

2016-08-21 Thread Chris Zhong
There are 2 Type-C phy on RK3399, they are almost same, except the
address of register. They support USB3.0 Type-C and DisplayPort1.3
Alt Mode on USB Type-C. Register a phy, supply it to USB3 controller
and DP controller.

Signed-off-by: Chris Zhong 
Reviewed-by: Guenter Roeck 

---

Changes in v13: None
Changes in v12: None
Changes in v11:
- split the dp-phy and usb3-phy to 2 child-node

Changes in v10:
- remove rockchip,uphy-dp-sel property

Changes in v9:
- change #phy-cells to 1

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None
Changes in v1: None

 arch/arm64/boot/dts/rockchip/rk3399.dtsi | 56 
 1 file changed, 56 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index a44eb67..23f7ae1 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1060,6 +1060,62 @@
};
};
 
+   tcphy0: phy@ff7c {
+   compatible = "rockchip,rk3399-typec-phy";
+   reg = <0x0 0xff7c 0x0 0x4>;
+   rockchip,grf = <>;
+   clocks = < SCLK_UPHY0_TCPDCORE>,
+< SCLK_UPHY0_TCPDPHY_REF>;
+   clock-names = "tcpdcore", "tcpdphy-ref";
+   assigned-clocks = < SCLK_UPHY0_TCPDCORE>;
+   assigned-clock-rates = <5000>;
+   resets = < SRST_UPHY0>,
+< SRST_UPHY0_PIPE_L00>,
+< SRST_P_UPHY0_TCPHY>;
+   reset-names = "uphy", "uphy-pipe", "uphy-tcphy";
+   rockchip,typec-conn-dir = <0xe580 0 16>;
+   rockchip,usb3tousb2-en = <0xe580 3 19>;
+   rockchip,external-psm = <0xe588 14 30>;
+   rockchip,pipe-status = <0xe5c0 0 0>;
+   status = "disabled";
+
+   tcphy0_dp: dp-port {
+   #phy-cells = <0>;
+   };
+
+   tcphy0_usb3: usb3-port {
+   #phy-cells = <0>;
+   };
+   };
+
+   tcphy1: phy@ff80 {
+   compatible = "rockchip,rk3399-typec-phy";
+   reg = <0x0 0xff80 0x0 0x4>;
+   rockchip,grf = <>;
+   clocks = < SCLK_UPHY1_TCPDCORE>,
+< SCLK_UPHY1_TCPDPHY_REF>;
+   clock-names = "tcpdcore", "tcpdphy-ref";
+   assigned-clocks = < SCLK_UPHY1_TCPDCORE>;
+   assigned-clock-rates = <5000>;
+   resets = < SRST_UPHY1>,
+< SRST_UPHY1_PIPE_L00>,
+< SRST_P_UPHY1_TCPHY>;
+   reset-names = "uphy", "uphy-pipe", "uphy-tcphy";
+   rockchip,typec-conn-dir = <0xe58c 0 16>;
+   rockchip,usb3tousb2-en = <0xe58c 3 19>;
+   rockchip,external-psm = <0xe594 14 30>;
+   rockchip,pipe-status = <0xe5c0 16 16>;
+   status = "disabled";
+
+   tcphy1_dp: dp-port {
+   #phy-cells = <0>;
+   };
+
+   tcphy1_usb3: usb3-port {
+   #phy-cells = <0>;
+   };
+   };
+
watchdog@ff84 {
compatible = "snps,dw-wdt";
reg = <0x0 0xff84 0x0 0x100>;
-- 
1.9.1



[v13 PATCH 2/5] phy: Add USB Type-C PHY driver for rk3399

2016-08-21 Thread Chris Zhong
Add a PHY provider driver for the rk3399 SoC Type-c PHY. The USB
Type-C PHY is designed to support the USB3 and DP applications. The
PHY basically has two main components: USB3 and DisplyPort. USB3
operates in SuperSpeed mode and the DP can operate at RBR, HBR and
HBR2 data rates. Hence, create 2 PHY deivces, the phy[0] for DP,
and phy[1] for USB3.

Signed-off-by: Chris Zhong 
Signed-off-by: Kever Yang 
Reviewed-by: Guenter Roeck 
Tested-by: Guenter Roeck 

---

Changes in v13:
- do not return err if nothing connected with Type-C, when usb phy power on,
  since the USB core driver will call phy power without USB3 device connected.

Changes in v12:
- enable DP+USB3 mode, only when EXTCON_PROP_USB_SUPERSPEED equal 1
  and DP is attached

Changes in v11:
- make a clearer demarcation between usb phy and dp phy.

Changes in v10:
- do not control dp select and hpd config in phy driver

Changes in v9:
- the new_mode should be int not u8
- move mutex_lock(>lock); to earlier place. in
  rockchip_usb3_phy_power_off
- better mutex lock for phy mode and flip
- split the Type-C PHY into two PHYs: USB3 and DP

Changes in v8:
- set the default cable id to EXTCON_USB_HOST
- optimization Error log

Changes in v7:
- support new API of extcon

Changes in v6:
- delete the support of PIN_ASSIGN_A/B
- set the default mode to MODE_DFP_USB
- disable DP PLL at USB3 only mode

Changes in v5:
- support get property from extcon
- remove PIN ASSIGN A/B support

Changes in v4:
- select EXTCON
- use phy framework to control the USB3 and DP function
- rename PIN_MAP_ to PIN_ASSIGN_

Changes in v3:
- remove the phy framework(Kishon Vijay Abraham I)
- add parentheses around the macro
- use a single space between type and name
- add spaces after opening and before closing braces.
- use u16 for register value
- remove type-c phy header file
- CodingStyle optimization
- use some cable extcon to get type-c port information
- add a extcon to notify Display Port

Changes in v2:
- select RESET_CONTROLLER
- alphabetic order
- modify some spelling mistakes
- make mode cleaner
- use bool for enable/disable
- check all of the return value
- return a better err number
- use more readx_poll_timeout()
- clk_disable_unprepare(tcphy->clk_ref);
- remove unuse functions, rockchip_typec_phy_power_on/off
- remove unnecessary typecast from void *
- use dts node to distinguish between phys.

Changes in v1:
- update the licence note
- init core clock to 50MHz
- use extcon API
- remove unused global
- add some comments for magic num
- change usleep_range(1000, 2000) tousleep_range(1000, 1050)
- remove __func__ from dev_err
- return err number when get clk failed
- remove ADDR_ADJ define
- use devm_clk_get(>dev, "tcpdcore")

 drivers/phy/Kconfig  |   9 +
 drivers/phy/Makefile |   1 +
 drivers/phy/phy-rockchip-typec.c | 977 +++
 3 files changed, 987 insertions(+)
 create mode 100644 drivers/phy/phy-rockchip-typec.c

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 42f3e30..c775fd7 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -348,6 +348,15 @@ config PHY_ROCKCHIP_PCIE
help
  Enable this to support the Rockchip PCIe PHY.
 
+config PHY_ROCKCHIP_TYPEC
+   tristate "Rockchip TYPEC PHY Driver"
+   depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
+   select EXTCON
+   select GENERIC_PHY
+   select RESET_CONTROLLER
+   help
+ Enable this to support the Rockchip USB TYPEC PHY.
+
 config PHY_ST_SPEAR1310_MIPHY
tristate "ST SPEAR1310-MIPHY driver"
select GENERIC_PHY
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index fbb91e7..5d58b63 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2)  += 
phy-rockchip-inno-usb2.o
 obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o
 obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o
 obj-$(CONFIG_PHY_ROCKCHIP_DP)  += phy-rockchip-dp.o
+obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o
 obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA)+= phy-qcom-ipq806x-sata.o
 obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY)   += phy-spear1310-miphy.o
 obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY)   += phy-spear1340-miphy.o
diff --git a/drivers/phy/phy-rockchip-typec.c b/drivers/phy/phy-rockchip-typec.c
new file mode 100644
index 000..6edeae6
--- /dev/null
+++ b/drivers/phy/phy-rockchip-typec.c
@@ -0,0 +1,977 @@
+/*
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ * Author: Chris Zhong 
+ * Kever Yang 
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * 

[PATCH v6 3/4] SCT Write Same / DSM Trim

2016-08-21 Thread Shaun Tancheff
Correct handling of devices with sector_size other that 512 bytes.

Signed-off-by: Shaun Tancheff 
---
In the case of a 4Kn device sector_size it is possible to describe a much
larger DSM Trim than the current fixed default of 512 bytes.

This patch assumes the minimum descriptor is sector_size and fills out
the descriptor accordingly.

The ACS-2 specification is quite clear that the DSM command payload is
sized as number of 512 byte transfers so a 4Kn device will operate
correctly without this patch.

v5:
 - Added support for a sector_size descriptor other than 512 bytes.

 drivers/ata/libata-scsi.c | 85 +++
 1 file changed, 57 insertions(+), 28 deletions(-)

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index ebf1a04..37f456e 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3283,7 +3283,7 @@ static unsigned int ata_scsi_pass_thru(struct 
ata_queued_cmd *qc)
 /**
  * ata_format_dsm_trim_descr() - SATL Write Same to DSM Trim
  * @cmd: SCSI command being translated
- * @num: Maximum number of entries (nominally 64).
+ * @trmax: Maximum number of entries that will fit in sector_size bytes.
  * @sector: Starting sector
  * @count: Total Range of request in logical sectors
  *
@@ -3298,63 +3298,80 @@ static unsigned int ata_scsi_pass_thru(struct 
ata_queued_cmd *qc)
  *  LBA's should be sorted order and not overlap.
  *
  * NOTE: this is the same format as ADD LBA(S) TO NV CACHE PINNED SET
+ *
+ * Return: Number of bytes copied into sglist.
  */
-static unsigned int ata_format_dsm_trim_descr(struct scsi_cmnd *cmd, u32 num,
- u64 sector, u32 count)
+static size_t ata_format_dsm_trim_descr(struct scsi_cmnd *cmd, u32 trmax,
+   u64 sector, u32 count)
 {
-   __le64 *buffer;
-   u32 i = 0, used_bytes;
+   struct scsi_device *sdp = cmd->device;
+   size_t len = sdp->sector_size;
+   size_t r;
+   __le64 *buf;
+   u32 i = 0;
unsigned long flags;
 
-   BUILD_BUG_ON(512 > ATA_SCSI_RBUF_SIZE);
+   WARN_ON(len > ATA_SCSI_RBUF_SIZE);
+
+   if (len > ATA_SCSI_RBUF_SIZE)
+   len = ATA_SCSI_RBUF_SIZE;
 
spin_lock_irqsave(_scsi_rbuf_lock, flags);
-   buffer = ((void *)ata_scsi_rbuf);
-   while (i < num) {
+   buf = ((void *)ata_scsi_rbuf);
+   memset(buf, 0, len);
+   while (i < trmax) {
u64 entry = sector |
((u64)(count > 0x ? 0x : count) << 48);
-   buffer[i++] = __cpu_to_le64(entry);
+   buf[i++] = __cpu_to_le64(entry);
if (count <= 0x)
break;
count -= 0x;
sector += 0x;
}
-
-   used_bytes = ALIGN(i * 8, 512);
-   memset(buffer + i, 0, used_bytes - i * 8);
-   sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buffer, 512);
+   r = sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buf, len);
spin_unlock_irqrestore(_scsi_rbuf_lock, flags);
 
-   return used_bytes;
+   return r;
 }
 
 /**
  * ata_format_dsm_trim_descr() - SATL Write Same to ATA SCT Write Same
  * @cmd: SCSI command being translated
  * @lba: Starting sector
- * @num: Number of logical sectors to be zero'd.
+ * @num: Number of sectors to be zero'd.
  *
- * Rewrite the WRITE SAME descriptor to be an SCT Write Same formatted
+ * Rewrite the WRITE SAME payload to be an SCT Write Same formatted
  * descriptor.
  * NOTE: Writes a pattern (0's) in the foreground.
- *   Large write-same requents can timeout.
+ *
+ * Return: Number of bytes copied into sglist.
  */
-static void ata_format_sct_write_same(struct scsi_cmnd *cmd, u64 lba, u64 num)
+static size_t ata_format_sct_write_same(struct scsi_cmnd *cmd, u64 lba, u64 
num)
 {
-   u16 *sctpg;
+   struct scsi_device *sdp = cmd->device;
+   size_t len = sdp->sector_size;
+   size_t r;
+   u16 *buf;
unsigned long flags;
 
spin_lock_irqsave(_scsi_rbuf_lock, flags);
-   sctpg = ((void *)ata_scsi_rbuf);
+   buf = ((void *)ata_scsi_rbuf);
+
+   put_unaligned_le16(0x0002,  [0]); /* SCT_ACT_WRITE_SAME */
+   put_unaligned_le16(0x0101,  [1]); /* WRITE PTRN FG */
+   put_unaligned_le64(lba, [2]);
+   put_unaligned_le64(num, [6]);
+   put_unaligned_le32(0u,  [10]); /* pattern */
+
+   WARN_ON(len > ATA_SCSI_RBUF_SIZE);
 
-   put_unaligned_le16(0x0002,  [0]); /* SCT_ACT_WRITE_SAME */
-   put_unaligned_le16(0x0101,  [1]); /* WRITE PTRN FG */
-   put_unaligned_le64(lba, [2]);
-   put_unaligned_le64(num, [6]);
-   put_unaligned_le32(0u,  [10]);
+   if (len > ATA_SCSI_RBUF_SIZE)
+   len = ATA_SCSI_RBUF_SIZE;
 
-   sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), sctpg, 512);
+   r = sg_copy_from_buffer(scsi_sglist(cmd), 

[PATCH v6 2/4] Add support for SCT Write Same

2016-08-21 Thread Shaun Tancheff
SATA drives may support write same via SCT. This is useful
for setting the drive contents to a specific pattern (0's).

Translate a SCSI WRITE SAME 16 command to be either a DSM TRIM
command or an SCT Write Same command.

Based on the UNMAP flag:
  - When set translate to DSM TRIM
  - When not set translate to SCT Write Same

Signed-off-by: Shaun Tancheff 
---
v6:
 - Change to use sg_copy_from_buffer as per Christoph Hellwig 
v5:
 - Addressed review comments
 - Report support for ZBC only for zoned devices.
 - kmap page during rewrite
 - Fix unmap set to require trim or error, if not unmap then sct write
   same or error.
v4:
 - Added partial MAINTENANCE_IN opcode simulation
 - Dropped all changes in drivers/scsi/*
 - Changed to honor the UNMAP flag -> TRIM, no UNMAP -> SCT.
v3:
 - Demux UNMAP/TRIM from WRITE SAME
v2:
 - Remove fugly ata hacking from sd.c

 drivers/ata/libata-scsi.c | 199 +++---
 include/linux/ata.h   |  43 ++
 2 files changed, 213 insertions(+), 29 deletions(-)

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 7990cb2..ebf1a04 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1159,8 +1159,6 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev)
 {
sdev->use_10_for_rw = 1;
sdev->use_10_for_ms = 1;
-   sdev->no_report_opcodes = 1;
-   sdev->no_write_same = 1;
 
/* Schedule policy is determined by ->qc_defer() callback and
 * it needs to see every deferred qc.  Set dev_blocked to 1 to
@@ -3287,7 +3285,7 @@ static unsigned int ata_scsi_pass_thru(struct 
ata_queued_cmd *qc)
  * @cmd: SCSI command being translated
  * @num: Maximum number of entries (nominally 64).
  * @sector: Starting sector
- * @count: Total Range of request
+ * @count: Total Range of request in logical sectors
  *
  * Rewrite the WRITE SAME descriptor to be a DSM TRIM little-endian formatted
  * descriptor.
@@ -3330,6 +3328,45 @@ static unsigned int ata_format_dsm_trim_descr(struct 
scsi_cmnd *cmd, u32 num,
return used_bytes;
 }
 
+/**
+ * ata_format_dsm_trim_descr() - SATL Write Same to ATA SCT Write Same
+ * @cmd: SCSI command being translated
+ * @lba: Starting sector
+ * @num: Number of logical sectors to be zero'd.
+ *
+ * Rewrite the WRITE SAME descriptor to be an SCT Write Same formatted
+ * descriptor.
+ * NOTE: Writes a pattern (0's) in the foreground.
+ *   Large write-same requents can timeout.
+ */
+static void ata_format_sct_write_same(struct scsi_cmnd *cmd, u64 lba, u64 num)
+{
+   u16 *sctpg;
+   unsigned long flags;
+
+   spin_lock_irqsave(_scsi_rbuf_lock, flags);
+   sctpg = ((void *)ata_scsi_rbuf);
+
+   put_unaligned_le16(0x0002,  [0]); /* SCT_ACT_WRITE_SAME */
+   put_unaligned_le16(0x0101,  [1]); /* WRITE PTRN FG */
+   put_unaligned_le64(lba, [2]);
+   put_unaligned_le64(num, [6]);
+   put_unaligned_le32(0u,  [10]);
+
+   sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), sctpg, 512);
+   spin_unlock_irqrestore(_scsi_rbuf_lock, flags);
+}
+
+/**
+ * ata_scsi_write_same_xlat() - SATL Write Same to ATA SCT Write Same
+ * @qc: Command to be translated
+ *
+ * Translate a SCSI WRITE SAME command to be either a DSM TRIM command or
+ * an SCT Write Same command.
+ * Based on WRITE SAME has the UNMAP flag
+ *   When set translate to DSM TRIM
+ *   When clear translate to SCT Write Same
+ */
 static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
 {
struct ata_taskfile *tf = >tf;
@@ -3342,6 +3379,7 @@ static unsigned int ata_scsi_write_same_xlat(struct 
ata_queued_cmd *qc)
u32 size;
u16 fp;
u8 bp = 0xff;
+   u8 unmap = cdb[1] & 0x8;
 
/* we may not issue DMA commands if no DMA mode is set */
if (unlikely(!dev->dma_mode))
@@ -3353,11 +3391,26 @@ static unsigned int ata_scsi_write_same_xlat(struct 
ata_queued_cmd *qc)
}
scsi_16_lba_len(cdb, , _block);
 
-   /* for now we only support WRITE SAME with the unmap bit set */
-   if (unlikely(!(cdb[1] & 0x8))) {
-   fp = 1;
-   bp = 3;
-   goto invalid_fld;
+   if (unmap) {
+   /* If trim is not enabled the cmd is invalid. */
+   if ((dev->horkage & ATA_HORKAGE_NOTRIM) ||
+   !ata_id_has_trim(dev->id)) {
+   fp = 1;
+   bp = 3;
+   goto invalid_fld;
+   }
+   /* If the request is too large the cmd is invalid */
+   if (n_block > 0x * trmax) {
+   fp = 2;
+   goto invalid_fld;
+   }
+   } else {
+   /* If write same is not available the cmd is invalid */
+   if (!ata_id_sct_write_same(dev->id)) {
+   fp = 1;
+   bp = 3;
+   goto invalid_fld;
+  

[v13 PATCH 3/5] arm64: dts: rockchip: add Type-C phy for RK3399

2016-08-21 Thread Chris Zhong
There are 2 Type-C phy on RK3399, they are almost same, except the
address of register. They support USB3.0 Type-C and DisplayPort1.3
Alt Mode on USB Type-C. Register a phy, supply it to USB3 controller
and DP controller.

Signed-off-by: Chris Zhong 
Reviewed-by: Guenter Roeck 

---

Changes in v13: None
Changes in v12: None
Changes in v11:
- split the dp-phy and usb3-phy to 2 child-node

Changes in v10:
- remove rockchip,uphy-dp-sel property

Changes in v9:
- change #phy-cells to 1

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None
Changes in v1: None

 arch/arm64/boot/dts/rockchip/rk3399.dtsi | 56 
 1 file changed, 56 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index a44eb67..23f7ae1 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1060,6 +1060,62 @@
};
};
 
+   tcphy0: phy@ff7c {
+   compatible = "rockchip,rk3399-typec-phy";
+   reg = <0x0 0xff7c 0x0 0x4>;
+   rockchip,grf = <>;
+   clocks = < SCLK_UPHY0_TCPDCORE>,
+< SCLK_UPHY0_TCPDPHY_REF>;
+   clock-names = "tcpdcore", "tcpdphy-ref";
+   assigned-clocks = < SCLK_UPHY0_TCPDCORE>;
+   assigned-clock-rates = <5000>;
+   resets = < SRST_UPHY0>,
+< SRST_UPHY0_PIPE_L00>,
+< SRST_P_UPHY0_TCPHY>;
+   reset-names = "uphy", "uphy-pipe", "uphy-tcphy";
+   rockchip,typec-conn-dir = <0xe580 0 16>;
+   rockchip,usb3tousb2-en = <0xe580 3 19>;
+   rockchip,external-psm = <0xe588 14 30>;
+   rockchip,pipe-status = <0xe5c0 0 0>;
+   status = "disabled";
+
+   tcphy0_dp: dp-port {
+   #phy-cells = <0>;
+   };
+
+   tcphy0_usb3: usb3-port {
+   #phy-cells = <0>;
+   };
+   };
+
+   tcphy1: phy@ff80 {
+   compatible = "rockchip,rk3399-typec-phy";
+   reg = <0x0 0xff80 0x0 0x4>;
+   rockchip,grf = <>;
+   clocks = < SCLK_UPHY1_TCPDCORE>,
+< SCLK_UPHY1_TCPDPHY_REF>;
+   clock-names = "tcpdcore", "tcpdphy-ref";
+   assigned-clocks = < SCLK_UPHY1_TCPDCORE>;
+   assigned-clock-rates = <5000>;
+   resets = < SRST_UPHY1>,
+< SRST_UPHY1_PIPE_L00>,
+< SRST_P_UPHY1_TCPHY>;
+   reset-names = "uphy", "uphy-pipe", "uphy-tcphy";
+   rockchip,typec-conn-dir = <0xe58c 0 16>;
+   rockchip,usb3tousb2-en = <0xe58c 3 19>;
+   rockchip,external-psm = <0xe594 14 30>;
+   rockchip,pipe-status = <0xe5c0 16 16>;
+   status = "disabled";
+
+   tcphy1_dp: dp-port {
+   #phy-cells = <0>;
+   };
+
+   tcphy1_usb3: usb3-port {
+   #phy-cells = <0>;
+   };
+   };
+
watchdog@ff84 {
compatible = "snps,dw-wdt";
reg = <0x0 0xff84 0x0 0x100>;
-- 
1.9.1



[v13 PATCH 2/5] phy: Add USB Type-C PHY driver for rk3399

2016-08-21 Thread Chris Zhong
Add a PHY provider driver for the rk3399 SoC Type-c PHY. The USB
Type-C PHY is designed to support the USB3 and DP applications. The
PHY basically has two main components: USB3 and DisplyPort. USB3
operates in SuperSpeed mode and the DP can operate at RBR, HBR and
HBR2 data rates. Hence, create 2 PHY deivces, the phy[0] for DP,
and phy[1] for USB3.

Signed-off-by: Chris Zhong 
Signed-off-by: Kever Yang 
Reviewed-by: Guenter Roeck 
Tested-by: Guenter Roeck 

---

Changes in v13:
- do not return err if nothing connected with Type-C, when usb phy power on,
  since the USB core driver will call phy power without USB3 device connected.

Changes in v12:
- enable DP+USB3 mode, only when EXTCON_PROP_USB_SUPERSPEED equal 1
  and DP is attached

Changes in v11:
- make a clearer demarcation between usb phy and dp phy.

Changes in v10:
- do not control dp select and hpd config in phy driver

Changes in v9:
- the new_mode should be int not u8
- move mutex_lock(>lock); to earlier place. in
  rockchip_usb3_phy_power_off
- better mutex lock for phy mode and flip
- split the Type-C PHY into two PHYs: USB3 and DP

Changes in v8:
- set the default cable id to EXTCON_USB_HOST
- optimization Error log

Changes in v7:
- support new API of extcon

Changes in v6:
- delete the support of PIN_ASSIGN_A/B
- set the default mode to MODE_DFP_USB
- disable DP PLL at USB3 only mode

Changes in v5:
- support get property from extcon
- remove PIN ASSIGN A/B support

Changes in v4:
- select EXTCON
- use phy framework to control the USB3 and DP function
- rename PIN_MAP_ to PIN_ASSIGN_

Changes in v3:
- remove the phy framework(Kishon Vijay Abraham I)
- add parentheses around the macro
- use a single space between type and name
- add spaces after opening and before closing braces.
- use u16 for register value
- remove type-c phy header file
- CodingStyle optimization
- use some cable extcon to get type-c port information
- add a extcon to notify Display Port

Changes in v2:
- select RESET_CONTROLLER
- alphabetic order
- modify some spelling mistakes
- make mode cleaner
- use bool for enable/disable
- check all of the return value
- return a better err number
- use more readx_poll_timeout()
- clk_disable_unprepare(tcphy->clk_ref);
- remove unuse functions, rockchip_typec_phy_power_on/off
- remove unnecessary typecast from void *
- use dts node to distinguish between phys.

Changes in v1:
- update the licence note
- init core clock to 50MHz
- use extcon API
- remove unused global
- add some comments for magic num
- change usleep_range(1000, 2000) tousleep_range(1000, 1050)
- remove __func__ from dev_err
- return err number when get clk failed
- remove ADDR_ADJ define
- use devm_clk_get(>dev, "tcpdcore")

 drivers/phy/Kconfig  |   9 +
 drivers/phy/Makefile |   1 +
 drivers/phy/phy-rockchip-typec.c | 977 +++
 3 files changed, 987 insertions(+)
 create mode 100644 drivers/phy/phy-rockchip-typec.c

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 42f3e30..c775fd7 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -348,6 +348,15 @@ config PHY_ROCKCHIP_PCIE
help
  Enable this to support the Rockchip PCIe PHY.
 
+config PHY_ROCKCHIP_TYPEC
+   tristate "Rockchip TYPEC PHY Driver"
+   depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
+   select EXTCON
+   select GENERIC_PHY
+   select RESET_CONTROLLER
+   help
+ Enable this to support the Rockchip USB TYPEC PHY.
+
 config PHY_ST_SPEAR1310_MIPHY
tristate "ST SPEAR1310-MIPHY driver"
select GENERIC_PHY
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index fbb91e7..5d58b63 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2)  += 
phy-rockchip-inno-usb2.o
 obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o
 obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o
 obj-$(CONFIG_PHY_ROCKCHIP_DP)  += phy-rockchip-dp.o
+obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o
 obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA)+= phy-qcom-ipq806x-sata.o
 obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY)   += phy-spear1310-miphy.o
 obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY)   += phy-spear1340-miphy.o
diff --git a/drivers/phy/phy-rockchip-typec.c b/drivers/phy/phy-rockchip-typec.c
new file mode 100644
index 000..6edeae6
--- /dev/null
+++ b/drivers/phy/phy-rockchip-typec.c
@@ -0,0 +1,977 @@
+/*
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ * Author: Chris Zhong 
+ * Kever Yang 
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 

[PATCH v6 0/4] SCT Write Same

2016-08-21 Thread Shaun Tancheff
At some point the method of issuing Write Same for ATA drives changed.
Currently write same is commonly available via SCT so expose the SCT
capabilities and use SCT Write Same when it is available.

This is useful for zoned based media that prefers to support discard
with lbprz set, aka discard zeroes data by mapping discard operations to
reset write pointer operations. Conventional zones that do not support
reset write pointer can still honor the discard zeroes data by issuing
a write same over the zone.

It may also be nice to know if various controllers that currently
disable WRITE SAME will work with the SCT Write Same code path:
  aacraid, arcmsr, megaraid, 3w-9xxx, 3w-sas, 3w-, gdth, hpsa, ips,
  megaraid, pmcraid, storvsc_drv

This patch against v4.8-rc2 is also at
https://github.com/stancheff/linux/tree/v4.8-rc2%2Bbiof.v9

g...@github.com:stancheff/linux.git v4.8-rc2+biof.v9

v6:
 - Fix bisect bug reported by Tom Yan 
 - Change to use sg_copy_from_buffer as per Christoph Hellwig 
 - Added support for a sector_size descriptor other than 512 bytes.
v5:
 - Addressed review comments
 - Report support for ZBC only for zoned devices.
 - kmap page during rewrite
 - Fix unmap set to require trim or error, if not unmap then sct write
   same or error.
v4:
 - Added partial MAINTENANCE_IN opcode simulation
 - Dropped all changes in drivers/scsi/*
 - Changed to honor the UNMAP flag -> TRIM, no UNMAP -> SCT.
v3:
 - Demux UNMAP/TRIM from WRITE SAME
v2:
 - Remove fugly ata hacking from sd.c

Shaun Tancheff (4):
  libata: Safely overwrite attached page in WRITE SAME xlat
  Add support for SCT Write Same
  SCT Write Same / DSM Trim
  SCT Write Same handle ATA_DFLAG_PIO

 drivers/ata/libata-scsi.c | 280 +-
 include/linux/ata.h   |  69 +++-
 2 files changed, 292 insertions(+), 57 deletions(-)

-- 
2.9.3



[PATCH v6 1/4] libata: Safely overwrite attached page in WRITE SAME xlat

2016-08-21 Thread Shaun Tancheff
Safely overwriting the attached page to ATA format from the SCSI formatted
variant.

Signed-off-by: Shaun Tancheff 
---
v6:
 - Fix bisect bug reported by Tom Yan 
 - Change to use sg_copy_from_buffer as per Christoph Hellwig 
v5:
 - Added prep patch to work with non-page aligned scatterlist pages
   and use kmap_atomic() to lock page during modification.

 drivers/ata/libata-scsi.c | 56 ++-
 include/linux/ata.h   | 26 --
 2 files changed, 51 insertions(+), 31 deletions(-)

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index e207b33..7990cb2 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3282,6 +3282,54 @@ static unsigned int ata_scsi_pass_thru(struct 
ata_queued_cmd *qc)
return 1;
 }
 
+/**
+ * ata_format_dsm_trim_descr() - SATL Write Same to DSM Trim
+ * @cmd: SCSI command being translated
+ * @num: Maximum number of entries (nominally 64).
+ * @sector: Starting sector
+ * @count: Total Range of request
+ *
+ * Rewrite the WRITE SAME descriptor to be a DSM TRIM little-endian formatted
+ * descriptor.
+ *
+ * Upto 64 entries of the format:
+ *   63:48 Range Length
+ *   47:0  LBA
+ *
+ *  Range Length of 0 is ignored.
+ *  LBA's should be sorted order and not overlap.
+ *
+ * NOTE: this is the same format as ADD LBA(S) TO NV CACHE PINNED SET
+ */
+static unsigned int ata_format_dsm_trim_descr(struct scsi_cmnd *cmd, u32 num,
+ u64 sector, u32 count)
+{
+   __le64 *buffer;
+   u32 i = 0, used_bytes;
+   unsigned long flags;
+
+   BUILD_BUG_ON(512 > ATA_SCSI_RBUF_SIZE);
+
+   spin_lock_irqsave(_scsi_rbuf_lock, flags);
+   buffer = ((void *)ata_scsi_rbuf);
+   while (i < num) {
+   u64 entry = sector |
+   ((u64)(count > 0x ? 0x : count) << 48);
+   buffer[i++] = __cpu_to_le64(entry);
+   if (count <= 0x)
+   break;
+   count -= 0x;
+   sector += 0x;
+   }
+
+   used_bytes = ALIGN(i * 8, 512);
+   memset(buffer + i, 0, used_bytes - i * 8);
+   sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buffer, 512);
+   spin_unlock_irqrestore(_scsi_rbuf_lock, flags);
+
+   return used_bytes;
+}
+
 static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
 {
struct ata_taskfile *tf = >tf;
@@ -3290,8 +3338,8 @@ static unsigned int ata_scsi_write_same_xlat(struct 
ata_queued_cmd *qc)
const u8 *cdb = scmd->cmnd;
u64 block;
u32 n_block;
+   const u32 trmax = ATA_MAX_TRIM_RNUM;
u32 size;
-   void *buf;
u16 fp;
u8 bp = 0xff;
 
@@ -3319,10 +3367,8 @@ static unsigned int ata_scsi_write_same_xlat(struct 
ata_queued_cmd *qc)
if (!scsi_sg_count(scmd))
goto invalid_param_len;
 
-   buf = page_address(sg_page(scsi_sglist(scmd)));
-
-   if (n_block <= 65535 * ATA_MAX_TRIM_RNUM) {
-   size = ata_set_lba_range_entries(buf, ATA_MAX_TRIM_RNUM, block, 
n_block);
+   if (n_block <= 0x * trmax) {
+   size = ata_format_dsm_trim_descr(scmd, trmax, block, n_block);
} else {
fp = 2;
goto invalid_fld;
diff --git a/include/linux/ata.h b/include/linux/ata.h
index adbc812..45a1d71 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -1071,32 +1071,6 @@ static inline void ata_id_to_hd_driveid(u16 *id)
 #endif
 }
 
-/*
- * Write LBA Range Entries to the buffer that will cover the extent from
- * sector to sector + count.  This is used for TRIM and for ADD LBA(S)
- * TO NV CACHE PINNED SET.
- */
-static inline unsigned ata_set_lba_range_entries(void *_buffer,
-   unsigned num, u64 sector, unsigned long count)
-{
-   __le64 *buffer = _buffer;
-   unsigned i = 0, used_bytes;
-
-   while (i < num) {
-   u64 entry = sector |
-   ((u64)(count > 0x ? 0x : count) << 48);
-   buffer[i++] = __cpu_to_le64(entry);
-   if (count <= 0x)
-   break;
-   count -= 0x;
-   sector += 0x;
-   }
-
-   used_bytes = ALIGN(i * 8, 512);
-   memset(buffer + i, 0, used_bytes - i * 8);
-   return used_bytes;
-}
-
 static inline bool ata_ok(u8 status)
 {
return ((status & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ | ATA_ERR))
-- 
2.9.3



[v13 PATCH 1/5] Documentation: bindings: add dt doc for Rockchip USB Type-C PHY

2016-08-21 Thread Chris Zhong
This patch adds a binding that describes the Rockchip USB Type-C PHY
for rk3399

Signed-off-by: Chris Zhong 
Reviewed-by: Tomasz Figa 
Reviewed-by: Kever Yang 
Reviewed-by: Guenter Roeck 
Acked-by: Rob Herring 

---

Changes in v13: None
Changes in v12: None
Changes in v11:
- make a clearer emarcation between usb phy and dp phy

Changes in v10:
- remove rockchip,uphy-dp-sel property

Changes in v9:
- change #phy-cells to 1

Changes in v8: None
Changes in v7: None
Changes in v6:
- add assigned-clocks and assigned-clock-rates

Changes in v5: None
Changes in v4:
- add a #phy-cells node

Changes in v3:
- use compatible: rockchip,rk3399-typec-phy
- use dashes instead of underscores.

Changes in v2:
- add some registers description

Changes in v1:
- add extcon node description
- move the registers in phy driver
- remove the suffix of reset

 .../devicetree/bindings/phy/phy-rockchip-typec.txt | 101 +
 1 file changed, 101 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt

diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt 
b/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt
new file mode 100644
index 000..6ea867e
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt
@@ -0,0 +1,101 @@
+* ROCKCHIP type-c PHY
+-
+
+Required properties:
+ - compatible : must be "rockchip,rk3399-typec-phy"
+ - reg: Address and length of the usb phy control register set
+ - rockchip,grf : phandle to the syscon managing the "general
+   register files"
+ - clocks : phandle + clock specifier for the phy clocks
+ - clock-names : string, clock name, must be "tcpdcore", "tcpdphy-ref";
+ - assigned-clocks: main clock, should be < SCLK_UPHY0_TCPDCORE> or
+   < SCLK_UPHY1_TCPDCORE>;
+ - assigned-clock-rates : the phy core clk frequency, shall be: 5000
+ - resets : a list of phandle + reset specifier pairs
+ - reset-names : string reset name, must be:
+"uphy", "uphy-pipe", "uphy-tcphy"
+ - extcon : extcon specifier for the Power Delivery
+
+Note, there are 2 type-c phys for RK3399, and they are almost identical, except
+these registers(description below), every register node contains 3 sections:
+offset, enable bit, write mask bit.
+ - rockchip,typec-conn-dir : the register of type-c connector direction,
+   for type-c phy0, it must be <0xe580 0 16>;
+   for type-c phy1, it must be <0xe58c 0 16>;
+ - rockchip,usb3tousb2-en : the register of type-c force usb3 to usb2 enable
+   control.
+   for type-c phy0, it must be <0xe580 3 19>;
+   for type-c phy1, it must be <0xe58c 3 19>;
+ - rockchip,external-psm : the register of type-c phy external psm clock
+   selection.
+   for type-c phy0, it must be <0xe588 14 30>;
+   for type-c phy1, it must be <0xe594 14 30>;
+ - rockchip,pipe-status : the register of type-c phy pipe status.
+   for type-c phy0, it must be <0xe5c0 0 0>;
+   for type-c phy1, it must be <0xe5c0 16 16>;
+
+Required nodes : a sub-node is required for each port the phy provides.
+The sub-node name is used to identify dp or usb3 port,
+and shall be the following entries:
+   * "dp-port" : the name of DP port.
+   * "usb3-port" : the name of USB3 port.
+
+Required properties (port (child) node):
+- #phy-cells : must be 0, See ./phy-bindings.txt for details.
+
+Example:
+   tcphy0: phy@ff7c {
+   compatible = "rockchip,rk3399-typec-phy";
+   reg = <0x0 0xff7c 0x0 0x4>;
+   rockchip,grf = <>;
+   extcon = <>;
+   clocks = < SCLK_UPHY0_TCPDCORE>,
+< SCLK_UPHY0_TCPDPHY_REF>;
+   clock-names = "tcpdcore", "tcpdphy-ref";
+   assigned-clocks = < SCLK_UPHY0_TCPDCORE>;
+   assigned-clock-rates = <5000>;
+   resets = < SRST_UPHY0>,
+< SRST_UPHY0_PIPE_L00>,
+< SRST_P_UPHY0_TCPHY>;
+   reset-names = "uphy", "uphy-pipe", "uphy-tcphy";
+   rockchip,typec-conn-dir = <0xe580 0 16>;
+   rockchip,usb3tousb2-en = <0xe580 3 19>;
+   rockchip,external-psm = <0xe588 14 30>;
+   rockchip,pipe-status = <0xe5c0 0 0>;
+
+   tcphy0_dp: dp-port {
+   #phy-cells = <0>;
+   };
+
+   tcphy0_usb3: usb3-port {
+   #phy-cells = <0>;
+   };
+   };
+
+   tcphy1: phy@ff80 {
+   compatible = "rockchip,rk3399-typec-phy";
+   reg = <0x0 0xff80 0x0 0x4>;
+   rockchip,grf = <>;
+   extcon = <>;
+   clocks = < SCLK_UPHY1_TCPDCORE>,
+< SCLK_UPHY1_TCPDPHY_REF>;
+   clock-names = "tcpdcore", 

[PATCH v3] time: alarmtimer: Add the trcepoints for alarmtimer

2016-08-21 Thread Baolin Wang
For system debugging, we usually want to know who sets one alarm timer, the
time of the timer, when the timer started and fired and so on. Thus adding
tracepoints can help us trace the alarmtimer information.

For example, when we debug the system supend/resume, if the system is always
resumed by RTC alarm, we can find out which process set the alarm timer to
resume system by below trace log:

..
Binder:2976_6-3473  [005] d..2  1076.587732: alarmtimer_start: 
process:Binder:2976_6
alarmtimer type:ALARM_BOOTTIME expires:123415400 time: 1970-1-1 0:20:35

Binder:2976_7-3480  [002] d..2  1076.592707: alarmtimer_cancel: 
process:Binder:2976_7
alarmtimer type:ALARM_BOOTTIME expires:13254630600 time: 2012-1-2 0:11:0

Binder:2976_7-3480  [002] d..2  1076.592731: alarmtimer_start: 
process:Binder:2976_7
alarmtimer type:ALARM_BOOTTIME expires:13253780400 time: 2012-1-1 0:34:0

system_server-2976  [003] d..2  1076.605587: alarmtimer_cancel: 
process:system_server
alarmtimer type:ALARM_BOOTTIME expires:123415400 time: 1970-1-1 0:20:35

system_server-2976  [003] d..2  1076.605608: alarmtimer_start: 
process:system_server
alarmtimer type:ALARM_BOOTTIME expires:123415500 time: 1970-1-1 0:20:35

system_server-3000  [002] ...1  1087.737565: alarmtimer_suspend: alarmtimer 
type:ALARM_BOOTTIME
expires time: 2012-1-1 0:34:0
..

>From the trace log, we can find out the 'Binder:2976_7' process set one alarm
timer which resumes the system.

Signed-off-by: Baolin Wang 
---
Changes since v2:
 - Add TRACE_DEFINE_ENUM() macros.
 - Change the time variables type to save space in the ring buffer.
 - Add trace_alarmtimer_suspend_enabled() in case of tracing is not enabled.

Changes since v1:
 - Fix the kbuild error.
 - Modify the changelog with adding trace log.
---
 include/trace/events/alarmtimer.h |  137 +
 kernel/time/alarmtimer.c  |   23 ++-
 2 files changed, 157 insertions(+), 3 deletions(-)
 create mode 100644 include/trace/events/alarmtimer.h

diff --git a/include/trace/events/alarmtimer.h 
b/include/trace/events/alarmtimer.h
new file mode 100644
index 000..6a34bc9
--- /dev/null
+++ b/include/trace/events/alarmtimer.h
@@ -0,0 +1,137 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM alarmtimer
+
+#if !defined(_TRACE_ALARMTIMER_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_ALARMTIMER_H
+
+#include 
+#include 
+#include 
+
+TRACE_DEFINE_ENUM(ALARM_REALTIME);
+TRACE_DEFINE_ENUM(ALARM_BOOTTIME);
+
+#define show_alarm_type(type)  __print_flags(type, " | ",  \
+   { 1 << ALARM_REALTIME, "ALARM_REALTIME" },  \
+   { 1 << ALARM_BOOTTIME, "ALARM_BOOTTIME" })
+
+DECLARE_EVENT_CLASS(alarm_setting,
+
+   TP_PROTO(struct rtc_time *rtc_time, int flag),
+
+   TP_ARGS(rtc_time, flag),
+
+   TP_STRUCT__entry(
+   __field(unsigned char, second)
+   __field(unsigned char, minute)
+   __field(unsigned char, hour)
+   __field(unsigned char, day)
+   __field(unsigned char, mon)
+   __field(unsigned short, year)
+   __field(unsigned char, alarm_type)
+   ),
+
+   TP_fast_assign(
+   __entry->second = rtc_time->tm_sec;
+   __entry->minute = rtc_time->tm_min;
+   __entry->hour = rtc_time->tm_hour;
+   __entry->day = rtc_time->tm_mday;
+   __entry->mon = rtc_time->tm_mon;
+   __entry->year = rtc_time->tm_year;
+   __entry->alarm_type = flag;
+   ),
+
+   TP_printk("alarmtimer type:%s expires time: %hu-%u-%u %u:%u:%u",
+ show_alarm_type((1 << __entry->alarm_type)),
+ __entry->year + 1900,
+ __entry->mon + 1,
+ __entry->day,
+ __entry->hour,
+ __entry->minute,
+ __entry->second
+   )
+);
+
+DEFINE_EVENT(alarm_setting, alarmtimer_suspend,
+
+   TP_PROTO(struct rtc_time *time, int flag),
+
+   TP_ARGS(time, flag)
+);
+
+DECLARE_EVENT_CLASS(alarm_processing,
+
+   TP_PROTO(struct alarm *alarm, char *process_name),
+
+   TP_ARGS(alarm, process_name),
+
+   TP_STRUCT__entry(
+   __field(unsigned long long, expires)
+   __field(unsigned char, second)
+   __field(unsigned char, minute)
+   __field(unsigned char, hour)
+   __field(unsigned char, day)
+   __field(unsigned char, mon)
+   __field(unsigned short, year)
+   __field(unsigned char, alarm_type)
+   __string(name, process_name)
+   ),
+
+   TP_fast_assign(
+   __entry->expires = alarm->node.expires.tv64;
+   __entry->second = rtc_ktime_to_tm(alarm->node.expires).tm_sec;
+   __entry->minute = rtc_ktime_to_tm(alarm->node.expires).tm_min;
+   __entry->hour = 

[PATCH v6 0/4] SCT Write Same

2016-08-21 Thread Shaun Tancheff
At some point the method of issuing Write Same for ATA drives changed.
Currently write same is commonly available via SCT so expose the SCT
capabilities and use SCT Write Same when it is available.

This is useful for zoned based media that prefers to support discard
with lbprz set, aka discard zeroes data by mapping discard operations to
reset write pointer operations. Conventional zones that do not support
reset write pointer can still honor the discard zeroes data by issuing
a write same over the zone.

It may also be nice to know if various controllers that currently
disable WRITE SAME will work with the SCT Write Same code path:
  aacraid, arcmsr, megaraid, 3w-9xxx, 3w-sas, 3w-, gdth, hpsa, ips,
  megaraid, pmcraid, storvsc_drv

This patch against v4.8-rc2 is also at
https://github.com/stancheff/linux/tree/v4.8-rc2%2Bbiof.v9

g...@github.com:stancheff/linux.git v4.8-rc2+biof.v9

v6:
 - Fix bisect bug reported by Tom Yan 
 - Change to use sg_copy_from_buffer as per Christoph Hellwig 
 - Added support for a sector_size descriptor other than 512 bytes.
v5:
 - Addressed review comments
 - Report support for ZBC only for zoned devices.
 - kmap page during rewrite
 - Fix unmap set to require trim or error, if not unmap then sct write
   same or error.
v4:
 - Added partial MAINTENANCE_IN opcode simulation
 - Dropped all changes in drivers/scsi/*
 - Changed to honor the UNMAP flag -> TRIM, no UNMAP -> SCT.
v3:
 - Demux UNMAP/TRIM from WRITE SAME
v2:
 - Remove fugly ata hacking from sd.c

Shaun Tancheff (4):
  libata: Safely overwrite attached page in WRITE SAME xlat
  Add support for SCT Write Same
  SCT Write Same / DSM Trim
  SCT Write Same handle ATA_DFLAG_PIO

 drivers/ata/libata-scsi.c | 280 +-
 include/linux/ata.h   |  69 +++-
 2 files changed, 292 insertions(+), 57 deletions(-)

-- 
2.9.3



[PATCH v6 1/4] libata: Safely overwrite attached page in WRITE SAME xlat

2016-08-21 Thread Shaun Tancheff
Safely overwriting the attached page to ATA format from the SCSI formatted
variant.

Signed-off-by: Shaun Tancheff 
---
v6:
 - Fix bisect bug reported by Tom Yan 
 - Change to use sg_copy_from_buffer as per Christoph Hellwig 
v5:
 - Added prep patch to work with non-page aligned scatterlist pages
   and use kmap_atomic() to lock page during modification.

 drivers/ata/libata-scsi.c | 56 ++-
 include/linux/ata.h   | 26 --
 2 files changed, 51 insertions(+), 31 deletions(-)

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index e207b33..7990cb2 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3282,6 +3282,54 @@ static unsigned int ata_scsi_pass_thru(struct 
ata_queued_cmd *qc)
return 1;
 }
 
+/**
+ * ata_format_dsm_trim_descr() - SATL Write Same to DSM Trim
+ * @cmd: SCSI command being translated
+ * @num: Maximum number of entries (nominally 64).
+ * @sector: Starting sector
+ * @count: Total Range of request
+ *
+ * Rewrite the WRITE SAME descriptor to be a DSM TRIM little-endian formatted
+ * descriptor.
+ *
+ * Upto 64 entries of the format:
+ *   63:48 Range Length
+ *   47:0  LBA
+ *
+ *  Range Length of 0 is ignored.
+ *  LBA's should be sorted order and not overlap.
+ *
+ * NOTE: this is the same format as ADD LBA(S) TO NV CACHE PINNED SET
+ */
+static unsigned int ata_format_dsm_trim_descr(struct scsi_cmnd *cmd, u32 num,
+ u64 sector, u32 count)
+{
+   __le64 *buffer;
+   u32 i = 0, used_bytes;
+   unsigned long flags;
+
+   BUILD_BUG_ON(512 > ATA_SCSI_RBUF_SIZE);
+
+   spin_lock_irqsave(_scsi_rbuf_lock, flags);
+   buffer = ((void *)ata_scsi_rbuf);
+   while (i < num) {
+   u64 entry = sector |
+   ((u64)(count > 0x ? 0x : count) << 48);
+   buffer[i++] = __cpu_to_le64(entry);
+   if (count <= 0x)
+   break;
+   count -= 0x;
+   sector += 0x;
+   }
+
+   used_bytes = ALIGN(i * 8, 512);
+   memset(buffer + i, 0, used_bytes - i * 8);
+   sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buffer, 512);
+   spin_unlock_irqrestore(_scsi_rbuf_lock, flags);
+
+   return used_bytes;
+}
+
 static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
 {
struct ata_taskfile *tf = >tf;
@@ -3290,8 +3338,8 @@ static unsigned int ata_scsi_write_same_xlat(struct 
ata_queued_cmd *qc)
const u8 *cdb = scmd->cmnd;
u64 block;
u32 n_block;
+   const u32 trmax = ATA_MAX_TRIM_RNUM;
u32 size;
-   void *buf;
u16 fp;
u8 bp = 0xff;
 
@@ -3319,10 +3367,8 @@ static unsigned int ata_scsi_write_same_xlat(struct 
ata_queued_cmd *qc)
if (!scsi_sg_count(scmd))
goto invalid_param_len;
 
-   buf = page_address(sg_page(scsi_sglist(scmd)));
-
-   if (n_block <= 65535 * ATA_MAX_TRIM_RNUM) {
-   size = ata_set_lba_range_entries(buf, ATA_MAX_TRIM_RNUM, block, 
n_block);
+   if (n_block <= 0x * trmax) {
+   size = ata_format_dsm_trim_descr(scmd, trmax, block, n_block);
} else {
fp = 2;
goto invalid_fld;
diff --git a/include/linux/ata.h b/include/linux/ata.h
index adbc812..45a1d71 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -1071,32 +1071,6 @@ static inline void ata_id_to_hd_driveid(u16 *id)
 #endif
 }
 
-/*
- * Write LBA Range Entries to the buffer that will cover the extent from
- * sector to sector + count.  This is used for TRIM and for ADD LBA(S)
- * TO NV CACHE PINNED SET.
- */
-static inline unsigned ata_set_lba_range_entries(void *_buffer,
-   unsigned num, u64 sector, unsigned long count)
-{
-   __le64 *buffer = _buffer;
-   unsigned i = 0, used_bytes;
-
-   while (i < num) {
-   u64 entry = sector |
-   ((u64)(count > 0x ? 0x : count) << 48);
-   buffer[i++] = __cpu_to_le64(entry);
-   if (count <= 0x)
-   break;
-   count -= 0x;
-   sector += 0x;
-   }
-
-   used_bytes = ALIGN(i * 8, 512);
-   memset(buffer + i, 0, used_bytes - i * 8);
-   return used_bytes;
-}
-
 static inline bool ata_ok(u8 status)
 {
return ((status & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ | ATA_ERR))
-- 
2.9.3



[v13 PATCH 1/5] Documentation: bindings: add dt doc for Rockchip USB Type-C PHY

2016-08-21 Thread Chris Zhong
This patch adds a binding that describes the Rockchip USB Type-C PHY
for rk3399

Signed-off-by: Chris Zhong 
Reviewed-by: Tomasz Figa 
Reviewed-by: Kever Yang 
Reviewed-by: Guenter Roeck 
Acked-by: Rob Herring 

---

Changes in v13: None
Changes in v12: None
Changes in v11:
- make a clearer emarcation between usb phy and dp phy

Changes in v10:
- remove rockchip,uphy-dp-sel property

Changes in v9:
- change #phy-cells to 1

Changes in v8: None
Changes in v7: None
Changes in v6:
- add assigned-clocks and assigned-clock-rates

Changes in v5: None
Changes in v4:
- add a #phy-cells node

Changes in v3:
- use compatible: rockchip,rk3399-typec-phy
- use dashes instead of underscores.

Changes in v2:
- add some registers description

Changes in v1:
- add extcon node description
- move the registers in phy driver
- remove the suffix of reset

 .../devicetree/bindings/phy/phy-rockchip-typec.txt | 101 +
 1 file changed, 101 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt

diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt 
b/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt
new file mode 100644
index 000..6ea867e
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt
@@ -0,0 +1,101 @@
+* ROCKCHIP type-c PHY
+-
+
+Required properties:
+ - compatible : must be "rockchip,rk3399-typec-phy"
+ - reg: Address and length of the usb phy control register set
+ - rockchip,grf : phandle to the syscon managing the "general
+   register files"
+ - clocks : phandle + clock specifier for the phy clocks
+ - clock-names : string, clock name, must be "tcpdcore", "tcpdphy-ref";
+ - assigned-clocks: main clock, should be < SCLK_UPHY0_TCPDCORE> or
+   < SCLK_UPHY1_TCPDCORE>;
+ - assigned-clock-rates : the phy core clk frequency, shall be: 5000
+ - resets : a list of phandle + reset specifier pairs
+ - reset-names : string reset name, must be:
+"uphy", "uphy-pipe", "uphy-tcphy"
+ - extcon : extcon specifier for the Power Delivery
+
+Note, there are 2 type-c phys for RK3399, and they are almost identical, except
+these registers(description below), every register node contains 3 sections:
+offset, enable bit, write mask bit.
+ - rockchip,typec-conn-dir : the register of type-c connector direction,
+   for type-c phy0, it must be <0xe580 0 16>;
+   for type-c phy1, it must be <0xe58c 0 16>;
+ - rockchip,usb3tousb2-en : the register of type-c force usb3 to usb2 enable
+   control.
+   for type-c phy0, it must be <0xe580 3 19>;
+   for type-c phy1, it must be <0xe58c 3 19>;
+ - rockchip,external-psm : the register of type-c phy external psm clock
+   selection.
+   for type-c phy0, it must be <0xe588 14 30>;
+   for type-c phy1, it must be <0xe594 14 30>;
+ - rockchip,pipe-status : the register of type-c phy pipe status.
+   for type-c phy0, it must be <0xe5c0 0 0>;
+   for type-c phy1, it must be <0xe5c0 16 16>;
+
+Required nodes : a sub-node is required for each port the phy provides.
+The sub-node name is used to identify dp or usb3 port,
+and shall be the following entries:
+   * "dp-port" : the name of DP port.
+   * "usb3-port" : the name of USB3 port.
+
+Required properties (port (child) node):
+- #phy-cells : must be 0, See ./phy-bindings.txt for details.
+
+Example:
+   tcphy0: phy@ff7c {
+   compatible = "rockchip,rk3399-typec-phy";
+   reg = <0x0 0xff7c 0x0 0x4>;
+   rockchip,grf = <>;
+   extcon = <>;
+   clocks = < SCLK_UPHY0_TCPDCORE>,
+< SCLK_UPHY0_TCPDPHY_REF>;
+   clock-names = "tcpdcore", "tcpdphy-ref";
+   assigned-clocks = < SCLK_UPHY0_TCPDCORE>;
+   assigned-clock-rates = <5000>;
+   resets = < SRST_UPHY0>,
+< SRST_UPHY0_PIPE_L00>,
+< SRST_P_UPHY0_TCPHY>;
+   reset-names = "uphy", "uphy-pipe", "uphy-tcphy";
+   rockchip,typec-conn-dir = <0xe580 0 16>;
+   rockchip,usb3tousb2-en = <0xe580 3 19>;
+   rockchip,external-psm = <0xe588 14 30>;
+   rockchip,pipe-status = <0xe5c0 0 0>;
+
+   tcphy0_dp: dp-port {
+   #phy-cells = <0>;
+   };
+
+   tcphy0_usb3: usb3-port {
+   #phy-cells = <0>;
+   };
+   };
+
+   tcphy1: phy@ff80 {
+   compatible = "rockchip,rk3399-typec-phy";
+   reg = <0x0 0xff80 0x0 0x4>;
+   rockchip,grf = <>;
+   extcon = <>;
+   clocks = < SCLK_UPHY1_TCPDCORE>,
+< SCLK_UPHY1_TCPDPHY_REF>;
+   clock-names = "tcpdcore", "tcpdphy-ref";
+   assigned-clocks = < SCLK_UPHY1_TCPDCORE>;
+   assigned-clock-rates = 

[PATCH v3] time: alarmtimer: Add the trcepoints for alarmtimer

2016-08-21 Thread Baolin Wang
For system debugging, we usually want to know who sets one alarm timer, the
time of the timer, when the timer started and fired and so on. Thus adding
tracepoints can help us trace the alarmtimer information.

For example, when we debug the system supend/resume, if the system is always
resumed by RTC alarm, we can find out which process set the alarm timer to
resume system by below trace log:

..
Binder:2976_6-3473  [005] d..2  1076.587732: alarmtimer_start: 
process:Binder:2976_6
alarmtimer type:ALARM_BOOTTIME expires:123415400 time: 1970-1-1 0:20:35

Binder:2976_7-3480  [002] d..2  1076.592707: alarmtimer_cancel: 
process:Binder:2976_7
alarmtimer type:ALARM_BOOTTIME expires:13254630600 time: 2012-1-2 0:11:0

Binder:2976_7-3480  [002] d..2  1076.592731: alarmtimer_start: 
process:Binder:2976_7
alarmtimer type:ALARM_BOOTTIME expires:13253780400 time: 2012-1-1 0:34:0

system_server-2976  [003] d..2  1076.605587: alarmtimer_cancel: 
process:system_server
alarmtimer type:ALARM_BOOTTIME expires:123415400 time: 1970-1-1 0:20:35

system_server-2976  [003] d..2  1076.605608: alarmtimer_start: 
process:system_server
alarmtimer type:ALARM_BOOTTIME expires:123415500 time: 1970-1-1 0:20:35

system_server-3000  [002] ...1  1087.737565: alarmtimer_suspend: alarmtimer 
type:ALARM_BOOTTIME
expires time: 2012-1-1 0:34:0
..

>From the trace log, we can find out the 'Binder:2976_7' process set one alarm
timer which resumes the system.

Signed-off-by: Baolin Wang 
---
Changes since v2:
 - Add TRACE_DEFINE_ENUM() macros.
 - Change the time variables type to save space in the ring buffer.
 - Add trace_alarmtimer_suspend_enabled() in case of tracing is not enabled.

Changes since v1:
 - Fix the kbuild error.
 - Modify the changelog with adding trace log.
---
 include/trace/events/alarmtimer.h |  137 +
 kernel/time/alarmtimer.c  |   23 ++-
 2 files changed, 157 insertions(+), 3 deletions(-)
 create mode 100644 include/trace/events/alarmtimer.h

diff --git a/include/trace/events/alarmtimer.h 
b/include/trace/events/alarmtimer.h
new file mode 100644
index 000..6a34bc9
--- /dev/null
+++ b/include/trace/events/alarmtimer.h
@@ -0,0 +1,137 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM alarmtimer
+
+#if !defined(_TRACE_ALARMTIMER_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_ALARMTIMER_H
+
+#include 
+#include 
+#include 
+
+TRACE_DEFINE_ENUM(ALARM_REALTIME);
+TRACE_DEFINE_ENUM(ALARM_BOOTTIME);
+
+#define show_alarm_type(type)  __print_flags(type, " | ",  \
+   { 1 << ALARM_REALTIME, "ALARM_REALTIME" },  \
+   { 1 << ALARM_BOOTTIME, "ALARM_BOOTTIME" })
+
+DECLARE_EVENT_CLASS(alarm_setting,
+
+   TP_PROTO(struct rtc_time *rtc_time, int flag),
+
+   TP_ARGS(rtc_time, flag),
+
+   TP_STRUCT__entry(
+   __field(unsigned char, second)
+   __field(unsigned char, minute)
+   __field(unsigned char, hour)
+   __field(unsigned char, day)
+   __field(unsigned char, mon)
+   __field(unsigned short, year)
+   __field(unsigned char, alarm_type)
+   ),
+
+   TP_fast_assign(
+   __entry->second = rtc_time->tm_sec;
+   __entry->minute = rtc_time->tm_min;
+   __entry->hour = rtc_time->tm_hour;
+   __entry->day = rtc_time->tm_mday;
+   __entry->mon = rtc_time->tm_mon;
+   __entry->year = rtc_time->tm_year;
+   __entry->alarm_type = flag;
+   ),
+
+   TP_printk("alarmtimer type:%s expires time: %hu-%u-%u %u:%u:%u",
+ show_alarm_type((1 << __entry->alarm_type)),
+ __entry->year + 1900,
+ __entry->mon + 1,
+ __entry->day,
+ __entry->hour,
+ __entry->minute,
+ __entry->second
+   )
+);
+
+DEFINE_EVENT(alarm_setting, alarmtimer_suspend,
+
+   TP_PROTO(struct rtc_time *time, int flag),
+
+   TP_ARGS(time, flag)
+);
+
+DECLARE_EVENT_CLASS(alarm_processing,
+
+   TP_PROTO(struct alarm *alarm, char *process_name),
+
+   TP_ARGS(alarm, process_name),
+
+   TP_STRUCT__entry(
+   __field(unsigned long long, expires)
+   __field(unsigned char, second)
+   __field(unsigned char, minute)
+   __field(unsigned char, hour)
+   __field(unsigned char, day)
+   __field(unsigned char, mon)
+   __field(unsigned short, year)
+   __field(unsigned char, alarm_type)
+   __string(name, process_name)
+   ),
+
+   TP_fast_assign(
+   __entry->expires = alarm->node.expires.tv64;
+   __entry->second = rtc_ktime_to_tm(alarm->node.expires).tm_sec;
+   __entry->minute = rtc_ktime_to_tm(alarm->node.expires).tm_min;
+   __entry->hour = rtc_ktime_to_tm(alarm->node.expires).tm_hour;
+   

[v13 PATCH 0/5] Rockchip Type-C and DisplayPort driver

2016-08-21 Thread Chris Zhong

Hi all

This series patch is for rockchip Type-C phy and DisplayPort controller
driver.

The USB Type-C PHY is designed to support the USB3 and DP applications.
The PHY basically has two main components: USB3 and DisplyPort. USB3
operates in SuperSpeed mode and the DP can operate at RBR, HBR and HBR2
data rates. The Type-C cable orientation detection and Power Delivery
(PD) is accomplished using a PD PHY or a exernal PD chip.

The DP controller is compliant with DisplayPort Specification,
Version 1.3, This IP is compatible with the rockchip type-c PHY IP.
There is a uCPU in DP controller, it need a firmware to work, please
put the firmware file[0] rockchip/dptx.bin to
/lib/firmware/rockchip/dptx.bin. The uCPU in charge of aux communication
and link training, the host use mailbox to communicate with the ucpu.

The DP contoller has register a notification with extcon API, to get the
alt mode from PD, the PD driver need call the devm_extcon_dev_allocate
to create a extcon device and use extcon_set_state to notify DP
controller. And call extcon_set_cable_property to set orientation.

About the DP audio, cdn-dp registered 2 DAIs: 0 is I2S, 1 is SPDIF.
We can reference them in simple-card.

This series is based on Mark Yao's branch[1] and Chanwoo Choi's
extcon-next branch[2], and Guenter's patch about
EXTCON_PROP_USB_SUPERSPEED[3], and Heiko's clk patch[4].

I test this patches on the rk3399-evb board, with a fusb302 driver,
this branch has no rk3399.dtsi, so the patch about dts is not included
in this series.

>From V9, the Type-C PHY is split into two PHYs: DP and USB3. The PHY
will be init, no matter which PHY be power_on. The DP module will
enter A2 mode (standby mode) after phy_init, if DP PHY is powered on,
the DP module will enter to A0 mode(running mode). Then if DP PHY is
powered off, DP module will back to A2 mode. If everything is
un-plugged, phy will be deinit.

[0]
kernel/git/firmware/linux-firmware.git
[1]
https://github.com/markyzq/kernel-drm-rockchip/tree/drm-rockchip-next-2016-05-23
[2]
https://git.kernel.org/cgit/linux/kernel/git/chanwoo/extcon.git extcon-next
[3]
https://patchwork.kernel.org/patch/9280955/
[4]
https://git.kernel.org/cgit/linux/kernel/git/mmind/linux-rockchip.git
/commit/?h=v4.9-clk/next=54479449c801e46ee2b6ba08e2f19cd810f74f94
https://git.kernel.org/cgit/linux/kernel/git/mmind/linux-rockchip.git
/commit/?h=v4.8-clk/fixes=a3f457d9636b3f5ae4fc6502cb0c95f60f5e342b


Changes in v13:
- do not return err if nothing connected with Type-C, when usb phy power on,
  since the USB core driver will call phy power without USB3 device connected.
- add dptx and apb reset
- support suspend/resume
- switch power domain dynamically
- re-training when hpd signal is triggered

Changes in v12:
- enable DP+USB3 mode, only when EXTCON_PROP_USB_SUPERSPEED equal 1
  and DP is attached
- use EXTCON_PROP_USB_SUPERSPEED to replace EXTCON_USB_HOST

Changes in v11:
- make a clearer emarcation between usb phy and dp phy
- make a clearer demarcation between usb phy and dp phy.
- split the dp-phy and usb3-phy to 2 child-node
- refer dp phy
- add best_encoder back, since it required by drm_atomic_helper_check

Changes in v10:
- remove rockchip,uphy-dp-sel property
- do not control dp select and hpd config in phy driver
- remove rockchip,uphy-dp-sel property
- add pclk_vio_grf clock
- remove best_encoder ops
- support read sink count from DPCD
- control the grf_clk in DP

Changes in v9:
- change #phy-cells to 1
- the new_mode should be int not u8
- move mutex_lock(>lock); to earlier place. in
  rockchip_usb3_phy_power_off
- better mutex lock for phy mode and flip
- split the Type-C PHY into two PHYs: USB3 and DP
- change #phy-cells to 1
- modify the reference phy = < 0>, < 0>;
- do not need reset the phy before power_on
- add a orientation information for set_capability
- retry to read dpcd in 10 seconds

Changes in v8:
- set the default cable id to EXTCON_USB_HOST
- optimization Error log
- optimization the err log

Changes in v7:
- support new API of extcon
- support firmware standby when no dptx connection
- optimization the calculation of tu size and valid symbol

Changes in v6:
- add assigned-clocks and assigned-clock-rates
- delete the support of PIN_ASSIGN_A/B
- set the default mode to MODE_DFP_USB
- disable DP PLL at USB3 only mode
- add assigned-clocks and assigned-clock-rates
- add power-domains
- add a port struct
- select SND_SOC_HDMI_CODEC
- force reset the phy when hpd detected

Changes in v5:
- support get property from extcon
- remove PIN ASSIGN A/B support
- alphabetical order
- do not use long, use u32 or u64
- return MODE_CLOCK_HIGH when requested > actual
- Optimized Coding Style
- add a formula to get better tu size and symbol value.
- modify according to Sean Paul's comments
- fixed the fw_wait always 0

Changes in v4:
- add a #phy-cells node
- select EXTCON
- use phy framework to control the USB3 and DP function
- rename PIN_MAP_ to PIN_ASSIGN_
- add a reset node
- support 2 phys
- use 

[v13 PATCH 4/5] Documentation: bindings: add dt documentation for cdn DP controller

2016-08-21 Thread Chris Zhong
This patch adds a binding that describes the cdn DP controller for
rk3399.

Signed-off-by: Chris Zhong 
Acked-by: Rob Herring 
Reviewed-by: Guenter Roeck 

---

Changes in v13:
- add dptx and apb reset

Changes in v12: None
Changes in v11:
- refer dp phy

Changes in v10:
- add pclk_vio_grf clock

Changes in v9:
- modify the reference phy = < 0>, < 0>;

Changes in v8: None
Changes in v7: None
Changes in v6:
- add assigned-clocks and assigned-clock-rates
- add power-domains

Changes in v5: None
Changes in v4:
- add a reset node
- support 2 phys

Changes in v3:
- add SoC specific compatible string
- remove reg = <1>;

Changes in v2: None
Changes in v1:
- add extcon node description
- add #sound-dai-cells description

 .../bindings/display/rockchip/cdn-dp-rockchip.txt  | 75 ++
 1 file changed, 75 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt 
b/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
new file mode 100644
index 000..9bd2c13
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
@@ -0,0 +1,75 @@
+Rockchip RK3399 specific extensions to the cdn Display Port
+
+
+Required properties:
+- compatible: must be "rockchip,rk3399-cdn-dp"
+
+- reg: physical base address of the controller and length
+
+- clocks: from common clock binding: handle to dp clock.
+
+- clock-names: from common clock binding:
+  Required elements: "core-clk" "pclk" "spdif" "grf"
+
+- resets : a list of phandle + reset specifier pairs
+- reset-names : string reset name, must be:
+   "spdif", "dptx", "apb".
+- power-domains : power-domain property defined with a phandle
+ to respective power domain.
+- assigned-clocks: main clock, should be < SCLK_DP_CORE>
+- assigned-clock-rates : the DP core clk frequency, shall be: 1
+
+- rockchip,grf: this soc should set GRF regs, so need get grf here.
+
+- ports: contain a port nodes with endpoint definitions as defined in
+Documentation/devicetree/bindings/media/video-interfaces.txt.
+contained 2 endpoints, connecting to the output of vop.
+
+- phys: from general PHY binding: the phandle for the PHY device.
+
+- extcon: extcon specifier for the Power Delivery
+
+- #sound-dai-cells = it must be 1 if your system is using 2 DAIs: I2S, SPDIF
+
+---
+
+Example:
+   cdn_dp: dp@fec0 {
+   compatible = "rockchip,rk3399-cdn-dp";
+   reg = <0x0 0xfec0 0x0 0x10>;
+   interrupts = ;
+   clocks = < SCLK_DP_CORE>, < PCLK_DP_CTRL>,
+< SCLK_SPDIF_REC_DPTX>, < PCLK_VIO_GRF>;
+   clock-names = "core-clk", "pclk", "spdif", "grf";
+   assigned-clocks = < SCLK_DP_CORE>;
+   assigned-clock-rates = <1>;
+   power-domains = < RK3399_PD_HDCP>;
+   phys = <_dp>, <_dp>;
+   resets = < SRST_DPTX_SPDIF_REC>, < SRST_P_UPHY0_DPTX>,
+< SRST_P_UPHY0_APB>;
+   reset-names = "spdif", "dptx", "apb";
+   extcon = <>, <>;
+   rockchip,grf = <>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   #sound-dai-cells = <1>;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   dp_in: port {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   dp_in_vopb: endpoint@0 {
+   reg = <0>;
+   remote-endpoint = <_out_dp>;
+   };
+
+   dp_in_vopl: endpoint@1 {
+   reg = <1>;
+   remote-endpoint = <_out_dp>;
+   };
+   };
+   };
+   };
-- 
1.9.1



[v13 PATCH 5/5] drm/rockchip: cdn-dp: add cdn DP support for rk3399

2016-08-21 Thread Chris Zhong
Add support for cdn DP controller which is embedded in the rk3399
SoCs. The DP is compliant with DisplayPort Specification,
Version 1.3, This IP is compatible with the rockchip type-c PHY IP.
There is a uCPU in DP controller, it need a firmware to work,
please put the firmware file to /lib/firmware/rockchip/dptx.bin. The
uCPU in charge of aux communication and link training, the host use
mailbox to communicate with the ucpu.
The dclk pin_pol of vop must not be invert for DP.

Signed-off-by: Chris Zhong 
Reviewed-by: Sean Paul 
Acked-by: Mark Yao 

---

Changes in v13:
- support suspend/resume
- switch power domain dynamically
- re-training when hpd signal is triggered

Changes in v12:
- use EXTCON_PROP_USB_SUPERSPEED to replace EXTCON_USB_HOST

Changes in v11:
- add best_encoder back, since it required by drm_atomic_helper_check

Changes in v10:
- remove best_encoder ops
- support read sink count from DPCD
- control the grf_clk in DP

Changes in v9:
- do not need reset the phy before power_on
- add a orientation information for set_capability
- retry to read dpcd in 10 seconds

Changes in v8:
- optimization the err log

Changes in v7:
- support firmware standby when no dptx connection
- optimization the calculation of tu size and valid symbol

Changes in v6:
- add a port struct
- select SND_SOC_HDMI_CODEC
- force reset the phy when hpd detected

Changes in v5:
- alphabetical order
- do not use long, use u32 or u64
- return MODE_CLOCK_HIGH when requested > actual
- Optimized Coding Style
- add a formula to get better tu size and symbol value.
- modify according to Sean Paul's comments
- fixed the fw_wait always 0

Changes in v4:
- use phy framework to control DP phy
- support 2 phys

Changes in v3:
- use EXTCON_DISP_DP and EXTCON_DISP_DP_ALT cable to get dp port state.
- reset spdif before config it
- modify the firmware clk to 100Mhz
- retry load firmware if fw file is requested too early

Changes in v2:
- Alphabetic order
- remove excess error message
- use define clk_rate
- check all return value
- remove dev_set_name(dp->dev, "cdn-dp");
- use schedule_delayed_work
- remove never-called functions
- remove some unnecessary ()

Changes in v1:
- use extcon API
- use hdmi-codec for the DP Asoc
- do not initialize the "ret"
- printk a err log when drm_of_encoder_active_endpoint_id
- modify the dclk pin_pol to a single line

 drivers/gpu/drm/rockchip/Kconfig|   10 +
 drivers/gpu/drm/rockchip/Makefile   |1 +
 drivers/gpu/drm/rockchip/cdn-dp-core.c  | 1052 +++
 drivers/gpu/drm/rockchip/cdn-dp-core.h  |  106 +++
 drivers/gpu/drm/rockchip/cdn-dp-reg.c   |  959 
 drivers/gpu/drm/rockchip/cdn-dp-reg.h   |  482 
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   13 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h |9 +
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c |2 +
 9 files changed, 2631 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-core.c
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-core.h
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.c
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.h

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index d30bdc3..20aaafe 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -25,6 +25,16 @@ config ROCKCHIP_ANALOGIX_DP
  for the Analogix Core DP driver. If you want to enable DP
  on RK3288 based SoC, you should selet this option.
 
+config ROCKCHIP_CDN_DP
+tristate "Rockchip cdn DP"
+depends on DRM_ROCKCHIP
+   select SND_SOC_HDMI_CODEC if SND_SOC
+help
+ This selects support for Rockchip SoC specific extensions
+ for the cdn DP driver. If you want to enable Dp on
+ RK3399 based SoC, you should select this
+ option.
+
 config ROCKCHIP_DW_HDMI
 tristate "Rockchip specific extensions for Synopsys DW HDMI"
 depends on DRM_ROCKCHIP
diff --git a/drivers/gpu/drm/rockchip/Makefile 
b/drivers/gpu/drm/rockchip/Makefile
index 9746365..6a07809 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -7,6 +7,7 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
 rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o
 
 obj-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
+obj-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
 obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
 obj-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
 obj-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
new file mode 100644
index 000..9be551d
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -0,0 +1,1052 @@
+/*
+ * Copyright (C) Fuzhou Rockchip Electronics 

[v13 PATCH 0/5] Rockchip Type-C and DisplayPort driver

2016-08-21 Thread Chris Zhong

Hi all

This series patch is for rockchip Type-C phy and DisplayPort controller
driver.

The USB Type-C PHY is designed to support the USB3 and DP applications.
The PHY basically has two main components: USB3 and DisplyPort. USB3
operates in SuperSpeed mode and the DP can operate at RBR, HBR and HBR2
data rates. The Type-C cable orientation detection and Power Delivery
(PD) is accomplished using a PD PHY or a exernal PD chip.

The DP controller is compliant with DisplayPort Specification,
Version 1.3, This IP is compatible with the rockchip type-c PHY IP.
There is a uCPU in DP controller, it need a firmware to work, please
put the firmware file[0] rockchip/dptx.bin to
/lib/firmware/rockchip/dptx.bin. The uCPU in charge of aux communication
and link training, the host use mailbox to communicate with the ucpu.

The DP contoller has register a notification with extcon API, to get the
alt mode from PD, the PD driver need call the devm_extcon_dev_allocate
to create a extcon device and use extcon_set_state to notify DP
controller. And call extcon_set_cable_property to set orientation.

About the DP audio, cdn-dp registered 2 DAIs: 0 is I2S, 1 is SPDIF.
We can reference them in simple-card.

This series is based on Mark Yao's branch[1] and Chanwoo Choi's
extcon-next branch[2], and Guenter's patch about
EXTCON_PROP_USB_SUPERSPEED[3], and Heiko's clk patch[4].

I test this patches on the rk3399-evb board, with a fusb302 driver,
this branch has no rk3399.dtsi, so the patch about dts is not included
in this series.

>From V9, the Type-C PHY is split into two PHYs: DP and USB3. The PHY
will be init, no matter which PHY be power_on. The DP module will
enter A2 mode (standby mode) after phy_init, if DP PHY is powered on,
the DP module will enter to A0 mode(running mode). Then if DP PHY is
powered off, DP module will back to A2 mode. If everything is
un-plugged, phy will be deinit.

[0]
kernel/git/firmware/linux-firmware.git
[1]
https://github.com/markyzq/kernel-drm-rockchip/tree/drm-rockchip-next-2016-05-23
[2]
https://git.kernel.org/cgit/linux/kernel/git/chanwoo/extcon.git extcon-next
[3]
https://patchwork.kernel.org/patch/9280955/
[4]
https://git.kernel.org/cgit/linux/kernel/git/mmind/linux-rockchip.git
/commit/?h=v4.9-clk/next=54479449c801e46ee2b6ba08e2f19cd810f74f94
https://git.kernel.org/cgit/linux/kernel/git/mmind/linux-rockchip.git
/commit/?h=v4.8-clk/fixes=a3f457d9636b3f5ae4fc6502cb0c95f60f5e342b


Changes in v13:
- do not return err if nothing connected with Type-C, when usb phy power on,
  since the USB core driver will call phy power without USB3 device connected.
- add dptx and apb reset
- support suspend/resume
- switch power domain dynamically
- re-training when hpd signal is triggered

Changes in v12:
- enable DP+USB3 mode, only when EXTCON_PROP_USB_SUPERSPEED equal 1
  and DP is attached
- use EXTCON_PROP_USB_SUPERSPEED to replace EXTCON_USB_HOST

Changes in v11:
- make a clearer emarcation between usb phy and dp phy
- make a clearer demarcation between usb phy and dp phy.
- split the dp-phy and usb3-phy to 2 child-node
- refer dp phy
- add best_encoder back, since it required by drm_atomic_helper_check

Changes in v10:
- remove rockchip,uphy-dp-sel property
- do not control dp select and hpd config in phy driver
- remove rockchip,uphy-dp-sel property
- add pclk_vio_grf clock
- remove best_encoder ops
- support read sink count from DPCD
- control the grf_clk in DP

Changes in v9:
- change #phy-cells to 1
- the new_mode should be int not u8
- move mutex_lock(>lock); to earlier place. in
  rockchip_usb3_phy_power_off
- better mutex lock for phy mode and flip
- split the Type-C PHY into two PHYs: USB3 and DP
- change #phy-cells to 1
- modify the reference phy = < 0>, < 0>;
- do not need reset the phy before power_on
- add a orientation information for set_capability
- retry to read dpcd in 10 seconds

Changes in v8:
- set the default cable id to EXTCON_USB_HOST
- optimization Error log
- optimization the err log

Changes in v7:
- support new API of extcon
- support firmware standby when no dptx connection
- optimization the calculation of tu size and valid symbol

Changes in v6:
- add assigned-clocks and assigned-clock-rates
- delete the support of PIN_ASSIGN_A/B
- set the default mode to MODE_DFP_USB
- disable DP PLL at USB3 only mode
- add assigned-clocks and assigned-clock-rates
- add power-domains
- add a port struct
- select SND_SOC_HDMI_CODEC
- force reset the phy when hpd detected

Changes in v5:
- support get property from extcon
- remove PIN ASSIGN A/B support
- alphabetical order
- do not use long, use u32 or u64
- return MODE_CLOCK_HIGH when requested > actual
- Optimized Coding Style
- add a formula to get better tu size and symbol value.
- modify according to Sean Paul's comments
- fixed the fw_wait always 0

Changes in v4:
- add a #phy-cells node
- select EXTCON
- use phy framework to control the USB3 and DP function
- rename PIN_MAP_ to PIN_ASSIGN_
- add a reset node
- support 2 phys
- use 

[v13 PATCH 4/5] Documentation: bindings: add dt documentation for cdn DP controller

2016-08-21 Thread Chris Zhong
This patch adds a binding that describes the cdn DP controller for
rk3399.

Signed-off-by: Chris Zhong 
Acked-by: Rob Herring 
Reviewed-by: Guenter Roeck 

---

Changes in v13:
- add dptx and apb reset

Changes in v12: None
Changes in v11:
- refer dp phy

Changes in v10:
- add pclk_vio_grf clock

Changes in v9:
- modify the reference phy = < 0>, < 0>;

Changes in v8: None
Changes in v7: None
Changes in v6:
- add assigned-clocks and assigned-clock-rates
- add power-domains

Changes in v5: None
Changes in v4:
- add a reset node
- support 2 phys

Changes in v3:
- add SoC specific compatible string
- remove reg = <1>;

Changes in v2: None
Changes in v1:
- add extcon node description
- add #sound-dai-cells description

 .../bindings/display/rockchip/cdn-dp-rockchip.txt  | 75 ++
 1 file changed, 75 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt 
b/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
new file mode 100644
index 000..9bd2c13
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt
@@ -0,0 +1,75 @@
+Rockchip RK3399 specific extensions to the cdn Display Port
+
+
+Required properties:
+- compatible: must be "rockchip,rk3399-cdn-dp"
+
+- reg: physical base address of the controller and length
+
+- clocks: from common clock binding: handle to dp clock.
+
+- clock-names: from common clock binding:
+  Required elements: "core-clk" "pclk" "spdif" "grf"
+
+- resets : a list of phandle + reset specifier pairs
+- reset-names : string reset name, must be:
+   "spdif", "dptx", "apb".
+- power-domains : power-domain property defined with a phandle
+ to respective power domain.
+- assigned-clocks: main clock, should be < SCLK_DP_CORE>
+- assigned-clock-rates : the DP core clk frequency, shall be: 1
+
+- rockchip,grf: this soc should set GRF regs, so need get grf here.
+
+- ports: contain a port nodes with endpoint definitions as defined in
+Documentation/devicetree/bindings/media/video-interfaces.txt.
+contained 2 endpoints, connecting to the output of vop.
+
+- phys: from general PHY binding: the phandle for the PHY device.
+
+- extcon: extcon specifier for the Power Delivery
+
+- #sound-dai-cells = it must be 1 if your system is using 2 DAIs: I2S, SPDIF
+
+---
+
+Example:
+   cdn_dp: dp@fec0 {
+   compatible = "rockchip,rk3399-cdn-dp";
+   reg = <0x0 0xfec0 0x0 0x10>;
+   interrupts = ;
+   clocks = < SCLK_DP_CORE>, < PCLK_DP_CTRL>,
+< SCLK_SPDIF_REC_DPTX>, < PCLK_VIO_GRF>;
+   clock-names = "core-clk", "pclk", "spdif", "grf";
+   assigned-clocks = < SCLK_DP_CORE>;
+   assigned-clock-rates = <1>;
+   power-domains = < RK3399_PD_HDCP>;
+   phys = <_dp>, <_dp>;
+   resets = < SRST_DPTX_SPDIF_REC>, < SRST_P_UPHY0_DPTX>,
+< SRST_P_UPHY0_APB>;
+   reset-names = "spdif", "dptx", "apb";
+   extcon = <>, <>;
+   rockchip,grf = <>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   #sound-dai-cells = <1>;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   dp_in: port {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   dp_in_vopb: endpoint@0 {
+   reg = <0>;
+   remote-endpoint = <_out_dp>;
+   };
+
+   dp_in_vopl: endpoint@1 {
+   reg = <1>;
+   remote-endpoint = <_out_dp>;
+   };
+   };
+   };
+   };
-- 
1.9.1



[v13 PATCH 5/5] drm/rockchip: cdn-dp: add cdn DP support for rk3399

2016-08-21 Thread Chris Zhong
Add support for cdn DP controller which is embedded in the rk3399
SoCs. The DP is compliant with DisplayPort Specification,
Version 1.3, This IP is compatible with the rockchip type-c PHY IP.
There is a uCPU in DP controller, it need a firmware to work,
please put the firmware file to /lib/firmware/rockchip/dptx.bin. The
uCPU in charge of aux communication and link training, the host use
mailbox to communicate with the ucpu.
The dclk pin_pol of vop must not be invert for DP.

Signed-off-by: Chris Zhong 
Reviewed-by: Sean Paul 
Acked-by: Mark Yao 

---

Changes in v13:
- support suspend/resume
- switch power domain dynamically
- re-training when hpd signal is triggered

Changes in v12:
- use EXTCON_PROP_USB_SUPERSPEED to replace EXTCON_USB_HOST

Changes in v11:
- add best_encoder back, since it required by drm_atomic_helper_check

Changes in v10:
- remove best_encoder ops
- support read sink count from DPCD
- control the grf_clk in DP

Changes in v9:
- do not need reset the phy before power_on
- add a orientation information for set_capability
- retry to read dpcd in 10 seconds

Changes in v8:
- optimization the err log

Changes in v7:
- support firmware standby when no dptx connection
- optimization the calculation of tu size and valid symbol

Changes in v6:
- add a port struct
- select SND_SOC_HDMI_CODEC
- force reset the phy when hpd detected

Changes in v5:
- alphabetical order
- do not use long, use u32 or u64
- return MODE_CLOCK_HIGH when requested > actual
- Optimized Coding Style
- add a formula to get better tu size and symbol value.
- modify according to Sean Paul's comments
- fixed the fw_wait always 0

Changes in v4:
- use phy framework to control DP phy
- support 2 phys

Changes in v3:
- use EXTCON_DISP_DP and EXTCON_DISP_DP_ALT cable to get dp port state.
- reset spdif before config it
- modify the firmware clk to 100Mhz
- retry load firmware if fw file is requested too early

Changes in v2:
- Alphabetic order
- remove excess error message
- use define clk_rate
- check all return value
- remove dev_set_name(dp->dev, "cdn-dp");
- use schedule_delayed_work
- remove never-called functions
- remove some unnecessary ()

Changes in v1:
- use extcon API
- use hdmi-codec for the DP Asoc
- do not initialize the "ret"
- printk a err log when drm_of_encoder_active_endpoint_id
- modify the dclk pin_pol to a single line

 drivers/gpu/drm/rockchip/Kconfig|   10 +
 drivers/gpu/drm/rockchip/Makefile   |1 +
 drivers/gpu/drm/rockchip/cdn-dp-core.c  | 1052 +++
 drivers/gpu/drm/rockchip/cdn-dp-core.h  |  106 +++
 drivers/gpu/drm/rockchip/cdn-dp-reg.c   |  959 
 drivers/gpu/drm/rockchip/cdn-dp-reg.h   |  482 
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   13 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h |9 +
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c |2 +
 9 files changed, 2631 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-core.c
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-core.h
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.c
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.h

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index d30bdc3..20aaafe 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -25,6 +25,16 @@ config ROCKCHIP_ANALOGIX_DP
  for the Analogix Core DP driver. If you want to enable DP
  on RK3288 based SoC, you should selet this option.
 
+config ROCKCHIP_CDN_DP
+tristate "Rockchip cdn DP"
+depends on DRM_ROCKCHIP
+   select SND_SOC_HDMI_CODEC if SND_SOC
+help
+ This selects support for Rockchip SoC specific extensions
+ for the cdn DP driver. If you want to enable Dp on
+ RK3399 based SoC, you should select this
+ option.
+
 config ROCKCHIP_DW_HDMI
 tristate "Rockchip specific extensions for Synopsys DW HDMI"
 depends on DRM_ROCKCHIP
diff --git a/drivers/gpu/drm/rockchip/Makefile 
b/drivers/gpu/drm/rockchip/Makefile
index 9746365..6a07809 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -7,6 +7,7 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
 rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o
 
 obj-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
+obj-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
 obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
 obj-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
 obj-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
new file mode 100644
index 000..9be551d
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -0,0 +1,1052 @@
+/*
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ * Author: Chris Zhong 
+ *
+ * This software is licensed under 

Re: [PATCH 3.10 090/180] xfs: xfs_iflush_cluster fails to abort on error

2016-08-21 Thread Dave Chinner
On Sun, Aug 21, 2016 at 05:30:20PM +0200, Willy Tarreau wrote:
> From: Dave Chinner 
> 
> commit b1438f477934f5a4d5a44df26f3079a7575d5946 upstream.
> 
> When a failure due to an inode buffer occurs, the error handling
> fails to abort the inode writeback correctly. This can result in the
> inode being reclaimed whilst still in the AIL, leading to
> use-after-free situations as well as filesystems that cannot be
> unmounted as the inode log items left in the AIL never get removed.
> 
> Fix this by ensuring fatal errors from xfs_imap_to_bp() result in
> the inode flush being aborted correctly.
> 
> Reported-by: Shyam Kaushik 
> Diagnosed-by: Shyam Kaushik 
> Tested-by: Shyam Kaushik 
> Signed-off-by: Dave Chinner 
> Reviewed-by: Christoph Hellwig 
> Signed-off-by: Dave Chinner 
> Signed-off-by: Greg Kroah-Hartman 
> Signed-off-by: Willy Tarreau 



> @@ -2768,14 +2768,22 @@ xfs_iflush(
>   }
>  
>   /*
> -  * Get the buffer containing the on-disk inode.
> +  * Get the buffer containing the on-disk inode. We are doing a try-lock
> +  * operation here, so we may get  an EAGAIN error. In that case, we
> +  * simply want to return with the inode still dirty.
> +  *
> +  * If we get any other error, we effectively have a corruption situation
> +  * and we cannot flush the inode, so we treat it the same as failing
> +  * xfs_iflush_int().
>*/
>   error = xfs_imap_to_bp(mp, NULL, >i_imap, , , XBF_TRYLOCK,
>  0);
> - if (error || !bp) {
> + if (error == -EAGAIN) {

Wrong. Errors changed sign in XFS in 3.17.

/rant

So, after just having to point this out (again!) for a different
stable kernel patchset review, and this specific problem causing
user-reported stable kernel regression and filesystem corruption
*months ago*. That resulted in discussion and new stable commits to
fix the problem. So now I'm left to wonder about the process of
stable kernels.

AFAICT, stable kernel maintainers are not watching what happens with
other stable kernels, nor are they talking to other stable kernel
maintainers. I should not have to tell every single stable kernel
maintainer that a specific patch needs to be changed after it's
already been reported broken, triaged and fixed in other stable
kernels. You've all got a record that the patch needs to be included
in a stable kernel, but nobody is seems to notice when it comes to
fixing problems with a stable patch even when that all happens on
sta...@vger.kernel.org.

Seriously, guys, pick up your act a bit and start talking between
yourselvesi and tracking regressions and fixes so the burden of
catching known reported and fixed problems with backports doesn't
rely on the upstream developers noticing the problem when hundreds
of patches for random stable kernels go past on lkml every week...

-Dave.
-- 
Dave Chinner
da...@fromorbit.com


Re: [PATCH 3.10 090/180] xfs: xfs_iflush_cluster fails to abort on error

2016-08-21 Thread Dave Chinner
On Sun, Aug 21, 2016 at 05:30:20PM +0200, Willy Tarreau wrote:
> From: Dave Chinner 
> 
> commit b1438f477934f5a4d5a44df26f3079a7575d5946 upstream.
> 
> When a failure due to an inode buffer occurs, the error handling
> fails to abort the inode writeback correctly. This can result in the
> inode being reclaimed whilst still in the AIL, leading to
> use-after-free situations as well as filesystems that cannot be
> unmounted as the inode log items left in the AIL never get removed.
> 
> Fix this by ensuring fatal errors from xfs_imap_to_bp() result in
> the inode flush being aborted correctly.
> 
> Reported-by: Shyam Kaushik 
> Diagnosed-by: Shyam Kaushik 
> Tested-by: Shyam Kaushik 
> Signed-off-by: Dave Chinner 
> Reviewed-by: Christoph Hellwig 
> Signed-off-by: Dave Chinner 
> Signed-off-by: Greg Kroah-Hartman 
> Signed-off-by: Willy Tarreau 



> @@ -2768,14 +2768,22 @@ xfs_iflush(
>   }
>  
>   /*
> -  * Get the buffer containing the on-disk inode.
> +  * Get the buffer containing the on-disk inode. We are doing a try-lock
> +  * operation here, so we may get  an EAGAIN error. In that case, we
> +  * simply want to return with the inode still dirty.
> +  *
> +  * If we get any other error, we effectively have a corruption situation
> +  * and we cannot flush the inode, so we treat it the same as failing
> +  * xfs_iflush_int().
>*/
>   error = xfs_imap_to_bp(mp, NULL, >i_imap, , , XBF_TRYLOCK,
>  0);
> - if (error || !bp) {
> + if (error == -EAGAIN) {

Wrong. Errors changed sign in XFS in 3.17.

/rant

So, after just having to point this out (again!) for a different
stable kernel patchset review, and this specific problem causing
user-reported stable kernel regression and filesystem corruption
*months ago*. That resulted in discussion and new stable commits to
fix the problem. So now I'm left to wonder about the process of
stable kernels.

AFAICT, stable kernel maintainers are not watching what happens with
other stable kernels, nor are they talking to other stable kernel
maintainers. I should not have to tell every single stable kernel
maintainer that a specific patch needs to be changed after it's
already been reported broken, triaged and fixed in other stable
kernels. You've all got a record that the patch needs to be included
in a stable kernel, but nobody is seems to notice when it comes to
fixing problems with a stable patch even when that all happens on
sta...@vger.kernel.org.

Seriously, guys, pick up your act a bit and start talking between
yourselvesi and tracking regressions and fixes so the burden of
catching known reported and fixed problems with backports doesn't
rely on the upstream developers noticing the problem when hundreds
of patches for random stable kernels go past on lkml every week...

-Dave.
-- 
Dave Chinner
da...@fromorbit.com


[PATCH v8 2/2] Add ioctl to issue ZBC/ZAC commands via block layer

2016-08-21 Thread Shaun Tancheff
Add support for ZBC ioctl's
BLKREPORT - Issue Report Zones to device.
BLKZONEACTION - Issue a Zone Action (Close, Finish, Open, or Reset)

Signed-off-by: Shaun Tancheff 
---
v8:
 - Changed ioctl for zone actions to a single ioctl that takes 
   a structure including the zone, zone action, all flag, and force option
 - Mapped REQ_META flag to 'force unit access' for zone operations
v6:
 - Added GFP_DMA to gfp mask.
v4:
 - Rebase on linux-next tag next-20160617.
 - Change bio flags to bio op's

 block/ioctl.c | 149 ++
 include/uapi/linux/blkzoned_api.h |  30 +++-
 include/uapi/linux/fs.h   |   1 +
 3 files changed, 179 insertions(+), 1 deletion(-)

diff --git a/block/ioctl.c b/block/ioctl.c
index ed2397f..d760523 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -194,6 +194,151 @@ int blkdev_reread_part(struct block_device *bdev)
 }
 EXPORT_SYMBOL(blkdev_reread_part);
 
+static int blk_zoned_report_ioctl(struct block_device *bdev, fmode_t mode,
+ void __user *parg)
+{
+   int error = -EFAULT;
+   gfp_t gfp = GFP_KERNEL | GFP_DMA;
+   void *iopg = NULL;
+   struct bdev_zone_report_io *bzrpt = NULL;
+   int order = 0;
+   struct page *pgs = NULL;
+   u32 alloc_size = PAGE_SIZE;
+   unsigned int op_flags = 0;
+   u8 opt = 0;
+
+   if (!(mode & FMODE_READ))
+   return -EBADF;
+
+   iopg = (void *)get_zeroed_page(gfp);
+   if (!iopg) {
+   error = -ENOMEM;
+   goto report_zones_out;
+   }
+   bzrpt = iopg;
+   if (copy_from_user(bzrpt, parg, sizeof(*bzrpt))) {
+   error = -EFAULT;
+   goto report_zones_out;
+   }
+   if (bzrpt->data.in.return_page_count > alloc_size) {
+   int npages;
+
+   alloc_size = bzrpt->data.in.return_page_count;
+   npages = (alloc_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+   pgs = alloc_pages(gfp, ilog2(npages));
+   if (pgs) {
+   void *mem = page_address(pgs);
+
+   if (!mem) {
+   error = -ENOMEM;
+   goto report_zones_out;
+   }
+   order = ilog2(npages);
+   memset(mem, 0, alloc_size);
+   memcpy(mem, bzrpt, sizeof(*bzrpt));
+   bzrpt = mem;
+   } else {
+   /* Result requires DMA capable memory */
+   pr_err("Not enough memory available for request.\n");
+   error = -ENOMEM;
+   goto report_zones_out;
+   }
+   } else {
+   alloc_size = bzrpt->data.in.return_page_count;
+   }
+   if (bzrpt->data.in.force_unit_access)
+   op_flags |= REQ_META;
+   opt = bzrpt->data.in.report_option;
+   error = blkdev_issue_zone_report(bdev, op_flags,
+   bzrpt->data.in.zone_locator_lba, opt,
+   pgs ? pgs : virt_to_page(iopg),
+   alloc_size, GFP_KERNEL);
+   if (error)
+   goto report_zones_out;
+
+   if (pgs) {
+   void *src = bzrpt;
+   u32 off = 0;
+
+   /*
+* When moving a multi-order page with GFP_DMA
+* the copy to user can trap ""
+* so instead we copy out 1 page at a time.
+*/
+   while (off < alloc_size && !error) {
+   u32 len = min_t(u32, PAGE_SIZE, alloc_size - off);
+
+   memcpy(iopg, src + off, len);
+   if (copy_to_user(parg + off, iopg, len))
+   error = -EFAULT;
+   off += len;
+   }
+   } else {
+   if (copy_to_user(parg, iopg, alloc_size))
+   error = -EFAULT;
+   }
+
+report_zones_out:
+   if (pgs)
+   __free_pages(pgs, order);
+   if (iopg)
+   free_page((unsigned long)iopg);
+   return error;
+}
+
+static int blk_zoned_action_ioctl(struct block_device *bdev, fmode_t mode,
+ void __user *parg)
+{
+   unsigned int op = 0;
+   unsigned int op_flags = 0;
+   sector_t lba;
+   struct bdev_zone_action za;
+
+   if (!(mode & FMODE_WRITE))
+   return -EBADF;
+
+   /* When acting on zones we explicitly disallow using a partition. */
+   if (bdev != bdev->bd_contains) {
+   pr_err("%s: All zone operations disallowed on this device\n",
+   __func__);
+   return -EFAULT;
+   }
+
+   if (copy_from_user(, parg, sizeof(za)))
+   return -EFAULT;
+
+   switch (za.action) {
+   case ZONE_ACTION_CLOSE:
+  

[PATCH v8 2/2] Add ioctl to issue ZBC/ZAC commands via block layer

2016-08-21 Thread Shaun Tancheff
Add support for ZBC ioctl's
BLKREPORT - Issue Report Zones to device.
BLKZONEACTION - Issue a Zone Action (Close, Finish, Open, or Reset)

Signed-off-by: Shaun Tancheff 
---
v8:
 - Changed ioctl for zone actions to a single ioctl that takes 
   a structure including the zone, zone action, all flag, and force option
 - Mapped REQ_META flag to 'force unit access' for zone operations
v6:
 - Added GFP_DMA to gfp mask.
v4:
 - Rebase on linux-next tag next-20160617.
 - Change bio flags to bio op's

 block/ioctl.c | 149 ++
 include/uapi/linux/blkzoned_api.h |  30 +++-
 include/uapi/linux/fs.h   |   1 +
 3 files changed, 179 insertions(+), 1 deletion(-)

diff --git a/block/ioctl.c b/block/ioctl.c
index ed2397f..d760523 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -194,6 +194,151 @@ int blkdev_reread_part(struct block_device *bdev)
 }
 EXPORT_SYMBOL(blkdev_reread_part);
 
+static int blk_zoned_report_ioctl(struct block_device *bdev, fmode_t mode,
+ void __user *parg)
+{
+   int error = -EFAULT;
+   gfp_t gfp = GFP_KERNEL | GFP_DMA;
+   void *iopg = NULL;
+   struct bdev_zone_report_io *bzrpt = NULL;
+   int order = 0;
+   struct page *pgs = NULL;
+   u32 alloc_size = PAGE_SIZE;
+   unsigned int op_flags = 0;
+   u8 opt = 0;
+
+   if (!(mode & FMODE_READ))
+   return -EBADF;
+
+   iopg = (void *)get_zeroed_page(gfp);
+   if (!iopg) {
+   error = -ENOMEM;
+   goto report_zones_out;
+   }
+   bzrpt = iopg;
+   if (copy_from_user(bzrpt, parg, sizeof(*bzrpt))) {
+   error = -EFAULT;
+   goto report_zones_out;
+   }
+   if (bzrpt->data.in.return_page_count > alloc_size) {
+   int npages;
+
+   alloc_size = bzrpt->data.in.return_page_count;
+   npages = (alloc_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+   pgs = alloc_pages(gfp, ilog2(npages));
+   if (pgs) {
+   void *mem = page_address(pgs);
+
+   if (!mem) {
+   error = -ENOMEM;
+   goto report_zones_out;
+   }
+   order = ilog2(npages);
+   memset(mem, 0, alloc_size);
+   memcpy(mem, bzrpt, sizeof(*bzrpt));
+   bzrpt = mem;
+   } else {
+   /* Result requires DMA capable memory */
+   pr_err("Not enough memory available for request.\n");
+   error = -ENOMEM;
+   goto report_zones_out;
+   }
+   } else {
+   alloc_size = bzrpt->data.in.return_page_count;
+   }
+   if (bzrpt->data.in.force_unit_access)
+   op_flags |= REQ_META;
+   opt = bzrpt->data.in.report_option;
+   error = blkdev_issue_zone_report(bdev, op_flags,
+   bzrpt->data.in.zone_locator_lba, opt,
+   pgs ? pgs : virt_to_page(iopg),
+   alloc_size, GFP_KERNEL);
+   if (error)
+   goto report_zones_out;
+
+   if (pgs) {
+   void *src = bzrpt;
+   u32 off = 0;
+
+   /*
+* When moving a multi-order page with GFP_DMA
+* the copy to user can trap ""
+* so instead we copy out 1 page at a time.
+*/
+   while (off < alloc_size && !error) {
+   u32 len = min_t(u32, PAGE_SIZE, alloc_size - off);
+
+   memcpy(iopg, src + off, len);
+   if (copy_to_user(parg + off, iopg, len))
+   error = -EFAULT;
+   off += len;
+   }
+   } else {
+   if (copy_to_user(parg, iopg, alloc_size))
+   error = -EFAULT;
+   }
+
+report_zones_out:
+   if (pgs)
+   __free_pages(pgs, order);
+   if (iopg)
+   free_page((unsigned long)iopg);
+   return error;
+}
+
+static int blk_zoned_action_ioctl(struct block_device *bdev, fmode_t mode,
+ void __user *parg)
+{
+   unsigned int op = 0;
+   unsigned int op_flags = 0;
+   sector_t lba;
+   struct bdev_zone_action za;
+
+   if (!(mode & FMODE_WRITE))
+   return -EBADF;
+
+   /* When acting on zones we explicitly disallow using a partition. */
+   if (bdev != bdev->bd_contains) {
+   pr_err("%s: All zone operations disallowed on this device\n",
+   __func__);
+   return -EFAULT;
+   }
+
+   if (copy_from_user(, parg, sizeof(za)))
+   return -EFAULT;
+
+   switch (za.action) {
+   case ZONE_ACTION_CLOSE:
+   op = REQ_OP_ZONE_CLOSE;
+  

[PATCH v8 1/2] Add bio/request flags to issue ZBC/ZAC commands

2016-08-21 Thread Shaun Tancheff
Add op flags to access to zone information as well as open, close
and reset zones:
  - REQ_OP_ZONE_REPORT - Query zone information (Report zones)
  - REQ_OP_ZONE_OPEN - Explicitly open a zone for writing
  - REQ_OP_ZONE_CLOSE - Explicitly close a zone
  - REQ_OP_ZONE_FINISH - Explicitly finish a zone
  - REQ_OP_ZONE_RESET - Reset Write Pointer to start of zone

These op flags can be used to create bio's to control zoned devices
through the block layer.

This is useful for file systems and device mappers that need explicit
control of zoned devices such as Host Managed and Host Aware SMR drives,

Report zones is a device read that requires a buffer.

Open, Close, Finish and Reset are device commands that have no
associated data transfer.
  Open -   Open is a zone for writing.
  Close -  Disallow writing to a zone.
  Finish - Disallow writing a zone and set the WP to the end
   of the zone.
  Reset -  Discard data in a zone and reset the WP to the start
   of the zone.

Sending an LBA of ~0 will attempt to operate on all zones.
This is typically used with Reset to wipe a drive as a Reset
behaves similar to TRIM in that all data in the zone(s) is deleted.

Report zones currently defaults to reporting on all zones. It expected
that support for the zone option flag will piggy back on streamid
support. The report option flag is useful as it can reduce the number
of zones in each report, but not critical.

Signed-off-by: Shaun Tancheff 
---
v8:
 - Added Finish Zone op
 - Fixed report zones copy to user to work when HARDENED_USERCOPY is enabled
v6:
 - Added GFP_DMA to gfp mask.
v5:
 - In sd_setup_zone_action_cmnd, remove unused vars and fix switch indent
 - In blk-lib fix documentation
v4:
 - Rebase on linux-next tag next-20160617.
 - Change bio flags to bio op's
V3:
 - Rebase on Mike Cristie's separate bio operations
 - Update blkzoned_api.h to include report zones PARTIAL bit.
V2:
 - Changed bi_rw to op_flags clarify sepeartion of bio op from flags.
 - Fixed memory leak in blkdev_issue_zone_report failing to put_bio().
 - Documented opt in blkdev_issue_zone_report.
 - Removed include/uapi/linux/fs.h from this patch.

 MAINTAINERS   |   9 ++
 block/blk-lib.c   |  94 
 drivers/scsi/sd.c | 121 +
 drivers/scsi/sd.h |   1 +
 include/linux/bio.h   |   8 +-
 include/linux/blk_types.h |   7 +-
 include/linux/blkdev.h|   1 +
 include/linux/blkzoned_api.h  |  25 ++
 include/uapi/linux/Kbuild |   1 +
 include/uapi/linux/blkzoned_api.h | 182 ++
 10 files changed, 447 insertions(+), 2 deletions(-)
 create mode 100644 include/linux/blkzoned_api.h
 create mode 100644 include/uapi/linux/blkzoned_api.h

diff --git a/MAINTAINERS b/MAINTAINERS
index a306795..aedf311 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12984,6 +12984,15 @@ F: Documentation/networking/z8530drv.txt
 F: drivers/net/hamradio/*scc.c
 F: drivers/net/hamradio/z8530.h
 
+ZBC AND ZBC BLOCK DEVICES
+M: Shaun Tancheff 
+W: http://seagate.com
+W: https://github.com/Seagate/ZDM-Device-Mapper
+L: linux-bl...@vger.kernel.org
+S: Maintained
+F: include/linux/blkzoned_api.h
+F: include/uapi/linux/blkzoned_api.h
+
 ZBUD COMPRESSED PAGE ALLOCATOR
 M: Seth Jennings 
 L: linux...@kvack.org
diff --git a/block/blk-lib.c b/block/blk-lib.c
index 083e56f..e92bd56 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -266,3 +266,97 @@ int blkdev_issue_zeroout(struct block_device *bdev, 
sector_t sector,
return __blkdev_issue_zeroout(bdev, sector, nr_sects, gfp_mask);
 }
 EXPORT_SYMBOL(blkdev_issue_zeroout);
+
+/**
+ * blkdev_issue_zone_report - queue a report zones operation
+ * @bdev:  target blockdev
+ * @op_flags:  extra bio rw flags. If unsure, use 0.
+ * @sector:starting sector (report will include this sector).
+ * @opt:   See: zone_report_option, default is 0 (all zones).
+ * @page:  one or more contiguous pages.
+ * @pgsz:  up to size of page in bytes, size of report.
+ * @gfp_mask:  memory allocation flags (for bio_alloc)
+ *
+ * Description:
+ *Issue a zone report request for the sectors in question.
+ */
+int blkdev_issue_zone_report(struct block_device *bdev, unsigned int op_flags,
+sector_t sector, u8 opt, struct page *page,
+size_t pgsz, gfp_t gfp_mask)
+{
+   struct bdev_zone_report *conv = page_address(page);
+   struct bio *bio;
+   unsigned int nr_iovecs = 1;
+   int ret = 0;
+
+   if (pgsz < (sizeof(struct bdev_zone_report) +
+   sizeof(struct bdev_zone_descriptor)))
+   return -EINVAL;
+
+   bio = bio_alloc(gfp_mask, nr_iovecs);
+   if (!bio)
+   return -ENOMEM;
+
+   

[PATCH v8 1/2] Add bio/request flags to issue ZBC/ZAC commands

2016-08-21 Thread Shaun Tancheff
Add op flags to access to zone information as well as open, close
and reset zones:
  - REQ_OP_ZONE_REPORT - Query zone information (Report zones)
  - REQ_OP_ZONE_OPEN - Explicitly open a zone for writing
  - REQ_OP_ZONE_CLOSE - Explicitly close a zone
  - REQ_OP_ZONE_FINISH - Explicitly finish a zone
  - REQ_OP_ZONE_RESET - Reset Write Pointer to start of zone

These op flags can be used to create bio's to control zoned devices
through the block layer.

This is useful for file systems and device mappers that need explicit
control of zoned devices such as Host Managed and Host Aware SMR drives,

Report zones is a device read that requires a buffer.

Open, Close, Finish and Reset are device commands that have no
associated data transfer.
  Open -   Open is a zone for writing.
  Close -  Disallow writing to a zone.
  Finish - Disallow writing a zone and set the WP to the end
   of the zone.
  Reset -  Discard data in a zone and reset the WP to the start
   of the zone.

Sending an LBA of ~0 will attempt to operate on all zones.
This is typically used with Reset to wipe a drive as a Reset
behaves similar to TRIM in that all data in the zone(s) is deleted.

Report zones currently defaults to reporting on all zones. It expected
that support for the zone option flag will piggy back on streamid
support. The report option flag is useful as it can reduce the number
of zones in each report, but not critical.

Signed-off-by: Shaun Tancheff 
---
v8:
 - Added Finish Zone op
 - Fixed report zones copy to user to work when HARDENED_USERCOPY is enabled
v6:
 - Added GFP_DMA to gfp mask.
v5:
 - In sd_setup_zone_action_cmnd, remove unused vars and fix switch indent
 - In blk-lib fix documentation
v4:
 - Rebase on linux-next tag next-20160617.
 - Change bio flags to bio op's
V3:
 - Rebase on Mike Cristie's separate bio operations
 - Update blkzoned_api.h to include report zones PARTIAL bit.
V2:
 - Changed bi_rw to op_flags clarify sepeartion of bio op from flags.
 - Fixed memory leak in blkdev_issue_zone_report failing to put_bio().
 - Documented opt in blkdev_issue_zone_report.
 - Removed include/uapi/linux/fs.h from this patch.

 MAINTAINERS   |   9 ++
 block/blk-lib.c   |  94 
 drivers/scsi/sd.c | 121 +
 drivers/scsi/sd.h |   1 +
 include/linux/bio.h   |   8 +-
 include/linux/blk_types.h |   7 +-
 include/linux/blkdev.h|   1 +
 include/linux/blkzoned_api.h  |  25 ++
 include/uapi/linux/Kbuild |   1 +
 include/uapi/linux/blkzoned_api.h | 182 ++
 10 files changed, 447 insertions(+), 2 deletions(-)
 create mode 100644 include/linux/blkzoned_api.h
 create mode 100644 include/uapi/linux/blkzoned_api.h

diff --git a/MAINTAINERS b/MAINTAINERS
index a306795..aedf311 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12984,6 +12984,15 @@ F: Documentation/networking/z8530drv.txt
 F: drivers/net/hamradio/*scc.c
 F: drivers/net/hamradio/z8530.h
 
+ZBC AND ZBC BLOCK DEVICES
+M: Shaun Tancheff 
+W: http://seagate.com
+W: https://github.com/Seagate/ZDM-Device-Mapper
+L: linux-bl...@vger.kernel.org
+S: Maintained
+F: include/linux/blkzoned_api.h
+F: include/uapi/linux/blkzoned_api.h
+
 ZBUD COMPRESSED PAGE ALLOCATOR
 M: Seth Jennings 
 L: linux...@kvack.org
diff --git a/block/blk-lib.c b/block/blk-lib.c
index 083e56f..e92bd56 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -266,3 +266,97 @@ int blkdev_issue_zeroout(struct block_device *bdev, 
sector_t sector,
return __blkdev_issue_zeroout(bdev, sector, nr_sects, gfp_mask);
 }
 EXPORT_SYMBOL(blkdev_issue_zeroout);
+
+/**
+ * blkdev_issue_zone_report - queue a report zones operation
+ * @bdev:  target blockdev
+ * @op_flags:  extra bio rw flags. If unsure, use 0.
+ * @sector:starting sector (report will include this sector).
+ * @opt:   See: zone_report_option, default is 0 (all zones).
+ * @page:  one or more contiguous pages.
+ * @pgsz:  up to size of page in bytes, size of report.
+ * @gfp_mask:  memory allocation flags (for bio_alloc)
+ *
+ * Description:
+ *Issue a zone report request for the sectors in question.
+ */
+int blkdev_issue_zone_report(struct block_device *bdev, unsigned int op_flags,
+sector_t sector, u8 opt, struct page *page,
+size_t pgsz, gfp_t gfp_mask)
+{
+   struct bdev_zone_report *conv = page_address(page);
+   struct bio *bio;
+   unsigned int nr_iovecs = 1;
+   int ret = 0;
+
+   if (pgsz < (sizeof(struct bdev_zone_report) +
+   sizeof(struct bdev_zone_descriptor)))
+   return -EINVAL;
+
+   bio = bio_alloc(gfp_mask, nr_iovecs);
+   if (!bio)
+   return -ENOMEM;
+
+   conv->descriptor_count = 0;
+   bio->bi_iter.bi_sector = sector;
+   

[PATCH v8 0/2] Block layer support ZAC/ZBC commands

2016-08-21 Thread Shaun Tancheff
Hi Jens,

This series is based on linus' v4.8-rc2 branch.

As Host Aware drives are becoming available we would like to be able
to make use of such drives. This series is also intended to be
suitable for use by Host Managed drives.

ZBC [and ZAC] drives add new commands for discovering and working
with Zones.

Part one of this series expands the bio/request reserved op size from
3 to 4 bits and then adds op codes for each of the ZBC commands:
   Report zones, close zone, finish zone, open zone and reset zone.

Part two of this series deals with integrating these new bio/request
op's with Hannes' zone cache.

This extends the ZBC support up to the block layer allowing direct
control by file systems or device mapper targets. Also by deferring
the zone handling to the authoritative subsystem there is an overall
lower memory usage for holding the active zone information as well
as clarifying responsible party for maintaining the write pointer
for each active zone.

By way of example a DM target may have several writes in progress. To sector
(or lba) for those writes will each depend on the previous write. While the
drive's write pointer will be updated as writes are completed the DM target
will be maintaining both where the next write should be scheduled from and
where the write pointer is based on writes completed w/o errors.

Knowing the drive zone topology enables DM targets and file systems to
extend their block allocation schemes and issue write pointer resets (or
discards) that are zone aligned.

A perhaps non-obvious approach is that a conventional drive will
returns a zone report descriptor with a single large conventional zone.
This is intended to allow a collection of zoned and non-zoned media to
be stitched together to provide a file system with a zoned device with
conventional space mapped to where it is useful.

Patches for util-linux can be found here:
g...@github.com:stancheff/util-linux.git v2.28.1+biof

https://github.com/stancheff/util-linux/tree/v2.28.1%2Bbiof

This patch is available here:
https://github.com/stancheff/linux/tree/v4.8-rc2%2Bbiof.v8

g...@github.com:stancheff/linux.git v4.8-rc2+biof.v8

v8:
 - Changed zone report to default to reading from zone cache.
 - Changed ioctl for zone commands to support forcing a query or command
   to be sent to media.
 - Fixed report zones copy to user to work when HARDENED_USERCOPY is enabled
v7:
 - Initial support for Hannes' zone cache.
v6:
 - Fix page alloc to include DMA flag for ioctl.
v5:
 - In sd_setup_zone_action_cmnd, remove unused vars and fix switch indent
 - In blk-lib fix documentation
v4:
 - Rebase on linux-next tag next-20160617.
 - Change bio flags to bio op's
 - Dropped ata16 hackery
V3:
 - Rebase on Mike Cristie's separate bio operations
 - Update blkzoned_api.h to include report zones PARTIAL bit.
 - Use zoned report reserved bit for ata-passthrough flag.

V2:
 - Changed bi_rw to op_flags clarify sepeartion of bio op from flags.
 - Fixed memory leak in blkdev_issue_zone_report failing to put_bio().
 - Documented opt in blkdev_issue_zone_report.
 - Moved include/uapi/linux/fs.h changes to patch 3
 - Fixed commit message for first patch in series.


Shaun Tancheff (2):
  Add bio/request flags to issue ZBC/ZAC commands
  Add ioctl to issue ZBC/ZAC commands via block layer

 MAINTAINERS   |   9 ++
 block/blk-lib.c   |  94 +
 block/ioctl.c | 149 +++
 drivers/scsi/sd.c | 121 ++
 drivers/scsi/sd.h |   1 +
 include/linux/bio.h   |   8 +-
 include/linux/blk_types.h |   7 +-
 include/linux/blkdev.h|   1 +
 include/linux/blkzoned_api.h  |  25 +
 include/uapi/linux/Kbuild |   1 +
 include/uapi/linux/blkzoned_api.h | 210 ++
 include/uapi/linux/fs.h   |   1 +
 12 files changed, 625 insertions(+), 2 deletions(-)
 create mode 100644 include/linux/blkzoned_api.h
 create mode 100644 include/uapi/linux/blkzoned_api.h

-- 
2.9.3



[PATCH v8 0/2] Block layer support ZAC/ZBC commands

2016-08-21 Thread Shaun Tancheff
Hi Jens,

This series is based on linus' v4.8-rc2 branch.

As Host Aware drives are becoming available we would like to be able
to make use of such drives. This series is also intended to be
suitable for use by Host Managed drives.

ZBC [and ZAC] drives add new commands for discovering and working
with Zones.

Part one of this series expands the bio/request reserved op size from
3 to 4 bits and then adds op codes for each of the ZBC commands:
   Report zones, close zone, finish zone, open zone and reset zone.

Part two of this series deals with integrating these new bio/request
op's with Hannes' zone cache.

This extends the ZBC support up to the block layer allowing direct
control by file systems or device mapper targets. Also by deferring
the zone handling to the authoritative subsystem there is an overall
lower memory usage for holding the active zone information as well
as clarifying responsible party for maintaining the write pointer
for each active zone.

By way of example a DM target may have several writes in progress. To sector
(or lba) for those writes will each depend on the previous write. While the
drive's write pointer will be updated as writes are completed the DM target
will be maintaining both where the next write should be scheduled from and
where the write pointer is based on writes completed w/o errors.

Knowing the drive zone topology enables DM targets and file systems to
extend their block allocation schemes and issue write pointer resets (or
discards) that are zone aligned.

A perhaps non-obvious approach is that a conventional drive will
returns a zone report descriptor with a single large conventional zone.
This is intended to allow a collection of zoned and non-zoned media to
be stitched together to provide a file system with a zoned device with
conventional space mapped to where it is useful.

Patches for util-linux can be found here:
g...@github.com:stancheff/util-linux.git v2.28.1+biof

https://github.com/stancheff/util-linux/tree/v2.28.1%2Bbiof

This patch is available here:
https://github.com/stancheff/linux/tree/v4.8-rc2%2Bbiof.v8

g...@github.com:stancheff/linux.git v4.8-rc2+biof.v8

v8:
 - Changed zone report to default to reading from zone cache.
 - Changed ioctl for zone commands to support forcing a query or command
   to be sent to media.
 - Fixed report zones copy to user to work when HARDENED_USERCOPY is enabled
v7:
 - Initial support for Hannes' zone cache.
v6:
 - Fix page alloc to include DMA flag for ioctl.
v5:
 - In sd_setup_zone_action_cmnd, remove unused vars and fix switch indent
 - In blk-lib fix documentation
v4:
 - Rebase on linux-next tag next-20160617.
 - Change bio flags to bio op's
 - Dropped ata16 hackery
V3:
 - Rebase on Mike Cristie's separate bio operations
 - Update blkzoned_api.h to include report zones PARTIAL bit.
 - Use zoned report reserved bit for ata-passthrough flag.

V2:
 - Changed bi_rw to op_flags clarify sepeartion of bio op from flags.
 - Fixed memory leak in blkdev_issue_zone_report failing to put_bio().
 - Documented opt in blkdev_issue_zone_report.
 - Moved include/uapi/linux/fs.h changes to patch 3
 - Fixed commit message for first patch in series.


Shaun Tancheff (2):
  Add bio/request flags to issue ZBC/ZAC commands
  Add ioctl to issue ZBC/ZAC commands via block layer

 MAINTAINERS   |   9 ++
 block/blk-lib.c   |  94 +
 block/ioctl.c | 149 +++
 drivers/scsi/sd.c | 121 ++
 drivers/scsi/sd.h |   1 +
 include/linux/bio.h   |   8 +-
 include/linux/blk_types.h |   7 +-
 include/linux/blkdev.h|   1 +
 include/linux/blkzoned_api.h  |  25 +
 include/uapi/linux/Kbuild |   1 +
 include/uapi/linux/blkzoned_api.h | 210 ++
 include/uapi/linux/fs.h   |   1 +
 12 files changed, 625 insertions(+), 2 deletions(-)
 create mode 100644 include/linux/blkzoned_api.h
 create mode 100644 include/uapi/linux/blkzoned_api.h

-- 
2.9.3



Re: [PATCH 1/1] arm64/hugetlb: clear PG_dcache_clean if the page is dirty when munmap

2016-08-21 Thread Leizhen (ThunderTown)


On 2016/7/20 17:19, Catalin Marinas wrote:
> On Wed, Jul 20, 2016 at 10:46:27AM +0800, Leizhen (ThunderTown) wrote:
>> On 2016/7/8 21:54, Catalin Marinas wrote:
>>> 8<
>>> diff --git a/arch/arm64/mm/flush.c b/arch/arm64/mm/flush.c
>>> index dbd12ea8ce68..c753fa804165 100644
>>> --- a/arch/arm64/mm/flush.c
>>> +++ b/arch/arm64/mm/flush.c
>>> @@ -75,7 +75,8 @@ void __sync_icache_dcache(pte_t pte, unsigned long 
>>> addr)
>>> if (!page_mapping(page))
>>> return;
>>>  
>>> -   if (!test_and_set_bit(PG_dcache_clean, >flags))
>>> +   if (!test_and_set_bit(PG_dcache_clean, >flags) ||
>>> +   PageDirty(page))
>>> sync_icache_aliases(page_address(page),
>>> PAGE_SIZE << compound_order(page));
>>> else if (icache_is_aivivt())
>>> 8<-
>>
>> Do you plan to send this patch? My colleagues told me that if our
>> patches are quite different, it should be Signed-off-by you.
> 
> The reason I'm not sending it is that I don't fully understand how it
> solves the problem for a shared file mmap(), not just hugetlbfs. As I
> said in an earlier email: after an msync() in user space we
> should flush the pages to disk via write_cache_pages(). This function
Hi Catalin:
   I'm so sorry for my fault. The previous small pages test result I actually 
ran on ramfs.
Today, I ran the case on harddisk fs, it worked well without this patch.

Summarized as follows:
small pages on ramfs: need this patch
small pages on harddisk fs: no need this patch
hugetlbfs: need this patch



> calls clear_page_dirty_for_io() after which PageDirty() is no longer
> true. I can't tell how a subsequent mmap() can see the written pages as
> dirty.
> 
>> I searched all Linux source code, __sync_icache_dcache is only called
>> by set_pte_at, and some check conditions(especially pte_exec) will
>> limit its impact.
>>
>>  if (pte_user(pte) && pte_exec(pte) && !pte_special(pte))
>>  __sync_icache_dcache(pte, addr);
> 
> Yes, and set_pte_at() would be called as a result of a page fault when
> accessing the mmap'ed file.
> 



Re: [PATCH 1/1] arm64/hugetlb: clear PG_dcache_clean if the page is dirty when munmap

2016-08-21 Thread Leizhen (ThunderTown)


On 2016/7/20 17:19, Catalin Marinas wrote:
> On Wed, Jul 20, 2016 at 10:46:27AM +0800, Leizhen (ThunderTown) wrote:
>> On 2016/7/8 21:54, Catalin Marinas wrote:
>>> 8<
>>> diff --git a/arch/arm64/mm/flush.c b/arch/arm64/mm/flush.c
>>> index dbd12ea8ce68..c753fa804165 100644
>>> --- a/arch/arm64/mm/flush.c
>>> +++ b/arch/arm64/mm/flush.c
>>> @@ -75,7 +75,8 @@ void __sync_icache_dcache(pte_t pte, unsigned long 
>>> addr)
>>> if (!page_mapping(page))
>>> return;
>>>  
>>> -   if (!test_and_set_bit(PG_dcache_clean, >flags))
>>> +   if (!test_and_set_bit(PG_dcache_clean, >flags) ||
>>> +   PageDirty(page))
>>> sync_icache_aliases(page_address(page),
>>> PAGE_SIZE << compound_order(page));
>>> else if (icache_is_aivivt())
>>> 8<-
>>
>> Do you plan to send this patch? My colleagues told me that if our
>> patches are quite different, it should be Signed-off-by you.
> 
> The reason I'm not sending it is that I don't fully understand how it
> solves the problem for a shared file mmap(), not just hugetlbfs. As I
> said in an earlier email: after an msync() in user space we
> should flush the pages to disk via write_cache_pages(). This function
Hi Catalin:
   I'm so sorry for my fault. The previous small pages test result I actually 
ran on ramfs.
Today, I ran the case on harddisk fs, it worked well without this patch.

Summarized as follows:
small pages on ramfs: need this patch
small pages on harddisk fs: no need this patch
hugetlbfs: need this patch



> calls clear_page_dirty_for_io() after which PageDirty() is no longer
> true. I can't tell how a subsequent mmap() can see the written pages as
> dirty.
> 
>> I searched all Linux source code, __sync_icache_dcache is only called
>> by set_pte_at, and some check conditions(especially pte_exec) will
>> limit its impact.
>>
>>  if (pte_user(pte) && pte_exec(pte) && !pte_special(pte))
>>  __sync_icache_dcache(pte, addr);
> 
> Yes, and set_pte_at() would be called as a result of a page fault when
> accessing the mmap'ed file.
> 



[PATCH] binfmt_misc: allow selecting the interpreter based on xattr keywords

2016-08-21 Thread Josh Max
This patch allows binfmt_misc to select the interpeter for arbitrary
binaries by comparing a specified registered keyword with the value
of a specified binary's extended attribute (user.binfmt.interp),
and then launching the program with the registered interpreter.

This is useful when wanting to launch a collection of binaries under
the same interpreter, even when they do not necessarily share a common
extension or magic bits, or when their magic conflics with the operation
of binfmt_elf. Some examples of its use would be to launch some executables
of various different architectures in a directory, or for running some
native binaries under a sandbox (like firejail) automatically during their
launch.

Signed-off-by: Josh Max 
---
 fs/binfmt_misc.c | 51 +++
 1 file changed, 47 insertions(+), 4 deletions(-)

diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index 6103a63..86d93c7 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "internal.h"
@@ -41,12 +42,17 @@ enum {
 static LIST_HEAD(entries);
 static int enabled = 1;
 
-enum {Enabled, Magic};
+enum {Enabled, Magic, Keyword};
 #define MISC_FMT_PRESERVE_ARGV0 (1 << 31)
 #define MISC_FMT_OPEN_BINARY (1 << 30)
 #define MISC_FMT_CREDENTIALS (1 << 29)
 #define MISC_FMT_OPEN_FILE (1 << 28)
 
+#define XATTR_BINFMT_PREFIX XATTR_USER_PREFIX "binfmt."
+#define XATTR_BINFMT_INTERPRETER_SUFFIX "interp"
+#define XATTR_NAME_BINFMT (XATTR_BINFMT_PREFIX XATTR_BINFMT_INTERPRETER_SUFFIX)
+#define XATTR_VALUE_MAX_LENGTH 128
+
 typedef struct {
struct list_head list;
unsigned long flags;/* type, status, etc. */
@@ -61,6 +67,7 @@ typedef struct {
 } Node;
 
 static DEFINE_RWLOCK(entries_lock);
+static int get_xattr_interp_keyword(struct file *file, char *buf, size_t 
count);
 static struct file_system_type bm_fs_type;
 static struct vfsmount *bm_mnt;
 static int entry_count;
@@ -87,6 +94,8 @@ static int entry_count;
  */
 static Node *check_file(struct linux_binprm *bprm)
 {
+   char k[XATTR_VALUE_MAX_LENGTH];
+   int k_len = get_xattr_interp_keyword(bprm->file, k, sizeof(k)-1);
char *p = strrchr(bprm->interp, '.');
struct list_head *l;
 
@@ -100,6 +109,16 @@ static Node *check_file(struct linux_binprm *bprm)
if (!test_bit(Enabled, >flags))
continue;
 
+   /* Do matching based on xattrs keyword */
+   if (test_bit(Keyword, >flags)) {
+   if (k_len <= 0)
+   continue;
+   k[k_len] = 0;
+   if (!strcmp(e->magic, k))
+   return e;
+   continue;
+   }
+
/* Do matching based on extension if applicable. */
if (!test_bit(Magic, >flags)) {
if (p && !strcmp(e->magic, p + 1))
@@ -309,6 +328,20 @@ static char *check_special_flags(char *sfs, Node *e)
 }
 
 /*
+ * Check to see if the filesystem supports xattrs
+ * and grab the value so it can be checked against
+ * the list of keywords in binfmt_misc for a match
+ */
+static int get_xattr_interp_keyword(struct file *file, char *buf, size_t count)
+{
+
+   if (unlikely(!file->f_inode->i_op->getxattr))
+   return -ENOENT;
+   return file->f_inode->i_op->getxattr(file->f_path.dentry, file->f_inode,
+   XATTR_NAME_BINFMT, buf, count);
+}
+
+/*
  * This registers a new binary format, it recognises the syntax
  * ':name:type:offset:magic:mask:interpreter:flags'
  * where the ':' is the IFS, that can be chosen with the first char
@@ -366,6 +399,10 @@ static Node *create_entry(const char __user *buffer, 
size_t count)
pr_debug("register: type: E (extension)\n");
e->flags = 1 << Enabled;
break;
+   case 'K':
+   pr_debug("register: type: K (xattrs keyword)\n");
+   e->flags = (1 << Enabled) | (1 << Keyword);
+   break;
case 'M':
pr_debug("register: type: M (magic)\n");
e->flags = (1 << Enabled) | (1 << Magic);
@@ -453,7 +490,7 @@ static Node *create_entry(const char __user *buffer, size_t 
count)
}
}
} else {
-   /* Handle the 'E' (extension) format. */
+   /* Handle the 'E' (extension) and 'K' (keyword) format. */
 
/* Skip the 'offset' field. */
p = strchr(p, del);
@@ -469,7 +506,10 @@ static Node *create_entry(const char __user *buffer, 
size_t count)
*p++ = '\0';
if (!e->magic[0] || strchr(e->magic, '/'))
goto einval;
-   pr_debug("register: extension: {%s}\n", e->magic);
+   if (test_bit(Keyword, >flags))
+   

[PATCH] binfmt_misc: allow selecting the interpreter based on xattr keywords

2016-08-21 Thread Josh Max
This patch allows binfmt_misc to select the interpeter for arbitrary
binaries by comparing a specified registered keyword with the value
of a specified binary's extended attribute (user.binfmt.interp),
and then launching the program with the registered interpreter.

This is useful when wanting to launch a collection of binaries under
the same interpreter, even when they do not necessarily share a common
extension or magic bits, or when their magic conflics with the operation
of binfmt_elf. Some examples of its use would be to launch some executables
of various different architectures in a directory, or for running some
native binaries under a sandbox (like firejail) automatically during their
launch.

Signed-off-by: Josh Max 
---
 fs/binfmt_misc.c | 51 +++
 1 file changed, 47 insertions(+), 4 deletions(-)

diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index 6103a63..86d93c7 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "internal.h"
@@ -41,12 +42,17 @@ enum {
 static LIST_HEAD(entries);
 static int enabled = 1;
 
-enum {Enabled, Magic};
+enum {Enabled, Magic, Keyword};
 #define MISC_FMT_PRESERVE_ARGV0 (1 << 31)
 #define MISC_FMT_OPEN_BINARY (1 << 30)
 #define MISC_FMT_CREDENTIALS (1 << 29)
 #define MISC_FMT_OPEN_FILE (1 << 28)
 
+#define XATTR_BINFMT_PREFIX XATTR_USER_PREFIX "binfmt."
+#define XATTR_BINFMT_INTERPRETER_SUFFIX "interp"
+#define XATTR_NAME_BINFMT (XATTR_BINFMT_PREFIX XATTR_BINFMT_INTERPRETER_SUFFIX)
+#define XATTR_VALUE_MAX_LENGTH 128
+
 typedef struct {
struct list_head list;
unsigned long flags;/* type, status, etc. */
@@ -61,6 +67,7 @@ typedef struct {
 } Node;
 
 static DEFINE_RWLOCK(entries_lock);
+static int get_xattr_interp_keyword(struct file *file, char *buf, size_t 
count);
 static struct file_system_type bm_fs_type;
 static struct vfsmount *bm_mnt;
 static int entry_count;
@@ -87,6 +94,8 @@ static int entry_count;
  */
 static Node *check_file(struct linux_binprm *bprm)
 {
+   char k[XATTR_VALUE_MAX_LENGTH];
+   int k_len = get_xattr_interp_keyword(bprm->file, k, sizeof(k)-1);
char *p = strrchr(bprm->interp, '.');
struct list_head *l;
 
@@ -100,6 +109,16 @@ static Node *check_file(struct linux_binprm *bprm)
if (!test_bit(Enabled, >flags))
continue;
 
+   /* Do matching based on xattrs keyword */
+   if (test_bit(Keyword, >flags)) {
+   if (k_len <= 0)
+   continue;
+   k[k_len] = 0;
+   if (!strcmp(e->magic, k))
+   return e;
+   continue;
+   }
+
/* Do matching based on extension if applicable. */
if (!test_bit(Magic, >flags)) {
if (p && !strcmp(e->magic, p + 1))
@@ -309,6 +328,20 @@ static char *check_special_flags(char *sfs, Node *e)
 }
 
 /*
+ * Check to see if the filesystem supports xattrs
+ * and grab the value so it can be checked against
+ * the list of keywords in binfmt_misc for a match
+ */
+static int get_xattr_interp_keyword(struct file *file, char *buf, size_t count)
+{
+
+   if (unlikely(!file->f_inode->i_op->getxattr))
+   return -ENOENT;
+   return file->f_inode->i_op->getxattr(file->f_path.dentry, file->f_inode,
+   XATTR_NAME_BINFMT, buf, count);
+}
+
+/*
  * This registers a new binary format, it recognises the syntax
  * ':name:type:offset:magic:mask:interpreter:flags'
  * where the ':' is the IFS, that can be chosen with the first char
@@ -366,6 +399,10 @@ static Node *create_entry(const char __user *buffer, 
size_t count)
pr_debug("register: type: E (extension)\n");
e->flags = 1 << Enabled;
break;
+   case 'K':
+   pr_debug("register: type: K (xattrs keyword)\n");
+   e->flags = (1 << Enabled) | (1 << Keyword);
+   break;
case 'M':
pr_debug("register: type: M (magic)\n");
e->flags = (1 << Enabled) | (1 << Magic);
@@ -453,7 +490,7 @@ static Node *create_entry(const char __user *buffer, size_t 
count)
}
}
} else {
-   /* Handle the 'E' (extension) format. */
+   /* Handle the 'E' (extension) and 'K' (keyword) format. */
 
/* Skip the 'offset' field. */
p = strchr(p, del);
@@ -469,7 +506,10 @@ static Node *create_entry(const char __user *buffer, 
size_t count)
*p++ = '\0';
if (!e->magic[0] || strchr(e->magic, '/'))
goto einval;
-   pr_debug("register: extension: {%s}\n", e->magic);
+   if (test_bit(Keyword, >flags))
+   pr_debug("register: keyword: 

Re: [PATCH v10 1/2] printk: Make printk() completely async

2016-08-21 Thread Sergey Senozhatsky
Hello,

On (08/20/16 14:24), Sergey Senozhatsky wrote:
> On (08/19/16 21:00), Jan Kara wrote:
> > > > depending on .config BUG() may never return back -- passing control
> > > > to do_exit(), so printk_deferred_exit() won't be executed. thus we
> > > > probably need to have a per-cpu variable that would indicate that
> > > > we are in deferred_bug. hm... but do we really need deferred BUG()
> > > > in the first place?
> > > 
> > > Good question. I am not aware of any BUG_ON() that would be called from
> > > wake_up_process() but it is hard to check everything.
> > > 
> > > A conservative approach would be to force synchronous printk from
> > > BUG_ON().
> > 
> > Just a quick thought: Cannot we just do printk_deferred_enter() when we are
> > about to call into the scheduler from printk code and printk_deferred_exit()
> > when leaving it? That would look like the least error-prone way how
> > handling this kind of recursion...
> 
> interesting idea.
> printk_deferred_enter() increments preempt count, so there may be additional
> obstacles and, as a result, ad-hocs, that scheduler people will sincerely 
> hate.
> need to think more.

so we probably can try something like this

---

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 2add7c5..b23f919 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2014,6 +2014,7 @@ try_to_wake_up(struct task_struct *p, unsigned int state, 
int wake_flags)
 * set_current_state() the waiting thread does.
 */
smp_mb__before_spinlock();
+   printk_deferred_enter();
raw_spin_lock_irqsave(>pi_lock, flags);
if (!(p->state & state))
goto out;
@@ -2073,6 +2074,7 @@ stat:
ttwu_stat(p, cpu, wake_flags);
 out:
raw_spin_unlock_irqrestore(>pi_lock, flags);
+   printk_deferred_exit();
 
return success;
 }


---

since we are basically interested in wake_up_process() only from
printk() POV. not sure how acceptable 2 * preempt_count and 2 * per-CPU
writes for every try_to_wake_up().


the other thing I just thought of is doing something as follows
!!!not tested, will not compile, just an idea!!!

---

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 6e260a0..bb8d719 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -1789,6 +1789,7 @@ asmlinkage int vprintk_emit(int facility, int level,
printk_delay();
 
local_irq_save(flags);
+   printk_nmi_enter();
this_cpu = smp_processor_id();
 
/*
@@ -1804,6 +1805,7 @@ asmlinkage int vprintk_emit(int facility, int level,
 */
if (!oops_in_progress && !lockdep_recursing(current)) {
recursion_bug = true;
+   printk_nmi_exit();
local_irq_restore(flags);
return 0;
}
@@ -1920,6 +1922,7 @@ asmlinkage int vprintk_emit(int facility, int level,
logbuf_cpu = UINT_MAX;
raw_spin_unlock(_lock);
lockdep_on();
+   printk_nmi_exit();
local_irq_restore(flags);
 
/* If called from the scheduler, we can not call up(). */
---

so may be we will not blow up in case of spin_dump() on logbuf_lock.
well, if logbuf_lock was corrupted then nothing will help us -- it's over.
but if raw_spin_lock(_lock), for instance, spin_dump()-s because
logbuf_lock was not released after `loops_per_jiffy * HZ' then deferred
printing may help.


probably we can make NMI printk_func to be more general way of using
an alternative-printk buffer and, for example, rename API it to
printk_alternative_enter() and printk_alternative_exit(), not to confuse
anyone. (yes, NMIs are not available on every platform)


and even more. we can start dump_stack() from recursion detection path
to that alternative printk-buffer, which is a bit more helpful than
"BUG: recent printk recursion!"
!!!not tested, will not compile, just an idea!!!

---

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 6e260a0..ebce39a 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -1789,6 +1789,7 @@ asmlinkage int vprintk_emit(int facility, int level,
printk_delay();
 
local_irq_save(flags);
+   printk_nmi_enter();
this_cpu = smp_processor_id();
 
/*
@@ -1804,6 +1805,8 @@ asmlinkage int vprintk_emit(int facility, int level,
 */
if (!oops_in_progress && !lockdep_recursing(current)) {
recursion_bug = true;
+   WARN_ON(1); /* <<< dump_stack to 
alternative buffer */
+   printk_nmi_exit();
local_irq_restore(flags);
return 0;
}
@@ -1816,14 +1819,8 @@ asmlinkage int vprintk_emit(int facility, int level,
logbuf_cpu = this_cpu;
 
if (unlikely(recursion_bug)) {
-   static const char recursion_msg[] =
-

Re: [Revised document] Crossrelease lockdep

2016-08-21 Thread Byungchul Park
On Fri, Aug 19, 2016 at 09:39:59PM +0900, Byungchul Park wrote:
> Hello,
> 
> I rewrote the document so that the need of crossrelease feature can be
> described logically. I think it's more important than to post specific
> implementation. Could you let me know your opinions about this?
> 
> Thanks,
> Byungchul
> 
> ->8-
> 
> Crossrelease
> 
> 
> Started by Byungchul Park 
> 
> Contents:
> 
>  (*) Background.
> 
>  - What causes deadlock.
>  - What lockdep detects.
>  - How lockdep works.
> 
>  (*) Limitation.
> 
>  - Limit to typical lock.
>  - Pros from the limitation.
>  - Cons from the limitation.
> 
>  (*) Generalization.
> 
>  - Relax the limitation.
> 
>  (*) Crossrelease.
> 
>  - Introduce crossrelease.
>  - Introduce commit.
> 
>  (*) Implementation.
> 
>  - Data structures.
>  - How crossrelease works.
> 
>  (*) Optimizations.
> 
>  - Avoid duplication.
>  - Avoid lock contention.
> 
> 
> ==
> Background
> ==
> 
> What causes deadlock
> 
> 
> A deadlock occurs when a context is waiting for an event to be issued
> which cannot be issued because the context or another context who can
> issue the event is also waiting for an event to be issued which cannot
> be issued. Single context or more than one context both waiting for an
> event and issuing an event may paricipate in a deadlock.
> 
> For example,
> 
> A context who can issue event D is waiting for event A to be issued.
> A context who can issue event A is waiting for event B to be issued.
> A context who can issue event B is waiting for event C to be issued.
> A context who can issue event C is waiting for event D to be issued.
> 
> A deadlock occurs when these four operations are run at a time because
> event D cannot be issued if event A isn't issued which in turn cannot be
> issued if event B isn't issued which in turn cannot be issued if event C
> isn't issued which in turn cannot be issued if event D isn't issued. No
> event can be issued since any of them never meets its precondition.
> 
> We can easily recognize that each wait operation creates a dependency
> between two issuings e.g. between issuing D and issuing A like, 'event D
> cannot be issued if event A isn't issued', in other words, 'issuing
> event D depends on issuing event A'. So the whole example can be
> rewritten in terms of dependency,
> 
> Do an operation making 'event D cannot be issued if event A isn't issued'.
> Do an operation making 'event A cannot be issued if event B isn't issued'.
> Do an operation making 'event B cannot be issued if event C isn't issued'.
> Do an operation making 'event C cannot be issued if event D isn't issued'.
> 
> or,
> 
> Do an operation making 'issuing event D depends on issuing event A'.
> Do an operation making 'issuing event A depends on issuing event B'.
> Do an operation making 'issuing event B depends on issuing event C'.
> Do an operation making 'issuing event C depends on issuing event D'.
> 
> What causes a deadlock is a set of dependencies a chain of which forms a
> cycle, which means that issuing event D depending on issuing event A
> depending on issuing event B depending on issuing event C depending on
> issuing event D, finally depends on issuing event D itself, which means
> no event can be issued.
> 
> Any set of operations creating dependencies causes a deadlock. The set
^^^
can
> of lock operations e.g. acquire and release is an example. Waiting for a
> lock to be released corresponds to waiting for an event and releasing a
> lock corresponds to issuing an event. So the description of dependency
> above can be altered to one in terms of lock.
> 
> In terms of event, issuing event A depends on issuing event B if,
> 
>   Event A cannot be issued if event B isn't issued.
> 
> In terms of lock, releasing lock A depends on releasing lock B if,
> 
>   Lock A cannot be released if lock B isn't released.
> 
> CONCLUSION
> 
> A set of dependencies a chain of which forms a cycle, causes a deadlock,
> no matter what creates the dependencies.
> 
> 
> What lockdep detects
> 
> 
> A deadlock actually occurs only when all operations creating problematic
> dependencies are run at a time. However, even if it has not happend, the
> deadlock potentially can occur if the problematic dependencies obviously
> exist. Thus it's meaningful to detect not only an actual deadlock but
> also its possibility. Lockdep does the both.
> 
> Whether a deadlock actually occurs or not depends on several factors,
> which means a deadlock may not occur even though problematic
> dependencies exist. For example, what order contexts are switched in is
> a factor. A deadlock will occur when contexts are switched so that all
> operations causing a deadlock become run simultaneously.
> 
> Lockdep tries to detect a 

Re: [PATCH v10 1/2] printk: Make printk() completely async

2016-08-21 Thread Sergey Senozhatsky
Hello,

On (08/20/16 14:24), Sergey Senozhatsky wrote:
> On (08/19/16 21:00), Jan Kara wrote:
> > > > depending on .config BUG() may never return back -- passing control
> > > > to do_exit(), so printk_deferred_exit() won't be executed. thus we
> > > > probably need to have a per-cpu variable that would indicate that
> > > > we are in deferred_bug. hm... but do we really need deferred BUG()
> > > > in the first place?
> > > 
> > > Good question. I am not aware of any BUG_ON() that would be called from
> > > wake_up_process() but it is hard to check everything.
> > > 
> > > A conservative approach would be to force synchronous printk from
> > > BUG_ON().
> > 
> > Just a quick thought: Cannot we just do printk_deferred_enter() when we are
> > about to call into the scheduler from printk code and printk_deferred_exit()
> > when leaving it? That would look like the least error-prone way how
> > handling this kind of recursion...
> 
> interesting idea.
> printk_deferred_enter() increments preempt count, so there may be additional
> obstacles and, as a result, ad-hocs, that scheduler people will sincerely 
> hate.
> need to think more.

so we probably can try something like this

---

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 2add7c5..b23f919 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2014,6 +2014,7 @@ try_to_wake_up(struct task_struct *p, unsigned int state, 
int wake_flags)
 * set_current_state() the waiting thread does.
 */
smp_mb__before_spinlock();
+   printk_deferred_enter();
raw_spin_lock_irqsave(>pi_lock, flags);
if (!(p->state & state))
goto out;
@@ -2073,6 +2074,7 @@ stat:
ttwu_stat(p, cpu, wake_flags);
 out:
raw_spin_unlock_irqrestore(>pi_lock, flags);
+   printk_deferred_exit();
 
return success;
 }


---

since we are basically interested in wake_up_process() only from
printk() POV. not sure how acceptable 2 * preempt_count and 2 * per-CPU
writes for every try_to_wake_up().


the other thing I just thought of is doing something as follows
!!!not tested, will not compile, just an idea!!!

---

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 6e260a0..bb8d719 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -1789,6 +1789,7 @@ asmlinkage int vprintk_emit(int facility, int level,
printk_delay();
 
local_irq_save(flags);
+   printk_nmi_enter();
this_cpu = smp_processor_id();
 
/*
@@ -1804,6 +1805,7 @@ asmlinkage int vprintk_emit(int facility, int level,
 */
if (!oops_in_progress && !lockdep_recursing(current)) {
recursion_bug = true;
+   printk_nmi_exit();
local_irq_restore(flags);
return 0;
}
@@ -1920,6 +1922,7 @@ asmlinkage int vprintk_emit(int facility, int level,
logbuf_cpu = UINT_MAX;
raw_spin_unlock(_lock);
lockdep_on();
+   printk_nmi_exit();
local_irq_restore(flags);
 
/* If called from the scheduler, we can not call up(). */
---

so may be we will not blow up in case of spin_dump() on logbuf_lock.
well, if logbuf_lock was corrupted then nothing will help us -- it's over.
but if raw_spin_lock(_lock), for instance, spin_dump()-s because
logbuf_lock was not released after `loops_per_jiffy * HZ' then deferred
printing may help.


probably we can make NMI printk_func to be more general way of using
an alternative-printk buffer and, for example, rename API it to
printk_alternative_enter() and printk_alternative_exit(), not to confuse
anyone. (yes, NMIs are not available on every platform)


and even more. we can start dump_stack() from recursion detection path
to that alternative printk-buffer, which is a bit more helpful than
"BUG: recent printk recursion!"
!!!not tested, will not compile, just an idea!!!

---

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 6e260a0..ebce39a 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -1789,6 +1789,7 @@ asmlinkage int vprintk_emit(int facility, int level,
printk_delay();
 
local_irq_save(flags);
+   printk_nmi_enter();
this_cpu = smp_processor_id();
 
/*
@@ -1804,6 +1805,8 @@ asmlinkage int vprintk_emit(int facility, int level,
 */
if (!oops_in_progress && !lockdep_recursing(current)) {
recursion_bug = true;
+   WARN_ON(1); /* <<< dump_stack to 
alternative buffer */
+   printk_nmi_exit();
local_irq_restore(flags);
return 0;
}
@@ -1816,14 +1819,8 @@ asmlinkage int vprintk_emit(int facility, int level,
logbuf_cpu = this_cpu;
 
if (unlikely(recursion_bug)) {
-   static const char recursion_msg[] =
-

Re: [Revised document] Crossrelease lockdep

2016-08-21 Thread Byungchul Park
On Fri, Aug 19, 2016 at 09:39:59PM +0900, Byungchul Park wrote:
> Hello,
> 
> I rewrote the document so that the need of crossrelease feature can be
> described logically. I think it's more important than to post specific
> implementation. Could you let me know your opinions about this?
> 
> Thanks,
> Byungchul
> 
> ->8-
> 
> Crossrelease
> 
> 
> Started by Byungchul Park 
> 
> Contents:
> 
>  (*) Background.
> 
>  - What causes deadlock.
>  - What lockdep detects.
>  - How lockdep works.
> 
>  (*) Limitation.
> 
>  - Limit to typical lock.
>  - Pros from the limitation.
>  - Cons from the limitation.
> 
>  (*) Generalization.
> 
>  - Relax the limitation.
> 
>  (*) Crossrelease.
> 
>  - Introduce crossrelease.
>  - Introduce commit.
> 
>  (*) Implementation.
> 
>  - Data structures.
>  - How crossrelease works.
> 
>  (*) Optimizations.
> 
>  - Avoid duplication.
>  - Avoid lock contention.
> 
> 
> ==
> Background
> ==
> 
> What causes deadlock
> 
> 
> A deadlock occurs when a context is waiting for an event to be issued
> which cannot be issued because the context or another context who can
> issue the event is also waiting for an event to be issued which cannot
> be issued. Single context or more than one context both waiting for an
> event and issuing an event may paricipate in a deadlock.
> 
> For example,
> 
> A context who can issue event D is waiting for event A to be issued.
> A context who can issue event A is waiting for event B to be issued.
> A context who can issue event B is waiting for event C to be issued.
> A context who can issue event C is waiting for event D to be issued.
> 
> A deadlock occurs when these four operations are run at a time because
> event D cannot be issued if event A isn't issued which in turn cannot be
> issued if event B isn't issued which in turn cannot be issued if event C
> isn't issued which in turn cannot be issued if event D isn't issued. No
> event can be issued since any of them never meets its precondition.
> 
> We can easily recognize that each wait operation creates a dependency
> between two issuings e.g. between issuing D and issuing A like, 'event D
> cannot be issued if event A isn't issued', in other words, 'issuing
> event D depends on issuing event A'. So the whole example can be
> rewritten in terms of dependency,
> 
> Do an operation making 'event D cannot be issued if event A isn't issued'.
> Do an operation making 'event A cannot be issued if event B isn't issued'.
> Do an operation making 'event B cannot be issued if event C isn't issued'.
> Do an operation making 'event C cannot be issued if event D isn't issued'.
> 
> or,
> 
> Do an operation making 'issuing event D depends on issuing event A'.
> Do an operation making 'issuing event A depends on issuing event B'.
> Do an operation making 'issuing event B depends on issuing event C'.
> Do an operation making 'issuing event C depends on issuing event D'.
> 
> What causes a deadlock is a set of dependencies a chain of which forms a
> cycle, which means that issuing event D depending on issuing event A
> depending on issuing event B depending on issuing event C depending on
> issuing event D, finally depends on issuing event D itself, which means
> no event can be issued.
> 
> Any set of operations creating dependencies causes a deadlock. The set
^^^
can
> of lock operations e.g. acquire and release is an example. Waiting for a
> lock to be released corresponds to waiting for an event and releasing a
> lock corresponds to issuing an event. So the description of dependency
> above can be altered to one in terms of lock.
> 
> In terms of event, issuing event A depends on issuing event B if,
> 
>   Event A cannot be issued if event B isn't issued.
> 
> In terms of lock, releasing lock A depends on releasing lock B if,
> 
>   Lock A cannot be released if lock B isn't released.
> 
> CONCLUSION
> 
> A set of dependencies a chain of which forms a cycle, causes a deadlock,
> no matter what creates the dependencies.
> 
> 
> What lockdep detects
> 
> 
> A deadlock actually occurs only when all operations creating problematic
> dependencies are run at a time. However, even if it has not happend, the
> deadlock potentially can occur if the problematic dependencies obviously
> exist. Thus it's meaningful to detect not only an actual deadlock but
> also its possibility. Lockdep does the both.
> 
> Whether a deadlock actually occurs or not depends on several factors,
> which means a deadlock may not occur even though problematic
> dependencies exist. For example, what order contexts are switched in is
> a factor. A deadlock will occur when contexts are switched so that all
> operations causing a deadlock become run simultaneously.
> 
> Lockdep tries to detect a deadlock or its possibility 

Fwd: Fwd: [PATCH 01/32] ver_linux: complete awk implementation

2016-08-21 Thread Alexander Kapshuk
-- Forwarded message --
From: Alexander Kapshuk 
Date: Sun, Aug 21, 2016 at 5:07 PM
Subject: Re: Fwd: [PATCH 01/32] ver_linux: complete awk implementation
To: Greg KH 


On Sun, Aug 21, 2016 at 11:19 AM, Greg KH  wrote:
>
> On Fri, Aug 19, 2016 at 09:12:28PM +0300, Alexander Kapshuk wrote:
> > Hello Greg,
> >
> > This is a follow-up on the series of 'ver_linux' patches I submitted at the 
> > end
> > of June, proposing a complete rewrite of the script in awk.
> >
> > So far, I have had feedback from one person, and I just wanted to get some
> > feedback from yourself too.
> >
> > I do appreciate the fact that you have other more pressing matters to 
> > attend to
> > at the moment, so there is no rush.
> >
> > I would appreciate hearing from you about my patches at your convenience.
>
> Last I saw, your patch series broke the build in the beginning and then
> fixed it up at the end, right?
>
> All patches have to never break the build, or functionality, at every
> step of the way.
>
> Sorry, it's a pain, but that's how the Linux kernel development model
> works.
>
> thanks,
>
> greg k-h


Thanks for your feedback and for clarifying how the Linux kernel
development model works.

Which of the two avenues presented below would you recommend taking?

(1). Submit a complete rewrite in awk as a single patch, to satisfy
the kernel development model requirements;
(2). Submit individual patches with repeating pieces of code
implemented as shell functions;

While my personal preference lies with option (1), I am willing to go
ahead with option (2), should the community prefer the shell
implementation over the awk one.

Thanks.

Alexander Kapshuk.


Fwd: Fwd: [PATCH 01/32] ver_linux: complete awk implementation

2016-08-21 Thread Alexander Kapshuk
-- Forwarded message --
From: Alexander Kapshuk 
Date: Sun, Aug 21, 2016 at 5:07 PM
Subject: Re: Fwd: [PATCH 01/32] ver_linux: complete awk implementation
To: Greg KH 


On Sun, Aug 21, 2016 at 11:19 AM, Greg KH  wrote:
>
> On Fri, Aug 19, 2016 at 09:12:28PM +0300, Alexander Kapshuk wrote:
> > Hello Greg,
> >
> > This is a follow-up on the series of 'ver_linux' patches I submitted at the 
> > end
> > of June, proposing a complete rewrite of the script in awk.
> >
> > So far, I have had feedback from one person, and I just wanted to get some
> > feedback from yourself too.
> >
> > I do appreciate the fact that you have other more pressing matters to 
> > attend to
> > at the moment, so there is no rush.
> >
> > I would appreciate hearing from you about my patches at your convenience.
>
> Last I saw, your patch series broke the build in the beginning and then
> fixed it up at the end, right?
>
> All patches have to never break the build, or functionality, at every
> step of the way.
>
> Sorry, it's a pain, but that's how the Linux kernel development model
> works.
>
> thanks,
>
> greg k-h


Thanks for your feedback and for clarifying how the Linux kernel
development model works.

Which of the two avenues presented below would you recommend taking?

(1). Submit a complete rewrite in awk as a single patch, to satisfy
the kernel development model requirements;
(2). Submit individual patches with repeating pieces of code
implemented as shell functions;

While my personal preference lies with option (1), I am willing to go
ahead with option (2), should the community prefer the shell
implementation over the awk one.

Thanks.

Alexander Kapshuk.


Re: [PATCH 3/5] firmware: ti_sci: Add support for Device control

2016-08-21 Thread Lokesh Vutla


On Saturday 20 August 2016 04:21 AM, Nishanth Menon wrote:
> Texas Instrument's System Control Interface (TI-SCI) Message Protocol
> is used in Texas Instrument's System on Chip (SoC) such as those
> in keystone family K2G SoC to communicate between various compute
> processors with a central system controller entity.
> 
> TI-SCI message protocol provides support for management of various
> hardware entitites within the SoC. Add support driver to allow
> communication with system controller entity within the SoC using the
> mailbox client.
> 
> We introduce the fundamental device management capability support to
> the driver protocol as part of this change.
> 
> [d-gerl...@ti.com: Contributed device reset handling]
> Signed-off-by: Dave Gerlach 
> Signed-off-by: Nishanth Menon 
> ---
>  drivers/firmware/ti_sci.c  | 433 
> +
>  drivers/firmware/ti_sci.h  |  98 
>  include/linux/soc/ti/ti_sci_protocol.h |  91 +++
>  3 files changed, 622 insertions(+)
> 
> diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
> index 4580c29dcb52..e0e286e76095 100644
> --- a/drivers/firmware/ti_sci.c
> +++ b/drivers/firmware/ti_sci.c
> @@ -496,6 +496,437 @@ fail:
>  }
>  
>  /**
> + * tis_sci_is_response_ack() - Generic ACK/NACK message checkup
> + * @r:   pointer to response buffer
> + *
> + * Return: true if the response was an ACK, else returns false.
> + */
> +static inline bool tis_sci_is_response_ack(void *r)

May be just ti_sci_is_response_ack() to be consistent? or you wanted to
keep it tis_sci* ?

> +{
> + struct ti_sci_msg_hdr *hdr = r;
> +
> + return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false;
> +}
> +
> +/**
> + * ti_sci_set_device_state() - Set device state helper
> + * @handle:  pointer to TI SCI handle
> + * @id:  Device identifier
> + * @flags:   flags to setup for the device
> + * @state:   State to move the device to
> + *
> + * Return: 0 if all went well, else returns appropriate error value.
> + */
> +static int ti_sci_set_device_state(const struct ti_sci_handle *handle,
> +u32 id, u32 flags, u8 state)
> +{
> + struct ti_sci_info *info;
> + struct ti_sci_msg_req_set_device_state *req;
> + struct ti_sci_msg_hdr *resp;
> + struct ti_sci_xfer *xfer;
> + struct device *dev;
> + int ret = 0;
> +
> + if (IS_ERR(handle))
> + return PTR_ERR(handle);
> + if (!handle)
> + return -EINVAL;
> +
> + info = handle_to_ti_sci_info(handle);
> + dev = info->dev;
> +
> + xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_DEVICE_STATE,
> +flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
> +sizeof(*req), sizeof(*resp));
> + if (IS_ERR(xfer)) {
> + ret = PTR_ERR(xfer);
> + dev_err(dev, "Message alloc failed(%d)\n", ret);
> + return ret;
> + }
> + req = (struct ti_sci_msg_req_set_device_state *)xfer->xfer_buf;
> + req->id = id;
> + req->state = state;
> +
> + ret = ti_sci_do_xfer(info, xfer);
> + if (ret) {
> + dev_err(dev, "Mbox send fail %d\n", ret);
> + goto fail;
> + }
> +
> + resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
> +
> + ret = tis_sci_is_response_ack(resp) ? 0 : -ENODEV;
> +
> +fail:
> + ti_sci_put_one_xfer(>minfo, xfer);
> +
> + return ret;
> +}
> +
> +/**
> + * ti_sci_get_device_state() - Get device state helper
> + * @handle:  Handle to the device
> + * @id:  Device Identifier
> + * @clcnt:   Pointer to Context Loss Count
> + * @resets:  pointer to resets
> + * @p_state: pointer to p_state
> + * @c_state: pointer to c_state
> + *
> + * Return: 0 if all went fine, else return appropriate error.
> + */
> +static int ti_sci_get_device_state(const struct ti_sci_handle *handle,
> +u32 id,  u32 *clcnt,  u32 *resets,
> + u8 *p_state,  u8 *c_state)
> +{
> + struct ti_sci_info *info;
> + struct ti_sci_msg_req_get_device_state *req;
> + struct ti_sci_msg_resp_get_device_state *resp;
> + struct ti_sci_xfer *xfer;
> + struct device *dev;
> + int ret = 0;
> +
> + if (IS_ERR(handle))
> + return PTR_ERR(handle);
> + if (!handle)
> + return -EINVAL;
> +
> + if (!clcnt && !resets && !p_state && !c_state)
> + return -EINVAL;
> +
> + info = handle_to_ti_sci_info(handle);
> + dev = info->dev;
> +
> + /* Response is expected, so need of any flags */
^^ no*

Thanks and regards,
Lokesh

> + xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_DEVICE_STATE,
> +0, sizeof(*req), sizeof(*resp));
> + if (IS_ERR(xfer)) {
> + ret = PTR_ERR(xfer);
> + dev_err(dev, 

Re: [PATCH 3/5] firmware: ti_sci: Add support for Device control

2016-08-21 Thread Lokesh Vutla


On Saturday 20 August 2016 04:21 AM, Nishanth Menon wrote:
> Texas Instrument's System Control Interface (TI-SCI) Message Protocol
> is used in Texas Instrument's System on Chip (SoC) such as those
> in keystone family K2G SoC to communicate between various compute
> processors with a central system controller entity.
> 
> TI-SCI message protocol provides support for management of various
> hardware entitites within the SoC. Add support driver to allow
> communication with system controller entity within the SoC using the
> mailbox client.
> 
> We introduce the fundamental device management capability support to
> the driver protocol as part of this change.
> 
> [d-gerl...@ti.com: Contributed device reset handling]
> Signed-off-by: Dave Gerlach 
> Signed-off-by: Nishanth Menon 
> ---
>  drivers/firmware/ti_sci.c  | 433 
> +
>  drivers/firmware/ti_sci.h  |  98 
>  include/linux/soc/ti/ti_sci_protocol.h |  91 +++
>  3 files changed, 622 insertions(+)
> 
> diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
> index 4580c29dcb52..e0e286e76095 100644
> --- a/drivers/firmware/ti_sci.c
> +++ b/drivers/firmware/ti_sci.c
> @@ -496,6 +496,437 @@ fail:
>  }
>  
>  /**
> + * tis_sci_is_response_ack() - Generic ACK/NACK message checkup
> + * @r:   pointer to response buffer
> + *
> + * Return: true if the response was an ACK, else returns false.
> + */
> +static inline bool tis_sci_is_response_ack(void *r)

May be just ti_sci_is_response_ack() to be consistent? or you wanted to
keep it tis_sci* ?

> +{
> + struct ti_sci_msg_hdr *hdr = r;
> +
> + return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false;
> +}
> +
> +/**
> + * ti_sci_set_device_state() - Set device state helper
> + * @handle:  pointer to TI SCI handle
> + * @id:  Device identifier
> + * @flags:   flags to setup for the device
> + * @state:   State to move the device to
> + *
> + * Return: 0 if all went well, else returns appropriate error value.
> + */
> +static int ti_sci_set_device_state(const struct ti_sci_handle *handle,
> +u32 id, u32 flags, u8 state)
> +{
> + struct ti_sci_info *info;
> + struct ti_sci_msg_req_set_device_state *req;
> + struct ti_sci_msg_hdr *resp;
> + struct ti_sci_xfer *xfer;
> + struct device *dev;
> + int ret = 0;
> +
> + if (IS_ERR(handle))
> + return PTR_ERR(handle);
> + if (!handle)
> + return -EINVAL;
> +
> + info = handle_to_ti_sci_info(handle);
> + dev = info->dev;
> +
> + xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_DEVICE_STATE,
> +flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
> +sizeof(*req), sizeof(*resp));
> + if (IS_ERR(xfer)) {
> + ret = PTR_ERR(xfer);
> + dev_err(dev, "Message alloc failed(%d)\n", ret);
> + return ret;
> + }
> + req = (struct ti_sci_msg_req_set_device_state *)xfer->xfer_buf;
> + req->id = id;
> + req->state = state;
> +
> + ret = ti_sci_do_xfer(info, xfer);
> + if (ret) {
> + dev_err(dev, "Mbox send fail %d\n", ret);
> + goto fail;
> + }
> +
> + resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
> +
> + ret = tis_sci_is_response_ack(resp) ? 0 : -ENODEV;
> +
> +fail:
> + ti_sci_put_one_xfer(>minfo, xfer);
> +
> + return ret;
> +}
> +
> +/**
> + * ti_sci_get_device_state() - Get device state helper
> + * @handle:  Handle to the device
> + * @id:  Device Identifier
> + * @clcnt:   Pointer to Context Loss Count
> + * @resets:  pointer to resets
> + * @p_state: pointer to p_state
> + * @c_state: pointer to c_state
> + *
> + * Return: 0 if all went fine, else return appropriate error.
> + */
> +static int ti_sci_get_device_state(const struct ti_sci_handle *handle,
> +u32 id,  u32 *clcnt,  u32 *resets,
> + u8 *p_state,  u8 *c_state)
> +{
> + struct ti_sci_info *info;
> + struct ti_sci_msg_req_get_device_state *req;
> + struct ti_sci_msg_resp_get_device_state *resp;
> + struct ti_sci_xfer *xfer;
> + struct device *dev;
> + int ret = 0;
> +
> + if (IS_ERR(handle))
> + return PTR_ERR(handle);
> + if (!handle)
> + return -EINVAL;
> +
> + if (!clcnt && !resets && !p_state && !c_state)
> + return -EINVAL;
> +
> + info = handle_to_ti_sci_info(handle);
> + dev = info->dev;
> +
> + /* Response is expected, so need of any flags */
^^ no*

Thanks and regards,
Lokesh

> + xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_DEVICE_STATE,
> +0, sizeof(*req), sizeof(*resp));
> + if (IS_ERR(xfer)) {
> + ret = PTR_ERR(xfer);
> + dev_err(dev, "Message alloc failed(%d)\n", 

Re: [PATCH v2 3/6] kexec_file: Allow skipping checksum calculation for some segments.

2016-08-21 Thread Thiago Jung Bauermann
Am Montag, 22 August 2016, 11:36:43 schrieb Dave Young:
> On 08/22/16 at 12:25am, Thiago Jung Bauermann wrote:
> > Am Montag, 22 August 2016, 11:17:45 schrieb Dave Young:
> > > On 08/18/16 at 06:09pm, Thiago Jung Bauermann wrote:
> > > > Hello Dave,
> > > > 
> > > > Thanks for your review!
> > > > 
> > > > [ Trimming down Cc: list a little to try to clear the "too many
> > > > recipients">
> > > > 
> > > >   mailing list restriction. ]
> > > 
> > > I also got "too many recipients".. Thanks for the trimming.
> > 
> > Didn't work though. What is the maximum number of recipients?
> 
> I have no idea as well..
> 
> > > > Am Donnerstag, 18 August 2016, 17:03:30 schrieb Dave Young:
> > > > > On 08/13/16 at 12:18am, Thiago Jung Bauermann wrote:
> > > > > > Adds checksum argument to kexec_add_buffer specifying whether
> > > > > > the
> > > > > > given
> > > > > > segment should be part of the checksum calculation.
> > > > > 
> > > > > Since it is used with add buffer, could it be added to kbuf as a
> > > > > new
> > > > > field?
> > > > 
> > > > I was on the fence about adding it as a new argument to
> > > > kexec_add_buffer
> > > > or as a new field to struct kexec_buf. Both alternatives make sense
> > > > to
> > > > me. I implemented your suggestion in the patch below, what do you
> > > > think?>
> > > > 
> > > > > Like kbuf.no_checksum, default value is 0 that means checksum is
> > > > > needed
> > > > > if it is 1 then no need a checksum.
> > > > 
> > > > It's an interesting idea and I implemented it that way, though in
> > > > practice all current users of struct kexec_buf put it on the stack
> > > > so
> > > > the field needs to be initialized explicitly.
> > > 
> > > No need to set it as false because it will be initialized to 0 by
> > > default?
> > 
> > As far as I know, variables on the stack are not initialized. Only
> > global
> > and static variables are.
> 
> But designated initializers will do it.

Ah, you are right! I'll provide an updated patch then. Thanks for your 
suggestion.

-- 
[]'s
Thiago Jung Bauermann
IBM Linux Technology Center



Re: [PATCH v2 3/6] kexec_file: Allow skipping checksum calculation for some segments.

2016-08-21 Thread Thiago Jung Bauermann
Am Montag, 22 August 2016, 11:36:43 schrieb Dave Young:
> On 08/22/16 at 12:25am, Thiago Jung Bauermann wrote:
> > Am Montag, 22 August 2016, 11:17:45 schrieb Dave Young:
> > > On 08/18/16 at 06:09pm, Thiago Jung Bauermann wrote:
> > > > Hello Dave,
> > > > 
> > > > Thanks for your review!
> > > > 
> > > > [ Trimming down Cc: list a little to try to clear the "too many
> > > > recipients">
> > > > 
> > > >   mailing list restriction. ]
> > > 
> > > I also got "too many recipients".. Thanks for the trimming.
> > 
> > Didn't work though. What is the maximum number of recipients?
> 
> I have no idea as well..
> 
> > > > Am Donnerstag, 18 August 2016, 17:03:30 schrieb Dave Young:
> > > > > On 08/13/16 at 12:18am, Thiago Jung Bauermann wrote:
> > > > > > Adds checksum argument to kexec_add_buffer specifying whether
> > > > > > the
> > > > > > given
> > > > > > segment should be part of the checksum calculation.
> > > > > 
> > > > > Since it is used with add buffer, could it be added to kbuf as a
> > > > > new
> > > > > field?
> > > > 
> > > > I was on the fence about adding it as a new argument to
> > > > kexec_add_buffer
> > > > or as a new field to struct kexec_buf. Both alternatives make sense
> > > > to
> > > > me. I implemented your suggestion in the patch below, what do you
> > > > think?>
> > > > 
> > > > > Like kbuf.no_checksum, default value is 0 that means checksum is
> > > > > needed
> > > > > if it is 1 then no need a checksum.
> > > > 
> > > > It's an interesting idea and I implemented it that way, though in
> > > > practice all current users of struct kexec_buf put it on the stack
> > > > so
> > > > the field needs to be initialized explicitly.
> > > 
> > > No need to set it as false because it will be initialized to 0 by
> > > default?
> > 
> > As far as I know, variables on the stack are not initialized. Only
> > global
> > and static variables are.
> 
> But designated initializers will do it.

Ah, you are right! I'll provide an updated patch then. Thanks for your 
suggestion.

-- 
[]'s
Thiago Jung Bauermann
IBM Linux Technology Center



Re: [PATCH v2 2/6] powerpc: kexec_file: Add buffer hand-over support for the next kernel

2016-08-21 Thread Thiago Jung Bauermann
Am Montag, 22 August 2016, 11:21:35 schrieb Dave Young:
> On 08/13/16 at 12:18am, Thiago Jung Bauermann wrote:
> > diff --git a/arch/powerpc/kernel/machine_kexec_64.c
> > b/arch/powerpc/kernel/machine_kexec_64.c index
> > a484a6346146..190c652e49b7 100644
> > --- a/arch/powerpc/kernel/machine_kexec_64.c
> > +++ b/arch/powerpc/kernel/machine_kexec_64.c
> > @@ -490,6 +490,60 @@ int arch_kimage_file_post_load_cleanup(struct
> > kimage *image)> 
> > return image->fops->cleanup(image->image_loader_data);
> >  
> >  }
> > 
> > +bool kexec_can_hand_over_buffer(void)
> > +{
> > +   return true;
> > +}
> > +
> > +int arch_kexec_add_handover_buffer(struct kimage *image,
> > +  unsigned long load_addr, unsigned long 
size)
> > +{
> > +   image->arch.handover_buffer_addr = load_addr;
> > +   image->arch.handover_buffer_size = size;
> > +
> > +   return 0;
> > +}
> > +
> > +int kexec_get_handover_buffer(void **addr, unsigned long *size)
> > +{
> > +   int ret;
> > +   u64 start_addr, end_addr;
> > +
> > +   ret = of_property_read_u64(of_chosen,
> > +  "linux,kexec-handover-buffer-start",
> > +  _addr);
> > +   if (ret == -EINVAL)
> > +   return -ENOENT;
> > +   else if (ret)
> > +   return -EINVAL;
> > +
> > +   ret = of_property_read_u64(of_chosen,
> > "linux,kexec-handover-buffer-end", +   
_addr);
> > +   if (ret == -EINVAL)
> > +   return -ENOENT;
> > +   else if (ret)
> > +   return -EINVAL;
> > +
> > +   *addr =  __va(start_addr);
> > +   /* -end is the first address after the buffer. */
> > +   *size = end_addr - start_addr;
> > +
> > +   return 0;
> > +}
> 
> This depends on dtb, so if IMA want to extend it to arches like x86 in
> the future you will have to think about other way to pass it.
> 
> How about think about a general way now?

The only general way I can think of is by adding a kernel command line 
parameter which the first kernel would pass to the second kernel, but IMHO 
that is ugly, because such parameter wouldn't be useful to a user, and it 
would also be something that, from the perspective of the user, would 
magically appear in the kernel command line of the second kernel...

-- 
[]'s
Thiago Jung Bauermann
IBM Linux Technology Center



Re: [PATCH v2 2/6] powerpc: kexec_file: Add buffer hand-over support for the next kernel

2016-08-21 Thread Thiago Jung Bauermann
Am Montag, 22 August 2016, 11:21:35 schrieb Dave Young:
> On 08/13/16 at 12:18am, Thiago Jung Bauermann wrote:
> > diff --git a/arch/powerpc/kernel/machine_kexec_64.c
> > b/arch/powerpc/kernel/machine_kexec_64.c index
> > a484a6346146..190c652e49b7 100644
> > --- a/arch/powerpc/kernel/machine_kexec_64.c
> > +++ b/arch/powerpc/kernel/machine_kexec_64.c
> > @@ -490,6 +490,60 @@ int arch_kimage_file_post_load_cleanup(struct
> > kimage *image)> 
> > return image->fops->cleanup(image->image_loader_data);
> >  
> >  }
> > 
> > +bool kexec_can_hand_over_buffer(void)
> > +{
> > +   return true;
> > +}
> > +
> > +int arch_kexec_add_handover_buffer(struct kimage *image,
> > +  unsigned long load_addr, unsigned long 
size)
> > +{
> > +   image->arch.handover_buffer_addr = load_addr;
> > +   image->arch.handover_buffer_size = size;
> > +
> > +   return 0;
> > +}
> > +
> > +int kexec_get_handover_buffer(void **addr, unsigned long *size)
> > +{
> > +   int ret;
> > +   u64 start_addr, end_addr;
> > +
> > +   ret = of_property_read_u64(of_chosen,
> > +  "linux,kexec-handover-buffer-start",
> > +  _addr);
> > +   if (ret == -EINVAL)
> > +   return -ENOENT;
> > +   else if (ret)
> > +   return -EINVAL;
> > +
> > +   ret = of_property_read_u64(of_chosen,
> > "linux,kexec-handover-buffer-end", +   
_addr);
> > +   if (ret == -EINVAL)
> > +   return -ENOENT;
> > +   else if (ret)
> > +   return -EINVAL;
> > +
> > +   *addr =  __va(start_addr);
> > +   /* -end is the first address after the buffer. */
> > +   *size = end_addr - start_addr;
> > +
> > +   return 0;
> > +}
> 
> This depends on dtb, so if IMA want to extend it to arches like x86 in
> the future you will have to think about other way to pass it.
> 
> How about think about a general way now?

The only general way I can think of is by adding a kernel command line 
parameter which the first kernel would pass to the second kernel, but IMHO 
that is ugly, because such parameter wouldn't be useful to a user, and it 
would also be something that, from the perspective of the user, would 
magically appear in the kernel command line of the second kernel...

-- 
[]'s
Thiago Jung Bauermann
IBM Linux Technology Center



  1   2   3   4   5   6   7   8   9   10   >