1*433d6423SLionel Sambuc /* libbdev - asynchronous call structure management */ 2*433d6423SLionel Sambuc 3*433d6423SLionel Sambuc #include <minix/drivers.h> 4*433d6423SLionel Sambuc #include <minix/bdev.h> 5*433d6423SLionel Sambuc #include <assert.h> 6*433d6423SLionel Sambuc 7*433d6423SLionel Sambuc #include "const.h" 8*433d6423SLionel Sambuc #include "type.h" 9*433d6423SLionel Sambuc #include "proto.h" 10*433d6423SLionel Sambuc 11*433d6423SLionel Sambuc static bdev_call_t *calls[NR_CALLS]; 12*433d6423SLionel Sambuc bdev_call_alloc(int count)13*433d6423SLionel Sambucbdev_call_t *bdev_call_alloc(int count) 14*433d6423SLionel Sambuc { 15*433d6423SLionel Sambuc /* Allocate a call structure. 16*433d6423SLionel Sambuc */ 17*433d6423SLionel Sambuc bdev_call_t *call; 18*433d6423SLionel Sambuc bdev_id_t id; 19*433d6423SLionel Sambuc 20*433d6423SLionel Sambuc for (id = 0; id < NR_CALLS; id++) 21*433d6423SLionel Sambuc if (calls[id] == NULL) 22*433d6423SLionel Sambuc break; 23*433d6423SLionel Sambuc 24*433d6423SLionel Sambuc if (id == NR_CALLS) 25*433d6423SLionel Sambuc return NULL; 26*433d6423SLionel Sambuc 27*433d6423SLionel Sambuc call = malloc(sizeof(bdev_call_t) + 28*433d6423SLionel Sambuc sizeof(call->gvec[0]) * (count - 1) + 29*433d6423SLionel Sambuc sizeof(call->vec[0]) * count); 30*433d6423SLionel Sambuc 31*433d6423SLionel Sambuc if (call == NULL) 32*433d6423SLionel Sambuc return NULL; 33*433d6423SLionel Sambuc 34*433d6423SLionel Sambuc call->id = id; 35*433d6423SLionel Sambuc call->vec = (iovec_t *) &call->gvec[count]; 36*433d6423SLionel Sambuc 37*433d6423SLionel Sambuc calls[id] = call; 38*433d6423SLionel Sambuc 39*433d6423SLionel Sambuc return call; 40*433d6423SLionel Sambuc } 41*433d6423SLionel Sambuc bdev_call_free(bdev_call_t * call)42*433d6423SLionel Sambucvoid bdev_call_free(bdev_call_t *call) 43*433d6423SLionel Sambuc { 44*433d6423SLionel Sambuc /* Free a call structure. 45*433d6423SLionel Sambuc */ 46*433d6423SLionel Sambuc 47*433d6423SLionel Sambuc assert(calls[call->id] == call); 48*433d6423SLionel Sambuc 49*433d6423SLionel Sambuc calls[call->id] = NULL; 50*433d6423SLionel Sambuc 51*433d6423SLionel Sambuc free(call); 52*433d6423SLionel Sambuc } 53*433d6423SLionel Sambuc bdev_call_get(bdev_id_t id)54*433d6423SLionel Sambucbdev_call_t *bdev_call_get(bdev_id_t id) 55*433d6423SLionel Sambuc { 56*433d6423SLionel Sambuc /* Retrieve a call structure by request number. 57*433d6423SLionel Sambuc */ 58*433d6423SLionel Sambuc 59*433d6423SLionel Sambuc if (id < 0 || id >= NR_CALLS) 60*433d6423SLionel Sambuc return NULL; 61*433d6423SLionel Sambuc 62*433d6423SLionel Sambuc return calls[id]; 63*433d6423SLionel Sambuc } 64*433d6423SLionel Sambuc bdev_call_find(dev_t dev)65*433d6423SLionel Sambucbdev_call_t *bdev_call_find(dev_t dev) 66*433d6423SLionel Sambuc { 67*433d6423SLionel Sambuc /* Find the first asynchronous request for the given device, if any. 68*433d6423SLionel Sambuc */ 69*433d6423SLionel Sambuc bdev_id_t id; 70*433d6423SLionel Sambuc 71*433d6423SLionel Sambuc for (id = 0; id < NR_CALLS; id++) 72*433d6423SLionel Sambuc if (calls[id] != NULL && calls[id]->dev == dev) 73*433d6423SLionel Sambuc return calls[id]; 74*433d6423SLionel Sambuc 75*433d6423SLionel Sambuc return NULL; 76*433d6423SLionel Sambuc } 77*433d6423SLionel Sambuc bdev_call_iter_maj(dev_t dev,bdev_call_t * call,bdev_call_t ** next)78*433d6423SLionel Sambucbdev_call_t *bdev_call_iter_maj(dev_t dev, bdev_call_t *call, 79*433d6423SLionel Sambuc bdev_call_t **next) 80*433d6423SLionel Sambuc { 81*433d6423SLionel Sambuc /* Iterate over all asynchronous requests for a major device. This function 82*433d6423SLionel Sambuc * must be safe even if the returned call structure is freed. 83*433d6423SLionel Sambuc */ 84*433d6423SLionel Sambuc bdev_id_t id; 85*433d6423SLionel Sambuc int major; 86*433d6423SLionel Sambuc 87*433d6423SLionel Sambuc major = major(dev); 88*433d6423SLionel Sambuc 89*433d6423SLionel Sambuc /* If this is the first invocation, find the first match. Otherwise, take the 90*433d6423SLionel Sambuc * call we found to be next in the last invocation, which may be NULL. 91*433d6423SLionel Sambuc */ 92*433d6423SLionel Sambuc if (call == NULL) { 93*433d6423SLionel Sambuc for (id = 0; id < NR_CALLS; id++) 94*433d6423SLionel Sambuc if (calls[id] != NULL && major(calls[id]->dev) == major) 95*433d6423SLionel Sambuc break; 96*433d6423SLionel Sambuc 97*433d6423SLionel Sambuc if (id == NR_CALLS) 98*433d6423SLionel Sambuc return NULL; 99*433d6423SLionel Sambuc 100*433d6423SLionel Sambuc call = calls[id]; 101*433d6423SLionel Sambuc } else { 102*433d6423SLionel Sambuc if ((call = *next) == NULL) 103*433d6423SLionel Sambuc return NULL; 104*433d6423SLionel Sambuc } 105*433d6423SLionel Sambuc 106*433d6423SLionel Sambuc /* Look for the next match, if any. */ 107*433d6423SLionel Sambuc *next = NULL; 108*433d6423SLionel Sambuc 109*433d6423SLionel Sambuc for (id = call->id + 1; id < NR_CALLS; id++) { 110*433d6423SLionel Sambuc if (calls[id] != NULL && major(calls[id]->dev) == major) { 111*433d6423SLionel Sambuc *next = calls[id]; 112*433d6423SLionel Sambuc 113*433d6423SLionel Sambuc break; 114*433d6423SLionel Sambuc } 115*433d6423SLionel Sambuc } 116*433d6423SLionel Sambuc 117*433d6423SLionel Sambuc return call; 118*433d6423SLionel Sambuc } 119