OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [pnp/] [interface.c] - Blame information for rev 65

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * interface.c - contains everything related to the user interface
3
 *
4
 * Some code, especially possible resource dumping is based on isapnp_proc.c (c) Jaroslav Kysela <perex@perex.cz>
5
 * Copyright 2002 Adam Belay <ambx1@neo.rr.com>
6
 */
7
 
8
#include <linux/pnp.h>
9
#include <linux/string.h>
10
#include <linux/errno.h>
11
#include <linux/list.h>
12
#include <linux/types.h>
13
#include <linux/stat.h>
14
#include <linux/ctype.h>
15
#include <linux/slab.h>
16
#include <asm/uaccess.h>
17
 
18
#include "base.h"
19
 
20
struct pnp_info_buffer {
21
        char *buffer;           /* pointer to begin of buffer */
22
        char *curr;             /* current position in buffer */
23
        unsigned long size;     /* current size */
24
        unsigned long len;      /* total length of buffer */
25
        int stop;               /* stop flag */
26
        int error;              /* error code */
27
};
28
 
29
typedef struct pnp_info_buffer pnp_info_buffer_t;
30
 
31
static int pnp_printf(pnp_info_buffer_t * buffer, char *fmt, ...)
32
{
33
        va_list args;
34
        int res;
35
 
36
        if (buffer->stop || buffer->error)
37
                return 0;
38
        va_start(args, fmt);
39
        res = vsnprintf(buffer->curr, buffer->len - buffer->size, fmt, args);
40
        va_end(args);
41
        if (buffer->size + res >= buffer->len) {
42
                buffer->stop = 1;
43
                return 0;
44
        }
45
        buffer->curr += res;
46
        buffer->size += res;
47
        return res;
48
}
49
 
50
static void pnp_print_port(pnp_info_buffer_t * buffer, char *space,
51
                           struct pnp_port *port)
52
{
53
        pnp_printf(buffer,
54
                   "%sport 0x%x-0x%x, align 0x%x, size 0x%x, %i-bit address decoding\n",
55
                   space, port->min, port->max,
56
                   port->align ? (port->align - 1) : 0, port->size,
57
                   port->flags & PNP_PORT_FLAG_16BITADDR ? 16 : 10);
58
}
59
 
60
static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
61
                          struct pnp_irq *irq)
62
{
63
        int first = 1, i;
64
 
65
        pnp_printf(buffer, "%sirq ", space);
66
        for (i = 0; i < PNP_IRQ_NR; i++)
67
                if (test_bit(i, irq->map)) {
68
                        if (!first) {
69
                                pnp_printf(buffer, ",");
70
                        } else {
71
                                first = 0;
72
                        }
73
                        if (i == 2 || i == 9)
74
                                pnp_printf(buffer, "2/9");
75
                        else
76
                                pnp_printf(buffer, "%i", i);
77
                }
78
        if (bitmap_empty(irq->map, PNP_IRQ_NR))
79
                pnp_printf(buffer, "<none>");
80
        if (irq->flags & IORESOURCE_IRQ_HIGHEDGE)
81
                pnp_printf(buffer, " High-Edge");
82
        if (irq->flags & IORESOURCE_IRQ_LOWEDGE)
83
                pnp_printf(buffer, " Low-Edge");
84
        if (irq->flags & IORESOURCE_IRQ_HIGHLEVEL)
85
                pnp_printf(buffer, " High-Level");
86
        if (irq->flags & IORESOURCE_IRQ_LOWLEVEL)
87
                pnp_printf(buffer, " Low-Level");
88
        pnp_printf(buffer, "\n");
89
}
90
 
91
static void pnp_print_dma(pnp_info_buffer_t * buffer, char *space,
92
                          struct pnp_dma *dma)
93
{
94
        int first = 1, i;
95
        char *s;
96
 
97
        pnp_printf(buffer, "%sdma ", space);
98
        for (i = 0; i < 8; i++)
99
                if (dma->map & (1 << i)) {
100
                        if (!first) {
101
                                pnp_printf(buffer, ",");
102
                        } else {
103
                                first = 0;
104
                        }
105
                        pnp_printf(buffer, "%i", i);
106
                }
107
        if (!dma->map)
108
                pnp_printf(buffer, "<none>");
109
        switch (dma->flags & IORESOURCE_DMA_TYPE_MASK) {
110
        case IORESOURCE_DMA_8BIT:
111
                s = "8-bit";
112
                break;
113
        case IORESOURCE_DMA_8AND16BIT:
114
                s = "8-bit&16-bit";
115
                break;
116
        default:
117
                s = "16-bit";
118
        }
119
        pnp_printf(buffer, " %s", s);
120
        if (dma->flags & IORESOURCE_DMA_MASTER)
121
                pnp_printf(buffer, " master");
122
        if (dma->flags & IORESOURCE_DMA_BYTE)
123
                pnp_printf(buffer, " byte-count");
124
        if (dma->flags & IORESOURCE_DMA_WORD)
125
                pnp_printf(buffer, " word-count");
126
        switch (dma->flags & IORESOURCE_DMA_SPEED_MASK) {
127
        case IORESOURCE_DMA_TYPEA:
128
                s = "type-A";
129
                break;
130
        case IORESOURCE_DMA_TYPEB:
131
                s = "type-B";
132
                break;
133
        case IORESOURCE_DMA_TYPEF:
134
                s = "type-F";
135
                break;
136
        default:
137
                s = "compatible";
138
                break;
139
        }
140
        pnp_printf(buffer, " %s\n", s);
141
}
142
 
143
static void pnp_print_mem(pnp_info_buffer_t * buffer, char *space,
144
                          struct pnp_mem *mem)
145
{
146
        char *s;
147
 
148
        pnp_printf(buffer, "%sMemory 0x%x-0x%x, align 0x%x, size 0x%x",
149
                   space, mem->min, mem->max, mem->align, mem->size);
150
        if (mem->flags & IORESOURCE_MEM_WRITEABLE)
151
                pnp_printf(buffer, ", writeable");
152
        if (mem->flags & IORESOURCE_MEM_CACHEABLE)
153
                pnp_printf(buffer, ", cacheable");
154
        if (mem->flags & IORESOURCE_MEM_RANGELENGTH)
155
                pnp_printf(buffer, ", range-length");
156
        if (mem->flags & IORESOURCE_MEM_SHADOWABLE)
157
                pnp_printf(buffer, ", shadowable");
158
        if (mem->flags & IORESOURCE_MEM_EXPANSIONROM)
159
                pnp_printf(buffer, ", expansion ROM");
160
        switch (mem->flags & IORESOURCE_MEM_TYPE_MASK) {
161
        case IORESOURCE_MEM_8BIT:
162
                s = "8-bit";
163
                break;
164
        case IORESOURCE_MEM_8AND16BIT:
165
                s = "8-bit&16-bit";
166
                break;
167
        case IORESOURCE_MEM_32BIT:
168
                s = "32-bit";
169
                break;
170
        default:
171
                s = "16-bit";
172
        }
173
        pnp_printf(buffer, ", %s\n", s);
174
}
175
 
176
static void pnp_print_option(pnp_info_buffer_t * buffer, char *space,
177
                             struct pnp_option *option, int dep)
178
{
179
        char *s;
180
        struct pnp_port *port;
181
        struct pnp_irq *irq;
182
        struct pnp_dma *dma;
183
        struct pnp_mem *mem;
184
 
185
        if (dep) {
186
                switch (option->priority) {
187
                case PNP_RES_PRIORITY_PREFERRED:
188
                        s = "preferred";
189
                        break;
190
                case PNP_RES_PRIORITY_ACCEPTABLE:
191
                        s = "acceptable";
192
                        break;
193
                case PNP_RES_PRIORITY_FUNCTIONAL:
194
                        s = "functional";
195
                        break;
196
                default:
197
                        s = "invalid";
198
                }
199
                pnp_printf(buffer, "Dependent: %02i - Priority %s\n", dep, s);
200
        }
201
 
202
        for (port = option->port; port; port = port->next)
203
                pnp_print_port(buffer, space, port);
204
        for (irq = option->irq; irq; irq = irq->next)
205
                pnp_print_irq(buffer, space, irq);
206
        for (dma = option->dma; dma; dma = dma->next)
207
                pnp_print_dma(buffer, space, dma);
208
        for (mem = option->mem; mem; mem = mem->next)
209
                pnp_print_mem(buffer, space, mem);
210
}
211
 
212
static ssize_t pnp_show_options(struct device *dmdev,
213
                                struct device_attribute *attr, char *buf)
214
{
215
        struct pnp_dev *dev = to_pnp_dev(dmdev);
216
        struct pnp_option *independent = dev->independent;
217
        struct pnp_option *dependent = dev->dependent;
218
        int ret, dep = 1;
219
 
220
        pnp_info_buffer_t *buffer = (pnp_info_buffer_t *)
221
            pnp_alloc(sizeof(pnp_info_buffer_t));
222
        if (!buffer)
223
                return -ENOMEM;
224
 
225
        buffer->len = PAGE_SIZE;
226
        buffer->buffer = buf;
227
        buffer->curr = buffer->buffer;
228
        if (independent)
229
                pnp_print_option(buffer, "", independent, 0);
230
 
231
        while (dependent) {
232
                pnp_print_option(buffer, "   ", dependent, dep);
233
                dependent = dependent->next;
234
                dep++;
235
        }
236
        ret = (buffer->curr - buf);
237
        kfree(buffer);
238
        return ret;
239
}
240
 
241
static DEVICE_ATTR(options, S_IRUGO, pnp_show_options, NULL);
242
 
243
static ssize_t pnp_show_current_resources(struct device *dmdev,
244
                                          struct device_attribute *attr,
245
                                          char *buf)
246
{
247
        struct pnp_dev *dev = to_pnp_dev(dmdev);
248
        int i, ret;
249
        pnp_info_buffer_t *buffer;
250
 
251
        if (!dev)
252
                return -EINVAL;
253
 
254
        buffer = (pnp_info_buffer_t *) pnp_alloc(sizeof(pnp_info_buffer_t));
255
        if (!buffer)
256
                return -ENOMEM;
257
        buffer->len = PAGE_SIZE;
258
        buffer->buffer = buf;
259
        buffer->curr = buffer->buffer;
260
 
261
        pnp_printf(buffer, "state = ");
262
        if (dev->active)
263
                pnp_printf(buffer, "active\n");
264
        else
265
                pnp_printf(buffer, "disabled\n");
266
 
267
        for (i = 0; i < PNP_MAX_PORT; i++) {
268
                if (pnp_port_valid(dev, i)) {
269
                        pnp_printf(buffer, "io");
270
                        if (pnp_port_flags(dev, i) & IORESOURCE_DISABLED)
271
                                pnp_printf(buffer, " disabled\n");
272
                        else
273
                                pnp_printf(buffer, " 0x%llx-0x%llx\n",
274
                                           (unsigned long long)
275
                                           pnp_port_start(dev, i),
276
                                           (unsigned long long)pnp_port_end(dev,
277
                                                                            i));
278
                }
279
        }
280
        for (i = 0; i < PNP_MAX_MEM; i++) {
281
                if (pnp_mem_valid(dev, i)) {
282
                        pnp_printf(buffer, "mem");
283
                        if (pnp_mem_flags(dev, i) & IORESOURCE_DISABLED)
284
                                pnp_printf(buffer, " disabled\n");
285
                        else
286
                                pnp_printf(buffer, " 0x%llx-0x%llx\n",
287
                                           (unsigned long long)
288
                                           pnp_mem_start(dev, i),
289
                                           (unsigned long long)pnp_mem_end(dev,
290
                                                                           i));
291
                }
292
        }
293
        for (i = 0; i < PNP_MAX_IRQ; i++) {
294
                if (pnp_irq_valid(dev, i)) {
295
                        pnp_printf(buffer, "irq");
296
                        if (pnp_irq_flags(dev, i) & IORESOURCE_DISABLED)
297
                                pnp_printf(buffer, " disabled\n");
298
                        else
299
                                pnp_printf(buffer, " %lld\n",
300
                                           (unsigned long long)pnp_irq(dev, i));
301
                }
302
        }
303
        for (i = 0; i < PNP_MAX_DMA; i++) {
304
                if (pnp_dma_valid(dev, i)) {
305
                        pnp_printf(buffer, "dma");
306
                        if (pnp_dma_flags(dev, i) & IORESOURCE_DISABLED)
307
                                pnp_printf(buffer, " disabled\n");
308
                        else
309
                                pnp_printf(buffer, " %lld\n",
310
                                           (unsigned long long)pnp_dma(dev, i));
311
                }
312
        }
313
        ret = (buffer->curr - buf);
314
        kfree(buffer);
315
        return ret;
316
}
317
 
318
extern struct semaphore pnp_res_mutex;
319
 
320
static ssize_t
321
pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
322
                          const char *ubuf, size_t count)
323
{
324
        struct pnp_dev *dev = to_pnp_dev(dmdev);
325
        char *buf = (void *)ubuf;
326
        int retval = 0;
327
 
328
        if (dev->status & PNP_ATTACHED) {
329
                retval = -EBUSY;
330
                dev_info(&dev->dev, "in use; can't configure\n");
331
                goto done;
332
        }
333
 
334
        while (isspace(*buf))
335
                ++buf;
336
        if (!strnicmp(buf, "disable", 7)) {
337
                retval = pnp_disable_dev(dev);
338
                goto done;
339
        }
340
        if (!strnicmp(buf, "activate", 8)) {
341
                retval = pnp_activate_dev(dev);
342
                goto done;
343
        }
344
        if (!strnicmp(buf, "fill", 4)) {
345
                if (dev->active)
346
                        goto done;
347
                retval = pnp_auto_config_dev(dev);
348
                goto done;
349
        }
350
        if (!strnicmp(buf, "auto", 4)) {
351
                if (dev->active)
352
                        goto done;
353
                pnp_init_resource_table(&dev->res);
354
                retval = pnp_auto_config_dev(dev);
355
                goto done;
356
        }
357
        if (!strnicmp(buf, "clear", 5)) {
358
                if (dev->active)
359
                        goto done;
360
                pnp_init_resource_table(&dev->res);
361
                goto done;
362
        }
363
        if (!strnicmp(buf, "get", 3)) {
364
                down(&pnp_res_mutex);
365
                if (pnp_can_read(dev))
366
                        dev->protocol->get(dev, &dev->res);
367
                up(&pnp_res_mutex);
368
                goto done;
369
        }
370
        if (!strnicmp(buf, "set", 3)) {
371
                int nport = 0, nmem = 0, nirq = 0, ndma = 0;
372
                if (dev->active)
373
                        goto done;
374
                buf += 3;
375
                pnp_init_resource_table(&dev->res);
376
                down(&pnp_res_mutex);
377
                while (1) {
378
                        while (isspace(*buf))
379
                                ++buf;
380
                        if (!strnicmp(buf, "io", 2)) {
381
                                buf += 2;
382
                                while (isspace(*buf))
383
                                        ++buf;
384
                                dev->res.port_resource[nport].start =
385
                                    simple_strtoul(buf, &buf, 0);
386
                                while (isspace(*buf))
387
                                        ++buf;
388
                                if (*buf == '-') {
389
                                        buf += 1;
390
                                        while (isspace(*buf))
391
                                                ++buf;
392
                                        dev->res.port_resource[nport].end =
393
                                            simple_strtoul(buf, &buf, 0);
394
                                } else
395
                                        dev->res.port_resource[nport].end =
396
                                            dev->res.port_resource[nport].start;
397
                                dev->res.port_resource[nport].flags =
398
                                    IORESOURCE_IO;
399
                                nport++;
400
                                if (nport >= PNP_MAX_PORT)
401
                                        break;
402
                                continue;
403
                        }
404
                        if (!strnicmp(buf, "mem", 3)) {
405
                                buf += 3;
406
                                while (isspace(*buf))
407
                                        ++buf;
408
                                dev->res.mem_resource[nmem].start =
409
                                    simple_strtoul(buf, &buf, 0);
410
                                while (isspace(*buf))
411
                                        ++buf;
412
                                if (*buf == '-') {
413
                                        buf += 1;
414
                                        while (isspace(*buf))
415
                                                ++buf;
416
                                        dev->res.mem_resource[nmem].end =
417
                                            simple_strtoul(buf, &buf, 0);
418
                                } else
419
                                        dev->res.mem_resource[nmem].end =
420
                                            dev->res.mem_resource[nmem].start;
421
                                dev->res.mem_resource[nmem].flags =
422
                                    IORESOURCE_MEM;
423
                                nmem++;
424
                                if (nmem >= PNP_MAX_MEM)
425
                                        break;
426
                                continue;
427
                        }
428
                        if (!strnicmp(buf, "irq", 3)) {
429
                                buf += 3;
430
                                while (isspace(*buf))
431
                                        ++buf;
432
                                dev->res.irq_resource[nirq].start =
433
                                    dev->res.irq_resource[nirq].end =
434
                                    simple_strtoul(buf, &buf, 0);
435
                                dev->res.irq_resource[nirq].flags =
436
                                    IORESOURCE_IRQ;
437
                                nirq++;
438
                                if (nirq >= PNP_MAX_IRQ)
439
                                        break;
440
                                continue;
441
                        }
442
                        if (!strnicmp(buf, "dma", 3)) {
443
                                buf += 3;
444
                                while (isspace(*buf))
445
                                        ++buf;
446
                                dev->res.dma_resource[ndma].start =
447
                                    dev->res.dma_resource[ndma].end =
448
                                    simple_strtoul(buf, &buf, 0);
449
                                dev->res.dma_resource[ndma].flags =
450
                                    IORESOURCE_DMA;
451
                                ndma++;
452
                                if (ndma >= PNP_MAX_DMA)
453
                                        break;
454
                                continue;
455
                        }
456
                        break;
457
                }
458
                up(&pnp_res_mutex);
459
                goto done;
460
        }
461
 
462
done:
463
        if (retval < 0)
464
                return retval;
465
        return count;
466
}
467
 
468
static DEVICE_ATTR(resources, S_IRUGO | S_IWUSR,
469
                   pnp_show_current_resources, pnp_set_current_resources);
470
 
471
static ssize_t pnp_show_current_ids(struct device *dmdev,
472
                                    struct device_attribute *attr, char *buf)
473
{
474
        char *str = buf;
475
        struct pnp_dev *dev = to_pnp_dev(dmdev);
476
        struct pnp_id *pos = dev->id;
477
 
478
        while (pos) {
479
                str += sprintf(str, "%s\n", pos->id);
480
                pos = pos->next;
481
        }
482
        return (str - buf);
483
}
484
 
485
static DEVICE_ATTR(id, S_IRUGO, pnp_show_current_ids, NULL);
486
 
487
int pnp_interface_attach_device(struct pnp_dev *dev)
488
{
489
        int rc = device_create_file(&dev->dev, &dev_attr_options);
490
 
491
        if (rc)
492
                goto err;
493
        rc = device_create_file(&dev->dev, &dev_attr_resources);
494
        if (rc)
495
                goto err_opt;
496
        rc = device_create_file(&dev->dev, &dev_attr_id);
497
        if (rc)
498
                goto err_res;
499
 
500
        return 0;
501
 
502
err_res:
503
        device_remove_file(&dev->dev, &dev_attr_resources);
504
err_opt:
505
        device_remove_file(&dev->dev, &dev_attr_options);
506
err:
507
        return rc;
508
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.