|
|
1.1 ! root 1: /* ! 2: * File: bufq.c ! 3: * ! 4: * Purpose: ! 5: * Queueing routines for SCSI driver. ! 6: * Should be generalizable for other hard drives. ! 7: * ! 8: * $Log: bufq.c,v $ ! 9: * Revision 1.2 91/05/21 23:23:36 hal ! 10: * Enhanced debug printout. ! 11: * ! 12: * Revision 1.1 91/05/21 13:54:11 root ! 13: * First running version. ! 14: * ! 15: */ ! 16: ! 17: /* ! 18: * Includes. ! 19: */ ! 20: #include <sys/coherent.h> ! 21: #include <sys/buf.h> ! 22: ! 23: /* ! 24: * Definitions. ! 25: * Constants. ! 26: * Macros with argument lists. ! 27: * Typedefs. ! 28: * Enums. ! 29: */ ! 30: typedef struct { ! 31: BUF * head; /* point to first node */ ! 32: BUF * tail; /* point to last node */ ! 33: int count; /* number of nodes in the queue */ ! 34: } bufq_type; ! 35: ! 36: /* ! 37: * Global Data. ! 38: * Import Variables. ! 39: * Export Variables. ! 40: * Local Variables. ! 41: */ ! 42: static int num_q; /* number of queues in use */ ! 43: static bufq_type * bufq_q; /* pointer to allocated queue structs */ ! 44: ! 45: /* ! 46: * Functions. ! 47: * Import Functions. ! 48: * Export Functions. ! 49: * Local Functions. ! 50: */ ! 51: int bufq_init(); ! 52: void bufq_rlse(); ! 53: void bufq_wr_tail(); ! 54: BUF * bufq_rd_head(); ! 55: BUF * bufq_rm_head(); ! 56: ! 57: /* ! 58: * Debug macros. ! 59: */ ! 60: #if (DEBUG >= 3) ! 61: #define QSIZE printf("Q%d:%d ", s_id, bqp->count) ! 62: #else ! 63: #if (DEBUG >= 2) ! 64: #define QSIZE {if (bqp->count>1)printf("Q%d:%d ", s_id, bqp->count);} ! 65: #else ! 66: #define QSIZE ! 67: #endif ! 68: #endif ! 69: ! 70: /* ! 71: * bufq_init() ! 72: * ! 73: * Set up the desired number of queues. ! 74: * ! 75: * Return 1 if ok, 0 if kalloc() failed. ! 76: */ ! 77: int bufq_init(qcount) ! 78: int qcount; ! 79: { ! 80: int ret; ! 81: ! 82: if (qcount > 0 && (bufq_q = kalloc(qcount*sizeof(bufq_type)))) { ! 83: ret = 1; ! 84: kclear(bufq_q, qcount*sizeof(bufq_type)); ! 85: num_q = qcount; ! 86: #if (DEBUG >= 2) ! 87: printf("%d queues allocated\n", qcount); ! 88: #endif ! 89: } else ! 90: ret = 0; ! 91: ! 92: return ret; ! 93: } ! 94: ! 95: /* ! 96: * bufq_rlse() ! 97: * ! 98: * Deallocate buffer queue structs. ! 99: */ ! 100: void bufq_rlse() ! 101: { ! 102: num_q = 0; ! 103: if (bufq_q) ! 104: kfree(bufq_q); ! 105: } ! 106: ! 107: /* ! 108: * bufq_wr_tail() ! 109: * ! 110: * Append a BUF object to the doubly-linked queue. ! 111: * Object to be inserted has been allocated by the caller. ! 112: * Run at high priority. ! 113: */ ! 114: void bufq_wr_tail(s_id, bp) ! 115: int s_id; ! 116: BUF * bp; ! 117: { ! 118: int s; ! 119: bufq_type * bqp; ! 120: ! 121: if (s_id < num_q) { ! 122: bqp = bufq_q + s_id; ! 123: s = sphi(); ! 124: if (bqp->count == 0) { ! 125: bqp->head = bqp->tail = bp; ! 126: bp->b_actf = bp->b_actl = NULL; ! 127: } else { ! 128: bqp->tail->b_actf = bp; ! 129: bp->b_actf = NULL; ! 130: bp->b_actl = bqp->tail; ! 131: bqp->tail = bp; ! 132: } ! 133: bqp->count++; ! 134: QSIZE; ! 135: spl(s); ! 136: } ! 137: } ! 138: ! 139: /* ! 140: * bufq_rd_head() ! 141: * ! 142: * Nondestructively fetch the head entry in the queue - i.e., this routine ! 143: * does not remove an entry from the queue (see ss_rm_head() for that). ! 144: * Return NULL if queue is empty, else return pointer to head item. ! 145: */ ! 146: BUF * bufq_rd_head(s_id) ! 147: int s_id; ! 148: { ! 149: bufq_type * bqp; ! 150: ! 151: if (s_id < num_q) { ! 152: bqp = bufq_q + s_id; ! 153: return bqp->head; ! 154: } else ! 155: return NULL; ! 156: } ! 157: ! 158: /* ! 159: * bufq_rm_head() ! 160: * ! 161: * Delete head item from the queue. Return a pointer to the node deleted, ! 162: * or NULL if the queue was already empty. ! 163: * Run at high priority. ! 164: * ! 165: * This routine does NOT deallocate the node. That must be done by the ! 166: * calling function after this routine runs. ! 167: */ ! 168: BUF * bufq_rm_head(s_id) ! 169: int s_id; ! 170: { ! 171: BUF * ret; ! 172: int s; ! 173: bufq_type * bqp; ! 174: ! 175: if (s_id < num_q) { ! 176: bqp = bufq_q + s_id; ! 177: s = sphi(); ! 178: if (bqp->count > 0) { ! 179: ret = bqp->head; ! 180: if (bqp->count == 1) { ! 181: bqp->head = bqp->tail = NULL; ! 182: } else { ! 183: bqp->head = bqp->head->b_actf; ! 184: bqp->head->b_actl = NULL; ! 185: } ! 186: bqp->count--; ! 187: QSIZE; ! 188: } else ! 189: ret = NULL; ! 190: spl(s); ! 191: } else ! 192: ret = NULL; ! 193: ! 194: return ret; ! 195: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.