1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * I/O Processor (IOP) ADB Driver 4 * Written and (C) 1999 by Joshua M. Thompson (funaho@jurai.org) 5 * Based on via-cuda.c by Paul Mackerras. 6 * 7 * 1999-07-01 (jmt) - First implementation for new driver architecture. 8 * 9 * 1999-07-31 (jmt) - First working version. 10 * 11 * TODO: 12 * 13 * o Implement SRQ handling. 14 */ 15 16 #include <linux/types.h> 17 #include <linux/kernel.h> 18 #include <linux/mm.h> 19 #include <linux/delay.h> 20 #include <linux/init.h> 21 #include <linux/proc_fs.h> 22 23 #include <asm/macintosh.h> 24 #include <asm/macints.h> 25 #include <asm/mac_iop.h> 26 #include <asm/mac_oss.h> 27 #include <asm/adb_iop.h> 28 29 #include <linux/adb.h> 30 31 /*#define DEBUG_ADB_IOP*/ 32 33 static struct adb_request *current_req; 34 static struct adb_request *last_req; 35 #if 0 36 static unsigned char reply_buff[16]; 37 static unsigned char *reply_ptr; 38 #endif 39 40 static enum adb_iop_state { 41 idle, 42 sending, 43 awaiting_reply 44 } adb_iop_state; 45 46 static void adb_iop_start(void); 47 static int adb_iop_probe(void); 48 static int adb_iop_init(void); 49 static int adb_iop_send_request(struct adb_request *, int); 50 static int adb_iop_write(struct adb_request *); 51 static int adb_iop_autopoll(int); 52 static void adb_iop_poll(void); 53 static int adb_iop_reset_bus(void); 54 55 struct adb_driver adb_iop_driver = { 56 .name = "ISM IOP", 57 .probe = adb_iop_probe, 58 .init = adb_iop_init, 59 .send_request = adb_iop_send_request, 60 .autopoll = adb_iop_autopoll, 61 .poll = adb_iop_poll, 62 .reset_bus = adb_iop_reset_bus 63 }; 64 65 static void adb_iop_end_req(struct adb_request *req, int state) 66 { 67 req->complete = 1; 68 current_req = req->next; 69 if (req->done) 70 (*req->done)(req); 71 adb_iop_state = state; 72 } 73 74 /* 75 * Completion routine for ADB commands sent to the IOP. 76 * 77 * This will be called when a packet has been successfully sent. 78 */ 79 80 static void adb_iop_complete(struct iop_msg *msg) 81 { 82 struct adb_request *req; 83 unsigned long flags; 84 85 local_irq_save(flags); 86 87 req = current_req; 88 if ((adb_iop_state == sending) && req && req->reply_expected) { 89 adb_iop_state = awaiting_reply; 90 } 91 92 local_irq_restore(flags); 93 } 94 95 /* 96 * Listen for ADB messages from the IOP. 97 * 98 * This will be called when unsolicited messages (usually replies to TALK 99 * commands or autopoll packets) are received. 100 */ 101 102 static void adb_iop_listen(struct iop_msg *msg) 103 { 104 struct adb_iopmsg *amsg = (struct adb_iopmsg *)msg->message; 105 struct adb_request *req; 106 unsigned long flags; 107 #ifdef DEBUG_ADB_IOP 108 int i; 109 #endif 110 111 local_irq_save(flags); 112 113 req = current_req; 114 115 #ifdef DEBUG_ADB_IOP 116 printk("adb_iop_listen %p: rcvd packet, %d bytes: %02X %02X", req, 117 (uint)amsg->count + 2, (uint)amsg->flags, (uint)amsg->cmd); 118 for (i = 0; i < amsg->count; i++) 119 printk(" %02X", (uint)amsg->data[i]); 120 printk("\n"); 121 #endif 122 123 /* Handle a timeout. Timeout packets seem to occur even after */ 124 /* we've gotten a valid reply to a TALK, so I'm assuming that */ 125 /* a "timeout" is actually more like an "end-of-data" signal. */ 126 /* We need to send back a timeout packet to the IOP to shut */ 127 /* it up, plus complete the current request, if any. */ 128 129 if (amsg->flags & ADB_IOP_TIMEOUT) { 130 msg->reply[0] = ADB_IOP_TIMEOUT | ADB_IOP_AUTOPOLL; 131 msg->reply[1] = 0; 132 msg->reply[2] = 0; 133 if (req && (adb_iop_state != idle)) { 134 adb_iop_end_req(req, idle); 135 } 136 } else { 137 /* TODO: is it possible for more than one chunk of data */ 138 /* to arrive before the timeout? If so we need to */ 139 /* use reply_ptr here like the other drivers do. */ 140 if ((adb_iop_state == awaiting_reply) && 141 (amsg->flags & ADB_IOP_EXPLICIT)) { 142 req->reply_len = amsg->count + 1; 143 memcpy(req->reply, &amsg->cmd, req->reply_len); 144 } else { 145 adb_input(&amsg->cmd, amsg->count + 1, 146 amsg->flags & ADB_IOP_AUTOPOLL); 147 } 148 memcpy(msg->reply, msg->message, IOP_MSG_LEN); 149 } 150 iop_complete_message(msg); 151 local_irq_restore(flags); 152 } 153 154 /* 155 * Start sending an ADB packet, IOP style 156 * 157 * There isn't much to do other than hand the packet over to the IOP 158 * after encapsulating it in an adb_iopmsg. 159 */ 160 161 static void adb_iop_start(void) 162 { 163 unsigned long flags; 164 struct adb_request *req; 165 struct adb_iopmsg amsg; 166 #ifdef DEBUG_ADB_IOP 167 int i; 168 #endif 169 170 /* get the packet to send */ 171 req = current_req; 172 if (!req) 173 return; 174 175 local_irq_save(flags); 176 177 #ifdef DEBUG_ADB_IOP 178 printk("adb_iop_start %p: sending packet, %d bytes:", req, req->nbytes); 179 for (i = 0; i < req->nbytes; i++) 180 printk(" %02X", (uint)req->data[i]); 181 printk("\n"); 182 #endif 183 184 /* The IOP takes MacII-style packets, so */ 185 /* strip the initial ADB_PACKET byte. */ 186 187 amsg.flags = ADB_IOP_EXPLICIT; 188 amsg.count = req->nbytes - 2; 189 190 /* amsg.data immediately follows amsg.cmd, effectively making */ 191 /* amsg.cmd a pointer to the beginning of a full ADB packet. */ 192 memcpy(&amsg.cmd, req->data + 1, req->nbytes - 1); 193 194 req->sent = 1; 195 adb_iop_state = sending; 196 local_irq_restore(flags); 197 198 /* Now send it. The IOP manager will call adb_iop_complete */ 199 /* when the packet has been sent. */ 200 201 iop_send_message(ADB_IOP, ADB_CHAN, req, sizeof(amsg), (__u8 *)&amsg, 202 adb_iop_complete); 203 } 204 205 int adb_iop_probe(void) 206 { 207 if (!iop_ism_present) 208 return -ENODEV; 209 return 0; 210 } 211 212 int adb_iop_init(void) 213 { 214 pr_info("adb: IOP ISM driver v0.4 for Unified ADB\n"); 215 iop_listen(ADB_IOP, ADB_CHAN, adb_iop_listen, "ADB"); 216 return 0; 217 } 218 219 int adb_iop_send_request(struct adb_request *req, int sync) 220 { 221 int err; 222 223 err = adb_iop_write(req); 224 if (err) 225 return err; 226 227 if (sync) { 228 while (!req->complete) 229 adb_iop_poll(); 230 } 231 return 0; 232 } 233 234 static int adb_iop_write(struct adb_request *req) 235 { 236 unsigned long flags; 237 238 if ((req->nbytes < 2) || (req->data[0] != ADB_PACKET)) { 239 req->complete = 1; 240 return -EINVAL; 241 } 242 243 local_irq_save(flags); 244 245 req->next = NULL; 246 req->sent = 0; 247 req->complete = 0; 248 req->reply_len = 0; 249 250 if (current_req != 0) { 251 last_req->next = req; 252 last_req = req; 253 } else { 254 current_req = req; 255 last_req = req; 256 } 257 258 local_irq_restore(flags); 259 260 if (adb_iop_state == idle) 261 adb_iop_start(); 262 return 0; 263 } 264 265 int adb_iop_autopoll(int devs) 266 { 267 /* TODO: how do we enable/disable autopoll? */ 268 return 0; 269 } 270 271 void adb_iop_poll(void) 272 { 273 if (adb_iop_state == idle) 274 adb_iop_start(); 275 iop_ism_irq_poll(ADB_IOP); 276 } 277 278 int adb_iop_reset_bus(void) 279 { 280 struct adb_request req = { 281 .reply_expected = 0, 282 .nbytes = 2, 283 .data = { ADB_PACKET, 0 }, 284 }; 285 286 adb_iop_write(&req); 287 while (!req.complete) { 288 adb_iop_poll(); 289 schedule(); 290 } 291 292 return 0; 293 } 294