|
|
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.