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