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