source: drsdaq/VME/struck/sis1100/V2.02/dev/pci/sis1100_read_loop.c@ 23

Last change on this file since 23 was 22, checked in by ogrimm, 16 years ago
First commit of drsdaq program
File size: 5.3 KB
Line 
1/* $ZEL: sis1100_read_loop.c,v 1.3 2004/05/27 23:10:32 wuestner Exp $ */
2
3/*
4 * Copyright (c) 2003-2004
5 * Peter Wuestner. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include "sis1100_sc.h"
30
31/*
32 * sis1100_read_loop always transports data directly to userspace!
33 * Access permissions have to be checked before.
34 */
35
36ssize_t
37sis1100_read_loop(
38 struct sis1100_softc* sc,
39 struct sis1100_fdata* fd,
40 u_int32_t addr, /* VME or SDRAM address */
41 int32_t am, /* address modifier, not used if <0 */
42 int size, /* datasize (bytes/word) */
43 int space, /* remote space (1,2: VME; 6: SDRAM) */
44 int fifo_mode,
45 size_t count, /* words (of size 'size') to be transferred */
46 /* count==0 is illegal */
47 size_t* count_read, /* words transferred */
48 u_int8_t* data, /* destination (user virtual address) */
49 int* prot_error
50 )
51{
52 u_int32_t head;
53 int idx, res=0;
54
55 *count_read=count;
56 head=0x00000002|(space&0x3f)<<16;
57 SEM_LOCK(sc->sem_hw);
58 if (am>=0) {
59 head|=0x800;
60 sis1100writereg(sc, t_am, am);
61 }
62 switch (size) {
63 case 1:
64 for (idx=0; idx<count; idx++, data++) {
65 u_int32_t val;
66 sis1100writereg(sc, t_hdr, head|(0x01000000<<(addr&3)));
67 sis1100writereg(sc, t_adl, addr);
68 do {
69 *prot_error=sis1100readreg(sc, prot_error);
70 } while (*prot_error==0x005);
71 if (*prot_error) {
72 *count_read=idx;
73 break;
74 }
75 val=sis1100rawreadreg(sc, tc_dal);
76#ifdef __NetBSD__
77#if defined(__LITTLE_ENDIAN)
78 subyte(data, (val>>((addr&3)<<3))&0xff);
79#else
80 subyte(data, (val>>((3-(addr&3))<<3))&0xff);
81#endif
82#elif __linux__
83#if defined(__LITTLE_ENDIAN)
84 __put_user((val>>((addr&3)<<3))&0xff, (u_int8_t*)(data));
85#else
86 __put_user((val>>((3-(addr&3))<<3))&0xff, (u_int8_t*)(data));
87#endif
88#endif
89 if (!fifo_mode) addr++;
90 }
91 break;
92 case 2:
93 for (idx=0; idx<count; idx++, data+=2) {
94 u_int32_t val;
95 sis1100writereg(sc, t_hdr, head|(0x03000000<<(addr&3)));
96 sis1100writereg(sc, t_adl, addr);
97 do {
98 *prot_error=sis1100readreg(sc, prot_error);
99 } while (*prot_error==0x005);
100 if (*prot_error) {
101 /*
102 pINFO(sc, "read_loop(2): addr=%x prot_error=%x idx=%d",
103 addr, *prot_error, idx);
104 */
105 *count_read=idx;
106 break;
107 }
108 val=sis1100rawreadreg(sc, tc_dal);
109/*
110 pINFO(sc, "read_loop: head=%08x addr=%x idx=%d val=%08x",
111 head|(0x03000000<<(addr&3)), addr, idx, val);
112*/
113#ifdef __NetBSD__
114#if defined(__LITTLE_ENDIAN)
115 susword(data, (val>>((addr&2)<<3))&0xffff);
116#else
117 susword(data, (val>>((2-(addr&2))<<3))&0xffff);
118#endif
119#elif __linux__
120#if defined(__LITTLE_ENDIAN)
121 __put_user((val>>((addr&2)<<3))&0xffff, (u_int16_t*)data);
122#else
123 __put_user((val>>((2-(addr&2))<<3))&0xffff, (u_int16_t*)data);
124#endif
125#endif
126 if (!fifo_mode) addr+=2;
127 }
128 break;
129 case 4:
130 sis1100writereg(sc, t_hdr, head|0x0f000000);
131 for (idx=0; idx<count; idx++, data+=4) {
132 u_int32_t val;
133 sis1100writereg(sc, t_adl, addr);
134 do {
135 *prot_error=sis1100readreg(sc, prot_error);
136 } while (*prot_error==0x005);
137 if (*prot_error) {
138 *count_read=idx;
139 break;
140 }
141 val=sis1100rawreadreg(sc, tc_dal);
142#ifdef __NetBSD__
143 suword(data, val);
144#elif __linux__
145 __put_user(val, (u_int32_t*)data);
146#endif
147 if (!fifo_mode) addr+=4;
148 }
149 break;
150 }
151 SEM_UNLOCK(sc->sem_hw);
152/*
153pINFO(sc, "read_loop(am=%x size=%d count=%d count_read=%d, addr=%x): res=%d",
154 am, size, count, *count_read, addr, res);
155*/
156 return res;
157}
Note: See TracBrowser for help on using the repository browser.