[Bug 96866] REGRESSION System frozen after resume
https://bugs.freedesktop.org/show_bug.cgi?id=96866 Christopher M. Penalver changed: What|Removed |Added Summary|System frozen after resume, |REGRESSION System frozen |on Ubuntu 16.04 kernel |after resume |4.4.0-22| Severity|critical|normal --- Comment #1 from Christopher M. Penalver --- 1) Edited title as not a Ubuntu bug, but an upstream one as per original reporter (reproducible in mainline 4.7-rc6 and a regression). 2) Issue after suspend isn't Critical. -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20160709/ca19e696/attachment.html>
[PATCH] drm/vc4: remove redundant ret status check
From: Colin Ian King At the current point where ret is being checked for non-zero it has not changed since it was initialized to zero, hence the check and the label unref are redundant and can be removed. Signed-off-by: Colin Ian King --- drivers/gpu/drm/vc4/vc4_drv.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 54d0471..0e4cf27 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -195,8 +195,6 @@ static int vc4_drm_bind(struct device *dev) vc4_bo_cache_init(drm); drm_mode_config_init(drm); - if (ret) - goto unref; vc4_gem_init(drm); @@ -218,7 +216,6 @@ unbind_all: component_unbind_all(dev, drm); gem_destroy: vc4_gem_destroy(drm); -unref: drm_dev_unref(drm); vc4_bo_cache_destroy(drm); return ret; -- 2.8.1
[PATCH v3 0/7] lib: string: add functions to case-convert strings
On 7/8/2016 6:43 PM, Markus Mayer wrote: > This series introduces a family of generic string case conversion > functions. This kind of functionality is needed in several places in > the kernel. Right now, everybody seems to be implementing their own > copy of this functionality. > > Based on the discussion of the previous version of this series[1] and > the use cases found in the kernel, it does look like having several > flavours of case conversion functions is beneficial. The use cases fall > into three categories: > - copying a string and converting the case while specifying a >maximum length to mimic strlcpy() > - copying a string and converting the case without specifying a >length to mimic strcpy() > - converting the case of a string in-place (i.e. modifying the >string that was passed in) > > Consequently, I am proposing these new functions: > void strlcpytoupper(char *dst, const char *src, size_t len); > void strlcpytolower(char *dst, const char *src, size_t len); > void strcpytoupper(char *dst, const char *src); > void strcpytolower(char *dst, const char *src); > void strtoupper(char *s); > void strtolower(char *s); You may want to read the article here: https://lwn.net/Articles/659214/ and follow up some of the discussion threads on LKML about the best semantics to advertise for the strlcpy/strscpy variants. It might be helpful to return some kind of overflow/truncation error from your copy functions so people can error-check the result. -- Chris Metcalf, Mellanox Technologies http://www.mellanox.com
[PATCH] qxl: correctly handling failed allocation
Hi, [auto build test ERROR on drm/drm-next] [also build test ERROR on v4.7-rc6 next-20160708] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Insu-Yun/qxl-correctly-handling-failed-allocation/20151230-031647 base: git://people.freedesktop.org/~airlied/linux.git drm-next config: x86_64-allmodconfig (attached as .config) compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All errors (new ones prefixed by >>): drivers/gpu/drm/qxl/qxl_kms.c: In function 'qxl_device_init': >> drivers/gpu/drm/qxl/qxl_kms.c:224:11: error: 'struct qxl_device' has no >> member named 'memslots'; did you mean 'mem_slots'? if (!qdev->memslots) ^~ vim +224 drivers/gpu/drm/qxl/qxl_kms.c 218 (~(uint64_t)0) >> (qdev->slot_id_bits + qdev->slot_gen_bits); 219 220 qdev->mem_slots = 221 kmalloc(qdev->n_mem_slots * sizeof(struct qxl_memslot), 222 GFP_KERNEL); 223 > 224 if (!qdev->memslots) 225 return -ENOMEM; 226 227 idr_init(&qdev->release_idr); --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation -- next part -- A non-text attachment was scrubbed... Name: .config.gz Type: application/octet-stream Size: 51082 bytes Desc: not available URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20160709/3dfe4b17/attachment-0001.obj>
[PATCH v3 0/7] lib: string: add functions to case-convert strings
On 9 July 2016 at 20:13, Chris Metcalf wrote: > On 7/8/2016 6:43 PM, Markus Mayer wrote: >> >> This series introduces a family of generic string case conversion >> functions. This kind of functionality is needed in several places in >> the kernel. Right now, everybody seems to be implementing their own >> copy of this functionality. >> >> Based on the discussion of the previous version of this series[1] and >> the use cases found in the kernel, it does look like having several >> flavours of case conversion functions is beneficial. The use cases fall >> into three categories: >> - copying a string and converting the case while specifying a >>maximum length to mimic strlcpy() >> - copying a string and converting the case without specifying a >>length to mimic strcpy() >> - converting the case of a string in-place (i.e. modifying the >>string that was passed in) >> >> Consequently, I am proposing these new functions: >> void strlcpytoupper(char *dst, const char *src, size_t len); >> void strlcpytolower(char *dst, const char *src, size_t len); >> void strcpytoupper(char *dst, const char *src); >> void strcpytolower(char *dst, const char *src); >> void strtoupper(char *s); >> void strtolower(char *s); > > > You may want to read the article here: > > https://lwn.net/Articles/659214/ I'll read that. Thanks. > and follow up some of the discussion threads on LKML about the best > semantics to advertise for the strlcpy/strscpy variants. It might be > helpful to return some kind of overflow/truncation error from your > copy functions so people can error-check the result. I am inclined to agree. However, everybody has been telling me that these functions should be void. Originally they weren't. Regards, -Markus
[PATCH 2/2] drm/vc4: Squash commit for Mario's precise vblank timestamping.
Hi Eric, thanks for all the infos and help! Both your patches look good and i have successfully tested them on top of with my vblank timestamping patch. So for both: Reviewed-and-tested-by: Mario Kleiner Will you squash 2/2 into my patch or should i resend my patch with yours squashed in? thanks, -mario On 07/08/2016 08:44 PM, Eric Anholt wrote: > Read out the DISPBASE registers to decide on the FIFO size. > > Signed-off-by: Eric Anholt > --- > > Mario: How about this for a squash into your commit? Here are the > values I dumped for cob_size: > > [2.148314] [drm] Scaler 0 size 5232 > [2.162239] [drm] Scaler 2 size 2048 > [2.172957] [drm] Scaler 1 size 13456 > > drivers/gpu/drm/vc4/vc4_crtc.c | 23 +-- > drivers/gpu/drm/vc4/vc4_regs.h | 18 +- > 2 files changed, 38 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c > index baf962bce063..3b7db17c356d 100644 > --- a/drivers/gpu/drm/vc4/vc4_crtc.c > +++ b/drivers/gpu/drm/vc4/vc4_crtc.c > @@ -55,6 +55,8 @@ struct vc4_crtc { > u8 lut_r[256]; > u8 lut_g[256]; > u8 lut_b[256]; > + /* Size in pixels of the COB memory allocated to this CRTC. */ > + u32 cob_size; > > struct drm_pending_vblank_event *event; > }; > @@ -195,8 +197,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, > unsigned int crtc_id, > *hpos = 0; > > /* This is the offset we need for translating hvs -> pv scanout pos. */ > - /* XXX Find proper formula from hw docs instead of guesstimating? */ > - fifo_lines = 2048 * 7 / mode->crtc_hdisplay; > + fifo_lines = vc4_crtc->cob_size / mode->crtc_hdisplay; > > if (fifo_lines > 0) > ret |= DRM_SCANOUTPOS_VALID; > @@ -873,6 +874,22 @@ static void vc4_set_crtc_possible_masks(struct > drm_device *drm, > } > } > > +static void > +vc4_crtc_get_cob_allocation(struct vc4_crtc *vc4_crtc) > +{ > + struct drm_device *drm = vc4_crtc->base.dev; > + struct vc4_dev *vc4 = to_vc4_dev(drm); > + u32 dispbase = HVS_READ(SCALER_DISPBASEX(vc4_crtc->channel)); > + /* Top/base are supposed to be 4-pixel aligned, but the > + * Raspberry Pi firmware fills the low bits (which are > + * presumably ignored). > + */ > + u32 top = VC4_GET_FIELD(dispbase, SCALER_DISPBASEX_TOP) & ~3; > + u32 base = VC4_GET_FIELD(dispbase, SCALER_DISPBASEX_BASE) & ~3; > + > + vc4_crtc->cob_size = top - base + 4; > +} > + > static int vc4_crtc_bind(struct device *dev, struct device *master, void > *data) > { > struct platform_device *pdev = to_platform_device(dev); > @@ -949,6 +966,8 @@ static int vc4_crtc_bind(struct device *dev, struct > device *master, void *data) > crtc->cursor = cursor_plane; > } > > + vc4_crtc_get_cob_allocation(vc4_crtc); > + > CRTC_WRITE(PV_INTEN, 0); > CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START); > ret = devm_request_irq(dev, platform_get_irq(pdev, 0), > diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h > index 63cdc28ff7bb..160942a9180e 100644 > --- a/drivers/gpu/drm/vc4/vc4_regs.h > +++ b/drivers/gpu/drm/vc4/vc4_regs.h > @@ -366,7 +366,6 @@ > # define SCALER_DISPBKGND_FILL BIT(24) > > #define SCALER_DISPSTAT00x0048 > -#define SCALER_DISPBASE00x004c > # define SCALER_DISPSTATX_MODE_MASK VC4_MASK(31, 30) > # define SCALER_DISPSTATX_MODE_SHIFT30 > # define SCALER_DISPSTATX_MODE_DISABLED 0 > @@ -379,6 +378,20 @@ > # define SCALER_DISPSTATX_FRAME_COUNT_SHIFT 12 > # define SCALER_DISPSTATX_LINE_MASK VC4_MASK(11, 0) > # define SCALER_DISPSTATX_LINE_SHIFT0 > + > +#define SCALER_DISPBASE00x004c > +/* Last pixel in the COB (display FIFO memory) allocated to this HVS > + * channel. Must be 4-pixel aligned (and thus 4 pixels less than the > + * next COB base). > + */ > +# define SCALER_DISPBASEX_TOP_MASK VC4_MASK(31, 16) > +# define SCALER_DISPBASEX_TOP_SHIFT 16 > +/* First pixel in the COB (display FIFO memory) allocated to this HVS > + * channel. Must be 4-pixel aligned. > + */ > +# define SCALER_DISPBASEX_BASE_MASK VC4_MASK(15, 0) > +# define SCALER_DISPBASEX_BASE_SHIFT 0 > + > #define SCALER_DISPCTRL10x0050 > #define SCALER_DISPBKGND1 0x0054 > #define SCALER_DISPBKGNDX(x)(SCALER_DISPBKGND0 + > \ > @@ -389,6 +402,9 @@ >(x) * (SCALER_DISPSTAT1 - \ > SCALER_DISPSTAT0)) > #define SCALER_DISPBASE10x005c > +#define SCALER_DISPBASEX(x) (SCALER_DISPBASE0 +\ > +
[PATCH 3/3] drm/imx: remove unneeded 'or' operation
From: Fabio Estevam There is no need for doing an extra 'or' operation when reading the return value from of_property_read_u32(). Just do a simple read instead. Signed-off-by: Fabio Estevam --- drivers/gpu/drm/imx/imx-tve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c index a52939c..2cf0631 100644 --- a/drivers/gpu/drm/imx/imx-tve.c +++ b/drivers/gpu/drm/imx/imx-tve.c @@ -594,7 +594,7 @@ static int imx_tve_bind(struct device *dev, struct device *master, void *data) return ret; } - ret |= of_property_read_u32(np, "fsl,vsync-pin", + ret = of_property_read_u32(np, "fsl,vsync-pin", &tve->vsync_pin); if (ret < 0) { -- 1.9.1
[PATCH 2/3] drm/imx: fix the error message
From: Fabio Estevam The error message should say "hsync" instead of "vsync" as we have just checked the "fsl,hsync-pin" property. Signed-off-by: Fabio Estevam --- drivers/gpu/drm/imx/imx-tve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c index c93301c..a52939c 100644 --- a/drivers/gpu/drm/imx/imx-tve.c +++ b/drivers/gpu/drm/imx/imx-tve.c @@ -590,7 +590,7 @@ static int imx_tve_bind(struct device *dev, struct device *master, void *data) &tve->hsync_pin); if (ret < 0) { - dev_err(dev, "failed to get vsync pin\n"); + dev_err(dev, "failed to get hsync pin\n"); return ret; } -- 1.9.1
[PATCH 1/3] drm/imx: check the value returned by regulator_set_voltage()
From: Fabio Estevam regulator_set_voltage() may fail, so we better check its return value and propagate it in the case of error. Signed-off-by: Fabio Estevam --- drivers/gpu/drm/imx/imx-tve.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c index baf7881..c93301c 100644 --- a/drivers/gpu/drm/imx/imx-tve.c +++ b/drivers/gpu/drm/imx/imx-tve.c @@ -633,7 +633,9 @@ static int imx_tve_bind(struct device *dev, struct device *master, void *data) tve->dac_reg = devm_regulator_get(dev, "dac"); if (!IS_ERR(tve->dac_reg)) { - regulator_set_voltage(tve->dac_reg, 275, 275); + ret = regulator_set_voltage(tve->dac_reg, 275, 275); + if (ret) + return ret; ret = regulator_enable(tve->dac_reg); if (ret) return ret; -- 1.9.1
[PATCH v3 1/7] lib: string: add functions to case-convert strings
On 08/07/16 23:43, Markus Mayer wrote: > Add a collection of generic functions to convert strings to lowercase > or uppercase. > > Changing the case of a string (with or without copying it first) seems > to be a recurring requirement in the kernel that is currently being > solved by several duplicated implementations doing the same thing. This > change aims at reducing this code duplication. > > The new functions are > void strlcpytoupper(char *dst, const char *src, size_t len); > void strlcpytolower(char *dst, const char *src, size_t len); > void strcpytoupper(char *dst, const char *src); > void strcpytolower(char *dst, const char *src); > void strtoupper(char *s); > void strtolower(char *s); > > The "str[l]cpyto*" versions of the function take a destination string > and a source string as arguments. The "strlcpyto*" versions additionally > take a length argument like strlcpy() itself. Lastly, the strto* > functions take a single string argument and modify the passed-in string. > > Like strlcpy(), and unlike strncpy(), the functions guarantee NULL > termination of the destination string. > > Signed-off-by: Markus Mayer > --- > include/linux/string.h | 40 > lib/string.c | 38 ++ > 2 files changed, 78 insertions(+) > > diff --git a/include/linux/string.h b/include/linux/string.h > index 26b6f6a..36c9d14 100644 > --- a/include/linux/string.h > +++ b/include/linux/string.h > @@ -116,6 +116,8 @@ extern void * memchr(const void *,int,__kernel_size_t); > #endif > void *memchr_inv(const void *s, int c, size_t n); > char *strreplace(char *s, char old, char new); > +extern void strlcpytoupper(char *dst, const char *src, size_t len); > +extern void strlcpytolower(char *dst, const char *src, size_t len); > > extern void kfree_const(const void *x); > > @@ -169,4 +171,42 @@ static inline const char *kbasename(const char *path) > return tail ? tail + 1 : path; > } > > +/** > + * strcpytoupper - Copy string and convert to uppercase. > + * @dst: The buffer to store the result. > + * @src: The string to convert to uppercase. > + */ > +static inline void strcpytoupper(char *dst, const char *src) > +{ > + strlcpytoupper(dst, src, -1); > +} > + Why not use SIZE_MAX instead of -1? > +/** > + * strcpytolower - Copy string and convert to lowercase. > + * @dst: The buffer to store the result. > + * @src: The string to convert to lowercase. > + */ > +static inline void strcpytolower(char *dst, const char *src) > +{ > + strlcpytolower(dst, src, -1); > +} > + Same here, and the 2 below :) Thanks Markus, Luis > +/** > + * strtoupper - Convert string to uppercase. > + * @s: The string to operate on. > + */ > +static inline void strtoupper(char *s) > +{ > + strlcpytoupper(s, s, -1); > +} > + > +/** > + * strtolower - Convert string to lowercase. > + * @s: The string to operate on. > + */ > +static inline void strtolower(char *s) > +{ > + strlcpytolower(s, s, -1); > +} > + > #endif /* _LINUX_STRING_H_ */ > diff --git a/lib/string.c b/lib/string.c > index ed83562..fd8c427 100644 > --- a/lib/string.c > +++ b/lib/string.c > @@ -952,3 +952,41 @@ char *strreplace(char *s, char old, char new) > return s; > } > EXPORT_SYMBOL(strreplace); > + > +/** > + * strlcpytoupper - Copy a length-limited string and convert to uppercase. > + * @dst: The buffer to store the result. > + * @src: The string to convert to uppercase. > + * @len: Maximum string length. May be SIZE_MAX (-1) to set no limit. > + */ > +void strlcpytoupper(char *dst, const char *src, size_t len) > +{ > + size_t i; > + > + if (!len) > + return; > + > + for (i = 0; i < len && src[i]; ++i) > + dst[i] = toupper(src[i]); > + dst[i < len ? i : i - 1] = '\0'; > +} > +EXPORT_SYMBOL(strlcpytoupper); > + > +/** > + * strlcpytolower - Copy a length-limited string and convert to lowercase. > + * @dst: The buffer to store the result. > + * @src: The string to convert to lowercase. > + * @len: Maximum string length. May be SIZE_MAX (-1) to set no limit. > + */ > +void strlcpytolower(char *dst, const char *src, size_t len) > +{ > + size_t i; > + > + if (!len) > + return; > + > + for (i = 0; i < len && src[i]; ++i) > + dst[i] = tolower(src[i]); > + dst[i < len ? i : i - 1] = '\0'; > +} > +EXPORT_SYMBOL(strlcpytolower); >
[Bug 96860] Aliasing when using vdpau with mpv
https://bugs.freedesktop.org/show_bug.cgi?id=96860 --- Comment #2 from nfxjfg at gmail.com --- > Does this happen with -vo vdpau as well? No. It didn't happen with mapping video mixer output surfaces in GL either. This issue came up because mpv started to map video surface textures directly. > If not it sounds like the deinterlacing shader in mpv doesn't work 100% > correctly. Any clue what could be wrong? (See linked mpv bug report.) Also, another user replied and claimed it got fixed by updating to Mesa 12. -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20160709/324f67c4/attachment.html>
[PATCH v3 1/7] lib: string: add functions to case-convert strings
On 9 July 2016 at 05:04, Luis de Bethencourt wrote: > On 08/07/16 23:43, Markus Mayer wrote: >> Add a collection of generic functions to convert strings to lowercase >> or uppercase. >> >> Changing the case of a string (with or without copying it first) seems >> to be a recurring requirement in the kernel that is currently being >> solved by several duplicated implementations doing the same thing. This >> change aims at reducing this code duplication. >> >> The new functions are >> void strlcpytoupper(char *dst, const char *src, size_t len); >> void strlcpytolower(char *dst, const char *src, size_t len); >> void strcpytoupper(char *dst, const char *src); >> void strcpytolower(char *dst, const char *src); >> void strtoupper(char *s); >> void strtolower(char *s); >> >> The "str[l]cpyto*" versions of the function take a destination string >> and a source string as arguments. The "strlcpyto*" versions additionally >> take a length argument like strlcpy() itself. Lastly, the strto* >> functions take a single string argument and modify the passed-in string. >> >> Like strlcpy(), and unlike strncpy(), the functions guarantee NULL >> termination of the destination string. >> >> Signed-off-by: Markus Mayer >> --- >> include/linux/string.h | 40 >> lib/string.c | 38 ++ >> 2 files changed, 78 insertions(+) >> >> diff --git a/include/linux/string.h b/include/linux/string.h >> index 26b6f6a..36c9d14 100644 >> --- a/include/linux/string.h >> +++ b/include/linux/string.h >> @@ -116,6 +116,8 @@ extern void * memchr(const void *,int,__kernel_size_t); >> #endif >> void *memchr_inv(const void *s, int c, size_t n); >> char *strreplace(char *s, char old, char new); >> +extern void strlcpytoupper(char *dst, const char *src, size_t len); >> +extern void strlcpytolower(char *dst, const char *src, size_t len); >> >> extern void kfree_const(const void *x); >> >> @@ -169,4 +171,42 @@ static inline const char *kbasename(const char *path) >> return tail ? tail + 1 : path; >> } >> >> +/** >> + * strcpytoupper - Copy string and convert to uppercase. >> + * @dst: The buffer to store the result. >> + * @src: The string to convert to uppercase. >> + */ >> +static inline void strcpytoupper(char *dst, const char *src) >> +{ >> + strlcpytoupper(dst, src, -1); >> +} >> + > > Why not use SIZE_MAX instead of -1? Sure. I'll change all four of them. Thanks. >> +/** >> + * strcpytolower - Copy string and convert to lowercase. >> + * @dst: The buffer to store the result. >> + * @src: The string to convert to lowercase. >> + */ >> +static inline void strcpytolower(char *dst, const char *src) >> +{ >> + strlcpytolower(dst, src, -1); >> +} >> + > > Same here, and the 2 below :) > > Thanks Markus, > Luis > >> +/** >> + * strtoupper - Convert string to uppercase. >> + * @s: The string to operate on. >> + */ >> +static inline void strtoupper(char *s) >> +{ >> + strlcpytoupper(s, s, -1); >> +} >> + >> +/** >> + * strtolower - Convert string to lowercase. >> + * @s: The string to operate on. >> + */ >> +static inline void strtolower(char *s) >> +{ >> + strlcpytolower(s, s, -1); >> +} >> + >> #endif /* _LINUX_STRING_H_ */ >> diff --git a/lib/string.c b/lib/string.c >> index ed83562..fd8c427 100644 >> --- a/lib/string.c >> +++ b/lib/string.c >> @@ -952,3 +952,41 @@ char *strreplace(char *s, char old, char new) >> return s; >> } >> EXPORT_SYMBOL(strreplace); >> + >> +/** >> + * strlcpytoupper - Copy a length-limited string and convert to uppercase. >> + * @dst: The buffer to store the result. >> + * @src: The string to convert to uppercase. >> + * @len: Maximum string length. May be SIZE_MAX (-1) to set no limit. >> + */ >> +void strlcpytoupper(char *dst, const char *src, size_t len) >> +{ >> + size_t i; >> + >> + if (!len) >> + return; >> + >> + for (i = 0; i < len && src[i]; ++i) >> + dst[i] = toupper(src[i]); >> + dst[i < len ? i : i - 1] = '\0'; >> +} >> +EXPORT_SYMBOL(strlcpytoupper); >> + >> +/** >> + * strlcpytolower - Copy a length-limited string and convert to lowercase. >> + * @dst: The buffer to store the result. >> + * @src: The string to convert to lowercase. >> + * @len: Maximum string length. May be SIZE_MAX (-1) to set no limit. >> + */ >> +void strlcpytolower(char *dst, const char *src, size_t len) >> +{ >> + size_t i; >> + >> + if (!len) >> + return; >> + >> + for (i = 0; i < len && src[i]; ++i) >> + dst[i] = tolower(src[i]); >> + dst[i < len ? i : i - 1] = '\0'; >> +} >> +EXPORT_SYMBOL(strlcpytolower); >> >