Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
macintosh
adb-iop.c
Go to the documentation of this file.
1
/*
2
* I/O Processor (IOP) ADB Driver
3
* Written and (C) 1999 by Joshua M. Thompson (
[email protected]
)
4
* Based on via-cuda.c by Paul Mackerras.
5
*
6
* 1999-07-01 (jmt) - First implementation for new driver architecture.
7
*
8
* 1999-07-31 (jmt) - First working version.
9
*
10
* TODO:
11
*
12
* o Implement SRQ handling.
13
*/
14
15
#include <linux/types.h>
16
#include <linux/kernel.h>
17
#include <
linux/mm.h
>
18
#include <
linux/delay.h
>
19
#include <
linux/init.h
>
20
#include <
linux/proc_fs.h
>
21
22
#include <
asm/macintosh.h
>
23
#include <
asm/macints.h
>
24
#include <
asm/mac_iop.h
>
25
#include <
asm/mac_oss.h
>
26
#include <
asm/adb_iop.h
>
27
28
#include <linux/adb.h>
29
30
/*#define DEBUG_ADB_IOP*/
31
32
extern
void
iop_ism_irq
(
int
,
void
*);
33
34
static
struct
adb_request
*
current_req
;
35
static
struct
adb_request
*last_req;
36
#if 0
37
static
unsigned
char
reply_buff[16];
38
static
unsigned
char
*reply_ptr;
39
#endif
40
41
static
enum
adb_iop_state
{
42
idle
,
43
sending
,
44
awaiting_reply
45
}
adb_iop_state
;
46
47
static
void
adb_iop_start(
void
);
48
static
int
adb_iop_probe(
void
);
49
static
int
adb_iop_init(
void
);
50
static
int
adb_iop_send_request(
struct
adb_request
*,
int
);
51
static
int
adb_iop_write(
struct
adb_request
*);
52
static
int
adb_iop_autopoll(
int
);
53
static
void
adb_iop_poll(
void
);
54
static
int
adb_iop_reset_bus(
void
);
55
56
struct
adb_driver
adb_iop_driver
= {
57
"ISM IOP"
,
58
adb_iop_probe,
59
adb_iop_init,
60
adb_iop_send_request,
61
adb_iop_autopoll,
62
adb_iop_poll,
63
adb_iop_reset_bus
64
};
65
66
static
void
adb_iop_end_req(
struct
adb_request
*
req
,
int
state
)
67
{
68
req->
complete
= 1;
69
current_req = req->
next
;
70
if
(req->
done
) (*req->
done
)(req);
71
adb_iop_state
=
state
;
72
}
73
74
/*
75
* Completion routine for ADB commands sent to the IOP.
76
*
77
* This will be called when a packet has been successfully sent.
78
*/
79
80
static
void
adb_iop_complete(
struct
iop_msg
*
msg
)
81
{
82
struct
adb_request
*
req
;
83
unsigned
long
flags
;
84
85
local_irq_save
(flags);
86
87
req =
current_req
;
88
if
((
adb_iop_state
==
sending
) && req && req->
reply_expected
) {
89
adb_iop_state
=
awaiting_reply
;
90
}
91
92
local_irq_restore
(flags);
93
}
94
95
/*
96
* Listen for ADB messages from the IOP.
97
*
98
* This will be called when unsolicited messages (usually replies to TALK
99
* commands or autopoll packets) are received.
100
*/
101
102
static
void
adb_iop_listen(
struct
iop_msg
*msg)
103
{
104
struct
adb_iopmsg
*amsg = (
struct
adb_iopmsg
*) msg->
message
;
105
struct
adb_request
*req;
106
unsigned
long
flags;
107
#ifdef DEBUG_ADB_IOP
108
int
i
;
109
#
endif
110
111
local_irq_save
(flags);
112
113
req =
current_req
;
114
115
#ifdef DEBUG_ADB_IOP
116
printk
(
"adb_iop_listen %p: rcvd packet, %d bytes: %02X %02X"
, req,
117
(
uint
) amsg->
count
+ 2, (
uint
) amsg->
flags
, (
uint
) amsg->
cmd
);
118
for
(
i
= 0;
i
< amsg->
count
;
i
++)
119
printk
(
" %02X"
, (
uint
) amsg->
data
[
i
]);
120
printk
(
"\n"
);
121
#endif
122
123
/* Handle a timeout. Timeout packets seem to occur even after */
124
/* we've gotten a valid reply to a TALK, so I'm assuming that */
125
/* a "timeout" is actually more like an "end-of-data" signal. */
126
/* We need to send back a timeout packet to the IOP to shut */
127
/* it up, plus complete the current request, if any. */
128
129
if
(amsg->
flags
&
ADB_IOP_TIMEOUT
) {
130
msg->
reply
[0] =
ADB_IOP_TIMEOUT
|
ADB_IOP_AUTOPOLL
;
131
msg->
reply
[1] = 0;
132
msg->
reply
[2] = 0;
133
if
(req && (
adb_iop_state
!=
idle
)) {
134
adb_iop_end_req(req,
idle
);
135
}
136
}
else
{
137
/* TODO: is it possible for more than one chunk of data */
138
/* to arrive before the timeout? If so we need to */
139
/* use reply_ptr here like the other drivers do. */
140
if
((
adb_iop_state
==
awaiting_reply
) &&
141
(amsg->
flags
&
ADB_IOP_EXPLICIT
)) {
142
req->
reply_len
= amsg->
count
+ 1;
143
memcpy
(req->
reply
, &amsg->
cmd
, req->
reply_len
);
144
}
else
{
145
adb_input
(&amsg->
cmd
, amsg->
count
+ 1,
146
amsg->
flags
&
ADB_IOP_AUTOPOLL
);
147
}
148
memcpy
(msg->
reply
, msg->
message
,
IOP_MSG_LEN
);
149
}
150
iop_complete_message
(msg);
151
local_irq_restore
(flags);
152
}
153
154
/*
155
* Start sending an ADB packet, IOP style
156
*
157
* There isn't much to do other than hand the packet over to the IOP
158
* after encapsulating it in an adb_iopmsg.
159
*/
160
161
static
void
adb_iop_start(
void
)
162
{
163
unsigned
long
flags
;
164
struct
adb_request
*
req
;
165
struct
adb_iopmsg
amsg;
166
#ifdef DEBUG_ADB_IOP
167
int
i
;
168
#endif
169
170
/* get the packet to send */
171
req =
current_req
;
172
if
(!req)
return
;
173
174
local_irq_save
(flags);
175
176
#ifdef DEBUG_ADB_IOP
177
printk
(
"adb_iop_start %p: sending packet, %d bytes:"
, req, req->
nbytes
);
178
for
(i = 0 ; i < req->
nbytes
; i++)
179
printk
(
" %02X"
, (
uint
) req->
data
[i]);
180
printk
(
"\n"
);
181
#endif
182
183
/* The IOP takes MacII-style packets, so */
184
/* strip the initial ADB_PACKET byte. */
185
186
amsg.
flags
=
ADB_IOP_EXPLICIT
;
187
amsg.
count
= req->
nbytes
- 2;
188
189
/* amsg.data immediately follows amsg.cmd, effectively making */
190
/* amsg.cmd a pointer to the beginning of a full ADB packet. */
191
memcpy
(&amsg.
cmd
, req->
data
+ 1, req->
nbytes
- 1);
192
193
req->
sent
= 1;
194
adb_iop_state
=
sending
;
195
local_irq_restore
(flags);
196
197
/* Now send it. The IOP manager will call adb_iop_complete */
198
/* when the packet has been sent. */
199
200
iop_send_message
(
ADB_IOP
,
ADB_CHAN
, req,
201
sizeof
(amsg), (
__u8
*) &amsg, adb_iop_complete);
202
}
203
204
int
adb_iop_probe(
void
)
205
{
206
if
(!
iop_ism_present
)
return
-
ENODEV
;
207
return
0;
208
}
209
210
int
adb_iop_init(
void
)
211
{
212
printk
(
"adb: IOP ISM driver v0.4 for Unified ADB.\n"
);
213
iop_listen
(
ADB_IOP
,
ADB_CHAN
, adb_iop_listen,
"ADB"
);
214
return
0;
215
}
216
217
int
adb_iop_send_request(
struct
adb_request
*req,
int
sync
)
218
{
219
int
err
;
220
221
err = adb_iop_write(req);
222
if
(err)
return
err
;
223
224
if
(sync) {
225
while
(!req->
complete
) adb_iop_poll();
226
}
227
return
0;
228
}
229
230
static
int
adb_iop_write(
struct
adb_request
*req)
231
{
232
unsigned
long
flags
;
233
234
if
((req->
nbytes
< 2) || (req->
data
[0] !=
ADB_PACKET
)) {
235
req->
complete
= 1;
236
return
-
EINVAL
;
237
}
238
239
local_irq_save
(flags);
240
241
req->
next
=
NULL
;
242
req->
sent
= 0;
243
req->
complete
= 0;
244
req->
reply_len
= 0;
245
246
if
(current_req != 0) {
247
last_req->
next
=
req
;
248
last_req =
req
;
249
}
else
{
250
current_req =
req
;
251
last_req =
req
;
252
}
253
254
local_irq_restore
(flags);
255
if
(
adb_iop_state
==
idle
) adb_iop_start();
256
return
0;
257
}
258
259
int
adb_iop_autopoll(
int
devs)
260
{
261
/* TODO: how do we enable/disable autopoll? */
262
return
0;
263
}
264
265
void
adb_iop_poll(
void
)
266
{
267
if
(
adb_iop_state
==
idle
) adb_iop_start();
268
iop_ism_irq
(0, (
void
*)
ADB_IOP
);
269
}
270
271
int
adb_iop_reset_bus(
void
)
272
{
273
struct
adb_request
req = {
274
.
reply_expected
= 0,
275
.nbytes = 2,
276
.data = {
ADB_PACKET
, 0 },
277
};
278
279
adb_iop_write(&req);
280
while
(!req.
complete
) {
281
adb_iop_poll();
282
schedule
();
283
}
284
285
return
0;
286
}
Generated on Thu Jan 10 2013 13:43:09 for Linux Kernel by
1.8.2