hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/macintosh/adb-iop.c
....@@ -7,10 +7,6 @@
77 * 1999-07-01 (jmt) - First implementation for new driver architecture.
88 *
99 * 1999-07-31 (jmt) - First working version.
10
- *
11
- * TODO:
12
- *
13
- * o Implement SRQ handling.
1410 */
1511
1612 #include <linux/types.h>
....@@ -18,29 +14,24 @@
1814 #include <linux/mm.h>
1915 #include <linux/delay.h>
2016 #include <linux/init.h>
21
-#include <linux/proc_fs.h>
2217
23
-#include <asm/macintosh.h>
24
-#include <asm/macints.h>
18
+#include <asm/macintosh.h>
19
+#include <asm/macints.h>
2520 #include <asm/mac_iop.h>
26
-#include <asm/mac_oss.h>
2721 #include <asm/adb_iop.h>
22
+#include <asm/unaligned.h>
2823
29
-#include <linux/adb.h>
30
-
31
-/*#define DEBUG_ADB_IOP*/
24
+#include <linux/adb.h>
3225
3326 static struct adb_request *current_req;
3427 static struct adb_request *last_req;
35
-#if 0
36
-static unsigned char reply_buff[16];
37
-static unsigned char *reply_ptr;
38
-#endif
28
+static unsigned int autopoll_devs;
29
+static u8 autopoll_addr;
3930
4031 static enum adb_iop_state {
41
- idle,
42
- sending,
43
- awaiting_reply
32
+ idle,
33
+ sending,
34
+ awaiting_reply
4435 } adb_iop_state;
4536
4637 static void adb_iop_start(void);
....@@ -52,6 +43,11 @@
5243 static void adb_iop_poll(void);
5344 static int adb_iop_reset_bus(void);
5445
46
+/* ADB command byte structure */
47
+#define ADDR_MASK 0xF0
48
+#define OP_MASK 0x0C
49
+#define TALK 0x0C
50
+
5551 struct adb_driver adb_iop_driver = {
5652 .name = "ISM IOP",
5753 .probe = adb_iop_probe,
....@@ -62,12 +58,19 @@
6258 .reset_bus = adb_iop_reset_bus
6359 };
6460
65
-static void adb_iop_end_req(struct adb_request *req, int state)
61
+static void adb_iop_done(void)
6662 {
63
+ struct adb_request *req = current_req;
64
+
65
+ adb_iop_state = idle;
66
+
6767 req->complete = 1;
6868 current_req = req->next;
69
- if (req->done) (*req->done)(req);
70
- adb_iop_state = state;
69
+ if (req->done)
70
+ (*req->done)(req);
71
+
72
+ if (adb_iop_state == idle)
73
+ adb_iop_start();
7174 }
7275
7376 /*
....@@ -78,15 +81,11 @@
7881
7982 static void adb_iop_complete(struct iop_msg *msg)
8083 {
81
- struct adb_request *req;
8284 unsigned long flags;
8385
8486 local_irq_save(flags);
8587
86
- req = current_req;
87
- if ((adb_iop_state == sending) && req && req->reply_expected) {
88
- adb_iop_state = awaiting_reply;
89
- }
88
+ adb_iop_state = awaiting_reply;
9089
9190 local_irq_restore(flags);
9291 }
....@@ -94,59 +93,57 @@
9493 /*
9594 * Listen for ADB messages from the IOP.
9695 *
97
- * This will be called when unsolicited messages (usually replies to TALK
98
- * commands or autopoll packets) are received.
96
+ * This will be called when unsolicited IOP messages are received.
97
+ * These IOP messages can carry ADB autopoll responses and also occur
98
+ * after explicit ADB commands.
9999 */
100100
101101 static void adb_iop_listen(struct iop_msg *msg)
102102 {
103
- struct adb_iopmsg *amsg = (struct adb_iopmsg *) msg->message;
104
- struct adb_request *req;
103
+ struct adb_iopmsg *amsg = (struct adb_iopmsg *)msg->message;
104
+ u8 addr = (amsg->cmd & ADDR_MASK) >> 4;
105
+ u8 op = amsg->cmd & OP_MASK;
105106 unsigned long flags;
106
-#ifdef DEBUG_ADB_IOP
107
- int i;
108
-#endif
107
+ bool req_done = false;
109108
110109 local_irq_save(flags);
111110
112
- req = current_req;
111
+ /* Responses to Talk commands may be unsolicited as they are
112
+ * produced when the IOP polls devices. They are mostly timeouts.
113
+ */
114
+ if (op == TALK && ((1 << addr) & autopoll_devs))
115
+ autopoll_addr = addr;
113116
114
-#ifdef DEBUG_ADB_IOP
115
- printk("adb_iop_listen %p: rcvd packet, %d bytes: %02X %02X", req,
116
- (uint) amsg->count + 2, (uint) amsg->flags, (uint) amsg->cmd);
117
- for (i = 0; i < amsg->count; i++)
118
- printk(" %02X", (uint) amsg->data[i]);
119
- printk("\n");
120
-#endif
117
+ switch (amsg->flags & (ADB_IOP_EXPLICIT |
118
+ ADB_IOP_AUTOPOLL |
119
+ ADB_IOP_TIMEOUT)) {
120
+ case ADB_IOP_EXPLICIT:
121
+ case ADB_IOP_EXPLICIT | ADB_IOP_TIMEOUT:
122
+ if (adb_iop_state == awaiting_reply) {
123
+ struct adb_request *req = current_req;
121124
122
- /* Handle a timeout. Timeout packets seem to occur even after */
123
- /* we've gotten a valid reply to a TALK, so I'm assuming that */
124
- /* a "timeout" is actually more like an "end-of-data" signal. */
125
- /* We need to send back a timeout packet to the IOP to shut */
126
- /* it up, plus complete the current request, if any. */
125
+ if (req->reply_expected) {
126
+ req->reply_len = amsg->count + 1;
127
+ memcpy(req->reply, &amsg->cmd, req->reply_len);
128
+ }
127129
128
- if (amsg->flags & ADB_IOP_TIMEOUT) {
129
- msg->reply[0] = ADB_IOP_TIMEOUT | ADB_IOP_AUTOPOLL;
130
- msg->reply[1] = 0;
131
- msg->reply[2] = 0;
132
- if (req && (adb_iop_state != idle)) {
133
- adb_iop_end_req(req, idle);
130
+ req_done = true;
134131 }
135
- } else {
136
- /* TODO: is it possible for more than one chunk of data */
137
- /* to arrive before the timeout? If so we need to */
138
- /* use reply_ptr here like the other drivers do. */
139
- if ((adb_iop_state == awaiting_reply) &&
140
- (amsg->flags & ADB_IOP_EXPLICIT)) {
141
- req->reply_len = amsg->count + 1;
142
- memcpy(req->reply, &amsg->cmd, req->reply_len);
143
- } else {
144
- adb_input(&amsg->cmd, amsg->count + 1,
145
- amsg->flags & ADB_IOP_AUTOPOLL);
146
- }
147
- memcpy(msg->reply, msg->message, IOP_MSG_LEN);
132
+ break;
133
+ case ADB_IOP_AUTOPOLL:
134
+ if (((1 << addr) & autopoll_devs) &&
135
+ amsg->cmd == ADB_READREG(addr, 0))
136
+ adb_input(&amsg->cmd, amsg->count + 1, 1);
137
+ break;
148138 }
139
+ msg->reply[0] = autopoll_addr ? ADB_IOP_AUTOPOLL : 0;
140
+ msg->reply[1] = 0;
141
+ msg->reply[2] = autopoll_addr ? ADB_READREG(autopoll_addr, 0) : 0;
149142 iop_complete_message(msg);
143
+
144
+ if (req_done)
145
+ adb_iop_done();
146
+
150147 local_irq_restore(flags);
151148 }
152149
....@@ -159,69 +156,60 @@
159156
160157 static void adb_iop_start(void)
161158 {
162
- unsigned long flags;
163159 struct adb_request *req;
164160 struct adb_iopmsg amsg;
165
-#ifdef DEBUG_ADB_IOP
166
- int i;
167
-#endif
168161
169162 /* get the packet to send */
170163 req = current_req;
171
- if (!req) return;
164
+ if (!req)
165
+ return;
172166
173
- local_irq_save(flags);
174
-
175
-#ifdef DEBUG_ADB_IOP
176
- printk("adb_iop_start %p: sending packet, %d bytes:", req, req->nbytes);
177
- for (i = 0 ; i < req->nbytes ; i++)
178
- printk(" %02X", (uint) req->data[i]);
179
- printk("\n");
180
-#endif
181
-
182
- /* The IOP takes MacII-style packets, so */
183
- /* strip the initial ADB_PACKET byte. */
184
-
167
+ /* The IOP takes MacII-style packets, so strip the initial
168
+ * ADB_PACKET byte.
169
+ */
185170 amsg.flags = ADB_IOP_EXPLICIT;
186171 amsg.count = req->nbytes - 2;
187172
188
- /* amsg.data immediately follows amsg.cmd, effectively making */
189
- /* amsg.cmd a pointer to the beginning of a full ADB packet. */
173
+ /* amsg.data immediately follows amsg.cmd, effectively making
174
+ * &amsg.cmd a pointer to the beginning of a full ADB packet.
175
+ */
190176 memcpy(&amsg.cmd, req->data + 1, req->nbytes - 1);
191177
192178 req->sent = 1;
193179 adb_iop_state = sending;
194
- local_irq_restore(flags);
195180
196
- /* Now send it. The IOP manager will call adb_iop_complete */
197
- /* when the packet has been sent. */
198
-
199
- iop_send_message(ADB_IOP, ADB_CHAN, req,
200
- sizeof(amsg), (__u8 *) &amsg, adb_iop_complete);
181
+ /* Now send it. The IOP manager will call adb_iop_complete
182
+ * when the message has been sent.
183
+ */
184
+ iop_send_message(ADB_IOP, ADB_CHAN, req, sizeof(amsg), (__u8 *)&amsg,
185
+ adb_iop_complete);
201186 }
202187
203
-int adb_iop_probe(void)
188
+static int adb_iop_probe(void)
204189 {
205
- if (!iop_ism_present) return -ENODEV;
190
+ if (!iop_ism_present)
191
+ return -ENODEV;
206192 return 0;
207193 }
208194
209
-int adb_iop_init(void)
195
+static int adb_iop_init(void)
210196 {
211
- printk("adb: IOP ISM driver v0.4 for Unified ADB.\n");
197
+ pr_info("adb: IOP ISM driver v0.4 for Unified ADB\n");
212198 iop_listen(ADB_IOP, ADB_CHAN, adb_iop_listen, "ADB");
213199 return 0;
214200 }
215201
216
-int adb_iop_send_request(struct adb_request *req, int sync)
202
+static int adb_iop_send_request(struct adb_request *req, int sync)
217203 {
218204 int err;
219205
220206 err = adb_iop_write(req);
221
- if (err) return err;
207
+ if (err)
208
+ return err;
222209
223210 if (sync) {
224
- while (!req->complete) adb_iop_poll();
211
+ while (!req->complete)
212
+ adb_iop_poll();
225213 }
226214 return 0;
227215 }
....@@ -235,14 +223,14 @@
235223 return -EINVAL;
236224 }
237225
238
- local_irq_save(flags);
239
-
240226 req->next = NULL;
241227 req->sent = 0;
242228 req->complete = 0;
243229 req->reply_len = 0;
244230
245
- if (current_req != 0) {
231
+ local_irq_save(flags);
232
+
233
+ if (current_req) {
246234 last_req->next = req;
247235 last_req = req;
248236 } else {
....@@ -250,36 +238,60 @@
250238 last_req = req;
251239 }
252240
241
+ if (adb_iop_state == idle)
242
+ adb_iop_start();
243
+
253244 local_irq_restore(flags);
254
- if (adb_iop_state == idle) adb_iop_start();
245
+
255246 return 0;
256247 }
257248
258
-int adb_iop_autopoll(int devs)
249
+static void adb_iop_set_ap_complete(struct iop_msg *msg)
259250 {
260
- /* TODO: how do we enable/disable autopoll? */
251
+ struct adb_iopmsg *amsg = (struct adb_iopmsg *)msg->message;
252
+
253
+ autopoll_devs = get_unaligned_be16(amsg->data);
254
+ if (autopoll_devs & (1 << autopoll_addr))
255
+ return;
256
+ autopoll_addr = autopoll_devs ? (ffs(autopoll_devs) - 1) : 0;
257
+}
258
+
259
+static int adb_iop_autopoll(int devs)
260
+{
261
+ struct adb_iopmsg amsg;
262
+ unsigned long flags;
263
+ unsigned int mask = (unsigned int)devs & 0xFFFE;
264
+
265
+ local_irq_save(flags);
266
+
267
+ amsg.flags = ADB_IOP_SET_AUTOPOLL | (mask ? ADB_IOP_AUTOPOLL : 0);
268
+ amsg.count = 2;
269
+ amsg.cmd = 0;
270
+ put_unaligned_be16(mask, amsg.data);
271
+
272
+ iop_send_message(ADB_IOP, ADB_CHAN, NULL, sizeof(amsg), (__u8 *)&amsg,
273
+ adb_iop_set_ap_complete);
274
+
275
+ local_irq_restore(flags);
276
+
261277 return 0;
262278 }
263279
264
-void adb_iop_poll(void)
280
+static void adb_iop_poll(void)
265281 {
266
- if (adb_iop_state == idle) adb_iop_start();
267282 iop_ism_irq_poll(ADB_IOP);
268283 }
269284
270
-int adb_iop_reset_bus(void)
285
+static int adb_iop_reset_bus(void)
271286 {
272
- struct adb_request req = {
273
- .reply_expected = 0,
274
- .nbytes = 2,
275
- .data = { ADB_PACKET, 0 },
276
- };
287
+ struct adb_request req;
277288
278
- adb_iop_write(&req);
279
- while (!req.complete) {
280
- adb_iop_poll();
281
- schedule();
282
- }
289
+ /* Command = 0, Address = ignored */
290
+ adb_request(&req, NULL, ADBREQ_NOSEND, 1, ADB_BUSRESET);
291
+ adb_iop_send_request(&req, 1);
292
+
293
+ /* Don't want any more requests during the Global Reset low time. */
294
+ mdelay(3);
283295
284296 return 0;
285297 }