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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [mca/] [mca-legacy.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
/* -*- mode: c; c-basic-offset: 8 -*- */
2
 
3
/*
4
 * MCA bus support functions for legacy (2.4) API.
5
 *
6
 * Legacy API means the API that operates in terms of MCA slot number
7
 *
8
 * (C) 2002 James Bottomley <James.Bottomley@HansenPartnership.com>
9
 *
10
**-----------------------------------------------------------------------------
11
**
12
**  This program is free software; you can redistribute it and/or modify
13
**  it under the terms of the GNU General Public License as published by
14
**  the Free Software Foundation; either version 2 of the License, or
15
**  (at your option) any later version.
16
**
17
**  This program is distributed in the hope that it will be useful,
18
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
19
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
**  GNU General Public License for more details.
21
**
22
**  You should have received a copy of the GNU General Public License
23
**  along with this program; if not, write to the Free Software
24
**  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
**
26
**-----------------------------------------------------------------------------
27
 */
28
 
29
#include <linux/module.h>
30
#include <linux/device.h>
31
#include <linux/mca-legacy.h>
32
#include <asm/io.h>
33
 
34
/* NOTE: This structure is stack allocated */
35
struct mca_find_adapter_info {
36
        int                     id;
37
        int                     slot;
38
        struct mca_device       *mca_dev;
39
};
40
 
41
/* The purpose of this iterator is to loop over all the devices and
42
 * find the one with the smallest slot number that's just greater than
43
 * or equal to the required slot with a matching id */
44
static int mca_find_adapter_callback(struct device *dev, void *data)
45
{
46
        struct mca_find_adapter_info *info = data;
47
        struct mca_device *mca_dev = to_mca_device(dev);
48
 
49
        if(mca_dev->pos_id != info->id)
50
                return 0;
51
 
52
        if(mca_dev->slot < info->slot)
53
                return 0;
54
 
55
        if(!info->mca_dev || info->mca_dev->slot >= mca_dev->slot)
56
                info->mca_dev = mca_dev;
57
 
58
        return 0;
59
}
60
 
61
/**
62
 *      mca_find_adapter - scan for adapters
63
 *      @id:    MCA identification to search for
64
 *      @start: starting slot
65
 *
66
 *      Search the MCA configuration for adapters matching the 16bit
67
 *      ID given. The first time it should be called with start as zero
68
 *      and then further calls made passing the return value of the
69
 *      previous call until %MCA_NOTFOUND is returned.
70
 *
71
 *      Disabled adapters are not reported.
72
 */
73
 
74
int mca_find_adapter(int id, int start)
75
{
76
        struct mca_find_adapter_info info;
77
 
78
        if(id == 0xffff)
79
                return MCA_NOTFOUND;
80
 
81
        info.slot = start;
82
        info.id = id;
83
        info.mca_dev = NULL;
84
 
85
        for(;;) {
86
                bus_for_each_dev(&mca_bus_type, NULL, &info, mca_find_adapter_callback);
87
 
88
                if(info.mca_dev == NULL)
89
                        return MCA_NOTFOUND;
90
 
91
                if(info.mca_dev->status != MCA_ADAPTER_DISABLED)
92
                        break;
93
 
94
                /* OK, found adapter but it was disabled.  Go around
95
                 * again, excluding the slot we just found */
96
 
97
                info.slot = info.mca_dev->slot + 1;
98
                info.mca_dev = NULL;
99
        }
100
 
101
        return info.mca_dev->slot;
102
}
103
EXPORT_SYMBOL(mca_find_adapter);
104
 
105
/*--------------------------------------------------------------------*/
106
 
107
/**
108
 *      mca_find_unused_adapter - scan for unused adapters
109
 *      @id:    MCA identification to search for
110
 *      @start: starting slot
111
 *
112
 *      Search the MCA configuration for adapters matching the 16bit
113
 *      ID given. The first time it should be called with start as zero
114
 *      and then further calls made passing the return value of the
115
 *      previous call until %MCA_NOTFOUND is returned.
116
 *
117
 *      Adapters that have been claimed by drivers and those that
118
 *      are disabled are not reported. This function thus allows a driver
119
 *      to scan for further cards when some may already be driven.
120
 */
121
 
122
int mca_find_unused_adapter(int id, int start)
123
{
124
        struct mca_find_adapter_info info = { 0 };
125
 
126
        if (!MCA_bus || id == 0xffff)
127
                return MCA_NOTFOUND;
128
 
129
        info.slot = start;
130
        info.id = id;
131
        info.mca_dev = NULL;
132
 
133
        for(;;) {
134
                bus_for_each_dev(&mca_bus_type, NULL, &info, mca_find_adapter_callback);
135
 
136
                if(info.mca_dev == NULL)
137
                        return MCA_NOTFOUND;
138
 
139
                if(info.mca_dev->status != MCA_ADAPTER_DISABLED
140
                   && !info.mca_dev->driver_loaded)
141
                        break;
142
 
143
                /* OK, found adapter but it was disabled or already in
144
                 * use.  Go around again, excluding the slot we just
145
                 * found */
146
 
147
                info.slot = info.mca_dev->slot + 1;
148
                info.mca_dev = NULL;
149
        }
150
 
151
        return info.mca_dev->slot;
152
}
153
EXPORT_SYMBOL(mca_find_unused_adapter);
154
 
155
/* NOTE: stack allocated structure */
156
struct mca_find_device_by_slot_info {
157
        int                     slot;
158
        struct mca_device       *mca_dev;
159
};
160
 
161
static int mca_find_device_by_slot_callback(struct device *dev, void *data)
162
{
163
        struct mca_find_device_by_slot_info *info = data;
164
        struct mca_device *mca_dev = to_mca_device(dev);
165
 
166
        if(mca_dev->slot == info->slot)
167
                info->mca_dev = mca_dev;
168
 
169
        return 0;
170
}
171
 
172
struct mca_device *mca_find_device_by_slot(int slot)
173
{
174
        struct mca_find_device_by_slot_info info;
175
 
176
        info.slot = slot;
177
        info.mca_dev = NULL;
178
 
179
        bus_for_each_dev(&mca_bus_type, NULL, &info, mca_find_device_by_slot_callback);
180
 
181
        return info.mca_dev;
182
}
183
 
184
/**
185
 *      mca_read_stored_pos - read POS register from boot data
186
 *      @slot: slot number to read from
187
 *      @reg:  register to read from
188
 *
189
 *      Fetch a POS value that was stored at boot time by the kernel
190
 *      when it scanned the MCA space. The register value is returned.
191
 *      Missing or invalid registers report 0.
192
 */
193
unsigned char mca_read_stored_pos(int slot, int reg)
194
{
195
        struct mca_device *mca_dev = mca_find_device_by_slot(slot);
196
 
197
        if(!mca_dev)
198
                return 0;
199
 
200
        return mca_device_read_stored_pos(mca_dev, reg);
201
}
202
EXPORT_SYMBOL(mca_read_stored_pos);
203
 
204
 
205
/**
206
 *      mca_read_pos - read POS register from card
207
 *      @slot: slot number to read from
208
 *      @reg:  register to read from
209
 *
210
 *      Fetch a POS value directly from the hardware to obtain the
211
 *      current value. This is much slower than mca_read_stored_pos and
212
 *      may not be invoked from interrupt context. It handles the
213
 *      deep magic required for onboard devices transparently.
214
 */
215
 
216
unsigned char mca_read_pos(int slot, int reg)
217
{
218
        struct mca_device *mca_dev = mca_find_device_by_slot(slot);
219
 
220
        if(!mca_dev)
221
                return 0;
222
 
223
        return mca_device_read_pos(mca_dev, reg);
224
}
225
EXPORT_SYMBOL(mca_read_pos);
226
 
227
 
228
/**
229
 *      mca_write_pos - read POS register from card
230
 *      @slot: slot number to read from
231
 *      @reg:  register to read from
232
 *      @byte: byte to write to the POS registers
233
 *
234
 *      Store a POS value directly from the hardware. You should not
235
 *      normally need to use this function and should have a very good
236
 *      knowledge of MCA bus before you do so. Doing this wrongly can
237
 *      damage the hardware.
238
 *
239
 *      This function may not be used from interrupt context.
240
 *
241
 *      Note that this a technically a Bad Thing, as IBM tech stuff says
242
 *      you should only set POS values through their utilities.
243
 *      However, some devices such as the 3c523 recommend that you write
244
 *      back some data to make sure the configuration is consistent.
245
 *      I'd say that IBM is right, but I like my drivers to work.
246
 *
247
 *      This function can't do checks to see if multiple devices end up
248
 *      with the same resources, so you might see magic smoke if someone
249
 *      screws up.
250
 */
251
 
252
void mca_write_pos(int slot, int reg, unsigned char byte)
253
{
254
        struct mca_device *mca_dev = mca_find_device_by_slot(slot);
255
 
256
        if(!mca_dev)
257
                return;
258
 
259
        mca_device_write_pos(mca_dev, reg, byte);
260
}
261
EXPORT_SYMBOL(mca_write_pos);
262
 
263
/**
264
 *      mca_set_adapter_name - Set the description of the card
265
 *      @slot: slot to name
266
 *      @name: text string for the namen
267
 *
268
 *      This function sets the name reported via /proc for this
269
 *      adapter slot. This is for user information only. Setting a
270
 *      name deletes any previous name.
271
 */
272
 
273
void mca_set_adapter_name(int slot, char* name)
274
{
275
        struct mca_device *mca_dev = mca_find_device_by_slot(slot);
276
 
277
        if(!mca_dev)
278
                return;
279
 
280
        mca_device_set_name(mca_dev, name);
281
}
282
EXPORT_SYMBOL(mca_set_adapter_name);
283
 
284
/**
285
 *      mca_is_adapter_used - check if claimed by driver
286
 *      @slot:  slot to check
287
 *
288
 *      Returns 1 if the slot has been claimed by a driver
289
 */
290
 
291
int mca_is_adapter_used(int slot)
292
{
293
        struct mca_device *mca_dev = mca_find_device_by_slot(slot);
294
 
295
        if(!mca_dev)
296
                return 0;
297
 
298
        return mca_device_claimed(mca_dev);
299
}
300
EXPORT_SYMBOL(mca_is_adapter_used);
301
 
302
/**
303
 *      mca_mark_as_used - claim an MCA device
304
 *      @slot:  slot to claim
305
 *      FIXME:  should we make this threadsafe
306
 *
307
 *      Claim an MCA slot for a device driver. If the
308
 *      slot is already taken the function returns 1,
309
 *      if it is not taken it is claimed and 0 is
310
 *      returned.
311
 */
312
 
313
int mca_mark_as_used(int slot)
314
{
315
        struct mca_device *mca_dev = mca_find_device_by_slot(slot);
316
 
317
        if(!mca_dev)
318
                /* FIXME: this is actually a severe error */
319
                return 1;
320
 
321
        if(mca_device_claimed(mca_dev))
322
                return 1;
323
 
324
        mca_device_set_claim(mca_dev, 1);
325
 
326
        return 0;
327
}
328
EXPORT_SYMBOL(mca_mark_as_used);
329
 
330
/**
331
 *      mca_mark_as_unused - release an MCA device
332
 *      @slot:  slot to claim
333
 *
334
 *      Release the slot for other drives to use.
335
 */
336
 
337
void mca_mark_as_unused(int slot)
338
{
339
        struct mca_device *mca_dev = mca_find_device_by_slot(slot);
340
 
341
        if(!mca_dev)
342
                return;
343
 
344
        mca_device_set_claim(mca_dev, 0);
345
}
346
EXPORT_SYMBOL(mca_mark_as_unused);
347
 

powered by: WebSVN 2.1.0

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