/* Copyright (C) 2011 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
*/
#ifndef _HW_GOLDFISH_PIPE_H
#define _HW_GOLDFISH_PIPE_H
#include <stdint.h>
#include "hw/hw.h"
/* TECHNICAL NOTE:
*
* A goldfish pipe is a very fast communication channel between the guest
* system and the emulator program.
*
* To open a new pipe to the emulator, a guest client will do the following:
*
* fd = open("/dev/qemu_pipe", O_RDWR);
* char invite[64];
* snprintf(invite, sizeof invite, "%s", pipeName);
* ret = write(fd, invite, strlen(invite));
*
* if (ret < 0) {
* // something bad happened, see errno
* }
*
* now read()/write() to communicate with <pipeName> service in the
* emulator.
*
* This header provides the interface used by pipe services in the emulator
* to receive new client connection and deal with them.
*
*
* 1/ Call goldfish_pipe_add_type() to register a new pipe service by name.
* This must provide a pointer to a series of functions that will be called
* during normal pipe operations.
*
* 2/ When a client connects to the service, the 'init' callback will be called
* to create a new service-specific client identifier (which must returned
* by the function).
*
* 3/ Call goldfish_pipe_close() to force the closure of a given pipe.
*
* 4/ Call goldfish_pipe_signal() to signal a change of state to the pipe.
*
*/
/* Buffer descriptor for sendBuffers() and recvBuffers() callbacks */
typedef struct GoldfishPipeBuffer {
uint8_t* data;
size_t size;
} GoldfishPipeBuffer;
/* Pipe handler funcs */
typedef struct {
/* Create new client connection, 'hwpipe' must be passed to other
* goldfish_pipe_xxx functions, while the returned value will be passed
* to other callbacks (e.g. close). 'pipeOpaque' is the value passed
* to goldfish_pipe_add_type() when registering a given pipe service.
*/
void* (*init)( void* hwpipe, void* pipeOpaque, const char* args );
/* Called when the guest kernel has finally closed a pipe connection.
* This is the only place where you can release/free the client connection.
* You should never invoke this callback directly. Call goldfish_pipe_close()
* instead.
*/
void (*close)( void* pipe );
/* Called when the guest is write()-ing to the pipe. Should return the
* number of bytes transfered, 0 for EOF status, or a negative error
* value otherwise, including PIPE_ERROR_AGAIN to indicate that the
* emulator is not ready to receive data yet.
*/
int (*sendBuffers)( void* pipe, const GoldfishPipeBuffer* buffers, int numBuffers );
/* Same as sendBuffers when the guest is read()-ing from the pipe. */
int (*recvBuffers)( void* pipe, GoldfishPipeBuffer* buffers, int numBuffers );
/* Called when guest wants to poll the read/write status for the pipe.
* Should return a combination of PIPE_POLL_XXX flags.
*/
unsigned (*poll)( void* pipe );
/* Called to signal that the guest wants to be woken when the set of
* PIPE_WAKE_XXX bit-flags in 'flags' occur. When the condition occurs,
* then the pipe implementation shall call goldfish_pipe_wake().
*/
void (*wakeOn)( void* opaque, int flags );
} GoldfishPipeFuncs;
/* Register a new pipe handler type. 'pipeOpaque' is passed directly
* to 'init() when a new pipe is connected to.
*/
extern void goldfish_pipe_add_type(const char* pipeName,
void* pipeOpaque,
const GoldfishPipeFuncs* pipeFuncs );
/* This tells the guest system that we want to close the pipe and that
* further attempts to read or write to it will fail. This will not
* necessarily call the 'close' callback immediately though.
*
* This will also wake-up any blocked guest threads waiting for i/o.
*/
extern void goldfish_pipe_close( void* hwpipe );
/* Signal that the pipe can be woken up. 'flags' must be a combination of
* PIPE_WAKE_READ and PIPE_WAKE_WRITE.
*/
extern void goldfish_pipe_wake( void* hwpipe, unsigned flags );
/* The following definitions must match those under:
*
* $KERNEL/drivers/misc/qemupipe/qemu_pipe.c
*
* Where $KERNEL points to the android-goldfish-2.6.xx branch on:
*
* android.git.kernel.org/kernel/qemu.git.
*/
/* pipe device registers */
#define PIPE_REG_COMMAND 0x00 /* write: value = command */
#define PIPE_REG_STATUS 0x04 /* read */
#define PIPE_REG_CHANNEL 0x08 /* read/write: channel id */
#define PIPE_REG_SIZE 0x0c /* read/write: buffer size */
#define PIPE_REG_ADDRESS 0x10 /* write: physical address */
#define PIPE_REG_WAKES 0x14 /* read: wake flags */
/* list of commands for PIPE_REG_COMMAND */
#define PIPE_CMD_OPEN 1 /* open new channel */
#define PIPE_CMD_CLOSE 2 /* close channel (from guest) */
#define PIPE_CMD_POLL 3 /* poll read/write status */
/* List of bitflags returned in status of CMD_POLL command */
#define PIPE_POLL_IN (1 << 0)
#define PIPE_POLL_OUT (1 << 1)
#define PIPE_POLL_HUP (1 << 2)
/* The following commands are related to write operations */
#define PIPE_CMD_WRITE_BUFFER 4 /* send a user buffer to the emulator */
#define PIPE_CMD_WAKE_ON_WRITE 5 /* tell the emulator to wake us when writing is possible */
/* The following commands are related to read operations, they must be
* listed in the same order than the corresponding write ones, since we
* will use (CMD_READ_BUFFER - CMD_WRITE_BUFFER) as a special offset
* in qemu_pipe_read_write() below.
*/
#define PIPE_CMD_READ_BUFFER 6 /* receive a page-contained buffer from the emulator */
#define PIPE_CMD_WAKE_ON_READ 7 /* tell the emulator to wake us when reading is possible */
/* Possible status values used to signal errors - see qemu_pipe_error_convert */
#define PIPE_ERROR_INVAL -1
#define PIPE_ERROR_AGAIN -2
#define PIPE_ERROR_NOMEM -3
#define PIPE_ERROR_IO -4
/* Bit-flags used to signal events from the emulator */
#define PIPE_WAKE_CLOSED (1 << 0) /* emulator closed pipe */
#define PIPE_WAKE_READ (1 << 1) /* pipe can now be read from */
#define PIPE_WAKE_WRITE (1 << 2) /* pipe can now be written to */
void pipe_dev_init(void);
#endif /* _HW_GOLDFISH_PIPE_H */