mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-29 07:04:10 +08:00
net: ipa: use a bitmap for set-up endpoints
Replace the 32-bit unsigned used to track endpoints that have completed setup with a Linux bitmap, to allow an arbitrary number of endpoints to be represented. Rework the error handling in ipa_endpoint_init() so the defined endpoint bitmap is freed if an error occurs early. Once endpoints have been initialized, ipa_endpoint_exit() is used to recover if the set of filtered endpoints is invalid. Signed-off-by: Alex Elder <elder@linaro.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
0f97fbd478
commit
ae5108e9b7
@ -66,7 +66,7 @@ struct ipa_interrupt;
|
||||
* @defined: Bitmap of endpoints defined in config data
|
||||
* @available: Bitmap of endpoints supported by hardware
|
||||
* @filtered: Bitmap of endpoints that support filtering
|
||||
* @set_up: Bit mask indicating endpoints set up
|
||||
* @set_up: Bitmap of endpoints that are set up for use
|
||||
* @enabled: Bit mask indicating endpoints enabled
|
||||
* @modem_tx_count: Number of defined modem TX endoints
|
||||
* @endpoint: Array of endpoint information
|
||||
@ -124,7 +124,7 @@ struct ipa {
|
||||
unsigned long *defined; /* Defined in configuration data */
|
||||
unsigned long *available; /* Supported by hardware */
|
||||
u64 filtered; /* Support filtering (AP and modem) */
|
||||
u32 set_up;
|
||||
unsigned long *set_up;
|
||||
u32 enabled;
|
||||
|
||||
u32 modem_tx_count;
|
||||
|
@ -1802,12 +1802,12 @@ static void ipa_endpoint_setup_one(struct ipa_endpoint *endpoint)
|
||||
|
||||
ipa_endpoint_program(endpoint);
|
||||
|
||||
endpoint->ipa->set_up |= BIT(endpoint->endpoint_id);
|
||||
__set_bit(endpoint->endpoint_id, endpoint->ipa->set_up);
|
||||
}
|
||||
|
||||
static void ipa_endpoint_teardown_one(struct ipa_endpoint *endpoint)
|
||||
{
|
||||
endpoint->ipa->set_up &= ~BIT(endpoint->endpoint_id);
|
||||
__clear_bit(endpoint->endpoint_id, endpoint->ipa->set_up);
|
||||
|
||||
if (!endpoint->toward_ipa)
|
||||
cancel_delayed_work_sync(&endpoint->replenish_work);
|
||||
@ -1819,23 +1819,16 @@ void ipa_endpoint_setup(struct ipa *ipa)
|
||||
{
|
||||
u32 endpoint_id;
|
||||
|
||||
ipa->set_up = 0;
|
||||
for_each_set_bit(endpoint_id, ipa->defined, ipa->endpoint_count)
|
||||
ipa_endpoint_setup_one(&ipa->endpoint[endpoint_id]);
|
||||
}
|
||||
|
||||
void ipa_endpoint_teardown(struct ipa *ipa)
|
||||
{
|
||||
u32 set_up = ipa->set_up;
|
||||
|
||||
while (set_up) {
|
||||
u32 endpoint_id = __fls(set_up);
|
||||
|
||||
set_up ^= BIT(endpoint_id);
|
||||
u32 endpoint_id;
|
||||
|
||||
for_each_set_bit(endpoint_id, ipa->set_up, ipa->endpoint_count)
|
||||
ipa_endpoint_teardown_one(&ipa->endpoint[endpoint_id]);
|
||||
}
|
||||
ipa->set_up = 0;
|
||||
}
|
||||
|
||||
void ipa_endpoint_deconfig(struct ipa *ipa)
|
||||
@ -1978,6 +1971,8 @@ void ipa_endpoint_exit(struct ipa *ipa)
|
||||
for_each_set_bit(endpoint_id, ipa->defined, ipa->endpoint_count)
|
||||
ipa_endpoint_exit_one(&ipa->endpoint[endpoint_id]);
|
||||
|
||||
bitmap_free(ipa->set_up);
|
||||
ipa->set_up = NULL;
|
||||
bitmap_free(ipa->defined);
|
||||
ipa->defined = NULL;
|
||||
|
||||
@ -1999,11 +1994,15 @@ int ipa_endpoint_init(struct ipa *ipa, u32 count,
|
||||
if (!ipa->endpoint_count)
|
||||
return -EINVAL;
|
||||
|
||||
/* Initialize the defined endpoint bitmap */
|
||||
/* Initialize endpoint state bitmaps */
|
||||
ipa->defined = bitmap_zalloc(ipa->endpoint_count, GFP_KERNEL);
|
||||
if (!ipa->defined)
|
||||
return -ENOMEM;
|
||||
|
||||
ipa->set_up = bitmap_zalloc(ipa->endpoint_count, GFP_KERNEL);
|
||||
if (!ipa->set_up)
|
||||
goto err_free_defined;
|
||||
|
||||
filtered = 0;
|
||||
for (name = 0; name < count; name++, data++) {
|
||||
if (ipa_gsi_endpoint_data_empty(data))
|
||||
@ -2017,15 +2016,20 @@ int ipa_endpoint_init(struct ipa *ipa, u32 count,
|
||||
ipa->modem_tx_count++;
|
||||
}
|
||||
|
||||
if (!ipa_filtered_valid(ipa, filtered))
|
||||
goto err_endpoint_exit;
|
||||
/* Make sure the set of filtered endpoints is valid */
|
||||
if (!ipa_filtered_valid(ipa, filtered)) {
|
||||
ipa_endpoint_exit(ipa);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ipa->filtered = filtered;
|
||||
|
||||
return 0;
|
||||
|
||||
err_endpoint_exit:
|
||||
ipa_endpoint_exit(ipa);
|
||||
err_free_defined:
|
||||
bitmap_free(ipa->defined);
|
||||
ipa->defined = NULL;
|
||||
|
||||
return -EINVAL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user