qcacld-3.0: Create new hdd_adapter_iterate() function

Currently, there is a problem in hdd_for_each_adapter(), as it is
checking for the NDI adapter only in an infinite loop. Create
hdd_adapter_iterate() in order to iterate through all adapters properly.

Change-Id: Ib0e22d0f46d6311d44de3ee48b3202376a42f209
CRs-Fixed: 2568906
This commit is contained in:
Alan Chen 2019-11-15 16:40:17 -08:00 committed by nshrivas
parent 7d76e2d36b
commit 18cb483d82
2 changed files with 81 additions and 0 deletions

View File

@ -2049,6 +2049,44 @@ QDF_STATUS hdd_add_adapter_back(struct hdd_context *hdd_ctx,
QDF_STATUS hdd_add_adapter_front(struct hdd_context *hdd_ctx,
struct hdd_adapter *adapter);
/**
* typedef hdd_adapter_iterate_cb() Iteration callback function
* @adapter: current adapter of interest
* @context: user context supplied to the iterator
*
* This specifies the type of a callback function to supply to
* hdd_adapter_iterate().
*
* Return:
* * QDF_STATUS_SUCCESS if further iteration should continue
* * QDF_STATUS_E_ABORTED if further iteration should be aborted
*/
typedef QDF_STATUS (*hdd_adapter_iterate_cb)(struct hdd_adapter *adapter,
void *context);
/**
* hdd_adapter_iterate() Safely iterate over all adapters
* @cb: callback function to invoke for each adapter
* @context: user-supplied context to pass to @cb
*
* This function will iterate over all of the adapters known to the system in
* a safe manner, invoking the callback function for each adapter.
* The callback function will be invoked in the same context/thread as the
* caller without any additional locks in force.
* Iteration continues until either the callback has been invoked for all
* adapters or a callback returns a value of QDF_STATUS_E_ABORTED to indicate
* that further iteration should cease.
*
* Return:
* * QDF_STATUS_E_ABORTED if any callback function returns that value
* * QDF_STATUS_E_FAILURE if the callback was not invoked for all adapters due
* to concurrency (i.e. adapter was deleted while iterating)
* * QDF_STATUS_SUCCESS if @cb was invoked for each adapter and none returned
* an error
*/
QDF_STATUS hdd_adapter_iterate(hdd_adapter_iterate_cb cb,
void *context);
/**
* hdd_for_each_adapter - adapter iterator macro
* @hdd_ctx: the global HDD context

View File

@ -7160,6 +7160,49 @@ QDF_STATUS hdd_add_adapter_front(struct hdd_context *hdd_ctx,
return status;
}
QDF_STATUS hdd_adapter_iterate(hdd_adapter_iterate_cb cb, void *context)
{
struct hdd_context *hdd_ctx;
struct hdd_adapter *cache[HDD_MAX_ADAPTERS];
struct hdd_adapter *adapter;
uint32_t n_cache = 0;
QDF_STATUS ret = QDF_STATUS_SUCCESS;
QDF_STATUS status;
int i;
hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
if (unlikely(!hdd_ctx)) {
hdd_err("HDD context is Null");
return QDF_STATUS_E_FAILURE;
}
qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
for (hdd_get_front_adapter_no_lock(hdd_ctx, &adapter); adapter;
hdd_get_next_adapter_no_lock(hdd_ctx, adapter, &adapter)) {
cache[n_cache++] = adapter;
}
qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
for (i = 0; i < n_cache - 1; i++) {
adapter = hdd_adapter_get_by_reference(hdd_ctx, cache[i]);
if (!adapter) {
/*
* detected remove while iterating
* concurrency failure
*/
ret = QDF_STATUS_E_FAILURE;
continue;
}
status = cb(adapter, context);
hdd_adapter_put(adapter);
if (status != QDF_STATUS_SUCCESS)
return status;
}
return ret;
}
struct hdd_adapter *hdd_get_adapter_by_rand_macaddr(
struct hdd_context *hdd_ctx, tSirMacAddr mac_addr)
{