source: drsdaq/VME/struck/sis1100/V2.02/dev/pci/sis1100_write_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.5 KB
Line 
1/* $ZEL: sis1100_write_loop.c,v 1.2 2004/05/27 23:10:40 wuestner Exp $ */
2
3/*
4 * Copyright (c) 2001-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#if !defined(__NetBSD__) && ! defined(__linux__)
32#error Invalid or Unknown Operating System
33#endif
34
35/*
36 * sis1100_write_loop always transports data directly from userspace!
37 * Access permissions have to be checked before.
38 */
39
40ssize_t
41sis1100_write_loop(
42 struct sis1100_softc* sc,
43 struct sis1100_fdata* fd,
44 u_int32_t addr, /* VME or SDRAM address */
45 int32_t am, /* address modifier, not used if <0 */
46 int size, /* datasize */
47 int space, /* remote space (1,2: VME; 6: SDRAM) */
48 int fifo_mode,
49 size_t count, /* words (of size 'size') to be transferred */
50 /* count==0 is illegal */
51 size_t* count_written, /* words transferred */
52 const u_int8_t* data, /* source (user virtual address) */
53 int* prot_error
54 )
55{
56 u_int32_t head;
57 int idx;
58
59 *count_written=count;
60 head=0x0f000404|(space&0x3f)<<16;
61 SEM_LOCK(sc->sem_hw);
62 if (am>=0) {
63 head|=0x800;
64 sis1100writereg(sc, t_am, am);
65 }
66 switch (size) {
67 case 1:
68 if (fifo_mode) {
69 sis1100writereg(sc, t_adl, addr);
70 sis1100writereg(sc, t_hdr, head|(0x01000000<<(addr&3)));
71 for (idx=0; idx<count; idx++, data++) {
72 u_int32_t val;
73#ifdef __NetBSD__
74 val=fubyte(data);
75#elif __linux__
76 __get_user(val, (u_int8_t*)data);
77#endif
78 val=(val&0xff)<<((addr&3)<<3);
79 sis1100rawwritereg(sc, t_dal, val);
80 }
81 } else {
82 for (idx=0; idx<count; idx++, data++, addr++) {
83 u_int32_t val;
84#ifdef __NetBSD__
85 val=fubyte(data);
86#elif __linux__
87 __get_user(val, (u_int8_t*)data);
88#endif
89 val=(val&0xff)<<((addr&3)<<3);
90 sis1100writereg(sc, t_hdr, head|(0x01000000<<(addr&3)));
91 sis1100writereg(sc, t_adl, addr);
92 sis1100rawwritereg(sc, t_dal, val);
93 }
94 }
95 break;
96 case 2:
97 if (fifo_mode) {
98 sis1100writereg(sc, t_adl, addr);
99 sis1100writereg(sc, t_hdr, head|(0x03000000<<(addr&3)));
100 for (idx=0; idx<count; idx++, data+=2) {
101 u_int32_t val;
102#ifdef __NetBSD__
103 val=fusword(data);
104#elif __linux__
105 __get_user(val, (u_int16_t*)data);
106#endif
107 val=(val&0xffff)<<((addr&3)<<3);
108 sis1100rawwritereg(sc, t_dal, val);
109 }
110 } else {
111 for (idx=0; idx<count; idx++, data+=2, addr+=2) {
112 u_int32_t val;
113#ifdef __NetBSD__
114 val=fusword(data);
115#elif __linux__
116 __get_user(val, (u_int16_t*)data);
117#endif
118 val=(val&0xffff)<<((addr&3)<<3);
119 sis1100writereg(sc, t_hdr, head|(0x03000000<<(addr&3)));
120 sis1100writereg(sc, t_adl, addr);
121 sis1100rawwritereg(sc, t_dal, val);
122 }
123 }
124 break;
125 case 4:
126 sis1100writereg(sc, t_hdr, head|0x0f000000);
127 if (fifo_mode) {
128 sis1100writereg(sc, t_adl, addr);
129 for (idx=0; idx<count; idx++, data+=4) {
130 u_int32_t val;
131#ifdef __NetBSD__
132 val=fuword(data);
133#elif __linux__
134 __get_user(val, (u_int32_t*)data);
135#endif
136 sis1100rawwritereg(sc, t_dal, val);
137 }
138 } else {
139 for (idx=0; idx<count; idx++, data+=4, addr+=4) {
140 u_int32_t val;
141#ifdef __NetBSD__
142 val=fuword(data);
143#elif __linux__
144 __get_user(val, (u_int32_t*)data);
145#endif
146 sis1100writereg(sc, t_adl, addr);
147 sis1100writereg(sc, t_dal, val);
148 }
149 }
150 break;
151 }
152
153 do {
154 *prot_error=sis1100readreg(sc, prot_error);
155 } while (*prot_error==0x005);
156
157 SEM_UNLOCK(sc->sem_hw);
158
159 /*
160 This is not really correct, but we don't know how many data
161 have been successfully written before an error occured.
162 */
163 return *prot_error?EIO:0;
164}
Note: See TracBrowser for help on using the repository browser.