cron job: media_tree daily build: ERRORS
This message is generated daily by a cron job that builds media_tree for the kernels and architectures in the list below. Results of the daily build of media_tree: date: Wed Apr 26 05:00:15 CEST 2017 media-tree git hash:3622d3e77ecef090b5111e3c5423313f11711dfa media_build git hash: 1af19680bde3e227d64d99ff5fdc43eb343a3b28 v4l-utils git hash: b514d615166bdc0901a4c71261b87db31e89f464 gcc version:i686-linux-gcc (GCC) 6.2.0 sparse version: v0.5.0-3553-g78b2ea6 smatch version: v0.5.0-3553-g78b2ea6 host hardware: x86_64 host os:4.9.0-164 linux-git-arm-at91: OK linux-git-arm-davinci: OK linux-git-arm-multi: OK linux-git-arm-pxa: OK linux-git-blackfin-bf561: OK linux-git-i686: OK linux-git-m32r: OK linux-git-mips: OK linux-git-powerpc64: OK linux-git-sh: OK linux-git-x86_64: OK linux-2.6.36.4-i686: ERRORS linux-2.6.37.6-i686: ERRORS linux-2.6.38.8-i686: ERRORS linux-2.6.39.4-i686: ERRORS linux-3.0.60-i686: ERRORS linux-3.1.10-i686: ERRORS linux-3.2.37-i686: OK linux-3.3.8-i686: OK linux-3.4.27-i686: OK linux-3.5.7-i686: OK linux-3.6.11-i686: OK linux-3.7.4-i686: OK linux-3.8-i686: OK linux-3.9.2-i686: OK linux-3.10.1-i686: WARNINGS linux-3.11.1-i686: ERRORS linux-3.12.67-i686: ERRORS linux-3.13.11-i686: ERRORS linux-3.14.9-i686: WARNINGS linux-3.15.2-i686: WARNINGS linux-3.16.7-i686: WARNINGS linux-3.17.8-i686: WARNINGS linux-3.18.7-i686: WARNINGS linux-3.19-i686: WARNINGS linux-4.0.9-i686: WARNINGS linux-4.1.33-i686: WARNINGS linux-4.2.8-i686: WARNINGS linux-4.3.6-i686: WARNINGS linux-4.4.22-i686: WARNINGS linux-4.5.7-i686: WARNINGS linux-4.6.7-i686: WARNINGS linux-4.7.5-i686: WARNINGS linux-4.8-i686: OK linux-4.9-i686: OK linux-4.10.1-i686: OK linux-4.11-rc1-i686: OK linux-2.6.36.4-x86_64: ERRORS linux-2.6.37.6-x86_64: ERRORS linux-2.6.38.8-x86_64: ERRORS linux-2.6.39.4-x86_64: ERRORS linux-3.0.60-x86_64: ERRORS linux-3.1.10-x86_64: ERRORS linux-3.2.37-x86_64: OK linux-3.3.8-x86_64: OK linux-3.4.27-x86_64: OK linux-3.5.7-x86_64: OK linux-3.6.11-x86_64: OK linux-3.7.4-x86_64: OK linux-3.8-x86_64: OK linux-3.9.2-x86_64: OK linux-3.10.1-x86_64: WARNINGS linux-3.11.1-x86_64: ERRORS linux-3.12.67-x86_64: ERRORS linux-3.13.11-x86_64: ERRORS linux-3.14.9-x86_64: WARNINGS linux-3.15.2-x86_64: WARNINGS linux-3.16.7-x86_64: WARNINGS linux-3.17.8-x86_64: WARNINGS linux-3.18.7-x86_64: WARNINGS linux-3.19-x86_64: WARNINGS linux-4.0.9-x86_64: WARNINGS linux-4.1.33-x86_64: WARNINGS linux-4.2.8-x86_64: WARNINGS linux-4.3.6-x86_64: WARNINGS linux-4.4.22-x86_64: WARNINGS linux-4.5.7-x86_64: WARNINGS linux-4.6.7-x86_64: WARNINGS linux-4.7.5-x86_64: WARNINGS linux-4.8-x86_64: WARNINGS linux-4.9-x86_64: WARNINGS linux-4.10.1-x86_64: WARNINGS linux-4.11-rc1-x86_64: OK apps: WARNINGS spec-git: OK sparse: WARNINGS Detailed results are available here: http://www.xs4all.nl/~hverkuil/logs/Wednesday.log Full logs are available here: http://www.xs4all.nl/~hverkuil/logs/Wednesday.tar.bz2 The Media Infrastructure API from this daily build is here: http://www.xs4all.nl/~hverkuil/spec/index.html
Re: [PATCH] [media] s5p-jpeg: fix recursive spinlock acquisition
On Wed, Apr 26, 2017 at 4:15 AM, Jacek Anaszewski wrote: > Hi Alexandre, > > Thanks for the patch. > > On 04/25/2017 08:19 AM, Alexandre Courbot wrote: >> v4l2_m2m_job_finish(), which is called from the interrupt handler with >> slock acquired, can call the device_run() hook immediately if another >> context was in the queue. This hook also acquires slock, resulting in >> a deadlock for this scenario. >> >> Fix this by releasing slock right before calling v4l2_m2m_job_finish(). >> This is safe to do as the state of the hardware cannot change before >> v4l2_m2m_job_finish() is called anyway. >> >> Signed-off-by: Alexandre Courbot >> --- >> drivers/media/platform/s5p-jpeg/jpeg-core.c | 12 +--- >> 1 file changed, 9 insertions(+), 3 deletions(-) >> >> diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c >> b/drivers/media/platform/s5p-jpeg/jpeg-core.c >> index 52dc7941db65..223b4379929e 100644 >> --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c >> +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c >> @@ -2642,13 +2642,13 @@ static irqreturn_t s5p_jpeg_irq(int irq, void >> *dev_id) >> if (curr_ctx->mode == S5P_JPEG_ENCODE) >> vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload_size); >> v4l2_m2m_buf_done(dst_buf, state); >> - v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx); >> >> curr_ctx->subsampling = s5p_jpeg_get_subsampling_mode(jpeg->regs); >> spin_unlock(&jpeg->slock); >> >> s5p_jpeg_clear_int(jpeg->regs); >> >> + v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx); >> return IRQ_HANDLED; >> } >> >> @@ -2707,11 +2707,12 @@ static irqreturn_t exynos4_jpeg_irq(int irq, void >> *priv) >> v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR); >> } >> >> - v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx); >> if (jpeg->variant->version == SJPEG_EXYNOS4) >> curr_ctx->subsampling = exynos4_jpeg_get_frame_fmt(jpeg->regs); >> >> spin_unlock(&jpeg->slock); >> + >> + v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx); >> return IRQ_HANDLED; >> } >> >> @@ -2770,10 +2771,15 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void >> *dev_id) >> if (curr_ctx->mode == S5P_JPEG_ENCODE) >> vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload_size); >> v4l2_m2m_buf_done(dst_buf, state); >> - v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx); >> >> curr_ctx->subsampling = >> exynos3250_jpeg_get_subsampling_mode(jpeg->regs); >> + >> + spin_unlock(&jpeg->slock); >> + >> + v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx); >> + return IRQ_HANDLED; >> + >> exit_unlock: >> spin_unlock(&jpeg->slock); >> return IRQ_HANDLED; >> > > Acked-by: Jacek Anaszewski > > Just out of curiosity - could you share how you discovered the problem - > by some static checkers or trying to use the driver? We discovered this issue after adding a new unit test for the jpeg codec in Chromium OS: https://bugs.chromium.org/p/chromium/issues/detail?id=705971 >From what I understand the test spawns different processes that access the codec device concurrently, creating the situation leading to the bug. On a slightly related note, I was thinking whether it would make sense to move the call to v4l2_m2m_job_finish() (and maybe other parts of the current interrupt handler) into a worker or a threaded interrupt handler so as to reduce the time we spend with interrupts disabled. Can I have your input on this idea?
Re: [PATCH] dma-buf: avoid scheduling on fence status query
CC a few extra lists I missed. Regards, Andres On 2017-04-25 09:36 PM, Andres Rodriguez wrote: When a timeout of zero is specified, the caller is only interested in the fence status. In the current implementation, dma_fence_default_wait will always call schedule_timeout() at least once for an unsignaled fence. This adds a significant overhead to a fence status query. Avoid this overhead by returning early if a zero timeout is specified. Signed-off-by: Andres Rodriguez --- This heavily affects the performance of the Source2 engine running on radv. This patch improves dota2(radv) perf on a i7-6700k+RX480 system from 72fps->81fps. drivers/dma-buf/dma-fence.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c index 0918d3f..348e9e2 100644 --- a/drivers/dma-buf/dma-fence.c +++ b/drivers/dma-buf/dma-fence.c @@ -380,6 +380,9 @@ dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout) if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) return ret; + if (!timeout) + return 0; + spin_lock_irqsave(fence->lock, flags); if (intr && signal_pending(current)) {
Re: [RFC 0/4] Exynos DRM: add Picture Processor extension
Hi Marek, On Thu, Apr 20, 2017 at 01:23:09PM +0200, Marek Szyprowski wrote: > Hi Laurent, > > On 2017-04-20 12:25, Laurent Pinchart wrote: > >Hi Marek, > > > >(CC'ing Sakari Ailus) > > > >Thank you for the patches. > > > >On Thursday 20 Apr 2017 11:13:36 Marek Szyprowski wrote: > >>Dear all, > >> > >>This is an updated proposal for extending EXYNOS DRM API with generic > >>support for hardware modules, which can be used for processing image data > >>from the one memory buffer to another. Typical memory-to-memory operations > >>are: rotation, scaling, colour space conversion or mix of them. This is a > >>follow-up of my previous proposal "[RFC 0/2] New feature: Framebuffer > >>processors", which has been rejected as "not really needed in the DRM > >>core": > >>http://www.mail-archive.com/dri-devel@lists.freedesktop.org/msg146286.html > >> > >>In this proposal I moved all the code to Exynos DRM driver, so now this > >>will be specific only to Exynos DRM. I've also changed the name from > >>framebuffer processor (fbproc) to picture processor (pp) to avoid confusion > >>with fbdev API. > >> > >>Here is a bit more information what picture processors are: > >> > >>Embedded SoCs are known to have a number of hardware blocks, which perform > >>such operations. They can be used in paralel to the main GPU module to > >>offload CPU from processing grapics or video data. One of example use of > >>such modules is implementing video overlay, which usually requires color > >>space conversion from NV12 (or similar) to RGB32 color space and scaling to > >>target window size. > >> > >>The proposed API is heavily inspired by atomic KMS approach - it is also > >>based on DRM objects and their properties. A new DRM object is introduced: > >>picture processor (called pp for convenience). Such objects have a set of > >>standard DRM properties, which describes the operation to be performed by > >>respective hardware module. In typical case those properties are a source > >>fb id and rectangle (x, y, width, height) and destination fb id and > >>rectangle. Optionally a rotation property can be also specified if > >>supported by the given hardware. To perform an operation on image data, > >>userspace provides a set of properties and their values for given fbproc > >>object in a similar way as object and properties are provided for > >>performing atomic page flip / mode setting. > >> > >>The proposed API consists of the 3 new ioctls: > >>- DRM_IOCTL_EXYNOS_PP_GET_RESOURCES: to enumerate all available picture > >> processors, > >>- DRM_IOCTL_EXYNOS_PP_GET: to query capabilities of given picture > >> processor, > >>- DRM_IOCTL_EXYNOS_PP_COMMIT: to perform operation described by given > >> property set. > >> > >>The proposed API is extensible. Drivers can attach their own, custom > >>properties to add support for more advanced picture processing (for example > >>blending). > >> > >>This proposal aims to replace Exynos DRM IPP (Image Post Processing) > >>subsystem. IPP API is over-engineered in general, but not really extensible > >>on the other side. It is also buggy, with significant design flaws - the > >>biggest issue is the fact that the API covers memory-2-memory picture > >>operations together with CRTC writeback and duplicating features, which > >>belongs to video plane. Comparing with IPP subsystem, the PP framework is > >>smaller (1807 vs 778 lines) and allows driver simplification (Exynos > >>rotator driver smaller by over 200 lines). > >This seems to be the kind of hardware that is typically supported by V4L2. > >Stupid question, why DRM ? > > Let me elaborate a bit on the reasons for implementing it in Exynos DRM: > > 1. we want to replace existing Exynos IPP subsystem: > - it is used only in some internal/vendor trees, not in open-source > - we want it to have sane and potentially extensible userspace API > - but we don't want to loose its functionality > > 2. we want to have simple API for performing single image processing > operation: > - typically it will be used by compositing window manager, this means that >some parameters of the processing might change on each vblank (like >destination rectangle for example). This api allows such change on each >operation without any additional cost. V4L2 requires to reinitialize >queues with new configuration on such change, what means that a bunch of >ioctls has to be called. What do you mean by re-initialising the queue? Format, buffers or something else? If you need a larger buffer than what you have already allocated, you'll need to re-allocate, V4L2 or not. We also do lack a way to destroy individual buffers in V4L2. It'd be up to implementing that and some work in videobuf2. Another thing is that V4L2 is very stream oriented. For most devices that's fine as a lot of the parameters are not changeable during streaming, especially if the pipeline is handled by multiple drivers. That said, for devices that process data from memory to memory
[PATCH] [media] cx18: fix spelling mistake: "demodualtor" -> "demodulator"
From: Colin Ian King trivial fix to spelling mistake and add in a white space in a CX18_ERR error message Signed-off-by: Colin Ian King --- drivers/media/pci/cx18/cx18-dvb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/pci/cx18/cx18-dvb.c b/drivers/media/pci/cx18/cx18-dvb.c index d130d65828b0..53f4d6bf81fb 100644 --- a/drivers/media/pci/cx18/cx18-dvb.c +++ b/drivers/media/pci/cx18/cx18-dvb.c @@ -151,7 +151,7 @@ static int yuan_mpc718_mt352_reqfw(struct cx18_stream *stream, } if (ret) { - CX18_ERR("The MPC718 board variant with the MT352 DVB-Tdemodualtor will not work without it\n"); + CX18_ERR("The MPC718 board variant with the MT352 DVB-T demodulator will not work without it\n"); CX18_ERR("Run 'linux/Documentation/dvb/get_dvb_firmware mpc718' if you need the firmware\n"); } return ret; -- 2.11.0
Re: [PATCH] [media] s5p-jpeg: fix recursive spinlock acquisition
Hi Alexandre, Thanks for the patch. On 04/25/2017 08:19 AM, Alexandre Courbot wrote: > v4l2_m2m_job_finish(), which is called from the interrupt handler with > slock acquired, can call the device_run() hook immediately if another > context was in the queue. This hook also acquires slock, resulting in > a deadlock for this scenario. > > Fix this by releasing slock right before calling v4l2_m2m_job_finish(). > This is safe to do as the state of the hardware cannot change before > v4l2_m2m_job_finish() is called anyway. > > Signed-off-by: Alexandre Courbot > --- > drivers/media/platform/s5p-jpeg/jpeg-core.c | 12 +--- > 1 file changed, 9 insertions(+), 3 deletions(-) > > diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c > b/drivers/media/platform/s5p-jpeg/jpeg-core.c > index 52dc7941db65..223b4379929e 100644 > --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c > +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c > @@ -2642,13 +2642,13 @@ static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id) > if (curr_ctx->mode == S5P_JPEG_ENCODE) > vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload_size); > v4l2_m2m_buf_done(dst_buf, state); > - v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx); > > curr_ctx->subsampling = s5p_jpeg_get_subsampling_mode(jpeg->regs); > spin_unlock(&jpeg->slock); > > s5p_jpeg_clear_int(jpeg->regs); > > + v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx); > return IRQ_HANDLED; > } > > @@ -2707,11 +2707,12 @@ static irqreturn_t exynos4_jpeg_irq(int irq, void > *priv) > v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR); > } > > - v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx); > if (jpeg->variant->version == SJPEG_EXYNOS4) > curr_ctx->subsampling = exynos4_jpeg_get_frame_fmt(jpeg->regs); > > spin_unlock(&jpeg->slock); > + > + v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx); > return IRQ_HANDLED; > } > > @@ -2770,10 +2771,15 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void > *dev_id) > if (curr_ctx->mode == S5P_JPEG_ENCODE) > vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload_size); > v4l2_m2m_buf_done(dst_buf, state); > - v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx); > > curr_ctx->subsampling = > exynos3250_jpeg_get_subsampling_mode(jpeg->regs); > + > + spin_unlock(&jpeg->slock); > + > + v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx); > + return IRQ_HANDLED; > + > exit_unlock: > spin_unlock(&jpeg->slock); > return IRQ_HANDLED; > Acked-by: Jacek Anaszewski Just out of curiosity - could you share how you discovered the problem - by some static checkers or trying to use the driver? -- Best regards, Jacek Anaszewski
[PATCH v2 16/21] mmc: sdhci: Make use of the new sg_map helper function
Straightforward conversion, except due to the lack of an error path we have to use SG_MAP_MUST_NOT_FAIL which may BUG_ON in certain cases in the future. Signed-off-by: Logan Gunthorpe Cc: Adrian Hunter Cc: Ulf Hansson --- drivers/mmc/host/sdhci.c | 14 +- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index ecd0d43..239507f 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -513,15 +513,19 @@ static int sdhci_pre_dma_transfer(struct sdhci_host *host, return sg_count; } +/* + * Note this function may return PTR_ERR and must be checked. + */ static char *sdhci_kmap_atomic(struct scatterlist *sg, unsigned long *flags) { local_irq_save(*flags); - return kmap_atomic(sg_page(sg)) + sg->offset; + return sg_map(sg, 0, SG_KMAP_ATOMIC | SG_MAP_MUST_NOT_FAIL); } -static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags) +static void sdhci_kunmap_atomic(struct scatterlist *sg, void *buffer, + unsigned long *flags) { - kunmap_atomic(buffer); + sg_unmap(sg, buffer, 0, SG_KMAP_ATOMIC); local_irq_restore(*flags); } @@ -585,7 +589,7 @@ static void sdhci_adma_table_pre(struct sdhci_host *host, if (data->flags & MMC_DATA_WRITE) { buffer = sdhci_kmap_atomic(sg, &flags); memcpy(align, buffer, offset); - sdhci_kunmap_atomic(buffer, &flags); + sdhci_kunmap_atomic(sg, buffer, &flags); } /* tran, valid */ @@ -663,7 +667,7 @@ static void sdhci_adma_table_post(struct sdhci_host *host, buffer = sdhci_kmap_atomic(sg, &flags); memcpy(buffer, align, size); - sdhci_kunmap_atomic(buffer, &flags); + sdhci_kunmap_atomic(sg, buffer, &flags); align += SDHCI_ADMA2_ALIGN; } -- 2.1.4
[PATCH v2 18/21] mmc: tmio: Make use of the new sg_map helper function
Straightforward conversion to sg_map helper. Seeing there is no cleare error path, SG_MAP_MUST_NOT_FAIL which may BUG_ON in certain cases in the future. Signed-off-by: Logan Gunthorpe Cc: Wolfram Sang Cc: Ulf Hansson --- drivers/mmc/host/tmio_mmc.h | 7 +-- drivers/mmc/host/tmio_mmc_pio.c | 12 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index d0edb57..bc43eb0 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h @@ -202,17 +202,20 @@ void tmio_mmc_enable_mmc_irqs(struct tmio_mmc_host *host, u32 i); void tmio_mmc_disable_mmc_irqs(struct tmio_mmc_host *host, u32 i); irqreturn_t tmio_mmc_irq(int irq, void *devid); +/* Note: this function may return PTR_ERR and must be checked! */ static inline char *tmio_mmc_kmap_atomic(struct scatterlist *sg, unsigned long *flags) { + void *ret; + local_irq_save(*flags); - return kmap_atomic(sg_page(sg)) + sg->offset; + return sg_map(sg, 0, SG_KMAP_ATOMIC | SG_MAP_MUST_NOT_FAIL); } static inline void tmio_mmc_kunmap_atomic(struct scatterlist *sg, unsigned long *flags, void *virt) { - kunmap_atomic(virt - sg->offset); + sg_unmap(sg, virt, 0, SG_KMAP_ATOMIC); local_irq_restore(*flags); } diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index a2d92f1..bbb4f19 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c @@ -506,6 +506,18 @@ static void tmio_mmc_check_bounce_buffer(struct tmio_mmc_host *host) if (host->sg_ptr == &host->bounce_sg) { unsigned long flags; void *sg_vaddr = tmio_mmc_kmap_atomic(host->sg_orig, &flags); + if (IS_ERR(sg_vaddr)) { + /* +* This should really never happen unless +* the code is changed to use memory that is +* not mappable in the sg. Seeing there doesn't +* seem to be any error path out of here, +* we can only WARN. +*/ + WARN(1, "Non-mappable memory used in sg!"); + return; + } + memcpy(sg_vaddr, host->bounce_buf, host->bounce_sg.length); tmio_mmc_kunmap_atomic(host->sg_orig, &flags, sg_vaddr); } -- 2.1.4
[PATCH v2 04/21] target: Make use of the new sg_map function at 16 call sites
Fairly straightforward conversions in all spots. In a couple of cases any error gets propogated up should sg_map fail. In other cases a warning is issued if the kmap fails seeing there's no clear error path. This should not be an issue until someone tries to use unmappable memory in the sgl with this driver. Signed-off-by: Logan Gunthorpe Cc: "Nicholas A. Bellinger" --- drivers/target/iscsi/iscsi_target.c| 29 +++--- drivers/target/target_core_rd.c| 3 +- drivers/target/target_core_sbc.c | 103 + drivers/target/target_core_transport.c | 18 -- drivers/target/target_core_user.c | 45 +- include/target/target_core_backend.h | 4 +- 6 files changed, 134 insertions(+), 68 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index e3f9ed3..3ab8d21 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -578,7 +578,7 @@ iscsit_xmit_nondatain_pdu(struct iscsi_conn *conn, struct iscsi_cmd *cmd, } static int iscsit_map_iovec(struct iscsi_cmd *, struct kvec *, u32, u32); -static void iscsit_unmap_iovec(struct iscsi_cmd *); +static void iscsit_unmap_iovec(struct iscsi_cmd *, struct kvec *); static u32 iscsit_do_crypto_hash_sg(struct ahash_request *, struct iscsi_cmd *, u32, u32, u32, u8 *); static int @@ -645,7 +645,7 @@ iscsit_xmit_datain_pdu(struct iscsi_conn *conn, struct iscsi_cmd *cmd, ret = iscsit_fe_sendpage_sg(cmd, conn); - iscsit_unmap_iovec(cmd); + iscsit_unmap_iovec(cmd, &cmd->iov_data[1]); if (ret < 0) { iscsit_tx_thread_wait_for_tcp(conn); @@ -924,7 +924,10 @@ static int iscsit_map_iovec( while (data_length) { u32 cur_len = min_t(u32, data_length, sg->length - page_off); - iov[i].iov_base = kmap(sg_page(sg)) + sg->offset + page_off; + iov[i].iov_base = sg_map(sg, page_off, SG_KMAP); + if (IS_ERR(iov[i].iov_base)) + goto map_err; + iov[i].iov_len = cur_len; data_length -= cur_len; @@ -936,17 +939,25 @@ static int iscsit_map_iovec( cmd->kmapped_nents = i; return i; + +map_err: + cmd->kmapped_nents = i - 1; + iscsit_unmap_iovec(cmd, iov); + return -1; } -static void iscsit_unmap_iovec(struct iscsi_cmd *cmd) +static void iscsit_unmap_iovec(struct iscsi_cmd *cmd, struct kvec *iov) { u32 i; struct scatterlist *sg; + unsigned int page_off = cmd->first_data_sg_off; sg = cmd->first_data_sg; - for (i = 0; i < cmd->kmapped_nents; i++) - kunmap(sg_page(&sg[i])); + for (i = 0; i < cmd->kmapped_nents; i++) { + sg_unmap(&sg[i], iov[i].iov_base, page_off, SG_KMAP); + page_off = 0; + } } static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn) @@ -1609,7 +1620,7 @@ iscsit_get_dataout(struct iscsi_conn *conn, struct iscsi_cmd *cmd, rx_got = rx_data(conn, &cmd->iov_data[0], iov_count, rx_size); - iscsit_unmap_iovec(cmd); + iscsit_unmap_iovec(cmd, iov); if (rx_got != rx_size) return -1; @@ -1710,7 +1721,7 @@ int iscsit_setup_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, if (!cmd) return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, (unsigned char *)hdr); - + return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, (unsigned char *)hdr); } @@ -2625,7 +2636,7 @@ static int iscsit_handle_immediate_data( rx_got = rx_data(conn, &cmd->iov_data[0], iov_count, rx_size); - iscsit_unmap_iovec(cmd); + iscsit_unmap_iovec(cmd, cmd->iov_data); if (rx_got != rx_size) { iscsit_rx_thread_wait_for_tcp(conn); diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index 5f23f34..348211c 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c @@ -432,7 +432,8 @@ static sense_reason_t rd_do_prot_rw(struct se_cmd *cmd, bool is_read) cmd->t_prot_sg, 0); } if (!rc) - sbc_dif_copy_prot(cmd, sectors, is_read, prot_sg, prot_offset); + rc = sbc_dif_copy_prot(cmd, sectors, is_read, prot_sg, + prot_offset); return rc; } diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index ee35c90..8ac07c6 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c @@ -420,17 +420,17 @@ static sense_reason_t xdreadwrite_callback(struct se_cmd *cmd, bool success, offset = 0; for_each_
[PATCH v2 03/21] libiscsi: Make use of new the sg_map helper function
Convert the kmap and kmap_atomic uses to the sg_map function. We now store the flags for the kmap instead of a boolean to indicate atomicitiy. We use ISCSI_TCP_INTERNAL_ERR error type that was prepared earlier for this. Signed-off-by: Logan Gunthorpe Cc: Lee Duncan Cc: Chris Leech --- drivers/scsi/libiscsi_tcp.c | 32 include/scsi/libiscsi_tcp.h | 2 +- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index 63a1d69..a34e25c 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c @@ -133,25 +133,23 @@ static void iscsi_tcp_segment_map(struct iscsi_segment *segment, int recv) if (page_count(sg_page(sg)) >= 1 && !recv) return; - if (recv) { - segment->atomic_mapped = true; - segment->sg_mapped = kmap_atomic(sg_page(sg)); - } else { - segment->atomic_mapped = false; - /* the xmit path can sleep with the page mapped so use kmap */ - segment->sg_mapped = kmap(sg_page(sg)); + /* the xmit path can sleep with the page mapped so don't use atomic */ + segment->sg_map_flags = recv ? SG_KMAP_ATOMIC : SG_KMAP; + segment->sg_mapped = sg_map(sg, 0, segment->sg_map_flags); + + if (IS_ERR(segment->sg_mapped)) { + segment->sg_mapped = NULL; + return; } - segment->data = segment->sg_mapped + sg->offset + segment->sg_offset; + segment->data = segment->sg_mapped + segment->sg_offset; } void iscsi_tcp_segment_unmap(struct iscsi_segment *segment) { if (segment->sg_mapped) { - if (segment->atomic_mapped) - kunmap_atomic(segment->sg_mapped); - else - kunmap(sg_page(segment->sg)); + sg_unmap(segment->sg, segment->sg_mapped, 0, +segment->sg_map_flags); segment->sg_mapped = NULL; segment->data = NULL; } @@ -304,6 +302,9 @@ iscsi_tcp_segment_recv(struct iscsi_tcp_conn *tcp_conn, break; } + if (segment->data) + return -EFAULT; + copy = min(len - copied, segment->size - segment->copied); ISCSI_DBG_TCP(tcp_conn->iscsi_conn, "copying %d\n", copy); memcpy(segment->data + segment->copied, ptr + copied, copy); @@ -927,6 +928,13 @@ int iscsi_tcp_recv_skb(struct iscsi_conn *conn, struct sk_buff *skb, avail); rc = iscsi_tcp_segment_recv(tcp_conn, segment, ptr, avail); BUG_ON(rc == 0); + if (rc < 0) { + ISCSI_DBG_TCP(conn, "memory fault. Consumed %d\n", + consumed); + *status = ISCSI_TCP_INTERNAL_ERR; + goto skb_done; + } + consumed += rc; if (segment->total_copied >= segment->total_size) { diff --git a/include/scsi/libiscsi_tcp.h b/include/scsi/libiscsi_tcp.h index 90691ad..58c79af 100644 --- a/include/scsi/libiscsi_tcp.h +++ b/include/scsi/libiscsi_tcp.h @@ -47,7 +47,7 @@ struct iscsi_segment { struct scatterlist *sg; void*sg_mapped; unsigned intsg_offset; - boolatomic_mapped; + int sg_map_flags; iscsi_segment_done_fn_t *done; }; -- 2.1.4
[PATCH v2 07/21] crypto: shash, caam: Make use of the new sg_map helper function
Very straightforward conversion to the new function in the caam driver and shash library. Signed-off-by: Logan Gunthorpe Cc: Herbert Xu Cc: "David S. Miller" --- crypto/shash.c| 9 ++--- drivers/crypto/caam/caamalg.c | 8 +++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/crypto/shash.c b/crypto/shash.c index 5e31c8d..5914881 100644 --- a/crypto/shash.c +++ b/crypto/shash.c @@ -283,10 +283,13 @@ int shash_ahash_digest(struct ahash_request *req, struct shash_desc *desc) if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) { void *data; - data = kmap_atomic(sg_page(sg)); - err = crypto_shash_digest(desc, data + offset, nbytes, + data = sg_map(sg, 0, SG_KMAP_ATOMIC); + if (IS_ERR(data)) + return PTR_ERR(data); + + err = crypto_shash_digest(desc, data, nbytes, req->result); - kunmap_atomic(data); + sg_unmap(sg, data, 0, SG_KMAP_ATOMIC); crypto_yield(desc->flags); } else err = crypto_shash_init(desc) ?: diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index 398807d..62d2f5d 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -89,7 +89,6 @@ static void dbg_dump_sg(const char *level, const char *prefix_str, struct scatterlist *sg, size_t tlen, bool ascii) { struct scatterlist *it; - void *it_page; size_t len; void *buf; @@ -98,19 +97,18 @@ static void dbg_dump_sg(const char *level, const char *prefix_str, * make sure the scatterlist's page * has a valid virtual memory mapping */ - it_page = kmap_atomic(sg_page(it)); - if (unlikely(!it_page)) { + buf = sg_map(it, 0, SG_KMAP_ATOMIC); + if (IS_ERR(buf)) { printk(KERN_ERR "dbg_dump_sg: kmap failed\n"); return; } - buf = it_page + it->offset; len = min_t(size_t, tlen, it->length); print_hex_dump(level, prefix_str, prefix_type, rowsize, groupsize, buf, len, ascii); tlen -= len; - kunmap_atomic(it_page); + sg_unmap(it, buf, 0, SG_KMAP_ATOMIC); } } #endif -- 2.1.4
[PATCH v2 14/21] scsi: libfc, csiostor: Change to sg_copy_buffer in two drivers
These two drivers appear to duplicate the functionality of sg_copy_buffer. So we clean them up to use the common code. This helps us remove a couple of instances that would otherwise be slightly tricky sg_map usages. Signed-off-by: Logan Gunthorpe Cc: Johannes Thumshirn --- drivers/scsi/csiostor/csio_scsi.c | 54 +++ drivers/scsi/libfc/fc_libfc.c | 49 --- 2 files changed, 14 insertions(+), 89 deletions(-) diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c index a1ff75f..bd9d062 100644 --- a/drivers/scsi/csiostor/csio_scsi.c +++ b/drivers/scsi/csiostor/csio_scsi.c @@ -1489,60 +1489,14 @@ static inline uint32_t csio_scsi_copy_to_sgl(struct csio_hw *hw, struct csio_ioreq *req) { struct scsi_cmnd *scmnd = (struct scsi_cmnd *)csio_scsi_cmnd(req); - struct scatterlist *sg; - uint32_t bytes_left; - uint32_t bytes_copy; - uint32_t buf_off = 0; - uint32_t start_off = 0; - uint32_t sg_off = 0; - void *sg_addr; - void *buf_addr; struct csio_dma_buf *dma_buf; + size_t copied; - bytes_left = scsi_bufflen(scmnd); - sg = scsi_sglist(scmnd); dma_buf = (struct csio_dma_buf *)csio_list_next(&req->gen_list); + copied = sg_copy_from_buffer(scsi_sglist(scmnd), scsi_sg_count(scmnd), +dma_buf->vaddr, scsi_bufflen(scmnd)); - /* Copy data from driver buffer to SGs of SCSI CMD */ - while (bytes_left > 0 && sg && dma_buf) { - if (buf_off >= dma_buf->len) { - buf_off = 0; - dma_buf = (struct csio_dma_buf *) - csio_list_next(dma_buf); - continue; - } - - if (start_off >= sg->length) { - start_off -= sg->length; - sg = sg_next(sg); - continue; - } - - buf_addr = dma_buf->vaddr + buf_off; - sg_off = sg->offset + start_off; - bytes_copy = min((dma_buf->len - buf_off), - sg->length - start_off); - bytes_copy = min((uint32_t)(PAGE_SIZE - (sg_off & ~PAGE_MASK)), -bytes_copy); - - sg_addr = kmap_atomic(sg_page(sg) + (sg_off >> PAGE_SHIFT)); - if (!sg_addr) { - csio_err(hw, "failed to kmap sg:%p of ioreq:%p\n", - sg, req); - break; - } - - csio_dbg(hw, "copy_to_sgl:sg_addr %p sg_off %d buf %p len %d\n", - sg_addr, sg_off, buf_addr, bytes_copy); - memcpy(sg_addr + (sg_off & ~PAGE_MASK), buf_addr, bytes_copy); - kunmap_atomic(sg_addr); - - start_off += bytes_copy; - buf_off += bytes_copy; - bytes_left -= bytes_copy; - } - - if (bytes_left > 0) + if (copied != scsi_bufflen(scmnd)) return DID_ERROR; else return DID_OK; diff --git a/drivers/scsi/libfc/fc_libfc.c b/drivers/scsi/libfc/fc_libfc.c index d623d08..ce0805a 100644 --- a/drivers/scsi/libfc/fc_libfc.c +++ b/drivers/scsi/libfc/fc_libfc.c @@ -113,45 +113,16 @@ u32 fc_copy_buffer_to_sglist(void *buf, size_t len, u32 *nents, size_t *offset, u32 *crc) { - size_t remaining = len; - u32 copy_len = 0; - - while (remaining > 0 && sg) { - size_t off, sg_bytes; - void *page_addr; - - if (*offset >= sg->length) { - /* -* Check for end and drop resources -* from the last iteration. -*/ - if (!(*nents)) - break; - --(*nents); - *offset -= sg->length; - sg = sg_next(sg); - continue; - } - sg_bytes = min(remaining, sg->length - *offset); - - /* -* The scatterlist item may be bigger than PAGE_SIZE, -* but we are limited to mapping PAGE_SIZE at a time. -*/ - off = *offset + sg->offset; - sg_bytes = min(sg_bytes, - (size_t)(PAGE_SIZE - (off & ~PAGE_MASK))); - page_addr = kmap_atomic(sg_page(sg) + (off >> PAGE_SHIFT)); - if (crc) - *crc = crc32(*crc, buf, sg_bytes); - memcpy((char *)page_addr + (off & ~PAGE_MASK), buf, sg_bytes); - kunmap_atomic(page_addr); - buf += sg_bytes; - *offset += sg_bytes; - remaining -= sg_bytes;
[PATCH v2 00/21] Introduce common scatterlist map function
Changes since v1: * Rebased onto next-20170424 * Removed the _offset version of these functions per Christoph's suggestion * Added an SG_MAP_MUST_NOT_FAIL flag which will BUG_ON in future cases that can't gracefully fail. This removes a bunch of the noise added in v1 to a couple of the drivers. (Per David Laight's suggestion) This flag is only meant for old code * Split the libiscsi patch into two (per Christoph's suggestion) the prep patch (patch 2 in this series) has already been sent separately * Fixed a locking mistake in the target patch (pointed out by a bot) * Dropped the nvmet patch and handled it with a different patch that has been sent separately * Dropped the chcr patch as they have already removed the code that needed to be changed I'm still hoping to only get Patch 1 in the series merged. (Any volunteers?) I'm willing to chase down the maintainers for the remaining patches separately after the first patch is in. The patchset is based on next-20170424 and can be found in the sg_map_v2 branch from this git tree: https://github.com/sbates130272/linux-p2pmem.git -- Hi Everyone, As part of my effort to enable P2P DMA transactions with PCI cards, we've identified the need to be able to safely put IO memory into scatterlists (and eventually other spots). This probably involves a conversion from struct page to pfn_t but that migration is a ways off and those decisions are yet to be made. As an initial step in that direction, I've started cleaning up some of the scatterlist code by trying to carve out a better defined layer between it and it's users. The longer term goal would be to remove sg_page or replace it with something that can potentially fail. This patchset is the first step in that effort. I've introduced a common function to map scatterlist memory and converted all the common kmap(sg_page()) cases. This removes about 66 sg_page calls (of ~331). Seeing this is a fairly large cleanup set that touches a wide swath of the kernel I have limited the people I've sent this to. I'd suggest we look toward merging the first patch and then I can send the individual subsystem patches on to their respective maintainers and get them merged independantly. (This is to avoid the conflicts I created with my last cleanup set... Sorry) Though, I'm certainly open to other suggestions to get it merged. Logan Gunthorpe (21): scatterlist: Introduce sg_map helper functions libiscsi: Add an internal error code libiscsi: Make use of new the sg_map helper function target: Make use of the new sg_map function at 16 call sites drm/i915: Make use of the new sg_map helper function crypto: hifn_795x: Make use of the new sg_map helper function crypto: shash, caam: Make use of the new sg_map helper function dm-crypt: Make use of the new sg_map helper in 4 call sites staging: unisys: visorbus: Make use of the new sg_map helper function RDS: Make use of the new sg_map helper function scsi: ipr, pmcraid, isci: Make use of the new sg_map helper scsi: hisi_sas, mvsas, gdth: Make use of the new sg_map helper function scsi: arcmsr, ips, megaraid: Make use of the new sg_map helper function scsi: libfc, csiostor: Change to sg_copy_buffer in two drivers xen-blkfront: Make use of the new sg_map helper function mmc: sdhci: Make use of the new sg_map helper function mmc: spi: Make use of the new sg_map helper function mmc: tmio: Make use of the new sg_map helper function mmc: sdricoh_cs: Make use of the new sg_map helper function mmc: tifm_sd: Make use of the new sg_map helper function memstick: Make use of the new sg_map helper function crypto/shash.c | 9 ++- drivers/block/xen-blkfront.c| 20 ++--- drivers/crypto/caam/caamalg.c | 8 +- drivers/crypto/hifn_795x.c | 32 +--- drivers/gpu/drm/i915/i915_gem.c | 27 --- drivers/md/dm-crypt.c | 39 ++--- drivers/memstick/host/jmb38x_ms.c | 11 +-- drivers/memstick/host/tifm_ms.c | 11 +-- drivers/mmc/host/mmc_spi.c | 26 -- drivers/mmc/host/sdhci.c| 14 ++-- drivers/mmc/host/sdricoh_cs.c | 14 ++-- drivers/mmc/host/tifm_sd.c | 50 +++- drivers/mmc/host/tmio_mmc.h | 7 +- drivers/mmc/host/tmio_mmc_pio.c | 12 +++ drivers/scsi/arcmsr/arcmsr_hba.c| 16 +++- drivers/scsi/csiostor/csio_scsi.c | 54 + drivers/scsi/cxgbi/libcxgbi.c | 5 ++ drivers/scsi/gdth.c | 9 ++- drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 14 ++-- drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 13 ++- drivers/scsi/ipr.c | 27 --- drivers/scsi/ips.c | 8 +- drivers/s
[PATCH v2 21/21] memstick: Make use of the new sg_map helper function
Straightforward conversion, but we have to make use of SG_MAP_MUST_NOT_FAIL which may BUG_ON in certain cases in the future. Signed-off-by: Logan Gunthorpe Cc: Alex Dubov --- drivers/memstick/host/jmb38x_ms.c | 11 ++- drivers/memstick/host/tifm_ms.c | 11 ++- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c index 48db922..9019e37 100644 --- a/drivers/memstick/host/jmb38x_ms.c +++ b/drivers/memstick/host/jmb38x_ms.c @@ -303,7 +303,6 @@ static int jmb38x_ms_transfer_data(struct jmb38x_ms_host *host) unsigned int off; unsigned int t_size, p_cnt; unsigned char *buf; - struct page *pg; unsigned long flags = 0; if (host->req->long_data) { @@ -318,14 +317,14 @@ static int jmb38x_ms_transfer_data(struct jmb38x_ms_host *host) unsigned int uninitialized_var(p_off); if (host->req->long_data) { - pg = nth_page(sg_page(&host->req->sg), - off >> PAGE_SHIFT); p_off = offset_in_page(off); p_cnt = PAGE_SIZE - p_off; p_cnt = min(p_cnt, length); local_irq_save(flags); - buf = kmap_atomic(pg) + p_off; + buf = sg_map(&host->req->sg, +off - host->req->sg.offset, +SG_KMAP_ATOMIC | SG_MAP_MUST_NOT_FAIL); } else { buf = host->req->data + host->block_pos; p_cnt = host->req->data_len - host->block_pos; @@ -341,7 +340,9 @@ static int jmb38x_ms_transfer_data(struct jmb38x_ms_host *host) : jmb38x_ms_read_reg_data(host, buf, p_cnt); if (host->req->long_data) { - kunmap_atomic(buf - p_off); + sg_unmap(&host->req->sg, buf, +off - host->req->sg.offset, +SG_KMAP_ATOMIC); local_irq_restore(flags); } diff --git a/drivers/memstick/host/tifm_ms.c b/drivers/memstick/host/tifm_ms.c index 7bafa72..304985d 100644 --- a/drivers/memstick/host/tifm_ms.c +++ b/drivers/memstick/host/tifm_ms.c @@ -186,7 +186,6 @@ static unsigned int tifm_ms_transfer_data(struct tifm_ms *host) unsigned int off; unsigned int t_size, p_cnt; unsigned char *buf; - struct page *pg; unsigned long flags = 0; if (host->req->long_data) { @@ -203,14 +202,14 @@ static unsigned int tifm_ms_transfer_data(struct tifm_ms *host) unsigned int uninitialized_var(p_off); if (host->req->long_data) { - pg = nth_page(sg_page(&host->req->sg), - off >> PAGE_SHIFT); p_off = offset_in_page(off); p_cnt = PAGE_SIZE - p_off; p_cnt = min(p_cnt, length); local_irq_save(flags); - buf = kmap_atomic(pg) + p_off; + buf = sg_map(&host->req->sg, +off - host->req->sg.offset, +SG_KMAP_ATOMIC | SG_MAP_MUST_NOT_FAIL); } else { buf = host->req->data + host->block_pos; p_cnt = host->req->data_len - host->block_pos; @@ -221,7 +220,9 @@ static unsigned int tifm_ms_transfer_data(struct tifm_ms *host) : tifm_ms_read_data(host, buf, p_cnt); if (host->req->long_data) { - kunmap_atomic(buf - p_off); + sg_unmap(&host->req->sg, buf, +off - host->req->sg.offset, +SG_KMAP_ATOMIC | SG_MAP_MUST_NOT_FAIL); local_irq_restore(flags); } -- 2.1.4
[PATCH v2 17/21] mmc: spi: Make use of the new sg_map helper function
We use the sg_map helper but it's slightly more complicated as we only check for the error when the mapping actually gets used. Such that if the mapping failed but wasn't needed then no error occurs. Signed-off-by: Logan Gunthorpe Cc: Ulf Hansson --- drivers/mmc/host/mmc_spi.c | 26 +++--- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 476e53d..d614f36 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -676,9 +676,15 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t, struct scratch *scratch = host->data; u32 pattern; - if (host->mmc->use_spi_crc) + if (host->mmc->use_spi_crc) { + if (IS_ERR(t->tx_buf)) + return PTR_ERR(t->tx_buf); + scratch->crc_val = cpu_to_be16( crc_itu_t(0, t->tx_buf, t->len)); + t->tx_buf += t->len; + } + if (host->dma_dev) dma_sync_single_for_device(host->dma_dev, host->data_dma, sizeof(*scratch), @@ -743,7 +749,6 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t, return status; } - t->tx_buf += t->len; if (host->dma_dev) t->tx_dma += t->len; @@ -809,6 +814,11 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t, } leftover = status << 1; + if (bitshift || host->mmc->use_spi_crc) { + if (IS_ERR(t->rx_buf)) + return PTR_ERR(t->rx_buf); + } + if (host->dma_dev) { dma_sync_single_for_device(host->dma_dev, host->data_dma, sizeof(*scratch), @@ -860,9 +870,10 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t, scratch->crc_val, crc, t->len); return -EILSEQ; } + + t->rx_buf += t->len; } - t->rx_buf += t->len; if (host->dma_dev) t->rx_dma += t->len; @@ -933,11 +944,11 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd, } /* allow pio too; we don't allow highmem */ - kmap_addr = kmap(sg_page(sg)); + kmap_addr = sg_map(sg, 0, SG_KMAP); if (direction == DMA_TO_DEVICE) - t->tx_buf = kmap_addr + sg->offset; + t->tx_buf = kmap_addr; else - t->rx_buf = kmap_addr + sg->offset; + t->rx_buf = kmap_addr; /* transfer each block, and update request status */ while (length) { @@ -967,7 +978,8 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd, /* discard mappings */ if (direction == DMA_FROM_DEVICE) flush_kernel_dcache_page(sg_page(sg)); - kunmap(sg_page(sg)); + if (!IS_ERR(kmap_addr)) + sg_unmap(sg, kmap_addr, 0, SG_KMAP); if (dma_dev) dma_unmap_page(dma_dev, dma_addr, PAGE_SIZE, dir); -- 2.1.4
[PATCH v2 09/21] staging: unisys: visorbus: Make use of the new sg_map helper function
Straightforward conversion to the new function. Signed-off-by: Logan Gunthorpe Acked-by: David Kershner --- drivers/staging/unisys/visorhba/visorhba_main.c | 12 +++- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c index d372115..c77426c 100644 --- a/drivers/staging/unisys/visorhba/visorhba_main.c +++ b/drivers/staging/unisys/visorhba/visorhba_main.c @@ -843,7 +843,6 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) struct scatterlist *sg; unsigned int i; char *this_page; - char *this_page_orig; int bufind = 0; struct visordisk_info *vdisk; struct visorhba_devdata *devdata; @@ -870,11 +869,14 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) sg = scsi_sglist(scsicmd); for (i = 0; i < scsi_sg_count(scsicmd); i++) { - this_page_orig = kmap_atomic(sg_page(sg + i)); - this_page = (void *)((unsigned long)this_page_orig | -sg[i].offset); + this_page = sg_map(sg + i, 0, SG_KMAP_ATOMIC); + if (IS_ERR(this_page)) { + scsicmd->result = DID_ERROR << 16; + return; + } + memcpy(this_page, buf + bufind, sg[i].length); - kunmap_atomic(this_page_orig); + sg_unmap(sg + i, this_page, 0, SG_KMAP_ATOMIC); } } else { devdata = (struct visorhba_devdata *)scsidev->host->hostdata; -- 2.1.4
[PATCH v2 06/21] crypto: hifn_795x: Make use of the new sg_map helper function
Conversion of a couple kmap_atomic instances to the sg_map helper function. However, it looks like there was a bug in the original code: the source scatter lists offset (t->offset) was passed to ablkcipher_get which added it to the destination address. This doesn't make a lot of sense, but t->offset is likely always zero anyway. So, this patch cleans that brokeness up. Also, a change to the error path: if ablkcipher_get failed, everything seemed to proceed as if it hadn't. Setting 'error' should hopefully clear that up. Signed-off-by: Logan Gunthorpe Cc: Herbert Xu Cc: "David S. Miller" --- drivers/crypto/hifn_795x.c | 32 +--- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index e09d405..34b1870 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -1619,7 +1619,7 @@ static int hifn_start_device(struct hifn_device *dev) return 0; } -static int ablkcipher_get(void *saddr, unsigned int *srestp, unsigned int offset, +static int ablkcipher_get(void *saddr, unsigned int *srestp, struct scatterlist *dst, unsigned int size, unsigned int *nbytesp) { unsigned int srest = *srestp, nbytes = *nbytesp, copy; @@ -1632,15 +1632,17 @@ static int ablkcipher_get(void *saddr, unsigned int *srestp, unsigned int offset while (size) { copy = min3(srest, dst->length, size); - daddr = kmap_atomic(sg_page(dst)); - memcpy(daddr + dst->offset + offset, saddr, copy); - kunmap_atomic(daddr); + daddr = sg_map(dst, 0, SG_KMAP_ATOMIC); + if (IS_ERR(daddr)) + return PTR_ERR(daddr); + + memcpy(daddr, saddr, copy); + sg_unmap(dst, daddr, 0, SG_KMAP_ATOMIC); nbytes -= copy; size -= copy; srest -= copy; saddr += copy; - offset = 0; pr_debug("%s: copy: %u, size: %u, srest: %u, nbytes: %u.\n", __func__, copy, size, srest, nbytes); @@ -1671,11 +1673,12 @@ static inline void hifn_complete_sa(struct hifn_device *dev, int i) static void hifn_process_ready(struct ablkcipher_request *req, int error) { + int err; struct hifn_request_context *rctx = ablkcipher_request_ctx(req); if (rctx->walk.flags & ASYNC_FLAGS_MISALIGNED) { unsigned int nbytes = req->nbytes; - int idx = 0, err; + int idx = 0; struct scatterlist *dst, *t; void *saddr; @@ -1695,17 +1698,24 @@ static void hifn_process_ready(struct ablkcipher_request *req, int error) continue; } - saddr = kmap_atomic(sg_page(t)); + saddr = sg_map(t, 0, SG_KMAP_ATOMIC); + if (IS_ERR(saddr)) { + if (!error) + error = PTR_ERR(saddr); + break; + } + + err = ablkcipher_get(saddr, &t->length, +dst, nbytes, &nbytes); + sg_unmap(t, saddr, 0, SG_KMAP_ATOMIC); - err = ablkcipher_get(saddr, &t->length, t->offset, - dst, nbytes, &nbytes); if (err < 0) { - kunmap_atomic(saddr); + if (!error) + error = err; break; } idx += err; - kunmap_atomic(saddr); } hifn_cipher_walk_exit(&rctx->walk); -- 2.1.4
[PATCH v2 11/21] scsi: ipr, pmcraid, isci: Make use of the new sg_map helper
Very straightforward conversion of three scsi drivers. Signed-off-by: Logan Gunthorpe Cc: Brian King Cc: Artur Paszkiewicz --- drivers/scsi/ipr.c | 27 ++- drivers/scsi/isci/request.c | 42 +- drivers/scsi/pmcraid.c | 19 --- 3 files changed, 51 insertions(+), 37 deletions(-) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index b0c68d2..b2324e1 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -3895,7 +3895,7 @@ static void ipr_free_ucode_buffer(struct ipr_sglist *sglist) static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist, u8 *buffer, u32 len) { - int bsize_elem, i, result = 0; + int bsize_elem, i; struct scatterlist *scatterlist; void *kaddr; @@ -3905,32 +3905,33 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist, scatterlist = sglist->scatterlist; for (i = 0; i < (len / bsize_elem); i++, buffer += bsize_elem) { - struct page *page = sg_page(&scatterlist[i]); + kaddr = sg_map(&scatterlist[i], 0, SG_KMAP); + if (IS_ERR(kaddr)) { + ipr_trace; + return PTR_ERR(kaddr); + } - kaddr = kmap(page); memcpy(kaddr, buffer, bsize_elem); - kunmap(page); + sg_unmap(&scatterlist[i], kaddr, 0, SG_KMAP); scatterlist[i].length = bsize_elem; - - if (result != 0) { - ipr_trace; - return result; - } } if (len % bsize_elem) { - struct page *page = sg_page(&scatterlist[i]); + kaddr = sg_map(&scatterlist[i], 0, SG_KMAP); + if (IS_ERR(kaddr)) { + ipr_trace; + return PTR_ERR(kaddr); + } - kaddr = kmap(page); memcpy(kaddr, buffer, len % bsize_elem); - kunmap(page); + sg_unmap(&scatterlist[i], kaddr, 0, SG_KMAP); scatterlist[i].length = len % bsize_elem; } sglist->buffer_len = len; - return result; + return 0; } /** diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index 47f66e9..6f5521b 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c @@ -1424,12 +1424,14 @@ sci_stp_request_pio_data_in_copy_data_buffer(struct isci_stp_request *stp_req, sg = task->scatter; while (total_len > 0) { - struct page *page = sg_page(sg); - copy_len = min_t(int, total_len, sg_dma_len(sg)); - kaddr = kmap_atomic(page); - memcpy(kaddr + sg->offset, src_addr, copy_len); - kunmap_atomic(kaddr); + kaddr = sg_map(sg, 0, SG_KMAP_ATOMIC); + if (IS_ERR(kaddr)) + return SCI_FAILURE; + + memcpy(kaddr, src_addr, copy_len); + sg_unmap(sg, kaddr, 0, SG_KMAP_ATOMIC); + total_len -= copy_len; src_addr += copy_len; sg = sg_next(sg); @@ -1771,14 +1773,16 @@ sci_io_request_frame_handler(struct isci_request *ireq, case SCI_REQ_SMP_WAIT_RESP: { struct sas_task *task = isci_request_access_task(ireq); struct scatterlist *sg = &task->smp_task.smp_resp; - void *frame_header, *kaddr; + void *frame_header; u8 *rsp; sci_unsolicited_frame_control_get_header(&ihost->uf_control, frame_index, &frame_header); - kaddr = kmap_atomic(sg_page(sg)); - rsp = kaddr + sg->offset; + rsp = sg_map(sg, 0, SG_KMAP_ATOMIC); + if (IS_ERR(rsp)) + return SCI_FAILURE; + sci_swab32_cpy(rsp, frame_header, 1); if (rsp[0] == SMP_RESPONSE) { @@ -1814,7 +1818,7 @@ sci_io_request_frame_handler(struct isci_request *ireq, ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR; sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); } - kunmap_atomic(kaddr); + sg_unmap(sg, rsp, 0, SG_KMAP_ATOMIC); sci_controller_release_frame(ihost, frame_index); @@ -2919,15 +2923,18 @@ static void isci_request_io_request_complete(struct isci_host *ihost, case SAS_PROTOCOL_SMP: { struct scatterlist *sg = &task->smp_task.smp_req; struct smp_req *smp_req; - void *kaddr; dma
[PATCH v2 19/21] mmc: sdricoh_cs: Make use of the new sg_map helper function
This is a straightforward conversion to the new function. Signed-off-by: Logan Gunthorpe Cc: Sascha Sommer Cc: Ulf Hansson --- drivers/mmc/host/sdricoh_cs.c | 14 +- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/host/sdricoh_cs.c b/drivers/mmc/host/sdricoh_cs.c index 5ff26ab..03225c3 100644 --- a/drivers/mmc/host/sdricoh_cs.c +++ b/drivers/mmc/host/sdricoh_cs.c @@ -319,16 +319,20 @@ static void sdricoh_request(struct mmc_host *mmc, struct mmc_request *mrq) for (i = 0; i < data->blocks; i++) { size_t len = data->blksz; u8 *buf; - struct page *page; int result; - page = sg_page(data->sg); - buf = kmap(page) + data->sg->offset + (len * i); + buf = sg_map(data->sg, (len * i), SG_KMAP); + if (IS_ERR(buf)) { + cmd->error = PTR_ERR(buf); + break; + } + result = sdricoh_blockio(host, data->flags & MMC_DATA_READ, buf, len); - kunmap(page); - flush_dcache_page(page); + sg_unmap(data->sg, buf, (len * i), SG_KMAP); + + flush_dcache_page(sg_page(data->sg)); if (result) { dev_err(dev, "sdricoh_request: cmd %i " "block transfer failed\n", cmd->opcode); -- 2.1.4
[PATCH v2 10/21] RDS: Make use of the new sg_map helper function
Straightforward conversion except there's no error path, so we make use of SG_MAP_MUST_NOT_FAIL which may BUG_ON in certain cases in the future. Signed-off-by: Logan Gunthorpe Cc: Santosh Shilimkar Cc: "David S. Miller" --- net/rds/ib_recv.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index e10624a..c665689 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c @@ -800,10 +800,10 @@ static void rds_ib_cong_recv(struct rds_connection *conn, to_copy = min(RDS_FRAG_SIZE - frag_off, PAGE_SIZE - map_off); BUG_ON(to_copy & 7); /* Must be 64bit aligned. */ + addr = sg_map(&frag->f_sg, 0, + SG_KMAP_ATOMIC | SG_MAP_MUST_NOT_FAIL); - addr = kmap_atomic(sg_page(&frag->f_sg)); - - src = addr + frag->f_sg.offset + frag_off; + src = addr + frag_off; dst = (void *)map->m_page_addrs[map_page] + map_off; for (k = 0; k < to_copy; k += 8) { /* Record ports that became uncongested, ie @@ -811,7 +811,7 @@ static void rds_ib_cong_recv(struct rds_connection *conn, uncongested |= ~(*src) & *dst; *dst++ = *src++; } - kunmap_atomic(addr); + sg_unmap(&frag->f_sg, addr, 0, SG_KMAP_ATOMIC); copied += to_copy; -- 2.1.4
[PATCH v2 12/21] scsi: hisi_sas, mvsas, gdth: Make use of the new sg_map helper function
Very straightforward conversion of three scsi drivers. Signed-off-by: Logan Gunthorpe Cc: Achim Leubner Cc: John Garry --- drivers/scsi/gdth.c| 9 +++-- drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 14 +- drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 13 + drivers/scsi/mvsas/mv_sas.c| 10 +- 4 files changed, 30 insertions(+), 16 deletions(-) diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index d020a13..c70248a2 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -2301,10 +2301,15 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, return; } local_irq_save(flags); -address = kmap_atomic(sg_page(sl)) + sl->offset; +address = sg_map(sl, 0, SG_KMAP_ATOMIC); +if (IS_ERR(address)) { +scp->result = DID_ERROR << 16; +return; + } + memcpy(address, buffer, cpnow); flush_dcache_page(sg_page(sl)); -kunmap_atomic(address); +sg_unmap(sl, address, 0, SG_KMAP_ATOMIC); local_irq_restore(flags); if (cpsum == cpcount) break; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index fc1c1b2..b3953e3 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1381,18 +1381,22 @@ static int slot_complete_v1_hw(struct hisi_hba *hisi_hba, void *to; struct scatterlist *sg_resp = &task->smp_task.smp_resp; - ts->stat = SAM_STAT_GOOD; - to = kmap_atomic(sg_page(sg_resp)); + to = sg_map(sg_resp, 0, SG_KMAP_ATOMIC); + if (IS_ERR(to)) { + dev_err(dev, "slot complete: error mapping memory"); + ts->stat = SAS_SG_ERR; + break; + } + ts->stat = SAM_STAT_GOOD; dma_unmap_sg(dev, &task->smp_task.smp_resp, 1, DMA_FROM_DEVICE); dma_unmap_sg(dev, &task->smp_task.smp_req, 1, DMA_TO_DEVICE); - memcpy(to + sg_resp->offset, - slot->status_buffer + + memcpy(to, slot->status_buffer + sizeof(struct hisi_sas_err_record), sg_dma_len(sg_resp)); - kunmap_atomic(to); + sg_unmap(sg_resp, to, 0, SG_KMAP_ATOMIC); break; } case SAS_PROTOCOL_SATA: diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index e241921..3e674a4 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -2307,18 +2307,23 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) struct scatterlist *sg_resp = &task->smp_task.smp_resp; void *to; + to = sg_map(sg_resp, 0, SG_KMAP_ATOMIC); + if (IS_ERR(to)) { + dev_err(dev, "slot complete: error mapping memory"); + ts->stat = SAS_SG_ERR; + break; + } + ts->stat = SAM_STAT_GOOD; - to = kmap_atomic(sg_page(sg_resp)); dma_unmap_sg(dev, &task->smp_task.smp_resp, 1, DMA_FROM_DEVICE); dma_unmap_sg(dev, &task->smp_task.smp_req, 1, DMA_TO_DEVICE); - memcpy(to + sg_resp->offset, - slot->status_buffer + + memcpy(to, slot->status_buffer + sizeof(struct hisi_sas_err_record), sg_dma_len(sg_resp)); - kunmap_atomic(to); + sg_unmap(sg_resp, to, 0, SG_KMAP_ATOMIC); break; } case SAS_PROTOCOL_SATA: diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c index c7cc803..a72e0ce 100644 --- a/drivers/scsi/mvsas/mv_sas.c +++ b/drivers/scsi/mvsas/mv_sas.c @@ -1798,11 +1798,11 @@ int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags) case SAS_PROTOCOL_SMP: { struct scatterlist *sg_resp = &task->smp_task.smp_resp; tstat->stat = SAM_STAT_GOOD; - to = kmap_atomic(sg_page(sg_resp)); - memcpy(to + sg_resp->offset, - slot->response + sizeof(struct mvs_err_info), - sg_dma_len(sg_resp)); - kunmap_atomic(to); + to = sg_map(sg_resp, 0, SG_KMAP_ATOMIC); + memcpy(to, + slot->response + sizeof(struct mvs_err_info), + sg_dma_len(sg_resp)); +
[PATCH v2 13/21] scsi: arcmsr, ips, megaraid: Make use of the new sg_map helper function
Very straightforward conversion of three scsi drivers Signed-off-by: Logan Gunthorpe Cc: Adaptec OEM Raid Solutions Cc: Kashyap Desai Cc: Sumit Saxena Cc: Shivasharan S --- drivers/scsi/arcmsr/arcmsr_hba.c | 16 drivers/scsi/ips.c | 8 drivers/scsi/megaraid.c | 9 +++-- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index af032c4..8c2de17 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -2306,7 +2306,10 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, use_sg = scsi_sg_count(cmd); sg = scsi_sglist(cmd); - buffer = kmap_atomic(sg_page(sg)) + sg->offset; + buffer = sg_map(sg, 0, SG_KMAP_ATOMIC); + if (IS_ERR(buffer)) + return ARCMSR_MESSAGE_FAIL; + if (use_sg > 1) { retvalue = ARCMSR_MESSAGE_FAIL; goto message_out; @@ -2539,7 +2542,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, message_out: if (use_sg) { struct scatterlist *sg = scsi_sglist(cmd); - kunmap_atomic(buffer - sg->offset); + sg_unmap(sg, buffer, 0, SG_KMAP_ATOMIC); } return retvalue; } @@ -2590,11 +2593,16 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb, strncpy(&inqdata[32], "R001", 4); /* Product Revision */ sg = scsi_sglist(cmd); - buffer = kmap_atomic(sg_page(sg)) + sg->offset; + buffer = sg_map(sg, 0, SG_KMAP_ATOMIC); + if (IS_ERR(buffer)) { + cmd->result = (DID_ERROR << 16); + cmd->scsi_done(cmd); + return; + } memcpy(buffer, inqdata, sizeof(inqdata)); sg = scsi_sglist(cmd); - kunmap_atomic(buffer - sg->offset); + sg_unmap(sg, buffer, 0, SG_KMAP_ATOMIC); cmd->scsi_done(cmd); } diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index 3419e1b..6e91729 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -1506,14 +1506,14 @@ static int ips_is_passthru(struct scsi_cmnd *SC) /* kmap_atomic() ensures addressability of the user buffer.*/ /* local_irq_save() protects the KM_IRQ0 address slot. */ local_irq_save(flags); -buffer = kmap_atomic(sg_page(sg)) + sg->offset; -if (buffer && buffer[0] == 'C' && buffer[1] == 'O' && +buffer = sg_map(sg, 0, SG_KMAP_ATOMIC); +if (!IS_ERR(buffer) && buffer[0] == 'C' && buffer[1] == 'O' && buffer[2] == 'P' && buffer[3] == 'P') { -kunmap_atomic(buffer - sg->offset); +sg_unmap(sg, buffer, 0, SG_KMAP_ATOMIC); local_irq_restore(flags); return 1; } -kunmap_atomic(buffer - sg->offset); +sg_unmap(sg, buffer, 0, SG_KMAP_ATOMIC); local_irq_restore(flags); } return 0; diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 3c63c29..f8aee59 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -663,10 +663,15 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy) struct scatterlist *sg; sg = scsi_sglist(cmd); - buf = kmap_atomic(sg_page(sg)) + sg->offset; + buf = sg_map(sg, 0, SG_KMAP_ATOMIC); + if (IS_ERR(buf)) { +cmd->result = (DID_ERROR << 16); + cmd->scsi_done(cmd); + return NULL; + } memset(buf, 0, cmd->cmnd[4]); - kunmap_atomic(buf - sg->offset); + sg_unmap(sg, buf, 0, SG_KMAP_ATOMIC); cmd->result = (DID_OK << 16); cmd->scsi_done(cmd); -- 2.1.4
[PATCH v2 05/21] drm/i915: Make use of the new sg_map helper function
This is a single straightforward conversion from kmap to sg_map. We also create the i915_gem_object_unmap function to common up the unmap code. Signed-off-by: Logan Gunthorpe Acked-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 27 --- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 07e9b27..2c33000 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2202,6 +2202,15 @@ static void __i915_gem_object_reset_page_iter(struct drm_i915_gem_object *obj) radix_tree_delete(&obj->mm.get_page.radix, iter.index); } +static void i915_gem_object_unmap(const struct drm_i915_gem_object *obj, + void *ptr) +{ + if (is_vmalloc_addr(ptr)) + vunmap(ptr); + else + sg_unmap(obj->mm.pages->sgl, ptr, 0, SG_KMAP); +} + void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj, enum i915_mm_subclass subclass) { @@ -2229,10 +2238,7 @@ void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj, void *ptr; ptr = ptr_mask_bits(obj->mm.mapping); - if (is_vmalloc_addr(ptr)) - vunmap(ptr); - else - kunmap(kmap_to_page(ptr)); + i915_gem_object_unmap(obj, ptr); obj->mm.mapping = NULL; } @@ -2499,8 +2505,11 @@ static void *i915_gem_object_map(const struct drm_i915_gem_object *obj, void *addr; /* A single page can always be kmapped */ - if (n_pages == 1 && type == I915_MAP_WB) - return kmap(sg_page(sgt->sgl)); + if (n_pages == 1 && type == I915_MAP_WB) { + addr = sg_map(sgt->sgl, 0, SG_KMAP); + if (IS_ERR(addr)) + return NULL; + } if (n_pages > ARRAY_SIZE(stack_pages)) { /* Too big for stack -- allocate temporary array instead */ @@ -2567,11 +2576,7 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj, goto err_unpin; } - if (is_vmalloc_addr(ptr)) - vunmap(ptr); - else - kunmap(kmap_to_page(ptr)); - + i915_gem_object_unmap(obj, ptr); ptr = obj->mm.mapping = NULL; } -- 2.1.4
[PATCH v2 20/21] mmc: tifm_sd: Make use of the new sg_map helper function
This conversion is a bit complicated. We modiy the read_fifo, write_fifo and copy_page functions to take a scatterlist instead of a page. Thus we can use sg_map instead of kmap_atomic. There's a bit of accounting that needed to be done for the offset for this to work. (Seeing sg_map takes care of the offset but it's already added and used earlier in the code.) There's also no error path, so we use SG_MAP_MUST_NOT_FAIL which may BUG_ON in certain cases in the future. Signed-off-by: Logan Gunthorpe Cc: Alex Dubov Cc: Ulf Hansson --- drivers/mmc/host/tifm_sd.c | 50 +++--- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c index 93c4b40..e64345a 100644 --- a/drivers/mmc/host/tifm_sd.c +++ b/drivers/mmc/host/tifm_sd.c @@ -111,14 +111,16 @@ struct tifm_sd { }; /* for some reason, host won't respond correctly to readw/writew */ -static void tifm_sd_read_fifo(struct tifm_sd *host, struct page *pg, +static void tifm_sd_read_fifo(struct tifm_sd *host, struct scatterlist *sg, unsigned int off, unsigned int cnt) { struct tifm_dev *sock = host->dev; unsigned char *buf; unsigned int pos = 0, val; - buf = kmap_atomic(pg) + off; + buf = sg_map(sg, off - sg->offset, +SG_KMAP_ATOMIC | SG_MAP_MUST_NOT_FAIL); + if (host->cmd_flags & DATA_CARRY) { buf[pos++] = host->bounce_buf_data[0]; host->cmd_flags &= ~DATA_CARRY; @@ -134,17 +136,19 @@ static void tifm_sd_read_fifo(struct tifm_sd *host, struct page *pg, } buf[pos++] = (val >> 8) & 0xff; } - kunmap_atomic(buf - off); + sg_unmap(sg, buf, off - sg->offset, SG_KMAP_ATOMIC); } -static void tifm_sd_write_fifo(struct tifm_sd *host, struct page *pg, +static void tifm_sd_write_fifo(struct tifm_sd *host, struct scatterlist *sg, unsigned int off, unsigned int cnt) { struct tifm_dev *sock = host->dev; unsigned char *buf; unsigned int pos = 0, val; - buf = kmap_atomic(pg) + off; + buf = sg_map(sg, off - sg->offset, +SG_KMAP_ATOMIC | SG_MAP_MUST_NOT_FAIL); + if (host->cmd_flags & DATA_CARRY) { val = host->bounce_buf_data[0] | ((buf[pos++] << 8) & 0xff00); writel(val, sock->addr + SOCK_MMCSD_DATA); @@ -161,7 +165,7 @@ static void tifm_sd_write_fifo(struct tifm_sd *host, struct page *pg, val |= (buf[pos++] << 8) & 0xff00; writel(val, sock->addr + SOCK_MMCSD_DATA); } - kunmap_atomic(buf - off); + sg_unmap(sg, buf, off - sg->offset, SG_KMAP_ATOMIC); } static void tifm_sd_transfer_data(struct tifm_sd *host) @@ -170,7 +174,6 @@ static void tifm_sd_transfer_data(struct tifm_sd *host) struct scatterlist *sg = r_data->sg; unsigned int off, cnt, t_size = TIFM_MMCSD_FIFO_SIZE * 2; unsigned int p_off, p_cnt; - struct page *pg; if (host->sg_pos == host->sg_len) return; @@ -192,33 +195,39 @@ static void tifm_sd_transfer_data(struct tifm_sd *host) } off = sg[host->sg_pos].offset + host->block_pos; - pg = nth_page(sg_page(&sg[host->sg_pos]), off >> PAGE_SHIFT); p_off = offset_in_page(off); p_cnt = PAGE_SIZE - p_off; p_cnt = min(p_cnt, cnt); p_cnt = min(p_cnt, t_size); if (r_data->flags & MMC_DATA_READ) - tifm_sd_read_fifo(host, pg, p_off, p_cnt); + tifm_sd_read_fifo(host, &sg[host->sg_pos], p_off, + p_cnt); else if (r_data->flags & MMC_DATA_WRITE) - tifm_sd_write_fifo(host, pg, p_off, p_cnt); + tifm_sd_write_fifo(host, &sg[host->sg_pos], p_off, + p_cnt); t_size -= p_cnt; host->block_pos += p_cnt; } } -static void tifm_sd_copy_page(struct page *dst, unsigned int dst_off, - struct page *src, unsigned int src_off, +static void tifm_sd_copy_page(struct scatterlist *dst, unsigned int dst_off, + struct scatterlist *src, unsigned int src_off, unsigned int count) { - unsigned char *src_buf = kmap_atomic(src) + src_off; - unsigned char *dst_buf = kmap_atomic(dst) + dst_off; + unsigned char *src_buf, *dst_buf; + + src_off -= src->offset; + dst_off -= dst->offset; + + src_buf = sg_map(src, src_off, SG_KMAP_ATOMIC | SG_MAP_MUST_NOT_FAIL); + dst_buf = sg_map(dst, dst_off, SG_KMAP_ATOMIC | SG_MAP_MUST_NOT_FAIL); memcpy(dst_buf, src_buf, count); - kunmap_atomic(dst_buf - dst_off); -
[PATCH v2 15/21] xen-blkfront: Make use of the new sg_map helper function
Straightforward conversion to the new helper, except due to the lack of error path, we have to use SG_MAP_MUST_NOT_FAIL which may BUG_ON in certain cases in the future. Signed-off-by: Logan Gunthorpe Cc: Boris Ostrovsky Cc: Juergen Gross Cc: Konrad Rzeszutek Wilk Cc: "Roger Pau Monné" --- drivers/block/xen-blkfront.c | 20 +++- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 3945963..ed62175 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -816,8 +816,9 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri BUG_ON(sg->offset + sg->length > PAGE_SIZE); if (setup.need_copy) { - setup.bvec_off = sg->offset; - setup.bvec_data = kmap_atomic(sg_page(sg)); + setup.bvec_off = 0; + setup.bvec_data = sg_map(sg, 0, SG_KMAP_ATOMIC | +SG_MAP_MUST_NOT_FAIL); } gnttab_foreach_grant_in_range(sg_page(sg), @@ -827,7 +828,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri &setup); if (setup.need_copy) - kunmap_atomic(setup.bvec_data); + sg_unmap(sg, setup.bvec_data, 0, SG_KMAP_ATOMIC); } if (setup.segments) kunmap_atomic(setup.segments); @@ -1053,7 +1054,7 @@ static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset) case XEN_SCSI_DISK5_MAJOR: case XEN_SCSI_DISK6_MAJOR: case XEN_SCSI_DISK7_MAJOR: - *offset = (*minor / PARTS_PER_DISK) + + *offset = (*minor / PARTS_PER_DISK) + ((major - XEN_SCSI_DISK1_MAJOR + 1) * 16) + EMULATED_SD_DISK_NAME_OFFSET; *minor = *minor + @@ -1068,7 +1069,7 @@ static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset) case XEN_SCSI_DISK13_MAJOR: case XEN_SCSI_DISK14_MAJOR: case XEN_SCSI_DISK15_MAJOR: - *offset = (*minor / PARTS_PER_DISK) + + *offset = (*minor / PARTS_PER_DISK) + ((major - XEN_SCSI_DISK8_MAJOR + 8) * 16) + EMULATED_SD_DISK_NAME_OFFSET; *minor = *minor + @@ -1119,7 +1120,7 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, if (!VDEV_IS_EXTENDED(info->vdevice)) { err = xen_translate_vdev(info->vdevice, &minor, &offset); if (err) - return err; + return err; nr_parts = PARTS_PER_DISK; } else { minor = BLKIF_MINOR_EXT(info->vdevice); @@ -1483,8 +1484,9 @@ static bool blkif_completion(unsigned long *id, for_each_sg(s->sg, sg, num_sg, i) { BUG_ON(sg->offset + sg->length > PAGE_SIZE); - data.bvec_offset = sg->offset; - data.bvec_data = kmap_atomic(sg_page(sg)); + data.bvec_offset = 0; + data.bvec_data = sg_map(sg, 0, SG_KMAP_ATOMIC | + SG_MAP_MUST_NOT_FAIL); gnttab_foreach_grant_in_range(sg_page(sg), sg->offset, @@ -1492,7 +1494,7 @@ static bool blkif_completion(unsigned long *id, blkif_copy_from_grant, &data); - kunmap_atomic(data.bvec_data); + sg_unmap(sg, data.bvec_data, 0, SG_KMAP_ATOMIC); } } /* Add the persistent grant into the list of free grants */ -- 2.1.4
[PATCH v2 08/21] dm-crypt: Make use of the new sg_map helper in 4 call sites
Very straightforward conversion to the new function in all four spots. Signed-off-by: Logan Gunthorpe Cc: Alasdair Kergon Cc: Mike Snitzer --- drivers/md/dm-crypt.c | 39 ++- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 8dbecf1..841f1fc 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -635,9 +635,12 @@ static int crypt_iv_lmk_gen(struct crypt_config *cc, u8 *iv, if (bio_data_dir(dmreq->ctx->bio_in) == WRITE) { sg = crypt_get_sg_data(cc, dmreq->sg_in); - src = kmap_atomic(sg_page(sg)); - r = crypt_iv_lmk_one(cc, iv, dmreq, src + sg->offset); - kunmap_atomic(src); + src = sg_map(sg, 0, SG_KMAP_ATOMIC); + if (IS_ERR(src)) + return PTR_ERR(src); + + r = crypt_iv_lmk_one(cc, iv, dmreq, src); + sg_unmap(sg, src, 0, SG_KMAP_ATOMIC); } else memset(iv, 0, cc->iv_size); @@ -655,14 +658,18 @@ static int crypt_iv_lmk_post(struct crypt_config *cc, u8 *iv, return 0; sg = crypt_get_sg_data(cc, dmreq->sg_out); - dst = kmap_atomic(sg_page(sg)); - r = crypt_iv_lmk_one(cc, iv, dmreq, dst + sg->offset); + dst = sg_map(sg, 0, SG_KMAP_ATOMIC); + if (IS_ERR(dst)) + return PTR_ERR(dst); + + r = crypt_iv_lmk_one(cc, iv, dmreq, dst); /* Tweak the first block of plaintext sector */ if (!r) - crypto_xor(dst + sg->offset, iv, cc->iv_size); + crypto_xor(dst, iv, cc->iv_size); + + sg_unmap(sg, dst, 0, SG_KMAP_ATOMIC); - kunmap_atomic(dst); return r; } @@ -786,9 +793,12 @@ static int crypt_iv_tcw_gen(struct crypt_config *cc, u8 *iv, /* Remove whitening from ciphertext */ if (bio_data_dir(dmreq->ctx->bio_in) != WRITE) { sg = crypt_get_sg_data(cc, dmreq->sg_in); - src = kmap_atomic(sg_page(sg)); - r = crypt_iv_tcw_whitening(cc, dmreq, src + sg->offset); - kunmap_atomic(src); + src = sg_map(sg, 0, SG_KMAP_ATOMIC); + if (IS_ERR(src)) + return PTR_ERR(src); + + r = crypt_iv_tcw_whitening(cc, dmreq, src); + sg_unmap(sg, src, 0, SG_KMAP_ATOMIC); } /* Calculate IV */ @@ -812,9 +822,12 @@ static int crypt_iv_tcw_post(struct crypt_config *cc, u8 *iv, /* Apply whitening on ciphertext */ sg = crypt_get_sg_data(cc, dmreq->sg_out); - dst = kmap_atomic(sg_page(sg)); - r = crypt_iv_tcw_whitening(cc, dmreq, dst + sg->offset); - kunmap_atomic(dst); + dst = sg_map(sg, 0, SG_KMAP_ATOMIC); + if (IS_ERR(dst)) + return PTR_ERR(dst); + + r = crypt_iv_tcw_whitening(cc, dmreq, dst); + sg_unmap(sg, dst, 0, SG_KMAP_ATOMIC); return r; } -- 2.1.4
[PATCH v2 01/21] scatterlist: Introduce sg_map helper functions
This patch introduces functions which kmap the pages inside an sgl. These functions replace a common pattern of kmap(sg_page(sg)) that is used in more than 50 places within the kernel. The motivation for this work is to eventually safely support sgls that contain io memory. In order for that to work, any access to the contents of an iomem SGL will need to be done with iomemcpy or hit some warning. (The exact details of how this will work have yet to be worked out.) Having all the kmaps in one place is just a first step in that direction. Additionally, seeing this helps cut down the users of sg_page, it should make any effort to go to struct-page-less DMAs a little easier (should that idea ever swing back into favour again). A flags option is added to select between a regular or atomic mapping so these functions can replace kmap(sg_page or kmap_atomic(sg_page. Future work may expand this to have flags for using page_address or vmap. We include a flag to require the function not to fail to support legacy code that has no easy error path. Much further in the future, there may be a flag to allocate memory and copy the data from/to iomem. We also add the semantic that sg_map can fail to create a mapping, despite the fact that the current code this is replacing is assumed to never fail and the current version of these functions cannot fail. This is to support iomem which may either have to fail to create the mapping or allocate memory as a bounce buffer which itself can fail. Also, in terms of cleanup, a few of the existing kmap(sg_page) users play things a bit loose in terms of whether they apply sg->offset so using these helper functions should help avoid such issues. Signed-off-by: Logan Gunthorpe --- include/linux/scatterlist.h | 85 + 1 file changed, 85 insertions(+) diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h index cb3c8fe..fad170b 100644 --- a/include/linux/scatterlist.h +++ b/include/linux/scatterlist.h @@ -5,6 +5,7 @@ #include #include #include +#include #include struct scatterlist { @@ -126,6 +127,90 @@ static inline struct page *sg_page(struct scatterlist *sg) return (struct page *)((sg)->page_link & ~0x3); } +#define SG_KMAP (1 << 0) /* create a mapping with kmap */ +#define SG_KMAP_ATOMIC (1 << 1) /* create a mapping with kmap_atomic */ +#define SG_MAP_MUST_NOT_FAIL (1 << 2) /* indicate sg_map should not fail */ + +/** + * sg_map - kmap a page inside an sgl + * @sg:SG entry + * @offset:Offset into entry + * @flags: Flags for creating the mapping + * + * Description: + * Use this function to map a page in the scatterlist at the specified + * offset. sg->offset is already added for you. Note: the semantics of + * this function are that it may fail. Thus, its output should be checked + * with IS_ERR and PTR_ERR. Otherwise, a pointer to the specified offset + * in the mapped page is returned. + * + * Flags can be any of: + * * SG_KMAP - Use kmap to create the mapping + * * SG_KMAP_ATOMIC- Use kmap_atomic to map the page atommically. + * Thus, the rules of that function apply: the + * cpu may not sleep until it is unmaped. + * * SG_MAP_MUST_NOT_FAIL - Indicate that sg_map must not fail. + * If it does, it will issue a BUG_ON instead. + * This is intended for legacy code only, it + * is not to be used in new code. + * + * Also, consider carefully whether this function is appropriate. It is + * largely not recommended for new code and if the sgl came from another + * subsystem and you don't know what kind of memory might be in the list + * then you definitely should not call it. Non-mappable memory may be in + * the sgl and thus this function may fail unexpectedly. Consider using + * sg_copy_to_buffer instead. + **/ +static inline void *sg_map(struct scatterlist *sg, size_t offset, int flags) +{ + struct page *pg; + unsigned int pg_off; + void *ret; + + offset += sg->offset; + pg = nth_page(sg_page(sg), offset >> PAGE_SHIFT); + pg_off = offset_in_page(offset); + + if (flags & SG_KMAP_ATOMIC) + ret = kmap_atomic(pg) + pg_off; + else if (flags & SG_KMAP) + ret = kmap(pg) + pg_off; + else + ret = ERR_PTR(-EINVAL); + + /* +* In theory, this can't happen yet. Once we start adding +* unmapable memory, it also shouldn't happen unless developers +* start putting unmappable struct pages in sgls and passing +* it to code that doesn't support it. +*/ + BUG_ON(flags & SG_MAP_MUST_NOT_FAIL && IS_ERR(ret)); + + return ret; +} + +/** + * sg_unmap - unmap a page that was mapped with sg_map_offset + * @sg:
[PATCH v2 02/21] libiscsi: Add an internal error code
This is a prep patch to add a new error code to libiscsi. We want to rework some kmap calls to be able to fail. When we do, we'd like to use this error code. This patch simply introduces ISCSI_TCP_INTERNAL_ERR and prints "Internal Error." when it gets hit. Signed-off-by: Logan Gunthorpe --- drivers/scsi/cxgbi/libcxgbi.c | 5 + include/scsi/libiscsi_tcp.h | 1 + 2 files changed, 6 insertions(+) diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index bd7d39e..e38d0c1 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c @@ -1556,6 +1556,11 @@ static inline int read_pdu_skb(struct iscsi_conn *conn, */ iscsi_conn_printk(KERN_ERR, conn, "Invalid pdu or skb."); return -EFAULT; + case ISCSI_TCP_INTERNAL_ERR: + pr_info("skb 0x%p, off %u, %d, TCP_INTERNAL_ERR.\n", + skb, offset, offloaded); + iscsi_conn_printk(KERN_ERR, conn, "Internal error."); + return -EFAULT; case ISCSI_TCP_SEGMENT_DONE: log_debug(1 << CXGBI_DBG_PDU_RX, "skb 0x%p, off %u, %d, TCP_SEG_DONE, rc %d.\n", diff --git a/include/scsi/libiscsi_tcp.h b/include/scsi/libiscsi_tcp.h index 30520d5..90691ad 100644 --- a/include/scsi/libiscsi_tcp.h +++ b/include/scsi/libiscsi_tcp.h @@ -92,6 +92,7 @@ enum { ISCSI_TCP_SKB_DONE, /* skb is out of data */ ISCSI_TCP_CONN_ERR, /* iscsi layer has fired a conn err */ ISCSI_TCP_SUSPENDED,/* conn is suspended */ + ISCSI_TCP_INTERNAL_ERR, /* an internal error occurred */ }; extern void iscsi_tcp_hdr_recv_prep(struct iscsi_tcp_conn *tcp_conn); -- 2.1.4
Re: support autofocus / autogain in libv4l2
Le mardi 25 avril 2017 à 13:30 +0200, Pali Rohár a écrit : > Pinos (renamed from PulseVideo) > > https://blogs.gnome.org/uraeus/2015/06/30/introducing-pulse-video/ > https://cgit.freedesktop.org/~wtay/pinos/ > > But from git history it looks like it is probably dead now... This is also incorrect. See "work" branch. It is still a one man show, code being aggressively re-factored. I suspect this will be the case until the "form" is considered acceptable. Nicolas signature.asc Description: This is a digitally signed message part
Re: support autofocus / autogain in libv4l2
Le mardi 25 avril 2017 à 10:05 +0200, Pavel Machek a écrit : > Well, fd's are hard, because application can do fork() and now > interesting stuff happens. Threads are tricky, because now you have > locking etc. > > libv4l2 is designed to be LD_PRELOADED. That is not really feasible > with "complex" library. That is incorrect. The library propose an API where you simply replace certain low level calls, like ioctl -> v4l2_ioctl, open -> v4l2_open(). You have to do that explicitly in your existing code. It does not abstract the API itself unlike libdrm. Nicolas signature.asc Description: This is a digitally signed message part
Re: support autofocus / autogain in libv4l2
Le mardi 25 avril 2017 à 10:08 +0200, Pali Rohár a écrit : > On Tuesday 25 April 2017 10:05:38 Pavel Machek wrote: > > > > It would be nice if more than one application could be > > > > accessing the > > > > camera at the same time... (I.e. something graphical running > > > > preview > > > > then using command line tool to grab a picture.) This one is > > > > definitely not solveable inside a library... > > > > > > Someone once suggested to have something like pulseaudio for V4L. > > > For such usage, a server would be interesting. Yet, I would code > > > it > > > in a way that applications using libv4l will talk with such > > > daemon > > > in a transparent way. > > > > Yes, we need something like pulseaudio for V4L. And yes, we should > > make it transparent for applications using libv4l. > > IIRC there is already some effort in writing such "video" server > which > would support accessing more application into webcam video, like > pulseaudio server for accessing more applications to microphone > input. > Because references are nice: https://blogs.gnome.org/uraeus/2015/06/30/introducing-pulse-video/ https://gstconf.ubicast.tv/videos/camera-sharing-and-sandboxing-with-pinos/ And why the internals are not going to be implemented using GStreamer in the end: https://gstconf.ubicast.tv/videos/keep-calm-and-refactor-about-the-essence-of-gstreamer/ regards, Nicolas signature.asc Description: This is a digitally signed message part
[PATCH] rcar-vin: Use of_nodes as specified by the subdev
From: Kieran Bingham The rvin_digital_notify_bound() call dereferences the subdev->dev pointer to obtain the of_node. On some error paths, this dev node can be set as NULL. The of_node is mapped into the subdevice structure on initialisation, so this is a safer source to compare the nodes. Dereference the of_node from the subdev structure instead of the dev structure. Fixes: 83fba2c06f19 ("rcar-vin: rework how subdevice is found and bound") Signed-off-by: Kieran Bingham --- drivers/media/platform/rcar-vin/rcar-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 5861ab281150..a530dc388b95 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -469,7 +469,7 @@ static int rvin_digital_notify_bound(struct v4l2_async_notifier *notifier, v4l2_set_subdev_hostdata(subdev, vin); - if (vin->digital.asd.match.of.node == subdev->dev->of_node) { + if (vin->digital.asd.match.of.node == subdev->of_node) { /* Find surce and sink pad of remote subdevice */ ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE); -- 2.7.4
[PATCH -next] [media] s5p-cec: remove unused including
From: Wei Yongjun Remove including that is not needed. Signed-off-by: Wei Yongjun --- drivers/media/platform/s5p-cec/s5p_cec.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/s5p-cec/s5p_cec.h b/drivers/media/platform/s5p-cec/s5p_cec.h index 7015845..8bcd8dc 100644 --- a/drivers/media/platform/s5p-cec/s5p_cec.h +++ b/drivers/media/platform/s5p-cec/s5p_cec.h @@ -22,7 +22,6 @@ #include #include #include -#include #include #include
Re: [PATCH 2/2] rcar-vin: group: use correct of_node
Hi Niklas, On 25/04/17 15:30, Niklas Söderlund wrote: > Hi Kieran, > > Thanks for your patch. > > On 2017-04-24 19:14:26 +0100, Kieran Bingham wrote: >> From: Kieran Bingham >> >> The unbind function dereferences the subdev->dev node to obtain the >> of_node. In error paths, the subdev->dev can be set to NULL, whilst the >> correct reference to the of_node is available as subdev->of_node. >> >> Correct the dereferencing, and move the variable outside of the loop as >> it is constant against the subdev, and not initialised per CSI, for both >> the bind and unbind functions >> >> Signed-off-by: Kieran Bingham >> --- >> drivers/media/platform/rcar-vin/rcar-core.c | 7 +++ >> 1 file changed, 3 insertions(+), 4 deletions(-) >> >> diff --git a/drivers/media/platform/rcar-vin/rcar-core.c >> b/drivers/media/platform/rcar-vin/rcar-core.c >> index 48557628e76d..a530dc388b95 100644 >> --- a/drivers/media/platform/rcar-vin/rcar-core.c >> +++ b/drivers/media/platform/rcar-vin/rcar-core.c >> @@ -469,7 +469,7 @@ static int rvin_digital_notify_bound(struct >> v4l2_async_notifier *notifier, >> >> v4l2_set_subdev_hostdata(subdev, vin); >> >> -if (vin->digital.asd.match.of.node == subdev->dev->of_node) { >> +if (vin->digital.asd.match.of.node == subdev->of_node) { >> /* Find surce and sink pad of remote subdevice */ > > This code is already present in upstream. Could you break this out in a > separate patch and resubmit it? Sure, no problem. >> >> ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE); >> @@ -738,12 +738,11 @@ static void rvin_group_notify_unbind(struct >> v4l2_async_notifier *notifier, >> struct v4l2_async_subdev *asd) >> { >> struct rvin_dev *vin = notifier_to_vin(notifier); >> +struct device_node *del = subdev->of_node; >> unsigned int i; >> >> mutex_lock(&vin->group->lock); >> for (i = 0; i < RVIN_CSI_MAX; i++) { >> -struct device_node *del = subdev->dev->of_node; >> - >> if (vin->group->bridge[i].asd.match.of.node == del) { >> vin_dbg(vin, "Unbind bridge %s\n", subdev->name); >> vin->group->bridge[i].subdev = NULL; >> @@ -768,13 +767,13 @@ static int rvin_group_notify_bound(struct >> v4l2_async_notifier *notifier, >> struct v4l2_async_subdev *asd) >> { >> struct rvin_dev *vin = notifier_to_vin(notifier); >> +struct device_node *new = subdev->of_node; >> unsigned int i; >> >> v4l2_set_subdev_hostdata(subdev, vin); >> >> mutex_lock(&vin->group->lock); >> for (i = 0; i < RVIN_CSI_MAX; i++) { >> -struct device_node *new = subdev->dev->of_node; >> >> if (vin->group->bridge[i].asd.match.of.node == new) { >> vin_dbg(vin, "Bound bridge %s\n", subdev->name); > > And I will squash these fixes in to the next version of my 'Gen3 with > media controller support' series since that is not yet picked up. Is > that OK with you? Yes, squashing this in seems appropriate. Regards Kieran >> -- >> 2.7.4 >> >
Re: [PATCH 2/2] rcar-vin: group: use correct of_node
Hi Kieran, Thanks for your patch. On 2017-04-24 19:14:26 +0100, Kieran Bingham wrote: > From: Kieran Bingham > > The unbind function dereferences the subdev->dev node to obtain the > of_node. In error paths, the subdev->dev can be set to NULL, whilst the > correct reference to the of_node is available as subdev->of_node. > > Correct the dereferencing, and move the variable outside of the loop as > it is constant against the subdev, and not initialised per CSI, for both > the bind and unbind functions > > Signed-off-by: Kieran Bingham > --- > drivers/media/platform/rcar-vin/rcar-core.c | 7 +++ > 1 file changed, 3 insertions(+), 4 deletions(-) > > diff --git a/drivers/media/platform/rcar-vin/rcar-core.c > b/drivers/media/platform/rcar-vin/rcar-core.c > index 48557628e76d..a530dc388b95 100644 > --- a/drivers/media/platform/rcar-vin/rcar-core.c > +++ b/drivers/media/platform/rcar-vin/rcar-core.c > @@ -469,7 +469,7 @@ static int rvin_digital_notify_bound(struct > v4l2_async_notifier *notifier, > > v4l2_set_subdev_hostdata(subdev, vin); > > - if (vin->digital.asd.match.of.node == subdev->dev->of_node) { > + if (vin->digital.asd.match.of.node == subdev->of_node) { > /* Find surce and sink pad of remote subdevice */ This code is already present in upstream. Could you break this out in a separate patch and resubmit it? > > ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE); > @@ -738,12 +738,11 @@ static void rvin_group_notify_unbind(struct > v4l2_async_notifier *notifier, >struct v4l2_async_subdev *asd) > { > struct rvin_dev *vin = notifier_to_vin(notifier); > + struct device_node *del = subdev->of_node; > unsigned int i; > > mutex_lock(&vin->group->lock); > for (i = 0; i < RVIN_CSI_MAX; i++) { > - struct device_node *del = subdev->dev->of_node; > - > if (vin->group->bridge[i].asd.match.of.node == del) { > vin_dbg(vin, "Unbind bridge %s\n", subdev->name); > vin->group->bridge[i].subdev = NULL; > @@ -768,13 +767,13 @@ static int rvin_group_notify_bound(struct > v4l2_async_notifier *notifier, > struct v4l2_async_subdev *asd) > { > struct rvin_dev *vin = notifier_to_vin(notifier); > + struct device_node *new = subdev->of_node; > unsigned int i; > > v4l2_set_subdev_hostdata(subdev, vin); > > mutex_lock(&vin->group->lock); > for (i = 0; i < RVIN_CSI_MAX; i++) { > - struct device_node *new = subdev->dev->of_node; > > if (vin->group->bridge[i].asd.match.of.node == new) { > vin_dbg(vin, "Bound bridge %s\n", subdev->name); And I will squash these fixes in to the next version of my 'Gen3 with media controller support' series since that is not yet picked up. Is that OK with you? > -- > 2.7.4 > -- Regards, Niklas Söderlund
Re: TW686x Linux Main Line Driver Issue
Hi Krishan, On 25 April 2017 at 03:46, Krishan Nilanga wrote: > Hi All, > > gst-launch-1.0 --gst-debug=3 v4l2src device=/dev/video0 ! > video/x-raw,width=640,height=480,pixelformat=UYVY ! imxeglvivsink > > I have tried to run the above gstreamer pipeline and I'm getting > > [ 97.392807] tw686x :01:00.0: DMA timeout. Resetting DMA for all > channels > [ 97.392827] tw686x :01:00.0: reset: stopping DMA > > for most IRQ calls of tw686x driver. > > for some other IRQ calls I'm getting > > [ 99.592901] tw686x :01:00.0: video0: unexpected p-b buffer! > [ 99.592924] tw686x :01:00.0: reset: stopping DMA > > in dmesg. > > I hope above details will help to understand the problem. > This does not provide much info. It merely says there is some hardware problem or the signal is being problematic. FWIW, when we get those messages on our platform it's always correlated to a bad cable or poor signal. What is your dma-mode configuration? -- Ezequiel García, VanguardiaSur www.vanguardiasur.com.ar
Re: [PATCH 1/2] [media] vb2: Fix an off by one error in 'vb2_plane_vaddr'
Gar... No. The 3.6+ from a9ae4692eda4 ("[media] vb2: fix plane index sanity check in vb2_plane_cookie()") feels totally arbitrary to me. No need to be consistent. Just do: Cc: sta...@vger.kernel.org Fixes: e23ccc0ad925 ("[media] v4l: add videobuf2 Video for Linux 2 driver framework") Fixes tags are always good too have btw. You should be adding them by default to everything even if it doesn't get backported to stable. regards, dan carpenter
Re: support autofocus / autogain in libv4l2
On Tuesday 25 April 2017 14:28:20 Pavel Machek wrote: > On Tue 2017-04-25 13:30:09, Pali Rohár wrote: > > On Tuesday 25 April 2017 13:23:30 Pavel Machek wrote: > > > Hi! > > > On Tue 2017-04-25 10:08:15, Pali Rohár wrote: > > > > On Tuesday 25 April 2017 10:05:38 Pavel Machek wrote: > > > > > > > It would be nice if more than one application could be accessing > > > > > > > the > > > > > > > camera at the same time... (I.e. something graphical running > > > > > > > preview > > > > > > > then using command line tool to grab a picture.) This one is > > > > > > > definitely not solveable inside a library... > > > > > > > > > > > > Someone once suggested to have something like pulseaudio for V4L. > > > > > > For such usage, a server would be interesting. Yet, I would code it > > > > > > in a way that applications using libv4l will talk with such daemon > > > > > > in a transparent way. > > > > > > > > > > Yes, we need something like pulseaudio for V4L. And yes, we should > > > > > make it transparent for applications using libv4l. > > > > > > > > IIRC there is already some effort in writing such "video" server which > > > > would support accessing more application into webcam video, like > > > > pulseaudio server for accessing more applications to microphone input. > > > > > > Do you have project name / url / something? > > > > Pinos (renamed from PulseVideo) > > > > https://blogs.gnome.org/uraeus/2015/06/30/introducing-pulse-video/ > > https://cgit.freedesktop.org/~wtay/pinos/ > > > > But from git history it looks like it is probably dead now... > > Actually, last commit is an hour ago on "work" branch. Seems alive to > me ;-). Great! I just (blindly) looked at master branch and it is old... > Thanks for pointer... > Pavel -- Pali Rohár pali.ro...@gmail.com
Re: support autofocus / autogain in libv4l2
On Tue 2017-04-25 13:30:09, Pali Rohár wrote: > On Tuesday 25 April 2017 13:23:30 Pavel Machek wrote: > > Hi! > > On Tue 2017-04-25 10:08:15, Pali Rohár wrote: > > > On Tuesday 25 April 2017 10:05:38 Pavel Machek wrote: > > > > > > It would be nice if more than one application could be accessing the > > > > > > camera at the same time... (I.e. something graphical running preview > > > > > > then using command line tool to grab a picture.) This one is > > > > > > definitely not solveable inside a library... > > > > > > > > > > Someone once suggested to have something like pulseaudio for V4L. > > > > > For such usage, a server would be interesting. Yet, I would code it > > > > > in a way that applications using libv4l will talk with such daemon > > > > > in a transparent way. > > > > > > > > Yes, we need something like pulseaudio for V4L. And yes, we should > > > > make it transparent for applications using libv4l. > > > > > > IIRC there is already some effort in writing such "video" server which > > > would support accessing more application into webcam video, like > > > pulseaudio server for accessing more applications to microphone input. > > > > Do you have project name / url / something? > > Pinos (renamed from PulseVideo) > > https://blogs.gnome.org/uraeus/2015/06/30/introducing-pulse-video/ > https://cgit.freedesktop.org/~wtay/pinos/ > > But from git history it looks like it is probably dead now... Actually, last commit is an hour ago on "work" branch. Seems alive to me ;-). Thanks for pointer... Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html signature.asc Description: Digital signature
Re: [PATCH v3 4/7] v4l: Switch from V4L2 OF not V4L2 fwnode API
Changes since v3: - Convert recently merged ov5645 and ov5647 to V4L2 fwnode -- Sakari Ailus e-mail: sakari.ai...@iki.fi XMPP: sai...@retiisi.org.uk
[PATCH v3.1 4/7] v4l: Switch from V4L2 OF not V4L2 fwnode API
Switch users of the v4l2_of_ APIs to the more generic v4l2_fwnode_ APIs. Async OF matching is replaced by fwnode matching and OF matching support is removed. Signed-off-by: Sakari Ailus Acked-by: Benoit Parrot # i2c/ov2569.c, am437x/am437x-vpfe.c and ti-vpe/cal.c Tested-by: Hans Verkuil # Atmel sama5d3 board + ov2640 sensor --- drivers/media/i2c/Kconfig | 11 + drivers/media/i2c/adv7604.c| 7 +-- drivers/media/i2c/mt9v032.c| 7 +-- drivers/media/i2c/ov2659.c | 8 ++-- drivers/media/i2c/ov5645.c | 7 +-- drivers/media/i2c/ov5647.c | 7 +-- drivers/media/i2c/s5c73m3/s5c73m3-core.c | 7 +-- drivers/media/i2c/s5k5baf.c| 6 +-- drivers/media/i2c/smiapp/Kconfig | 1 + drivers/media/i2c/smiapp/smiapp-core.c | 29 ++-- drivers/media/i2c/tc358743.c | 11 +++-- drivers/media/i2c/tvp514x.c| 6 +-- drivers/media/i2c/tvp5150.c| 7 +-- drivers/media/i2c/tvp7002.c| 6 +-- drivers/media/platform/Kconfig | 3 ++ drivers/media/platform/am437x/Kconfig | 1 + drivers/media/platform/am437x/am437x-vpfe.c| 15 +++--- drivers/media/platform/atmel/Kconfig | 2 + drivers/media/platform/atmel/atmel-isc.c | 13 -- drivers/media/platform/atmel/atmel-isi.c | 11 +++-- drivers/media/platform/exynos4-is/Kconfig | 2 + drivers/media/platform/exynos4-is/media-dev.c | 13 +++--- drivers/media/platform/exynos4-is/mipi-csis.c | 6 +-- drivers/media/platform/omap3isp/isp.c | 49 ++-- drivers/media/platform/pxa_camera.c| 11 +++-- drivers/media/platform/rcar-vin/Kconfig| 1 + drivers/media/platform/rcar-vin/rcar-core.c| 19 drivers/media/platform/soc_camera/soc_camera.c | 7 +-- drivers/media/platform/ti-vpe/cal.c| 15 +++--- drivers/media/platform/xilinx/Kconfig | 1 + drivers/media/platform/xilinx/xilinx-vipp.c| 63 ++ drivers/media/v4l2-core/v4l2-async.c | 14 +- include/media/v4l2-async.h | 5 -- 33 files changed, 204 insertions(+), 167 deletions(-) diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index b358d1a..aeb7485 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -210,6 +210,7 @@ config VIDEO_ADV7604 depends on GPIOLIB || COMPILE_TEST select HDMI select MEDIA_CEC_EDID + select V4L2_FWNODE ---help--- Support for the Analog Devices ADV7604 video decoder. @@ -324,6 +325,7 @@ config VIDEO_TC358743 tristate "Toshiba TC358743 decoder" depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API select HDMI + select V4L2_FWNODE ---help--- Support for the Toshiba TC358743 HDMI to MIPI CSI-2 bridge. @@ -333,6 +335,7 @@ config VIDEO_TC358743 config VIDEO_TVP514X tristate "Texas Instruments TVP514x video decoder" depends on VIDEO_V4L2 && I2C + select V4L2_FWNODE ---help--- This is a Video4Linux2 sensor-level driver for the TI TVP5146/47 decoder. It is currently working with the TI OMAP3 camera @@ -344,6 +347,7 @@ config VIDEO_TVP514X config VIDEO_TVP5150 tristate "Texas Instruments TVP5150 video decoder" depends on VIDEO_V4L2 && I2C + select V4L2_FWNODE ---help--- Support for the Texas Instruments TVP5150 video decoder. @@ -353,6 +357,7 @@ config VIDEO_TVP5150 config VIDEO_TVP7002 tristate "Texas Instruments TVP7002 video decoder" depends on VIDEO_V4L2 && I2C + select V4L2_FWNODE ---help--- Support for the Texas Instruments TVP7002 video decoder. @@ -535,6 +540,7 @@ config VIDEO_OV2659 tristate "OmniVision OV2659 sensor support" depends on VIDEO_V4L2 && I2C depends on MEDIA_CAMERA_SUPPORT + select V4L2_FWNODE ---help--- This is a Video4Linux2 sensor-level driver for the OmniVision OV2659 camera. @@ -547,6 +553,7 @@ config VIDEO_OV5645 depends on OF depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API depends on MEDIA_CAMERA_SUPPORT + select V4L2_FWNODE ---help--- This is a Video4Linux2 sensor-level driver for the OmniVision OV5645 camera. @@ -558,6 +565,7 @@ config VIDEO_OV5647 tristate "OmniVision OV5647 sensor support" depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API depends on MEDIA_CAMERA_SUPPORT + select V4L2_FWNODE ---help--- This is a Video4Linux2 sensor-level driver for the OmniVision OV5647 camera. @@ -650,6 +658,7 @@ config VIDEO_MT9V032 depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API depen
Re: [git:media_tree/master] [media] uvcvideo: Don't record timespec_sub
Hi Mauro On 10/04/17 11:42, Mauro Carvalho Chehab wrote: > This is an automatic generated email to let you know that the following patch > were queued: > > Subject: [media] uvcvideo: Don't record timespec_sub In my submission, this subject line was "uvcvideo: Don't recode timespec_sub" I don't believe we are 'recording' timespec_sub. I suspect it is too late to fix now. -- Regards Kieran > Author: Kieran Bingham > Date:Mon Apr 3 08:25:31 2017 -0300 > > The statistics function subtracts two timespecs manually. A helper is > provided by the kernel to do this. > > Replace the implementation, using the helper. > > Signed-off-by: Kieran Bingham > Signed-off-by: Laurent Pinchart > Signed-off-by: Mauro Carvalho Chehab > > drivers/media/usb/uvc/uvc_video.c | 10 ++ > 1 file changed, 2 insertions(+), 8 deletions(-) > > --- > > diff --git a/drivers/media/usb/uvc/uvc_video.c > b/drivers/media/usb/uvc/uvc_video.c > index 128c0a7826ce..47d93a938dde 100644 > --- a/drivers/media/usb/uvc/uvc_video.c > +++ b/drivers/media/usb/uvc/uvc_video.c > @@ -868,14 +868,8 @@ size_t uvc_video_stats_dump(struct uvc_streaming > *stream, char *buf, > struct timespec ts; > size_t count = 0; > > - ts.tv_sec = stream->stats.stream.stop_ts.tv_sec > - - stream->stats.stream.start_ts.tv_sec; > - ts.tv_nsec = stream->stats.stream.stop_ts.tv_nsec > -- stream->stats.stream.start_ts.tv_nsec; > - if (ts.tv_nsec < 0) { > - ts.tv_sec--; > - ts.tv_nsec += 10; > - } > + ts = timespec_sub(stream->stats.stream.stop_ts, > + stream->stats.stream.start_ts); > > /* Compute the SCR.SOF frequency estimate. At the nominal 1kHz SOF >* frequency this will not overflow before more than 1h. >
Re: support autofocus / autogain in libv4l2
On Tuesday 25 April 2017 13:23:30 Pavel Machek wrote: > Hi! > On Tue 2017-04-25 10:08:15, Pali Rohár wrote: > > On Tuesday 25 April 2017 10:05:38 Pavel Machek wrote: > > > > > It would be nice if more than one application could be accessing the > > > > > camera at the same time... (I.e. something graphical running preview > > > > > then using command line tool to grab a picture.) This one is > > > > > definitely not solveable inside a library... > > > > > > > > Someone once suggested to have something like pulseaudio for V4L. > > > > For such usage, a server would be interesting. Yet, I would code it > > > > in a way that applications using libv4l will talk with such daemon > > > > in a transparent way. > > > > > > Yes, we need something like pulseaudio for V4L. And yes, we should > > > make it transparent for applications using libv4l. > > > > IIRC there is already some effort in writing such "video" server which > > would support accessing more application into webcam video, like > > pulseaudio server for accessing more applications to microphone input. > > Do you have project name / url / something? Pinos (renamed from PulseVideo) https://blogs.gnome.org/uraeus/2015/06/30/introducing-pulse-video/ https://cgit.freedesktop.org/~wtay/pinos/ But from git history it looks like it is probably dead now... -- Pali Rohár pali.ro...@gmail.com
Re: support autofocus / autogain in libv4l2
Hi! On Tue 2017-04-25 10:08:15, Pali Rohár wrote: > On Tuesday 25 April 2017 10:05:38 Pavel Machek wrote: > > > > It would be nice if more than one application could be accessing the > > > > camera at the same time... (I.e. something graphical running preview > > > > then using command line tool to grab a picture.) This one is > > > > definitely not solveable inside a library... > > > > > > Someone once suggested to have something like pulseaudio for V4L. > > > For such usage, a server would be interesting. Yet, I would code it > > > in a way that applications using libv4l will talk with such daemon > > > in a transparent way. > > > > Yes, we need something like pulseaudio for V4L. And yes, we should > > make it transparent for applications using libv4l. > > IIRC there is already some effort in writing such "video" server which > would support accessing more application into webcam video, like > pulseaudio server for accessing more applications to microphone input. Do you have project name / url / something? Thanks, Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html signature.asc Description: Digital signature
Re: support autofocus / autogain in libv4l2
Hi! > > Umm, and it looks like libv4l can not automatically convert from > > GRBG10.. and if it could, going through RGB24 would probably be too > > slow on this device :-(. > > I suspect it shouldn't be hard to add support for GRBG10. It already > supports 8 and 16 bits Bayer formats, at lib/libv4lconvert/bayer.c > (to both RGB and YUV formats). Proper format for 16 bit bayer would be tricky, AFAICT. Anyway, does this look reasonable? It does not work too well here, since omap3isp driver does not seem to support ENUM_FMT. (And I get just half of the vertical image, strange. Interlacing?) Best regards, Pavel diff --git a/lib/libv4lconvert/libv4lconvert.c b/lib/libv4lconvert/libv4lconvert.c index d3d8936..2a469b2 100644 --- a/lib/libv4lconvert/libv4lconvert.c +++ b/lib/libv4lconvert/libv4lconvert.c @@ -123,6 +126,8 @@ static const struct v4lconvert_pixfmt supported_src_pixfmts[] = { { V4L2_PIX_FMT_SGRBG8, 8, 8, 8, 1 }, { V4L2_PIX_FMT_SRGGB8, 8, 8, 8, 1 }, { V4L2_PIX_FMT_STV0680, 8, 8, 8, 1 }, + + { V4L2_PIX_FMT_SGRBG10, 16, 8, 8, 1 }, /* compressed bayer */ { V4L2_PIX_FMT_SPCA561, 0, 9, 9, 1 }, { V4L2_PIX_FMT_SN9C10X, 0, 9, 9, 1 }, @@ -668,6 +680,7 @@ static int v4lconvert_processing_needs_double_conversion( case V4L2_PIX_FMT_SGRBG8: case V4L2_PIX_FMT_SRGGB8: case V4L2_PIX_FMT_STV0680: + case V4L2_PIX_FMT_SGRBG10: return 0; } switch (dest_pix_fmt) { @@ -694,6 +707,17 @@ unsigned char *v4lconvert_alloc_buffer(int needed, return *buf; } +static void v4lconvert_10to8(void *_src, unsigned char *dst, int width, int height) +{ + int i; + uint16_t *src = _src; + + printf("sizes %d x %d\n", width, height); + for (i=0; i> 2; + } +} + int v4lconvert_oom_error(struct v4lconvert_data *data) { V4LCONVERT_ERR("could not allocate memory\n"); @@ -867,7 +893,8 @@ static int v4lconvert_convert_pixfmt(struct v4lconvert_data *data, #endif case V4L2_PIX_FMT_SN9C2028: case V4L2_PIX_FMT_SQ905C: - case V4L2_PIX_FMT_STV0680: { /* Not compressed but needs some shuffling */ + case V4L2_PIX_FMT_STV0680: + case V4L2_PIX_FMT_SGRBG10: { /* Not compressed but needs some shuffling */ unsigned char *tmpbuf; struct v4l2_format tmpfmt = *fmt; @@ -877,6 +904,11 @@ static int v4lconvert_convert_pixfmt(struct v4lconvert_data *data, return v4lconvert_oom_error(data); switch (src_pix_fmt) { + case V4L2_PIX_FMT_SGRBG10: + v4lconvert_10to8(src, tmpbuf, width, height); + + tmpfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SGRBG8; + break; case V4L2_PIX_FMT_SPCA561: v4lconvert_decode_spca561(src, tmpbuf, width, height); tmpfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SGBRG8; @@ -949,6 +981,7 @@ static int v4lconvert_convert_pixfmt(struct v4lconvert_data *data, V4LCONVERT_ERR("short raw bayer data frame\n"); errno = EPIPE; result = -1; + /* FIXME: but then we proceed anyway?! */ } switch (dest_pix_fmt) { case V4L2_PIX_FMT_RGB24: -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html signature.asc Description: Digital signature
stih-cec: can you check if it works when there is no HPD?
Hi Benjamin, The CEC specification allows sending certain CEC messages even if there is no HPD signal. This is for displays that turn off the HPD when they go into standby or switch to another input, but still keep the CEC bus alive. Support for this was added to 4.12. But does your driver handle this? Sometimes when the HPD goes away the HDMI driver powers off the CEC part as well. I test this with a pulse-eight USB CEC adapter, since it is easy to setup this situation (just don't connect anything to the TV). Without that adapter it might be harder to test this. Regards, Hans
[PATCH] [RFC] em28xx: allow setting the eeprom bus at cards struct
Right now, all devices use bus 0 for eeprom. However, it seems that newer versions of Terratec H6 uses a different buffer for eeprom. So, add support to use a different I2C address for eeprom and add a new card ID for the board described at: http://forum.kodi.tv/showthread.php?tid=312902 PS.: This patch was meant to allow testing the device. It may be wrong or incomplete, as it doesn't attempt to set GPIOs. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-cards.c | 20 drivers/media/usb/em28xx/em28xx-i2c.c | 5 + drivers/media/usb/em28xx/em28xx.h | 5 - 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index a12b599a1fa2..b788ae0d5646 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -1193,6 +1193,23 @@ struct em28xx_board em28xx_boards[] = { .i2c_speed= EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, }, + [EM2884_BOARD_TERRATEC_H6] = { + .name = "Terratec Cinergy H6", + .has_dvb = 1, + .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS, +#if 0 + .tuner_type = TUNER_PHILIPS_TDA8290, + .tuner_addr = 0x41, + .dvb_gpio = terratec_h5_digital, /* FIXME: probably wrong */ + .tuner_gpio = terratec_h5_gpio, +#else + .tuner_type = TUNER_ABSENT, +#endif + .def_i2c_bus = 1, + .eeprom_i2c_bus = 1, + .i2c_speed= EM28XX_I2C_CLK_WAIT_ENABLE | + EM28XX_I2C_FREQ_400_KHZ, + }, [EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C] = { .name = "Hauppauge WinTV HVR 930C", .has_dvb = 1, @@ -2496,6 +2513,8 @@ struct usb_device_id em28xx_id_table[] = { .driver_info = EM2884_BOARD_TERRATEC_H5 }, { USB_DEVICE(0x0ccd, 0x10b6), /* H5 Rev. 3 */ .driver_info = EM2884_BOARD_TERRATEC_H5 }, + { USB_DEVICE(0x0ccd, 0x10b2), /* H6 */ + .driver_info = EM2884_BOARD_TERRATEC_H6 }, { USB_DEVICE(0x0ccd, 0x0084), .driver_info = EM2860_BOARD_TERRATEC_AV350 }, { USB_DEVICE(0x0ccd, 0x0096), @@ -2669,6 +2688,7 @@ static inline void em28xx_set_model(struct em28xx *dev) /* Should be initialized early, for I2C to work */ dev->def_i2c_bus = dev->board.def_i2c_bus; + dev->eeprom_i2c_bus = dev->board.eeprom_i2c_bus; } /* Wait until AC97_RESET reports the expected value reliably before proceeding. diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index 8c472d5adb50..df0ab4b6f18f 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -665,8 +665,6 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, *eedata = NULL; *eedata_len = 0; - /* EEPROM is always on i2c bus 0 on all known devices. */ - dev->i2c_client[bus].addr = 0xa0 >> 1; /* Check if board has eeprom */ @@ -975,8 +973,7 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, dev->i2c_client[bus] = em28xx_client_template; dev->i2c_client[bus].adapter = &dev->i2c_adap[bus]; - /* Up to now, all eeproms are at bus 0 */ - if (!bus) { + if (bus == dev->eeprom_i2c_bus) { retval = em28xx_i2c_eeprom(dev, bus, &dev->eedata, &dev->eedata_len); if ((retval < 0) && (retval != -ENODEV)) { dev_err(&dev->intf->dev, diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index e8d97d5ec161..a333ca954129 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -148,6 +148,7 @@ #define EM28178_BOARD_PLEX_PX_BCUD98 #define EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB 99 #define EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595 100 +#define EM2884_BOARD_TERRATEC_H6 101 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 @@ -440,7 +441,8 @@ struct em28xx_board { int vchannels; int tuner_type; int tuner_addr; - unsigned def_i2c_bus; /* Default I2C bus */ + unsigned def_i2c_bus; /* Default I2C bus */ + unsigned eeprom_i2c_bus;/* EEPROM I2C bus */ /* i2c flags */ unsigned int tda9887_conf; @@ -643,6 +645,7 @@ struct em28xx { unsigned char eeprom_addrwidth_16bit:1; unsigned def_i2c_bus; /* Default I2C bus */ + unsigned eeprom_i2c_bus;/* EEPROM I2C bus */ unsigned cur_i2c_bus; /* Current I2C bus */ struct rt_mutex i2c_bus_lock; -- 2.9.3
Re: [PATCH] ov2640: print error if devm_*_optional*() fails
On 25/04/17 11:45, Mauro Carvalho Chehab wrote: > devm_gpiod_get_optional() can return -ENOSYS if GPIOLIB is > disabled, causing probe to fail. Warn the user if this > happens. > > Acked-by: Sakari Ailus > Signed-off-by: Mauro Carvalho Chehab Acked-by: Hans Verkuil Thanks! Regards, Hans > --- > drivers/media/i2c/ov2640.c | 30 ++ > 1 file changed, 22 insertions(+), 8 deletions(-) > > diff --git a/drivers/media/i2c/ov2640.c b/drivers/media/i2c/ov2640.c > index 4a2ae24f8722..e6d0c1f64f0b 100644 > --- a/drivers/media/i2c/ov2640.c > +++ b/drivers/media/i2c/ov2640.c > @@ -765,17 +765,17 @@ static int ov2640_s_register(struct v4l2_subdev *sd, > > static int ov2640_s_power(struct v4l2_subdev *sd, int on) > { > - struct i2c_client *client = v4l2_get_subdevdata(sd); > - struct ov2640_priv *priv = to_ov2640(client); > - > #ifdef CONFIG_GPIOLIB > + struct i2c_client *client = v4l2_get_subdevdata(sd); > + struct ov2640_priv *priv = to_ov2640(client); > + > if (priv->pwdn_gpio) > gpiod_direction_output(priv->pwdn_gpio, !on); > if (on && priv->resetb_gpio) { > /* Active the resetb pin to perform a reset pulse */ > gpiod_direction_output(priv->resetb_gpio, 1); > usleep_range(3000, 5000); > - gpiod_direction_output(priv->resetb_gpio, 0); > + gpiod_set_value(priv->resetb_gpio, 0); > } > #endif > return 0; > @@ -1048,21 +1048,35 @@ static const struct v4l2_subdev_ops ov2640_subdev_ops > = { > static int ov2640_probe_dt(struct i2c_client *client, > struct ov2640_priv *priv) > { > + int ret; > + > /* Request the reset GPIO deasserted */ > priv->resetb_gpio = devm_gpiod_get_optional(&client->dev, "resetb", > GPIOD_OUT_LOW); > + > if (!priv->resetb_gpio) > dev_dbg(&client->dev, "resetb gpio is not assigned!\n"); > - else if (IS_ERR(priv->resetb_gpio)) > - return PTR_ERR(priv->resetb_gpio); > + > + ret = PTR_ERR_OR_ZERO(priv->resetb_gpio); > + if (ret && ret != -ENOSYS) { > + dev_dbg(&client->dev, > + "Error %d while getting resetb gpio\n", ret); > + return ret; > + } > > /* Request the power down GPIO asserted */ > priv->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "pwdn", > GPIOD_OUT_HIGH); > + > if (!priv->pwdn_gpio) > dev_dbg(&client->dev, "pwdn gpio is not assigned!\n"); > - else if (IS_ERR(priv->pwdn_gpio)) > - return PTR_ERR(priv->pwdn_gpio); > + > + ret = PTR_ERR_OR_ZERO(priv->pwdn_gpio); > + if (ret && ret != -ENOSYS) { > + dev_dbg(&client->dev, > + "Error %d while getting pwdn gpio\n", ret); > + return ret; > + } > > return 0; > } >
[PATCH] ov2640: print error if devm_*_optional*() fails
devm_gpiod_get_optional() can return -ENOSYS if GPIOLIB is disabled, causing probe to fail. Warn the user if this happens. Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov2640.c | 30 ++ 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/drivers/media/i2c/ov2640.c b/drivers/media/i2c/ov2640.c index 4a2ae24f8722..e6d0c1f64f0b 100644 --- a/drivers/media/i2c/ov2640.c +++ b/drivers/media/i2c/ov2640.c @@ -765,17 +765,17 @@ static int ov2640_s_register(struct v4l2_subdev *sd, static int ov2640_s_power(struct v4l2_subdev *sd, int on) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct ov2640_priv *priv = to_ov2640(client); - #ifdef CONFIG_GPIOLIB + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov2640_priv *priv = to_ov2640(client); + if (priv->pwdn_gpio) gpiod_direction_output(priv->pwdn_gpio, !on); if (on && priv->resetb_gpio) { /* Active the resetb pin to perform a reset pulse */ gpiod_direction_output(priv->resetb_gpio, 1); usleep_range(3000, 5000); - gpiod_direction_output(priv->resetb_gpio, 0); + gpiod_set_value(priv->resetb_gpio, 0); } #endif return 0; @@ -1048,21 +1048,35 @@ static const struct v4l2_subdev_ops ov2640_subdev_ops = { static int ov2640_probe_dt(struct i2c_client *client, struct ov2640_priv *priv) { + int ret; + /* Request the reset GPIO deasserted */ priv->resetb_gpio = devm_gpiod_get_optional(&client->dev, "resetb", GPIOD_OUT_LOW); + if (!priv->resetb_gpio) dev_dbg(&client->dev, "resetb gpio is not assigned!\n"); - else if (IS_ERR(priv->resetb_gpio)) - return PTR_ERR(priv->resetb_gpio); + + ret = PTR_ERR_OR_ZERO(priv->resetb_gpio); + if (ret && ret != -ENOSYS) { + dev_dbg(&client->dev, + "Error %d while getting resetb gpio\n", ret); + return ret; + } /* Request the power down GPIO asserted */ priv->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "pwdn", GPIOD_OUT_HIGH); + if (!priv->pwdn_gpio) dev_dbg(&client->dev, "pwdn gpio is not assigned!\n"); - else if (IS_ERR(priv->pwdn_gpio)) - return PTR_ERR(priv->pwdn_gpio); + + ret = PTR_ERR_OR_ZERO(priv->pwdn_gpio); + if (ret && ret != -ENOSYS) { + dev_dbg(&client->dev, + "Error %d while getting pwdn gpio\n", ret); + return ret; + } return 0; } -- 2.9.3
Re: [PATCH] [media] ov2640: make GPIOLIB an optional dependency
Hi Mauro, On Mon, Apr 24, 2017 at 11:05:29PM -0300, Mauro Carvalho Chehab wrote: > Em Mon, 24 Apr 2017 20:38:47 +0300 > Sakari Ailus escreveu: > > > Hi Mauro, > > > > On Mon, Apr 24, 2017 at 12:50:36PM -0300, Mauro Carvalho Chehab wrote: > > > Em Mon, 24 Apr 2017 17:44:02 +0300 > > > Sakari Ailus escreveu: > > > > > > > Hi Mauro and others, > > > > > > > > On Fri, Apr 21, 2017 at 11:39:42AM -0300, Mauro Carvalho Chehab wrote: > > > > > Em Fri, 21 Apr 2017 08:33:12 +0200 > > > > > Pavel Machek escreveu: > > > > > > > > > > > Hi! > > > > > > > > > > > > > > Better solution would be for VIDEO_EM28XX_V4L2 to depend on > > > > > > > > GPIOLIB, > > > > > > > > too, no? If not, should there be BUG_ON(priv->pwdn_gpio); > > > > > > > > BUG_ON(priv->resetb_gpio);? > > > > > > > > > > > > > > Pavel, > > > > > > > > > > > > > > The em28xx driver was added upstream several years the gpio > > > > > > > driver. > > > > > > > It controls GPIO using a different logic. It makes no sense to > > > > > > > make > > > > > > > it dependent on GPIOLIB, except if someone converts it to use it. > > > > > > > > > > > > > > > > > > > At least comment in the sourcecode...? Remove pwdn_gpio fields from > > > > > > structure in !GPIOLIB case, because otherwise they are trap for the > > > > > > programmer trying to understand what is going on? > > > > > > > > > > > > > > > Sorry, I answered to another e-mail thread related to it. I assumed > > > > > that it was c/c to linux-media, but it is, in fact a private e-mail. > > > > > > > > > > > > > I thought so, too! X-) > > > > > > > > > > > > > > I can see two alternatives: > > > > > > > > > > 1) Restore old behavior, assuming that all drivers that use OV2640 > > > > > will > > > > > have GPIOLIB enabled, with a patch like: > > > > > > > > > > diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig > > > > > index fd181c99ce11..4e834c36f7da 100644 > > > > > --- a/drivers/media/i2c/Kconfig > > > > > +++ b/drivers/media/i2c/Kconfig > > > > > @@ -521,6 +521,7 @@ config VIDEO_OV2640 > > > > > tristate "OmniVision OV2640 sensor support" > > > > > depends on VIDEO_V4L2 && I2C > > > > > depends on MEDIA_CAMERA_SUPPORT > > > > > + depends on GPIOLIB if OF > > > > > help > > > > > This is a Video4Linux2 sensor-level driver for the > > > > > OmniVision > > > > > OV2640 camera. > > > > > > > > > > However, I was told that some OF drivers don't actually define the > > > > > GPIO > > > > > pins. > > > > > > > > > > So, the other option is: > > > > > > > > > > 2) Make the logic smarter for OF, with this change: > > > > > > > > > > > > > > > diff --git a/drivers/media/i2c/ov2640.c b/drivers/media/i2c/ov2640.c > > > > > index 4a2ae24f8722..8855c81a9e1f 100644 > > > > > --- a/drivers/media/i2c/ov2640.c > > > > > +++ b/drivers/media/i2c/ov2640.c > > > > > @@ -1048,21 +1048,39 @@ static const struct v4l2_subdev_ops > > > > > ov2640_subdev_ops = { > > > > > static int ov2640_probe_dt(struct i2c_client *client, > > > > > struct ov2640_priv *priv) > > > > > { > > > > > + int ret; > > > > > + > > > > > /* Request the reset GPIO deasserted */ > > > > > priv->resetb_gpio = devm_gpiod_get_optional(&client->dev, > > > > > "resetb", > > > > > GPIOD_OUT_LOW); > > > > > - if (!priv->resetb_gpio) > > > > > + if (!priv->resetb_gpio) { > > > > > dev_dbg(&client->dev, "resetb gpio is not assigned!\n"); > > > > > - else if (IS_ERR(priv->resetb_gpio)) > > > > > - return PTR_ERR(priv->resetb_gpio); > > > > > + } else { > > > > > + ret = PTR_ERR(priv->resetb_gpio); > > > > > + > > > > > + if (ret && ret != -ENOSYS) { > > > > > + dev_dbg(&client->dev, > > > > > + "Error %d while getting resetb gpio\n", > > > > > + ret); > > > > > + return ret; > > > > > + } > > > > > + } > > > > > > > > This would work. I just wish it'd look nicer. :-) > > > > > > > > How about something like: > > > > > > > > ret = PTR_ERR(priv->reset_gpio); > > > > if (!priv->reset_gpio) { > > > > dev_dbg("reset gpio is not assigned"); > > > > } else if (ret != -ENOSYS) { > > > > dev_dbg("error %d while getting reset gpio, ret); > > > > > > It still need to test if ret == 0, as otherwise it will do the wrong thing > > > here. > > > > ret won't be zero here, that was checked above. You could check for just ret > > though, it'd be easier to read that way. > > > > > > > > > > > I guess the patch below does the trick and it is not ugly :-) > > > > > > > > > > return ret; > > > > } > > > > > > > > I prefer this option as it's not dependent on the system firmware type. > > > > > > > > > > Thanks, > > > Mauro > > > > > > [PATCH] ov2640: print error if dev
Re: [PATCH v3 0/7] V4L2 fwnode support
On 10/04/17 15:02, Sakari Ailus wrote: > Hello everyone, > > This patchset adds support for fwnode to V4L2. Besides OF, also ACPI based > systems can be supported this way. By using V4L2 fwnode, the individual > drivers do not need to be aware of the underlying firmware implementation. > The patchset also removes specific V4L2 OF support and converts the > affected drivers to use V4L2 fwnode. Successfully tested with my Atmel sama5d3 board + ov2640 sensor. Tested-by: Hans Verkuil Regards, Hans > > The patchset depends on another patchset here: > > http://www.spinics.net/lists/linux-acpi/msg72973.html> > > A git tree with the dependencies can be found here: > > https://git.linuxtv.org/sailus/media_tree.git/log/?h=v4l2-acpi-merge> > > v1 of the set can be found here: > > http://www.spinics.net/lists/linux-media/msg111073.html> > > and v2 here: > > http://www.spinics.net/lists/linux-media/msg114110.html> > > changes since v2: > > - Use EXPORT_SYMBOL_GPL() instead of EXPORT_SYMBOL(). > > - Alphabetically order the topics under V4L2 core kAPI documentation. > > - Prefer "fwnode" variable name for struct fwnode_handle pointers instead > of "fwn". Similarly, use "vep" for struct v4l2_fwnode_endpoint instead > of "vfwn". > > - Convert existing users of OF matching to fwnode matching. > > - Remove OF matching support as well as compatibility between OF and > fwnode matching. > > - Use of_node_cmp() to determine whether two nodes match in case both of > them are OF nodes. There is thus no functional difference between > existing OF matching in v1. > > - Continue to use struct device_node.full_name on fwnodes that are known > to be OF nodes instead of omitting such debug information. Drivers that > can actually use fwnode need a new interface to provide this in fwnode > framework. This is out of scope of the patchset. > > - Remove linux/of.h header inclusion in > drivers/media/v4l2-core/v4l2-flash-led-class.c. > > - Improved line wrapping primarily in > drivers/media/v4l2-core/v4l2-fwnode.c. > > - Rewrap KernelDoc documentation for V4L2 fwnode API up to 80 characters > per line (new patch). > > - Fix KernelDoc documentation, there were a few locations where the > argument had been changed but the documentation was not updated > accordingly. > > - Fix punctuation and wording in V4L2 fwnode documentation. > > - Drop patch "v4l: media/drv-intf/soc_mediabus.h: include dependent header > file". It is no longer needed. > > - Fix obtaining port parent in v4l2_fwnode_parse_link() on ACPI. > > - Include newly OF-supported atmel-isi to V4L2 OF -> fwnode conversion. > > - Add that the v4l2-fwnode.c has origins in v4l2-of.c to the commit > message and the file header. > > changes since v1: > > - Use existing dev_fwnode() instead of device_fwnode_handle() added by the > ACPI graph patchset, > > - Fix too long line of ^'s in ReST documentation and > > - Drop the patch rearranging the header files. It'd better go in > separately, if at all. > > Sakari Ailus (7): > v4l: fwnode: Support generic fwnode for parsing standardised > properties > v4l: async: Add fwnode match support > v4l: flash led class: Use fwnode_handle instead of device_node in init > v4l: Switch from V4L2 OF not V4L2 fwnode API > docs-rst: media: Sort topic list alphabetically > docs-rst: media: Switch documentation to V4L2 fwnode API > v4l: Remove V4L2 OF framework in favour of V4L2 fwnode framework > > Documentation/media/kapi/v4l2-core.rst | 20 +- > Documentation/media/kapi/v4l2-fwnode.rst | 3 + > Documentation/media/kapi/v4l2-of.rst | 3 - > drivers/leds/leds-aat1290.c| 5 +- > drivers/leds/leds-max77693.c | 5 +- > drivers/media/i2c/Kconfig | 9 + > drivers/media/i2c/adv7604.c| 7 +- > drivers/media/i2c/mt9v032.c| 7 +- > drivers/media/i2c/ov2659.c | 8 +- > drivers/media/i2c/s5c73m3/s5c73m3-core.c | 7 +- > drivers/media/i2c/s5k5baf.c| 6 +- > drivers/media/i2c/smiapp/Kconfig | 1 + > drivers/media/i2c/smiapp/smiapp-core.c | 29 ++- > drivers/media/i2c/tc358743.c | 11 +- > drivers/media/i2c/tvp514x.c| 6 +- > drivers/media/i2c/tvp5150.c| 7 +- > drivers/media/i2c/tvp7002.c| 6 +- > drivers/media/platform/Kconfig | 3 + > drivers/media/platform/am437x/Kconfig | 1 + > drivers/media/platform/am437x/am437x-vpfe.c| 15 +- > drivers/media/platform/atmel/Kconfig | 1 + > drivers/media/platform/atmel/atmel-isc.c | 13 +- > drivers/media/platform/exynos4-is/Kconfig | 2 + > drivers/media/platform/exynos4-is/media-dev.c | 13 +- > drivers/media/platform/exynos4-is/mipi-csis.c | 6 +- > drivers/media/platform/
Re: support autofocus / autogain in libv4l2
Hi! > > > Please don't add a new application under lib/. It is fine if you want > > > some testing application, if the ones there aren't enough, but please > > > place it under contrib/test/. > > > > > > You should likely take a look at v4l2grab first, as it could have > > > almost everything you would need. > > > > I really need some kind of video output. v4l2grab is not useful > > there. v4l2gl might be, but I don't think I have enough dependencies. > > Well, you could use some app to show the snaps that v4l2grab takes. That would be too slow :-(. > Yeah, compiling v4l2gl on N9 can indeed be complex. I suspect that it > shouldn't hard to compile xawtv there (probably disabling some optional > features). I do have mplayer working, but that one is not linked against libv4l2 :-(. > > Umm, and it looks like libv4l can not automatically convert from > > GRBG10.. and if it could, going through RGB24 would probably be too > > slow on this device :-(. > > I suspect it shouldn't be hard to add support for GRBG10. It already > supports 8 and 16 bits Bayer formats, at lib/libv4lconvert/bayer.c > (to both RGB and YUV formats). Is 16bit bayer a recent development? I can't see it in commit 374806e868f5a7a48ecffde4c6a1abfcfa5ccd65 Author: Hans Verkuil Date: Fri Apr 22 09:31:57 2016 +0200 > > Is there an example using autogain/autowhitebalance from > > libv4lconvert? > > Well, if you plug a USB camera without those controls, it should > automatically expose controls for it, as if the device had such > controls. And settings are persistent, so I can enable autogain, then lauch something like xawtv, and it will automatically get autogain? Ok, good. Regards, Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html signature.asc Description: Digital signature
Re: support autofocus / autogain in libv4l2
On Tuesday 25 April 2017 10:05:38 Pavel Machek wrote: > > > It would be nice if more than one application could be accessing the > > > camera at the same time... (I.e. something graphical running preview > > > then using command line tool to grab a picture.) This one is > > > definitely not solveable inside a library... > > > > Someone once suggested to have something like pulseaudio for V4L. > > For such usage, a server would be interesting. Yet, I would code it > > in a way that applications using libv4l will talk with such daemon > > in a transparent way. > > Yes, we need something like pulseaudio for V4L. And yes, we should > make it transparent for applications using libv4l. IIRC there is already some effort in writing such "video" server which would support accessing more application into webcam video, like pulseaudio server for accessing more applications to microphone input. -- Pali Rohár pali.ro...@gmail.com
Re: support autofocus / autogain in libv4l2
Hi! > > > > For focus to be useful, we need autofocus implmented > > > > somewhere. Unfortunately, v4l framework does not seem to provide good > > > > place where to put autofocus. I believe, long-term, we'll need some > > > > kind of "video server" providing this kind of services. > > > > > > > > Anyway, we probably don't want autofocus in kernel (even through some > > > > cameras do it in hardware), and we probably don't want autofocus in > > > > each and every user application. > > > > > > > > So what remains is libv4l2. > > > > > > IMO, the best place for autofocus is at libv4l2. Putting it on a > > > separate "video server" application looks really weird for me. > > > > Well... let me see. libraries are quite limited -- it is hard to open > > files, or use threads/have custom main loop. It may be useful to > > switch resolutions -- do autofocus/autogain at lower resolution, then > > switch to high one for taking picture. It would be good to have that > > in "system" code, but I'm not at all sure libv4l2 design will allow > > that. > > I don't see why it would be hard to open files or have threads inside > a library. There are several libraries that do that already, specially > the ones designed to be used on multimidia apps. Well, fd's are hard, because application can do fork() and now interesting stuff happens. Threads are tricky, because now you have locking etc. libv4l2 is designed to be LD_PRELOADED. That is not really feasible with "complex" library. > > It would be good if application could say "render live camera into > > this window" and only care about user interface, then say "give me a > > high resolution jpeg". But that would require main loop in the > > library... > > Nothing prevents writing an upper layer on the top of libv4l in > order to provide such kind of functions. Agreed. > > It would be nice if more than one application could be accessing the > > camera at the same time... (I.e. something graphical running preview > > then using command line tool to grab a picture.) This one is > > definitely not solveable inside a library... > > Someone once suggested to have something like pulseaudio for V4L. > For such usage, a server would be interesting. Yet, I would code it > in a way that applications using libv4l will talk with such daemon > in a transparent way. Yes, we need something like pulseaudio for V4L. And yes, we should make it transparent for applications using libv4l. Regards, Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html signature.asc Description: Digital signature
Re: [PATCH] rc-core: use the full 32 bits for NEC scancodes
April 24, 2017 5:58 PM, "Sean Young" wrote: > On Tue, Apr 18, 2017 at 05:50:27PM +0200, David Härdeman wrote: >> Using the full 32 bits for all kinds of NEC scancodes simplifies rc-core >> and the nec decoder without any loss of functionality. At the same time >> it ensures that scancodes for NEC16/NEC24/NEC32 do not overlap and >> removes lots of duplication (as you can see from the patch, the same NEC >> disambiguation logic is contained in several different drivers). >> >> Using NEC32 also removes ambiguity. For example, consider these two NEC >> messages: >> NEC16 message to address 0x05, command 0x03 >> NEC24 message to address 0x0005, command 0x03 >> >> They'll both have scancode 0x0503, and there's no way to tell which >> message was received. > > More precisely, there is no way to tell which protocol variant it was sent > with. Oh, but there is. The driver/rc-core will know. It's just that userspace cannot ever know. > With the Sony and rc6 protocols, you can also get the same scancode from > different protocol variants. I think the right solution is to pass the > protocol > variant to user space (and the keymap mapper). Yes, I'm working on refreshing my patches to add a new EVIOCGKEYCODE_V2/EVIOCSKEYCODE_V2 ioctl which includes the protocol. And actually, those patches are greatly simplified by only using NEC32. > This also solves some other problems, e.g. rc6_6a_20:0x75460 is also decoded > by the sony protocol decoder (as scancode 0). I know. And it also makes it possible to make /sys/class/rc/rc0/protocols fully automatic. And we could theoretically also refuse to set unsupported protocols in the keytable (not sure yet if that's something we should do). >> In order to maintain backwards compatibility, some heuristics are added >> in rc-main.c to convert scancodes to NEC32 as necessary when userspace >> adds entries to the keytable using the regular input ioctls. > > This is where it falls apart. In the patch below, you guess the protocol > variant from the scancode value. By your own example above, nec24 with > an address of 0x0005 would be not be possible in a keymap since it would > guessed as nec16 (see to_nec32() below) and expanded to 0x05fb03fc. An > actual nec24 would be 0x000503fc. It's not 100% bulletproof. There's no way to fix this issue in a 100% backwards compatible manner. But the future EVIOCGKEYCODE_V2/EVIOCSKEYCODE_V2 ioctl would make the heuristics unnecessary. >> These >> heuristics are essentially the same as the ones that are currently in >> drivers/media/rc/img-ir/img-ir-nec.c (which are rendered unecessary >> with this patch). > > Rendered unnecessary since you moved it to core code. You've changed the > img-ir filter functionality in the process, breaking userspace. I doubt it can be fixed in a way which doesn't involve some userspace changes. But the breakage can be minimized. > This is the scancode filter in the img-ir which admittedly isn't great, > so I don't think we should introduce it elsewhere. What would be much > better would be if we could specify the protocol variants for ir decoding, > rather than just "nec" or "sony" or "rc6". I'm not sure how to do this > without breaking userspace though. I think the best way is by introducing the new ioctls. Anyway, I'll try to post the whole patchset later today, then it should be clearer why this is a good change. >> The reason this has to be done now is that the newer sysfs wakefilter API >> will expose the difference between the NEC protocols to userspace for no >> good reason and once exposed, it will be much more difficult to change the >> logic. >> >> Signed-off-by: David Härdeman >> --- >> drivers/media/rc/igorplugusb.c | 4 + >> drivers/media/rc/img-ir/img-ir-nec.c | 92 +++--- >> drivers/media/rc/ir-nec-decoder.c | 63 --- >> drivers/media/rc/rc-main.c | 74 --- >> drivers/media/rc/winbond-cir.c | 32 +--- >> 5 files changed, 89 insertions(+), 176 deletions(-) >> >> diff --git a/drivers/media/pci/cx88/cx88-input.c >> b/drivers/media/pci/cx88/cx88-input.c >> index 01f2e472a2a0..61c46763ac97 100644 >> --- a/drivers/media/pci/cx88/cx88-input.c >> +++ b/drivers/media/pci/cx88/cx88-input.c >> @@ -146,7 +146,7 @@ static void cx88_ir_handle_key(struct cx88_IR *ir) >> scancode = RC_SCANCODE_NECX(addr, cmd); >> >> if (0 == (gpio & ir->mask_keyup)) >> - rc_keydown_notimeout(ir->dev, RC_TYPE_NECX, scancode, >> + rc_keydown_notimeout(ir->dev, RC_TYPE_NEC, scancode, >> 0); >> else >> rc_keyup(ir->dev); >> @@ -348,7 +348,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev >> *pci) >> * 002-T mini RC, provided with newer PV hardware >> */ >> ir_codes = RC_MAP_PIXELVIEW_MK12; >> - rc_type = RC_BIT_NECX; >> + rc_type = RC_BIT_NEC; >> ir->gpio_addr = MO_GP1_IO; >> ir->mask_keyup = 0x80; >> ir->polling = 10; /* ms */ >> diff --git a/drivers/media/pci/saa7134/saa7134-input.c >> b/drivers/media/pci/saa7134/sa
Re: [PATCH] rc-core: use the full 32 bits for NEC scancodes in wakefilters
April 24, 2017 6:02 PM, "Sean Young" wrote: > On Tue, Apr 18, 2017 at 10:31:04PM +0200, David Härdeman wrote: > >> The new sysfs wakefilter API will expose the difference between the NEC >> protocols to userspace for no good reason and once exposed, it will be much >> more difficult to change the logic. >> >> By only allowing full NEC32 scancodes to be set, any heuristics in the kernel >> can be avoided. > > No heuristics are being removed in this patch or the other patch for nec32, > if anything it gets worse. It avoids having to add heuristics in the future if we move to always use nec32 in the kernel<->userspace API. That, IMHO, is the only sane default. Explicitly differentiating between NEC16/24/32 in the API provides no benefits whatsoever. > This patch depends on the other patch, which needs work. It's a minimal version of the other patch, not dependent on it. It just makes sure that the wakeup logic only supports nec32 before that API becomes official. >> This is the minimalistic version of the full NEC32 patch posted here: >> http://www.spinics.net/lists/linux-media/msg114603.html >> >> Signed-off-by: David Härdeman >> --- >> drivers/media/rc/rc-main.c | 17 - >> drivers/media/rc/winbond-cir.c | 32 ++-- >> 2 files changed, 6 insertions(+), 43 deletions(-) >> >> diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c >> index 6ec73357fa47..8a2a2973e718 100644 >> --- a/drivers/media/rc/rc-main.c >> +++ b/drivers/media/rc/rc-main.c >> @@ -742,8 +742,6 @@ static int rc_validate_filter(struct rc_dev *dev, >> [RC_TYPE_SONY15] = 0xff007f, >> [RC_TYPE_SONY20] = 0x1fff7f, >> [RC_TYPE_JVC] = 0x, >> - [RC_TYPE_NEC] = 0x, >> - [RC_TYPE_NECX] = 0xff, >> [RC_TYPE_NEC32] = 0x, >> [RC_TYPE_SANYO] = 0x1f, >> [RC_TYPE_MCIR2_KBD] = 0x, >> @@ -759,14 +757,9 @@ static int rc_validate_filter(struct rc_dev *dev, >> enum rc_type protocol = dev->wakeup_protocol; >> >> switch (protocol) { >> + case RC_TYPE_NEC: >> case RC_TYPE_NECX: >> - if s >> 16) ^ ~(s >> 8)) & 0xff) == 0) >> - return -EINVAL; >> - break; >> - case RC_TYPE_NEC32: >> - if s >> 24) ^ ~(s >> 16)) & 0xff) == 0) >> - return -EINVAL; >> - break; >> + return -EINVAL; >> case RC_TYPE_RC6_MCE: >> if ((s & 0x) != 0x800f) >> return -EINVAL; >> @@ -1330,7 +1323,7 @@ static ssize_t store_filter(struct device *device, >> /* >> * This is the list of all variants of all protocols, which is used by >> * the wakeup_protocols sysfs entry. In the protocols sysfs entry some >> - * some protocols are grouped together (e.g. nec = nec + necx + nec32). >> + * some protocols are grouped together. >> * >> * For wakeup we need to know the exact protocol variant so the hardware >> * can be programmed exactly what to expect. >> @@ -1345,9 +1338,7 @@ static const char * const proto_variant_names[] = { >> [RC_TYPE_SONY12] = "sony-12", >> [RC_TYPE_SONY15] = "sony-15", >> [RC_TYPE_SONY20] = "sony-20", >> - [RC_TYPE_NEC] = "nec", >> - [RC_TYPE_NECX] = "nec-x", >> - [RC_TYPE_NEC32] = "nec-32", >> + [RC_TYPE_NEC32] = "nec", >> [RC_TYPE_SANYO] = "sanyo", >> [RC_TYPE_MCIR2_KBD] = "mcir2-kbd", >> [RC_TYPE_MCIR2_MSE] = "mcir2-mse", >> diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c >> index 5a4d4a611197..6ef0e7232356 100644 >> --- a/drivers/media/rc/winbond-cir.c >> +++ b/drivers/media/rc/winbond-cir.c >> @@ -714,34 +714,6 @@ wbcir_shutdown(struct pnp_dev *device) >> proto = IR_PROTOCOL_RC5; >> break; >> >> - case RC_TYPE_NEC: >> - mask[1] = bitrev8(mask_sc); >> - mask[0] = mask[1]; >> - mask[3] = bitrev8(mask_sc >> 8); >> - mask[2] = mask[3]; >> - >> - match[1] = bitrev8(wake_sc); >> - match[0] = ~match[1]; >> - match[3] = bitrev8(wake_sc >> 8); >> - match[2] = ~match[3]; >> - >> - proto = IR_PROTOCOL_NEC; >> - break; >> - >> - case RC_TYPE_NECX: >> - mask[1] = bitrev8(mask_sc); >> - mask[0] = mask[1]; >> - mask[2] = bitrev8(mask_sc >> 8); >> - mask[3] = bitrev8(mask_sc >> 16); >> - >> - match[1] = bitrev8(wake_sc); >> - match[0] = ~match[1]; >> - match[2] = bitrev8(wake_sc >> 8); >> - match[3] = bitrev8(wake_sc >> 16); >> - >> - proto = IR_PROTOCOL_NEC; >> - break; >> - >> case RC_TYPE_NEC32: >> mask[0] = bitrev8(mask_sc); >> mask[1] = bitrev8(mask_sc >> 8); >> @@ -1087,8 +1059,8 @@ wbcir_probe(struct pnp_dev *device, const struct >> pnp_device_id *dev_id) >> data->dev->max_timeout = 10 * IR_DEFAULT_TIMEOUT; >> data->dev->rx_resolution = US_TO_NS(2); >> data->dev->allowed_protocols = RC_BIT_ALL_IR_DECODER; >> - data->dev->allowed_wakeup_protocols = RC_BIT_NEC | RC_BIT_NECX | >> - RC_BIT_NEC32 | RC_BIT_RC5 | RC_BIT_RC6_0 | >> + data->dev->allowed_wakeup_protocols = >> + RC_BIT_NEC | RC_BIT_RC5 | RC_BIT_RC6_0 | >> RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | >> RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE; >> data->dev->wakeup_protocol = RC_TYPE_RC6_MCE;
[PATCH] media: rc: meson-ir: store raw event without processing
From: Jonas Karlman This patch fixes meson-it driver by storing event without processing to avoid losing key pressed events when system is loaded and events are occurring too fast. This issue was reported at [1] [1] https://github.com/LibreELEC/linux-amlogic/pull/42 Signed-off-by: Jonas Karlman Signed-off-by: Neil Armstrong --- drivers/media/rc/meson-ir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c index 5576dbd..42ae2ec 100644 --- a/drivers/media/rc/meson-ir.c +++ b/drivers/media/rc/meson-ir.c @@ -97,7 +97,7 @@ static irqreturn_t meson_ir_irq(int irqno, void *dev_id) rawir.pulse = !!(readl(ir->reg + IR_DEC_STATUS) & STATUS_IR_DEC_IN); - ir_raw_event_store_with_filter(ir->rc, &rawir); + ir_raw_event_store(ir->rc, &rawir); ir_raw_event_handle(ir->rc); spin_unlock(&ir->lock); -- 1.9.1
[PATCH] media: rc: meson-ir: switch config to NEC decoding on shutdown
From: Alex Deryskyba On the Amlogic SoCs, the bootloader firmware can handle the IR hardware in order to Wake up or Power back the system when in suspend on shutdown mode. This patch switches the hardware configuration in a state usable by the firmware to permit powering the system back. Some vendor bootloader firmware were modified to switch to this configuration but it may not be the case for all available products. This patch was originally posted at [1]. [1] https://github.com/LibreELEC/linux-amlogic/pull/27 Signed-off-by: Alex Deryskyba Signed-off-by: Neil Armstrong --- drivers/media/rc/meson-ir.c | 27 +++ 1 file changed, 27 insertions(+) diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c index 42ae2ec..0632f6a 100644 --- a/drivers/media/rc/meson-ir.c +++ b/drivers/media/rc/meson-ir.c @@ -211,6 +211,32 @@ static int meson_ir_remove(struct platform_device *pdev) return 0; } +static void meson_ir_shutdown(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; + struct meson_ir *ir = platform_get_drvdata(pdev); + unsigned long flags; + + spin_lock_irqsave(&ir->lock, flags); + + /* +* Set operation mode to NEC/hardware decoding to give +* bootloader a chance to power the system back on +*/ + if (of_device_is_compatible(node, "amlogic,meson6-ir")) + meson_ir_set_mask(ir, IR_DEC_REG1, REG1_MODE_MASK, + DECODE_MODE_NEC << REG1_MODE_SHIFT); + else + meson_ir_set_mask(ir, IR_DEC_REG2, REG2_MODE_MASK, + DECODE_MODE_NEC << REG2_MODE_SHIFT); + + /* Set rate to default value */ + meson_ir_set_mask(ir, IR_DEC_REG0, REG0_RATE_MASK, 0x13); + + spin_unlock_irqrestore(&ir->lock, flags); +} + static const struct of_device_id meson_ir_match[] = { { .compatible = "amlogic,meson6-ir" }, { .compatible = "amlogic,meson8b-ir" }, @@ -222,6 +248,7 @@ static int meson_ir_remove(struct platform_device *pdev) static struct platform_driver meson_ir_driver = { .probe = meson_ir_probe, .remove = meson_ir_remove, + .shutdown = meson_ir_shutdown, .driver = { .name = DRIVER_NAME, .of_match_table = meson_ir_match, -- 1.9.1
[PATCH] ARM64: defconfig: enable IR core, decoders and Meson IR device
This patch enables the MEDIA Infrared RC Decoders and Meson Infrared decoder for ARM64 defconfig. These drivers are selected as modules by default. Signed-off-by: Neil Armstrong --- arch/arm64/configs/defconfig | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index c021aefa..59c400f 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -321,6 +321,11 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_MEDIA_ANALOG_TV_SUPPORT=y CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y CONFIG_MEDIA_CONTROLLER=y +CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_RC_CORE=y +CONFIG_RC_DEVICES=y +CONFIG_RC_DECODERS=y +CONFIG_IR_MESON=m CONFIG_VIDEO_V4L2_SUBDEV_API=y # CONFIG_DVB_NET is not set CONFIG_V4L_MEM2MEM_DRIVERS=y -- 1.9.1