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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [s390/] [s390dyn.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *  arch/s390/kernel/s390dyn.c
3
 *   S/390 dynamic device attachment
4
 *
5
 *  S390 version
6
 *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
7
 *    Author(s): Ingo Adlung (adlung@de.ibm.com)
8
 */
9
 
10
#include <linux/module.h>
11
#include <linux/init.h>
12
#include <linux/smp_lock.h>
13
 
14
#include <asm/irq.h>
15
#include <asm/s390io.h>
16
#include <asm/s390dyn.h>
17
 
18
static struct list_head devreg_anchor = LIST_HEAD_INIT(devreg_anchor);
19
static spinlock_t  dyn_lock           = SPIN_LOCK_UNLOCKED;
20
 
21
static inline int s390_device_register_internal(devreg_t *drinfo)
22
{
23
        struct list_head *p;
24
 
25
        list_for_each(p, &devreg_anchor) {
26
                devreg_t *pdevreg = list_entry(p, devreg_t, list);
27
 
28
                if (pdevreg == drinfo)
29
                        return -EINVAL;
30
                /*
31
                 * We don't allow multiple drivers to register
32
                 * for the same device number
33
                 */
34
                if (pdevreg->ci.devno == drinfo->ci.devno &&
35
                    (pdevreg->flag & DEVREG_TYPE_DEVNO) &&
36
                    (drinfo->flag & DEVREG_TYPE_DEVNO))
37
                        return -EBUSY;
38
 
39
                if (drinfo->flag == (DEVREG_TYPE_DEVCHARS |
40
                                     DEVREG_EXACT_MATCH) &&
41
                    !memcmp(&drinfo->ci.hc, &pdevreg->ci.hc,
42
                            sizeof(devreg_hc_t)))
43
                        return -EBUSY;
44
        }
45
 
46
        /*
47
         * no collision found, enqueue
48
         */
49
        list_add (&drinfo->list, &devreg_anchor);
50
 
51
        return 0;
52
}
53
 
54
int s390_device_register( devreg_t *drinfo )
55
{
56
        unsigned long flags;
57
        int ret;
58
 
59
        if (drinfo == NULL ||
60
            !(drinfo->flag & (DEVREG_TYPE_DEVNO | DEVREG_TYPE_DEVCHARS)))
61
                return -EINVAL;
62
 
63
        spin_lock_irqsave (&dyn_lock, flags);
64
        ret = s390_device_register_internal(drinfo);
65
        spin_unlock_irqrestore( &dyn_lock, flags );
66
 
67
        return ret;
68
}
69
 
70
static inline int s390_device_unregister_internal(devreg_t *dreg)
71
{
72
        struct list_head *p;
73
 
74
        list_for_each(p, &devreg_anchor) {
75
                devreg_t *pdevreg = list_entry(p, devreg_t, list);
76
 
77
                if (pdevreg == dreg) {
78
                        list_del (&dreg->list);
79
                        return 0;
80
                }
81
        }
82
        return -EINVAL;
83
}
84
 
85
int s390_device_unregister(devreg_t *dreg)
86
{
87
        unsigned long  flags;
88
        int ret;
89
 
90
        if (dreg == NULL)
91
                return -EINVAL;
92
 
93
        spin_lock_irqsave(&dyn_lock, flags);
94
        ret = s390_device_unregister_internal(dreg);
95
        spin_unlock_irqrestore(&dyn_lock, flags);
96
 
97
        return ret;
98
}
99
 
100
static inline devreg_t *s390_search_devreg_internal(ioinfo_t *ioinfo)
101
{
102
        struct list_head *p;
103
 
104
        list_for_each(p, &devreg_anchor) {
105
                devreg_t *pdevreg = list_entry(p, devreg_t, list);
106
                senseid_t *sid;
107
                int flag;
108
 
109
                flag = pdevreg->flag;
110
                sid = &ioinfo->senseid;
111
                if (flag & DEVREG_TYPE_DEVNO) {
112
                        if (ioinfo->ui.flags.dval != 1 ||
113
                            ioinfo->devno != pdevreg->ci.devno)
114
                                continue;
115
                } else if (flag & DEVREG_TYPE_DEVCHARS) {
116
                        if ( (flag & DEVREG_MATCH_CU_TYPE) &&
117
                             pdevreg->ci.hc.ctype != sid->cu_type )
118
                                continue;
119
                        if ( (flag & DEVREG_MATCH_CU_MODEL) &&
120
                             pdevreg->ci.hc.cmode != sid->cu_model )
121
                                continue;
122
                        if ( (flag & DEVREG_MATCH_DEV_TYPE) &&
123
                             pdevreg->ci.hc.dtype != sid->dev_type )
124
                                continue;
125
                        if ( (flag & DEVREG_MATCH_DEV_MODEL) &&
126
                             pdevreg->ci.hc.dmode != sid->dev_model )
127
                                continue;
128
                } else {
129
                        continue;
130
                }
131
 
132
                return pdevreg;
133
        }
134
        return NULL;
135
}
136
 
137
devreg_t * s390_search_devreg( ioinfo_t *ioinfo )
138
{
139
        unsigned long  flags;
140
        devreg_t *pdevreg;
141
 
142
        if (ioinfo == NULL)
143
                return NULL;
144
 
145
        spin_lock_irqsave(&dyn_lock, flags);
146
        pdevreg = s390_search_devreg_internal(ioinfo);
147
        spin_unlock_irqrestore(&dyn_lock, flags);
148
 
149
        return pdevreg;
150
}
151
 
152
EXPORT_SYMBOL(s390_device_register);
153
EXPORT_SYMBOL(s390_device_unregister);
154
 

powered by: WebSVN 2.1.0

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