Deleted Added
full compact
cuda.c (184473) cuda.c (185724)
1/*-
2 * Copyright (c) 2006 Michael Lorenz
3 * Copyright 2008 by Nathan Whitehorn
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 15 unchanged lines hidden (view full) ---

24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 */
30
31#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2006 Michael Lorenz
3 * Copyright 2008 by Nathan Whitehorn
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 15 unchanged lines hidden (view full) ---

24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: head/sys/powerpc/powermac/cuda.c 184473 2008-10-30 15:27:13Z nwhitehorn $");
32__FBSDID("$FreeBSD: head/sys/powerpc/powermac/cuda.c 185724 2008-12-06 23:26:02Z nwhitehorn $");
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/module.h>
37#include <sys/bus.h>
38#include <sys/conf.h>
39#include <sys/kernel.h>
40

--- 19 unchanged lines hidden (view full) ---

60
61/*
62 * MacIO interface
63 */
64static int cuda_probe(device_t);
65static int cuda_attach(device_t);
66static int cuda_detach(device_t);
67
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/module.h>
37#include <sys/bus.h>
38#include <sys/conf.h>
39#include <sys/kernel.h>
40

--- 19 unchanged lines hidden (view full) ---

60
61/*
62 * MacIO interface
63 */
64static int cuda_probe(device_t);
65static int cuda_attach(device_t);
66static int cuda_detach(device_t);
67
68static u_int cuda_adb_send(device_t dev, u_char command_byte, int len,
68static u_int cuda_adb_send(device_t dev, u_char command_byte, int len,
69 u_char *data, u_char poll);
69 u_char *data, u_char poll);
70static u_int cuda_adb_autopoll(device_t dev, uint16_t mask);
71static void cuda_poll(device_t dev);
70static u_int cuda_adb_autopoll(device_t dev, uint16_t mask);
71static void cuda_poll(device_t dev);
72static void cuda_send_inbound(struct cuda_softc *sc);
73static void cuda_send_outbound(struct cuda_softc *sc);
72
73static device_method_t cuda_methods[] = {
74 /* Device interface */
75 DEVMETHOD(device_probe, cuda_probe),
76 DEVMETHOD(device_attach, cuda_attach),
77 DEVMETHOD(device_detach, cuda_detach),
78 DEVMETHOD(device_shutdown, bus_generic_shutdown),
79 DEVMETHOD(device_suspend, bus_generic_suspend),

--- 17 unchanged lines hidden (view full) ---

97 sizeof(struct cuda_softc),
98};
99
100static devclass_t cuda_devclass;
101
102DRIVER_MODULE(cuda, macio, cuda_driver, cuda_devclass, 0, 0);
103DRIVER_MODULE(adb, cuda, adb_driver, adb_devclass, 0, 0);
104
74
75static device_method_t cuda_methods[] = {
76 /* Device interface */
77 DEVMETHOD(device_probe, cuda_probe),
78 DEVMETHOD(device_attach, cuda_attach),
79 DEVMETHOD(device_detach, cuda_detach),
80 DEVMETHOD(device_shutdown, bus_generic_shutdown),
81 DEVMETHOD(device_suspend, bus_generic_suspend),

--- 17 unchanged lines hidden (view full) ---

99 sizeof(struct cuda_softc),
100};
101
102static devclass_t cuda_devclass;
103
104DRIVER_MODULE(cuda, macio, cuda_driver, cuda_devclass, 0, 0);
105DRIVER_MODULE(adb, cuda, adb_driver, adb_devclass, 0, 0);
106
107MALLOC_DEFINE(M_CUDA, "cuda", "CUDA packet queue");
108
105static void cuda_intr(void *arg);
106static uint8_t cuda_read_reg(struct cuda_softc *sc, u_int offset);
107static void cuda_write_reg(struct cuda_softc *sc, u_int offset, uint8_t value);
108static void cuda_idle(struct cuda_softc *);
109static void cuda_tip(struct cuda_softc *);
110static void cuda_clear_tip(struct cuda_softc *);
111static void cuda_in(struct cuda_softc *);
112static void cuda_out(struct cuda_softc *);

--- 52 unchanged lines hidden (view full) ---

165
166 mtx_init(&sc->sc_mutex,"cuda",NULL,MTX_DEF | MTX_RECURSE);
167
168 sc->sc_sent = 0;
169 sc->sc_received = 0;
170 sc->sc_waiting = 0;
171 sc->sc_polling = 0;
172 sc->sc_state = CUDA_NOTREADY;
109static void cuda_intr(void *arg);
110static uint8_t cuda_read_reg(struct cuda_softc *sc, u_int offset);
111static void cuda_write_reg(struct cuda_softc *sc, u_int offset, uint8_t value);
112static void cuda_idle(struct cuda_softc *);
113static void cuda_tip(struct cuda_softc *);
114static void cuda_clear_tip(struct cuda_softc *);
115static void cuda_in(struct cuda_softc *);
116static void cuda_out(struct cuda_softc *);

--- 52 unchanged lines hidden (view full) ---

169
170 mtx_init(&sc->sc_mutex,"cuda",NULL,MTX_DEF | MTX_RECURSE);
171
172 sc->sc_sent = 0;
173 sc->sc_received = 0;
174 sc->sc_waiting = 0;
175 sc->sc_polling = 0;
176 sc->sc_state = CUDA_NOTREADY;
173 sc->sc_error = 0;
174 sc->sc_autopoll = 0;
175
177 sc->sc_autopoll = 0;
178
179 STAILQ_INIT(&sc->sc_inq);
180 STAILQ_INIT(&sc->sc_outq);
181
176 /* Init CUDA */
177
178 reg = cuda_read_reg(sc, vDirB);
179 reg |= 0x30; /* register B bits 4 and 5: outputs */
180 cuda_write_reg(sc, vDirB, reg);
181
182 reg = cuda_read_reg(sc, vDirB);
183 reg &= 0xf7; /* register B bit 3: input */

--- 146 unchanged lines hidden (view full) ---

330 return ((cuda_read_reg(sc, vBufB) & vPB3) == 0);
331}
332
333static int
334cuda_send(void *cookie, int poll, int length, uint8_t *msg)
335{
336 struct cuda_softc *sc = cookie;
337 device_t dev = sc->sc_dev;
182 /* Init CUDA */
183
184 reg = cuda_read_reg(sc, vDirB);
185 reg |= 0x30; /* register B bits 4 and 5: outputs */
186 cuda_write_reg(sc, vDirB, reg);
187
188 reg = cuda_read_reg(sc, vDirB);
189 reg &= 0xf7; /* register B bit 3: input */

--- 146 unchanged lines hidden (view full) ---

336 return ((cuda_read_reg(sc, vBufB) & vPB3) == 0);
337}
338
339static int
340cuda_send(void *cookie, int poll, int length, uint8_t *msg)
341{
342 struct cuda_softc *sc = cookie;
343 device_t dev = sc->sc_dev;
344 struct cuda_packet *pkt;
338
339 if (sc->sc_state == CUDA_NOTREADY)
345
346 if (sc->sc_state == CUDA_NOTREADY)
340 return -1;
347 return (-1);
341
342 mtx_lock(&sc->sc_mutex);
343
348
349 mtx_lock(&sc->sc_mutex);
350
344 if (sc->sc_state != CUDA_IDLE) {
345 if (sc->sc_waiting == 0) {
346 sc->sc_waiting = 1;
347 } else {
348 mtx_unlock(&sc->sc_mutex);
349 return -1;
350 }
351 pkt = malloc(sizeof(struct cuda_packet), M_CUDA, M_WAITOK);
352 pkt->len = length - 1;
353 pkt->type = msg[0];
354 memcpy(pkt->data, &msg[1], pkt->len);
355
356 STAILQ_INSERT_TAIL(&sc->sc_outq, pkt, pkt_q);
357
358 /*
359 * If we already are sending a packet, we should bail now that this
360 * one has been added to the queue.
361 */
362
363 if (sc->sc_waiting) {
364 mtx_unlock(&sc->sc_mutex);
365 return (0);
351 }
352
366 }
367
353 sc->sc_error = 0;
354 memcpy(sc->sc_out, msg, length);
355 sc->sc_out_length = length;
368 cuda_send_outbound(sc);
369 mtx_unlock(&sc->sc_mutex);
370
371 if (sc->sc_polling || poll || cold)
372 cuda_poll(dev);
373
374 return (0);
375}
376
377static void
378cuda_send_outbound(struct cuda_softc *sc)
379{
380 struct cuda_packet *pkt;
381
382 mtx_assert(&sc->sc_mutex, MA_OWNED);
383
384 pkt = STAILQ_FIRST(&sc->sc_outq);
385 if (pkt == NULL)
386 return;
387
388 sc->sc_out_length = pkt->len + 1;
389 memcpy(sc->sc_out, &pkt->type, pkt->len + 1);
356 sc->sc_sent = 0;
357
390 sc->sc_sent = 0;
391
358 if (sc->sc_waiting != 1) {
359 DELAY(150);
392 free(pkt, M_CUDA);
393 STAILQ_REMOVE_HEAD(&sc->sc_outq, pkt_q);
394
395 sc->sc_waiting = 1;
396
397 cuda_poll(sc->sc_dev);
398
399 DELAY(150);
400
401 if (sc->sc_state == CUDA_IDLE && !cuda_intr_state(sc)) {
360 sc->sc_state = CUDA_OUT;
361 cuda_out(sc);
362 cuda_write_reg(sc, vSR, sc->sc_out[0]);
363 cuda_ack_off(sc);
364 cuda_tip(sc);
365 }
402 sc->sc_state = CUDA_OUT;
403 cuda_out(sc);
404 cuda_write_reg(sc, vSR, sc->sc_out[0]);
405 cuda_ack_off(sc);
406 cuda_tip(sc);
407 }
366 sc->sc_waiting = 1;
367 mtx_unlock(&sc->sc_mutex);
408}
368
409
369 if (sc->sc_polling || poll || cold) {
370 cuda_poll(dev);
410static void
411cuda_send_inbound(struct cuda_softc *sc)
412{
413 device_t dev;
414 struct cuda_packet *pkt;
415
416 dev = sc->sc_dev;
417
418 mtx_lock(&sc->sc_mutex);
419
420 while ((pkt = STAILQ_FIRST(&sc->sc_inq)) != NULL) {
421 STAILQ_REMOVE_HEAD(&sc->sc_inq, pkt_q);
422
423 mtx_unlock(&sc->sc_mutex);
424
425 /* check if we have a handler for this message */
426 switch (pkt->type) {
427 case CUDA_ADB:
428 if (pkt->len > 2) {
429 adb_receive_raw_packet(sc->adb_bus,
430 pkt->data[0],pkt->data[1],
431 pkt->len - 2,&pkt->data[2]);
432 } else {
433 adb_receive_raw_packet(sc->adb_bus,
434 pkt->data[0],pkt->data[1],0,NULL);
435 }
436 break;
437 case CUDA_PSEUDO:
438 mtx_lock(&sc->sc_mutex);
439 if (pkt->data[0] == CMD_AUTOPOLL)
440 sc->sc_autopoll = 1;
441 mtx_unlock(&sc->sc_mutex);
442 break;
443 case CUDA_ERROR:
444 /*
445 * CUDA will throw errors if we miss a race between
446 * sending and receiving packets. This is already
447 * handled when we abort packet output to handle
448 * this packet in cuda_intr(). Thus, we ignore
449 * these messages.
450 */
451 break;
452 default:
453 device_printf(dev,"unknown CUDA command %d\n",
454 pkt->type);
455 break;
456 }
457
458 free(pkt,M_CUDA);
459
460 mtx_lock(&sc->sc_mutex);
371 }
372
461 }
462
373 return 0;
463 mtx_unlock(&sc->sc_mutex);
374}
375
376static void
377cuda_poll(device_t dev)
378{
379 struct cuda_softc *sc = device_get_softc(dev);
380
381 if (sc->sc_state == CUDA_IDLE && !cuda_intr_state(sc) &&
382 !sc->sc_waiting)
383 return;
384
464}
465
466static void
467cuda_poll(device_t dev)
468{
469 struct cuda_softc *sc = device_get_softc(dev);
470
471 if (sc->sc_state == CUDA_IDLE && !cuda_intr_state(sc) &&
472 !sc->sc_waiting)
473 return;
474
385 if ((cuda_read_reg(sc, vIFR) & vSR_INT) == vSR_INT)
386 cuda_intr(dev);
475 cuda_intr(dev);
387}
388
389static void
390cuda_intr(void *arg)
391{
392 device_t dev;
393 struct cuda_softc *sc;
394
476}
477
478static void
479cuda_intr(void *arg)
480{
481 device_t dev;
482 struct cuda_softc *sc;
483
395 int i, ending, type, restart_send;
484 int i, ending, restart_send, process_inbound;
396 uint8_t reg;
397
398 dev = (device_t)arg;
399 sc = device_get_softc(dev);
400
401 mtx_lock(&sc->sc_mutex);
402
403 restart_send = 0;
485 uint8_t reg;
486
487 dev = (device_t)arg;
488 sc = device_get_softc(dev);
489
490 mtx_lock(&sc->sc_mutex);
491
492 restart_send = 0;
493 process_inbound = 0;
404 reg = cuda_read_reg(sc, vIFR);
494 reg = cuda_read_reg(sc, vIFR);
495 if ((reg & vSR_INT) != vSR_INT) {
496 mtx_unlock(&sc->sc_mutex);
497 return;
498 }
499
405 cuda_write_reg(sc, vIFR, 0x7f); /* Clear interrupt */
406
407switch_start:
408 switch (sc->sc_state) {
409 case CUDA_IDLE:
410 /*
411 * This is an unexpected packet, so grab the first (dummy)
412 * byte, set up the proper vars, and tell the chip we are

--- 32 unchanged lines hidden (view full) ---

445 /* bitch only once */
446 if (sc->sc_received == 256) {
447 device_printf(dev,"input overflow\n");
448 ending = 1;
449 }
450 } else
451 sc->sc_received++;
452
500 cuda_write_reg(sc, vIFR, 0x7f); /* Clear interrupt */
501
502switch_start:
503 switch (sc->sc_state) {
504 case CUDA_IDLE:
505 /*
506 * This is an unexpected packet, so grab the first (dummy)
507 * byte, set up the proper vars, and tell the chip we are

--- 32 unchanged lines hidden (view full) ---

540 /* bitch only once */
541 if (sc->sc_received == 256) {
542 device_printf(dev,"input overflow\n");
543 ending = 1;
544 }
545 } else
546 sc->sc_received++;
547
453 if (sc->sc_received > 3) {
454 if ((sc->sc_in[3] == CMD_IIC) &&
455 (sc->sc_received > (sc->sc_i2c_read_len + 4))) {
456 ending = 1;
457 }
458 }
459
460 /* intr off means this is the last byte (end of frame) */
461 if (cuda_intr_state(sc) == 0) {
462 ending = 1;
463 } else {
464 cuda_toggle_ack(sc);
465 }
466
467 if (ending == 1) { /* end of message? */
548 /* intr off means this is the last byte (end of frame) */
549 if (cuda_intr_state(sc) == 0) {
550 ending = 1;
551 } else {
552 cuda_toggle_ack(sc);
553 }
554
555 if (ending == 1) { /* end of message? */
468 sc->sc_in[0] = sc->sc_received - 1;
556 struct cuda_packet *pkt;
469
470 /* reset vars and signal the end of this frame */
471 cuda_idle(sc);
472
557
558 /* reset vars and signal the end of this frame */
559 cuda_idle(sc);
560
473 /* check if we have a handler for this message */
474 type = sc->sc_in[1];
561 /* Queue up the packet */
562 pkt = malloc(sizeof(struct cuda_packet), M_CUDA,
563 M_WAITOK);
475
564
476 switch (type) {
477 case CUDA_ADB:
478 if (sc->sc_received > 4) {
479 adb_receive_raw_packet(sc->adb_bus,
480 sc->sc_in[2],sc->sc_in[3],
481 sc->sc_received - 4,&sc->sc_in[4]);
482 } else {
483 adb_receive_raw_packet(sc->adb_bus,
484 sc->sc_in[2],sc->sc_in[3],0,NULL);
485 }
486 break;
487 case CUDA_PSEUDO:
488 if (sc->sc_in[3] == CMD_AUTOPOLL)
489 sc->sc_autopoll = 1;
490 break;
491 case CUDA_ERROR:
492 device_printf(dev,"CUDA Error\n");
493 sc->sc_error = 1;
494 break;
495 default:
496 device_printf(dev,"unknown CUDA command %d\n",
497 type);
498 break;
499 }
565 pkt->len = sc->sc_received - 2;
566 pkt->type = sc->sc_in[1];
567 memcpy(pkt->data, &sc->sc_in[2], pkt->len);
500
568
569 STAILQ_INSERT_TAIL(&sc->sc_inq, pkt, pkt_q);
570
501 sc->sc_state = CUDA_IDLE;
571 sc->sc_state = CUDA_IDLE;
502
503 sc->sc_received = 0;
572 sc->sc_received = 0;
573 process_inbound = 1;
504
505 /*
506 * If there is something waiting to be sent out,
507 * set everything up and send the first byte.
508 */
509 if (sc->sc_waiting == 1) {
510 DELAY(1500); /* required */
511 sc->sc_sent = 0;

--- 9 unchanged lines hidden (view full) ---

521 cuda_in(sc);
522 cuda_idle(sc);
523 sc->sc_sent = 0;
524 sc->sc_state = CUDA_IDLE;
525 sc->sc_received = 0;
526 DELAY(150);
527 goto switch_start;
528 }
574
575 /*
576 * If there is something waiting to be sent out,
577 * set everything up and send the first byte.
578 */
579 if (sc->sc_waiting == 1) {
580 DELAY(1500); /* required */
581 sc->sc_sent = 0;

--- 9 unchanged lines hidden (view full) ---

591 cuda_in(sc);
592 cuda_idle(sc);
593 sc->sc_sent = 0;
594 sc->sc_state = CUDA_IDLE;
595 sc->sc_received = 0;
596 DELAY(150);
597 goto switch_start;
598 }
599
529 /*
530 * If we got here, it's ok to start sending
531 * so load the first byte and tell the chip
532 * we want to send.
533 */
534 cuda_out(sc);
535 cuda_write_reg(sc, vSR,
536 sc->sc_out[sc->sc_sent]);

--- 16 unchanged lines hidden (view full) ---

553 sc->sc_waiting = 1; /* must retry when done with
554 * read */
555 DELAY(150);
556 goto switch_start; /* process next state right
557 * now */
558 break;
559 }
560 if (sc->sc_out_length == sc->sc_sent) { /* check for done */
600 /*
601 * If we got here, it's ok to start sending
602 * so load the first byte and tell the chip
603 * we want to send.
604 */
605 cuda_out(sc);
606 cuda_write_reg(sc, vSR,
607 sc->sc_out[sc->sc_sent]);

--- 16 unchanged lines hidden (view full) ---

624 sc->sc_waiting = 1; /* must retry when done with
625 * read */
626 DELAY(150);
627 goto switch_start; /* process next state right
628 * now */
629 break;
630 }
631 if (sc->sc_out_length == sc->sc_sent) { /* check for done */
561
562 sc->sc_waiting = 0; /* done writing */
563 sc->sc_state = CUDA_IDLE; /* signal bus is idle */
564 cuda_in(sc);
565 cuda_idle(sc);
566 } else {
567 /* send next byte */
568 cuda_write_reg(sc, vSR, sc->sc_out[sc->sc_sent]);
569 cuda_toggle_ack(sc); /* signal byte ready to

--- 4 unchanged lines hidden (view full) ---

574 case CUDA_NOTREADY:
575 break;
576
577 default:
578 break;
579 }
580
581 mtx_unlock(&sc->sc_mutex);
632 sc->sc_waiting = 0; /* done writing */
633 sc->sc_state = CUDA_IDLE; /* signal bus is idle */
634 cuda_in(sc);
635 cuda_idle(sc);
636 } else {
637 /* send next byte */
638 cuda_write_reg(sc, vSR, sc->sc_out[sc->sc_sent]);
639 cuda_toggle_ack(sc); /* signal byte ready to

--- 4 unchanged lines hidden (view full) ---

644 case CUDA_NOTREADY:
645 break;
646
647 default:
648 break;
649 }
650
651 mtx_unlock(&sc->sc_mutex);
652
653 if (process_inbound)
654 cuda_send_inbound(sc);
655
656 mtx_lock(&sc->sc_mutex);
657 /* If we have another packet waiting, set it up */
658 if (!sc->sc_waiting && sc->sc_state == CUDA_IDLE)
659 cuda_send_outbound(sc);
660
661 mtx_unlock(&sc->sc_mutex);
662
582}
583
584static u_int
663}
664
665static u_int
585cuda_adb_send(device_t dev, u_char command_byte, int len, u_char *data, u_char poll)
666cuda_adb_send(device_t dev, u_char command_byte, int len, u_char *data,
667 u_char poll)
586{
587 struct cuda_softc *sc = device_get_softc(dev);
668{
669 struct cuda_softc *sc = device_get_softc(dev);
588 int i;
589 uint8_t packet[16];
670 uint8_t packet[16];
671 int i;
590
591 /* construct an ADB command packet and send it */
592 packet[0] = CUDA_ADB;
593 packet[1] = command_byte;
594 for (i = 0; i < len; i++)
595 packet[i + 2] = data[i];
596
672
673 /* construct an ADB command packet and send it */
674 packet[0] = CUDA_ADB;
675 packet[1] = command_byte;
676 for (i = 0; i < len; i++)
677 packet[i + 2] = data[i];
678
597 if (poll)
598 cuda_poll(dev);
599
600 cuda_send(sc, poll, len + 2, packet);
601
679 cuda_send(sc, poll, len + 2, packet);
680
602 if (poll)
603 cuda_poll(dev);
604
605 return 0;
681 return (0);
606}
607
608static u_int
609cuda_adb_autopoll(device_t dev, uint16_t mask) {
610 struct cuda_softc *sc = device_get_softc(dev);
611
612 uint8_t cmd[] = {CUDA_PSEUDO, CMD_AUTOPOLL, mask != 0};
613
614 mtx_lock(&sc->sc_mutex);
615
616 if (cmd[2] == sc->sc_autopoll) {
617 mtx_unlock(&sc->sc_mutex);
682}
683
684static u_int
685cuda_adb_autopoll(device_t dev, uint16_t mask) {
686 struct cuda_softc *sc = device_get_softc(dev);
687
688 uint8_t cmd[] = {CUDA_PSEUDO, CMD_AUTOPOLL, mask != 0};
689
690 mtx_lock(&sc->sc_mutex);
691
692 if (cmd[2] == sc->sc_autopoll) {
693 mtx_unlock(&sc->sc_mutex);
618 return 0;
694 return (0);
619 }
620
695 }
696
621 while (sc->sc_state != CUDA_IDLE)
622 mtx_sleep(dev,&sc->sc_mutex,0,"cuda",1);
623
624 sc->sc_autopoll = -1;
697 sc->sc_autopoll = -1;
625 cuda_send(sc, 0, 3, cmd);
698 cuda_send(sc, 1, 3, cmd);
626
627 mtx_unlock(&sc->sc_mutex);
699
700 mtx_unlock(&sc->sc_mutex);
628
629 return 0;
701
702 return (0);
630}
631
703}
704