~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/macintosh/adb.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Device driver for the Apple Desktop Bus
  3  * and the /dev/adb device on macintoshes.
  4  *
  5  * Copyright (C) 1996 Paul Mackerras.
  6  *
  7  * Modified to declare controllers as structures, added
  8  * client notification of bus reset and handles PowerBook
  9  * sleep, by Benjamin Herrenschmidt.
 10  *
 11  * To do:
 12  *
 13  * - /proc/adb to list the devices and infos
 14  * - more /dev/adb to allow userland to receive the
 15  *   flow of auto-polling datas from a given device.
 16  */
 17 
 18 #include <linux/config.h>
 19 #include <linux/types.h>
 20 #include <linux/errno.h>
 21 #include <linux/kernel.h>
 22 #include <linux/malloc.h>
 23 #include <linux/module.h>
 24 #include <linux/fs.h>
 25 #include <linux/devfs_fs_kernel.h>
 26 #include <linux/mm.h>
 27 #include <linux/sched.h>
 28 #include <linux/smp_lock.h>
 29 #include <linux/adb.h>
 30 #include <linux/cuda.h>
 31 #include <linux/pmu.h>
 32 #include <linux/notifier.h>
 33 #include <linux/wait.h>
 34 #include <linux/init.h>
 35 #include <asm/uaccess.h>
 36 #ifdef CONFIG_PPC
 37 #include <asm/prom.h>
 38 #include <asm/hydra.h>
 39 #endif
 40 
 41 EXPORT_SYMBOL(adb_controller);
 42 EXPORT_SYMBOL(adb_client_list);
 43 
 44 extern struct adb_driver via_macii_driver;
 45 extern struct adb_driver via_maciisi_driver;
 46 extern struct adb_driver via_cuda_driver;
 47 extern struct adb_driver adb_iop_driver;
 48 extern struct adb_driver via_pmu_driver;
 49 extern struct adb_driver macio_adb_driver;
 50 
 51 static struct adb_driver *adb_driver_list[] = {
 52 #ifdef CONFIG_ADB_MACII
 53         &via_macii_driver,
 54 #endif
 55 #ifdef CONFIG_ADB_MACIISI
 56         &via_maciisi_driver,
 57 #endif
 58 #ifdef CONFIG_ADB_CUDA
 59         &via_cuda_driver,
 60 #endif
 61 #ifdef CONFIG_ADB_IOP
 62         &adb_iop_driver,
 63 #endif
 64 #ifdef CONFIG_ADB_PMU
 65         &via_pmu_driver,
 66 #endif
 67 #ifdef CONFIG_ADB_MACIO
 68         &macio_adb_driver,
 69 #endif
 70         NULL
 71 };
 72 
 73 struct adb_driver *adb_controller;
 74 struct notifier_block *adb_client_list = NULL;
 75 static int adb_got_sleep = 0;
 76 static int adb_inited = 0;
 77 
 78 #ifdef CONFIG_PMAC_PBOOK
 79 static int adb_notify_sleep(struct pmu_sleep_notifier *self, int when);
 80 static struct pmu_sleep_notifier adb_sleep_notifier = {
 81         adb_notify_sleep,
 82         SLEEP_LEVEL_ADB,
 83 };
 84 #endif
 85 
 86 static int adb_scan_bus(void);
 87 
 88 static struct adb_handler {
 89         void (*handler)(unsigned char *, int, struct pt_regs *, int);
 90         int original_address;
 91         int handler_id;
 92 } adb_handler[16];
 93 
 94 #if 0
 95 static void printADBreply(struct adb_request *req)
 96 {
 97         int i;
 98 
 99         printk("adb reply (%d)", req->reply_len);
100         for(i = 0; i < req->reply_len; i++)
101                 printk(" %x", req->reply[i]);
102         printk("\n");
103 
104 }
105 #endif
106 
107 static int adb_scan_bus(void)
108 {
109         int i, highFree=0, noMovement;
110         int devmask = 0;
111         struct adb_request req;
112         
113         /* assumes adb_handler[] is all zeroes at this point */
114         for (i = 1; i < 16; i++) {
115                 /* see if there is anything at address i */
116                 adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
117                             (i << 4) | 0xf);
118                 if (req.reply_len > 1)
119                         /* one or more devices at this address */
120                         adb_handler[i].original_address = i;
121                 else if (i > highFree)
122                         highFree = i;
123         }
124 
125         /* Note we reset noMovement to 0 each time we move a device */
126         for (noMovement = 1; noMovement < 2 && highFree > 0; noMovement++) {
127                 for (i = 1; i < 16; i++) {
128                         if (adb_handler[i].original_address == 0)
129                                 continue;
130                         /*
131                          * Send a "talk register 3" command to address i
132                          * to provoke a collision if there is more than
133                          * one device at this address.
134                          */
135                         adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
136                                     (i << 4) | 0xf);
137                         /*
138                          * Move the device(s) which didn't detect a
139                          * collision to address `highFree'.  Hopefully
140                          * this only moves one device.
141                          */
142                         adb_request(&req, NULL, ADBREQ_SYNC, 3,
143                                     (i<< 4) | 0xb, (highFree | 0x60), 0xfe);
144                         /*
145                          * See if anybody actually moved. This is suggested
146                          * by HW TechNote 01:
147                          *
148                          * http://developer.apple.com/technotes/hw/hw_01.html
149                          */
150                         adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
151                                     (highFree << 4) | 0xf);
152                         if (req.reply_len <= 1) continue;
153                         /*
154                          * Test whether there are any device(s) left
155                          * at address i.
156                          */
157                         adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
158                                     (i << 4) | 0xf);
159                         if (req.reply_len > 1) {
160                                 /*
161                                  * There are still one or more devices
162                                  * left at address i.  Register the one(s)
163                                  * we moved to `highFree', and find a new
164                                  * value for highFree.
165                                  */
166                                 adb_handler[highFree].original_address =
167                                         adb_handler[i].original_address;
168                                 while (highFree > 0 &&
169                                        adb_handler[highFree].original_address)
170                                         highFree--;
171                                 if (highFree <= 0)
172                                         break;
173 
174                                 noMovement = 0;
175                         }
176                         else {
177                                 /*
178                                  * No devices left at address i; move the
179                                  * one(s) we moved to `highFree' back to i.
180                                  */
181                                 adb_request(&req, NULL, ADBREQ_SYNC, 3,
182                                             (highFree << 4) | 0xb,
183                                             (i | 0x60), 0xfe);
184                         }
185                 }       
186         }
187 
188         /* Now fill in the handler_id field of the adb_handler entries. */
189         printk(KERN_DEBUG "adb devices:");
190         for (i = 1; i < 16; i++) {
191                 if (adb_handler[i].original_address == 0)
192                         continue;
193                 adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
194                             (i << 4) | 0xf);
195                 adb_handler[i].handler_id = req.reply[2];
196                 printk(" [%d]: %d %x", i, adb_handler[i].original_address,
197                        adb_handler[i].handler_id);
198                 devmask |= 1 << i;
199         }
200         printk("\n");
201         return devmask;
202 }
203 
204 int __init adb_init(void)
205 {
206         struct adb_driver *driver;
207         int i;
208 
209 #ifdef CONFIG_PPC
210         if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) )
211                 return 0;
212 #endif
213 #ifdef CONFIG_MAC
214         if (!MACH_IS_MAC)
215                 return 0;
216 #endif
217 
218         /* xmon may do early-init */
219         if (adb_inited)
220                 return 0;
221         adb_inited = 1;
222                 
223         adb_controller = NULL;
224 
225         i = 0;
226         while ((driver = adb_driver_list[i++]) != NULL) {
227                 if (!driver->probe()) {
228                         adb_controller = driver;
229                         break;
230                 }
231         }
232         if ((adb_controller == NULL) || adb_controller->init()) {
233                 printk(KERN_WARNING "Warning: no ADB interface detected\n");
234         } else {
235 #ifdef CONFIG_PMAC_PBOOK
236                 pmu_register_sleep_notifier(&adb_sleep_notifier);
237 #endif /* CONFIG_PMAC_PBOOK */
238 
239                 adb_reset_bus();
240         }
241         return 0;
242 }
243 
244 __initcall(adb_init);
245 
246 #ifdef CONFIG_PMAC_PBOOK
247 /*
248  * notify clients before sleep and reset bus afterwards
249  */
250 int
251 adb_notify_sleep(struct pmu_sleep_notifier *self, int when)
252 {
253         int ret;
254         
255         switch (when) {
256         case PBOOK_SLEEP_REQUEST:
257                 adb_got_sleep = 1;
258                 if (adb_controller->autopoll)
259                         adb_controller->autopoll(0);
260                 ret = notifier_call_chain(&adb_client_list, ADB_MSG_POWERDOWN, NULL);
261                 if (ret & NOTIFY_STOP_MASK)
262                         return PBOOK_SLEEP_REFUSE;
263                 break;
264         case PBOOK_SLEEP_REJECT:
265                 if (adb_got_sleep) {
266                         adb_got_sleep = 0;
267                         adb_reset_bus();
268                 }
269                 break;
270                 
271         case PBOOK_SLEEP_NOW:
272                 break;
273         case PBOOK_WAKE:
274                 adb_reset_bus();
275                 adb_got_sleep = 0;
276                 break;
277         }
278         return PBOOK_SLEEP_OK;
279 }
280 #endif /* CONFIG_PMAC_PBOOK */
281 
282 int
283 adb_reset_bus(void)
284 {
285         int ret, nret, devs;
286         unsigned long flags;
287         
288         if (adb_controller == NULL)
289                 return -ENXIO;
290                 
291         if (adb_controller->autopoll)
292                 adb_controller->autopoll(0);
293 
294         nret = notifier_call_chain(&adb_client_list, ADB_MSG_PRE_RESET, NULL);
295         if (nret & NOTIFY_STOP_MASK) {
296                 if (adb_controller->autopoll)
297                         adb_controller->autopoll(devs);
298                 return -EBUSY;
299         }
300 
301         save_flags(flags);
302         cli();
303         memset(adb_handler, 0, sizeof(adb_handler));
304         restore_flags(flags);
305         
306         if (adb_controller->reset_bus)
307                 ret = adb_controller->reset_bus();
308         else
309                 ret = 0;
310 
311         if (!ret) {
312                 devs = adb_scan_bus();
313                 if (adb_controller->autopoll)
314                         adb_controller->autopoll(devs);
315         }
316 
317         nret = notifier_call_chain(&adb_client_list, ADB_MSG_POST_RESET, NULL);
318         if (nret & NOTIFY_STOP_MASK)
319                 return -EBUSY;
320         
321         return ret;
322 }
323 
324 void
325 adb_poll(void)
326 {
327         if ((adb_controller == NULL)||(adb_controller->poll == NULL))
328                 return;
329         adb_controller->poll();
330 }
331 
332 
333 int
334 adb_request(struct adb_request *req, void (*done)(struct adb_request *),
335             int flags, int nbytes, ...)
336 {
337         va_list list;
338         int i;
339         struct adb_request sreq;
340 
341         if ((adb_controller == NULL) || (adb_controller->send_request == NULL))
342                 return -ENXIO;
343         if (nbytes < 1)
344                 return -EINVAL;
345         
346         if (req == NULL) {
347                 req = &sreq;
348                 flags |= ADBREQ_SYNC;
349         }
350         req->nbytes = nbytes+1;
351         req->done = done;
352         req->reply_expected = flags & ADBREQ_REPLY;
353         req->data[0] = ADB_PACKET;
354         va_start(list, nbytes);
355         for (i = 0; i < nbytes; ++i)
356                 req->data[i+1] = va_arg(list, int);
357         va_end(list);
358 
359         if (flags & ADBREQ_NOSEND)
360                 return 0;
361 
362         return adb_controller->send_request(req, flags & ADBREQ_SYNC);
363 }
364 
365  /* Ultimately this should return the number of devices with
366     the given default id.
367     And it does it now ! Note: changed behaviour: This function
368     will now register if default_id _and_ handler_id both match
369     but handler_id can be left to 0 to match with default_id only.
370     When handler_id is set, this function will try to adjust
371     the handler_id id it doesn't match. */
372 int
373 adb_register(int default_id, int handler_id, struct adb_ids *ids,
374              void (*handler)(unsigned char *, int, struct pt_regs *, int))
375 {
376         int i;
377 
378         ids->nids = 0;
379         for (i = 1; i < 16; i++) {
380                 if ((adb_handler[i].original_address == default_id) &&
381                     (!handler_id || (handler_id == adb_handler[i].handler_id) || 
382                     adb_try_handler_change(i, handler_id))) {
383                         if (adb_handler[i].handler != 0) {
384                                 printk(KERN_ERR
385                                        "Two handlers for ADB device %d\n",
386                                        default_id);
387                                 continue;
388                         }
389                         adb_handler[i].handler = handler;
390                         ids->id[ids->nids++] = i;
391                 }
392         }
393         return ids->nids;
394 }
395 
396 int
397 adb_unregister(int index)
398 {
399         if (!adb_handler[index].handler)
400                 return -ENODEV;
401         adb_handler[index].handler = 0;
402         return 0;
403 }
404 
405 void
406 adb_input(unsigned char *buf, int nb, struct pt_regs *regs, int autopoll)
407 {
408         int i, id;
409         static int dump_adb_input = 0;
410 
411         /* We skip keystrokes and mouse moves when the sleep process
412          * has been started. We stop autopoll, but this is another security
413          */
414         if (adb_got_sleep)
415                 return;
416                 
417         id = buf[0] >> 4;
418         if (dump_adb_input) {
419                 printk(KERN_INFO "adb packet: ");
420                 for (i = 0; i < nb; ++i)
421                         printk(" %x", buf[i]);
422                 printk(", id = %d\n", id);
423         }
424         if (adb_handler[id].handler != 0) {
425                 (*adb_handler[id].handler)(buf, nb, regs, autopoll);
426         }
427 }
428 
429 /* Try to change handler to new_id. Will return 1 if successful */
430 int
431 adb_try_handler_change(int address, int new_id)
432 {
433         struct adb_request req;
434 
435         if (adb_handler[address].handler_id == new_id)
436             return 1;
437         adb_request(&req, NULL, ADBREQ_SYNC, 3,
438             ADB_WRITEREG(address, 3), address | 0x20, new_id);
439         adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
440             ADB_READREG(address, 3));
441         if (req.reply_len < 2)
442             return 0;
443         if (req.reply[2] != new_id)
444             return 0;
445         adb_handler[address].handler_id = req.reply[2];
446 
447         return 1;
448 }
449 
450 int
451 adb_get_infos(int address, int *original_address, int *handler_id)
452 {
453         *original_address = adb_handler[address].original_address;
454         *handler_id = adb_handler[address].handler_id;
455         
456         return (*original_address != 0);
457 }
458 
459 
460 /*
461  * /dev/adb device driver.
462  */
463 
464 #define ADB_MAJOR       56      /* major number for /dev/adb */
465 
466 extern void adbdev_init(void);
467 
468 struct adbdev_state {
469         spinlock_t      lock;
470         atomic_t        n_pending;
471         struct adb_request *completed;
472         wait_queue_head_t wait_queue;
473         int             inuse;
474 };
475 
476 static void adb_write_done(struct adb_request *req)
477 {
478         struct adbdev_state *state = (struct adbdev_state *) req->arg;
479         unsigned long flags;
480 
481         if (!req->complete) {
482                 req->reply_len = 0;
483                 req->complete = 1;
484         }
485         spin_lock_irqsave(&state->lock, flags);
486         atomic_dec(&state->n_pending);
487         if (!state->inuse) {
488                 kfree(req);
489                 if (atomic_read(&state->n_pending) == 0) {
490                         spin_unlock_irqrestore(&state->lock, flags);
491                         kfree(state);
492                         return;
493                 }
494         } else {
495                 struct adb_request **ap = &state->completed;
496                 while (*ap != NULL)
497                         ap = &(*ap)->next;
498                 req->next = NULL;
499                 *ap = req;
500                 wake_up_interruptible(&state->wait_queue);
501         }
502         spin_unlock_irqrestore(&state->lock, flags);
503 }
504 
505 static int adb_open(struct inode *inode, struct file *file)
506 {
507         struct adbdev_state *state;
508 
509         if (MINOR(inode->i_rdev) > 0 || adb_controller == NULL)
510                 return -ENXIO;
511         state = kmalloc(sizeof(struct adbdev_state), GFP_KERNEL);
512         if (state == 0)
513                 return -ENOMEM;
514         file->private_data = state;
515         spin_lock_init(&state->lock);
516         atomic_set(&state->n_pending, 0);
517         state->completed = NULL;
518         init_waitqueue_head(&state->wait_queue);
519         state->inuse = 1;
520 
521         return 0;
522 }
523 
524 static int adb_release(struct inode *inode, struct file *file)
525 {
526         struct adbdev_state *state = file->private_data;
527         unsigned long flags;
528 
529         lock_kernel();
530         if (state) {
531                 file->private_data = NULL;
532                 spin_lock_irqsave(&state->lock, flags);
533                 if (atomic_read(&state->n_pending) == 0
534                     && state->completed == NULL) {
535                         spin_unlock_irqrestore(&state->lock, flags);
536                         kfree(state);
537                 } else {
538                         state->inuse = 0;
539                         spin_unlock_irqrestore(&state->lock, flags);
540                 }
541         }
542         unlock_kernel();
543         return 0;
544 }
545 
546 static long long adb_lseek(struct file *file, loff_t offset, int origin)
547 {
548         return -ESPIPE;
549 }
550 
551 static ssize_t adb_read(struct file *file, char *buf,
552                         size_t count, loff_t *ppos)
553 {
554         int ret;
555         struct adbdev_state *state = file->private_data;
556         struct adb_request *req;
557         wait_queue_t wait = __WAITQUEUE_INITIALIZER(wait,current);
558         unsigned long flags;
559 
560         if (count < 2)
561                 return -EINVAL;
562         if (count > sizeof(req->reply))
563                 count = sizeof(req->reply);
564         ret = verify_area(VERIFY_WRITE, buf, count);
565         if (ret)
566                 return ret;
567 
568         req = NULL;
569         add_wait_queue(&state->wait_queue, &wait);
570         current->state = TASK_INTERRUPTIBLE;
571 
572         for (;;) {
573                 spin_lock_irqsave(&state->lock, flags);
574                 req = state->completed;
575                 if (req != NULL)
576                         state->completed = req->next;
577                 else if (atomic_read(&state->n_pending) == 0)
578                         ret = -EIO;
579                 spin_unlock_irqrestore(&state->lock, flags);
580                 if (req != NULL || ret != 0)
581                         break;
582                 
583                 if (file->f_flags & O_NONBLOCK) {
584                         ret = -EAGAIN;
585                         break;
586                 }
587                 if (signal_pending(current)) {
588                         ret = -ERESTARTSYS;
589                         break;
590                 }
591                 schedule();
592         }
593 
594         current->state = TASK_RUNNING;
595         remove_wait_queue(&state->wait_queue, &wait);
596 
597         if (ret)
598                 return ret;
599 
600         ret = req->reply_len;
601         if (ret > count)
602                 ret = count;
603         if (ret > 0 && copy_to_user(buf, req->reply, ret))
604                 ret = -EFAULT;
605 
606         kfree(req);
607         return ret;
608 }
609 
610 static ssize_t adb_write(struct file *file, const char *buf,
611                          size_t count, loff_t *ppos)
612 {
613         int ret/*, i*/;
614         struct adbdev_state *state = file->private_data;
615         struct adb_request *req;
616 
617         if (count < 2 || count > sizeof(req->data))
618                 return -EINVAL;
619         ret = verify_area(VERIFY_READ, buf, count);
620         if (ret)
621                 return ret;
622 
623         req = (struct adb_request *) kmalloc(sizeof(struct adb_request),
624                                              GFP_KERNEL);
625         if (req == NULL)
626                 return -ENOMEM;
627 
628         req->nbytes = count;
629         req->done = adb_write_done;
630         req->arg = (void *) state;
631         req->complete = 0;
632         
633         ret = -EFAULT;
634         if (copy_from_user(req->data, buf, count))
635                 goto out;
636 
637         atomic_inc(&state->n_pending);
638         if (adb_controller == NULL) return -ENXIO;
639 
640         /* Special case for ADB_BUSRESET request, all others are sent to
641            the controller */
642         if ((req->data[0] == ADB_PACKET)&&(count > 1)
643                 &&(req->data[1] == ADB_BUSRESET)) {
644                 ret = adb_reset_bus();
645                 atomic_dec(&state->n_pending);
646                 goto out;
647         } else {        
648                 req->reply_expected = ((req->data[1] & 0xc) == 0xc);
649 
650                 if (adb_controller && adb_controller->send_request)
651                         ret = adb_controller->send_request(req, 0);
652                 else
653                         ret = -ENXIO;
654         }
655 
656         if (ret != 0) {
657                 atomic_dec(&state->n_pending);
658                 goto out;
659         }
660         return count;
661 
662 out:
663         kfree(req);
664         return ret;
665 }
666 
667 static struct file_operations adb_fops = {
668         llseek:         adb_lseek,
669         read:           adb_read,
670         write:          adb_write,
671         open:           adb_open,
672         release:        adb_release,
673 };
674 
675 void adbdev_init()
676 {
677 #ifdef CONFIG_PPC
678         if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) )
679                 return;
680 #endif
681 #ifdef CONFIG_MAC
682         if (!MACH_IS_MAC)
683                 return;
684 #endif
685 
686         if (devfs_register_chrdev(ADB_MAJOR, "adb", &adb_fops))
687                 printk(KERN_ERR "adb: unable to get major %d\n", ADB_MAJOR);
688         else
689                 devfs_register (NULL, "adb", DEVFS_FL_DEFAULT,
690                                 ADB_MAJOR, 0,
691                                 S_IFCHR | S_IRUSR | S_IWUSR,
692                                 &adb_fops, NULL);
693 }
694 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.