diff mbox series

[061/120] MIPS: PS2: SIF: sif_rpc_bind() to request an RPC server connection

Message ID 560734ac45b85db15b6ad002e433c3db979084dd.1567326213.git.noring@nocrew.org (mailing list archive)
State RFC
Headers show
Series Linux for the PlayStation 2 | expand

Commit Message

Fredrik Noring Sept. 1, 2019, 4:01 p.m. UTC
This is the first initialisation step to perform remote procedure calls.

A PAGE_SIZE buffer is allocated to store RPC data. A future improvement is
to make the buffer size adjustable.

Signed-off-by: Fredrik Noring <noring@nocrew.org>
---
 arch/mips/include/asm/mach-ps2/sif.h |  2 ++
 drivers/ps2/sif.c                    | 38 ++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)
diff mbox series

Patch

diff --git a/arch/mips/include/asm/mach-ps2/sif.h b/arch/mips/include/asm/mach-ps2/sif.h
index 3d163980a4be..1d9a7ede2fb5 100644
--- a/arch/mips/include/asm/mach-ps2/sif.h
+++ b/arch/mips/include/asm/mach-ps2/sif.h
@@ -85,4 +85,6 @@  struct sif_rpc_client
 	struct completion done;
 };
 
+int sif_rpc_bind(struct sif_rpc_client *client, u32 server_id);
+
 #endif /* __ASM_MACH_PS2_SIF_H */
diff --git a/drivers/ps2/sif.c b/drivers/ps2/sif.c
index 7a5aab785237..ecb26239518c 100644
--- a/drivers/ps2/sif.c
+++ b/drivers/ps2/sif.c
@@ -387,6 +387,44 @@  static irqreturn_t sif0_dma_handler(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+/**
+ * sif_rpc_bind - request a connection to an IOP RPC server
+ * @client: RPC client object to initialise
+ * @server_id: identification number for the requested IOP RPC server
+ *
+ * A %PAGE_SIZE buffer is allocated to store RPC data. A future improvement is
+ * to make its size adjustable.
+ *
+ * Return: 0 on success, otherwise a negative error number
+ */
+int sif_rpc_bind(struct sif_rpc_client *client, u32 server_id)
+{
+	const struct sif_rpc_bind_packet bind = {
+		.client    = client,
+		.server_id = server_id,
+	};
+	int err;
+
+	memset(client, 0, sizeof(*client));
+	init_completion(&client->done);
+
+	client->client_size_max = SIF0_BUFFER_SIZE;
+	client->client_buffer = (void *)__get_free_page(GFP_DMA);
+	if (client->client_buffer == NULL)
+		return -ENOMEM;
+
+	err = sif_cmd(SIF_CMD_RPC_BIND, &bind, sizeof(bind));
+	if (err) {
+		free_page((unsigned long)client->client_buffer);
+		return err;
+	}
+
+	wait_for_completion(&client->done);
+
+	return client->server ? 0 : -ENXIO;
+}
+EXPORT_SYMBOL_GPL(sif_rpc_bind);
+
 static void cmd_rpc_end(const struct sif_cmd_header *header,
 	const void *data, void *arg)
 {