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