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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
/*
* libraw1394 - library for raw access to the 1394 bus with the Linux subsystem.
*
* Copyright (C) 1999,2000 Andreas Bombe
*
* This library is licensed under the GNU Lesser General Public License (LGPL),
* version 2.1 or later. See the file COPYING.LIB in the distribution for
* details.
*/
#include <config.h>
#include <unistd.h>
#include <errno.h>
#include "raw1394.h"
#include "kernel-raw1394.h"
#include "raw1394_private.h"
int raw1394_start_read(struct raw1394_handle *handle, nodeid_t node,
nodeaddr_t addr, size_t length, quadlet_t *buffer,
unsigned long tag)
{
struct raw1394_request *req = &handle->req;
CLEAR_REQ(req);
req->type = RAW1394_REQ_ASYNC_READ;
req->generation = handle->generation;
req->tag = tag;
req->address = ((__u64)node << 48) | addr;
req->length = length;
req->recvb = ptr2int(buffer);
return (int)write(handle->fd, req, sizeof(*req));
}
int raw1394_start_write(struct raw1394_handle *handle, nodeid_t node,
nodeaddr_t addr, size_t length, quadlet_t *data,
unsigned long tag)
{
struct raw1394_request *req = &handle->req;
CLEAR_REQ(req);
req->type = RAW1394_REQ_ASYNC_WRITE;
req->generation = handle->generation;
req->tag = tag;
req->address = ((__u64)node << 48) | addr;
req->length = length;
req->sendb = ptr2int(data);
return (int)write(handle->fd, req, sizeof(*req));
}
int raw1394_start_lock(struct raw1394_handle *handle, nodeid_t node,
nodeaddr_t addr, unsigned int extcode, quadlet_t data,
quadlet_t arg, quadlet_t *result, unsigned long tag)
{
struct raw1394_request *req = &handle->req;
quadlet_t sendbuf[2];
if ((extcode > 7) || (extcode == 0)) {
errno = EINVAL;
return -1;
}
CLEAR_REQ(req);
req->type = RAW1394_REQ_LOCK;
req->generation = handle->generation;
req->tag = tag;
req->address = ((__u64)node << 48) | addr;
req->sendb = ptr2int(sendbuf);
req->recvb = ptr2int(result);
req->misc = extcode;
switch (extcode) {
case 3: /* EXTCODE_FETCH_ADD */
case 4: /* EXTCODE_LITTLE_ADD */
sendbuf[0] = data;
req->length = 4;
break;
default:
sendbuf[0] = arg;
sendbuf[1] = data;
req->length = 8;
break;
}
return (int)write(handle->fd, req, sizeof(*req));
}
int raw1394_start_iso_write(struct raw1394_handle *handle, unsigned int channel,
unsigned int tag, unsigned int sy,
unsigned int speed, size_t length, quadlet_t *data,
unsigned long rawtag)
{
struct raw1394_request *req = &handle->req;
CLEAR_REQ(req);
req->type = RAW1394_REQ_ISO_SEND;
req->generation = handle->generation;
req->tag = tag;
req->address = ((__u64)channel << 48) | speed;
req->misc = (tag << 16) | sy;
req->length = length;
req->sendb = ptr2int(data);
return (int)write(handle->fd, req, sizeof(*req));
}
#define SYNCFUNC_VARS \
struct sync_cb_data sd = { 0, 0 }; \
struct raw1394_reqhandle rh = { (req_callback_t)_raw1394_sync_cb, \
&sd }; \
int err
#define SYNCFUNC_BODY \
while (!sd.done) { \
if (err < 0) return err; \
err = raw1394_loop_iterate(handle); \
} \
return sd.errcode
int raw1394_read(struct raw1394_handle *handle, nodeid_t node, nodeaddr_t addr,
size_t length, quadlet_t *buffer)
{
SYNCFUNC_VARS;
err = raw1394_start_read(handle, node, addr, length, buffer,
(unsigned long)&rh);
SYNCFUNC_BODY;
}
int raw1394_write(struct raw1394_handle *handle, nodeid_t node, nodeaddr_t addr,
size_t length, quadlet_t *data)
{
SYNCFUNC_VARS;
err = raw1394_start_write(handle, node, addr, length, data,
(unsigned long)&rh);
SYNCFUNC_BODY;
}
int raw1394_lock(struct raw1394_handle *handle, nodeid_t node, nodeaddr_t addr,
unsigned int extcode, quadlet_t data, quadlet_t arg,
quadlet_t *result)
{
SYNCFUNC_VARS;
err = raw1394_start_lock(handle, node, addr, extcode, data, arg, result,
(unsigned long)&rh);
SYNCFUNC_BODY;
}
int raw1394_iso_write(struct raw1394_handle *handle, unsigned int channel,
unsigned int tag, unsigned int sy, unsigned int speed,
size_t length, quadlet_t *data)
{
SYNCFUNC_VARS;
err = raw1394_start_iso_write(handle, channel, tag, sy, speed, length,
data, (unsigned long)&rh);
SYNCFUNC_BODY;
}
#undef SYNCFUNC_VARS
#undef SYNCFUNC_BODY
|