xref: /dragonfly/sys/bus/cam/cam_extend.c (revision 9dbf638f)
1 /*
2  * Written by Julian Elischer (julian@tfs.com)
3  * for TRW Financial Systems for use under the MACH(2.5) operating system.
4  *
5  * TRW Financial Systems, in accordance with their agreement with Carnegie
6  * Mellon University, makes this software available to CMU to distribute
7  * or use in any manner that they see fit as long as this message is kept with
8  * the software. For this reason TFS also grants any other persons or
9  * organisations permission to use or modify this software.
10  *
11  * TFS supplies this software to be publicly redistributed
12  * on the understanding that TFS is not responsible for the correct
13  * functioning of this software in any circumstances.
14  *
15  * $FreeBSD: src/sys/cam/cam_extend.c,v 1.3 1999/08/28 00:40:39 peter Exp $
16  * $DragonFly: src/sys/bus/cam/cam_extend.c,v 1.3 2003/08/07 21:16:44 dillon Exp $
17  */
18 /*
19  * XXX XXX XXX XXX  We should get DEVFS working so that we
20  * don't have to do this, possibly sparse, array based junk.
21  * XXX: We can do this now with dev_t, that's even better.
22  */
23 /*
24  * Extensible arrays: Use a realloc like implementation to permit
25  * the arrays to be extend.
26  */
27 #include <sys/param.h>
28 #include <sys/systm.h>
29 #include <sys/kernel.h>
30 #include <sys/malloc.h>
31 
32 #include "cam_extend.h"
33 
34 struct extend_array
35 {
36 	int nelem;
37 	void **ps;
38 };
39 
40 static void *
41 cam_extend_alloc(size_t s)
42 {
43 	void *p = malloc(s, M_DEVBUF, M_NOWAIT);
44 	if (!p)
45 		panic("extend_alloc: malloc failed.");
46 	return p;
47 }
48 
49 static void
50 cam_extend_free(void *p)
51 {
52 	free(p, M_DEVBUF);
53 }
54 
55 /* EXTEND_CHUNK: Number of extend slots to allocate whenever we need a new
56  * one.
57  */
58 #ifndef EXTEND_CHUNK
59 	#define EXTEND_CHUNK 8
60 #endif
61 
62 struct extend_array *
63 cam_extend_new(void)
64 {
65 	struct extend_array *p = cam_extend_alloc(sizeof(*p));
66 	if (p) {
67 		p->nelem = 0;
68 		p->ps = 0;
69 	}
70 
71 	return p;
72 }
73 
74 void *
75 cam_extend_set(struct extend_array *ea, int index, void *value)
76 {
77 	if (index >= ea->nelem) {
78 		void **space;
79 		space = cam_extend_alloc(sizeof(void *) * (index + EXTEND_CHUNK));
80 		bzero(space, sizeof(void *) * (index + EXTEND_CHUNK));
81 
82 		/* Make sure we have something to copy before we copy it */
83 		if (ea->nelem) {
84 			bcopy(ea->ps, space, sizeof(void *) * ea->nelem);
85 			cam_extend_free(ea->ps);
86 		}
87 
88 		ea->ps = space;
89 		ea->nelem = index + EXTEND_CHUNK;
90 	}
91 	if (ea->ps[index]) {
92 		printf("extend_set: entry %d already has storage.\n", index);
93 		return 0;
94 	}
95 	else
96 		ea->ps[index] = value;
97 
98 	return value;
99 }
100 
101 void *
102 cam_extend_get(struct extend_array *ea,
103 	       int index)
104 {
105 	if (ea == NULL || index >= ea->nelem || index < 0)
106 		return NULL;
107 	return ea->ps[index];
108 }
109 
110 void
111 cam_extend_release(struct extend_array *ea, int index)
112 {
113 	void *p = cam_extend_get(ea, index);
114 	if (p) {
115 		ea->ps[index] = 0;
116 	}
117 }
118