summaryrefslogtreecommitdiffstats
path: root/qemu/roms/SLOF/lib/libvirtio/p9.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/SLOF/lib/libvirtio/p9.c')
-rw-r--r--qemu/roms/SLOF/lib/libvirtio/p9.c575
1 files changed, 0 insertions, 575 deletions
diff --git a/qemu/roms/SLOF/lib/libvirtio/p9.c b/qemu/roms/SLOF/lib/libvirtio/p9.c
deleted file mode 100644
index 0e5953031..000000000
--- a/qemu/roms/SLOF/lib/libvirtio/p9.c
+++ /dev/null
@@ -1,575 +0,0 @@
-/******************************************************************************
- * Copyright (c) 2011 IBM Corporation
- * All rights reserved.
- * This program and the accompanying materials
- * are made available under the terms of the BSD License
- * which accompanies this distribution, and is available at
- * http://www.opensource.org/licenses/bsd-license.php
- *
- * Contributors:
- * IBM Corporation - initial implementation
- *****************************************************************************/
-
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <byteorder.h>
-#include "p9.h"
-
-
-/* Protocol stack marshaling. */
-uint8_t *sp;
-
-#define GET_08(s,i) (s)[(i)]
-#define GET_16(s,i) le16_to_cpu(*(uint16_t*)(&(s)[(i)]))
-#define GET_32(s,i) le32_to_cpu(*(uint32_t*)(&(s)[(i)]))
-#define GET_64(s,i) le64_to_cpu(*(uint64_t*)(&(s)[(i)]))
-
-#define SET_08(s,i,v) (s)[(i)] = (v)
-#define SET_16(s,i,v) *(uint16_t*)(&(s)[(i)]) = cpu_to_le16(v)
-#define SET_32(s,i,v) *(uint32_t*)(&(s)[(i)]) = cpu_to_le32(v)
-#define SET_64(s,i,v) *(uint64_t*)(&(s)[(i)]) = cpu_to_le64(v)
-
-#define PUT_08(v) sp[0] = (v);sp+=1
-#define PUT_16(v) *(uint16_t*)(&sp[0]) = cpu_to_le16(v);sp+=2
-#define PUT_32(v) *(uint32_t*)(&sp[0]) = cpu_to_le32(v);sp+=4
-#define PUT_64(v) *(uint64_t*)(&sp[0]) = cpu_to_le64(v);sp+=8
-
-#define PUT_HD(m,t) PUT_32(0);PUT_08(m);PUT_16(t)
-#define PUT_SN(v,n) PUT_16(n);memcpy(sp,(v),(n));sp+=n
-#define PUT_ST(v) PUT_16(strlen(v));memcpy(sp,(v),strlen(v));\
- sp+=strlen(v)
-
-#define GET_SIZE (sp - tx)
-
-
-/* General defines. */
-#define MIN(a,b) ((a)>(b)?(b):(a))
-
-#define NOTAG ((uint16_t)~0)
-#define NOFID ((uint32_t)~0)
-#define TAG 1
-#define BUF_SIZE (8*1024)
-
-#define VERSION "9P2000.u"
-#define UNKNOWN_VER "unknown"
-
-#define MSG_SIZE 0
-#define MSG_ID 4
-#define MSG_ERR 0x6b
-#define MSG_ERR_STR 9
-#define MSG_ERR_STR_LEN 7
-#define MSG_TAG 5
-#define MSG_VER_MSIZE 7
-#define MSG_VER_STR_LEN 11
-#define MSG_VER_STR 13
-#define MSG_WALK_TX_ELMT 15
-#define MSG_WALK_RX_ELMT 7
-#define MSG_SIZE 0
-#define MSG_WALK_MAX_ELMT 16
-#define MSG_QID_SIZE 13
-#define MSG_WALK_RX_HDR_SIZE 9
-#define MSG_OPEN_IOUNIT 20
-#define MSG_OPEN_MODE_MASK 0x5f
-#define MSG_READ_COUNT 7
-#define MSG_READ_DATA 11
-#define MSG_STAT_LEN 42
-#define MSG_STAT_TYPE 17
-
-#define T_VERSION 100
-#define R_VERSION (T_VERSION + 1)
-#define T_ATTACH 104
-#define R_ATTACH (T_ATTACH + 1)
-#define T_ERROR 106
-#define R_ERROR (T_ERROR + 1)
-#define T_WALK 110
-#define R_WALK (T_WALK + 1)
-#define T_OPEN 112
-#define R_OPEN (T_OPEN + 1)
-#define T_READ 116
-#define R_READ (T_READ + 1)
-#define T_CLUNK 120
-#define R_CLUNK (T_CLUNK + 1)
-#define T_STAT 124
-#define R_STAT (T_STAT + 1)
-
-static p9_transact_t transact;
-static void *transact_opaque;
-static uint8_t *tx;
-static uint8_t *rx;
-
-
-/**
- * p9_reg_transport
- *
- * Registers a transport function for use by the P9 protocol. The transport
- * connects the P9 Client (this library) to a server instance.
- *
- * @param transact_func[in] Function pointer to type p9_transact_t.
- * @param tx_buffer[in] TX buffer, must be 8k in size.
- * @param rx_buffer[in] RX buffer, must be 8k in size.
- */
-void p9_reg_transport(p9_transact_t transact_func, void *opaque,
- uint8_t *tx_buffer, uint8_t *rx_buffer)
-{
- transact = transact_func;
- transact_opaque = opaque;
- tx = tx_buffer;
- rx = rx_buffer;
-}
-
-/**
- * reset_buffers
- *
- * Reset the RX and TX buffers to BUF_SIZE (8k) and reset the Stack Pointer
- * for the TX buffer, which is referenced by the PUT_* macro's.
- */
-void reset_buffers(void)
-{
- memset(tx, 0, BUF_SIZE);
- memset(rx, 0, BUF_SIZE);
- sp = tx;
-}
-
-/**
- * p9_transaction
- *
- * Perform a transaction (send/recv) over the registered transport.
- *
- * @param connection[in|out] Connection object.
- * @return 0 = success, -ve = error.
- */
-int p9_transaction(p9_connection_t *connection)
-{
- int rc;
- int tx_size = GET_SIZE;
- uint32_t rx_size = connection->message_size;
-
- if (transact == NULL) {
- return P9_NO_TRANSPORT;
- }
- if (tx == NULL || rx == NULL) {
- return P9_NO_BUFFER;
- }
- if (connection->message_size > BUF_SIZE) {
- return P9_MSG_SIZE_TOO_BIG;
- }
- if (tx_size > connection->message_size) {
- return P9_MSG_TOO_LONG;
- }
-
- SET_32(tx, MSG_SIZE, tx_size);
- rc = transact(transact_opaque, tx, tx_size, rx, &rx_size);
-
- if (rc != 0) {
- return P9_TRANSPORT_ERROR;
- }
- if (GET_16(tx, MSG_TAG) != GET_16(rx, MSG_TAG)) {
- return P9_UNEXPECTED_TAG;
- }
- if (GET_08(rx, MSG_ID) == MSG_ERR) {
- char error_string[200];
-
- memset(error_string, 0, 200);
- strncpy(error_string, (char *)&rx[MSG_ERR_STR],
- MIN(200 - 1, GET_16(rx, MSG_ERR_STR_LEN)));
-#ifndef TEST
- printf("\nError: %s\n", error_string);
-#endif
- return P9_R_ERROR;
- }
- if ((GET_08(tx, MSG_ID) + 1) != GET_08(rx, MSG_ID)) {
- return P9_UNEXPECTED_MSG;
- }
-
- return 0;
-}
-
-/**
- * p9_version
- *
- * Called to start a session. Negotiates the maximum message size for the
- * P9 protocol.
- *
- * @param connection[in|out] Connection object, contains message_size.
- * @return 0 = success, -ve = error.
- *
- * @remark
- * size[4] Tversion tag[2] msize[4] version[s]
- * size[4] Rversion tag[2] msize[4] version[s]
- */
-int p9_version(p9_connection_t *connection)
-{
- int rc;
- char *ver_str;
- int ver_len;
-
- reset_buffers();
-
- /* Build message. */
- PUT_HD(T_VERSION, NOTAG);
- PUT_32(connection->message_size);
- PUT_ST(VERSION);
-
- /* Send message. */
- rc = p9_transaction(connection);
- if (rc != 0) {
- return rc;
- }
-
- /* Handle response. */
- connection->message_size = MIN(connection->message_size,
- GET_32(rx, MSG_VER_MSIZE));
-
- ver_str = (char *)&rx[MSG_VER_STR];
- ver_len = GET_16(rx, MSG_VER_STR_LEN);
- if (strncmp(UNKNOWN_VER, ver_str, ver_len) == 0) {
- return P9_UNKNOWN_VERSION;
- }
-
-
- return 0;
-}
-
-/**
- * p9_attach
- *
- * Called to open a connection for a user to a file tree on the server. There
- * is no authorisation undertaken (NOFID).
- *
- * @param connection[in|out] Connection object, contains uname and aname as
- * well as the connection fid and returned qid.
- * @return 0 = success, -ve = error.
- *
- * @remark
- * size[4] Tattach tag[2] fid[4] afid[4] uname[s] aname[s] n_uname[4]
- * size[4] Rattach tag[2] qid[13]
- */
-int p9_attach(p9_connection_t *connection)
-{
- int rc;
- int length = 19 + strlen(connection->uname) + strlen(connection->aname);
-
- if (length > connection->message_size) {
- return P9_MSG_TOO_LONG;
- }
-
- reset_buffers();
-
- /* Build message. */
- PUT_HD(T_ATTACH, TAG);
- PUT_32(connection->fid);
- PUT_32(NOFID);
- PUT_ST(connection->uname);
- PUT_ST(connection->aname);
- PUT_32(~0); /* ??? */
-
- /* Send message. */
- rc = p9_transaction(connection);
- if (rc != 0) {
- return rc;
- }
-
-
- return 0;
-}
-
-/**
- * p9_clunk
- *
- * Called when closing a file or connection (or after failed opens). Tells the
- * server that the supplied fid is no longer needed by this client.
- *
- * @param connection[in|out] Connection object.
- * @param fid[in] Fid to be clunked (released) on the server.
- * @return 0 = success, -ve = error.
- *
- * @remark
- * size[4] Tclunk tag[2] fid[4]
- * size[4] Rclunk tag[2]
- */
-int p9_clunk(p9_connection_t *connection, uint32_t fid)
-{
- int rc;
-
- reset_buffers();
-
- /* Build message. */
- PUT_HD(T_CLUNK, TAG);
- PUT_32(fid);
-
- /* Send message. */
- rc = p9_transaction(connection);
- if (rc != 0) {
- return rc;
- }
-
-
- return 0;
-}
-
-/**
- * p9_walk
- *
- * Walk the provided path to a file (or directory) starting at the directory
- * indicated by fid and assigning new_fid to the last successfully walked
- * element. If not all elements of the path can be walked then the pos
- * pointer is set to the part of the path following the last successful
- * walked element. The function can be called again to walk the remainder
- * of the path (or produce an error).
- *
- * @param connection[in] Connection object.
- * @param fid[in] Fid to start walk from, must be directory or root (from
- * call to p9_attach).
- * @param new_fid[in] Fid to be used for the last walked element.
- * @param pos[in|out] Position in path that remains to be walked. If the
- * path was completely walked without error this will point to the NULL
- * at the end of path.
- * @return 1 = partial walk, 0 = success, -ve = error.
- *
- * @remark
- * size[4] Twalk tag[2] fid[4] newfid[4] nwname[2] nwname*(wname[s])
- * size[4] Rwalk tag[2] nwqid[2] nwqid*(qid[13])
- */
-int p9_walk(p9_connection_t *connection, uint32_t fid, uint32_t new_fid,
- uint8_t **pos)
-{
- int rc;
- const char *path = (const char *)*pos;
- uint8_t *s_tok;
- uint8_t *e_tok;
- int element_count = 0;
-
- if (path == NULL) {
- *pos = NULL;
- return P9_NULL_PATH;
- }
-
- reset_buffers();
-
- /* Build message. */
- PUT_HD(T_WALK, TAG); /* Length to 0, set later. */
- PUT_32(fid);
- PUT_32(new_fid);
- PUT_16(0); /* Element count to 0, set later. */
-
- /* Get elements from path, and append to message. */
- s_tok = (uint8_t *)path;
- e_tok = s_tok;
-
- while (*s_tok != 0) {
- while (*s_tok == '/') {
- s_tok++;
- }
- e_tok = s_tok;
- while ((*e_tok != '/') && (*e_tok != 0)) {
- e_tok++;
- }
-
- /* Check the element is OK. */
- if (strncmp(".", (const char *)s_tok, (e_tok - s_tok)) == 0) {
- /* Don't send ".", continue to next. */
- s_tok = e_tok;
- continue;
- }
- int tx_size = (e_tok - s_tok + 2 + GET_SIZE);
- int rx_size = ((element_count + 1) * MSG_QID_SIZE
- + MSG_WALK_RX_HDR_SIZE);
- if ((tx_size > connection->message_size)
- || (rx_size > connection->message_size)) {
- /*
- * Element makes TX msg too long OR expected RX msg
- * too long. Move pos to previous element and do
- * partial walk.
- */
- e_tok = s_tok;
- if (*(e_tok - 1) == '/') {
- e_tok--;
- }
- break;
- }
-
- /* Add the element to the message. */
- PUT_SN(s_tok, e_tok - s_tok);
- element_count++;
-
- /* Server supports no more than 16 elements, partial walk. */
- if (element_count == MSG_WALK_MAX_ELMT) {
- break;
- }
-
- /* Ready to find the next element. */
- s_tok = e_tok;
- }
-
- if ((element_count == 0) && (strlen(path) > 0)) {
- return P9_PATH_ELEMENT_TOO_LONG;
- }
-
- *pos = e_tok;
-
- /* Update counts and then send message. */
- SET_16(tx, MSG_WALK_TX_ELMT, element_count);
- rc = p9_transaction(connection);
- if (rc != 0) {
- return rc;
- }
-
- /* Check for special return conditions. */
- if (element_count != GET_16(rx, MSG_WALK_RX_ELMT)) {
- /* Find the last element successfully walked */
- s_tok = (uint8_t *)path;
- e_tok = s_tok;
- element_count = GET_16(rx, MSG_WALK_RX_ELMT);
-
- while (element_count--) {
- while (*s_tok == '/') {
- s_tok++;
- }
-
- e_tok = s_tok;
-
- while ((*e_tok != '/') && (*e_tok != 0)) {
- e_tok++;
- }
-
- s_tok = e_tok;
- }
-
- *pos = e_tok;
- }
- if (**pos != 0) {
- rc = P9_PARTIAL_WALK;
- }
-
-
- return rc;
-}
-
-/**
- * p9_open
- *
- * Opens the file represented by fid with associated mode bit mask. The iounit
- * size returned from the server is written to the connection object.
- *
- * @param file[in|out] File object, contains fid for file.
- * @param mode[in] Mode to open with. Bit's 0=R, 1=W, 2=RW, 3=EX, 4=Trunc
- * and 6=Delete on Close.
- * @return 0 = success, -ve = error.
- *
- * @remark
- * size[4] Topen tag[2] fid[4] mode[1]
- * size[4] Ropen tag[2] qid[13] iounit[4]
- */
-int p9_open(p9_file_t *file, uint8_t mode)
-{
- int rc;
- p9_connection_t *connection = file->connection;
-
- reset_buffers();
- file->iounit = 0;
-
- /* Build message. */
- PUT_HD(T_OPEN, TAG);
- PUT_32(file->fid);
- PUT_08(mode & MSG_OPEN_MODE_MASK);
-
- /* Send message. */
- rc = p9_transaction(connection);
- if (rc != 0) {
- return rc;
- }
-
- /* Handle response. */
- file->iounit = GET_32(rx, MSG_OPEN_IOUNIT);
-
-
- return 0;
-}
-
-/**
- * p9_read
- *
- * Reads the file in to buffer.
- *
- * @param file[in] File object, contains fid for file.
- * @param buffer[out] Buffer for data.
- * @param count[in] Number of bytes to read (less bytes than requested
- * may be read).
- * @param offset[in] Offset in file to read from.
- * @return Bytes read, -ve = error.
- *
- * @remark
- * size[4] Tread tag[2] fid[4] offset[8] count[4]
- * size[4] Rread tag[2] count[4] data[count]
- */
-int p9_read(p9_file_t *file, uint8_t *buffer,
- uint32_t count, uint64_t offset)
-{
- int rc;
- p9_connection_t *connection = file->connection;
- uint32_t got;
-
- reset_buffers();
- count = MIN((connection->message_size - MSG_READ_DATA), count);
-
- /* Build message. */
- PUT_HD(T_READ, TAG);
- PUT_32(file->fid);
- PUT_64(offset);
- PUT_32(count);
-
- /* Send message. */
- rc = p9_transaction(connection);
- if (rc != 0) {
- return rc;
- }
- got = GET_32(rx, MSG_READ_COUNT);
- if (got > count) {
- return P9_READ_UNEXPECTED_DATA;
- }
-
- /* Handle response. */
- memcpy(buffer, &rx[MSG_READ_DATA], got);
-
- return got;
-}
-
-/**
- * p9_stat
- *
- * Stat's the fid and writes the type and length to the file object.
- *
- * @param file[in|out] File object, contains fid for file.
- * @return 0 = success, -ve = error.
- *
- * @remark
- * size[4] Tstat tag[2] fid[4]
- * size[4] Rstat tag[2] size[2] stat[n]
- */
-int p9_stat(p9_file_t *file)
-{
- int rc;
- p9_connection_t *connection = file->connection;
-
- reset_buffers();
- file->length = 0;
- file->type = 0;
-
- /* Build message. */
- PUT_HD(T_STAT, TAG);
- PUT_32(file->fid);
-
- /* Send message. */
- rc = p9_transaction(connection);
- if (rc != 0) {
- return rc;
- }
-
- /* Handle response. */
- file->length = GET_64(rx, MSG_STAT_LEN);
- file->type = GET_08(rx, MSG_STAT_TYPE);
-
-
- return 0;
-}