| 1 | |
| 2 | |
| 3 | * Device driver for the Apple Desktop Bus
|
| 4 | * and the /dev/adb device on macintoshes.
|
| 5 | *
|
| 6 | * Copyright (C) 1996 Paul Mackerras.
|
| 7 | *
|
| 8 | * Modified to declare controllers as structures, added
|
| 9 | * client notification of bus reset and handles PowerBook
|
| 10 | * sleep, by Benjamin Herrenschmidt.
|
| 11 | *
|
| 12 | * To do:
|
| 13 | *
|
| 14 | * - /sys/bus/adb to list the devices and infos
|
| 15 | * - more /dev/adb to allow userland to receive the
|
| 16 | * flow of auto-polling datas from a given device.
|
| 17 | * - move bus probe to a kernel thread
|
| 18 |
|
| 19 |
|
| 20 | #include <linux/types.h>
|
| 21 | #include <linux/errno.h>
|
| 22 | #include <linux/kernel.h>
|
| 23 | #include <linux/slab.h>
|
| 24 | #include <linux/module.h>
|
| 25 | #include <linux/fs.h>
|
| 26 | #include <linux/mm.h>
|
| 27 | #include <linux/sched/signal.h>
|
| 28 | #include <linux/adb.h>
|
| 29 | #include <linux/cuda.h>
|
| 30 | #include <linux/pmu.h>
|
| 31 | #include <linux/notifier.h>
|
| 32 | #include <linux/wait.h>
|
| 33 | #include <linux/init.h>
|
| 34 | #include <linux/delay.h>
|
| 35 | #include <linux/spinlock.h>
|
| 36 | #include <linux/completion.h>
|
| 37 | #include <linux/device.h>
|
| 38 | #include <linux/kthread.h>
|
| 39 | #include <linux/platform_device.h>
|
| 40 | #include <linux/mutex.h>
|
| 41 | #include <linux/of.h>
|
| 42 |
|
| 43 | #include <linux/uaccess.h>
|
| 44 | #ifdef CONFIG_PPC
|
| 45 | #include <asm/machdep.h>
|
| 46 | #endif
|
| 47 |
|
| 48 |
|
| 49 | EXPORT_SYMBOL(adb_client_list);
|
| 50 |
|
| 51 | extern struct adb_driver via_macii_driver;
|
| 52 | extern struct adb_driver via_cuda_driver;
|
| 53 | extern struct adb_driver adb_iop_driver;
|
| 54 | extern struct adb_driver via_pmu_driver;
|
| 55 | extern struct adb_driver macio_adb_driver;
|
| 56 |
|
| 57 | static DEFINE_MUTEX(adb_mutex);
|
| 58 | static struct adb_driver *adb_driver_list[] = {
|
| 59 | #ifdef CONFIG_ADB_MACII
|
| 60 | &via_macii_driver,
|
| 61 | #endif
|
| 62 | #ifdef CONFIG_ADB_CUDA
|
| 63 | &via_cuda_driver,
|
| 64 | #endif
|
| 65 | #ifdef CONFIG_ADB_IOP
|
| 66 | &adb_iop_driver,
|
| 67 | #endif
|
| 68 | #ifdef CONFIG_ADB_PMU
|
| 69 | &via_pmu_driver,
|
| 70 | #endif
|
| 71 | #ifdef CONFIG_ADB_MACIO
|
| 72 | &macio_adb_driver,
|
| 73 | #endif
|
| 74 | NULL
|
| 75 | };
|
| 76 |
|
| 77 | static const struct class adb_dev_class = {
|
| 78 | .name = "adb",
|
| 79 | };
|
| 80 |
|
| 81 | static struct adb_driver *adb_controller;
|
| 82 | BLOCKING_NOTIFIER_HEAD(adb_client_list);
|
| 83 | static int adb_got_sleep;
|
| 84 | static int adb_inited;
|
| 85 | static DEFINE_SEMAPHORE(adb_probe_mutex, 1);
|
| 86 | static int sleepy_trackpad;
|
| 87 | static int autopoll_devs;
|
| 88 | int __adb_probe_sync;
|
| 89 |
|
| 90 | static int adb_scan_bus(void);
|
| 91 | static int do_adb_reset_bus(void);
|
| 92 | static void adbdev_init(void);
|
| 93 | static int try_handler_change(int, int);
|
| 94 |
|
| 95 | static struct adb_handler {
|
| 96 | void (*handler)(unsigned char *, int, int);
|
| 97 | int original_address;
|
| 98 | int handler_id;
|
| 99 | int busy;
|
| 100 | } adb_handler[16];
|
| 101 |
|
| 102 | |
| 103 | * The adb_handler_mutex mutex protects all accesses to the original_address
|
| 104 | * and handler_id fields of adb_handler[i] for all i, and changes to the
|
| 105 | * handler field.
|
| 106 | * Accesses to the handler field are protected by the adb_handler_lock
|
| 107 | * rwlock. It is held across all calls to any handler, so that by the
|
| 108 | * time adb_unregister returns, we know that the old handler isn't being
|
| 109 | * called.
|
| 110 |
|
| 111 | static DEFINE_MUTEX(adb_handler_mutex);
|
| 112 | static DEFINE_RWLOCK(adb_handler_lock);
|
| 113 |
|
| 114 | #if 0 |
| 115 | static void printADBreply(struct adb_request *req)
|
| 116 | {
|
| 117 | int i;
|
| 118 |
|
| 119 | printk("adb reply (%d)", req->reply_len);
|
| 120 | for(i = 0; i < req->reply_len; i++)
|
| 121 | printk(" %x", req->reply[i]);
|
| 122 | printk("\n");
|
| 123 |
|
| 124 | }
|
| 125 | #endif
|
| 126 |
|
| 127 | static int adb_scan_bus(void)
|
| 128 | {
|
| 129 | int i, highFree=0, noMovement;
|
| 130 | int devmask = 0;
|
| 131 | struct adb_request req;
|
| 132 |
|
| 133 |
|
| 134 | for (i = 1; i < 16; i++) {
|
| 135 |
|
| 136 | adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
|
| 137 | (i << 4) | 0xf);
|
| 138 | if (req.reply_len > 1)
|
| 139 |
|
| 140 | adb_handler[i].original_address = i;
|
| 141 | else if (i > highFree)
|
| 142 | highFree = i;
|
| 143 | }
|
| 144 |
|
| 145 |
|
| 146 | for (noMovement = 1; noMovement < 2 && highFree > 0; noMovement++) {
|
| 147 | for (i = 1; i < 16; i++) {
|
| 148 | if (adb_handler[i].original_address == 0)
|
| 149 | continue;
|
| 150 | |
| 151 | * Send a "talk register 3" command to address i
|
| 152 | * to provoke a collision if there is more than
|
| 153 | * one device at this address.
|
| 154 |
|
| 155 | adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
|
| 156 | (i << 4) | 0xf);
|
| 157 | |
| 158 | * Move the device(s) which didn't detect a
|
| 159 | * collision to address `highFree'. Hopefully
|
| 160 | * this only moves one device.
|
| 161 |
|
| 162 | adb_request(&req, NULL, ADBREQ_SYNC, 3,
|
| 163 | (i<< 4) | 0xb, (highFree | 0x60), 0xfe);
|
| 164 | |
| 165 | * See if anybody actually moved. This is suggested
|
| 166 | * by HW TechNote 01:
|
| 167 | *
|
| 168 | * https://developer.apple.com/technotes/hw/hw_01.html
|
| 169 |
|
| 170 | adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
|
| 171 | (highFree << 4) | 0xf);
|
| 172 | if (req.reply_len <= 1) continue;
|
| 173 | |
| 174 | * Test whether there are any device(s) left
|
| 175 | * at address i.
|
| 176 |
|
| 177 | adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
|
| 178 | (i << 4) | 0xf);
|
| 179 | if (req.reply_len > 1) {
|
| 180 | |
| 181 | * There are still one or more devices
|
| 182 | * left at address i. Register the one(s)
|
| 183 | * we moved to `highFree', and find a new
|
| 184 | * value for highFree.
|
| 185 |
|
| 186 | adb_handler[highFree].original_address =
|
| 187 | adb_handler[i].original_address;
|
| 188 | while (highFree > 0 &&
|
| 189 | adb_handler[highFree].original_address)
|
| 190 | highFree--;
|
| 191 | if (highFree <= 0)
|
| 192 | break;
|
| 193 |
|
| 194 | noMovement = 0;
|
| 195 | } else {
|
| 196 | |
| 197 | * No devices left at address i; move the
|
| 198 | * one(s) we moved to `highFree' back to i.
|
| 199 |
|
| 200 | adb_request(&req, NULL, ADBREQ_SYNC, 3,
|
| 201 | (highFree << 4) | 0xb,
|
| 202 | (i | 0x60), 0xfe);
|
| 203 | }
|
| 204 | }
|
| 205 | }
|
| 206 |
|
| 207 |
|
| 208 | for (i = 1; i < 16; i++) {
|
| 209 | if (adb_handler[i].original_address == 0)
|
| 210 | continue;
|
| 211 | adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
|
| 212 | (i << 4) | 0xf);
|
| 213 | adb_handler[i].handler_id = req.reply[2];
|
| 214 | printk(KERN_DEBUG "adb device [%d]: %d 0x%X\n", i,
|
| 215 | adb_handler[i].original_address,
|
| 216 | adb_handler[i].handler_id);
|
| 217 | devmask |= 1 << i;
|
| 218 | }
|
| 219 | return devmask;
|
| 220 | }
|
| 221 |
|
| 222 | |
| 223 | * This kernel task handles ADB probing. It dies once probing is
|
| 224 | * completed.
|
| 225 |
|
| 226 | static int
|
| 227 | adb_probe_task(void *x)
|
| 228 | {
|
| 229 | pr_debug("adb: starting probe task...\n");
|
| 230 | do_adb_reset_bus();
|
| 231 | pr_debug("adb: finished probe task...\n");
|
| 232 |
|
| 233 | up(&adb_probe_mutex);
|
| 234 |
|
| 235 | return 0;
|
| 236 | }
|
| 237 |
|
| 238 | static void
|
| 239 | __adb_probe_task(struct work_struct *bullshit)
|
| 240 | {
|
| 241 | kthread_run(adb_probe_task, NULL, "kadbprobe");
|
| 242 | }
|
| 243 |
|
| 244 | static DECLARE_WORK(adb_reset_work, __adb_probe_task);
|
| 245 |
|
| 246 | int
|
| 247 | adb_reset_bus(void)
|
| 248 | {
|
| 249 | if (__adb_probe_sync) {
|
| 250 | do_adb_reset_bus();
|
| 251 | return 0;
|
| 252 | }
|
| 253 |
|
| 254 | down(&adb_probe_mutex);
|
| 255 | schedule_work(&adb_reset_work);
|
| 256 | return 0;
|
| 257 | }
|
| 258 |
|
| 259 | #ifdef CONFIG_PM
|
| 260 | |
| 261 | * notify clients before sleep
|
| 262 |
|
| 263 | static int __adb_suspend(struct platform_device *dev, pm_message_t state)
|
| 264 | {
|
| 265 | adb_got_sleep = 1;
|
| 266 |
|
| 267 | down(&adb_probe_mutex);
|
| 268 |
|
| 269 | if (adb_controller->autopoll)
|
| 270 | adb_controller->autopoll(0);
|
| 271 | blocking_notifier_call_chain(&adb_client_list, ADB_MSG_POWERDOWN, NULL);
|
| 272 |
|
| 273 | return 0;
|
| 274 | }
|
| 275 |
|
| 276 | static int adb_suspend(struct device *dev)
|
| 277 | {
|
| 278 | return __adb_suspend(to_platform_device(dev), PMSG_SUSPEND);
|
| 279 | }
|
| 280 |
|
| 281 | static int adb_freeze(struct device *dev)
|
| 282 | {
|
| 283 | return __adb_suspend(to_platform_device(dev), PMSG_FREEZE);
|
| 284 | }
|
| 285 |
|
| 286 | static int adb_poweroff(struct device *dev)
|
| 287 | {
|
| 288 | return __adb_suspend(to_platform_device(dev), PMSG_HIBERNATE);
|
| 289 | }
|
| 290 |
|
| 291 | |
| 292 | * reset bus after sleep
|
| 293 |
|
| 294 | static int __adb_resume(struct platform_device *dev)
|
| 295 | {
|
| 296 | adb_got_sleep = 0;
|
| 297 | up(&adb_probe_mutex);
|
| 298 | adb_reset_bus();
|
| 299 |
|
| 300 | return 0;
|
| 301 | }
|
| 302 |
|
| 303 | static int adb_resume(struct device *dev)
|
| 304 | {
|
| 305 | return __adb_resume(to_platform_device(dev));
|
| 306 | }
|
| 307 | #endif
|
| 308 |
|
| 309 | static int __init adb_init(void)
|
| 310 | {
|
| 311 | struct adb_driver *driver;
|
| 312 | int i;
|
| 313 |
|
| 314 | #ifdef CONFIG_PPC32
|
| 315 | if (!machine_is(chrp) && !machine_is(powermac))
|
| 316 | return 0;
|
| 317 | #endif
|
| 318 | #ifdef CONFIG_MAC
|
| 319 | if (!MACH_IS_MAC)
|
| 320 | return 0;
|
| 321 | #endif
|
| 322 |
|
| 323 |
|
| 324 | if (adb_inited)
|
| 325 | return 0;
|
| 326 | adb_inited = 1;
|
| 327 |
|
| 328 | adb_controller = NULL;
|
| 329 |
|
| 330 | i = 0;
|
| 331 | while ((driver = adb_driver_list[i++]) != NULL) {
|
| 332 | if (!driver->probe()) {
|
| 333 | adb_controller = driver;
|
| 334 | break;
|
| 335 | }
|
| 336 | }
|
| 337 | if (adb_controller != NULL && adb_controller->init &&
|
| 338 | adb_controller->init())
|
| 339 | adb_controller = NULL;
|
| 340 | if (adb_controller == NULL) {
|
| 341 | pr_warn("Warning: no ADB interface detected\n");
|
| 342 | } else {
|
| 343 | #ifdef CONFIG_PPC
|
| 344 | if (of_machine_is_compatible("AAPL,PowerBook1998") ||
|
| 345 | of_machine_is_compatible("PowerBook1,1"))
|
| 346 | sleepy_trackpad = 1;
|
| 347 | #endif
|
| 348 |
|
| 349 | adbdev_init();
|
| 350 | adb_reset_bus();
|
| 351 | }
|
| 352 | return 0;
|
| 353 | }
|
| 354 |
|
| 355 | device_initcall(adb_init);
|
| 356 |
|
| 357 | static int
|
| 358 | do_adb_reset_bus(void)
|
| 359 | {
|
| 360 | int ret;
|
| 361 |
|
| 362 | if (adb_controller == NULL)
|
| 363 | return -ENXIO;
|
| 364 |
|
| 365 | if (adb_controller->autopoll)
|
| 366 | adb_controller->autopoll(0);
|
| 367 |
|
| 368 | blocking_notifier_call_chain(&adb_client_list,
|
| 369 | ADB_MSG_PRE_RESET, NULL);
|
| 370 |
|
| 371 | if (sleepy_trackpad) {
|
| 372 |
|
| 373 | msleep(500);
|
| 374 | }
|
| 375 |
|
| 376 | mutex_lock(&adb_handler_mutex);
|
| 377 | write_lock_irq(&adb_handler_lock);
|
| 378 | memset(adb_handler, 0, sizeof(adb_handler));
|
| 379 | write_unlock_irq(&adb_handler_lock);
|
| 380 |
|
| 381 |
|
| 382 | if (adb_controller->reset_bus)
|
| 383 | ret = adb_controller->reset_bus();
|
| 384 | else
|
| 385 | ret = 0;
|
| 386 |
|
| 387 | if (sleepy_trackpad) {
|
| 388 |
|
| 389 | msleep(1500);
|
| 390 | }
|
| 391 |
|
| 392 | if (!ret) {
|
| 393 | autopoll_devs = adb_scan_bus();
|
| 394 | if (adb_controller->autopoll)
|
| 395 | adb_controller->autopoll(autopoll_devs);
|
| 396 | }
|
| 397 | mutex_unlock(&adb_handler_mutex);
|
| 398 |
|
| 399 | blocking_notifier_call_chain(&adb_client_list,
|
| 400 | ADB_MSG_POST_RESET, NULL);
|
| 401 |
|
| 402 | return ret;
|
| 403 | }
|
| 404 |
|
| 405 | void
|
| 406 | adb_poll(void)
|
| 407 | {
|
| 408 | if ((adb_controller == NULL)||(adb_controller->poll == NULL))
|
| 409 | return;
|
| 410 | adb_controller->poll();
|
| 411 | }
|
| 412 | EXPORT_SYMBOL(adb_poll);
|
| 413 |
|
| 414 | static void adb_sync_req_done(struct adb_request *req)
|
| 415 | {
|
| 416 | struct completion *comp = req->arg;
|
| 417 |
|
| 418 | complete(comp);
|
| 419 | }
|
| 420 |
|
| 421 | int
|
| 422 | adb_request(struct adb_request *req, void (*done)(struct adb_request *),
|
| 423 | int flags, int nbytes, ...)
|
| 424 | {
|
| 425 | va_list list;
|
| 426 | int i;
|
| 427 | int rc;
|
| 428 | struct completion comp;
|
| 429 |
|
| 430 | if ((adb_controller == NULL) || (adb_controller->send_request == NULL))
|
| 431 | return -ENXIO;
|
| 432 | if (nbytes < 1)
|
| 433 | return -EINVAL;
|
| 434 |
|
| 435 | req->nbytes = nbytes+1;
|
| 436 | req->done = done;
|
| 437 | req->reply_expected = flags & ADBREQ_REPLY;
|
| 438 | req->data[0] = ADB_PACKET;
|
| 439 | va_start(list, nbytes);
|
| 440 | for (i = 0; i < nbytes; ++i)
|
| 441 | req->data[i+1] = va_arg(list, int);
|
| 442 | va_end(list);
|
| 443 |
|
| 444 | if (flags & ADBREQ_NOSEND)
|
| 445 | return 0;
|
| 446 |
|
| 447 |
|
| 448 | if (flags & ADBREQ_SYNC) {
|
| 449 | WARN_ON(done);
|
| 450 | req->done = adb_sync_req_done;
|
| 451 | req->arg = ∁
|
| 452 | init_completion(&comp);
|
| 453 | }
|
| 454 |
|
| 455 | rc = adb_controller->send_request(req, 0);
|
| 456 |
|
| 457 | if ((flags & ADBREQ_SYNC) && !rc && !req->complete)
|
| 458 | wait_for_completion(&comp);
|
| 459 |
|
| 460 | return rc;
|
| 461 | }
|
| 462 | EXPORT_SYMBOL(adb_request);
|
| 463 |
|
| 464 | |
| 465 | the given default id.
|
| 466 | And it does it now ! Note: changed behaviour: This function
|
| 467 | will now register if default_id _and_ handler_id both match
|
| 468 | but handler_id can be left to 0 to match with default_id only.
|
| 469 | When handler_id is set, this function will try to adjust
|
| 470 | the handler_id id it doesn't match.
|
| 471 | int
|
| 472 | adb_register(int default_id, int handler_id, struct adb_ids *ids,
|
| 473 | void (*handler)(unsigned char *, int, int))
|
| 474 | {
|
| 475 | int i;
|
| 476 |
|
| 477 | mutex_lock(&adb_handler_mutex);
|
| 478 | ids->nids = 0;
|
| 479 | for (i = 1; i < 16; i++) {
|
| 480 | if ((adb_handler[i].original_address == default_id) &&
|
| 481 | (!handler_id || (handler_id == adb_handler[i].handler_id) ||
|
| 482 | try_handler_change(i, handler_id))) {
|
| 483 | if (adb_handler[i].handler) {
|
| 484 | pr_err("Two handlers for ADB device %d\n",
|
| 485 | default_id);
|
| 486 | continue;
|
| 487 | }
|
| 488 | write_lock_irq(&adb_handler_lock);
|
| 489 | adb_handler[i].handler = handler;
|
| 490 | write_unlock_irq(&adb_handler_lock);
|
| 491 | ids->id[ids->nids++] = i;
|
| 492 | }
|
| 493 | }
|
| 494 | mutex_unlock(&adb_handler_mutex);
|
| 495 | return ids->nids;
|
| 496 | }
|
| 497 | EXPORT_SYMBOL(adb_register);
|
| 498 |
|
| 499 | int
|
| 500 | adb_unregister(int index)
|
| 501 | {
|
| 502 | int ret = -ENODEV;
|
| 503 |
|
| 504 | mutex_lock(&adb_handler_mutex);
|
| 505 | write_lock_irq(&adb_handler_lock);
|
| 506 | if (adb_handler[index].handler) {
|
| 507 | while(adb_handler[index].busy) {
|
| 508 | write_unlock_irq(&adb_handler_lock);
|
| 509 | yield();
|
| 510 | write_lock_irq(&adb_handler_lock);
|
| 511 | }
|
| 512 | ret = 0;
|
| 513 | adb_handler[index].handler = NULL;
|
| 514 | }
|
| 515 | write_unlock_irq(&adb_handler_lock);
|
| 516 | mutex_unlock(&adb_handler_mutex);
|
| 517 | return ret;
|
| 518 | }
|
| 519 | EXPORT_SYMBOL(adb_unregister);
|
| 520 |
|
| 521 | void
|
| 522 | adb_input(unsigned char *buf, int nb, int autopoll)
|
| 523 | {
|
| 524 | int i, id;
|
| 525 | static int dump_adb_input;
|
| 526 | unsigned long flags;
|
| 527 |
|
| 528 | void (*handler)(unsigned char *, int, int);
|
| 529 |
|
| 530 | |
| 531 | * has been started. We stop autopoll, but this is another security
|
| 532 |
|
| 533 | if (adb_got_sleep)
|
| 534 | return;
|
| 535 |
|
| 536 | id = buf[0] >> 4;
|
| 537 | if (dump_adb_input) {
|
| 538 | pr_info("adb packet: ");
|
| 539 | for (i = 0; i < nb; ++i)
|
| 540 | pr_cont(" %x", buf[i]);
|
| 541 | pr_cont(", id = %d\n", id);
|
| 542 | }
|
| 543 | write_lock_irqsave(&adb_handler_lock, flags);
|
| 544 | handler = adb_handler[id].handler;
|
| 545 | if (handler != NULL)
|
| 546 | adb_handler[id].busy = 1;
|
| 547 | write_unlock_irqrestore(&adb_handler_lock, flags);
|
| 548 | if (handler != NULL) {
|
| 549 | (*handler)(buf, nb, autopoll);
|
| 550 | wmb();
|
| 551 | adb_handler[id].busy = 0;
|
| 552 | }
|
| 553 |
|
| 554 | }
|
| 555 |
|
| 556 |
|
| 557 | static int try_handler_change(int address, int new_id)
|
| 558 | {
|
| 559 | struct adb_request req;
|
| 560 |
|
| 561 | if (adb_handler[address].handler_id == new_id)
|
| 562 | return 1;
|
| 563 | adb_request(&req, NULL, ADBREQ_SYNC, 3,
|
| 564 | ADB_WRITEREG(address, 3), address | 0x20, new_id);
|
| 565 | adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
|
| 566 | ADB_READREG(address, 3));
|
| 567 | if (req.reply_len < 2)
|
| 568 | return 0;
|
| 569 | if (req.reply[2] != new_id)
|
| 570 | return 0;
|
| 571 | adb_handler[address].handler_id = req.reply[2];
|
| 572 |
|
| 573 | return 1;
|
| 574 | }
|
| 575 |
|
| 576 | int
|
| 577 | adb_try_handler_change(int address, int new_id)
|
| 578 | {
|
| 579 | int ret;
|
| 580 |
|
| 581 | mutex_lock(&adb_handler_mutex);
|
| 582 | ret = try_handler_change(address, new_id);
|
| 583 | mutex_unlock(&adb_handler_mutex);
|
| 584 | if (ret)
|
| 585 | pr_debug("adb handler change: [%d] 0x%X\n", address, new_id);
|
| 586 | return ret;
|
| 587 | }
|
| 588 | EXPORT_SYMBOL(adb_try_handler_change);
|
| 589 |
|
| 590 | int
|
| 591 | adb_get_infos(int address, int *original_address, int *handler_id)
|
| 592 | {
|
| 593 | mutex_lock(&adb_handler_mutex);
|
| 594 | *original_address = adb_handler[address].original_address;
|
| 595 | *handler_id = adb_handler[address].handler_id;
|
| 596 | mutex_unlock(&adb_handler_mutex);
|
| 597 |
|
| 598 | return (*original_address != 0);
|
| 599 | }
|
| 600 |
|
| 601 |
|
| 602 | |
| 603 | * /dev/adb device driver.
|
| 604 |
|
| 605 |
|
| 606 | #define ADB_MAJOR 56
|
| 607 |
|
| 608 | struct adbdev_state {
|
| 609 | spinlock_t lock;
|
| 610 | atomic_t n_pending;
|
| 611 | struct adb_request *completed;
|
| 612 | wait_queue_head_t wait_queue;
|
| 613 | int inuse;
|
| 614 | };
|
| 615 |
|
| 616 | static void adb_write_done(struct adb_request *req)
|
| 617 | {
|
| 618 | struct adbdev_state *state = (struct adbdev_state *) req->arg;
|
| 619 | unsigned long flags;
|
| 620 |
|
| 621 | if (!req->complete) {
|
| 622 | req->reply_len = 0;
|
| 623 | req->complete = 1;
|
| 624 | }
|
| 625 | spin_lock_irqsave(&state->lock, flags);
|
| 626 | atomic_dec(&state->n_pending);
|
| 627 | if (!state->inuse) {
|
| 628 | kfree(req);
|
| 629 | if (atomic_read(&state->n_pending) == 0) {
|
| 630 | spin_unlock_irqrestore(&state->lock, flags);
|
| 631 | kfree(state);
|
| 632 | return;
|
| 633 | }
|
| 634 | } else {
|
| 635 | struct adb_request **ap = &state->completed;
|
| 636 | while (*ap != NULL)
|
| 637 | ap = &(*ap)->next;
|
| 638 | req->next = NULL;
|
| 639 | *ap = req;
|
| 640 | wake_up_interruptible(&state->wait_queue);
|
| 641 | }
|
| 642 | spin_unlock_irqrestore(&state->lock, flags);
|
| 643 | }
|
| 644 |
|
| 645 | static int
|
| 646 | do_adb_query(struct adb_request *req)
|
| 647 | {
|
| 648 | int ret = -EINVAL;
|
| 649 |
|
| 650 | switch(req->data[1]) {
|
| 651 | case ADB_QUERY_GETDEVINFO:
|
| 652 | if (req->nbytes < 3 || req->data[2] >= 16)
|
| 653 | break;
|
| 654 | mutex_lock(&adb_handler_mutex);
|
| 655 | req->reply[0] = adb_handler[req->data[2]].original_address;
|
| 656 | req->reply[1] = adb_handler[req->data[2]].handler_id;
|
| 657 | mutex_unlock(&adb_handler_mutex);
|
| 658 | req->complete = 1;
|
| 659 | req->reply_len = 2;
|
| 660 | adb_write_done(req);
|
| 661 | ret = 0;
|
| 662 | break;
|
| 663 | }
|
| 664 | return ret;
|
| 665 | }
|
| 666 |
|
| 667 | static int adb_open(struct inode *inode, struct file *file)
|
| 668 | {
|
| 669 | struct adbdev_state *state;
|
| 670 | int ret = 0;
|
| 671 |
|
| 672 | mutex_lock(&adb_mutex);
|
| 673 | if (iminor(inode) > 0 || adb_controller == NULL) {
|
| 674 | ret = -ENXIO;
|
| 675 | goto out;
|
| 676 | }
|
| 677 | state = kmalloc_obj(struct adbdev_state);
|
| 678 | if (!state) {
|
| 679 | ret = -ENOMEM;
|
| 680 | goto out;
|
| 681 | }
|
| 682 | file->private_data = state;
|
| 683 | spin_lock_init(&state->lock);
|
| 684 | atomic_set(&state->n_pending, 0);
|
| 685 | state->completed = NULL;
|
| 686 | init_waitqueue_head(&state->wait_queue);
|
| 687 | state->inuse = 1;
|
| 688 |
|
| 689 | out:
|
| 690 | mutex_unlock(&adb_mutex);
|
| 691 | return ret;
|
| 692 | }
|
| 693 |
|
| 694 | static int adb_release(struct inode *inode, struct file *file)
|
| 695 | {
|
| 696 | struct adbdev_state *state = file->private_data;
|
| 697 | unsigned long flags;
|
| 698 |
|
| 699 | mutex_lock(&adb_mutex);
|
| 700 | if (state) {
|
| 701 | file->private_data = NULL;
|
| 702 | spin_lock_irqsave(&state->lock, flags);
|
| 703 | if (atomic_read(&state->n_pending) == 0
|
| 704 | && state->completed == NULL) {
|
| 705 | spin_unlock_irqrestore(&state->lock, flags);
|
| 706 | kfree(state);
|
| 707 | } else {
|
| 708 | state->inuse = 0;
|
| 709 | spin_unlock_irqrestore(&state->lock, flags);
|
| 710 | }
|
| 711 | }
|
| 712 | mutex_unlock(&adb_mutex);
|
| 713 | return 0;
|
| 714 | }
|
| 715 |
|
| 716 | static ssize_t adb_read(struct file *file, char __user *buf,
|
| 717 | size_t count, loff_t *ppos)
|
| 718 | {
|
| 719 | int ret = 0;
|
| 720 | struct adbdev_state *state = file->private_data;
|
| 721 | struct adb_request *req;
|
| 722 | DECLARE_WAITQUEUE(wait, current);
|
| 723 | unsigned long flags;
|
| 724 |
|
| 725 | if (count < 2)
|
| 726 | return -EINVAL;
|
| 727 | if (count > sizeof(req->reply))
|
| 728 | count = sizeof(req->reply);
|
| 729 |
|
| 730 | req = NULL;
|
| 731 | spin_lock_irqsave(&state->lock, flags);
|
| 732 | add_wait_queue(&state->wait_queue, &wait);
|
| 733 | set_current_state(TASK_INTERRUPTIBLE);
|
| 734 |
|
| 735 | for (;;) {
|
| 736 | req = state->completed;
|
| 737 | if (req != NULL)
|
| 738 | state->completed = req->next;
|
| 739 | else if (atomic_read(&state->n_pending) == 0)
|
| 740 | ret = -EIO;
|
| 741 | if (req != NULL || ret != 0)
|
| 742 | break;
|
| 743 |
|
| 744 | if (file->f_flags & O_NONBLOCK) {
|
| 745 | ret = -EAGAIN;
|
| 746 | break;
|
| 747 | }
|
| 748 | if (signal_pending(current)) {
|
| 749 | ret = -ERESTARTSYS;
|
| 750 | break;
|
| 751 | }
|
| 752 | spin_unlock_irqrestore(&state->lock, flags);
|
| 753 | schedule();
|
| 754 | spin_lock_irqsave(&state->lock, flags);
|
| 755 | }
|
| 756 |
|
| 757 | set_current_state(TASK_RUNNING);
|
| 758 | remove_wait_queue(&state->wait_queue, &wait);
|
| 759 | spin_unlock_irqrestore(&state->lock, flags);
|
| 760 |
|
| 761 | if (ret)
|
| 762 | return ret;
|
| 763 |
|
| 764 | ret = req->reply_len;
|
| 765 | if (ret > count)
|
| 766 | ret = count;
|
| 767 | if (ret > 0 && copy_to_user(buf, req->reply, ret))
|
| 768 | ret = -EFAULT;
|
| 769 |
|
| 770 | kfree(req);
|
| 771 | return ret;
|
| 772 | }
|
| 773 |
|
| 774 | static ssize_t adb_write(struct file *file, const char __user *buf,
|
| 775 | size_t count, loff_t *ppos)
|
| 776 | {
|
| 777 | int ret;
|
| 778 | struct adbdev_state *state = file->private_data;
|
| 779 | struct adb_request *req;
|
| 780 |
|
| 781 | if (count < 2 || count > sizeof(req->data))
|
| 782 | return -EINVAL;
|
| 783 | if (adb_controller == NULL)
|
| 784 | return -ENXIO;
|
| 785 |
|
| 786 | req = kmalloc_obj(struct adb_request);
|
| 787 | if (req == NULL)
|
| 788 | return -ENOMEM;
|
| 789 |
|
| 790 | req->nbytes = count;
|
| 791 | req->done = adb_write_done;
|
| 792 | req->arg = (void *) state;
|
| 793 | req->complete = 0;
|
| 794 |
|
| 795 | ret = -EFAULT;
|
| 796 | if (copy_from_user(req->data, buf, count))
|
| 797 | goto out;
|
| 798 |
|
| 799 | atomic_inc(&state->n_pending);
|
| 800 |
|
| 801 |
|
| 802 | down(&adb_probe_mutex);
|
| 803 |
|
| 804 |
|
| 805 | if (req->data[0] == ADB_QUERY) {
|
| 806 | if (count > 1)
|
| 807 | ret = do_adb_query(req);
|
| 808 | else
|
| 809 | ret = -EINVAL;
|
| 810 | up(&adb_probe_mutex);
|
| 811 | }
|
| 812 | |
| 813 | the controller
|
| 814 | else if ((req->data[0] == ADB_PACKET) && (count > 1)
|
| 815 | && (req->data[1] == ADB_BUSRESET)) {
|
| 816 | ret = do_adb_reset_bus();
|
| 817 | up(&adb_probe_mutex);
|
| 818 | atomic_dec(&state->n_pending);
|
| 819 | if (ret == 0)
|
| 820 | ret = count;
|
| 821 | goto out;
|
| 822 | } else {
|
| 823 | req->reply_expected = ((req->data[1] & 0xc) == 0xc);
|
| 824 | if (adb_controller && adb_controller->send_request)
|
| 825 | ret = adb_controller->send_request(req, 0);
|
| 826 | else
|
| 827 | ret = -ENXIO;
|
| 828 | up(&adb_probe_mutex);
|
| 829 | }
|
| 830 |
|
| 831 | if (ret != 0) {
|
| 832 | atomic_dec(&state->n_pending);
|
| 833 | goto out;
|
| 834 | }
|
| 835 | return count;
|
| 836 |
|
| 837 | out:
|
| 838 | kfree(req);
|
| 839 | return ret;
|
| 840 | }
|
| 841 |
|
| 842 | static const struct file_operations adb_fops = {
|
| 843 | .owner = THIS_MODULE,
|
| 844 | .read = adb_read,
|
| 845 | .write = adb_write,
|
| 846 | .open = adb_open,
|
| 847 | .release = adb_release,
|
| 848 | };
|
| 849 |
|
| 850 | #ifdef CONFIG_PM
|
| 851 | static const struct dev_pm_ops adb_dev_pm_ops = {
|
| 852 | .suspend = adb_suspend,
|
| 853 | .resume = adb_resume,
|
| 854 |
|
| 855 | .freeze = adb_freeze,
|
| 856 | .thaw = adb_resume,
|
| 857 | .poweroff = adb_poweroff,
|
| 858 | .restore = adb_resume,
|
| 859 | };
|
| 860 | #endif
|
| 861 |
|
| 862 | static struct platform_driver adb_pfdrv = {
|
| 863 | .driver = {
|
| 864 | .name = "adb",
|
| 865 | #ifdef CONFIG_PM
|
| 866 | .pm = &adb_dev_pm_ops,
|
| 867 | #endif
|
| 868 | },
|
| 869 | };
|
| 870 |
|
| 871 | static struct platform_device adb_pfdev = {
|
| 872 | .name = "adb",
|
| 873 | };
|
| 874 |
|
| 875 | static int __init
|
| 876 | adb_dummy_probe(struct platform_device *dev)
|
| 877 | {
|
| 878 | if (dev == &adb_pfdev)
|
| 879 | return 0;
|
| 880 | return -ENODEV;
|
| 881 | }
|
| 882 |
|
| 883 | static void __init
|
| 884 | adbdev_init(void)
|
| 885 | {
|
| 886 | if (register_chrdev(ADB_MAJOR, "adb", &adb_fops)) {
|
| 887 | pr_err("adb: unable to get major %d\n", ADB_MAJOR);
|
| 888 | return;
|
| 889 | }
|
| 890 |
|
| 891 | if (class_register(&adb_dev_class))
|
| 892 | return;
|
| 893 |
|
| 894 | device_create(&adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL, "adb");
|
| 895 |
|
| 896 | platform_device_register(&adb_pfdev);
|
| 897 | platform_driver_probe(&adb_pfdrv, adb_dummy_probe);
|
| 898 | }
|