epidma.c
2.98 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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/**************************************************************************
* *
* 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 "osint.h"
#include "rcp.h"
extern OSDevMgr __osPiDevMgr;
extern OSMesgQueue *osPiGetCmdQueue(void);
/*
* Name: osPiStartDma
*
* Description:
* Set up a DMA transfer between RDRAM and PI device address space by
* sending a request to PIM. If the request priority is OS_MESG_PRI_HIGH,
* jam the message to the front of PIM command queue; otherwise, simply
* send it to the queue. If PIM is not active, return a "-1"; otherwise,
* return the status of either osSendMesg() or osJamMesg().
*
* Globals Referenced:
* __osPiDevMgr
*/
s32
osEPiStartDma(OSPiHandle *pihandle, OSIoMesg *mb, s32 direction)
{
register s32 ret;
/*
* Check for existence of PI Manager
*/
if (!__osPiDevMgr.active) {
#ifdef _DEBUG
__osError(ERR_OSPISTARTDMA_PIMGR, 0);
#endif
return(-1);
}
#ifdef _DEBUG
/*
* Check for valid message priority
*/
if ((mb->hdr.pri != OS_MESG_PRI_NORMAL) &&
(mb->hdr.pri != OS_MESG_PRI_HIGH)) {
__osError(ERR_OSPISTARTDMA_PRI, 1, mb->hdr.pri);
return(-1);
}
/*
* Check for valid direction
*/
if ((direction != OS_READ) && (direction != OS_WRITE)) {
__osError(ERR_OSPISTARTDMA_DIR, 1, direction);
return(-1);
}
/*
* Need 16-bit alignment for ROM
*/
if (mb->devAddr & 0x1) {
__osError(ERR_OSPISTARTDMA_DEVADDR, 1, mb->devAddr);
return(-1);
}
/*
* Need 64-bit alignment for RDRAM
*/
if ((u32)mb->dramAddr & 0x7) {
__osError(ERR_OSPISTARTDMA_ADDR, 1, mb->dramAddr);
return(-1);
}
/*
* Size must be a multiple of 2 bytes
*/
if (mb->size & 0x1) {
__osError(ERR_OSPISTARTDMA_SIZE, 1, mb->size);
return(-1);
}
/*
* Check for valid range: 0 < mb->size <= 16 MBytes
*/
if ((mb->size == 0) || (mb->size > (16*1024*1024))) {
__osError(ERR_OSPISTARTDMA_RANGE, 1, mb->size);
return(-1);
}
#endif
/*
* Fill up I/O request message
*/
mb->piHandle = pihandle;
if (direction == OS_READ)
mb->hdr.type = OS_MESG_TYPE_EDMAREAD;
else
mb->hdr.type = OS_MESG_TYPE_EDMAWRITE;
/*
* Send it to Peripheral Interface Manager
*/
if (mb->hdr.pri == OS_MESG_PRI_HIGH)
ret = osJamMesg(osPiGetCmdQueue(), (void *)mb, OS_MESG_NOBLOCK);
else
ret = osSendMesg(osPiGetCmdQueue(), (void *)mb, OS_MESG_NOBLOCK);
return(ret);
} /* osEPiStartDma */