1d7cd6603SJérôme Duval /*======================================================================
2d7cd6603SJérôme Duval
3d7cd6603SJérôme Duval PCMCIA card configuration register dump
4d7cd6603SJérôme Duval
5d7cd6603SJérôme Duval dump_cisreg.c 1.31 2001/11/30 23:10:17
6d7cd6603SJérôme Duval
7d7cd6603SJérôme Duval The contents of this file are subject to the Mozilla Public
8d7cd6603SJérôme Duval License Version 1.1 (the "License"); you may not use this file
9d7cd6603SJérôme Duval except in compliance with the License. You may obtain a copy of
10d7cd6603SJérôme Duval the License at http://www.mozilla.org/MPL/
11d7cd6603SJérôme Duval
12d7cd6603SJérôme Duval Software distributed under the License is distributed on an "AS
13d7cd6603SJérôme Duval IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14d7cd6603SJérôme Duval implied. See the License for the specific language governing
15d7cd6603SJérôme Duval rights and limitations under the License.
16d7cd6603SJérôme Duval
17d7cd6603SJérôme Duval The initial developer of the original code is David A. Hinds
18d7cd6603SJérôme Duval <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
19d7cd6603SJérôme Duval are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
20d7cd6603SJérôme Duval
21d7cd6603SJérôme Duval Alternatively, the contents of this file may be used under the
22d7cd6603SJérôme Duval terms of the GNU General Public License version 2 (the "GPL"), in
23d7cd6603SJérôme Duval which case the provisions of the GPL are applicable instead of the
24d7cd6603SJérôme Duval above. If you wish to allow the use of your version of this file
25d7cd6603SJérôme Duval only under the terms of the GPL and not to allow others to use
26d7cd6603SJérôme Duval your version of this file under the MPL, indicate your decision
27d7cd6603SJérôme Duval by deleting the provisions above and replace them with the notice
28d7cd6603SJérôme Duval and other provisions required by the GPL. If you do not delete
29d7cd6603SJérôme Duval the provisions above, a recipient may use your version of this
30d7cd6603SJérôme Duval file under either the MPL or the GPL.
31d7cd6603SJérôme Duval
32d7cd6603SJérôme Duval ======================================================================*/
33*bc3955feSIngo Weinhold #if (defined(__BEOS__) || defined(__HAIKU__))
34d7cd6603SJérôme Duval #include <OS.h>
35d7cd6603SJérôme Duval #endif
36d7cd6603SJérôme Duval #include <sys/types.h>
37d7cd6603SJérôme Duval #include <stdio.h>
38d7cd6603SJérôme Duval #include <stdlib.h>
39d7cd6603SJérôme Duval #include <string.h>
40d7cd6603SJérôme Duval #include <unistd.h>
41d7cd6603SJérôme Duval #include <fcntl.h>
42d7cd6603SJérôme Duval #include <errno.h>
43d7cd6603SJérôme Duval #include <sys/time.h>
44d7cd6603SJérôme Duval #include <sys/ioctl.h>
45d7cd6603SJérôme Duval #include <sys/stat.h>
46d7cd6603SJérôme Duval
47d7cd6603SJérôme Duval #include <pcmcia/cs_types.h>
48d7cd6603SJérôme Duval #include <pcmcia/cs.h>
49d7cd6603SJérôme Duval #include <pcmcia/cistpl.h>
50d7cd6603SJérôme Duval #include <pcmcia/cisreg.h>
51d7cd6603SJérôme Duval #include <pcmcia/ds.h>
52d7cd6603SJérôme Duval
53d7cd6603SJérôme Duval /*====================================================================*/
54*bc3955feSIngo Weinhold #if (!defined(__BEOS__) && !defined(__HAIKU__))
55d7cd6603SJérôme Duval static int major = 0;
56d7cd6603SJérôme Duval
lookup_dev(char * name)57d7cd6603SJérôme Duval static int lookup_dev(char *name)
58d7cd6603SJérôme Duval {
59d7cd6603SJérôme Duval FILE *f;
60d7cd6603SJérôme Duval int n;
61d7cd6603SJérôme Duval char s[32], t[32];
62d7cd6603SJérôme Duval
63d7cd6603SJérôme Duval f = fopen("/proc/devices", "r");
64d7cd6603SJérôme Duval if (f == NULL)
65d7cd6603SJérôme Duval return -1;
66d7cd6603SJérôme Duval while (fgets(s, 32, f) != NULL) {
67d7cd6603SJérôme Duval if (sscanf(s, "%d %s", &n, t) == 2)
68d7cd6603SJérôme Duval if (strcmp(name, t) == 0)
69d7cd6603SJérôme Duval break;
70d7cd6603SJérôme Duval }
71d7cd6603SJérôme Duval fclose(f);
72d7cd6603SJérôme Duval if (strcmp(name, t) == 0)
73d7cd6603SJérôme Duval return n;
74d7cd6603SJérôme Duval else
75d7cd6603SJérôme Duval return -1;
76d7cd6603SJérôme Duval }
77d7cd6603SJérôme Duval #endif
78d7cd6603SJérôme Duval
79d7cd6603SJérôme Duval /*====================================================================*/
80d7cd6603SJérôme Duval
open_sock(int sock)81d7cd6603SJérôme Duval static int open_sock(int sock)
82d7cd6603SJérôme Duval {
83*bc3955feSIngo Weinhold #if (defined(__BEOS__) || defined(__HAIKU__))
84d7cd6603SJérôme Duval char fn[B_OS_NAME_LENGTH];
85d7cd6603SJérôme Duval sprintf(fn, "/dev/bus/pcmcia/sock/%d", sock);
86d7cd6603SJérôme Duval return open(fn, O_RDONLY);
87d7cd6603SJérôme Duval #else
88d7cd6603SJérôme Duval static char *paths[] = {
89d7cd6603SJérôme Duval "/var/lib/pcmcia", "/var/run", "/dev", "/tmp", NULL
90d7cd6603SJérôme Duval };
91d7cd6603SJérôme Duval int fd;
92d7cd6603SJérôme Duval char **p, fn[64];
93d7cd6603SJérôme Duval dev_t dev = (major<<8) + sock;
94d7cd6603SJérôme Duval
95d7cd6603SJérôme Duval for (p = paths; *p; p++) {
96d7cd6603SJérôme Duval sprintf(fn, "%s/dc%d", *p, getpid());
97d7cd6603SJérôme Duval if (mknod(fn, (S_IFCHR|S_IREAD|S_IWRITE), dev) == 0) {
98d7cd6603SJérôme Duval fd = open(fn, O_RDONLY);
99d7cd6603SJérôme Duval unlink(fn);
100d7cd6603SJérôme Duval if (fd >= 0)
101d7cd6603SJérôme Duval return fd;
102d7cd6603SJérôme Duval if (errno == ENODEV) break;
103d7cd6603SJérôme Duval }
104d7cd6603SJérôme Duval }
105d7cd6603SJérôme Duval return -1;
106d7cd6603SJérôme Duval #endif
107d7cd6603SJérôme Duval } /* open_sock */
108d7cd6603SJérôme Duval
109d7cd6603SJérôme Duval /*====================================================================*/
110d7cd6603SJérôme Duval
get_reg(int fd,int fn,off_t off)111d7cd6603SJérôme Duval static int get_reg(int fd, int fn, off_t off)
112d7cd6603SJérôme Duval {
113d7cd6603SJérôme Duval ds_ioctl_arg_t arg;
114d7cd6603SJérôme Duval int ret;
115d7cd6603SJérôme Duval
116d7cd6603SJérôme Duval arg.conf_reg.Function = fn;
117d7cd6603SJérôme Duval arg.conf_reg.Action = CS_READ;
118d7cd6603SJérôme Duval arg.conf_reg.Offset = off;
119d7cd6603SJérôme Duval ret = ioctl(fd, DS_ACCESS_CONFIGURATION_REGISTER, &arg);
120d7cd6603SJérôme Duval if (ret != 0) {
121d7cd6603SJérôme Duval printf(" read config register: %s\n\n", strerror(errno));
122d7cd6603SJérôme Duval return -1;
123d7cd6603SJérôme Duval }
124d7cd6603SJérôme Duval return arg.conf_reg.Value;
125d7cd6603SJérôme Duval }
126d7cd6603SJérôme Duval
dump_option(int fd,int fn,int mfc)127d7cd6603SJérôme Duval static int dump_option(int fd, int fn, int mfc)
128d7cd6603SJérôme Duval {
129d7cd6603SJérôme Duval int v = get_reg(fd, fn, CISREG_COR);
130d7cd6603SJérôme Duval
131d7cd6603SJérôme Duval if (v == -1) return -1;
132d7cd6603SJérôme Duval printf(" Configuration option register = %#2.2x\n", v);
133d7cd6603SJérôme Duval printf(" ");
134d7cd6603SJérôme Duval if (v & COR_LEVEL_REQ) printf(" [level_req]");
135d7cd6603SJérôme Duval if (v & COR_SOFT_RESET) printf(" [soft_reset]");
136d7cd6603SJérôme Duval if (mfc) {
137d7cd6603SJérôme Duval if (v & COR_FUNC_ENA) printf(" [func_ena]");
138d7cd6603SJérôme Duval if (v & COR_ADDR_DECODE) printf(" [addr_decode]");
139d7cd6603SJérôme Duval if (v & COR_IREQ_ENA) printf(" [ireq_ena]");
140d7cd6603SJérôme Duval printf(" [index = %#2.2x]\n", v & COR_MFC_CONFIG_MASK);
141d7cd6603SJérôme Duval } else
142d7cd6603SJérôme Duval printf(" [index = %#2.2x]\n", v & COR_CONFIG_MASK);
143d7cd6603SJérôme Duval return 0;
144d7cd6603SJérôme Duval }
145d7cd6603SJérôme Duval
dump_status(int fd,int fn)146d7cd6603SJérôme Duval static void dump_status(int fd, int fn)
147d7cd6603SJérôme Duval {
148d7cd6603SJérôme Duval int v = get_reg(fd, fn, CISREG_CCSR);
149d7cd6603SJérôme Duval
150d7cd6603SJérôme Duval printf(" Card configuration and status register = %#2.2x\n", v);
151d7cd6603SJérôme Duval printf(" ");
152d7cd6603SJérôme Duval if (v & CCSR_INTR_ACK) printf(" [intr_ack]");
153d7cd6603SJérôme Duval if (v & CCSR_INTR_PENDING) printf(" [intr_pending]");
154d7cd6603SJérôme Duval if (v & CCSR_POWER_DOWN) printf(" [power_down]");
155d7cd6603SJérôme Duval if (v & CCSR_AUDIO_ENA) printf(" [audio]");
156d7cd6603SJérôme Duval if (v & CCSR_IOIS8) printf(" [IOis8]");
157d7cd6603SJérôme Duval if (v & CCSR_SIGCHG_ENA) printf(" [sigchg]");
158d7cd6603SJérôme Duval if (v & CCSR_CHANGED) printf(" [changed]");
159d7cd6603SJérôme Duval printf("\n");
160d7cd6603SJérôme Duval }
161d7cd6603SJérôme Duval
dump_pin(int fd,int fn)162d7cd6603SJérôme Duval static void dump_pin(int fd, int fn)
163d7cd6603SJérôme Duval {
164d7cd6603SJérôme Duval int v = get_reg(fd, fn, CISREG_PRR);
165d7cd6603SJérôme Duval
166d7cd6603SJérôme Duval printf(" Pin replacement register = %#2.2x\n", v);
167d7cd6603SJérôme Duval printf(" ");
168d7cd6603SJérôme Duval if (v & PRR_WP_STATUS) printf(" [wp]");
169d7cd6603SJérôme Duval if (v & PRR_READY_STATUS) printf(" [ready]");
170d7cd6603SJérôme Duval if (v & PRR_BVD2_STATUS) printf(" [bvd2]");
171d7cd6603SJérôme Duval if (v & PRR_BVD1_STATUS) printf(" [bvd1]");
172d7cd6603SJérôme Duval if (v & PRR_WP_EVENT) printf(" [wp_event]");
173d7cd6603SJérôme Duval if (v & PRR_READY_EVENT) printf(" [ready_event]");
174d7cd6603SJérôme Duval if (v & PRR_BVD2_EVENT) printf(" [bvd2_event]");
175d7cd6603SJérôme Duval if (v & PRR_BVD1_EVENT) printf(" [bvd1_event]");
176d7cd6603SJérôme Duval printf("\n");
177d7cd6603SJérôme Duval }
178d7cd6603SJérôme Duval
dump_copy(int fd,int fn)179d7cd6603SJérôme Duval static void dump_copy(int fd, int fn)
180d7cd6603SJérôme Duval {
181d7cd6603SJérôme Duval int v = get_reg(fd, fn, CISREG_SCR);
182d7cd6603SJérôme Duval
183d7cd6603SJérôme Duval printf(" Socket and copy register = %#2.2x\n", v);
184d7cd6603SJérôme Duval printf(" [socket = %d] [copy = %d]\n",
185d7cd6603SJérôme Duval v & SCR_SOCKET_NUM,
186d7cd6603SJérôme Duval (v & SCR_COPY_NUM) >> 4);
187d7cd6603SJérôme Duval }
188d7cd6603SJérôme Duval
dump_ext_status(int fd,int fn)189d7cd6603SJérôme Duval static void dump_ext_status(int fd, int fn)
190d7cd6603SJérôme Duval {
191d7cd6603SJérôme Duval int v = get_reg(fd, fn, CISREG_ESR);
192d7cd6603SJérôme Duval printf(" Extended status register = %#2.2x\n", v);
193d7cd6603SJérôme Duval printf(" ");
194d7cd6603SJérôme Duval if (v & ESR_REQ_ATTN_ENA) printf(" [req_attn_ena]");
195d7cd6603SJérôme Duval if (v & ESR_REQ_ATTN) printf(" [req_attn]");
196d7cd6603SJérôme Duval printf("\n");
197d7cd6603SJérôme Duval }
198d7cd6603SJérôme Duval
199d7cd6603SJérôme Duval /*====================================================================*/
200d7cd6603SJérôme Duval
dump_all(int fd,int fn,int mfc,u_int mask)201d7cd6603SJérôme Duval static void dump_all(int fd, int fn, int mfc, u_int mask)
202d7cd6603SJérôme Duval {
203d7cd6603SJérôme Duval int addr;
204d7cd6603SJérôme Duval if (mask & PRESENT_OPTION) {
205d7cd6603SJérôme Duval if (dump_option(fd, fn, mfc) != 0)
206d7cd6603SJérôme Duval return;
207d7cd6603SJérôme Duval }
208d7cd6603SJérôme Duval if (mask & PRESENT_STATUS)
209d7cd6603SJérôme Duval dump_status(fd, fn);
210d7cd6603SJérôme Duval if (mask & PRESENT_PIN_REPLACE)
211d7cd6603SJérôme Duval dump_pin(fd, fn);
212d7cd6603SJérôme Duval if (mask & PRESENT_COPY)
213d7cd6603SJérôme Duval dump_copy(fd, fn);
214d7cd6603SJérôme Duval if (mask & PRESENT_EXT_STATUS)
215d7cd6603SJérôme Duval dump_ext_status(fd, fn);
216d7cd6603SJérôme Duval if (mask & PRESENT_IOBASE_0) {
217d7cd6603SJérôme Duval addr = get_reg(fd, fn, CISREG_IOBASE_0);
218d7cd6603SJérôme Duval addr += get_reg(fd, fn, CISREG_IOBASE_1) << 8;
219d7cd6603SJérôme Duval printf(" IO base = 0x%04x\n", addr);
220d7cd6603SJérôme Duval }
221d7cd6603SJérôme Duval if (mask & PRESENT_IOSIZE)
222d7cd6603SJérôme Duval printf(" IO size = %d\n", get_reg(fd, fn, CISREG_IOSIZE));
223d7cd6603SJérôme Duval if (mask == 0)
224d7cd6603SJérôme Duval printf(" no config registers\n\n");
225d7cd6603SJérôme Duval else
226d7cd6603SJérôme Duval printf("\n");
227d7cd6603SJérôme Duval }
228d7cd6603SJérôme Duval
229d7cd6603SJérôme Duval /*====================================================================*/
230d7cd6603SJérôme Duval
231d7cd6603SJérôme Duval #define MAX_SOCKS 8
232d7cd6603SJérôme Duval
main(int argc,char * argv[])233d7cd6603SJérôme Duval int main(int argc, char *argv[])
234d7cd6603SJérôme Duval {
235d7cd6603SJérôme Duval int i, j, nfn, fd, ret;
236d7cd6603SJérôme Duval u_int mask;
237d7cd6603SJérôme Duval ds_ioctl_arg_t arg;
238d7cd6603SJérôme Duval
239*bc3955feSIngo Weinhold #if (!defined(__BEOS__) && !defined(__HAIKU__))
240d7cd6603SJérôme Duval major = lookup_dev("pcmcia");
241d7cd6603SJérôme Duval if (major < 0) {
242d7cd6603SJérôme Duval fprintf(stderr, "no pcmcia driver in /proc/devices\n");
243d7cd6603SJérôme Duval exit(EXIT_FAILURE);
244d7cd6603SJérôme Duval }
245d7cd6603SJérôme Duval #endif
246d7cd6603SJérôme Duval
247d7cd6603SJérôme Duval for (i = 0; i < MAX_SOCKS; i++) {
248d7cd6603SJérôme Duval fd = open_sock(i);
249d7cd6603SJérôme Duval if (fd < 0) break;
250d7cd6603SJérôme Duval
251d7cd6603SJérôme Duval arg.tuple.TupleDataMax = sizeof(arg.tuple_parse.data);
252d7cd6603SJérôme Duval arg.tuple.Attributes = TUPLE_RETURN_COMMON;
253d7cd6603SJérôme Duval arg.tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
254d7cd6603SJérôme Duval arg.tuple.TupleOffset = 0;
255d7cd6603SJérôme Duval if (ioctl(fd, DS_GET_FIRST_TUPLE, &arg) == 0) {
256d7cd6603SJérôme Duval ioctl(fd, DS_GET_TUPLE_DATA, &arg);
257d7cd6603SJérôme Duval ioctl(fd, DS_PARSE_TUPLE, &arg);
258d7cd6603SJérôme Duval nfn = arg.tuple_parse.parse.longlink_mfc.nfn;
259d7cd6603SJérôme Duval } else {
260d7cd6603SJérôme Duval nfn = 1;
261d7cd6603SJérôme Duval arg.tuple.DesiredTuple = CISTPL_DEVICE;
262d7cd6603SJérôme Duval ret = ioctl(fd, DS_GET_FIRST_TUPLE, &arg);
263d7cd6603SJérôme Duval if (ret != 0) {
264d7cd6603SJérôme Duval if (errno != ENODEV) perror("ioctl()");
265d7cd6603SJérôme Duval continue;
266d7cd6603SJérôme Duval }
267d7cd6603SJérôme Duval }
268d7cd6603SJérôme Duval
269d7cd6603SJérôme Duval arg.tuple.DesiredTuple = CISTPL_CONFIG;
270d7cd6603SJérôme Duval
271d7cd6603SJérôme Duval for (j = 0; j < nfn; j++) {
272d7cd6603SJérôme Duval printf("Socket %d function %d:\n", i, j);
273d7cd6603SJérôme Duval if (ioctl(fd, DS_GET_NEXT_TUPLE, &arg) != 0) {
274d7cd6603SJérôme Duval printf(" no config tuple: %s\n\n", strerror(errno));
275d7cd6603SJérôme Duval continue;
276d7cd6603SJérôme Duval }
277d7cd6603SJérôme Duval ioctl(fd, DS_GET_TUPLE_DATA, &arg);
278d7cd6603SJérôme Duval ioctl(fd, DS_PARSE_TUPLE, &arg);
279d7cd6603SJérôme Duval printf(" Config register base = %#4.4x, mask = %#4.4x\n",
280d7cd6603SJérôme Duval arg.tuple_parse.parse.config.base,
281d7cd6603SJérôme Duval arg.tuple_parse.parse.config.rmask[0]);
282d7cd6603SJérôme Duval mask = arg.tuple_parse.parse.config.rmask[0];
283d7cd6603SJérôme Duval dump_all(fd, j, (nfn > 1), mask);
284d7cd6603SJérôme Duval }
285d7cd6603SJérôme Duval
286d7cd6603SJérôme Duval }
287d7cd6603SJérôme Duval return 0;
288d7cd6603SJérôme Duval }
289