Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  imx8-isi-hw.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2019-2020 NXP
 */


#include <linux/delay.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/types.h>

#include "imx8-isi-core.h"
#include "imx8-isi-regs.h"

#define ISI_DOWNSCALE_THRESHOLD  0x4000

static inline u32 mxc_isi_read(struct mxc_isi_pipe *pipe, u32 reg)
{
 return readl(pipe->regs + reg);
}

static inline void mxc_isi_write(struct mxc_isi_pipe *pipe, u32 reg, u32 val)
{
 writel(val, pipe->regs + reg);
}

/* -----------------------------------------------------------------------------
 * Buffers & M2M operation
 */


void mxc_isi_channel_set_inbuf(struct mxc_isi_pipe *pipe, dma_addr_t dma_addr)
{
 mxc_isi_write(pipe, CHNL_IN_BUF_ADDR, lower_32_bits(dma_addr));
 if (pipe->isi->pdata->has_36bit_dma)
  mxc_isi_write(pipe, CHNL_IN_BUF_XTND_ADDR,
         upper_32_bits(dma_addr));
}

void mxc_isi_channel_set_outbuf(struct mxc_isi_pipe *pipe,
    const dma_addr_t dma_addrs[3],
    enum mxc_isi_buf_id buf_id)
{
 int val;

 val = mxc_isi_read(pipe, CHNL_OUT_BUF_CTRL);

 if (buf_id == MXC_ISI_BUF1) {
  mxc_isi_write(pipe, CHNL_OUT_BUF1_ADDR_Y,
         lower_32_bits(dma_addrs[0]));
  mxc_isi_write(pipe, CHNL_OUT_BUF1_ADDR_U,
         lower_32_bits(dma_addrs[1]));
  mxc_isi_write(pipe, CHNL_OUT_BUF1_ADDR_V,
         lower_32_bits(dma_addrs[2]));
  if (pipe->isi->pdata->has_36bit_dma) {
   mxc_isi_write(pipe, CHNL_Y_BUF1_XTND_ADDR,
          upper_32_bits(dma_addrs[0]));
   mxc_isi_write(pipe, CHNL_U_BUF1_XTND_ADDR,
          upper_32_bits(dma_addrs[1]));
   mxc_isi_write(pipe, CHNL_V_BUF1_XTND_ADDR,
          upper_32_bits(dma_addrs[2]));
  }
  val ^= CHNL_OUT_BUF_CTRL_LOAD_BUF1_ADDR;
 } else  {
  mxc_isi_write(pipe, CHNL_OUT_BUF2_ADDR_Y,
         lower_32_bits(dma_addrs[0]));
  mxc_isi_write(pipe, CHNL_OUT_BUF2_ADDR_U,
         lower_32_bits(dma_addrs[1]));
  mxc_isi_write(pipe, CHNL_OUT_BUF2_ADDR_V,
         lower_32_bits(dma_addrs[2]));
  if (pipe->isi->pdata->has_36bit_dma) {
   mxc_isi_write(pipe, CHNL_Y_BUF2_XTND_ADDR,
          upper_32_bits(dma_addrs[0]));
   mxc_isi_write(pipe, CHNL_U_BUF2_XTND_ADDR,
          upper_32_bits(dma_addrs[1]));
   mxc_isi_write(pipe, CHNL_V_BUF2_XTND_ADDR,
          upper_32_bits(dma_addrs[2]));
  }
  val ^= CHNL_OUT_BUF_CTRL_LOAD_BUF2_ADDR;
 }

 mxc_isi_write(pipe, CHNL_OUT_BUF_CTRL, val);
}

void mxc_isi_channel_m2m_start(struct mxc_isi_pipe *pipe)
{
 u32 val;

 val = mxc_isi_read(pipe, CHNL_MEM_RD_CTRL);
 val &= ~CHNL_MEM_RD_CTRL_READ_MEM;
 mxc_isi_write(pipe, CHNL_MEM_RD_CTRL, val);

 fsleep(300);

 val |= CHNL_MEM_RD_CTRL_READ_MEM;
 mxc_isi_write(pipe, CHNL_MEM_RD_CTRL, val);
}

/* -----------------------------------------------------------------------------
 * Pipeline configuration
 */


static u32 mxc_isi_channel_scaling_ratio(unsigned int from, unsigned int to,
      u32 *dec)
{
 unsigned int ratio = from / to;

 if (ratio < 2)
  *dec = 1;
 else if (ratio < 4)
  *dec = 2;
 else if (ratio < 8)
  *dec = 4;
 else
  *dec = 8;

 return min_t(u32, from * 0x1000 / (to * *dec), ISI_DOWNSCALE_THRESHOLD);
}

static void mxc_isi_channel_set_scaling(struct mxc_isi_pipe *pipe,
     enum mxc_isi_encoding encoding,
     const struct v4l2_area *in_size,
     const struct v4l2_area *out_size,
     bool *bypass)
{
 u32 xscale, yscale;
 u32 decx, decy;
 u32 val;

 dev_dbg(pipe->isi->dev, "input %ux%u, output %ux%u\n",
  in_size->width, in_size->height,
  out_size->width, out_size->height);

 xscale = mxc_isi_channel_scaling_ratio(in_size->width, out_size->width,
            &decx);
 yscale = mxc_isi_channel_scaling_ratio(in_size->height, out_size->height,
            &decy);

 val = mxc_isi_read(pipe, CHNL_IMG_CTRL);
 val &= ~(CHNL_IMG_CTRL_DEC_X_MASK | CHNL_IMG_CTRL_DEC_Y_MASK |
   CHNL_IMG_CTRL_YCBCR_MODE);

 val |= CHNL_IMG_CTRL_DEC_X(ilog2(decx))
     |  CHNL_IMG_CTRL_DEC_Y(ilog2(decy));

 /*
 * Contrary to what the documentation states, YCBCR_MODE does not
 * control conversion between YCbCr and RGB, but whether the scaler
 * operates in YUV mode or in RGB mode. It must be set when the scaler
 * input is YUV.
 */

 if (encoding == MXC_ISI_ENC_YUV)
  val |= CHNL_IMG_CTRL_YCBCR_MODE;

 mxc_isi_write(pipe, CHNL_IMG_CTRL, val);

 mxc_isi_write(pipe, CHNL_SCALE_FACTOR,
        CHNL_SCALE_FACTOR_Y_SCALE(yscale) |
        CHNL_SCALE_FACTOR_X_SCALE(xscale));

 mxc_isi_write(pipe, CHNL_SCALE_OFFSET, 0);

 mxc_isi_write(pipe, CHNL_SCL_IMG_CFG,
        CHNL_SCL_IMG_CFG_HEIGHT(out_size->height) |
        CHNL_SCL_IMG_CFG_WIDTH(out_size->width));

 *bypass = in_size->height == out_size->height &&
    in_size->width == out_size->width;
}

static void mxc_isi_channel_set_crop(struct mxc_isi_pipe *pipe,
         const struct v4l2_area *src,
         const struct v4l2_rect *dst)
{
 u32 val, val0, val1;

 val = mxc_isi_read(pipe, CHNL_IMG_CTRL);
 val &= ~CHNL_IMG_CTRL_CROP_EN;

 if (src->height == dst->height && src->width == dst->width) {
  mxc_isi_write(pipe, CHNL_IMG_CTRL, val);
  return;
 }

 val |= CHNL_IMG_CTRL_CROP_EN;
 val0 = CHNL_CROP_ULC_X(dst->left) | CHNL_CROP_ULC_Y(dst->top);
 val1 = CHNL_CROP_LRC_X(dst->width) | CHNL_CROP_LRC_Y(dst->height);

 mxc_isi_write(pipe, CHNL_CROP_ULC, val0);
 mxc_isi_write(pipe, CHNL_CROP_LRC, val1 + val0);
 mxc_isi_write(pipe, CHNL_IMG_CTRL, val);
}

/*
 * A2,A1,      B1, A3,     B3, B2,
 * C2, C1,     D1, C3,     D3, D2
 */

static const u32 mxc_isi_yuv2rgb_coeffs[6] = {
 /* YUV -> RGB */
 0x0000012a, 0x012a0198, 0x0730079c,
 0x0204012a, 0x01f00000, 0x01800180
};

static const u32 mxc_isi_rgb2yuv_coeffs[6] = {
 /* RGB->YUV */
 0x00810041, 0x07db0019, 0x007007b6,
 0x07a20070, 0x001007ee, 0x00800080
};

static void mxc_isi_channel_set_csc(struct mxc_isi_pipe *pipe,
        enum mxc_isi_encoding in_encoding,
        enum mxc_isi_encoding out_encoding,
        bool *bypass)
{
 static const char * const encodings[] = {
  [MXC_ISI_ENC_RAW] = "RAW",
  [MXC_ISI_ENC_RGB] = "RGB",
  [MXC_ISI_ENC_YUV] = "YUV",
 };
 const u32 *coeffs = NULL;
 u32 val;

 val = mxc_isi_read(pipe, CHNL_IMG_CTRL);
 val &= ~(CHNL_IMG_CTRL_CSC_BYPASS | CHNL_IMG_CTRL_CSC_MODE_MASK);

 if (in_encoding == MXC_ISI_ENC_YUV &&
     out_encoding == MXC_ISI_ENC_RGB) {
  /* YUV2RGB */
  coeffs = mxc_isi_yuv2rgb_coeffs;
  /* YCbCr enable???  */
  val |= CHNL_IMG_CTRL_CSC_MODE(CHNL_IMG_CTRL_CSC_MODE_YCBCR2RGB);
 } else if (in_encoding == MXC_ISI_ENC_RGB &&
     out_encoding == MXC_ISI_ENC_YUV) {
  /* RGB2YUV */
  coeffs = mxc_isi_rgb2yuv_coeffs;
  val |= CHNL_IMG_CTRL_CSC_MODE(CHNL_IMG_CTRL_CSC_MODE_RGB2YCBCR);
 } else {
  /* Bypass CSC */
  val |= CHNL_IMG_CTRL_CSC_BYPASS;
 }

 dev_dbg(pipe->isi->dev, "CSC: %s -> %s\n",
  encodings[in_encoding], encodings[out_encoding]);

 if (coeffs) {
  mxc_isi_write(pipe, CHNL_CSC_COEFF0, coeffs[0]);
  mxc_isi_write(pipe, CHNL_CSC_COEFF1, coeffs[1]);
  mxc_isi_write(pipe, CHNL_CSC_COEFF2, coeffs[2]);
  mxc_isi_write(pipe, CHNL_CSC_COEFF3, coeffs[3]);
  mxc_isi_write(pipe, CHNL_CSC_COEFF4, coeffs[4]);
  mxc_isi_write(pipe, CHNL_CSC_COEFF5, coeffs[5]);
 }

 mxc_isi_write(pipe, CHNL_IMG_CTRL, val);

 *bypass = !coeffs;
}

void mxc_isi_channel_set_alpha(struct mxc_isi_pipe *pipe, u8 alpha)
{
 u32 val;

 val = mxc_isi_read(pipe, CHNL_IMG_CTRL);
 val &= ~CHNL_IMG_CTRL_GBL_ALPHA_VAL_MASK;
 val |= CHNL_IMG_CTRL_GBL_ALPHA_VAL(alpha) |
        CHNL_IMG_CTRL_GBL_ALPHA_EN;
 mxc_isi_write(pipe, CHNL_IMG_CTRL, val);
}

void mxc_isi_channel_set_flip(struct mxc_isi_pipe *pipe, bool hflip, bool vflip)
{
 u32 val;

 val = mxc_isi_read(pipe, CHNL_IMG_CTRL);
 val &= ~(CHNL_IMG_CTRL_VFLIP_EN | CHNL_IMG_CTRL_HFLIP_EN);

 if (vflip)
  val |= CHNL_IMG_CTRL_VFLIP_EN;
 if (hflip)
  val |= CHNL_IMG_CTRL_HFLIP_EN;

 mxc_isi_write(pipe, CHNL_IMG_CTRL, val);
}

static void mxc_isi_channel_set_panic_threshold(struct mxc_isi_pipe *pipe)
{
 const struct mxc_isi_set_thd *set_thd = pipe->isi->pdata->set_thd;
 u32 val;

 val = mxc_isi_read(pipe, CHNL_OUT_BUF_CTRL);

 val &= ~(set_thd->panic_set_thd_y.mask);
 val |= set_thd->panic_set_thd_y.threshold << set_thd->panic_set_thd_y.offset;

 val &= ~(set_thd->panic_set_thd_u.mask);
 val |= set_thd->panic_set_thd_u.threshold << set_thd->panic_set_thd_u.offset;

 val &= ~(set_thd->panic_set_thd_v.mask);
 val |= set_thd->panic_set_thd_v.threshold << set_thd->panic_set_thd_v.offset;

 mxc_isi_write(pipe, CHNL_OUT_BUF_CTRL, val);
}

static void mxc_isi_channel_set_control(struct mxc_isi_pipe *pipe,
     enum mxc_isi_input_id input,
     bool bypass)
{
 u32 val;

 mutex_lock(&pipe->lock);

 val = mxc_isi_read(pipe, CHNL_CTRL);
 val &= ~(CHNL_CTRL_CHNL_BYPASS | CHNL_CTRL_CHAIN_BUF_MASK |
   CHNL_CTRL_BLANK_PXL_MASK | CHNL_CTRL_SRC_TYPE_MASK |
   CHNL_CTRL_MIPI_VC_ID_MASK | CHNL_CTRL_SRC_INPUT_MASK);

 /*
 * If no scaling or color space conversion is needed, bypass the
 * channel.
 */

 if (bypass)
  val |= CHNL_CTRL_CHNL_BYPASS;

 /* Chain line buffers if needed. */
 if (pipe->chained)
  val |= CHNL_CTRL_CHAIN_BUF(CHNL_CTRL_CHAIN_BUF_2_CHAIN);

 val |= CHNL_CTRL_BLANK_PXL(0xff);

 /* Input source (including VC configuration for CSI-2) */
 if (input == MXC_ISI_INPUT_MEM) {
  /*
 * The memory input is connected to the last port of the
 * crossbar switch, after all pixel link inputs. The SRC_INPUT
 * field controls the input selection and must be set
 * accordingly, despite being documented as ignored when using
 * the memory input in the i.MX8MP reference manual, and
 * reserved in the i.MX8MN reference manual.
 */

  val |= CHNL_CTRL_SRC_TYPE(CHNL_CTRL_SRC_TYPE_MEMORY);
  val |= CHNL_CTRL_SRC_INPUT(pipe->isi->pdata->num_ports);
 } else {
  val |= CHNL_CTRL_SRC_TYPE(CHNL_CTRL_SRC_TYPE_DEVICE);
  val |= CHNL_CTRL_SRC_INPUT(input);
  val |= CHNL_CTRL_MIPI_VC_ID(0); /* FIXME: For CSI-2 only */
 }

 mxc_isi_write(pipe, CHNL_CTRL, val);

 mutex_unlock(&pipe->lock);
}

void mxc_isi_channel_config(struct mxc_isi_pipe *pipe,
       enum mxc_isi_input_id input,
       const struct v4l2_area *in_size,
       const struct v4l2_area *scale,
       const struct v4l2_rect *crop,
       enum mxc_isi_encoding in_encoding,
       enum mxc_isi_encoding out_encoding)
{
 bool csc_bypass;
 bool scaler_bypass;

 /* Input frame size */
 mxc_isi_write(pipe, CHNL_IMG_CFG,
        CHNL_IMG_CFG_HEIGHT(in_size->height) |
        CHNL_IMG_CFG_WIDTH(in_size->width));

 /* Scaling */
 mxc_isi_channel_set_scaling(pipe, in_encoding, in_size, scale,
        &scaler_bypass);
 mxc_isi_channel_set_crop(pipe, scale, crop);

 /* CSC */
 mxc_isi_channel_set_csc(pipe, in_encoding, out_encoding, &csc_bypass);

 /* Output buffer management */
 mxc_isi_channel_set_panic_threshold(pipe);

 /* Channel control */
 mxc_isi_channel_set_control(pipe, input, csc_bypass && scaler_bypass);
}

void mxc_isi_channel_set_input_format(struct mxc_isi_pipe *pipe,
          const struct mxc_isi_format_info *info,
          const struct v4l2_pix_format_mplane *format)
{
 unsigned int bpl = format->plane_fmt[0].bytesperline;

 mxc_isi_write(pipe, CHNL_MEM_RD_CTRL,
        CHNL_MEM_RD_CTRL_IMG_TYPE(info->isi_in_format));
 mxc_isi_write(pipe, CHNL_IN_BUF_PITCH,
        CHNL_IN_BUF_PITCH_LINE_PITCH(bpl));
}

void mxc_isi_channel_set_output_format(struct mxc_isi_pipe *pipe,
           const struct mxc_isi_format_info *info,
           struct v4l2_pix_format_mplane *format)
{
 u32 val;

 /* set outbuf format */
 dev_dbg(pipe->isi->dev, "output format %p4cc", &format->pixelformat);

 val = mxc_isi_read(pipe, CHNL_IMG_CTRL);
 val &= ~CHNL_IMG_CTRL_FORMAT_MASK;
 val |= CHNL_IMG_CTRL_FORMAT(info->isi_out_format);
 mxc_isi_write(pipe, CHNL_IMG_CTRL, val);

 /* line pitch */
 mxc_isi_write(pipe, CHNL_OUT_BUF_PITCH,
        format->plane_fmt[0].bytesperline);
}

/* -----------------------------------------------------------------------------
 * IRQ
 */


u32 mxc_isi_channel_irq_status(struct mxc_isi_pipe *pipe, bool clear)
{
 u32 status;

 status = mxc_isi_read(pipe, CHNL_STS);
 if (clear)
  mxc_isi_write(pipe, CHNL_STS, status);

 return status;
}

void mxc_isi_channel_irq_clear(struct mxc_isi_pipe *pipe)
{
 mxc_isi_write(pipe, CHNL_STS, 0xffffffff);
}

static void mxc_isi_channel_irq_enable(struct mxc_isi_pipe *pipe)
{
 const struct mxc_isi_ier_reg *ier_reg = pipe->isi->pdata->ier_reg;
 u32 val;

 val = CHNL_IER_FRM_RCVD_EN |
  CHNL_IER_AXI_WR_ERR_U_EN |
  CHNL_IER_AXI_WR_ERR_V_EN |
  CHNL_IER_AXI_WR_ERR_Y_EN;

 /* Y/U/V overflow enable */
 val |= ier_reg->oflw_y_buf_en.mask |
        ier_reg->oflw_u_buf_en.mask |
        ier_reg->oflw_v_buf_en.mask;

 /* Y/U/V excess overflow enable */
 val |= ier_reg->excs_oflw_y_buf_en.mask |
        ier_reg->excs_oflw_u_buf_en.mask |
        ier_reg->excs_oflw_v_buf_en.mask;

 /* Y/U/V panic enable */
 val |= ier_reg->panic_y_buf_en.mask |
        ier_reg->panic_u_buf_en.mask |
        ier_reg->panic_v_buf_en.mask;

 mxc_isi_channel_irq_clear(pipe);
 mxc_isi_write(pipe, CHNL_IER, val);
}

static void mxc_isi_channel_irq_disable(struct mxc_isi_pipe *pipe)
{
 mxc_isi_write(pipe, CHNL_IER, 0);
}

/* -----------------------------------------------------------------------------
 * Init, deinit, enable, disable
 */


static void mxc_isi_channel_sw_reset(struct mxc_isi_pipe *pipe, bool enable_clk)
{
 mxc_isi_write(pipe, CHNL_CTRL, CHNL_CTRL_SW_RST);
 mdelay(5);
 mxc_isi_write(pipe, CHNL_CTRL, enable_clk ? CHNL_CTRL_CLK_EN : 0);
}

static void __mxc_isi_channel_get(struct mxc_isi_pipe *pipe)
{
 if (!pipe->use_count++)
  mxc_isi_channel_sw_reset(pipe, true);
}

void mxc_isi_channel_get(struct mxc_isi_pipe *pipe)
{
 mutex_lock(&pipe->lock);
 __mxc_isi_channel_get(pipe);
 mutex_unlock(&pipe->lock);
}

static void __mxc_isi_channel_put(struct mxc_isi_pipe *pipe)
{
 if (!--pipe->use_count)
  mxc_isi_channel_sw_reset(pipe, false);
}

void mxc_isi_channel_put(struct mxc_isi_pipe *pipe)
{
 mutex_lock(&pipe->lock);
 __mxc_isi_channel_put(pipe);
 mutex_unlock(&pipe->lock);
}

void mxc_isi_channel_enable(struct mxc_isi_pipe *pipe)
{
 u32 val;

 mxc_isi_channel_irq_enable(pipe);

 mutex_lock(&pipe->lock);

 val = mxc_isi_read(pipe, CHNL_CTRL);
 val |= CHNL_CTRL_CHNL_EN;
 mxc_isi_write(pipe, CHNL_CTRL, val);

 mutex_unlock(&pipe->lock);
}

void mxc_isi_channel_disable(struct mxc_isi_pipe *pipe)
{
 u32 val;

 mxc_isi_channel_irq_disable(pipe);

 mutex_lock(&pipe->lock);

 val = mxc_isi_read(pipe, CHNL_CTRL);
 val &= ~CHNL_CTRL_CHNL_EN;
 mxc_isi_write(pipe, CHNL_CTRL, val);

 mutex_unlock(&pipe->lock);
}

/* -----------------------------------------------------------------------------
 * Resource management & chaining
 */

int mxc_isi_channel_acquire(struct mxc_isi_pipe *pipe,
       mxc_isi_pipe_irq_t irq_handler, bool bypass)
{
 u8 resources;
 int ret = 0;

 mutex_lock(&pipe->lock);

 if (pipe->irq_handler) {
  ret = -EBUSY;
  goto unlock;
 }

 /*
 * Make sure the resources we need are available. The output buffer is
 * always needed to operate the channel, the line buffer is needed only
 * when the channel isn't in bypass mode.
 */

 resources = MXC_ISI_CHANNEL_RES_OUTPUT_BUF
    | (!bypass ? MXC_ISI_CHANNEL_RES_LINE_BUF : 0);
 if ((pipe->available_res & resources) != resources) {
  ret = -EBUSY;
  goto unlock;
 }

 /* Acquire the channel resources. */
 pipe->acquired_res = resources;
 pipe->available_res &= ~resources;
 pipe->irq_handler = irq_handler;

unlock:
 mutex_unlock(&pipe->lock);

 return ret;
}

void mxc_isi_channel_release(struct mxc_isi_pipe *pipe)
{
 mutex_lock(&pipe->lock);

 pipe->irq_handler = NULL;
 pipe->available_res |= pipe->acquired_res;
 pipe->acquired_res = 0;

 mutex_unlock(&pipe->lock);
}

/*
 * We currently support line buffer chaining only, for handling images with a
 * width larger than 2048 pixels.
 *
 * TODO: Support secondary line buffer for downscaling YUV420 images.
 */

int mxc_isi_channel_chain(struct mxc_isi_pipe *pipe, bool bypass)
{
 /* Channel chaining requires both line and output buffer. */
 const u8 resources = MXC_ISI_CHANNEL_RES_OUTPUT_BUF
      | MXC_ISI_CHANNEL_RES_LINE_BUF;
 struct mxc_isi_pipe *chained_pipe = pipe + 1;
 int ret = 0;

 /*
 * If buffer chaining is required, make sure this channel is not the
 * last one, otherwise there's no 'next' channel to chain with. This
 * should be prevented by checks in the set format handlers, but let's
 * be defensive.
 */

 if (WARN_ON(pipe->id == pipe->isi->pdata->num_channels - 1))
  return -EINVAL;

 mutex_lock(&chained_pipe->lock);

 /* Safety checks. */
 if (WARN_ON(pipe->chained || chained_pipe->chained_res)) {
  ret = -EINVAL;
  goto unlock;
 }

 if ((chained_pipe->available_res & resources) != resources) {
  ret = -EBUSY;
  goto unlock;
 }

 pipe->chained = true;
 chained_pipe->chained_res |= resources;
 chained_pipe->available_res &= ~resources;

 __mxc_isi_channel_get(chained_pipe);

unlock:
 mutex_unlock(&chained_pipe->lock);

 return ret;
}

void mxc_isi_channel_unchain(struct mxc_isi_pipe *pipe)
{
 struct mxc_isi_pipe *chained_pipe = pipe + 1;

 if (!pipe->chained)
  return;

 pipe->chained = false;

 mutex_lock(&chained_pipe->lock);

 chained_pipe->available_res |= chained_pipe->chained_res;
 chained_pipe->chained_res = 0;

 __mxc_isi_channel_put(chained_pipe);

 mutex_unlock(&chained_pipe->lock);
}

Messung V0.5
C=95 H=89 G=91

¤ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge