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 */ 17 /* 18 * XXX XXX XXX XXX We should get DEVFS working so that we 19 * don't have to do this, possibly sparse, array based junk. 20 * XXX: We can do this now with cdev_t, that's even better. 21 */ 22 /* 23 * Extensible arrays: Use a realloc like implementation to permit 24 * the arrays to be extend. 25 */ 26 #include <sys/param.h> 27 #include <sys/systm.h> 28 #include <sys/kernel.h> 29 #include <sys/malloc.h> 30 31 #include "cam_extend.h" 32 33 struct extend_array 34 { 35 int nelem; 36 void **ps; 37 }; 38 39 /* EXTEND_CHUNK: Number of extend slots to allocate whenever we need a new 40 * one. 41 */ 42 #ifndef EXTEND_CHUNK 43 #define EXTEND_CHUNK 8 44 #endif 45 46 struct extend_array * 47 cam_extend_new(void) 48 { 49 return(kmalloc(sizeof(struct extend_array), M_DEVBUF, 50 M_INTWAIT | M_ZERO)); 51 } 52 53 void * 54 cam_extend_set(struct extend_array *ea, int index, void *value) 55 { 56 if (index >= ea->nelem) { 57 void **space; 58 space = kmalloc(sizeof(void *) * (index + EXTEND_CHUNK), 59 M_DEVBUF, M_INTWAIT | M_ZERO); 60 61 /* Make sure we have something to copy before we copy it */ 62 if (ea->nelem) { 63 bcopy(ea->ps, space, sizeof(void *) * ea->nelem); 64 kfree(ea->ps, M_DEVBUF); 65 } 66 67 ea->ps = space; 68 ea->nelem = index + EXTEND_CHUNK; 69 } 70 if (ea->ps[index]) { 71 kprintf("extend_set: entry %d already has storage.\n", index); 72 return 0; 73 } 74 else 75 ea->ps[index] = value; 76 77 return value; 78 } 79 80 void * 81 cam_extend_get(struct extend_array *ea, 82 int index) 83 { 84 if (ea == NULL || index >= ea->nelem || index < 0) 85 return NULL; 86 return ea->ps[index]; 87 } 88 89 void 90 cam_extend_release(struct extend_array *ea, int index) 91 { 92 void *p = cam_extend_get(ea, index); 93 if (p) { 94 ea->ps[index] = NULL; 95 } 96 } 97