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