Skip to content

Commit 8390726

Browse files
author
Stefan Richter
committed
---
yaml --- r: 206788 b: refs/heads/rpi-3.2.27 c: 9f6d3c4 h: refs/heads/rpi-3.2.27
1 parent 758f85b commit 8390726

File tree

8 files changed

+1653
-2
lines changed

8 files changed

+1653
-2
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/rpi-3.2.27: aed69d2b79bb5af008526998e466da6d0eac7ae5
2+
refs/heads/rpi-3.2.27: 9f6d3c4b76314c40c866a935d78c80fd284768bd

trunk/MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2256,6 +2256,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git
22562256
S: Maintained
22572257
F: drivers/firewire/
22582258
F: include/linux/firewire*.h
2259+
F: tools/firewire/
22592260

22602261
FIRMWARE LOADER (request_firmware)
22612262
S: Orphan

trunk/drivers/firewire/Kconfig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ config FIREWIRE_NOSY
8585
Apple Power Mac G3 blue & white (onboard controller).
8686

8787
To compile this driver as a module, say M here: The module will be
88-
called nosy.
88+
called nosy. Source code of a userspace interface to nosy, called
89+
nosy-dump, can be found in tools/firewire/ of the kernel sources.
8990

9091
If unsure, say N.
9192

trunk/tools/firewire/Makefile

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
version = 0.3
2+
prefix = /usr
3+
4+
CC = gcc
5+
6+
all : nosy-dump
7+
8+
nosy-dump : CFLAGS = -Wall -O2 -g
9+
nosy-dump : CPPFLAGS = -DVERSION=\"$(version)\" -I../../drivers/firewire
10+
nosy-dump : LDFLAGS = -g
11+
nosy-dump : LDLIBS = -lpopt
12+
13+
nosy-dump : nosy-dump.o decode-fcp.o
14+
15+
clean :
16+
rm -rf *.o nosy-dump
17+
18+
install :
19+
install nosy-dump $(prefix)/bin/nosy-dump

trunk/tools/firewire/decode-fcp.c

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
#include <stdlib.h>
2+
#include <stdio.h>
3+
#include "list.h"
4+
#include "nosy-dump.h"
5+
6+
#define CSR_FCP_COMMAND 0xfffff0000b00ull
7+
#define CSR_FCP_RESPONSE 0xfffff0000d00ull
8+
9+
static const char * const ctype_names[16] = {
10+
"control",
11+
"status",
12+
"specific inquiry",
13+
"notify",
14+
"general inquiry",
15+
"(reserved 0x05)",
16+
"(reserved 0x06)",
17+
"(reserved 0x07)",
18+
"not implemented",
19+
"accepted",
20+
"rejected",
21+
"in transition",
22+
"stable",
23+
"changed",
24+
"(reserved 0x0e)",
25+
"interim"
26+
};
27+
28+
static const char * const subunit_type_names[32] = {
29+
"monitor",
30+
"audio",
31+
"printer",
32+
"disc",
33+
"tape recorder/player",
34+
"tuner",
35+
"ca",
36+
"camera",
37+
"(reserved 0x08)",
38+
"panel",
39+
"bulletin board",
40+
"camera storage",
41+
"(reserved 0x0c)",
42+
"(reserved 0x0d)",
43+
"(reserved 0x0e)",
44+
"(reserved 0x0f)",
45+
"(reserved 0x10)",
46+
"(reserved 0x11)",
47+
"(reserved 0x12)",
48+
"(reserved 0x13)",
49+
"(reserved 0x14)",
50+
"(reserved 0x15)",
51+
"(reserved 0x16)",
52+
"(reserved 0x17)",
53+
"(reserved 0x18)",
54+
"(reserved 0x19)",
55+
"(reserved 0x1a)",
56+
"(reserved 0x1b)",
57+
"vendor unique",
58+
"all subunit types",
59+
"subunit_type extended to next byte",
60+
"unit"
61+
};
62+
63+
struct avc_enum {
64+
int value;
65+
const char *name;
66+
};
67+
68+
struct avc_field {
69+
const char *name; /* Short name for field. */
70+
int offset; /* Location of field, specified in bits.
71+
* Negative means from end of packet */
72+
int width; /* Width of field, 0 means use data_length. */
73+
struct avc_enum *names;
74+
};
75+
76+
struct avc_opcode_info {
77+
const char *name;
78+
struct avc_field fields[8];
79+
};
80+
81+
struct avc_enum power_field_names[] = {
82+
{ 0x70, "on" },
83+
{ 0x60, "off" },
84+
{ }
85+
};
86+
87+
static const struct avc_opcode_info opcode_info[256] = {
88+
89+
/* TA Document 1999026
90+
* AV/C Digital Interface Command Set General Specification
91+
* Version 4.0 */
92+
[0xb2] =
93+
{ "power", {
94+
{ "state", 0, 8, power_field_names }
95+
}
96+
},
97+
[0x30] =
98+
{ "unit info", {
99+
{ "foo", 0, 8 },
100+
{ "unit_type", 8, 5 },
101+
{ "unit", 13, 3 },
102+
{ "company id", 16, 24 },
103+
}
104+
},
105+
[0x31] = { "subunit info" },
106+
[0x01] = { "reserve" },
107+
[0xb0] = { "version" },
108+
[0x00] = { "vendor dependent" },
109+
110+
[0x02] = { "plug info" },
111+
[0x12] = { "channel usage" },
112+
[0x24] = { "connect" },
113+
[0x20] = { "connect av" },
114+
[0x22] = { "connections" },
115+
[0x11] = { "digital input" },
116+
[0x10] = { "digital output" },
117+
[0x25] = { "disconnect" },
118+
[0x21] = { "disconnect av" },
119+
[0x19] = { "input plug signal format" },
120+
[0x18] = { "output plug signal format" },
121+
[0x1f] = { "general bus setup" },
122+
123+
/* TA Document 1999025
124+
* AV/C Descriptor Mechanism Specification Version 1.0 */
125+
[0x0c] = { "create descriptor" },
126+
[0x08] = { "open descriptor" },
127+
[0x09] = { "read descriptor" },
128+
[0x0a] = { "write descriptor" },
129+
[0x05] = { "open info block" },
130+
[0x06] = { "read info block" },
131+
[0x07] = { "write info block" },
132+
[0x0b] = { "search descriptor" },
133+
[0x0d] = { "object number select" },
134+
135+
/* TA Document 1999015
136+
* AV/C Command Set for Rate Control of Isochronous Data Flow 1.0 */
137+
[0xb3] = { "rate", {
138+
{ "subfunction", 0, 8 },
139+
{ "result", 8, 8 },
140+
{ "plug_type", 16, 8 },
141+
{ "plug_id", 16, 8 },
142+
}
143+
},
144+
145+
/* TA Document 1999008
146+
* AV/C Audio Subunit Specification 1.0 */
147+
[0xb8] = { "function block" },
148+
149+
/* TA Document 2001001
150+
* AV/C Panel Subunit Specification 1.1 */
151+
[0x7d] = { "gui update" },
152+
[0x7e] = { "push gui data" },
153+
[0x7f] = { "user action" },
154+
[0x7c] = { "pass through" },
155+
156+
/* */
157+
[0x26] = { "asynchronous connection" },
158+
};
159+
160+
struct avc_frame {
161+
unsigned int operand0 : 8;
162+
unsigned int opcode : 8;
163+
unsigned int subunit_id : 3;
164+
unsigned int subunit_type : 5;
165+
unsigned int ctype : 4;
166+
unsigned int cts : 4;
167+
};
168+
169+
static void
170+
decode_avc(struct link_transaction *t)
171+
{
172+
struct avc_frame *frame = (struct avc_frame *) t->request->packet.write_block.data;
173+
const struct avc_opcode_info *info;
174+
const char *name;
175+
char buffer[32];
176+
int i;
177+
178+
info = &opcode_info[frame->opcode];
179+
if (info->name == NULL) {
180+
snprintf(buffer, sizeof buffer, "(unknown opcode 0x%02x)", frame->opcode);
181+
name = buffer;
182+
} else {
183+
name = info->name;
184+
}
185+
186+
printf("av/c %s, subunit_type=%s, subunit_id=%d, opcode=%s",
187+
ctype_names[frame->ctype], subunit_type_names[frame->subunit_type],
188+
frame->subunit_id, name);
189+
190+
for (i = 0; info->fields[i].name != NULL; i++) {
191+
printf(", %s", info->fields[i].name);
192+
}
193+
194+
printf("\n");
195+
}
196+
197+
198+
int
199+
decode_fcp(struct link_transaction *t)
200+
{
201+
struct avc_frame *frame = (struct avc_frame *) t->request->packet.write_block.data;
202+
unsigned long long offset;
203+
204+
offset = ((unsigned long long) t->request->packet.common.offset_high << 32) |
205+
t->request->packet.common.offset_low;
206+
207+
if (t->request->packet.common.tcode != TCODE_WRITE_BLOCK)
208+
return 0;
209+
210+
if (offset == CSR_FCP_COMMAND || offset == CSR_FCP_RESPONSE) {
211+
switch (frame->cts) {
212+
case 0x00:
213+
decode_avc(t);
214+
break;
215+
case 0x01:
216+
printf("cal fcp frame (cts=0x01)\n");
217+
break;
218+
case 0x02:
219+
printf("ehs fcp frame (cts=0x02)\n");
220+
break;
221+
case 0x03:
222+
printf("havi fcp frame (cts=0x03)\n");
223+
break;
224+
case 0x0e:
225+
printf("vendor specific fcp frame (cts=0x0e)\n");
226+
break;
227+
case 0x0f:
228+
printf("extended cts\n");
229+
break;
230+
default:
231+
printf("reserved fcp frame (ctx=0x%02x)\n", frame->cts);
232+
break;
233+
}
234+
return 1;
235+
}
236+
237+
return 0;
238+
}
239+

trunk/tools/firewire/list.h

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
struct list {
2+
struct list *next, *prev;
3+
};
4+
5+
static inline void
6+
list_init(struct list *list)
7+
{
8+
list->next = list;
9+
list->prev = list;
10+
}
11+
12+
static inline int
13+
list_empty(struct list *list)
14+
{
15+
return list->next == list;
16+
}
17+
18+
static inline void
19+
list_insert(struct list *link, struct list *new_link)
20+
{
21+
new_link->prev = link->prev;
22+
new_link->next = link;
23+
new_link->prev->next = new_link;
24+
new_link->next->prev = new_link;
25+
}
26+
27+
static inline void
28+
list_append(struct list *list, struct list *new_link)
29+
{
30+
list_insert((struct list *)list, new_link);
31+
}
32+
33+
static inline void
34+
list_prepend(struct list *list, struct list *new_link)
35+
{
36+
list_insert(list->next, new_link);
37+
}
38+
39+
static inline void
40+
list_remove(struct list *link)
41+
{
42+
link->prev->next = link->next;
43+
link->next->prev = link->prev;
44+
}
45+
46+
#define list_entry(link, type, member) \
47+
((type *)((char *)(link)-(unsigned long)(&((type *)0)->member)))
48+
49+
#define list_head(list, type, member) \
50+
list_entry((list)->next, type, member)
51+
52+
#define list_tail(list, type, member) \
53+
list_entry((list)->prev, type, member)
54+
55+
#define list_next(elm, member) \
56+
list_entry((elm)->member.next, typeof(*elm), member)
57+
58+
#define list_for_each_entry(pos, list, member) \
59+
for (pos = list_head(list, typeof(*pos), member); \
60+
&pos->member != (list); \
61+
pos = list_next(pos, member))
62+

0 commit comments

Comments
 (0)