/* disconnect_bc * process closing of connection associated with given AT state structure * and B channel */ static void disconnect_bc(struct at_state_t *at_state, struct cardstate *cs, struct bc_state *bcs) { unsigned long flags; spin_lock_irqsave(&cs->lock, flags); ++at_state->seq_index; /* revert to selected idle mode */ if (!cs->cidmode) { cs->at_state.pending_commands |= PC_UMMODE; gig_dbg(DEBUG_EVENT, "Scheduling PC_UMMODE"); cs->commands_pending = 1; } spin_unlock_irqrestore(&cs->lock, flags); /* invoke hardware specific handler */ cs->ops->close_bchannel(bcs); /* notify LL */ if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) { bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL); gigaset_isdn_hupD(bcs); } }
/* disconnect * process closing of connection associated with given AT state structure */ static void disconnect(struct at_state_t **at_state_p) { unsigned long flags; struct bc_state *bcs = (*at_state_p)->bcs; struct cardstate *cs = (*at_state_p)->cs; spin_lock_irqsave(&cs->lock, flags); ++(*at_state_p)->seq_index; /* revert to selected idle mode */ if (!cs->cidmode) { cs->at_state.pending_commands |= PC_UMMODE; gig_dbg(DEBUG_EVENT, "Scheduling PC_UMMODE"); cs->commands_pending = 1; } spin_unlock_irqrestore(&cs->lock, flags); if (bcs) { /* B channel assigned: invoke hardware specific handler */ cs->ops->close_bchannel(bcs); /* notify LL */ if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) { bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL); gigaset_isdn_hupD(bcs); } } else { /* no B channel assigned: just deallocate */ spin_lock_irqsave(&cs->lock, flags); list_del(&(*at_state_p)->list); kfree(*at_state_p); *at_state_p = NULL; spin_unlock_irqrestore(&cs->lock, flags); } }
static void bchannel_down(struct bc_state *bcs) { if (bcs->chstate & CHS_B_UP) { bcs->chstate &= ~CHS_B_UP; gigaset_isdn_hupB(bcs); } if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) { bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL); gigaset_isdn_hupD(bcs); } gigaset_free_channel(bcs); gigaset_bcs_reinit(bcs); }