source: drsdaq/VME/struck/sis1100/V2.02/dev/pci/sis1100_read.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: 4.5 KB
Line 
1/* $ZEL: sis1100_read.c,v 1.5 2004/05/27 23:10:29 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
31static int
32sis1100_read_irqdata(struct sis1100_softc* sc, struct sis1100_fdata* fd,
33 size_t count, size_t* count_read, void* data, int nonblocking)
34{
35 struct sis1100_irq_ack ack;
36 struct sis1100_irq_get get;
37 int res;
38
39 if (count!=sizeof(struct sis1100_irq_get)) return EINVAL;
40/*
41 if (!nonblocking)
42 pINFO(sc, "read_irqdata: !O_NONBLOCK");
43*/
44 if (nonblocking && !irq_pending(sc, fd, fd->owned_irqs))
45 return EAGAIN;
46
47 get.irq_mask=fd->owned_irqs;
48 res=sis1100_irq_wait(sc, fd, &get);
49 if (res) {
50 pINFO(sc, "read_irqdata: res=%d", res);
51 return res;
52 }
53
54 ack.irq_mask=get.irqs;
55 sis1100_irq_ack(sc, fd, &ack);
56/*
57pINFO(sc, "read_irqdata: irqs=0x%x remote_hw=%d",
58 get.irqs, get.remote_status);
59*/
60 if (
61#ifdef __NetBSD__
62 copyout(&get, data, sizeof(struct sis1100_irq_get))
63#elif __linux__
64 copy_to_user(data, &get, sizeof(struct sis1100_irq_get))
65#endif
66 ) return EFAULT;
67
68 *count_read=sizeof(struct sis1100_irq_get);
69 return 0;
70}
71
72static int
73_sis1100_read(struct sis1100_softc* sc, struct sis1100_fdata* fd,
74 size_t count, size_t* count_read, u_int32_t addr, void* data,
75 int nonblocking)
76{
77 int32_t am;
78 int datasize;
79 int space, fifo;
80 int res;
81/*
82 * pINFO(sc, "read: subdev=%d", fd->subdev);
83 */
84 switch (fd->subdev) {
85 case sis1100_subdev_ram:
86 am=-1;
87 datasize=4;
88 space=6;
89 fifo=0;
90 break;
91 case sis1100_subdev_remote:
92 am=fd->vmespace_am;
93 datasize=fd->vmespace_datasize;
94 space=1;
95 fifo=fd->fifo_mode;
96 break;
97 case sis1100_subdev_ctrl:
98 return sis1100_read_irqdata(sc, fd, count, count_read, data,
99 nonblocking);
100 case sis1100_subdev_dsp:
101 default:
102 /* just to avoid warning: ... might be used uninitialized */
103 am=0;
104 datasize=0;
105 space=0; fifo=0;
106 return ENOTTY;
107 }
108
109 if (count%datasize) return EINVAL;
110
111 res=sis1100_read_block(sc, fd,
112 datasize, fifo, count/datasize, count_read, space, am,
113 addr, data, &fd->last_prot_err);
114 *count_read*=datasize;
115 if (!count_read && (count!=0)) res=EIO;
116 return res;
117}
118
119#ifdef __NetBSD__
120
121int
122sis1100_read(dev_t dev, struct uio* uio, int f)
123{
124 struct sis1100_softc* sc=SIS1100SC(dev);
125 struct sis1100_fdata* fd=SIS1100FD(dev);
126 size_t count, count_read;
127 u_int32_t addr;
128 void* data;
129 int res;
130
131 count=uio->uio_resid;
132 addr=uio->uio_offset;
133 data=uio->uio_iov->iov_base;
134
135 res=_sis1100_read(sc, fd, count, &count_read, addr, data,
136 0 /* XXX O_NONBLOCK !! */);
137 if (!res) uio->uio_resid-=count_read;
138 return res;
139}
140
141#elif __linux__
142
143ssize_t sis1100_read(struct file* file, char* buf, size_t count,
144 loff_t* ppos)
145{
146 struct sis1100_softc* sc=SIS1100SC(file);
147 struct sis1100_fdata* fd=SIS1100FD(file);
148 size_t count_read;
149 int res;
150
151 res=_sis1100_read(sc, fd, count, &count_read, *ppos, buf,
152 file->f_flags&O_NONBLOCK);
153 if (!res) *ppos+=count_read;
154 return res?-res:count_read;
155}
156
157#endif
Note: See TracBrowser for help on using the repository browser.