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