void xpc_process_sent_chctl_flags(struct xpc_partition *part) { unsigned long irq_flags; union xpc_channel_ctl_flags chctl; struct xpc_channel *ch; int ch_number; u32 ch_flags; chctl.all_flags = xpc_arch_ops.get_chctl_all_flags(part); for (ch_number = 0; ch_number < part->nchannels; ch_number++) { ch = &part->channels[ch_number]; if (chctl.flags[ch_number] & XPC_OPENCLOSE_CHCTL_FLAGS) { xpc_process_openclose_chctl_flags(part, ch_number, chctl.flags[ch_number]); } ch_flags = ch->flags; if (ch_flags & XPC_C_DISCONNECTING) { spin_lock_irqsave(&ch->lock, irq_flags); xpc_process_disconnect(ch, &irq_flags); spin_unlock_irqrestore(&ch->lock, irq_flags); continue; } if (part->act_state == XPC_P_AS_DEACTIVATING) continue; if (!(ch_flags & XPC_C_CONNECTED)) { if (!(ch_flags & XPC_C_OPENREQUEST)) { DBUG_ON(ch_flags & XPC_C_SETUP); (void)xpc_connect_channel(ch); } continue; } if (chctl.flags[ch_number] & XPC_MSG_CHCTL_FLAGS) xpc_arch_ops.process_msg_chctl_flags(part, ch_number); } }
void xpc_process_sent_chctl_flags(struct xpc_partition *part) { unsigned long irq_flags; union xpc_channel_ctl_flags chctl; struct xpc_channel *ch; int ch_number; u32 ch_flags; chctl.all_flags = xpc_get_chctl_all_flags(part); /* * Initiate channel connections for registered channels. * * For each connected channel that has pending messages activate idle * kthreads and/or create new kthreads as needed. */ for (ch_number = 0; ch_number < part->nchannels; ch_number++) { ch = &part->channels[ch_number]; /* * Process any open or close related chctl flags, and then deal * with connecting or disconnecting the channel as required. */ if (chctl.flags[ch_number] & XPC_OPENCLOSE_CHCTL_FLAGS) { xpc_process_openclose_chctl_flags(part, ch_number, chctl.flags[ch_number]); } ch_flags = ch->flags; /* need an atomic snapshot of flags */ if (ch_flags & XPC_C_DISCONNECTING) { spin_lock_irqsave(&ch->lock, irq_flags); xpc_process_disconnect(ch, &irq_flags); spin_unlock_irqrestore(&ch->lock, irq_flags); continue; } if (part->act_state == XPC_P_AS_DEACTIVATING) continue; if (!(ch_flags & XPC_C_CONNECTED)) { if (!(ch_flags & XPC_C_OPENREQUEST)) { DBUG_ON(ch_flags & XPC_C_SETUP); (void)xpc_connect_channel(ch); } else { spin_lock_irqsave(&ch->lock, irq_flags); xpc_process_connect(ch, &irq_flags); spin_unlock_irqrestore(&ch->lock, irq_flags); } continue; } /* * Process any message related chctl flags, this may involve * the activation of kthreads to deliver any pending messages * sent from the other partition. */ if (chctl.flags[ch_number] & XPC_MSG_CHCTL_FLAGS) xpc_process_msg_chctl_flags(part, ch_number); } }