The following diff is a partial rewrite of the actual adb(4) driver. It
only applies to CUDA-based machines:
$ dmesg |grep via-cuda && echo "Test this diff"
I tried to separate as much as possible the code responsible for the
CUDA chip, more or less like it is done for the PMU. It's a first step
toward creating two different drivers for the two kinds of chips present
in the macppc world, and a common adb interface.
This diff includes:
- A better initialization sequence based on the xnu & linux drivers.
- A simpler state machine which doesn't need a timer and shouldn't
generate collision.
I haven't seen any problem so far with my iMac G3 but I'm very
interested in some more tests especially if you have a machine with an
adb keyboard & mouse.
Comments?
Martin
Index: conf/files.macppc
===================================================================
RCS file: /cvs/src/sys/arch/macppc/conf/files.macppc,v
retrieving revision 1.64
diff -u -p -r1.64 files.macppc
--- conf/files.macppc 25 May 2011 07:42:15 -0000 1.64
+++ conf/files.macppc 22 Jun 2011 13:18:37 -0000
@@ -153,6 +153,7 @@ file arch/macppc/dev/z8530tty.c
zstty
device adb {}
attach adb at macobio
file arch/macppc/dev/adb.c adb needs-flag
+file arch/macppc/dev/cuda.c adb
file arch/macppc/dev/pm_direct.c adb
include "dev/adb/files.adb"
Index: dev/adb.c
===================================================================
RCS file: /cvs/src/sys/arch/macppc/dev/adb.c,v
retrieving revision 1.34
diff -u -p -r1.34 adb.c
--- dev/adb.c 16 Jun 2011 10:51:48 -0000 1.34
+++ dev/adb.c 22 Jun 2011 13:18:37 -0000
@@ -80,13 +80,6 @@
* - (Related to above) Actually implement the adbOutbound queue.
* This is fairly easy once you switch all the intr routines
* over to using adbCommand structs directly.
- * - There is a bug in the state machine of adb_intr_cuda
- * code that causes hangs, especially on 030 machines, probably
- * because of some timing issues. Because I have been unable to
- * determine the exact cause of this bug, I used the timeout function
- * to check for and recover from this condition. If anyone finds
- * the actual cause of this bug, the calls to timeout and the
- * adb_cuda_tickle routine can be removed.
*/
#include <sys/param.h>
@@ -105,6 +98,7 @@
#include <dev/adb/adb.h>
#include <macppc/dev/adbvar.h>
+#include <macppc/dev/cuda.h>
#include <macppc/dev/pm_direct.h>
#include <macppc/dev/viareg.h>
@@ -123,56 +117,7 @@ int adb_polling; /* Are we polling? (D
int adb_debug; /* Output debugging messages */
#endif /* ADB_DEBUG */
-/* some misc. leftovers */
-#define vPB 0x0000
-#define vPB3 0x08
-#define vPB4 0x10
-#define vPB5 0x20
-#define vSR_INT 0x04
-#define vSR_OUT 0x10
-
-/* the type of ADB action that we are currently performing */
-#define ADB_ACTION_NOTREADY 0x1 /* has not been initialized yet */
-#define ADB_ACTION_IDLE 0x2 /* the bus is currently idle */
-#define ADB_ACTION_OUT 0x3 /* sending out a command */
-#define ADB_ACTION_IN 0x4 /* receiving data */
-
-/*
- * Shortcuts for setting or testing the VIA bit states.
- * Not all shortcuts are used for every type of ADB hardware.
- */
-#define ADB_SET_STATE_IDLE_CUDA() via_reg_or(VIA1, vBufB, (vPB4 | vPB5))
-#define ADB_SET_STATE_TIP() via_reg_and(VIA1, vBufB, ~vPB5)
-#define ADB_CLR_STATE_TIP() via_reg_or(VIA1, vBufB, vPB5)
-#define ADB_TOGGLE_STATE_ACK_CUDA() via_reg_xor(VIA1, vBufB, vPB4)
-#define ADB_SET_STATE_ACKOFF_CUDA() via_reg_or(VIA1, vBufB, vPB4)
-#define ADB_SET_SR_INPUT() via_reg_and(VIA1, vACR, ~vSR_OUT)
-#define ADB_SET_SR_OUTPUT() via_reg_or(VIA1, vACR, vSR_OUT)
-#define ADB_SR() read_via_reg(VIA1, vSR)
-#define ADB_VIA_INTR_ENABLE() write_via_reg(VIA1, vIER, 0x84)
-#define ADB_VIA_INTR_DISABLE() write_via_reg(VIA1, vIER, 0x04)
-#define ADB_VIA_CLR_INTR() write_via_reg(VIA1, vIFR, 0x04)
-#define ADB_INTR_IS_OFF (vPB3 == (read_via_reg(VIA1, vBufB)
& vPB3))
-#define ADB_INTR_IS_ON (0 == (read_via_reg(VIA1, vBufB) & vPB3))
-#define ADB_SR_INTR_IS_ON (vSR_INT == (read_via_reg(VIA1, \
- vIFR) & vSR_INT))
-
-/*
- * This is the delay that is required (in uS) between certain
- * ADB transactions. The actual timing delay for for each uS is
- * calculated at boot time to account for differences in machine speed.
- */
-#define ADB_DELAY 150
-
-/*
- * Maximum ADB message length; includes space for data, result, and
- * device code - plus a little for safety.
- */
-#define ADB_MAX_MSG_LENGTH 16
-#define ADB_MAX_HDR_LENGTH 8
-
#define ADB_QUEUE 32
-#define ADB_TICKLE_TICKS 4
/*
* A structure for storing information about each ADB device.
@@ -186,27 +131,10 @@ struct ADBDevEntry {
};
/*
- * Eventually used for two separate queues, the queue between
- * the upper and lower halves, and the outgoing packet queue.
- */
-struct adbCommand {
- u_char header[ADB_MAX_HDR_LENGTH]; /* not used yet */
- u_char data[ADB_MAX_MSG_LENGTH]; /* packet data only */
- u_char *saveBuf; /* where to save result */
- u_char *compRout; /* completion routine pointer */
- u_char *compData; /* completion routine data pointer */
- u_int cmd; /* the original command for this data */
- u_int unsol; /* 1 if packet was unsolicited */
- u_int ack_only; /* 1 for no special processing */
-};
-
-/*
* A few variables that we need and their initial values.
*/
int adbHardware = ADB_HW_UNKNOWN;
-int adbActionState = ADB_ACTION_NOTREADY;
int adbWaiting; /* waiting for return data from the device */
-int adbWriteDelay; /* working on (or waiting to do) a write */
int adbWaitingCmd; /* ADB command we are waiting for */
u_char *adbBuffer; /* pointer to user data area */
@@ -214,11 +142,6 @@ void *adbCompRout; /* pointer to the co
void *adbCompData; /* pointer to the completion routine data */
int adbStarting = 1; /* doing adb_reinit so do polling differently */
-u_char adbInputBuffer[ADB_MAX_MSG_LENGTH]; /* data input buffer */
-u_char adbOutputBuffer[ADB_MAX_MSG_LENGTH]; /* data output buffer */
-
-int adbSentChars; /* how many characters we have sent */
-
struct ADBDevEntry ADBDevTable[16]; /* our ADB device table */
int ADBNumDevices; /* num. of ADB devices found with adb_reinit */
@@ -227,10 +150,6 @@ int adbInCount; /* how many
packets in
int adbInHead; /* head of in queue */
int adbInTail; /* tail of in queue */
-int tickle_count; /* how many tickles seen for this
packet? */
-int tickle_serial; /* the last packet tickled */
-int adb_cuda_serial; /* the current packet */
-struct timeout adb_cuda_timeout;
struct timeout adb_softintr_timeout;
int adbempty; /* nonzero if no adb devices */
@@ -242,24 +161,15 @@ volatile u_char *Via1Base;
#ifdef ADB_DEBUG
void print_single(u_char *);
#endif
-void adb_intr_cuda(void);
-void adb_soft_intr(void);
-int send_adb_cuda(u_char *, u_char *, void *, void *, int);
-void adb_cuda_tickle(void);
-void adb_pass_up(struct adbCommand *);
-void adb_op_comprout(caddr_t, caddr_t, int);
void adb_reinit(void);
int count_adbs(void);
int get_ind_adb_info(ADBDataBlock *, int);
int get_adb_info(ADBDataBlock *, int);
int adb_op(Ptr, Ptr, Ptr, short);
void adb_hw_setup(void);
-int adb_cmd_result(u_char *);
void setsoftadb(void);
int adb_intr(void *arg);
-void adb_cuda_autopoll(void);
-void adb_cuda_fileserver_mode(void);
#ifdef ADB_DEBUG
/*
@@ -293,348 +203,6 @@ print_single(str)
}
#endif
-void
-adb_cuda_tickle(void)
-{
- volatile int s;
-
- if (adbActionState == ADB_ACTION_IN) {
- if (tickle_serial == adb_cuda_serial) {
- if (++tickle_count > 0) {
- s = splhigh();
- adbActionState = ADB_ACTION_IDLE;
- adbInputBuffer[0] = 0;
- ADB_SET_STATE_IDLE_CUDA();
- splx(s);
- }
- } else {
- tickle_serial = adb_cuda_serial;
- tickle_count = 0;
- }
- } else {
- tickle_serial = adb_cuda_serial;
- tickle_count = 0;
- }
-
- timeout_add(&adb_cuda_timeout, ADB_TICKLE_TICKS);
-}
-
-/*
- * called when when an adb interrupt happens
- *
- * Cuda version of adb_intr
- * TO DO: do we want to add some calls to intr_dispatch() here to
- * grab serial interrupts?
- */
-void
-adb_intr_cuda(void)
-{
- volatile int i, ending;
- volatile unsigned int s;
- struct adbCommand packet;
-
- s = splhigh(); /* can't be too careful - might be called */
- /* from a routine, NOT an interrupt */
-
- ADB_VIA_CLR_INTR(); /* clear interrupt */
- ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */
-
-switch_start:
- switch (adbActionState) {
- case ADB_ACTION_IDLE:
- /*
- * This is an unexpected packet, so grab the first (dummy)
- * byte, set up the proper vars, and tell the chip we are
- * starting to receive the packet by setting the TIP bit.
- */
- adbInputBuffer[1] = ADB_SR();
- adb_cuda_serial++;
- if (ADB_INTR_IS_OFF) /* must have been a fake start */
- break;
-
- ADB_SET_SR_INPUT();
- ADB_SET_STATE_TIP();
-
- adbInputBuffer[0] = 1;
- adbActionState = ADB_ACTION_IN;
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("idle 0x%02x ", adbInputBuffer[1]);
-#endif
- break;
-
- case ADB_ACTION_IN:
- adbInputBuffer[++adbInputBuffer[0]] = ADB_SR();
- /* intr off means this is the last byte (end of frame) */
- if (ADB_INTR_IS_OFF)
- ending = 1;
- else
- ending = 0;
-
- if (1 == ending) { /* end of message? */
-#ifdef ADB_DEBUG
- if (adb_debug) {
- printf_intr("in end 0x%02x ",
- adbInputBuffer[adbInputBuffer[0]]);
- print_single(adbInputBuffer);
- }
-#endif
-
- /*
- * Are we waiting AND does this packet match what we
- * are waiting for AND is it coming from either the
- * ADB or RTC/PRAM sub-device? This section _should_
- * recognize all ADB and RTC/PRAM type commands, but
- * there may be more... NOTE: commands are always at
- * [4], even for RTC/PRAM commands.
- */
- /* set up data for adb_pass_up */
- memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] +
1);
-
- if ((adbWaiting == 1) &&
- (adbInputBuffer[4] == adbWaitingCmd) &&
- ((adbInputBuffer[2] == 0x00) ||
- (adbInputBuffer[2] == 0x01))) {
- packet.saveBuf = adbBuffer;
- packet.compRout = adbCompRout;
- packet.compData = adbCompData;
- packet.unsol = 0;
- packet.ack_only = 0;
- adb_pass_up(&packet);
-
- adbWaitingCmd = 0; /* reset "waiting" vars
*/
- adbWaiting = 0;
- adbBuffer = NULL;
- adbCompRout = NULL;
- adbCompData = NULL;
- } else {
- packet.unsol = 1;
- packet.ack_only = 0;
- adb_pass_up(&packet);
- }
-
-
- /* reset vars and signal the end of this frame */
- adbActionState = ADB_ACTION_IDLE;
- adbInputBuffer[0] = 0;
- ADB_SET_STATE_IDLE_CUDA();
- /*ADB_SET_SR_INPUT();*/
-
- /*
- * If there is something waiting to be sent out,
- * the set everything up and send the first byte.
- */
- if (adbWriteDelay == 1) {
- delay(ADB_DELAY); /* required */
- adbSentChars = 0;
- adbActionState = ADB_ACTION_OUT;
- /*
- * If the interrupt is on, we were too slow
- * and the chip has already started to send
- * something to us, so back out of the write
- * and start a read cycle.
- */
- if (ADB_INTR_IS_ON) {
- ADB_SET_SR_INPUT();
- ADB_SET_STATE_IDLE_CUDA();
- adbSentChars = 0;
- adbActionState = ADB_ACTION_IDLE;
- adbInputBuffer[0] = 0;
- break;
- }
- /*
- * If we got here, it's ok to start sending
- * so load the first byte and tell the chip
- * we want to send.
- */
- ADB_SET_STATE_TIP();
- ADB_SET_SR_OUTPUT();
- write_via_reg(VIA1, vSR,
adbOutputBuffer[adbSentChars + 1]);
- }
- } else {
- ADB_TOGGLE_STATE_ACK_CUDA();
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("in 0x%02x ",
- adbInputBuffer[adbInputBuffer[0]]);
-#endif
- }
- break;
-
- case ADB_ACTION_OUT:
- i = ADB_SR(); /* reset SR-intr in IFR */
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("intr out 0x%02x ", i);
-#endif
-
- adbSentChars++;
- if (ADB_INTR_IS_ON) { /* ADB intr low during write */
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("intr was on ");
-#endif
- ADB_SET_SR_INPUT(); /* make sure SR is set to IN */
- ADB_SET_STATE_IDLE_CUDA();
- adbSentChars = 0; /* must start all over */
- adbActionState = ADB_ACTION_IDLE; /* new state */
- adbInputBuffer[0] = 0;
- adbWriteDelay = 1; /* must retry when done with
- * read */
- delay(ADB_DELAY);
- goto switch_start; /* process next state right
- * now */
- break;
- }
- if (adbOutputBuffer[0] == adbSentChars) { /* check for
done */
- if (0 == adb_cmd_result(adbOutputBuffer)) { /* do
we expect data
- *
back? */
- adbWaiting = 1; /* signal waiting for return */
- adbWaitingCmd = adbOutputBuffer[2]; /* save
waiting command */
- } else { /* no talk, so done */
- /* set up stuff for adb_pass_up */
- memcpy(packet.data, adbInputBuffer,
adbInputBuffer[0] + 1);
- packet.saveBuf = adbBuffer;
- packet.compRout = adbCompRout;
- packet.compData = adbCompData;
- packet.cmd = adbWaitingCmd;
- packet.unsol = 0;
- packet.ack_only = 1;
- adb_pass_up(&packet);
-
- /* reset "waiting" vars, just in case */
- adbWaitingCmd = 0;
- adbBuffer = NULL;
- adbCompRout = NULL;
- adbCompData = NULL;
- }
-
- adbWriteDelay = 0; /* done writing */
- adbActionState = ADB_ACTION_IDLE; /* signal bus
is idle */
- ADB_SET_SR_INPUT();
- ADB_SET_STATE_IDLE_CUDA();
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("write done ");
-#endif
- } else {
- write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars +
1]); /* send next byte */
- ADB_TOGGLE_STATE_ACK_CUDA(); /* signal byte ready to
- * shift */
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("toggle ");
-#endif
- }
- break;
-
- case ADB_ACTION_NOTREADY:
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("adb: not yet initialized\n");
-#endif
- break;
-
- default:
- ;
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("intr: unknown ADB state\n");
-#endif
- }
-
- ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */
-
- splx(s); /* restore */
-}
-
-
-int
-send_adb_cuda(u_char * in, u_char * buffer, void *compRout, void *data, int
- command)
-{
- int s, len;
-
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("SEND\n");
-#endif
-
- if (adbActionState == ADB_ACTION_NOTREADY)
- return 1;
-
- /* Don't interrupt while we are messing with the ADB */
- s = splhigh();
-
- if ((adbActionState == ADB_ACTION_IDLE) && /* ADB available? */
- (ADB_INTR_IS_OFF)) { /* and no incoming interrupt? */
- } else
- if (adbWriteDelay == 0) /* it's busy, but is anything waiting?
*/
- adbWriteDelay = 1; /* if no, then we'll "queue"
- * it up */
- else {
- splx(s);
- return 1; /* really busy! */
- }
-
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("QUEUE\n");
-#endif
- if ((long)in == (long)0) { /* need to convert? */
- if ((command & 0x0c) == 0x08) /* copy addl data ONLY if
- * doing a listen! */
- len = buffer[0]; /* length of additional data */
- else
- len = 0;/* no additional data */
-
- adbOutputBuffer[0] = 2 + len; /* dev. type + command + addl.
- * data */
- adbOutputBuffer[1] = 0x00; /* mark as an ADB command */
- adbOutputBuffer[2] = (u_char)command; /* load command */
-
- /* copy additional output data, if any */
- memcpy(adbOutputBuffer + 3, buffer + 1, len);
- } else
- /* if data ready, just copy over */
- memcpy(adbOutputBuffer, in, in[0] + 2);
-
- adbSentChars = 0; /* nothing sent yet */
- adbBuffer = buffer; /* save buffer to know where to save result */
- adbCompRout = compRout; /* save completion routine pointer */
- adbCompData = data; /* save completion routine data pointer */
- adbWaitingCmd = adbOutputBuffer[2]; /* save wait command */
-
- if (adbWriteDelay != 1) { /* start command now? */
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("out start NOW");
-#endif
- delay(ADB_DELAY);
- adbActionState = ADB_ACTION_OUT; /* set next state */
- ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
- write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars + 1]);
/* load byte for output */
- ADB_SET_STATE_ACKOFF_CUDA();
- ADB_SET_STATE_TIP(); /* tell ADB that we want to send */
- }
- adbWriteDelay = 1; /* something in the write "queue" */
-
- splx(s);
-
- if ((s & (1 << 18)) || adb_polling) /* XXX were VIA1 interrupts blocked
? */
- /* poll until byte done */
- while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON)
- || (adbWaiting == 1))
- if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt"
*/
- adb_intr_cuda(); /* process it */
- if (cold)
- delay(ADB_DELAY);
- adb_soft_intr();
- }
-
- return 0;
-}
-
/*
* Called when when an adb interrupt happens.
* This routine simply transfers control over to the appropriate
@@ -649,7 +217,7 @@ adb_intr(void *arg)
break;
case ADB_HW_CUDA:
- adb_intr_cuda();
+ cuda_intr();
break;
}
return 1;
@@ -797,8 +365,6 @@ adb_soft_intr(void)
u_char *comprout;
u_char *compdata;
-/*delay(2*ADB_DELAY);*/
-
while (adbInCount) {
#ifdef ADB_DEBUG
if (adb_debug & 0x80)
@@ -868,7 +434,8 @@ adb_soft_intr(void)
int
adb_op(Ptr buffer, Ptr compRout, Ptr data, short command)
{
- int result;
+ int result, len = 0;
+
switch (adbHardware) {
case ADB_HW_PMU:
@@ -882,13 +449,32 @@ adb_op(Ptr buffer, Ptr compRout, Ptr dat
break;
case ADB_HW_CUDA:
- result = send_adb_cuda((u_char *)0, (u_char *)buffer,
- (void *)compRout, (void *)data, (int)command);
- if (result == 0)
- return 0;
- else
- return -1;
- break;
+
+ if (buffer != NULL) {
+ /* copy addl data ONLY if doing a listen! */
+ if ((command & 0x0c) == 0x08) {
+ len = buffer[0];
+
+ /*
+ * XXX - Craft a real ADB packet,
+ * The ADB code should be updated to *always*
+ * pass a real packet to the CUDA and PMU send
+ * methods.
+ */
+ memcpy(buffer + 2, buffer + 1, len);
+ }
+
+ buffer[1] = (uint8_t)command;
+
+ result = cuda_send(buffer, len + 2, compRout, data);
+ } else {
+ uint8_t msg[] = { 0x00, 0x00 };
+
+ msg[1] = (uint8_t)command;
+ result = cuda_send(msg, 2, compRout, data);
+ }
+
+ return (result);
default:
return -1;
@@ -904,8 +490,6 @@ adb_op(Ptr buffer, Ptr compRout, Ptr dat
void
adb_hw_setup(void)
{
- volatile int i;
-
switch (adbHardware) {
case ADB_HW_PMU:
@@ -917,32 +501,7 @@ adb_hw_setup(void)
break;
case ADB_HW_CUDA:
- via_reg_or(VIA1, vDirB, 0x30); /* register B bits 4 and 5:
- * outputs */
- via_reg_and(VIA1, vDirB, 0xf7); /* register B bit 3: input */
- via_reg_and(VIA1, vACR, ~vSR_OUT); /* make sure SR is set
- * to IN */
- write_via_reg(VIA1, vACR, (read_via_reg(VIA1, vACR) | 0x0c) &
~0x10);
- adbActionState = ADB_ACTION_IDLE; /* used by all types of
- * hardware */
- write_via_reg(VIA1, vIER, 0x84);/* make sure VIA interrupts
- * are on */
- ADB_SET_STATE_IDLE_CUDA(); /* set ADB bus state to idle */
-
- /* sort of a device reset */
- i = ADB_SR(); /* clear interrupt */
- ADB_VIA_INTR_DISABLE(); /* no interrupts while clearing */
- ADB_SET_STATE_IDLE_CUDA(); /* reset state to idle */
- delay(ADB_DELAY);
- ADB_SET_STATE_TIP(); /* signal start of frame */
- delay(ADB_DELAY);
- ADB_TOGGLE_STATE_ACK_CUDA();
- delay(ADB_DELAY);
- ADB_CLR_STATE_TIP();
- delay(ADB_DELAY);
- ADB_SET_STATE_IDLE_CUDA(); /* back to idle state */
- i = ADB_SR(); /* clear interrupt */
- ADB_VIA_INTR_ENABLE(); /* ints ok now */
+ cuda_init();
break;
case ADB_HW_UNKNOWN:
@@ -1178,48 +737,12 @@ adb_reinit(void)
printf_intr("adb: adb_reinit complete\n");
#endif
- if (adbHardware == ADB_HW_CUDA) {
- timeout_set(&adb_cuda_timeout, (void *)adb_cuda_tickle, NULL);
- timeout_add(&adb_cuda_timeout, ADB_TICKLE_TICKS);
- }
-
if (adbHardware != ADB_HW_PMU) /* ints must be on for PB? */
splx(s);
}
/*
- * adb_cmd_result
- *
- * This routine lets the caller know whether the specified adb command string
- * should expect a returned result, such as a TALK command.
- *
- * returns: 0 if a result should be expected
- * 1 if a result should NOT be expected
- */
-int
-adb_cmd_result(u_char *in)
-{
- switch (adbHardware) {
- case ADB_HW_CUDA:
- /* was it an ADB talk command? */
- if ((in[1] == 0x00) && ((in[2] & 0x0c) == 0x0c))
- return 0;
- /* was it an RTC/PRAM read date/time? */
- if ((in[1] == 0x01) && (in[2] == 0x03))
- return 0;
- return 1;
-
- case ADB_HW_PMU:
- return 1;
-
- default:
- return 1;
- }
-}
-
-
-/*
* adb_op_sync
*
* This routine does exactly what the adb_op routine does, except that after
@@ -1359,34 +882,15 @@ set_adb_info(ADBSetInfoBlock * info, int
int
adb_read_date_time(time_t *time)
{
- u_char output[ADB_MAX_MSG_LENGTH];
- int result;
- int retcode;
- volatile int flag = 0;
+ int retcode = 0;
switch (adbHardware) {
case ADB_HW_PMU:
pm_read_date_time(time);
- retcode = 0;
break;
case ADB_HW_CUDA:
- output[0] = 0x02; /* 2 byte message */
- output[1] = 0x01; /* to pram/rtc device */
- output[2] = 0x03; /* read date/time */
- result = send_adb_cuda((u_char *)output, (u_char *)output,
- (void *)adb_op_comprout, (void *)&flag, (int)0);
- if (result != 0) { /* exit if not sent */
- retcode = -1;
- break;
- }
-
- while (0 == flag) /* wait for result */
- ;
-
- delay(20); /* completion occurs too soon? */
- memcpy(time, output + 1, 4);
- retcode = 0;
+ retcode = cuda_time_read(time);
break;
case ADB_HW_UNKNOWN:
@@ -1401,38 +905,18 @@ adb_read_date_time(time_t *time)
} else {
*time = 0;
}
+
return retcode;
}
-/* caller should really use machine-independent version: setPramTime */
-/* this version does pseudo-adb access only */
int
adb_set_date_time(time_t time)
{
- u_char output[ADB_MAX_MSG_LENGTH];
- int result;
- volatile int flag = 0;
-
time += DIFF19041970;
switch (adbHardware) {
case ADB_HW_CUDA:
- output[0] = 0x06; /* 6 byte message */
- output[1] = 0x01; /* to pram/rtc device */
- output[2] = 0x09; /* set date/time */
- output[3] = (u_char)(time >> 24);
- output[4] = (u_char)(time >> 16);
- output[5] = (u_char)(time >> 8);
- output[6] = (u_char)(time);
- result = send_adb_cuda((u_char *)output, (u_char *)0,
- (void *)adb_op_comprout, (void *)&flag, (int)0);
- if (result != 0) /* exit if not sent */
- return -1;
-
- while (0 == flag) /* wait for send to finish */
- ;
-
- return 0;
+ return cuda_time_write(time);
case ADB_HW_PMU:
pm_set_date_time(time);
@@ -1443,13 +927,9 @@ adb_set_date_time(time_t time)
}
}
-
int
adb_poweroff(void)
{
- u_char output[ADB_MAX_MSG_LENGTH];
- int result;
-
adb_polling = 1;
switch (adbHardware) {
@@ -1458,20 +938,13 @@ adb_poweroff(void)
pmu_fileserver_mode(0);
pm_adb_poweroff();
- for (;;); /* wait for power off */
+ for (;;)
+ ; /* wait for power off */
return 0;
case ADB_HW_CUDA:
- output[0] = 0x02; /* 2 byte message */
- output[1] = 0x01; /* to pram/rtc/soft-power device */
- output[2] = 0x0a; /* set poweroff */
- result = send_adb_cuda((u_char *)output, (u_char *)0,
- (void *)0, (void *)0, (int)0);
- if (result != 0) /* exit if not sent */
- return -1;
-
- for (;;); /* wait for power off */
+ cuda_poweroff();
return 0;
@@ -1489,63 +962,15 @@ setsoftadb()
}
void
-adb_cuda_autopoll()
-{
- volatile int flag = 0;
- int result;
- u_char output[16];
-
- output[0] = 0x03; /* 3-byte message */
- output[1] = 0x01; /* to pram/rtc/soft-power device */
- output[2] = 0x01; /* cuda autopoll */
- output[3] = 0x01;
- result = send_adb_cuda(output, output, adb_op_comprout,
- (void *)&flag, 0);
- if (result != 0) /* exit if not sent */
- return;
-
- while (flag == 0); /* wait for result */
-}
-
-void
-adb_cuda_fileserver_mode()
-{
- volatile int flag = 0;
- int result;
- u_char output[16];
-
- output[0] = 0x03; /* 3-byte message */
- output[1] = 0x01; /* to pram/rtc device/soft-power device */
- output[2] = 0x13; /* cuda file server mode */
- output[3] = 0x01; /* True - Turn on after AC loss */
-
- result = send_adb_cuda(output, output, adb_op_comprout,
- (void *)&flag, 0);
- if (result != 0)
- return;
-
- while (flag == 0);
-}
-
-void
adb_restart()
{
- int result;
- u_char output[16];
-
adb_polling = 1;
switch (adbHardware) {
case ADB_HW_CUDA:
- output[0] = 0x02; /* 2 byte message */
- output[1] = 0x01; /* to pram/rtc/soft-power device */
- output[2] = 0x11; /* restart */
- result = send_adb_cuda((u_char *)output, (u_char *)0,
- (void *)0, (void *)0, (int)0);
- if (result != 0) /* exit if not sent */
- return;
- while (1); /* not return */
+ cuda_restart();
+ /* NOTREACHED */
case ADB_HW_PMU:
pm_adb_restart();
while (1); /* not return */
@@ -1676,11 +1101,11 @@ adbattach(struct device *parent, struct
}
if (adbHardware == ADB_HW_CUDA)
- adb_cuda_fileserver_mode();
+ cuda_fileserver_mode();
if (adbHardware == ADB_HW_PMU)
pmu_fileserver_mode(1);
if (adbHardware == ADB_HW_CUDA)
- adb_cuda_autopoll();
+ cuda_autopoll();
adb_polling = 0;
}
Index: dev/adbvar.h
===================================================================
RCS file: /cvs/src/sys/arch/macppc/dev/adbvar.h,v
retrieving revision 1.8
diff -u -p -r1.8 adbvar.h
--- dev/adbvar.h 18 Jan 2006 23:21:17 -0000 1.8
+++ dev/adbvar.h 22 Jun 2011 13:18:37 -0000
@@ -36,12 +36,40 @@ struct adb_softc {
char *sc_regbase;
};
+extern volatile u_char *Via1Base;
+
+#define ADB_MAX_MSG_LENGTH 16
+#define ADB_MAX_HDR_LENGTH 8
+
+struct adbCommand {
+ u_char header[ADB_MAX_HDR_LENGTH]; /* not used yet */
+ u_char data[ADB_MAX_MSG_LENGTH]; /* packet data only */
+ u_char *saveBuf; /* where to save result */
+ u_char *compRout; /* completion routine pointer */
+ u_char *compData; /* completion routine data pointer */
+ u_int cmd; /* the original command for this data */
+ u_int unsol; /* 1 if packet was unsolicited */
+ u_int ack_only; /* 1 for no special processing */
+};
+
+extern u_char *adbBuffer; /* pointer to user data area */
+extern void *adbCompRout; /* pointer to the completion routine */
+extern void *adbCompData; /* pointer to the completion routine data */
+extern int adbWaiting; /* waiting for return data from the device */
+extern int adbWaitingCmd; /* ADB command we are waiting for */
+
+
extern int adbHardware;
+extern int adb_polling;
/* types of adb hardware that we support */
#define ADB_HW_UNKNOWN 0x01 /* don't know */
#define ADB_HW_PMU 0x04 /* PowerBook series */
#define ADB_HW_CUDA 0x05 /* Machines with a Cuda chip */
+
+void adb_soft_intr(void);
+void adb_op_comprout(caddr_t, caddr_t, int);
+void adb_pass_up(struct adbCommand *);
int adb_poweroff(void);
void adb_restart(void);
Index: dev/cuda.c
===================================================================
RCS file: dev/cuda.c
diff -N dev/cuda.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dev/cuda.c 22 Jun 2011 13:18:37 -0000
@@ -0,0 +1,565 @@
+/* $OpenBSD$ */
+/*
+ * Copyright (c) 2011 Martin Pieuchot <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/timeout.h>
+
+#include <machine/pio.h>
+#include <machine/autoconf.h>
+
+#include <macppc/dev/cuda.h>
+#include <macppc/dev/adbvar.h>
+
+#define CUDA_DEBUG
+
+#ifdef CUDA_DEBUG
+#define DPRINTF(x...) printf(x)
+#else
+#define DPRINTF(x...)
+#endif
+
+/*
+struct cuda_softc {
+ struct device sc_dev;
+ uint8_t *sc_viaaddr;
+*/
+#define ST_NOTREADY 0
+#define ST_IDLE 1
+#define ST_SENDING 3
+#define ST_RECEIVING 4
+#define ST_RECEIVED 5
+ int state; /* interrupt state */
+
+ int enqueued; /* bytes are waiting to be send */
+
+ int received;
+ uint8_t inqueue[16];
+
+ int sent;
+ int length;
+ uint8_t outqueue[16];
+/*
+};
+*/
+
+
+/*
+ * VIA registers used by Cuda
+ */
+#define DATB 0x0000 /* B-side data register */
+#define DIRB 0x0400 /* B-side direction register (1 for out) */
+#define SR 0x1400 /* Shift register */
+#define ACR 0x1600 /* Auxiliary control register */
+#define IFR 0x1a00 /* Interrupt flag register */
+#define IER 0x1c00 /* Interrupt enable register */
+
+/*
+ * Cuda signals/bits for the B-side data register.
+ */
+#define TREQ 0x08 /* PB3 */
+#define BYTEACK 0x10 /* PB4 */
+#define TIP 0x20 /* PB5 */
+
+/*
+ * Cuda values for the VIA auxillary control
+ */
+#define EXTCLOCK 0x0c
+#define SREG_OUT 0x10
+
+/*
+ * Interrupts bits.
+ */
+#define INTR_DISABLE 0x00
+#define INTR_SR 0x04
+#define INTR_ALL 0x7f
+#define INTR_ENABLE 0x80
+
+
+void cuda_poll(void);
+
+
+inline void cuda_write(int, uint8_t);
+inline uint8_t cuda_read(int);
+
+inline void cuda_set_idle(void);
+inline void cuda_set_receiving(void);
+inline void cuda_set_sending(void);
+inline void cuda_set_tip(void);
+inline void cuda_toggle_byteack(void);
+
+#define WAIT_FOR(x) \
+ do { \
+ int i; \
+ \
+ for (i = 0; i < 1000; i++) \
+ if ((x)) \
+ break; \
+ } while (0);
+
+void
+cuda_init(void)
+{
+ /*
+ * Set the signals directions:
+ * BYTEACK and TIP are outputs and TREQ in input.
+ */
+ cuda_write(DIRB, (cuda_read(DIRB) | BYTEACK | TIP) & ~TREQ);
+ cuda_set_idle();
+
+ /* Clock control, shift data by external clock CB1. */
+ cuda_write(ACR, (cuda_read(ACR) | EXTCLOCK));
+ cuda_set_receiving();
+
+ (void)cuda_read(SR);
+
+ /* Disable all interrupts from VIA */
+ cuda_write(IER, INTR_DISABLE | INTR_ALL);
+ (void)cuda_read(IER);
+
+ /* Reset ADB, it needs 4 mSec to complete. */
+ delay(4000);
+ (void)cuda_read(SR);
+ cuda_write(IFR, INTR_SR);
+
+ /* Sync with CUDA. */
+ cuda_write(DATB, cuda_read(DATB) & ~BYTEACK);
+ WAIT_FOR((cuda_read(DATB) & TREQ) == 0);
+ WAIT_FOR(cuda_read(IFR) & INTR_SR);
+ (void)cuda_read(SR);
+ cuda_write(IFR, INTR_SR);
+
+ /* End the Sync. */
+ cuda_write(DATB, cuda_read(DATB) | BYTEACK);
+ WAIT_FOR(cuda_read(DATB) & TREQ);
+ WAIT_FOR(cuda_read(IFR) & INTR_SR);
+ (void)cuda_read(SR);
+ cuda_write(IFR, INTR_SR);
+
+ /*
+ * Clear all interrupts, then enable only those from
+ * the shift register.
+ */
+ cuda_write(IFR, INTR_ALL);
+ cuda_write(IER, INTR_ENABLE | INTR_SR);
+
+ state = ST_IDLE;
+ DPRINTF("\ncuda: init OK\n");
+}
+
+int
+cuda_send(uint8_t *cmd, int len, void *func, void *fargs)
+{
+ int s;
+
+ if (state == ST_NOTREADY)
+ return (-1);
+
+ s = splhigh();
+
+ if (state != ST_IDLE || (cuda_read(DATB) & TREQ) == 0) {
+ DPRINTF("cuda: state = %d, enqueued = %d\n", state, enqueued);
+ if (enqueued == 0) {
+ enqueued = 1;
+ } else {
+ splx(s);
+ return (-1);
+ }
+ }
+
+ sent = 0;
+ length = len;
+ memcpy(outqueue, cmd, len);
+
+ /* TODO: clean the ADB mess. */
+ if (func != NULL) {
+ adbBuffer = cmd;
+ adbCompRout = func;
+ adbCompData = fargs;
+ adbWaitingCmd = cmd[1];
+ }
+
+ if (enqueued == 0) {
+ cuda_set_sending();
+ cuda_write(SR, outqueue[0]);
+ cuda_set_tip();
+ state = ST_SENDING;
+ sent = 0;
+ DPRINTF("cuda: send: %02x", outqueue[0]);
+
+ enqueued = 1;
+ }
+
+ splx(s);
+
+ if (adb_polling || cold)
+ cuda_poll();
+
+ return (0);
+}
+
+void
+cuda_poll(void)
+{
+ int s;
+
+ while ((state != ST_IDLE) || (cuda_read(DATB) & TREQ) == 0 ||
adbWaiting)
+ if ((cuda_read(IFR) & INTR_SR) == INTR_SR) {
+ s = splhigh();
+ cuda_intr();
+ splx(s);
+
+ /* XXX - ADB mess, don't call soft_intr() here. */
+ if (cold)
+ delay(150);
+ adb_soft_intr();
+ }
+}
+
+int
+cuda_intr(void)
+{
+ /* We only deal with the Shift Register interrupts. */
+ if ((cuda_read(IFR) & INTR_SR) == 0)
+ return (0);
+
+ cuda_write(IFR, INTR_SR);
+
+ switch (state) {
+ case ST_IDLE:
+ inqueue[1] = cuda_read(SR);
+
+ if (cuda_read(DATB) & TREQ) {
+ DPRINTF("cuda: unsolicited byte\n");
+
+ if (enqueued == 1) {
+ cuda_set_sending();
+ cuda_write(SR, outqueue[0]);
+ cuda_set_tip();
+ state = ST_SENDING;
+ sent = 0;
+ DPRINTF("cuda: send: %02x", outqueue[0]);
+ }
+ break;
+ }
+
+ cuda_set_receiving();
+ cuda_set_tip();
+ state = ST_RECEIVING;
+ received = 1;
+ DPRINTF("cuda: recv: %02x", inqueue[1]);
+ break;
+
+ case ST_RECEIVING:
+ inqueue[++received] = cuda_read(SR);
+ DPRINTF(" %02x", inqueue[received]);
+
+ if (cuda_read(DATB) & TREQ) {
+ cuda_set_idle();
+ state = ST_RECEIVED;
+ } else {
+ cuda_toggle_byteack();
+ }
+ break;
+
+ case ST_RECEIVED:
+ (void)cuda_read(SR);
+ DPRINTF(", eof (%d bytes)\n", received);
+
+ /*
+ * XXX - for compatibility reasons with the actual
+ * ADB system inqueue[0] contains the number of bytes
+ * received.
+ */
+ inqueue[0] = received - 1;
+
+ /* TODO clean the ADB mess. */
+ if ((adbWaiting == 1) && (inqueue[4] == adbWaitingCmd) &&
+ (inqueue[2] == CUDA_ADDR_ADB || inqueue[2] ==
CUDA_ADDR_PSEUDO)) {
+ struct adbCommand packet;
+
+ memcpy(packet.data, inqueue, received);
+ packet.saveBuf = adbBuffer;
+ packet.compRout = adbCompRout;
+ packet.compData = adbCompData;
+ packet.unsol = 0;
+ packet.ack_only = 0;
+ adb_pass_up(&packet);
+
+ adbWaitingCmd = 0;
+ adbWaiting = 0;
+ adbBuffer = NULL;
+ adbCompRout = NULL;
+ adbCompData = NULL;
+ } else {
+ struct adbCommand packet;
+
+ memcpy(packet.data, inqueue, received);
+ packet.unsol = 1;
+ packet.ack_only = 0;
+ adb_pass_up(&packet);
+ }
+
+ cuda_set_idle();
+ state = ST_IDLE;
+ received = 0;
+
+ if ((enqueued == 1) && (cuda_read(DATB) & TREQ)) {
+ cuda_set_sending();
+ cuda_write(SR, outqueue[0]);
+ cuda_set_tip();
+ state = ST_SENDING;
+ sent = 0;
+ DPRINTF("cuda: send: %02x", outqueue[0]);
+ }
+ break;
+
+ case ST_SENDING:
+ if ((cuda_read(DATB) & TREQ) == 0) {
+ DPRINTF(", collision, enqueue.\n");
+ enqueued = 1;
+
+ cuda_set_receiving();
+ (void)cuda_read(SR);
+ cuda_set_idle();
+ state = ST_IDLE;
+ received = 0;
+ break;
+ }
+
+ if (++sent == length) {
+ DPRINTF(", eof (%d bytes)\n", sent);
+
+ /* TODO clean the ADB mess. */
+ if ((outqueue[0] == CUDA_ADDR_ADB && (outqueue[1] &
0x0c) == 0x0c) ||
+ (outqueue[0] == CUDA_ADDR_PSEUDO && (outqueue[1] ==
CUDA_CMD_READ_RTC))) {
+ adbWaiting = 1;
+ adbWaitingCmd = outqueue[1];
+ } else {
+ struct adbCommand packet;
+
+ /* ack-only, copy the sended msg */
+ packet.data[0] = sent;
+ memcpy(packet.data + 1, outqueue, sent);
+
+ packet.saveBuf = adbBuffer;
+ packet.compRout = adbCompRout;
+ packet.compData = adbCompData;
+ packet.cmd = adbWaitingCmd;
+ packet.unsol = 0;
+ packet.ack_only = 1;
+ adb_pass_up(&packet);
+
+ adbWaitingCmd = 0;
+ adbBuffer = NULL;
+ adbCompRout = NULL;
+ adbCompData = NULL;
+ }
+
+ enqueued = 0;
+ cuda_set_receiving();
+ cuda_set_idle();
+ state = ST_IDLE;
+ } else {
+ cuda_write(SR, outqueue[sent]);
+ cuda_toggle_byteack();
+ DPRINTF(" %02x", outqueue[sent]);
+ }
+
+ break;
+
+ case ST_NOTREADY:
+ DPRINTF("cuda: ADB not yet initialized\n");
+ break;
+
+ default:
+ DPRINTF("cuda: unknown ADB state\n");
+ break;
+ }
+
+ return (1);
+}
+
+inline void
+cuda_write(int offset, uint8_t value)
+{
+ /*
+ * XXX Via1Base shouldn't be global.
+ */
+ out8(Via1Base + offset, value);
+}
+
+inline uint8_t
+cuda_read(int offset)
+{
+ /*
+ * XXX Via1Base shouldn't be global.
+ */
+ return in8(Via1Base + offset);
+}
+
+inline void
+cuda_set_idle(void)
+{
+ cuda_write(DATB, cuda_read(DATB) | BYTEACK | TIP);
+}
+
+inline void
+cuda_set_tip(void)
+{
+ cuda_write(DATB, cuda_read(DATB) & ~TIP);
+}
+
+inline void
+cuda_toggle_byteack(void)
+{
+ cuda_write(DATB, cuda_read(DATB) ^ BYTEACK);
+}
+
+inline void
+cuda_set_receiving(void)
+{
+ cuda_write(ACR, cuda_read(ACR) & ~SREG_OUT);
+}
+
+inline void
+cuda_set_sending(void)
+{
+ cuda_write(ACR, cuda_read(ACR) | SREG_OUT);
+}
+
+void
+cuda_autopoll(void)
+{
+ volatile int flag = 0;
+ uint8_t cmd[16];
+
+ cmd[0] = CUDA_ADDR_PSEUDO;
+ cmd[1] = CUDA_CMD_AUTOPOLL;
+ cmd[2] = 1; /* ON */
+
+ if (cuda_send(cmd, 3, adb_op_comprout, (void *)&flag))
+ return;
+
+ while (flag == 0)
+ ;
+}
+
+int
+cuda_time_read(time_t *time)
+{
+ volatile int flag = 0;
+ uint8_t cmd[16];
+
+ cmd[0] = CUDA_ADDR_PSEUDO;
+ cmd[1] = CUDA_CMD_READ_RTC;
+
+ if (cuda_send(cmd, 2, adb_op_comprout, (void *)&flag))
+ return (-1);
+
+ while (0 == flag)
+ ;
+
+ delay(20);
+
+ /* XXX - ADB mess
+ * For compatibility reasons the first byte
+ * returned is the size of the response.
+ */
+ memcpy(time, cmd + 1, 4);
+
+ return (0);
+}
+
+int
+cuda_time_write(time_t time)
+{
+ volatile int flag = 0;
+ uint8_t cmd[16];
+
+ cmd[0] = CUDA_ADDR_PSEUDO;
+ cmd[1] = CUDA_CMD_WRITE_RTC;
+ cmd[2] = (uint8_t)(time >> 24);
+ cmd[3] = (uint8_t)(time >> 16);
+ cmd[4] = (uint8_t)(time >> 8);
+ cmd[5] = (uint8_t)(time);
+
+ if (cuda_send(cmd, 6, adb_op_comprout, (void *)&flag));
+ return (-1);
+
+ while (0 == flag)
+ ;
+
+ return (0);
+}
+
+int
+cuda_poweroff(void)
+{
+ uint8_t cmd[16];
+
+ /*
+ * Clean enqueued msg to be sure this one won't fail.
+ */
+ cuda_poll();
+
+ cmd[0] = CUDA_ADDR_PSEUDO;
+ cmd[1] = CUDA_CMD_POWEROFF;
+
+ if (cuda_send(cmd, 2, NULL, NULL))
+ return (-1);
+
+ while (1)
+ ;
+}
+
+void
+cuda_restart(void)
+{
+ uint8_t cmd[16];
+
+ /*
+ * Clean enqueued msg to be sure this one won't fail.
+ */
+ cuda_poll();
+
+ cmd[0] = CUDA_ADDR_PSEUDO;
+ cmd[1] = CUDA_CMD_RESTART;
+
+ if (cuda_send(cmd, 2, NULL, NULL))
+ return;
+
+ while (1)
+ ;
+}
+
+void
+cuda_fileserver_mode(void)
+{
+ volatile int flag = 0;
+ uint8_t cmd[16];
+
+ cmd[0] = CUDA_ADDR_PSEUDO;
+ cmd[1] = CUDA_CMD_FILESERVER;
+ cmd[2] = 1; /* ON */
+
+ if (cuda_send(cmd, 3, adb_op_comprout, (void *)&flag))
+ return;
+
+ while (flag == 0)
+ ;
+}
Index: dev/cuda.h
===================================================================
RCS file: dev/cuda.h
diff -N dev/cuda.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dev/cuda.h 22 Jun 2011 13:18:37 -0000
@@ -0,0 +1,44 @@
+/* $OpenBSD$ */
+/*
+ * Copyright (c) 2011 Martin Pieuchot <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define CUDA_ADDR_ADB 0x00
+#define CUDA_ADDR_PSEUDO 0x01 /* PRAM, rtc, soft-power */
+#define CUDA_ADDR_ERROR 0x02
+#define CUDA_ADDR_TIMER 0x03
+#define CUDA_ADDR_POWER 0x04
+#define CUDA_ADDR_IIC 0x05
+#define CUDA_ADDR_PMU 0x06
+#define CUDA_ADDR_ADB_QUERY 0x07
+
+#define CUDA_CMD_AUTOPOLL 0x01
+#define CUDA_CMD_READ_RTC 0x03
+#define CUDA_CMD_WRITE_RTC 0x09
+#define CUDA_CMD_POWEROFF 0x0a
+#define CUDA_CMD_RESTART 0x11
+#define CUDA_CMD_FILESERVER 0x13
+
+void cuda_init(void);
+
+int cuda_intr(void);
+int cuda_send(uint8_t *, int, void *, void *);
+
+void cuda_autopoll(void);
+int cuda_time_read(time_t *);
+int cuda_time_write(time_t);
+int cuda_poweroff(void);
+void cuda_restart(void);
+void cuda_fileserver_mode(void);
Index: dev/pm_direct.c
===================================================================
RCS file: /cvs/src/sys/arch/macppc/dev/pm_direct.c,v
retrieving revision 1.23
diff -u -p -r1.23 pm_direct.c
--- dev/pm_direct.c 14 May 2011 12:01:16 -0000 1.23
+++ dev/pm_direct.c 22 Jun 2011 13:18:37 -0000
@@ -163,31 +163,6 @@ void pm_adb_get_TALK_result(PMData *);
void pm_adb_get_ADB_data(PMData *);
-/*
- * These variables are in adb_direct.c.
- */
-extern u_char *adbBuffer; /* pointer to user data area */
-extern void *adbCompRout; /* pointer to the completion routine */
-extern void *adbCompData; /* pointer to the completion routine data */
-extern int adbWaiting; /* waiting for return data from the device */
-extern int adbWaitingCmd; /* ADB command we are waiting for */
-extern int adbStarting; /* doing ADB reinit, so do "polling"
differently */
-
-#define ADB_MAX_MSG_LENGTH 16
-#define ADB_MAX_HDR_LENGTH 8
-struct adbCommand {
- u_char header[ADB_MAX_HDR_LENGTH]; /* not used yet */
- u_char data[ADB_MAX_MSG_LENGTH]; /* packet data only */
- u_char *saveBuf; /* where to save result */
- u_char *compRout; /* completion routine pointer */
- u_char *compData; /* completion routine data pointer */
- u_int cmd; /* the original command for this data */
- u_int unsol; /* 1 if packet was unsolicited */
- u_int ack_only; /* 1 for no special processing */
-};
-extern void adb_pass_up(struct adbCommand *);
-
-
#ifdef ADB_DEBUG
/*
* This function dumps contents of the PMData