^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Greybus operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2014-2015 Google Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright 2014-2015 Linaro Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/greybus.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "greybus_trace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) static struct kmem_cache *gb_operation_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static struct kmem_cache *gb_message_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /* Workqueue to handle Greybus operation completions. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static struct workqueue_struct *gb_operation_completion_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* Wait queue for synchronous cancellations. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static DECLARE_WAIT_QUEUE_HEAD(gb_operation_cancellation_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Protects updates to operation->errno.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static DEFINE_SPINLOCK(gb_operations_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static int gb_operation_response_send(struct gb_operation *operation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) int errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * Increment operation active count and add to connection list unless the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * connection is going away.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * Caller holds operation reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static int gb_operation_get_active(struct gb_operation *operation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct gb_connection *connection = operation->connection;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) spin_lock_irqsave(&connection->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) switch (connection->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) case GB_CONNECTION_STATE_ENABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) case GB_CONNECTION_STATE_ENABLED_TX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (gb_operation_is_incoming(operation))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) case GB_CONNECTION_STATE_DISCONNECTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (!gb_operation_is_core(operation))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (operation->active++ == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) list_add_tail(&operation->links, &connection->operations);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) trace_gb_operation_get_active(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) spin_unlock_irqrestore(&connection->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) err_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) spin_unlock_irqrestore(&connection->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* Caller holds operation reference. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static void gb_operation_put_active(struct gb_operation *operation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct gb_connection *connection = operation->connection;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) spin_lock_irqsave(&connection->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) trace_gb_operation_put_active(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (--operation->active == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) list_del(&operation->links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (atomic_read(&operation->waiters))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) wake_up(&gb_operation_cancellation_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) spin_unlock_irqrestore(&connection->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static bool gb_operation_is_active(struct gb_operation *operation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct gb_connection *connection = operation->connection;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) bool ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) spin_lock_irqsave(&connection->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) ret = operation->active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) spin_unlock_irqrestore(&connection->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * Set an operation's result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * Initially an outgoing operation's errno value is -EBADR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * If no error occurs before sending the request message the only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * valid value operation->errno can be set to is -EINPROGRESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * indicating the request has been (or rather is about to be) sent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * At that point nobody should be looking at the result until the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * response arrives.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * The first time the result gets set after the request has been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * sent, that result "sticks." That is, if two concurrent threads
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * race to set the result, the first one wins. The return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * tells the caller whether its result was recorded; if not the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * caller has nothing more to do.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * The result value -EILSEQ is reserved to signal an implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * error; if it's ever observed, the code performing the request has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * done something fundamentally wrong. It is an error to try to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * the result to -EBADR, and attempts to do so result in a warning,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * and -EILSEQ is used instead. Similarly, the only valid result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * value to set for an operation in initial state is -EINPROGRESS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * Attempts to do otherwise will also record a (successful) -EILSEQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * operation result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static bool gb_operation_result_set(struct gb_operation *operation, int result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (result == -EINPROGRESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * -EINPROGRESS is used to indicate the request is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * in flight. It should be the first result value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * set after the initial -EBADR. Issue a warning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * and record an implementation error if it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * set at any other time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) spin_lock_irqsave(&gb_operations_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) prev = operation->errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (prev == -EBADR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) operation->errno = result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) operation->errno = -EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) spin_unlock_irqrestore(&gb_operations_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) WARN_ON(prev != -EBADR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * The first result value set after a request has been sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * will be the final result of the operation. Subsequent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * attempts to set the result are ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * Note that -EBADR is a reserved "initial state" result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * value. Attempts to set this value result in a warning,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * and the result code is set to -EILSEQ instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (WARN_ON(result == -EBADR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) result = -EILSEQ; /* Nobody should be setting -EBADR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) spin_lock_irqsave(&gb_operations_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) prev = operation->errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (prev == -EINPROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) operation->errno = result; /* First and final result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) spin_unlock_irqrestore(&gb_operations_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return prev == -EINPROGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) int gb_operation_result(struct gb_operation *operation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) int result = operation->errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) WARN_ON(result == -EBADR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) WARN_ON(result == -EINPROGRESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) EXPORT_SYMBOL_GPL(gb_operation_result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * Looks up an outgoing operation on a connection and returns a refcounted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * pointer if found, or NULL otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static struct gb_operation *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) gb_operation_find_outgoing(struct gb_connection *connection, u16 operation_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct gb_operation *operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) spin_lock_irqsave(&connection->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) list_for_each_entry(operation, &connection->operations, links)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (operation->id == operation_id &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) !gb_operation_is_incoming(operation)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) gb_operation_get(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) spin_unlock_irqrestore(&connection->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return found ? operation : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static int gb_message_send(struct gb_message *message, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct gb_connection *connection = message->operation->connection;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) trace_gb_message_send(message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return connection->hd->driver->message_send(connection->hd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) connection->hd_cport_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) message,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * Cancel a message we have passed to the host device layer to be sent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static void gb_message_cancel(struct gb_message *message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct gb_host_device *hd = message->operation->connection->hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) hd->driver->message_cancel(message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static void gb_operation_request_handle(struct gb_operation *operation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct gb_connection *connection = operation->connection;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (connection->handler) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) status = connection->handler(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) dev_err(&connection->hd->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) "%s: unexpected incoming request of type 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) connection->name, operation->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) status = -EPROTONOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) ret = gb_operation_response_send(operation, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) dev_err(&connection->hd->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) "%s: failed to send response %d for type 0x%02x: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) connection->name, status, operation->type, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * Process operation work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * For incoming requests, call the protocol request handler. The operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * result should be -EINPROGRESS at this point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * For outgoing requests, the operation result value should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * been set before queueing this. The operation callback function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * allows the original requester to know the request has completed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * and its result is available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static void gb_operation_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) struct gb_operation *operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) operation = container_of(work, struct gb_operation, work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (gb_operation_is_incoming(operation)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) gb_operation_request_handle(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) ret = del_timer_sync(&operation->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) /* Cancel request message if scheduled by timeout. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (gb_operation_result(operation) == -ETIMEDOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) gb_message_cancel(operation->request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) operation->callback(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) gb_operation_put_active(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) gb_operation_put(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static void gb_operation_timeout(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct gb_operation *operation = from_timer(operation, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (gb_operation_result_set(operation, -ETIMEDOUT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * A stuck request message will be cancelled from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * workqueue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) queue_work(gb_operation_completion_wq, &operation->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static void gb_operation_message_init(struct gb_host_device *hd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct gb_message *message,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) u16 operation_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) size_t payload_size, u8 type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) struct gb_operation_msg_hdr *header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) header = message->buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) message->header = header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) message->payload = payload_size ? header + 1 : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) message->payload_size = payload_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * The type supplied for incoming message buffers will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * GB_REQUEST_TYPE_INVALID. Such buffers will be overwritten by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * arriving data so there's no need to initialize the message header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (type != GB_REQUEST_TYPE_INVALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) u16 message_size = (u16)(sizeof(*header) + payload_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * For a request, the operation id gets filled in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) * when the message is sent. For a response, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * will be copied from the request by the caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * The result field in a request message must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * zero. It will be set just prior to sending for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * a response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) header->size = cpu_to_le16(message_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) header->operation_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) header->type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) header->result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * Allocate a message to be used for an operation request or response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * Both types of message contain a common header. The request message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * for an outgoing operation is outbound, as is the response message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * for an incoming operation. The message header for an outbound
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * message is partially initialized here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * The headers for inbound messages don't need to be initialized;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * they'll be filled in by arriving data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * Our message buffers have the following layout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * message header \_ these combined are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * message payload / the message size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static struct gb_message *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) gb_operation_message_alloc(struct gb_host_device *hd, u8 type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) size_t payload_size, gfp_t gfp_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct gb_message *message;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct gb_operation_msg_hdr *header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) size_t message_size = payload_size + sizeof(*header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (message_size > hd->buffer_size_max) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) dev_warn(&hd->dev, "requested message size too big (%zu > %zu)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) message_size, hd->buffer_size_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) /* Allocate the message structure and buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) message = kmem_cache_zalloc(gb_message_cache, gfp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (!message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) message->buffer = kzalloc(message_size, gfp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (!message->buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) goto err_free_message;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* Initialize the message. Operation id is filled in later. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) gb_operation_message_init(hd, message, 0, payload_size, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return message;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) err_free_message:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) kmem_cache_free(gb_message_cache, message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) static void gb_operation_message_free(struct gb_message *message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) kfree(message->buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) kmem_cache_free(gb_message_cache, message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * Map an enum gb_operation_status value (which is represented in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * message as a single byte) to an appropriate Linux negative errno.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static int gb_operation_status_map(u8 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) case GB_OP_SUCCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) case GB_OP_INTERRUPTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) case GB_OP_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) case GB_OP_NO_MEMORY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) case GB_OP_PROTOCOL_BAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) return -EPROTONOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) case GB_OP_OVERFLOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) case GB_OP_INVALID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) case GB_OP_RETRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) case GB_OP_NONEXISTENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) case GB_OP_MALFUNCTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return -EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) case GB_OP_UNKNOWN_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * Map a Linux errno value (from operation->errno) into the value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * that should represent it in a response message status sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * over the wire. Returns an enum gb_operation_status value (which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * is represented in a message as a single byte).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static u8 gb_operation_errno_map(int errno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) switch (errno) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return GB_OP_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) case -EINTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return GB_OP_INTERRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) case -ETIMEDOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return GB_OP_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) case -ENOMEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return GB_OP_NO_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) case -EPROTONOSUPPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return GB_OP_PROTOCOL_BAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) case -EMSGSIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return GB_OP_OVERFLOW; /* Could be underflow too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) case -EINVAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return GB_OP_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) case -EAGAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return GB_OP_RETRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) case -EILSEQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return GB_OP_MALFUNCTION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) case -ENODEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return GB_OP_NONEXISTENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) case -EIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return GB_OP_UNKNOWN_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) bool gb_operation_response_alloc(struct gb_operation *operation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) size_t response_size, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) struct gb_host_device *hd = operation->connection->hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct gb_operation_msg_hdr *request_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct gb_message *response;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) u8 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) type = operation->type | GB_MESSAGE_TYPE_RESPONSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) response = gb_operation_message_alloc(hd, type, response_size, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (!response)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) response->operation = operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * Size and type get initialized when the message is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * allocated. The errno will be set before sending. All
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * that's left is the operation id, which we copy from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * request message header (as-is, in little-endian order).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) request_header = operation->request->header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) response->header->operation_id = request_header->operation_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) operation->response = response;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) EXPORT_SYMBOL_GPL(gb_operation_response_alloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) * Create a Greybus operation to be sent over the given connection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) * The request buffer will be big enough for a payload of the given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) * size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) * For outgoing requests, the request message's header will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) * initialized with the type of the request and the message size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) * Outgoing operations must also specify the response buffer size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) * which must be sufficient to hold all expected response data. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * response message header will eventually be overwritten, so there's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * no need to initialize it here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) * Request messages for incoming operations can arrive in interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) * context, so they must be allocated with GFP_ATOMIC. In this case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * the request buffer will be immediately overwritten, so there is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * no need to initialize the message header. Responsibility for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * allocating a response buffer lies with the incoming request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) * handler for a protocol. So we don't allocate that here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * Returns a pointer to the new operation or a null pointer if an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * error occurs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) static struct gb_operation *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) gb_operation_create_common(struct gb_connection *connection, u8 type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) size_t request_size, size_t response_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) unsigned long op_flags, gfp_t gfp_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) struct gb_host_device *hd = connection->hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct gb_operation *operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) operation = kmem_cache_zalloc(gb_operation_cache, gfp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (!operation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) operation->connection = connection;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) operation->request = gb_operation_message_alloc(hd, type, request_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) gfp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (!operation->request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) goto err_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) operation->request->operation = operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /* Allocate the response buffer for outgoing operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (!(op_flags & GB_OPERATION_FLAG_INCOMING)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (!gb_operation_response_alloc(operation, response_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) gfp_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) goto err_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) timer_setup(&operation->timer, gb_operation_timeout, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) operation->flags = op_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) operation->type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) operation->errno = -EBADR; /* Initial value--means "never set" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) INIT_WORK(&operation->work, gb_operation_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) init_completion(&operation->completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) kref_init(&operation->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) atomic_set(&operation->waiters, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) err_request:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) gb_operation_message_free(operation->request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) err_cache:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) kmem_cache_free(gb_operation_cache, operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) * Create a new operation associated with the given connection. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) * request and response sizes provided are the number of bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) * required to hold the request/response payload only. Both of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) * these are allowed to be 0. Note that 0x00 is reserved as an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) * invalid operation type for all protocols, and this is enforced
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) * here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) struct gb_operation *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) gb_operation_create_flags(struct gb_connection *connection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) u8 type, size_t request_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) size_t response_size, unsigned long flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) struct gb_operation *operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (WARN_ON_ONCE(type == GB_REQUEST_TYPE_INVALID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if (WARN_ON_ONCE(type & GB_MESSAGE_TYPE_RESPONSE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) type &= ~GB_MESSAGE_TYPE_RESPONSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (WARN_ON_ONCE(flags & ~GB_OPERATION_FLAG_USER_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) flags &= GB_OPERATION_FLAG_USER_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) operation = gb_operation_create_common(connection, type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) request_size, response_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) flags, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (operation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) trace_gb_operation_create(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) return operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) EXPORT_SYMBOL_GPL(gb_operation_create_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) struct gb_operation *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) gb_operation_create_core(struct gb_connection *connection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) u8 type, size_t request_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) size_t response_size, unsigned long flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) struct gb_operation *operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) flags |= GB_OPERATION_FLAG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) operation = gb_operation_create_common(connection, type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) request_size, response_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) flags, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (operation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) trace_gb_operation_create_core(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) /* Do not export this function. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) size_t gb_operation_get_payload_size_max(struct gb_connection *connection)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) struct gb_host_device *hd = connection->hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return hd->buffer_size_max - sizeof(struct gb_operation_msg_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) EXPORT_SYMBOL_GPL(gb_operation_get_payload_size_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) static struct gb_operation *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) gb_operation_create_incoming(struct gb_connection *connection, u16 id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) u8 type, void *data, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct gb_operation *operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) size_t request_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) unsigned long flags = GB_OPERATION_FLAG_INCOMING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /* Caller has made sure we at least have a message header. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) request_size = size - sizeof(struct gb_operation_msg_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (!id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) flags |= GB_OPERATION_FLAG_UNIDIRECTIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) operation = gb_operation_create_common(connection, type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) request_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) GB_REQUEST_TYPE_INVALID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) flags, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (!operation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) operation->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) memcpy(operation->request->header, data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) trace_gb_operation_create_incoming(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) return operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) * Get an additional reference on an operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) void gb_operation_get(struct gb_operation *operation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) kref_get(&operation->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) EXPORT_SYMBOL_GPL(gb_operation_get);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * Destroy a previously created operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) static void _gb_operation_destroy(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) struct gb_operation *operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) operation = container_of(kref, struct gb_operation, kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) trace_gb_operation_destroy(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (operation->response)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) gb_operation_message_free(operation->response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) gb_operation_message_free(operation->request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) kmem_cache_free(gb_operation_cache, operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) * Drop a reference on an operation, and destroy it when the last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) * one is gone.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) void gb_operation_put(struct gb_operation *operation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (WARN_ON(!operation))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) kref_put(&operation->kref, _gb_operation_destroy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) EXPORT_SYMBOL_GPL(gb_operation_put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) /* Tell the requester we're done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) static void gb_operation_sync_callback(struct gb_operation *operation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) complete(&operation->completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * gb_operation_request_send() - send an operation request message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) * @operation: the operation to initiate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) * @callback: the operation completion callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) * @timeout: operation timeout in milliseconds, or zero for no timeout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) * @gfp: the memory flags to use for any allocations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) * The caller has filled in any payload so the request message is ready to go.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) * The callback function supplied will be called when the response message has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) * arrived, a unidirectional request has been sent, or the operation is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) * cancelled, indicating that the operation is complete. The callback function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) * can fetch the result of the operation using gb_operation_result() if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) * desired.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) * Return: 0 if the request was successfully queued in the host-driver queues,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) * or a negative errno.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) int gb_operation_request_send(struct gb_operation *operation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) gb_operation_callback callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) unsigned int timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) struct gb_connection *connection = operation->connection;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) struct gb_operation_msg_hdr *header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) unsigned int cycle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (gb_connection_is_offloaded(connection))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (!callback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) * Record the callback function, which is executed in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) * non-atomic (workqueue) context when the final result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) * of an operation has been set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) operation->callback = callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * Assign the operation's id, and store it in the request header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * Zero is a reserved operation id for unidirectional operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (gb_operation_is_unidirectional(operation)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) operation->id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) cycle = (unsigned int)atomic_inc_return(&connection->op_cycle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) operation->id = (u16)(cycle % U16_MAX + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) header = operation->request->header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) header->operation_id = cpu_to_le16(operation->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) gb_operation_result_set(operation, -EINPROGRESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) * Get an extra reference on the operation. It'll be dropped when the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) * operation completes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) gb_operation_get(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) ret = gb_operation_get_active(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) goto err_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) ret = gb_message_send(operation->request, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) goto err_put_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (timeout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) operation->timer.expires = jiffies + msecs_to_jiffies(timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) add_timer(&operation->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) err_put_active:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) gb_operation_put_active(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) err_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) gb_operation_put(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) EXPORT_SYMBOL_GPL(gb_operation_request_send);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) * Send a synchronous operation. This function is expected to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) * block, returning only when the response has arrived, (or when an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) * error is detected. The return value is the result of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) * operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) int gb_operation_request_send_sync_timeout(struct gb_operation *operation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) unsigned int timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) ret = gb_operation_request_send(operation, gb_operation_sync_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) timeout, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) ret = wait_for_completion_interruptible(&operation->completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) /* Cancel the operation if interrupted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) gb_operation_cancel(operation, -ECANCELED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) return gb_operation_result(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) EXPORT_SYMBOL_GPL(gb_operation_request_send_sync_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) * Send a response for an incoming operation request. A non-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) * errno indicates a failed operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) * If there is any response payload, the incoming request handler is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) * responsible for allocating the response message. Otherwise the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) * it can simply supply the result errno; this function will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) * allocate the response message if necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) static int gb_operation_response_send(struct gb_operation *operation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) int errno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) struct gb_connection *connection = operation->connection;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (!operation->response &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) !gb_operation_is_unidirectional(operation)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (!gb_operation_response_alloc(operation, 0, GFP_KERNEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) /* Record the result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (!gb_operation_result_set(operation, errno)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) dev_err(&connection->hd->dev, "request result already set\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) return -EIO; /* Shouldn't happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) /* Sender of request does not care about response. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) if (gb_operation_is_unidirectional(operation))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) /* Reference will be dropped when message has been sent. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) gb_operation_get(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) ret = gb_operation_get_active(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) goto err_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) /* Fill in the response header and send it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) operation->response->header->result = gb_operation_errno_map(errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) ret = gb_message_send(operation->response, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) goto err_put_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) err_put_active:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) gb_operation_put_active(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) err_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) gb_operation_put(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) * This function is called when a message send request has completed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) void greybus_message_sent(struct gb_host_device *hd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) struct gb_message *message, int status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) struct gb_operation *operation = message->operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) struct gb_connection *connection = operation->connection;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) * If the message was a response, we just need to drop our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) * reference to the operation. If an error occurred, report
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) * it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) * For requests, if there's no error and the operation in not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) * unidirectional, there's nothing more to do until the response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) * arrives. If an error occurred attempting to send it, or if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) * operation is unidrectional, record the result of the operation and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) * schedule its completion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if (message == operation->response) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) dev_err(&connection->hd->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) "%s: error sending response 0x%02x: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) connection->name, operation->type, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) gb_operation_put_active(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) gb_operation_put(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) } else if (status || gb_operation_is_unidirectional(operation)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (gb_operation_result_set(operation, status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) queue_work(gb_operation_completion_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) &operation->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) EXPORT_SYMBOL_GPL(greybus_message_sent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) * We've received data on a connection, and it doesn't look like a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) * response, so we assume it's a request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) * This is called in interrupt context, so just copy the incoming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) * data into the request buffer and handle the rest via workqueue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) static void gb_connection_recv_request(struct gb_connection *connection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) const struct gb_operation_msg_hdr *header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) void *data, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) struct gb_operation *operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) u16 operation_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) u8 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) operation_id = le16_to_cpu(header->operation_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) type = header->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) operation = gb_operation_create_incoming(connection, operation_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) type, data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (!operation) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) dev_err(&connection->hd->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) "%s: can't create incoming operation\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) connection->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) ret = gb_operation_get_active(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) gb_operation_put(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) trace_gb_message_recv_request(operation->request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) * The initial reference to the operation will be dropped when the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) * request handler returns.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (gb_operation_result_set(operation, -EINPROGRESS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) queue_work(connection->wq, &operation->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) * We've received data that appears to be an operation response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) * message. Look up the operation, and record that we've received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) * its response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) * This is called in interrupt context, so just copy the incoming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) * data into the response buffer and handle the rest via workqueue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) static void gb_connection_recv_response(struct gb_connection *connection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) const struct gb_operation_msg_hdr *header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) void *data, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) struct gb_operation *operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) struct gb_message *message;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) size_t message_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) u16 operation_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) int errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) operation_id = le16_to_cpu(header->operation_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (!operation_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) dev_err_ratelimited(&connection->hd->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) "%s: invalid response id 0 received\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) connection->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) operation = gb_operation_find_outgoing(connection, operation_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (!operation) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) dev_err_ratelimited(&connection->hd->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) "%s: unexpected response id 0x%04x received\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) connection->name, operation_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) errno = gb_operation_status_map(header->result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) message = operation->response;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) message_size = sizeof(*header) + message->payload_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if (!errno && size > message_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) dev_err_ratelimited(&connection->hd->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) "%s: malformed response 0x%02x received (%zu > %zu)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) connection->name, header->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) size, message_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) errno = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) } else if (!errno && size < message_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (gb_operation_short_response_allowed(operation)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) message->payload_size = size - sizeof(*header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) dev_err_ratelimited(&connection->hd->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) "%s: short response 0x%02x received (%zu < %zu)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) connection->name, header->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) size, message_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) errno = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) /* We must ignore the payload if a bad status is returned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (errno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) size = sizeof(*header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) /* The rest will be handled in work queue context */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (gb_operation_result_set(operation, errno)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) memcpy(message->buffer, data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) trace_gb_message_recv_response(message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) queue_work(gb_operation_completion_wq, &operation->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) gb_operation_put(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) * Handle data arriving on a connection. As soon as we return the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) * supplied data buffer will be reused (so unless we do something
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) * with, it's effectively dropped).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) void gb_connection_recv(struct gb_connection *connection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) void *data, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) struct gb_operation_msg_hdr header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) struct device *dev = &connection->hd->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) size_t msg_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) if (connection->state == GB_CONNECTION_STATE_DISABLED ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) gb_connection_is_offloaded(connection)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) dev_warn_ratelimited(dev, "%s: dropping %zu received bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) connection->name, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) if (size < sizeof(header)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) dev_err_ratelimited(dev, "%s: short message received\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) connection->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) /* Use memcpy as data may be unaligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) memcpy(&header, data, sizeof(header));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) msg_size = le16_to_cpu(header.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) if (size < msg_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) dev_err_ratelimited(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) "%s: incomplete message 0x%04x of type 0x%02x received (%zu < %zu)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) connection->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) le16_to_cpu(header.operation_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) header.type, size, msg_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) return; /* XXX Should still complete operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) if (header.type & GB_MESSAGE_TYPE_RESPONSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) gb_connection_recv_response(connection, &header, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) msg_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) gb_connection_recv_request(connection, &header, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) msg_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) * Cancel an outgoing operation synchronously, and record the given error to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) * indicate why.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) void gb_operation_cancel(struct gb_operation *operation, int errno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) if (WARN_ON(gb_operation_is_incoming(operation)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (gb_operation_result_set(operation, errno)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) gb_message_cancel(operation->request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) queue_work(gb_operation_completion_wq, &operation->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) trace_gb_message_cancel_outgoing(operation->request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) atomic_inc(&operation->waiters);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) wait_event(gb_operation_cancellation_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) !gb_operation_is_active(operation));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) atomic_dec(&operation->waiters);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) EXPORT_SYMBOL_GPL(gb_operation_cancel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) * Cancel an incoming operation synchronously. Called during connection tear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) * down.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) void gb_operation_cancel_incoming(struct gb_operation *operation, int errno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (WARN_ON(!gb_operation_is_incoming(operation)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) if (!gb_operation_is_unidirectional(operation)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) * Make sure the request handler has submitted the response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) * before cancelling it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) flush_work(&operation->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) if (!gb_operation_result_set(operation, errno))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) gb_message_cancel(operation->response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) trace_gb_message_cancel_incoming(operation->response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) atomic_inc(&operation->waiters);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) wait_event(gb_operation_cancellation_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) !gb_operation_is_active(operation));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) atomic_dec(&operation->waiters);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) * gb_operation_sync_timeout() - implement a "simple" synchronous operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) * @connection: the Greybus connection to send this to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) * @type: the type of operation to send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) * @request: pointer to a memory buffer to copy the request from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) * @request_size: size of @request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) * @response: pointer to a memory buffer to copy the response to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) * @response_size: the size of @response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) * @timeout: operation timeout in milliseconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) * This function implements a simple synchronous Greybus operation. It sends
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) * the provided operation request and waits (sleeps) until the corresponding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) * operation response message has been successfully received, or an error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) * occurs. @request and @response are buffers to hold the request and response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) * data respectively, and if they are not NULL, their size must be specified in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) * @request_size and @response_size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) * If a response payload is to come back, and @response is not NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) * @response_size number of bytes will be copied into @response if the operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) * is successful.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) * If there is an error, the response buffer is left alone.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) int gb_operation_sync_timeout(struct gb_connection *connection, int type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) void *request, int request_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) void *response, int response_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) unsigned int timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) struct gb_operation *operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) if ((response_size && !response) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) (request_size && !request))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) operation = gb_operation_create(connection, type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) request_size, response_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) if (!operation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) if (request_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) memcpy(operation->request->payload, request, request_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) ret = gb_operation_request_send_sync_timeout(operation, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) dev_err(&connection->hd->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) "%s: synchronous operation id 0x%04x of type 0x%02x failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) connection->name, operation->id, type, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) if (response_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) memcpy(response, operation->response->payload,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) response_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) gb_operation_put(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) EXPORT_SYMBOL_GPL(gb_operation_sync_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) * gb_operation_unidirectional_timeout() - initiate a unidirectional operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) * @connection: connection to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) * @type: type of operation to send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) * @request: memory buffer to copy the request from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) * @request_size: size of @request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) * @timeout: send timeout in milliseconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) * Initiate a unidirectional operation by sending a request message and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) * waiting for it to be acknowledged as sent by the host device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) * Note that successful send of a unidirectional operation does not imply that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) * the request as actually reached the remote end of the connection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) int gb_operation_unidirectional_timeout(struct gb_connection *connection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) int type, void *request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) int request_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) unsigned int timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) struct gb_operation *operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) if (request_size && !request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) operation = gb_operation_create_flags(connection, type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) request_size, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) GB_OPERATION_FLAG_UNIDIRECTIONAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) if (!operation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) if (request_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) memcpy(operation->request->payload, request, request_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) ret = gb_operation_request_send_sync_timeout(operation, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) dev_err(&connection->hd->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) "%s: unidirectional operation of type 0x%02x failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) connection->name, type, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) gb_operation_put(operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) EXPORT_SYMBOL_GPL(gb_operation_unidirectional_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) int __init gb_operation_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) gb_message_cache = kmem_cache_create("gb_message_cache",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) sizeof(struct gb_message), 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) if (!gb_message_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) gb_operation_cache = kmem_cache_create("gb_operation_cache",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) sizeof(struct gb_operation), 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) if (!gb_operation_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) goto err_destroy_message_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) gb_operation_completion_wq = alloc_workqueue("greybus_completion",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) if (!gb_operation_completion_wq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) goto err_destroy_operation_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) err_destroy_operation_cache:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) kmem_cache_destroy(gb_operation_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) gb_operation_cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) err_destroy_message_cache:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) kmem_cache_destroy(gb_message_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) gb_message_cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) void gb_operation_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) destroy_workqueue(gb_operation_completion_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) gb_operation_completion_wq = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) kmem_cache_destroy(gb_operation_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) gb_operation_cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) kmem_cache_destroy(gb_message_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) gb_message_cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }