writehost.c
2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/**************************************************************************
* *
* Copyright (C) 1995, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
#include <os.h>
#include <os_internal.h>
#include <rdb.h>
#include <ultraerror.h>
#ifndef _FINALROM
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
static int writeHostInitialized = 0;
static OSMesgQueue writeHostMesgQueue;
static OSMesg writeHostMesgBuf[1];
/*
* Name: osWriteHost
*
* Description:
* Send nbytes of data starting at dramAddr to the host.
*
* CAUTION: Application must insure that only one call to osWriteHost at a time!!!
* Application on host must have opened /dev/u64_data before osWriteHost
* is called!
*
* How it works:
* An application on the indy must open /dev/u64_data before osWriteHost is called.
* After the device is opened, either osWriteHost, or uhReadGame may be called in either
* order. When uhReadGame is called by the host application, it will block until data
* begins to arrive. When osWriteHost is called, it will send a message indicating
* how many bytes it will send, before expecting an ack back. It will follow this message
* with the data. Once the data has been read out of the kernel driver buffers, and into
* the host application buffers, the kernel will send a signal back, acknowledging the
* transfer, and indicating it is ready for the next block.
*
*/
void osWriteHost(void *dramAddr, u32 nbytes)
{
u8 *tPtr = (u8*)dramAddr;
u32 sent;
u8 dCount[3];
u32 count;
#ifdef _DEBUG
/*
* Size must be non-zero
*/
if (nbytes == 0)
{
__osError(ERR_OSWRITEHOST_SIZE, 1, nbytes);
return;
}
#endif
if(!writeHostInitialized)
{
osCreateMesgQueue(&writeHostMesgQueue, writeHostMesgBuf, 1);
osSetEventMesg(OS_EVENT_RDB_DATA_DONE, &writeHostMesgQueue, NULL);
writeHostInitialized = 1;
}
while(nbytes) /* break into blocks of RDB_DATA_MAX_BLOCK_SIZE */
{ /* this is to insure that kernal buffers don't overflow */
count = MIN(nbytes,RDB_DATA_MAX_BLOCK_SIZE);
dCount[0] = (u8)((count & 0x00FF0000) >> 16);
dCount[1] = (u8)((count & 0x0000FF00) >> 8);
dCount[2] = (u8)(count & 0x000000FF);
sent = 0;
while(sent < 3)
sent += __osRdbSend(&dCount[sent],3-sent,RDB_TYPE_GtoH_DATA_CT);
sent = 0;
while(sent < count)
sent += __osRdbSend(&tPtr[sent],count-sent,RDB_TYPE_GtoH_DATA);
nbytes -= count;
tPtr += count;
osRecvMesg(&writeHostMesgQueue, NULL, OS_MESG_BLOCK);
}
}
#endif /* ifndef _FINALROM */