Browse Source

Initial sketch for the generic data-transfer interface.

tags/v0.9.3
Michael Brown 18 years ago
parent
commit
2575ddc889
5 changed files with 417 additions and 0 deletions
  1. 81
    0
      src/core/interface.c
  2. 74
    0
      src/core/xfer.c
  3. 36
    0
      src/include/gpxe/interface.h
  4. 148
    0
      src/include/gpxe/iobuf.h
  5. 78
    0
      src/include/gpxe/xfer.h

+ 81
- 0
src/core/interface.c View File

@@ -0,0 +1,81 @@
1
+/*
2
+ * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+#include <assert.h>
20
+#include <gpxe/interface.h>
21
+
22
+/** @file
23
+ *
24
+ * Object communication interfaces
25
+ *
26
+ */
27
+
28
+/**
29
+ * Obtain reference to interface
30
+ *
31
+ * @v intf		Interface
32
+ * @ret intf		Interface
33
+ *
34
+ * Increases the reference count on the interface.
35
+ */
36
+static struct interface * intf_get ( struct interface *intf ) {
37
+	intf->refcnt ( intf, +1 );
38
+	return intf;
39
+}
40
+
41
+/**
42
+ * Drop reference to interface
43
+ *
44
+ * @v intf		Interface
45
+ *
46
+ * Decreases the reference count on the interface.
47
+ */
48
+static void intf_put ( struct interface *intf ) {
49
+	intf->refcnt ( intf, -1 );
50
+}
51
+
52
+/**
53
+ * Plug an interface into a new destination interface
54
+ *
55
+ * @v intf		Interface
56
+ * @v dest		New destination interface
57
+ *
58
+ * The reference to the existing destination interface is dropped, a
59
+ * reference to the new destination interface is obtained, and the
60
+ * interface is updated to point to the new destination interface.
61
+ *
62
+ * Note that there is no "unplug" call; instead you must plug the
63
+ * interface into a null interface.
64
+ */
65
+void plug ( struct interface *intf, struct interface *dest ) {
66
+	intf_put ( intf->dest );
67
+	intf->dest = intf_get ( dest );
68
+}
69
+
70
+/**
71
+ * Null update reference count
72
+ *
73
+ * @v intf		Interface
74
+ * @v delta		Change to apply to reference count
75
+ *
76
+ * Use this as the refcnt() method for an interface that does not need
77
+ * to support reference counting.
78
+ */
79
+void null_refcnt ( struct interface *intf __unused, int delta __unused ) {
80
+	/* Do nothing */
81
+}

+ 74
- 0
src/core/xfer.c View File

@@ -0,0 +1,74 @@
1
+/*
2
+ * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+#include <errno.h>
20
+#include <gpxe/xfer.h>
21
+
22
+/** @file
23
+ *
24
+ * Data transfer interfaces
25
+ *
26
+ */
27
+
28
+/**
29
+ * Deliver datagram
30
+ *
31
+ * @v xfer		Data-transfer interface
32
+ * @v iobuf		Datagram I/O buffer
33
+ * @ret rc		Return status code
34
+ */
35
+int deliver ( struct xfer_interface *xfer, struct io_buffer *iobuf ) {
36
+	struct xfer_interface *dest = xfer_dest ( xfer );
37
+
38
+	return dest->op->deliver ( dest, xfer, iobuf );
39
+}
40
+
41
+/**
42
+ * Null deliver datagram
43
+ *
44
+ * @v xfer		Data-transfer interface
45
+ * @v src		Source interface
46
+ * @v iobuf		Datagram I/O buffer
47
+ * @ret rc		Return status code
48
+ */
49
+static int null_deliver ( struct xfer_interface *xfer __unused,
50
+			  struct xfer_interface *src __unused,
51
+			  struct io_buffer *iobuf ) {
52
+	free_iob ( iobuf );
53
+	return -EPIPE;
54
+}
55
+
56
+/** Null data transfer interface operations */
57
+struct xfer_interface_operations null_xfer_ops = {
58
+	.deliver = null_deliver,
59
+};
60
+
61
+/**
62
+ * Null data transfer interface
63
+ *
64
+ * This is the interface to which data transfer interfaces are
65
+ * connected when unplugged.  It will never generate messages, and
66
+ * will silently absorb all received messages.
67
+ */
68
+struct xfer_interface null_xfer = {
69
+	.intf = {
70
+		.dest = &null_xfer.intf,
71
+		.refcnt = null_refcnt,
72
+	},
73
+	.op = &null_xfer_ops,
74
+};

+ 36
- 0
src/include/gpxe/interface.h View File

@@ -0,0 +1,36 @@
1
+#ifndef _GPXE_INTERFACE_H
2
+#define _GPXE_INTERFACE_H
3
+
4
+/** @file
5
+ *
6
+ * Object communication interfaces
7
+ *
8
+ */
9
+
10
+/** An object communication interface */
11
+struct interface {
12
+	/** Destination interface
13
+	 *
14
+	 * When messages are sent via this interface, they will be
15
+	 * delivered to the destination interface.
16
+	 *
17
+	 * This pointer may never be NULL.  When the interface is
18
+	 * unplugged, it should point to a null interface.
19
+	 */
20
+	struct interface *dest;
21
+	/** Update reference count
22
+	 *
23
+	 * @v intf		Interface
24
+	 * @v delta		Change to apply to reference count
25
+	 *
26
+	 * This method updates the reference count for the object
27
+	 * containing the interface.
28
+	 */
29
+	void ( * refcnt ) ( struct interface *intf, int delta );
30
+};
31
+
32
+extern void plug ( struct interface *intf, struct interface *dest );
33
+
34
+extern void null_refcnt ( struct interface *intf, int delta );
35
+
36
+#endif /* _GPXE_INTERFACE_H */

+ 148
- 0
src/include/gpxe/iobuf.h View File

@@ -0,0 +1,148 @@
1
+#ifndef _GPXE_IOBUF_H
2
+#define _GPXE_IOBUF_H
3
+
4
+/** @file
5
+ *
6
+ * I/O buffers
7
+ *
8
+ */
9
+
10
+#include <stdint.h>
11
+#include <assert.h>
12
+#include <gpxe/list.h>
13
+
14
+/**
15
+ * A persistent I/O buffer
16
+ *
17
+ * This data structure encapsulates a long-lived I/O buffer.  The
18
+ * buffer may be passed between multiple owners, queued for possible
19
+ * retransmission, etc.
20
+ */
21
+struct io_buffer {
22
+	/** List of which this buffer is a member
23
+	 *
24
+	 * The list must belong to the current owner of the buffer.
25
+	 * Different owners may maintain different lists (e.g. a
26
+	 * retransmission list for TCP).
27
+	 */
28
+	struct list_head list;
29
+
30
+	/** Start of the buffer */
31
+	void *head;
32
+	/** Start of data */
33
+	void *data;
34
+	/** End of data */
35
+	void *tail;
36
+	/** End of the buffer */
37
+        void *end;
38
+};
39
+
40
+/**
41
+ * Reserve space at start of I/O buffer
42
+ *
43
+ * @v iob	I/O buffer
44
+ * @v len	Length to reserve
45
+ * @ret data	Pointer to new start of buffer
46
+ */
47
+static inline void * iob_reserve ( struct io_buffer *iob, size_t len ) {
48
+	iob->data += len;
49
+	iob->tail += len;
50
+	assert ( iob->tail <= iob->end );
51
+	return iob->data;
52
+}
53
+
54
+/**
55
+ * Add data to start of I/O buffer
56
+ *
57
+ * @v iob	I/O buffer
58
+ * @v len	Length to add
59
+ * @ret data	Pointer to new start of buffer
60
+ */
61
+static inline void * iob_push ( struct io_buffer *iob, size_t len ) {
62
+	iob->data -= len;
63
+	assert ( iob->data >= iob->head );
64
+	return iob->data;
65
+}
66
+
67
+/**
68
+ * Remove data from start of I/O buffer
69
+ *
70
+ * @v iob	I/O buffer
71
+ * @v len	Length to remove
72
+ * @ret data	Pointer to new start of buffer
73
+ */
74
+static inline void * iob_pull ( struct io_buffer *iob, size_t len ) {
75
+	iob->data += len;
76
+	assert ( iob->data <= iob->tail );
77
+	return iob->data;
78
+}
79
+
80
+/**
81
+ * Add data to end of I/O buffer
82
+ *
83
+ * @v iob	I/O buffer
84
+ * @v len	Length to add
85
+ * @ret data	Pointer to newly added space
86
+ */
87
+static inline void * iob_put ( struct io_buffer *iob, size_t len ) {
88
+	void *old_tail = iob->tail;
89
+	iob->tail += len;
90
+	assert ( iob->tail <= iob->end );
91
+	return old_tail;
92
+}
93
+
94
+/**
95
+ * Remove data from end of I/O buffer
96
+ *
97
+ * @v iob	I/O buffer
98
+ * @v len	Length to remove
99
+ */
100
+static inline void iob_unput ( struct io_buffer *iob, size_t len ) {
101
+	iob->tail -= len;
102
+	assert ( iob->tail >= iob->data );
103
+}
104
+
105
+/**
106
+ * Empty an I/O buffer
107
+ *
108
+ * @v iob	I/O buffer
109
+ */
110
+static inline void iob_empty ( struct io_buffer *iob ) {
111
+	iob->tail = iob->data;
112
+}
113
+
114
+/**
115
+ * Calculate length of data in an I/O buffer
116
+ *
117
+ * @v iob	I/O buffer
118
+ * @ret len	Length of data in buffer
119
+ */
120
+static inline size_t iob_len ( struct io_buffer *iob ) {
121
+	return ( iob->tail - iob->data );
122
+}
123
+
124
+/**
125
+ * Calculate available space at start of an I/O buffer
126
+ *
127
+ * @v iob	I/O buffer
128
+ * @ret len	Length of data available at start of buffer
129
+ */
130
+static inline size_t iob_headroom ( struct io_buffer *iob ) {
131
+	return ( iob->data - iob->head );
132
+}
133
+
134
+/**
135
+ * Calculate available space at end of an I/O buffer
136
+ *
137
+ * @v iob	I/O buffer
138
+ * @ret len	Length of data available at end of buffer
139
+ */
140
+static inline size_t iob_tailroom ( struct io_buffer *iob ) {
141
+	return ( iob->end - iob->tail );
142
+}
143
+
144
+extern struct io_buffer * alloc_iob ( size_t len );
145
+extern void free_iob ( struct io_buffer *iob );
146
+extern void iob_pad ( struct io_buffer *iob, size_t min_len );
147
+
148
+#endif /* _GPXE_IOBUF_H */

+ 78
- 0
src/include/gpxe/xfer.h View File

@@ -0,0 +1,78 @@
1
+#ifndef _GPXE_XFER_H
2
+#define _GPXE_XFER_H
3
+
4
+/** @file
5
+ *
6
+ * Data transfer interfaces
7
+ *
8
+ */
9
+
10
+#include <stddef.h>
11
+#include <gpxe/interface.h>
12
+#include <gpxe/iobuf.h>
13
+
14
+struct xfer_interface;
15
+
16
+/** Data transfer interface operations */
17
+struct xfer_interface_operations {
18
+	/** Deliver datagram
19
+	 *
20
+	 * @v xfer		Data-transfer interface
21
+	 * @v src		Source  interface
22
+	 * @v iobuf		Datagram I/O buffer
23
+	 * @ret rc		Return status code
24
+	 */
25
+	int ( * deliver ) ( struct xfer_interface *xfer,
26
+			    struct xfer_interface *src,
27
+			    struct io_buffer *iobuf );
28
+};
29
+
30
+/** A data transfer interface */
31
+struct xfer_interface {
32
+	/** Generic object communication interface */
33
+	struct interface intf;
34
+	/** Operations for received messages */
35
+	struct xfer_interface_operations *op;
36
+};
37
+
38
+extern struct xfer_interface null_xfer;
39
+extern struct xfer_interface_operations null_xfer_ops;
40
+
41
+static inline struct xfer_interface *
42
+xfer_dest ( struct xfer_interface *xfer ) {
43
+	return container_of ( xfer->intf.dest, struct xfer_interface, intf );
44
+}
45
+
46
+/**
47
+ * Plug a data-transfer interface into a new destination interface
48
+ *
49
+ * @v xfer		Data-transfer interface
50
+ * @v dest		New destination interface
51
+ */
52
+static inline void xfer_plug ( struct xfer_interface *xfer,
53
+			       struct xfer_interface *dest ) {
54
+	plug ( &xfer->intf, &dest->intf );
55
+}
56
+
57
+/**
58
+ * Unplug a data-transfer interface
59
+ *
60
+ * @v xfer		Data-transfer interface
61
+ */
62
+static inline void xfer_unplug ( struct xfer_interface *xfer ) {
63
+	plug ( &xfer->intf, &null_xfer.intf );
64
+}
65
+
66
+/**
67
+ * Terminate a data-transfer interface
68
+ *
69
+ * @v xfer		Data-transfer interface
70
+ *
71
+ * After calling this method, no further messages will be received via
72
+ * the interface.
73
+ */
74
+static inline void xfer_terminate ( struct xfer_interface *xfer ) {
75
+	xfer->op = &null_xfer_ops;
76
+};
77
+
78
+#endif /* _GPXE_XFER_H */

Loading…
Cancel
Save