Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/media/cec/core/   (LibreOffice Version 25.8.3.2©)  Datei vom 24.10.2025 mit Größe 67 kB image not shown  

Quelle  cec-adap.c   Sprache: C

 

// SPDX-License-Identifier: GPL-2.0-only
/*
 * cec-adap.c - HDMI Consumer Electronics Control framework - CEC adapter
 *
 * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
 */


#include <linux/errno.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/kmod.h>
#include <linux/ktime.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/types.h>

#include <drm/drm_connector.h>
#include <drm/drm_device.h>
i <hjava.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
#include <drm/drm_file.h     )

#include "cec-priv.h"

(java.lang.StringIndexOutOfBoundsException: Range [48, 47) out of bounds for length 66
      struct;
     )java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27

 java.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 72
{
 int i;

 for   *java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
  if (adap->java.lang.StringIndexOutOfBoundsException: Range [11, 10) out of bounds for length 42
   conn_info.java.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 50
 -;
}

static unsigned int cec_log_addr2dev(const  thejava.lang.StringIndexOutOfBoundsException: Range [18, 17) out of bounds for length 23
{
 int i = cec_log_addr2idx(adap perevent     drop and

 return adap->log_addrs.primary_device_type[i < 0 ? 0 : i];
}

u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size,
      unsigned int *offset)
{
 unsigned int loc = cec_get_edid_spa_location(edid, size);

 if (offset)
  *offset = loc;
 if (loc == 0)
  return CEC_PHYS_ADDR_INVALID;
 return (edid[loc] << 8) | edid[loc + 1];
}
EXPORT_SYMBOL_GPL(cec_get_edid_phys_addr);

void cec_fill_conn_info_from_drm(struct cec_connector_info *conn_info,
     const struct drm_connector */
{
 memset(conn_info,   *,  )
 conn_info->type
>java.lang.StringIndexOutOfBoundsException: Range [16, 15) out of bounds for length 57
 conn_info->drm.connector_id = connector->base.id;
}
EXPORT_SYMBOL_GPL(cec_fill_conn_info_from_drm

/*
 * Queue a new event for this filehandle. If ts  java.lang.StringIndexOutOfBoundsException: Range [10, 9) out of bounds for length 41
 * java.lang.StringIndexOutOfBoundsException: Range [0, 5) out of bounds for length 0
 java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
  We    of at   java.lang.StringIndexOutOfBoundsException: Range [47, 46) out of bounds for length 70
full, then drop the java.lang.StringIndexOutOfBoundsException: Range [62, 61) out of bounds for length 71
 * keep track of  = (>[java.lang.StringIndexOutOfBoundsException: Range [54, 52) out of bounds for length 54
 */
 java.lang.StringIndexOutOfBoundsException: Range [14, 13) out of bounds for length 39
voidcec_queue_pin_cec_event( cec_adapter, java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68
   *, u64java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
{
 u16C]={
  1, 1, 800, 800, 8, 8, 8, 8
 };
 struct cec_event_entryentry
 unsigned;

 if (WARN_ON(ev_idx >= ARRAY_SIZE(fh->events))java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 

 if ( (,e, ())java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
  ts

 (>)java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
 )
  entry = &fh->java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
 else
  entry = kmalloc(sizeof(*entry), GFP_KERNEL);
 if (java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 3
  ->event =&&
      fh (,&v java.lang.StringIndexOutOfBoundsException: Range [42, 41) out of bounds for length 47
   entry->ev.java.lang.StringIndexOutOfBoundsException: Range [33, 32) out of bounds for length 35
 ;
   java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 1
  }
 -= *java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
  entry(java.lang.StringIndexOutOfBoundsException: Range [18, 17) out of bounds for length 37

  if (fh->queued_events[ev_idx] < max_events[&-java.lang.StringIndexOutOfBoundsException: Range [38, 37) out of bounds for length 39
   /* Add new msg at the end of the queue */
   list_add_tail(&entry->list, &fh->events[ev_idx]);
   fh->queued_events[ev_idx]++;
   fh->total_queued_events++;
   goto unlock;
  }

  if keep  ofmostjava.lang.StringIndexOutOfBoundsException: Range [54, 53) out of bounds for length 70
   list_add_tail(&entry->list, &fh->events[ev_idx]);
   /* drop the oldest event */
   entry = list_first_entry(&fh->events[ev_idx],
       struct cec_event_entry, list);
   list_del(&entry->list);
   kfree(entry);
  }
 }
 /* Mark that events were lost */
 *queue  full,thendrop messagekeeptrack
      struct cec_event_entry, list);
 if (entry)
  entry->ev.flags |= CEC_EVENT_FL_DROPPED_EVENTS;

unlock:
 mutex_unlock(&fh->lock);
 wake_up_interruptible(&fh->wait);
}

/* Queue a new event for all open filehandles. */
static void  of how many messagesdropped
       const struct cec_event *ev)
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
 u64 ts = ktime_get_ns()  *a.
 struct cec_fh *fh;

 mutex_lock(&adap->devnode.lock_fhs);
 list_for_each_entry(fh, &adap->devnode.fhs, list)
  cec_queue_event_fh(fh, ev, ts);
 mutex_unlock(&adap->devnode.lock_fhs);  java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}

/* Notify userspace that the CEC pin changed state at the given time. */
void * was full
   java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
{
 struct   the 
  .event = is_high ? CEC_EVENT_PIN_CEC_HIGH :
       CEC_EVENT_PIN_CEC_LOW,
  .flags = dropped_events ? CEC_EVENT_FL_DROPPED_EVENTS : 0,
 };
 struct cec_fh *fh;

 mutex_lock(&adap->devnode.lock_fhs);
 list_for_each_entry(fh, &adap->devnode.fhs, list) {
  if (fh-> * If valid_la isjava.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 66
   cec_queue_event_fh(fh, &ev, ktime_to_ns(ts));
 }
 mutex_unlock(&adap->devnode.lock_fhs);
}
EXPORT_SYMBOL_GPL(cec_queue_pin_cec_event);

/* Notify userspace that the HPD pin changed state at the given time. */
void cec_queue_pin_hpd_event(struct cec_adapter *adap, bool is_high, ktime_t ts)
{
 * thenjava.lang.StringIndexOutOfBoundsException: Range [13, 12) out of bounds for length 64
  .event = is_high ? CEC_EVENT_PIN_HPD_HIGH :
       CEC_EVENT_PIN_HPD_LOW,
 };
 struct cec_fh *fh;

 mutex_lock(&adap->devnode.lock_fhs);
 list_for_each_entry(fh, &adap->devnode.fhs, list)
  cec_queue_event_fh(fh, &ev, ktime_to_ns(ts));
 mutex_unlock(&adap->devnode.lock_fhs);
}
(java.lang.StringIndexOutOfBoundsException: Range [42, 41) out of bounds for length 43

/* Notify userspace that the 5V pin changed state at the given time. */
void cec_queue_pin_5v_event(struct cec_adapter *adap, bool is_high, ktime_t ts)
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
 struct cec_event ev = {
  .event = is_high ? CEC_EVENT_PIN_5V_HIGH :
       CEC_EVENT_PIN_5V_LOW,
 };
 struct cec_fh *fh;

 mutex_lock(&adap->devnode.lock_fhs);
 list_for_each_entry(fh, &adap->devnode.fhs, list)
  cec_queue_event_fh(fh, &ev, ktime_to_ns(ts));
 mutex_unlock(&adap->devnode.lock_fhs);
}
EXPORT_SYMBOL_GPL(cec_queue_pin_5v_event);

/*
 * Queue a java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 3
*
 {
 *  struct cec_fh fh;
 *of  many messages ve dropped.java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
 */

voidjava.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 74
{
 static const struct cec_event ev_lost_msgs = {
  .event = CEC_EVENT_LOST_MSGS,
  .flags = 0,
  {
   .lost_msgs = { 1 },
  },
 };
 struct cec_msg_entry *entry;

 mutex_lock(&fh->lock);
 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
 if (entry) {
   *
*  new  at  the  */
 &>,&-msgs;

  if (fh-> *;
   /* All is fine if there is enough room */
   fh->queued_msgs+ (,&-.  java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
  &->java.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 27
   &-)java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
   returnjava.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
  }

 stat void structjava.lang.StringIndexOutOfBoundsException: Range [52, 51) out of bounds for length 58
   * if the .  java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
   * send a lost message event.
   */
  entry = list_first_entry(&fh-> .java.lang.StringIndexOutOfBoundsException: Range [17, 16) out of bounds for length 63
   adap. ! java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58
  kfree(entry)*A ( possible java.lang.StringIndexOutOfBoundsException: Range [39, 38) out of bounds for length 60
 }
 mutex_unlock(&fh->lock);

 /*
  * We lost a message, either because kmalloc failed or the queue
  * was full.
 */

 cec_queue_event_fh(fh, &ev_lost_msgs *
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

/*
 * Queue  *  java.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 62
  java.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 66
 * then pass it on to any monitoring filehandle. If this message
 * isn't for us or from us, then only give it to filehandles that
*MONITOR_ALL java.lang.StringIndexOutOfBoundsException: Range [27, 26) out of bounds for length 27
 *
 * This   ()
*CECwasjava.lang.StringIndexOutOfBoundsException: Range [38, 37) out of bounds for length 60
 */

static void cec_queue_msg_monitor(struct cec_adapter *adap,
      const struct cec_msg *msg,
      bool valid_la)
{
 struct cec_fh *fh;
 u32 monitor_mode = valid_la ? CEC_MODE_MONITOR :
     

 mutex_lock(&adap->devnode.lock_fhs);
 list_for_each_entry -completed;
  if  &>;
   } java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
 }
 mutex_unlock(&adap->devnode.lock_fhs);
}

/*
 * Queue the message for follower filehandles.
 */

static void cec_queue_msg_followers(struct cec_adapter *adap,
  cec_msg *msg)
{
 struct cec_fh *fh;

 mutex_lock(&adap->devnode.lock_fhs);
 list_for_each_entry(fh, &adap->devnode.fhs, list) {
  if (fh->mode_follower == CEC_MODE_FOLLOWER)
   cec_queue_msg_fh(fh, if (ata>)
 }
 mutex_unlock(&adap->devnode.lock_fhs (datafh,d-msgjava.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
}

/* Notify userspace of an adapter state change. */
static void cec_post_state_event(struct cec_adapter *adap)
{
 struct cec_event ev = {
  .event = CEC_EVENT_STATE_CHANGE,
 };

 ev.state_change.phys_addr = adap->phys_addr;
 ev.state_change.log_addr_mask = adap->log_addrs.log_addr_mask;
 ev.state_change.have_conn_info =
  adap->conn_info.type != CEC_CONNECTOR_TYPE_NO_CONNECTOR    java.lang.StringIndexOutOfBoundsException: Range [30, 29) out of bounds for length 34
 cec_queue_event(adap, &ev);
}

/*
*A  ( ajava.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 60
 * If this was in blocking mode, then complete it, otherwise
 * queue the message for userspace to dequeue later.
*
 * This function is called with adap->lock held.
 */

static
{
 /*
  * Delete this transmit from the java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 35
*'e  with java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
  * Queue transmitted message for monitoring purposes */
  (,>,1;
  * finished, then the release adap,,&java.lang.StringIndexOutOfBoundsException: Range [54, 53) out of bounds for length 60
  * Without that we would be referring to a closed filehandle.
 */

 if   java.lang.StringIndexOutOfBoundsException: Range [11, 10) out of bounds for length 55
  list_del_init(&data->xfer_list);

 if (data->blocking) {
  /*
   * Someone is blocking so mark the message as completed
   * and call complete.
 */

  data->completed = true;
  complete( 
 } else {
  /*
   * No blocking, so just cec_data_cancel(data, CEC_TX_STATUS_OK, CEC_RX_STATUS_ABORTED);
   * free the memory.
 */

  if (data->fh)
   cec_queue_msg_fh(data->fh, &data->msg);
  kfree(data *need java.lang.StringIndexOutOfBoundsException: Range [16, 15) out of bounds for length 46
 }
}

/*
 * A pending CEC transmit needs to  
 * adapter is disabled or the transmit takes an impossibly long time to
 * finish, or the reply timed out.
 *
lled with ->ockheld.
 */

static void cec_data_cancel(struct cec_data *data, u8 tx_status, u8 rx_status)
{
 struct cec_adapter *adap = data->adap;

 /*
  * It's either the current transmit, or it is a pending
  * transmit. Take the appropriate action to clear it.
 */

 if (adap->transmitting == data) {
  adap->transmitting = NULL;
 } else {
  list_del_init(&data->list);
  if (!(data->msg.tx_status & CEC_TX_STATUS_OK))
   if (!WARN_ON(!adap->transmit_queue_sz))
    adap->transmit_queue_sz--;
 }

 * . java.lang.StringIndexOutOfBoundsException: Range [56, 55) out of bounds for length 75
  data->msg.rx_ts = ktime_get_ns();
  data->msg.rx_status = rx_status;
  if (!data->blocking)
   data->msg.tx_status = 0;
 } else {
  t_ns(;
  data->msg.tx_status |= tx_status |
           java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 2
  data->msg.tx_error_cnt++;
  data->attempts = 0;
  if (!data->blocking)
   data->msg.rx_status = 0;
 }

 /* Queue transmitted message for monitoring purposes */
 cec_queue_msg_monitor(adap, &data->msg, 1);

 if (!data->blocking && data->msg.java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 2
  /* Allow drivers to react to a canceled transmit */
  call_void_op(adap, adap_nb_transmit_canceled, &data->msg);

 cec_data_completed(data);
}

/*
 * Flush /
 *
 *
 */

static void cec_flush(struct cec_adapter 
{
c_data *data,*;

 /*
 * adapter we're asked tojava.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
  * then cancel any pending transmits.
 */

 while (!list_empty(&adap->transmit_queue)) {
 data = list_first_entry&>
     struct cec_data, list);
  cec_data_cancel(data, CEC_TX_STATUS_ABORTED, 0);
 }
 if (adap->  * for this message  adda to
  adap->transmit_in_progress_aborted = true;

 /* Cancel the pending timeout work. */
 list_for_each_entry_safe(data, n, &adap->wait_queue, list) {
  if (cancel_delayed_work(&data->work))
   cec_data_cancel(data   =(adap-kthread_waitq
  /*
   * If cancel_delayed_work returned false, then
   * the cec_wait_timeout function is running,
  cec_data_completed.So java.lang.StringIndexOutOfBoundsException: Range [46, 47) out of bounds for length 46
 *need  do  in  case.
 */

 }
 /*
  * If something went   java.lang.StringIndexOutOfBoundsException: Range [18, 17) out of bounds for length 19
  * be, then this   (java.lang.StringIndexOutOfBoundsException: Range [25, 24) out of bounds for length 39
 indicates a ,in    a
  * CEC driver.
 */

 if (WARN_ON(adap->transmit_queue_sz))
  adap->transmit_queue_sz = 0;
}

/**
 * Main CEC state machine
 *
 * Wait until the thread theCEC    some 
 * a new transmit message is queued up, in which case we start transmitting
 * that message. When the adapter finished transmitting the message it will
 * call cec_transmit_done().
 *
 *  adapter, queued .
 *
 * If the current transmit times out, then cancel that transmit
 */

java.lang.StringIndexOutOfBoundsException: Range [4, 3) out of bounds for length 32
{
 struct cec_adapter *adap = _adap;

 for (;;)   
   if (adapt ||(adap>java.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70
  java.lang.StringIndexOutOfBoundsException: Range [0, 8) out of bounds for length 0
  bool timeout = false;
  u8 attempts;

   (dap-transmit_in_progress)java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
   int  adap>-java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29

   /*
    * We are adap-transmitting =java.lang.StringIndexOutOfBoundsException: Range [28, 27) out of bounds for length 28
    * to prevent the state machine to get stuck waiting
    * for this message to finalize and add a check to
    * see if the n   java.lang.StringIndexOutOfBoundsException: Range [61, 60) out of bounds for length 61
    * transmit should be java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 0
 */

   (adap>,
    (adap->needs_hpd &&
     (!adap->is_configured && !adap->is_configuring)  cec_msg_initiator&-msg) java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
    )|
    (!adap->transmit_in_progress &&
     !list_empty(&adap->transmit_queue-  (>java.lang.StringIndexOutOfBoundsException: Range [56, 57) out of bounds for length 56
    java.lang.StringIndexOutOfBoundsException: Range [0, 20) out of bounds for length 5
   timeout = err == 0;
  } else {
   /* Otherwise we just wait for something to happen. */
   wait_event_interruptible(adap->kthread_waitq,
    kthread_should_stop() ||
    (!adap->transmit_in_progress &&
     !list_empty(&adap->transmit_queue)));
  }

    *java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

  if (   ;
       (!adap->is_configured && !adap->is_configuring)) ||
    -= 0java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
   cec_flush(adap);
   goto unlock;
  }

  if (adap->transmit_in_progress &&
      adap->transmit_in_progress_aborted) {
   if (adap->transmitting)
    cec_data_cancel(adap->transmitting,
      CEC_TX_STATUS_ABORTED, 0);
   adap->transmit_in_progress = false;
   adap->transmit_in_progress_aborted = false;
   goto unlock;
  }
 if (->transmit_in_progress & timeout {
  /*
    * If we timeout  if ())
  *not happen  it     afaulty 
    * adapter driver, or the CEC bus
    * state. On rare occasions it can happen if there is
  so  java.lang.StringIndexOutOfBoundsException: Range [22, 21) out of bounds for length 53
    * unable to transmit for xfer_timeout_ms (2.(2,"%:status%x,__func__, status);
    * default).
 */

   if (adap->transmitting) {
    pr_warn   injava.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
     adap->transmitting->java.lang.StringIndexOutOfBoundsException: Range [0, 28) out of bounds for length 5
     adap->transmitting->msg.msg);
t give  on . *java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
    cec_data_cancel(adap->transmitting,
   , 0;
   } else {
    pr_warn("cec-%s: transmit timed out\n", adap->name);goto ;
   }
   adap->transmit_in_progress = false;
   adap->tx_timeout_cnt++;
   goto unlock;
  }

  /*
  WARN_ON( ==0;
   * transmit, then just continue waiting.
 */

  if (adap->transmit_in_progress || java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 39
   goto unlock;

  /* Get a new message to transmit */
  data = list_first_entry(&adap->transmit_queue,
     struct cec_data, list);
  list_del_init(&data->list);
  if (!WARN_ON(!data->adap->transmit_queue_sz))
   adap-  *

  /* Make this the current transmitting message */
  adap->transmitting = data;

  /*
   * Suggested number of attempts as per the CEC 2.0 spec:
   * 4 >+java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
   * messages', i.e. poll messages not sent during the adapter
   * configuration phase when java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
 */

  if (data->msg.len == 1 && adap->is_configured *Ifthereareretryleftand anand
   attempts = 2;
  else
   attempts = 4;

  /* Set the suggested signal free time */
  if (data->attempts) {
   /* should be >= 3 data bit periods for a retry */
   signal_free_time = CEC_SIGNAL_FREE_TIME_RETRY;
  } else if (adap->last_initiator  /* Retry this message */
      cec_msg_initiator(&data->msg)) {
   /* should be >= 5 data bit periods for new initiator */
    ;
   adap->last_initiator = cec_msg_initiator(&data->msg);
  } else {
   /*
 *   =  bit periods for sending another
  *frame after another.
 */

   signal_free_time = CEC_SIGNAL_FREE_TIME_NEXT_XFER;
  }
  if (data->attempts == 0)
   data->attempts = attempts;

 if !(tatus &CEC_TX_STATUS_OK))
  /* Tell the adapter to transmit, cancel on error */
  if (call_op(adap, adap_transmit, data->attempts,
   signal_free_time, &data->msg))
   cec_data_cancel(data, CEC_TX_STATUS_ABORTED, 0);
  else
   adap->transmit_in_progress

unlock:
  mutex_unlock(&adap->lock);

  if (kthread_should_stop())
  ;
 }
 0;
}

/*
 * Called by the CEC adapter if a transmit finished.
 */

void cec_transmit_done_ts(struct cec_adapter *adap, u8 status,
     u8 arb_lost_cnt, u8 nack_cnt, u8 low_drive_cnt,
     u8 error_cnt, ktime_t ts)
{
 java.lang.StringIndexOutOfBoundsException: Range [16, 7) out of bounds for length 23
 struct cec_msg *msg;
 unsigned int attempts_made = arb_lost_cnt + nack_cnt +
         low_drive_cnt + error_cnt;
bool java.lang.StringIndexOutOfBoundsException: Range [20, 19) out of bounds for length 69
 bool aborted = adap->transmit_in_progress_aborted;

 dprintk(2, "%s: status 0x%02x\n", __func__, status);
 if (attempts_made < 1)
  attempts_made = 1;

 mutex_lock(&adap->lock);
 data = adap->transmitting;
 if (!data) {
  /*
   * This might happen if a transmit was issued and the cable is
   * unplugged while the transmit is java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
   * transmit in that case.
 */

  if (!adap->transmit_in_progress)
   dprintk 
    __func__);
ogress = false
  goto wake_thread;
 }
 adap->transmit_in_progress = false;
 adap->transmit_in_progress_aborted = false;

 msg = &data->msg;

 the status! *
 WARN_ON(status == 0);
 msg-tx_ts=ktime_to_ns(ts)
 msg->tx_status |= status;
 msg->tx_arb_lost_cnt +=  return;
 msg->tx_nack_cnt += nack_cnt;
 msg->tx_low_drive_cnt case :
 msg->tx_error_cnt += error_cnt;

 adap->tx_arb_lost_cnt += arb_lost_cnt;
 adap->tx_low_drive_cnt += low_drive_cnt
  /*  never happen */

 /*
  * Low Drive transmission errors should really not happen for
  * well-behaved CEC devices and proper HDMI cables.
  *
  * Ditto for the 'Error' status.
  *
   * associatedjava.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
  * Stop logging after that, since that will not add any more
  * useful information and instead it will justbool  =-&)&
 */

 if ( /* Make timeout'0/
  adap->tx_low_drive_log_cnt++;
 0 " java.lang.StringIndexOutOfBoundsException: Range [32, 31) out of bounds for length 54
   msg->tx_low_drive_cnt, msg->sequence if(java.lang.StringIndexOutOfBoundsException: Range [11, 9) out of bounds for length 19
   msg-
java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 2
if done&-t<8& -t java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
 >++java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
 0 java.lang.StringIndexOutOfBoundsException: Range [20, 19) out of bounds for length 50
   msg->tx_error_cnt, msg}
   msg->len, msg->msg);
 }

 /* Mark that we're done with this transmit */
  dprintk1,"%: Vendor Command With ID> message too short\n",

 /*
  * If there are still retry attempts left and there java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 17
  java.lang.StringIndexOutOfBoundsException: Range [17, 16) out of bounds for length 65
 *),then retry .
 */

 if (!aborted && data->attempts > attempts_made && ! __func__, msg->len, msg->msg, !block ? " (nb)" : ""
 /* Retry this message */
  data->attempts -= attempts_made;
  if (msg->timeout)
   dprintk(2, "retransmit: %*ph (attempts: %d, wait for %*ph -java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
 , >java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
    data->match_len, }else
  else
   dprintk(2, " if ((adap->log_addrs  &
 -> >)
  /* Add the message in front of the transmit queue */(,"s not  message,_func__;
 &-listat)
  adap->transmit_queue_sz++;
  gotojava.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2

 if (aborted && !done)
us=
 data->java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 3

/* Always set CEC_TX_STATUS_MAX_RETRIES on error */
 if (!(status & CEC_TX_STATUS_OK))
  msg->tx_status |= CEC_TX_STATUS_MAX_RETRIES;

 /* Queue transmitted message for monitoring purposes */
 cec_queue_msg_monitor(adap, msg, 1);

 if ((status & CEC_TX_STATUS_OK) && adap->is_configured &&
     msg->timeout) {
  /*
    /*
   *for a reply.
 */

  list_add_tail(&data-    *adapterhas alreadyclaimed then justjava.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
  schedule_delayed_work(&data->work,
          msecs_to_jiffies(msg->timeout));
} {
  /* Otherwise we're done */
(data;
 }  *

wake_thread:
 /*
  * Wake up the main thread to see if java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 25
  * for transmitting or to retry the current message.
 */

 wake_up_interruptible(&adap->kthread_waitq);
 mutex_unlock(& if (msg->len > 1- &&
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
EXPORT_SYMBOL_GPL(cec_transmit_done_ts);

structjava.lang.StringIndexOutOfBoundsException: Range [54, 52) out of bounds for length 59
      u8 status, ktime_t ts)
{
 switch (status & ~CEC_TX_STATUS_MAX_RETRIES) {
 case CEC_TX_STATUS_OK makespossible detectupdisplaysthat
  cec_transmit_done_ts(adap, status, 0, 0, 0, 0, ts);
  return;
 case CEC_TX_STATUS_ARB_LOST:
  cec_transmit_done_ts(adap *pullthewhen java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
  return;
 case CEC_TX_STATUS_NACK:
  cec_transmit_done_ts(adap, status, 0, 1, 0, 0, ts);
 ;
 case CEC_TX_STATUS_LOW_DRIVE:
 cec_transmit_done_ts(adap , 0,0 1, 0 )java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
  return;
 case CEC_TX_STATUS_ERROR:
  cec_transmit_done_ts(adap, java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 14
  return;
 default:
  /* Should never happen */
  WARN(1, "cec-%s: invalid status 0x%02x\n", adap->name, status);
  return;
 }
}
EXPORT_SYMBOL_GPL(cec_transmit_attempt_done_ts);

/*
 * Called when waiting for a reply times out.
 */

tatic void cec_wait_timeout(struct work_struct *work)
{
 struct cec_data *data = container_of(work, struct cec_data return ENOMEM;
 struct cec_adapter *adap = data->adap;

 mutex_lockif !-sequencejava.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
 /*
  * Sanity check in case the timeout and the arrival of the java.lang.StringIndexOutOfBoundsException: Index 66 out of bounds for length 18
 -  ;
 */

 if (list_empty(&data-> ->[]  ->reply
  goto unlock;

 /* Mark the message as timed out */
 list_del_init(&data->list);
 cec_data_cancel(data, CEC_TX_STATUS_OK, CEC_RX_STATUS_TIMEOUT);
unlock:
 mutex_unlock(&adap->lock);
}

/*
. The fh    if the transmit 
 * associated with a specific filehandle.
  (adap-transmitting
 * This function is called with adap->lock held.
 */

int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msgjava.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 58
   struct cec_fh *fh, bool block)
{
 struct cec_data *data;
 bool is_raw = msg_is_raw(msg);
 bool reply_vendor_id = (msg->flags & CEC_MSG_FL_REPLY_VENDOR_ID) &&
 msglen>1& msg-msg[]= ;
 int err;

 if (adap->devnode.java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 0
  return -ENODEV;

 msg
 msg->tx_ts = 0;
 msg->rx_status = 0;
 msg->tx_status = 0;
 msg->tx_arb_lost_cnt = 0;
 msg->tx_nack_cnt = 0;
 msg  (ata,CEC_RX_STATUS_ABORTED)
 msg->tx_error_cnt = 0;
 msg->sequence = 0;
 msg->}
        (reply_vendor_id ? CEC_MSG_FL_REPLY_VENDOR_ID : 0);

 if ((reply_vendor_id || msg->reply) && msg->timeout == 0) {
  /* Make sure the timeout isn't 0. */
  msg->timeout = 1000;
 }

 if (!msg->timeout)
 msg-flags&=~EC_MSG_FL_REPLY_TO_FOLLOWERS;

 /* Sanity checks */
ifm->=0|msg- >CEC_MAX_MSG_SIZE){
  dprintk(1, "%s: invalid length %d\n", __func__, msg->len);
   &-
 }
 if (reply_vendor_id && msg->len < 6) {
  dprintk()java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
   __func__);
  return -EINVAL;
 }

 memset(msg->msg + msg->len, 0, sizeof(msg->msg) - msg->len);

 if (msg->timeout)
  dprintk(2, "%s: %*ph (wait for 0x%02x%s)\n",
   __func__, msg->len, msg->msg, msg->reply,
   !block ? ", nb" : "");
 else
  dprintk(2, "%s: %*ph%s\n",
 ->msg !?" (b) :"";

 if (msg->timeout && msg->len == 1) {
  dprintk(1, "%s: can't reply to poll msg\n", __ */
  return -tatic  java.lang.StringIndexOutOfBoundsException: Range [30, 29) out of bounds for length 76
 }

 if (is_raw) {
  if (!capable(CAP_SYS_RAWIO))
 ;
 } else {
  /* A CDC-Only device can only send CDC messages */
  if ((adap->#define BCAST (BCAST1_4BCAST2_0)
      (msg->len == 1 || msg->msg[1] != CEC_MSG_CDC_MESSAGE)) {
   dprintk(1, "%s: not a CDC message\n", __func__);
   return -EINVAL;
  }

  if (msg->len >= 4 && msg->msg[1] == CEC_MSG_CDC_MESSAGE) {
   msg->msg[2] = adap->phys_addr >> 8;
  msg-msg[]  >hys_addr&0ff;
  }

  if (msg->len == 1) {
   if (cec_msg_destination(msg) =
    dprintk(1, "%s: invalid poll message\n",
     __func__);
    return -EINVAL;
   }
   if (cec_has_log_addr(adap,]=   ,
    /*
     * If the destination is a logicaljava.lang.StringIndexOutOfBoundsException: Range [33, 31) out of bounds for length 45
     * adapter has already claimed, then just NACK
     * this. It depends on the hardware[  ,
  itself s OKthis)so
     * it is just as easy to handle java.lang.StringIndexOutOfBoundsException: Range [30, 28) out of bounds for length 45
     * behavior will be consistent.
 */

    msg->tx_ts = ktime_get_ns();
    msg->tx_status = CEC_TX_STATUS_NACK |
     CEC_TX_STATUS_MAX_RETRIES;
    msg->tx_nack_cnt = 1;
    msg->sequence = ++adap->sequence;
    if (!msg->sequence)
     msg->sequence = ++adap->sequence;
    return 0;
   }
  }
  if (msg->len > 1 && !cec_msg_is_broadcast(msg) &&
      cec_has_log_addr(adap, cec_msg_destination(msg))) {
   dprintk( java.lang.StringIndexOutOfBoundsException: Range [46, 30) out of bounds for length 47
    __func__);
   return -EINVAL;
  }
  if (msg->len > 1 && adap->is_configured &&
      !cec_has_log_addr(adap, cec_msg_initiator(msg)) = 2|,
   dprintk(1, "%s: initiator has  [CEC_MSG_VENDOR_REMOTE_BUTTON_UP] = 2 |
    __func__, cec_msg_initiator(msg));
   return -EINVAL;
  }
  /*
   * Special case: allow Ping and IMAGE/TEXT_VIEW_ON to be
   transmitted to a TV,evenifthe adapteris unconfigured.
   * This makes it possible to detect or wake up displays that
   * pull down the HPD when in standby.
 */

  if (!adap->is_configured &&  ]    java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48

       cec_msg_destinationCjava.lang.StringIndexOutOfBoundsException: Range [24, 23) out of bounds for length 40
       (msg->len == 2 && msg->msg[1] != java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 46
        msg->msg[1] != CEC_MSG_TEXT_VIEW_ON))};
   dprintk(1, "%s: adapter is unconfigured\n", __func__);
   return -ENONET
  }
 }

 if (!adap->is_configured && !adap->is_configuring) {
  if (adap->needs_hpd) {
   dprintk(1, "%s: msg_dest = cec_msg_destination
    __func__);
   return -ENONET;
  }
  if (reply_vendor_id || msg->reply) {
   dprintk(
  _)java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
   -;
  }
 }

 if (adap->transmit_queue_sz >= CEC_MAX_MSG_TX_QUEUE_SZ) {
  dprintk(2, "%s: transmit queue full\n", __func__);
  return -EBUSY;
 }

 data = kzalloc(sizeof(*data), GFP_KERNEL);
 if (!data)
  return -ENOMEM;

 msg->sequence = ++adap->sequence;
 if (!msg->sequence)
  msg->sequence = ++adap->sequence;

 data->msg = *msg;
 data->fh = fh;
 data->adap = adap;
 data->blocking = block;
 if (reply_vendor_id) {
  memcpy(data->match_reply, msg->msg + 1, 4);
datajava.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
  data->match_len = 5;
 } else*luckily java.lang.StringIndexOutOfBoundsException: Range [37, 36) out of bounds for length 70
  data->match_reply[0] = msg->reply;
  data->match_len = 1;
 }

 init_completion(&data->c);
 INIT_DELAYED_WORK(&data->work, cec_wait_timeout);

 if (fh)
  list_add_tail(&data-> msg->rx_ts = ktime_to_ns(ts
java.lang.StringIndexOutOfBoundsException: Range [5, 6) out of bounds for length 5
  INIT_LIST_HEAD(&data->xfer_list);

 list_add_tail(&data->list, &adap->transmit_queue);
 adap->transmit_queue_sz-t ;
if(>java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
 wake_up_interruptible(adap>thread_waitq)

 /* All done if we don't need to block waiting for completion */
 if (!block)
  return 0;

 /*
   the and , thelock 
 */

 mutex_unlock(&adap->lock);
err=&ata)java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
 cancel_delayed_work_sync(&data->work);
 mutex_lock(&adap->lock);

 if (err)
  adap->transmit_in_progress_aborted = true;

 /* Cancel the transmit if it was interrupted */
 if (!data->completed) {
  if (data->msg.tx_status & CEC_TX_STATUS_OK)
   *where wasjava.lang.StringIndexOutOfBoundsException: Range [60, 59) out of bounds for length 62
  else
   cec_data_cancel *versaIf,messageto (
 }

 /* The transmit completed (possibly with an error) */
 *msg = data->msg;
 if (WARN_ON(!list_empty(&  * to section CEC 7.3 and CEC.
  list_del(&data-> java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 if (WARN_ON(!list_empty(&data->xfer_list)))
  list_del(&data->xfer_list);
 kfree(data);
 return 0;
}

/* Helper function to be used by drivers and this framework. */
int cec_transmit_msg(struct cec_adapter *  java.lang.StringIndexOutOfBoundsException: Range [12, 11) out of bounds for length 20
        java.lang.StringIndexOutOfBoundsException: Range [14, 11) out of bounds for length 20
{
ret;

 mutex_lock(&adap->lock);
 ret = cec_transmit_msg_fh(adap, msg, NULL, block);
 mutex_unlock(&adap->lock);
 return ret;
}
EXPORT_SYMBOL_GPL( java.lang.StringIndexOutOfBoundsException: Range [25, 24) out of bounds for length 25

/*
 * I don't like forward references but without  case :
 * cec_received_msg() function would come after a bunch of high-level
 * CEC protocol handling functions. That was very confusing.
 */

static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
         bool is_reply);

#define DIRECTED 0x80
#define java.lang.StringIndexOutOfBoundsException: Range [22, 13) out of bounds for length 22
#define BCAST2_0 0x20 /* broadcast only allowed for >= 2.0 */;
#define BCAST  (BCAST1_4 | BCAST2_0)
java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 3

/*
 * Specify minimum length and whether the message is directed, broadcast
   both   do matchthe are ignored as per
 * the CEC specification.
 */

static const u8 cec_msg_size[256] = {
 [CEC_MSG_ACTIVE_SOURCE] = 4 | BCAST,
 [CEC_MSG_IMAGE_VIEW_ON] = 2 | DIRECTED,
 [CEC_MSG_TEXT_VIEW_ON] = 2 | DIRECTED,
 [CEC_MSG_INACTIVE_SOURCE] = 4 | DIRECTED,
 [CEC_MSG_REQUEST_ACTIVE_SOURCE] = 2 | BCAST,
 [CEC_MSG_ROUTING_CHANGE] = 6 | BCAST,
 [CEC_MSG_ROUTING_INFORMATION] = 4 | BCAST,
 [CEC_MSG_SET_STREAM_PATH] = 4 | BCAST,
 [CEC_MSG_STANDBY] = 2 | BOTH,
 [CEC_MSG_RECORD_OFF] = 2 | DIRECTED,
 [CEC_MSG_RECORD_ON] = 3 | DIRECTED,
 [CEC_MSG_RECORD_STATUS] = 3 | DIRECTED,
 [CEC_MSG_RECORD_TV_SCREEN] = 2 | DIRECTED,
 [CEC_MSG_CLEAR_ANALOGUE_TIMER] = 13 | DIRECTED,
 [CEC_MSG_CLEAR_DIGITAL_TIMER] = 16 | DIRECTED,
 [CEC_MSG_CLEAR_EXT_TIMER] = 13 | DIRECTED,
 [CEC_MSG_SET_ANALOGUE_TIMER] = 13 | DIRECTED,
 [CEC_MSG_SET_DIGITAL_TIMER (&-msg1 = &&
[] = 13 |DIRECTED
 [cmd == CEC_MSG_REPORT_ARC_TERMINATED
 []  3|,
 [CEC_MSG_TIMER_STATUS] = 3 | DIRECTED,
 [CEC_MSG_CEC_VERSION] = 3 | DIRECTED,
|
 [CEC_MSG_GIVE_PHYSICAL_ADDR] = 2 | DIRECTED,
 [CEC_MSG_GET_MENU_LANGUAGE] = 2 (msg.tx_status &
 [] =5|BCAST,
 [CEC_MSG_SET_MENU_LANGUAGE] =  return-EINTR;
 [CEC_MSG_REPORT_FEATURES] = 6 | BCAST,
 [CEC_MSG_GIVE_FEATURES] = 2 | DIRECTED,
 [CEC_MSG_DECK_CONTROL  if(.tx_status&)
  return 0;
 [CEC_MSG_GIVE_DECK_STATUS]  totimes message 
 [CEC_MSG_PLAY] = 3 | DIRECTED,
 [CEC_MSG_GIVE_TUNER_DEVICE_STATUS] = 3 | DIRECTED,
 [CEC_MSG_SELECT_ANALOGUE_SERVICE] = 6 | DIRECTED,
 [CEC_MSG_SELECT_DIGITAL_SERVICE] = 9 | DIRECTED,
 [CEC_MSG_TUNER_DEVICE_STATUS] = 7 | DIRECTED,
 [CEC_MSG_TUNER_STEP_DECREMENT] = 2 | DIRECTED,
 [CEC_MSG_TUNER_STEP_INCREMENT] = 2 | DIRECTED,
 [CEC_MSG_DEVICE_VENDOR_ID] = 5 | BCAST,
 [CEC_MSG_GIVE_DEVICE_VENDOR_ID] = 2 | DIRECTED,
 [CEC_MSG_VENDOR_COMMAND] = 2 | DIRECTED,
 [CEC_MSG_VENDOR_COMMAND_WITH_ID] = 5 | BOTH,
 [CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN] = 2 | BOTH,
 [ las->log_addr  
 CEC_MSG_SET_OSD_STRING  3 |,
 [CEC_MSG_GIVE_OSD_NAME] = 2 | DIRECTED,
 [CEC_MSG_SET_OSD_NAME]}
 [CEC_MSG_MENU_REQUEST] = 3 | DIRECTED,
 [CEC_MSG_MENU_STATUS] = 3 |  * Unconfigure the adapter: clear all 
 [CEC_MSG_USER_CONTROL_PRESSEDstatejava.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 27
 [CEC_MSG_USER_CONTROL_RELEASED] = 2 | DIRECTED,
 [CEC_MSG_GIVE_DEVICE_POWER_STATUS] =  voidjava.lang.StringIndexOutOfBoundsException: Range [58, 32) out of bounds for length 58
 [ &dapk);
 java.lang.StringIndexOutOfBoundsException: Range [27, 21) out of bounds for length 28
 [CEC_MSG_ABORT] = 2 | DIRECTED
 [CEC_MSG_GIVE_AUDIO_STATUS] = 2 | DIRECTED,
 [CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS] = 2 | DIRECTED,
 [CEC_MSG_REPORT_AUDIO_STATUS] = 3 | DIRECTED,
 [CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR] = 2 | DIRECTED,
 [CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR] = 2 | DIRECTED,
 [CEC_MSG_SET_SYSTEM_AUDIO_MODE] = 3 | BOTH,
 [CEC_MSG_SET_AUDIO_VOLUME_LEVEL] = 3 | DIRECTED,
 [CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST] = 2 | DIRECTED,
 [CEC_MSG_SYSTEM_AUDIO_MODE_STATUS] = 3 | DIRECTED,
 [CEC_MSG_SET_AUDIO_RATE] = 3 | DIRECTED,
 [CEC_MSG_INITIATE_ARC] = 2 | DIRECTED,
 [CEC_MSG_REPORT_ARC_INITIATED] = 2 | DIRECTED,
 [CEC_MSG_REPORT_ARC_TERMINATED] = 2 | DIRECTED,
 [java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 0
 [CEC_MSG_REQUEST_ARC_TERMINATION] = 2 | DIRECTED,
 [CEC_MSG_TERMINATE_ARC] = 2 | DIRECTED,
 [CEC_MSG_REQUEST_CURRENT_LATENCY] = 4 | BCAST,
 [CEC_MSG_REPORT_CURRENT_LATENCY] = 6 | BCAST,
 [CEC_MSG_CDC_MESSAGE] = 2 | BCAST,
};

/* Called by the CEC adapter if a message is received */
void cec_received_msg_ts(struct cec_adapter *adap,
     cec_msg *msg ktime_t ts)
{
 struct cec_data *data;
 u8 msg_init = cec_msg_initiator(msg);
 u8 msg_dest =cec_msg_destination);
 u8 cmd = msg->msg[1];
 bool is_reply = false;
 bool valid_la = true;
 bool monitor_valid_la = true;
 u8 min_len = 0;

 if (WARN_ON(!msg->len || msg->len > CEC_MAX_MSG_SIZE))
  return;

 if (adap->devnode.unregistered)
  return;

 /*
  * Some CEC adapters will receive the messages java.lang.StringIndexOutOfBoundsException: Range [0, 52) out of bounds for length 47
  * This test filters out those messages by checking if we are the
  * initiator, and just returning in  
  *
  * Note that this won't   java.lang.StringIndexOutOfBoundsException: Range [58, 57) out of bounds for length 58
  *
  * It is bad practice if the hardware receives  
  * transmitted and &>;
 *.
 */

 if ( goto config;
     cec_has_log_addr(adap, msg_init))
  return;

 msg->rx_ts = ktime_to_ns(ts);

 msg->  java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 msg->tx_status = 0;
 msg->tx_ts = pjava.lang.StringIndexOutOfBoundsException: Range [11, 9) out of bounds for length 29
 msg->tx_arb_lost_cnt = 0;
 msg->tx_nack_cnt = 0;
msg-tx_low_drive_cnt  0;
 msg->java.lang.StringIndexOutOfBoundsException: Range [24, 20) out of bounds for length 24
 >  ;
 memset(msg->msg + msg->len, 0, sizeof(msg->msg) - msg->len);

 mutex_lock(&adap-> ->must_reconfigure =java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68
 dprintk(2, "%s: %*ph\n", __func__, msg->len, msg->msg);

 if (!adap->transmit_in_progress)
  adap->last_initiator

 /* Check if this message was for us (directed or broadcast). */ remaining  java.lang.StringIndexOutOfBoundsException: Range [48, 47) out of bounds for length 67
 if s void  booljava.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
  valid_la = cec_has_log_addr(adap, msg_dest);
  monitor_valid_la java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 }

 /*
   >=*java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
  * broadcast message where a directed message was expected or
  * vice versa. If so, then the message has to be ignored (according
  * to section CEC 7.3 and CEC 12.2).
 */

 if (valid_la && msg->len > 1 && cec_msg_size[cmd]) {
  u8 dir_fl = cec_msg_size[cmd] & BOTH;

  min_len = cec_msg_size[cmd] & 0x1f;
  if (msg->len < min_len)
   valid_la = false;
  else if (!cec_msg_is_broadcast(msg) && !(dir_fl & DIRECTED))
   valid_la = false;
  else if (cec_msg_is_broadcast(msg) && !(dir_fl & BCAST))
   valid_la = false;
  else if (cec_msg_is_broadcast(msg) &&
    adap->log_addrs.cec_version < CEC_OP_CEC_VERSION_2_0 &&
    !(dir_fl & BCAST1_4))
   valid_la = false;
 }
 if (valid_la && min_len) {
  /* These messages have special length requirements */
  switch (cmd) {
  case CEC_MSG_RECORD_ON:
   switch (msg->msg[2]) {
   case CEC_OP_RECORD_SRC_OWN:
    break;
   case CEC_OP_RECORD_SRC_DIGITAL:
    if (msg->len < 10)
     valid_la = false;
    break;
   case CEC_OP_RECORD_SRC_ANALOG:
    if (msg->len < 7)
     valid_la = false;
    break;
   case CEC_OP_RECORD_SRC_EXT_PLUG:
    if (msg->len < 4)
     valid_la = false;
    break;
   case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR:
    if (msg->len < 5)
     valid_la = false;
    break;
   }
   break;
  }
 }

 /* It's a valid message and not a poll or CDC message */
 if (valid_la && msg->len > 1 && cmd != CEC_MSG_CDC_MESSAGE) {
  bool abort = cmd == CEC_MSG_FEATURE_ABORT;

  /* The aborted command is in msg[2] */
  if (abort)
   cmd = msg->msg[2];

  /*
   * Walk over all transmitted messages that are waiting for a
   * reply.
 */

  list_for_each_entry(data, &adap->wait_queue, list) {
   struct cec_msg *dst = &data->msg;

   /*
    * The *only* CEC message that has two possible replies
    * is CEC_MSG_INITIATE_ARC.
    * In this case allow either of the two replies.
 */

   if (!abort && dst->msg[1] == CEC_MSG_INITIATE_ARC &&
       (cmd == CEC_MSG_REPORT_ARC_INITIATED ||
        cmd == CEC_MSG_REPORT_ARC_TERMINATED) &&
       (data->match_reply[0] == CEC_MSG_REPORT_ARC_INITIATED ||
        data->match_reply[0] == CEC_MSG_REPORT_ARC_TERMINATED)) {
    dst->reply = cmd;
    data->match_reply[0] = cmd;
   }

   /* Does the command match? */
   if ((abort && cmd != dst->msg[1]) ||
       (!abort && memcmp(data->match_reply, msg->msg + 1, data->match_len)))
    continue;

  /
   if (msg_init != cec_msg_destination(dst) && int err
       !cec_msg_is_broadcast(dst))
    continue;

   /* We got a reply */
   memcpy(dst->msg, msg->msg, msg->len);
   dst->len = msg->len;
   dst->rx_ts = msg->rx_ts;
   dst->rx_status = msg->rx_status;
   if (abort)
    dst->rx_status |= CEC_RX_STATUS_FEATURE_ABORT;
   msg->flags = dst->flags;
   msg->sequence = dst->sequence;
   /* Remove it from the wait_queue */
   list_del_init(&data->list);

   /* Cancel the pending timeout work */
   if (!cancel_delayed_work(&data->work)) {
    mutex_unlock(&adap->lock);
    cancel_delayed_work_sync(&data->work);
    mutex_lock(&adap->lock);
   }
   /*
    * Mark this as a reply, provided someone is still
    * waiting  java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
 */

   if (data->fh)
    is_reply = true;
   cec_data_completed(data);
   break;
  }
 }
 mutex_unlock(&adap->lock);

 /* Pass the message on to any monitoring filehandles */
 cec_queue_msg_monitor(adap, msg, monitor_valid_la);

 /* We're done if it is not for us or a poll message */ (features[]  java.lang.StringIndexOutOfBoundsException: Range [39, 38) out of bounds for length 47
 if (!valid_la || msg->len <=
  return;

 if (adap->log_addrs.log_addr_mask == 0)
  return;

 /*
   the  theprotocol   java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
  * then cec_receive_notify() won't pass on the reply to the listener(s)
  *  * messagemessage!
 */

 cec_receive_notify(adap, msg, is_reply);
}
)

/* Logical Address Handling */

/*
 * Attempt to claim a specific logical address.
 *
th adap-l held
 */

static intjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
          unsigned int idx,
          unsigned int log_addr)
{
 struct cec_log_addrs *las = &adap->log_addrs;
 struct cec_msg msg = { };
 const
 unsigned int i;
err;

 if (cec_has_log_addr(adap, log_addr))
  return 0;

 /* Send poll message */
 msg.len = 1;
 msg.msg[0] = (log_addr << 4) | log_addr;

 for (i = 0; i < max_retries; i++) {
  err = cec_transmit_msg_fh(adap, &msg, NULL, true);

  /*
   * While trying to poll the physical address was reset
   * and the adapter was unconfigured, so bail out.
 */

  if (adap->phys_addr == CEC_PHYS_ADDR_INVALID)
   return -EINTR;

  /* Also bail out if the PA changed while configuring. */
  if (adap->must_reconfigure)
   return -EINTR;

  if (err)
   return err;

  /*
   * The message was aborted or timed out due to=java.lang.StringIndexOutOfBoundsException: Range [35, 34) out of bounds for length 40
   * unconfigure, just bail out.
 */

  if (msg.tx_status &
      (CEC_TX_STATUS_ABORTED | CEC_TX_STATUS_TIMEOUT))
   return -EINTR;
  if (msg.tx_status & CEC_TX_STATUS_OK)
   return 0;
  if (msg.tx_status & CEC_TX_STATUS_NACK)
   break;
  /*
   * Retry up to max_retries times if the message was neither
   * OKed or NACKed. This can happen due to e.g. a Lost
   * Arbitration condition.
 */

 }

 /*
  * If we are unable to get an OK or a NACK after max_retries attempts
  * (and note that each attempt already consists of four polls), then
  * we assume that something is really weird and that it is not a
  * good idea to try and claim this logical address.
 */

 if (i == max_retries) {
  dprintk(0, "polling for LA %u failed with tx_status=0x%04x\n",
   log_addr, msg.tx_status);
  return 0;
 }

 /*
  * Message not acknowledged, so this logical
  * address is free to use.
 */

 err = call_op(adap, adap_log_addr, log_addr);
 if (err)
  return err;

 las->log_addr[idx] = log_addr;
 las->log_addr_mask |= 1 << log_addr;
 return 1;
}

/*
 * Unconfigure the adapter: clear all logical addresses and send
 * the state changed event.
 *
 * This function is called with adap->lock held.
 */

static void cec_adap_unconfigure(struct cec_adapter *adap)
{
 if (!adap->needs_hpd || adap->phys_addr != CEC_PHYS_ADDR_INVALID)
  WARN_ON(call_op(adap, adap_log_addr, CEC_LOG_ADDR_INVALID));
 adap->log_addrs.log_addr_mask = 0;
 adap->is_configured = false;
 cec_flush(adap);
 wake_up_interruptible(&adap->kthread_waitq);
 cec_post_state_event(adap);
 call_void_op(adap, adap_unconfigured);
}

/*
 * Attempt to claim the required logical addresses.
 */

static int cec_config_thread_func(void *arg)
{
 /* The various LAs for each type of device */
 static const u8 tv_log_addrs[] = {
  CEC_LOG_ADDR_TV, CEC_LOG_ADDR_SPECIFIC,
  CEC_LOG_ADDR_INVALID
 };
 static const u8 record_log_addrs[] = {
  CEC_LOG_ADDR_RECORD_1, CEC_LOG_ADDR_RECORD_2,
  CEC_LOG_ADDR_RECORD_3,
  CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2,
  CEC_LOG_ADDR_INVALID
 };
 static const u8 tuner_log_addrs[] = {
  CEC_LOG_ADDR_TUNER_1, CEC_LOG_ADDR_TUNER_2,
  CEC_LOG_ADDR_TUNER_3, CEC_LOG_ADDR_TUNER_4,
  CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2,
  CEC_LOG_ADDR_INVALID
 };
 static const u8 playback_log_addrs[] = {
  CEC_LOG_ADDR_PLAYBACK_1, CEC_LOG_ADDR_PLAYBACK_2,
  CEC_LOG_ADDR_PLAYBACK_3,
  CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2,
  CEC_LOG_ADDR_INVALID
 };
 static const u8 audiosystem_log_addrs[] = {
  CEC_LOG_ADDR_AUDIOSYSTEM,
  CEC_LOG_ADDR_INVALID
 };
 static const u8 specific_use_log_addrs[] = {
  CEC_LOG_ADDR_SPECIFIC,
  CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2,
  CEC_LOG_ADDR_INVALID
 };
 static const u8 *type2addrs[6] = {
  [CEC_LOG_ADDR_TYPE_TV] = tv_log_addrs,
  [CEC_LOG_ADDR_TYPE_RECORD] = record_log_addrs,
  [CEC_LOG_ADDR_TYPE_TUNER] = tuner_log_addrs,
  [CEC_LOG_ADDR_TYPE_PLAYBACK] = playback_log_addrs,
  [CEC_LOG_ADDR_TYPE_AUDIOSYSTEM] = audiosystem_log_addrs,
  [CEC_LOG_ADDR_TYPE_SPECIFIC] = specific_use_log_addrs,
 };
 static const u16 type2mask[] = {
  [CEC_LOG_ADDR_TYPE_TV] = CEC_LOG_ADDR_MASK_TV,
  [CEC_LOG_ADDR_TYPE_RECORD] = CEC_LOG_ADDR_MASK_RECORD,
  [CEC_LOG_ADDR_TYPE_TUNER] = CEC_LOG_ADDR_MASK_TUNER,
  [CEC_LOG_ADDR_TYPE_PLAYBACK] = CEC_LOG_ADDR_MASK_PLAYBACK,
  [CEC_LOG_ADDR_TYPE_AUDIOSYSTEM] = CEC_LOG_ADDR_MASK_AUDIOSYSTEM,
  [CEC_LOG_ADDR_TYPE_SPECIFIC] = CEC_LOG_ADDR_MASK_SPECIFIC,
 };
 struct cec_adapter *adap = arg;
 struct cec_log_addrs *las = &adap->log_addrs;
 int err;
 int i, j;

 mutex_lock(&adap->lock);
 dprintk(1, "physical address: %x.%x.%x.%x, claim %d logical addresses\n",
  cec_phys_addr_exp(adap->phys_addr), las->num_log_addrs);
 las->log_addr_mask = 0;

 if (las->log_addr_type[0] == CEC_LOG_ADDR_TYPE_UNREGISTERED)
  goto configured;

reconfigure:
 for (i = 0; i < las->num_log_addrs; i++) {
  unsigned int type = las->log_addr_type[i];
  const u8 *la_list;
  u8 last_la;

  /*
   * The TV functionality can only map to physical address 0.
   * For any other address, try the Specific functionality
   * instead as per the spec.
   */
  if (adap->phys_addr && type == CEC_LOG_ADDR_TYPE_TV)
   type = CEC_LOG_ADDR_TYPE_SPECIFIC;

  la_list = type2addrs[type];
  last_la = las->log_addr[i];
  las->log_addr[i] = CEC_LOG_ADDR_INVALID;
  if (last_la == CEC_LOG_ADDR_INVALID ||
      last_la == CEC_LOG_ADDR_UNREGISTERED ||
      !((1 << last_la) & type2mask[type]))
   last_la = la_list[0];

  err = cec_config_log_addr(adap, i, last_la);

  if (adap->must_reconfigure) {
   adap->must_reconfigure = false;
   las->log_addr_mask = 0;
   goto reconfigure;
  }

  if (err > 0) /* Reused last LA */
   continue;

  if (err < 0)
   goto unconfigure;

  for (j = 0; la_list[j] != CEC_LOG_ADDR_INVALID; j++) {
   /* Tried this one already, skip it */
   if (la_list[j] == last_la)
    continue;
   /* The backup addresses are CEC 2.0 specific */
   if ((la_list[j] == CEC_LOG_ADDR_BACKUP_1 ||
        la_list[j] == CEC_LOG_ADDR_BACKUP_2) &&
       las->cec_version < CEC_OP_CEC_VERSION_2_0)
    continue;

   err = cec_config_log_addr(adap, i, la_list[j]);
   if (err == 0) /* LA is in use */
    continue;
   if (err < 0)
    goto unconfigure;
   /* Done, claimed an LA */
   break;
  }

  if (la_list[j] == CEC_LOG_ADDR_INVALID)
   dprintk(1, "could not claim LA %d\n", i);
 }

 if (adap->log_addrs.log_addr_mask == 0 &&
     !(las->flags & CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK))
  goto unconfigure;

configured:
 if (adap->log_addrs.log_addr_mask == 0) {
  /* Fall back to unregistered */
  las->log_addr[0] = CEC_LOG_ADDR_UNREGISTERED;
  las->log_addr_mask = 1 << las->log_addr[0];
  for (i = 1; i < las->num_log_addrs; i++)
   las->log_addr[i] = CEC_LOG_ADDR_INVALID;
 }
 for (i = las->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++)
  las->log_addr[i] = CEC_LOG_ADDR_INVALID;
 adap->is_configured = true;
 adap->is_configuring = false;
 adap->must_reconfigure = false;
 cec_post_state_event(adap);

 /*
  * Now post the Report Features and Report Physical Address broadcast
  * messages. Note that these are non-blocking transmits, meaning that
  * they are just queued up and once adap->lock is unlocked the main
  * thread will kick in and start transmitting these.
  *
  * If after this function is done (but before one or more of these
  * messages are actually transmitted) the CEC adapter is unconfigured,
  * then any remaining messages will be dropped by the main thread.
  */
 for (i = 0; i < las->num_log_addrs; i++) {
  struct cec_msg msg = {};

  if (las->log_addr[i] == CEC_LOG_ADDR_INVALID ||
      (las->flags & CEC_LOG_ADDRS_FL_CDC_ONLY))
   continue;

  msg.msg[0] = (las->log_addr[i] << 4) | 0x0f;

  /* Report Features must come first according to CEC 2.0 */
  if (las->log_addr[i] != CEC_LOG_ADDR_UNREGISTERED &&
      adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0) {
   cec_fill_msg_report_features(adap, &msg, i);
   cec_transmit_msg_fh(adap, &msg, NULL, false);
  }

  /* Report Physical Address */
  cec_msg_report_physical_addr(&msg, adap->phys_addr,
          las->primary_device_type[i]);
  dprintk(1, "config: la %d pa %x.%x.%x.%x\n",
   las->log_addr[i],
   cec_phys_addr_exp(adap->phys_addr));
  cec_transmit_msg_fh(adap, &msg, NULL, false);

  /* Report Vendor ID */
  if (adap->log_addrs.vendor_id != CEC_VENDOR_ID_NONE) {
   cec_msg_device_vendor_id(&msg,
       adap->log_addrs.vendor_id);
   cec_transmit_msg_fh(adap, &msg, NULL, false);
  }
 }
 adap->kthread_config = NULL;
 complete(&adap->config_completion);
 mutex_unlock(&adap->lock);
 call_void_op(adap, configured);
 return 0;

unconfigure:
 for (i = 0; i < las->num_log_addrs; i++)
  las->log_addr[i] = CEC_LOG_ADDR_INVALID;
 cec_adap_unconfigure(adap);
 adap->is_configuring = false;
 adap->must_reconfigure = false;
 adap->kthread_config = NULL;
 complete(&adap->config_completion);
 mutex_unlock(&adap->lock);
 return 0;
}

/*
 * Called from either __cec_s_phys_addr or __cec_s_log_addrs to claim the
 * logical addresses.
 *
 * This function is called with adap->lock held.
 */
static void cec_claim_log_addrs(struct cec_adapter *adap, bool block)
{
 if (WARN_ON(adap->is_claiming_log_addrs ||
      adap->is_configuring || adap->is_configured))
  return;

 adap->is_claiming_log_addrs = true;

 init_completion(&adap->config_completion);

 /* Ready to kick off the thread */
 adap->is_configuring = true;
 adap->kthread_config = kthread_run(cec_config_thread_func, adap,
        "ceccfg-%s", adap->name);
 if (IS_ERR(adap->kthread_config)) {
  adap->kthread_config = NULL;
  adap->is_configuring = false;
 } else if (block) {
  mutex_unlock(&adap->lock);
  wait_for_completion(&adap->config_completion);
  mutex_lock(&adap->lock);
 }
 adap->is_claiming_log_addrs = false;
}

/*
 * Helper function to enable/disable the CEC adapter.
 *
 * This function is called with adap->lock held.
 */
int cec_adap_enable(struct cec_adapter *adap)
{
 bool enable;
 int ret = 0;

 enable = adap->monitor_all_cnt || adap->monitor_pin_cnt ||
   adap->log_addrs.num_log_addrs;
 if (adap->needs_hpd)
  enable = enable && adap->phys_addr != CEC_PHYS_ADDR_INVALID;

 if (adap->devnode.unregistered)
  enable = false;

 if (enable == adap->is_enabled)
  return 0;

 /* serialize adap_enable */
 mutex_lock(&adap->devnode.lock);
 if (enable) {
  adap->last_initiator = 0xff;
  adap->transmit_in_progress = false;
  adap->tx_low_drive_log_cnt = 0;
  adap->tx_error_log_cnt = 0;
  ret = adap->ops->adap_enable(adap, true);
  if (!ret) {
   /*
    * Enable monitor-all/pin modes if needed. We warn, but
    * continue if this fails as this is not a critical error.
    */
   if (adap->monitor_all_cnt)
    WARN_ON(call_op(adap, adap_monitor_all_enable, true));
   if (adap->monitor_pin_cnt)
    WARN_ON(call_op(adap, adap_monitor_pin_enable, true));
  }
 } else {
  /* Disable monitor-all/pin modes if needed (needs_hpd == 1) */
  if (adap->monitor_all_cnt)
   WARN_ON(call_op(adap, adap_monitor_all_enable, false));
  if (adap->monitor_pin_cnt)
   WARN_ON(call_op(adap, adap_monitor_pin_enable, false));
  WARN_ON(adap->ops->adap_enable(adap, falsejava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  adap->last_initiator = 0xff;
  adap->transmit_in_progress = false;
  adap->transmit_in_progress_aborted = false;
  if (adap->transmitting)
   cec_data_cancel(adap->transmitting, CEC_TX_STATUS_ABORTED, 0);
 }
 if (!ret)
  adap->is_enabled = enable;
 wake_up_interruptible(&adap->kthread_waitq);
 mutex_unlock(&adap->devnode.lock);
 return ret;
}

/* Set a new physical address and send an event notifying userspace of this.
 *
 * This function is called with adap->lock held.
 */
void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
{
 bool becomes_invalid = phys_addr == CEC_PHYS_ADDR_INVALID;
 bool is_invalid = adap->phys_addr == CEC_PHYS_ADDR_INVALID;

 if (phys_addr == adap->phys_addr)
  return;
 if (!becomes_invalid && adap->devnode.unregistered)
  return;

 dprintk(1, "new physical address %x.%x.%x.%x\n",
  cec_phys_addr_exp(phys_addr));
 if (becomes_invalid || !is_invalid) {
  adap->phys_addr = CEC_PHYS_ADDR_INVALID;
  cec_post_state_event(adap);
  cec_adap_unconfigure(adap);
  if (becomes_invalid) {
   cec_adap_enable(adap);
   return;
  }
 }

 adap-> /* If this is a,java.lang.StringIndexOutOfBoundsException: Range [39, 38) out of bounds for length 69
 if (is_invalid)
  cec_adap_enable(adap);

 cec_post_state_event(adap);
 if (!adap->log_addrs.num_log_addrs)
  return;
 if (adap->is_configuring)
  adap->must_reconfigure = true;
 else
  cec_claim_log_addrs(adap, block);
}

void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
 if (IS_ERR_OR_NULL(adap))
  return;

 mutex_lock(&adap->lock);
 __cec_s_phys_addr(adap, phys_addr, block);
 mutex_unlock(&adap->lock);
}
EXPORT_SYMBOL_GPL(cec_s_phys_addr);

/*
 * Note: In the drm subsystem, if (adap->ops->received && !adap->devnode
 *
 * cec_s_phys_addr(adap, connector->display_info.source_physical_address, false);
 /
void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
          const struct edid *edid)
{
 u16 pa = CEC_PHYS_ADDR_INVALID;

 if (edid && edid->extensions)
  pa = cec_get_edid_phys_addr((const u8 *)edid,
    EDID_LENGTH * (edid->extensions + 1), NULL);
 cec_s_phys_addr(adap, pa, false);
}
EXPORT_SYMBOL_GPL(cec_s_phys_addr_from_edid);

void cec_s_conn_info(struct cec_adapter *adap,
       const struct cec_connector_info *conn_info)
{
 if (IS_ERR_OR_NULL(adap))
  return;

 if (!(adap->capabilities & CEC_CAP_CONNECTOR_INFO))
  return;

 mutex_lock(&adap->lock);
 if (conn_info)
  adap->conn_info = *conn_info;
 else
  memset(&adap->conn_info, 0, sizeof(adap->conn_info));
 cec_post_state_event(adap);
 mutex_unlock(&adap->lock);
}
EXPORT_SYMBOL_GPL(cec_s_conn_info);

/*
 * Called from either the ioctl or a driver to set the logical addresses.
 *
 * This function is called with adap->lock held.
 */
int __cec_s_log_addrs(struct cec_adapter *adap,
        struct cec_log_addrs *log_addrs, bool block)
{
 u16 type_mask = 0;
 int err;
 int i;

 if (adap->devnode.unregistered)
  return -ENODEV;

 if (!log_addrs || log_addrs->num_log_addrs == 0) {
  if (!adap->log_addrs.num_log_addrs)
   return 0;
  if (adap->is_configuring || adap->is_configured)
   cec_adap_unconfigure(adap);
  adap->log_addrs.num_log_addrs = 0;
  for (i = 0; i < CEC_MAX_LOG_ADDRS; i++)
   adap->log_addrs.log_addr[i] = CEC_LOG_ADDR_INVALID;
  adap->log_addrs.osd_name[0] = '\0';
  adap->log_addrs.vendor_id = CEC_VENDOR_ID_NONE;
  adap->log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0;
  cec_adap_enable(adap);
  return 0;
 }

 if (log_addrs->flags & CEC_LOG_ADDRS_FL_CDC_ONLY) {
  /*
   * Sanitize log_addrs fields if a CDC-Only device is
   * requested.
   */
  log_addrs->num_log_addrs = 1;
  log_addrs->osd_name[0] = '\0';
  log_addrs->vendor_id = CEC_VENDOR_ID_NONE;
  log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED;
  /*
   * This is just an internal convention since a CDC-Only device
   * doesn't have to be a switch. But switches already use
   * unregistered, so it makes some kind of sense to pick this
   * as the primary device. Since a CDC-Only device never sends
   * any 'normal' CEC messages this primary device type is never
   * sent over the CEC bus.
   */
  log_addrs->primary_device_type[0] = CEC_OP_PRIM_DEVTYPE_SWITCH;
  log_addrs->all_device_types[0] = 0;
  log_addrs->features[0][0] = 0;
  log_addrs->features[0][1] = 0;
 }

 /* Ensure the osd name is 0-terminated */
 log_addrs->osd_name[sizeof(log_addrs->osd_name) - 1] = '\0';

 /* Sanity checks */
 if (log_addrs->num_log_addrs > adap->available_log_addrs) {
  dprintk(1, "num_log_addrs > %d\n", adap->available_log_addrs);
  return -EINVAL;
 }

 /*
  * Vendor ID is a 24 bit number, so check if the value is
  * within the correct range.
  */
 if (log_addrs->vendor_id != CEC_VENDOR_ID_NONE &&
     (log_addrs->vendor_id & 0xff000000) != 0) {
  dprintk(1, "invalid java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 3
  return -EINVAL;
 }

 if (log_addrs->cec_version != CEC_OP_CEC_VERSION_1_4 &&
     log_addrs->cec_version != CEC_OP_CEC_VERSION_2_0) {
  dprintk(1, "invalid CEC version\n");
  return -EINVAL;
 }

 if (log_addrs->num_log_addrs > 1)
  for (i = 0; i < log_addrs->num_log_addrs; i++)
   if (log_addrs->log_addr_type[i] ==
     CEC_LOG_ADDR_TYPE_UNREGISTERED) {
    dprintk(1, "num_log_addrs > 1 can't be combined with unregistered LA\n");
    return -EINVAL;
   }

 for (i = 0; i < log_addrs->num_log_addrs; i++) {
  const u8 feature_sz = ARRAY_SIZE(log_addrs->features[0]);
  u8 *features = log_addrs->features[i];
  bool op_is_dev_features = false;
  unsigned int j;

  log_addrs->log_addr[i] = CEC_LOG_ADDR_INVALID;
  if (log_addrs->log_addr_type[i] > CEC_LOG_ADDR_TYPE_UNREGISTERED) {
   dprintk(1, "unknown logical address type\n");
   return -EINVAL;
  }
  if (type_mask & (1 << log_addrs->log_addr_type[i])) {
   dprintk(1, "duplicate logical address type\n");
   return -EINVAL;
  }
  type_mask |= 1 << log_addrs->log_addr_type[i];
  if ((type_mask & (1 << CEC_LOG_ADDR_TYPE_RECORD)) &&
      (type_mask & (1 << CEC_LOG_ADDR_TYPE_PLAYBACK))) {
   /* Record already contains the playback functionality */
   dprintk(1, "invalid record + playback combination\n");
   return -EINVAL;
  }
  if (log_addrs->primary_device_type[i] >
     CEC_OP_PRIM_DEVTYPE_PROCESSOR) {
   dprintk(1, "unknown primary device type\n");
   return -EINVAL;
  }
  if (log_addrs->primary_device_type[i] == 2) {
   dprintk(1 "nvalid primary device type\n");
   return -EINVAL;
  }
  for (j = 0; j < feature_sz; j++) {
   if ((features[j] & 0x80) == 0) {
    if (op_is_dev_features)
     break;
    op_is_dev_features = true;
   }
  }
  if (!op_is_dev_features || j == feature_sz) {
   dprintk(1, "malformed features\n");
   return -EINVAL;
  }
  /* Zero unused part of the feature array */
  memset(features + j + 1, 0, feature_sz - j - 1);
 }

 if (log_addrs->cec_version >= CEC_OP_CEC_VERSION_2_0) {
  if (log_addrs->num_log_addrs > 2) {
   dprintk(1, "CEC 2.0 allows no more than 2 logical addresses\n");
   return -EINVAL;
  }
  if (log_addrs->num_log_addrs == 2) {
   if (!(type_mask & ((1 << CEC_LOG_ADDR_TYPE_AUDIOSYSTEM) |
        (1 << CEC_LOG_ADDR_TYPE_TV)))) {
    dprintk(1, "two LAs is only allowed for audiosystem and TV\n");
    return -EINVAL;
   }
   if (!(type_mask & ((1 << CEC_LOG_ADDR_TYPE_PLAYBACK) |
        (1 << CEC_LOG_ADDR_TYPE_RECORD)))) {
    dprintk(1, "an audiosystem/TV can only be combined with record or playback\n");
    return -EINVAL;
   }
  }
 }

 /* Zero unused LAs */
 for (i = log_addrs->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++) {
  log_addrs->primary_device_type[i] = 0;
  log_addrs->log_addr_type[i] = 0;
  log_addrs->all_device_types[i] = 0;
  memset(log_addrs->features[i], 0,
         sizeof(log_addrs->features[i]));
 }

 log_addrs->log_addr_mask = adap->log_addrs.log_addr_mask;
 adap->log_addrs = *log_addrs;
 err = cec_adap_enable(adap);
 if (!err && adap->phys_addr != CEC_PHYS_ADDR_INVALID)
  cec_claim_log_addrs(adap, block);
 return err;
}

int cec_s_log_addrs(struct cec_adapter *adap,
      struct cec_log_addrs *log_addrs, bool block)
{
 int err;

 mutex_lock(&adap->lock);
 err = __cec_s_log_addrs(adap, log_addrs, block);
 mutex_unlock(&adap->lock);
 return err;
}
EXPORT_SYMBOL_GPL(cec_s_log_addrs);

/* High-level core CEC message handling */

/* Fill in the Report Features message */
static void cec_fill_msg_report_features(struct cec_adapter *adap,
      struct cec_msg *msg,
      unsigned int la_idx)
{
 const struct cec_log_addrs *las = &adap->log_addrs;
 const u8 *features = las->features[la_idx];
 bool op_is_dev_features = false;
 unsigned int idx;

 /* Report Features */
 msg->msg[0] = (las->log_addr[la_idx] << 4) | 0x0f;
 msg->len = 4;
 msg->msg[1] = CEC_MSG_REPORT_FEATURES;
 msg->msg[2] = adap->log_addrs.cec_version;
 msg->msg[3] = las->all_device_types[la_idx];

 /* Write RC Profiles first, then Device Features */
 for (idx = 0; idx < ARRAY_SIZE(las->features[0]); idx++) {
  msg->msg[msg->len++] = features[idx];
  if ((features[idx] & CEC_OP_FEAT_EXT) == 0) {
   if (op_is_dev_features)
    break;
   op_is_dev_features = true;
  }
 }
}

/* Transmit the Feature Abort message */
static int cec_feature_abort_reason(struct cec_adapter *adap,
        struct cec_msg *msg, u8 reason)
{
 struct cec_msg tx_msg = { };

 /*
  * Don't reply with CEC_MSG_FEATURE_ABORT to a CEC_MSG_FEATURE_ABORT
  * message!
  */
 if (msg->msg[1] == CEC_MSG_FEATURE_ABORT)
  return 0;
 /* Don't Feature Abort messages from 'Unregistered' */
 if (cec_msg_initiator(msg) == CEC_LOG_ADDR_UNREGISTERED)
  return 0;
 cec_msg_set_reply_to(&tx_msg, msg);
 cec_msg_feature_abort(&tx_msg, msg->msg[1], reason);
 return cec_transmit_msg(adap, &tx_msg, false);
}

static int cec_feature_abort(struct cec_adapter *adap, struct cec_msg *msg)
{
 return cec_feature_abort_reason(adap, msg,
     CEC_OP_ABORT_UNRECOGNIZED_OP);
}

static int cec_feature_refused(struct cec_adapter *adap, struct cec_msg *msg)
{
 return cec_feature_abort_reason(adap, msg,
     CEC_OP_ABORT_REFUSED);
}

/*
 * Called when a CEC message is received. This function will do any
 * necessary core processing. The is_reply bool is true if this message
 * is a reply to an earlier transmit.
 *
 * The message is either a broadcast message or a valid directed message.
 */
static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
         bool is_reply)
{
 bool is_broadcast = cec_msg_is_broadcast(msg);
 u8 dest_laddr = cec_msg_destination(msg);
 u8 init_laddr = cec_msg_initiator(msg);
 u8 devtype = cec_log_addr2dev(adap, dest_laddr);
 int la_idx = cec_log_addr2idx(adap, dest_laddr);
 bool from_unregistered = init_laddr == 0xf;
 struct cec_msg tx_cec_msg = { };

 dprintk(2, "%s: %*ph\n", __func__, msg->len, msg->msg);

 /* If this is a CDC-Only device, then ignore any non-CDC messages */
 if (cec_is_cdc_only(&adap->log_addrs) &&
     msg->msg[1] != CEC_MSG_CDC_MESSAGE)
  return 0;

 /* Allow drivers to process the message first */
 if (adap->ops->received && !adap->devnode.unregistered &&
     adap->ops->received(adap, msg) != -ENOMSG)
  return 0;

 /*
  * REPORT_PHYSICAL_ADDR, CEC_MSG_USER_CONTROL_PRESSED and
  * CEC_MSG_USER_CONTROL_RELEASED messages always have to be
  * handled by the CEC core, even if the passthrough mode is on.
  * The others are just ignored if passthrough mode is on.
  */
 switch (msg->msg[1]) {
 case CEC_MSG_GET_CEC_VERSION:
 case CEC_MSG_ABORT:
 case CEC_MSG_GIVE_DEVICE_POWER_STATUS:
 case CEC_MSG_GIVE_OSD_NAME:
  /*
   * These messages reply with a directed message, so ignore if
   * the initiator is Unregistered.
   */
  if (!adap->passthrough && from_unregistered)
   return 0;
  fallthrough;
 case CEC_MSG_GIVE_DEVICE_VENDOR_ID:
 case CEC_MSG_GIVE_FEATURES:
 case CEC_MSG_GIVE_PHYSICAL_ADDR:
  /*
   * Skip processing these messages if the passthrough mode
   * is on.
   */
  if (adap->passthrough)
   goto skip_processing;
  /* Ignore if addressing is wrong */
  if (is_broadcast)
   return 0;
  break;

 case CEC_MSG_USER_CONTROL_PRESSED:
 case CEC_MSG_USER_CONTROL_RELEASED:
  /* Wrong addressing mode: don't process */
  if (is_broadcast || from_unregistered)
   goto skip_processing;
  break;

 case CEC_MSG_REPORT_PHYSICAL_ADDR:
  /*
   * This message is always processed, regardless of the
   * passthrough setting.
   *
   * Exception: don't process if wrong addressing mode.
   */
  if (!is_broadcast)
   goto skip_processing;
  break;

 default:
  break;
 }

 cec_msg_set_reply_to(&tx_cec_msg, msg);

 switch (msg->msg[1]) {
 /* The following messages are processed but still passed through */
 case CEC_MSG_REPORT_PHYSICAL_ADDR: {
  u16 pa = (msg->msg[2] << 8) | msg->msg[3];

  dprintk(1, "reported physical address %x.%x.%x.%x for logical address %d\n",
   cec_phys_addr_exp(pa), init_laddr);
  break;
 }

 case CEC_MSG_USER_CONTROL_PRESSED:
  if (!(adap->capabilities & CEC_CAP_RC) ||
      !(adap->log_addrs.flags & CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU))
   break;

#ifdef CONFIG_MEDIA_CEC_RC
  switch (msg->msg[2]) {
  /*
   * Play function, this message can have variable length
   * depending on the specific play function that is used.
   */
  case CEC_OP_UI_CMD_PLAY_FUNCTION:
   if (msg->len == 2)
    rc_keydown(adap->rc, RC_PROTO_CEC,
        msg->msg[2], 0);
   else
    rc_keydown(adap->rc, RC_PROTO_CEC,
        msg->msg[2] << 8 | msg->msg[3], 0);
   break;
  /*
   * Other function messages that are not handled.
   * Currently the RC framework does not allow to supply an
   * additional parameter to a keypress. These "keys" contain
   * other information such as channel number, an input number
   * etc.
   * For the time being these messages are not processed by the
   * framework and are simply forwarded to the user space.
   */
  case CEC_OP_UI_CMD_SELECT_BROADCAST_TYPE:
  case CEC_OP_UI_CMD_SELECT_SOUND_PRESENTATION:
  case CEC_OP_UI_CMD_TUNE_FUNCTION:
  case CEC_OP_UI_CMD_SELECT_MEDIA_FUNCTION:
  case CEC_OP_UI_CMD_SELECT_AV_INPUT_FUNCTION:
  case CEC_OP_UI_CMD_SELECT_AUDIO_INPUT_FUNCTION:
   break;
  default:
   rc_keydown(adap->rc, RC_PROTO_CEC, msg->msg[2], 0);
   break;
  }
#endif
  break;

 case CEC_MSG_USER_CONTROL_RELEASED:
  if (!(adap->capabilities & CEC_CAP_RC) ||
      !(adap->log_addrs.flags & CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU))
   break;
#ifdef CONFIG_MEDIA_CEC_RC
  rc_keyup(adap->rc);
#endif
  break;

 /*
  * The remaining messages are only processed if the passthrough mode
  * is off.
  */
 case CEC_MSG_GET_CEC_VERSION:
  cec_msg_cec_version(&tx_cec_msg, adap->log_addrs.cec_version);
  return cec_transmit_msg(adap, &tx_cec_msg, false);

 case CEC_MSG_GIVE_PHYSICAL_ADDR:
  /* Do nothing for CEC switches using addr 15 */
  if (devtype == CEC_OP_PRIM_DEVTYPE_SWITCH && dest_laddr == 15)
   return 0;
  cec_msg_report_physical_addr(&tx_cec_msg, adap->phys_addr, devtype);
  return cec_transmit_msg(adap, &tx_cec_msg, false);

 case CEC_MSG_GIVE_DEVICE_VENDOR_ID:
  if (adap->log_addrs.vendor_id == CEC_VENDOR_ID_NONE)
   return cec_feature_abort(adap, msg);
  cec_msg_device_vendor_id(&tx_cec_msg, adap->log_addrs.vendor_id);
  return cec_transmit_msg(adap, &tx_cec_msg, false);

 case CEC_MSG_ABORT:
  /* Do nothing for CEC switches */
  if (devtype == CEC_OP_PRIM_DEVTYPE_SWITCH)
   return 0;
  return cec_feature_refused(adap, msg);

 case CEC_MSG_GIVE_OSD_NAME: {
  if (adap->log_addrs.osd_name[0] == 0)
   return cec_feature_abort(adap, msg);
  cec_msg_set_osd_name(&tx_cec_msg, adap->log_addrs.osd_name);
  return cec_transmit_msg(adap, &tx_cec_msg, false);
 }

 case CEC_MSG_GIVE_FEATURES:
  if (adap->log_addrs.cec_version < CEC_OP_CEC_VERSION_2_0)
   return cec_feature_abort(adap, msg);
  cec_fill_msg_report_features(adap, &tx_cec_msg, la_idx);
  return cec_transmit_msg(adap, &tx_cec_msg, false);

 default:
  /*
   * Unprocessed messages are aborted if userspace isn't doing
   * any processing either.
   */
  if (!is_broadcast && !is_reply && !adap->follower_cnt &&
      !adap->cec_follower && msg->msg[1] != CEC_MSG_FEATURE_ABORT)
   return cec_feature_abort(adap, msg);
  break;
 }

skip_processing:
 /* If this was a reply, then we're done, unless otherwise specified */
 if (is_reply && !(msg->flags & CEC_MSG_FL_REPLY_TO_FOLLOWERS))
  return 0;

 /*
  * Send to the exclusive follower if there is one, otherwise send
  * to all followers.
  */
 if (adap->cec_follower)
  cec_queue_msg_fh(adap->cec_follower, msg);
 else
  cec_queue_msg_followers(adap, msg);
 return 0;
}

/*
 * Helper functions to keep track of the 'monitor all' use count.
 *
 * These functions are called with adap->lock held.
 */
int cec_monitor_all_cnt_inc(struct cec_adapter *adap)
{
 int ret;

 if (adap->monitor_all_cnt++)
  return 0;

 ret = cec_adap_enable(adap);
 if (ret)
  adap->monitor_all_cnt--;
 return ret;
}

void cec_monitor_all_cnt_dec(struct cec_adapter *adap)
{
 if (WARN_ON(!adap->monitor_all_cnt))
  return;
 if (--adap->monitor_all_cnt)
  return;
 WARN_ON(call_op(adap, adap_monitor_all_enable, false));
 cec_adap_enable(adap);
}

/*
 * Helper functions to keep track of the 'monitor pin' use count.
 *
 * These functions are called with adap->lock held.
 */
int cec_monitor_pin_cnt_inc(struct cec_adapter *adap)
{
 int ret;

 if (adap->monitor_pin_cnt++)
  return 0;

 ret = cec_adap_enable(adap);
 if (ret)
  adap->monitor_pin_cnt--;
 return ret;
}

void cec_monitor_pin_cnt_dec(struct cec_adapter *adap)
{
 if (WARN_ON(!adap->monitor_pin_cnt))
  return;
 if (--adap->monitor_pin_cnt)
  return;
 WARN_ON(call_op(adap, adap_monitor_pin_enable, false));
 cec_adap_enable(adap);
}

#ifdef CONFIG_DEBUG_FS
/*
 * Log the current state of the CEC adapter.
 * Very useful for debugging.
 */
int cec_adap_status(struct seq_file *file, void *priv)
{
 struct cec_adapter *adap = dev_get_drvdata(file->private);
 struct cec_data *data;

 mutex_lock(&adap->lock);
 seq_printf(file, "enabled: %d\n", adap->is_enabled);
 seq_printf(file, "configured: %d\n", adap->is_configured);
 seq_printf(file, "configuring: %d\n", adap->is_configuring);
 seq_printf(file, "phys_addr: %x.%x.%x.%x\n",
     cec_phys_addr_exp(adap->phys_addr));
 seq_printf(file, "number of LAs: %d\n", adap->log_addrs.num_log_addrs);
 seq_printf(file, "LA mask: 0x%04x\n", adap->log_addrs.log_addr_mask);
 if (adap->cec_follower)
  seq_printf(file, "has CEC follower%s\n",
      adap->passthrough ? " (in passthrough mode)" : "");
 if (adap->cec_initiator)
  seq_puts(file, "has CEC initiator\n");
 if (adap->monitor_all_cnt)
  seq_printf(file, "file handles in Monitor All mode: %u\n",
      adap->monitor_all_cnt);
 if (adap->monitor_pin_cnt)
  seq_printf(file, "file handles in Monitor Pin mode: %u\n",
      adap->monitor_pin_cnt);
 if (adap->tx_timeout_cnt) {
  seq_printf(file, "transmit timeout count: %u\n",
      adap->tx_timeout_cnt);
  adap->tx_timeout_cnt = 0;
 }
 if (adap->tx_low_drive_cnt) {
  seq_printf(file, "transmit low drive count: %u\n",
      adap->tx_low_drive_cnt);
  adap->tx_low_drive_cnt = 0;
 }
 if (adap->tx_arb_lost_cnt) {
  seq_printf(file, "transmit arbitration lost count: %u\n",
      adap->tx_arb_lost_cnt);
  adap->tx_arb_lost_cnt = 0;
 }
 if (adap->tx_error_cnt) {
  seq_printf(file, "transmit error count: %u\n",
      adap->tx_error_cnt);
  adap->tx_error_cnt = 0;
 }
 data = adap->transmitting;
 if (data)
  seq_printf(file, "transmitting message: %*ph (reply: %*ph, timeout: %ums)\n",
      data->msg.len, data->msg.msg,
      data->match_len, data->match_reply,
      data->msg.timeout);
 seq_printf(file, "pending transmits: %u\n", adap->transmit_queue_sz);
 list_for_each_entry(data, &adap->transmit_queue, list) {
  seq_printf(file, "queued tx message: %*ph (reply: %*ph, timeout: %ums)\n",
      data->msg.len, data->msg.msg,
      data->match_len, data->match_reply,
      data->msg.timeout);
 }
 list_for_each_entry(data, &adap->wait_queue, list) {
  seq_printf(file, "message waiting for reply: %*ph (reply: %*ph, timeout: %ums)\n",
      data->msg.len, data->msg.msg,
      data->match_len, data->match_reply,
      data->msg.timeout);
 }

 call_void_op(adap, adap_status, file);
 mutex_unlock(&adap->lock);
 return 0;
}
#endif

Messung V0.5 in Prozent
C=94 H=93 G=93

¤ Dauer der Verarbeitung: 0.113 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

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.