|
@@ -137,6 +137,8 @@ void st_send_frame(unsigned char chnl_id, struct st_data_s *st_gdata)
|
|
|
* st_reg_complete -
|
|
|
* to call registration complete callbacks
|
|
|
* of all protocol stack drivers
|
|
|
+ * This function is being called with spin lock held, protocol drivers are
|
|
|
+ * only expected to complete their waits and do nothing more than that.
|
|
|
*/
|
|
|
void st_reg_complete(struct st_data_s *st_gdata, char err)
|
|
|
{
|
|
@@ -538,11 +540,12 @@ long st_register(struct st_proto_s *new_proto)
|
|
|
set_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state);
|
|
|
st_recv = st_kim_recv;
|
|
|
|
|
|
+ /* enable the ST LL - to set default chip state */
|
|
|
+ st_ll_enable(st_gdata);
|
|
|
+
|
|
|
/* release lock previously held - re-locked below */
|
|
|
spin_unlock_irqrestore(&st_gdata->lock, flags);
|
|
|
|
|
|
- /* enable the ST LL - to set default chip state */
|
|
|
- st_ll_enable(st_gdata);
|
|
|
/* this may take a while to complete
|
|
|
* since it involves BT fw download
|
|
|
*/
|
|
@@ -553,10 +556,13 @@ long st_register(struct st_proto_s *new_proto)
|
|
|
(test_bit(ST_REG_PENDING, &st_gdata->st_state))) {
|
|
|
pr_err(" KIM failure complete callback ");
|
|
|
st_reg_complete(st_gdata, err);
|
|
|
+ clear_bit(ST_REG_PENDING, &st_gdata->st_state);
|
|
|
}
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
+ spin_lock_irqsave(&st_gdata->lock, flags);
|
|
|
+
|
|
|
clear_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state);
|
|
|
st_recv = st_int_recv;
|
|
|
|
|
@@ -576,10 +582,10 @@ long st_register(struct st_proto_s *new_proto)
|
|
|
if (st_gdata->is_registered[new_proto->chnl_id] == true) {
|
|
|
pr_err(" proto %d already registered ",
|
|
|
new_proto->chnl_id);
|
|
|
+ spin_unlock_irqrestore(&st_gdata->lock, flags);
|
|
|
return -EALREADY;
|
|
|
}
|
|
|
|
|
|
- spin_lock_irqsave(&st_gdata->lock, flags);
|
|
|
add_channel_to_table(st_gdata, new_proto);
|
|
|
st_gdata->protos_registered++;
|
|
|
new_proto->write = st_write;
|
|
@@ -619,7 +625,7 @@ long st_unregister(struct st_proto_s *proto)
|
|
|
|
|
|
spin_lock_irqsave(&st_gdata->lock, flags);
|
|
|
|
|
|
- if (st_gdata->list[proto->chnl_id] == NULL) {
|
|
|
+ if (st_gdata->is_registered[proto->chnl_id] == false) {
|
|
|
pr_err(" chnl_id %d not registered", proto->chnl_id);
|
|
|
spin_unlock_irqrestore(&st_gdata->lock, flags);
|
|
|
return -EPROTONOSUPPORT;
|
|
@@ -629,6 +635,10 @@ long st_unregister(struct st_proto_s *proto)
|
|
|
remove_channel_from_table(st_gdata, proto);
|
|
|
spin_unlock_irqrestore(&st_gdata->lock, flags);
|
|
|
|
|
|
+ /* paranoid check */
|
|
|
+ if (st_gdata->protos_registered < ST_EMPTY)
|
|
|
+ st_gdata->protos_registered = ST_EMPTY;
|
|
|
+
|
|
|
if ((st_gdata->protos_registered == ST_EMPTY) &&
|
|
|
(!test_bit(ST_REG_PENDING, &st_gdata->st_state))) {
|
|
|
pr_info(" all chnl_ids unregistered ");
|