#include #include #include #define PORT_CAST(p) OBJECT_C_CAST(struct port, p_base, &port_type, p) static struct object_type port_type = { .ob_name = "port", .ob_size = sizeof(struct port), .ob_header_offset = offsetof(struct port, p_base), }; kern_status_t port_type_init(void) { return object_type_register(&port_type); } struct port *port_cast(struct object *obj) { return PORT_CAST(obj); } static void wait_for_reply(struct port *port) { } struct port *port_create(void) { struct object *port_object = object_create(&port_type); if (!port_object) { return NULL; } struct port *port = PORT_CAST(port_object); port->p_status = PORT_OFFLINE; return port; } kern_status_t port_connect(struct port *port, struct channel *remote) { if (port->p_status != PORT_OFFLINE) { return KERN_BAD_STATE; } port->p_remote = remote; port->p_status = PORT_READY; return KERN_OK; } kern_status_t port_send_msg( struct port *port, const struct msg *req, struct msg *resp) { if (port->p_status != PORT_READY) { return KERN_BAD_STATE; } struct thread *self = current_thread(); struct kmsg *msg = &self->tr_msg; msg->msg_sender_thread = self; msg->msg_sender_port = port; msg->msg_req = req; msg->msg_resp = resp; unsigned long flags; channel_lock_irqsave(port->p_remote, &flags); channel_enqueue_msg(port->p_remote, msg); channel_unlock_irqrestore(port->p_remote, flags); port->p_status = PORT_SEND_BLOCKED; wait_for_reply(port); return msg->msg_result; }