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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [armnommu/] [drivers/] [block/] [ide-ics.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1622 jcastillo
/*
2
 * linux/arch/arm/drivers/block/ide-ics.c
3
 *
4
 * Copyright (c) 1996,1997 Russell King.
5
 *
6
 * Changelog:
7
 *  08-06-1996  RMK     Created
8
 *  12-09-1997  RMK     Added interrupt enable/disable
9
 */
10
 
11
#include <linux/module.h>
12
#include <linux/malloc.h>
13
#include <linux/blkdev.h>
14
#include <linux/errno.h>
15
 
16
#include <asm/dma.h>
17
#include <asm/ecard.h>
18
#include <asm/io.h>
19
 
20
#include "ide.h"
21
 
22
/*
23
 * Maximum number of interfaces per card
24
 */
25
#define MAX_IFS 2
26
 
27
#define ICS_IDENT_OFFSET                0x8a0
28
 
29
#define ICS_ARCIN_V5_INTRSTAT           0x000
30
#define ICS_ARCIN_V5_INTROFFSET         0x001
31
#define ICS_ARCIN_V5_IDEOFFSET          0xa00
32
#define ICS_ARCIN_V5_IDEALTOFFSET       0xae0
33
#define ICS_ARCIN_V5_IDESTEPPING        4
34
 
35
#define ICS_ARCIN_V6_IDEOFFSET_1        0x800
36
#define ICS_ARCIN_V6_INTROFFSET_1       0x880
37
#define ICS_ARCIN_V6_INTRSTAT_1         0x8a4
38
#define ICS_ARCIN_V6_IDEALTOFFSET_1     0x8e0
39
#define ICS_ARCIN_V6_IDEOFFSET_2        0xc00
40
#define ICS_ARCIN_V6_INTROFFSET_2       0xc80
41
#define ICS_ARCIN_V6_INTRSTAT_2         0xca4
42
#define ICS_ARCIN_V6_IDEALTOFFSET_2     0xce0
43
#define ICS_ARCIN_V6_IDESTEPPING        4
44
 
45
static const card_ids icside_cids[] = {
46
        { MANU_ICS, PROD_ICS_IDE },
47
        { MANU_ICS2, PROD_ICS2_IDE },
48
        { 0xffff, 0xffff }
49
};
50
 
51
typedef enum {
52
        ics_if_unknown,
53
        ics_if_arcin_v5,
54
        ics_if_arcin_v6
55
} iftype_t;
56
 
57
static struct expansion_card *ec[MAX_ECARDS];
58
static int result[MAX_ECARDS][MAX_IFS];
59
 
60
 
61
/* ---------------- Version 5 PCB Support Functions --------------------- */
62
/* Prototype: icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr)
63
 * Purpose  : enable interrupts from card
64
 */
65
static void icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr)
66
{
67
        unsigned int memc_port = (unsigned int)ec->irq_data;
68
        outb (0, memc_port + ICS_ARCIN_V5_INTROFFSET);
69
}
70
 
71
/* Prototype: icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr)
72
 * Purpose  : disable interrupts from card
73
 */
74
static void icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr)
75
{
76
        unsigned int memc_port = (unsigned int)ec->irq_data;
77
        inb (memc_port + ICS_ARCIN_V5_INTROFFSET);
78
}
79
 
80
static const expansioncard_ops_t icside_ops_arcin_v5 = {
81
        icside_irqenable_arcin_v5,
82
        icside_irqdisable_arcin_v5,
83
        NULL,
84
        NULL,
85
        NULL,
86
        NULL
87
};
88
 
89
 
90
/* ---------------- Version 6 PCB Support Functions --------------------- */
91
/* Prototype: icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr)
92
 * Purpose  : enable interrupts from card
93
 */
94
static void icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr)
95
{
96
        unsigned int ide_base_port = (unsigned int)ec->irq_data;
97
        outb (0, ide_base_port + ICS_ARCIN_V6_INTROFFSET_1);
98
        outb (0, ide_base_port + ICS_ARCIN_V6_INTROFFSET_2);
99
}
100
 
101
/* Prototype: icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
102
 * Purpose  : disable interrupts from card
103
 */
104
static void icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
105
{
106
        unsigned int ide_base_port = (unsigned int)ec->irq_data;
107
        inb (ide_base_port + ICS_ARCIN_V6_INTROFFSET_1);
108
        inb (ide_base_port + ICS_ARCIN_V6_INTROFFSET_2);
109
}
110
 
111
/* Prototype: icside_irqprobe(struct expansion_card *ec)
112
 * Purpose  : detect an active interrupt from card
113
 */
114
static int icside_irqprobe_arcin_v6(struct expansion_card *ec)
115
{
116
        unsigned int ide_base_port = (unsigned int)ec->irq_data;
117
 
118
        return inb(ide_base_port + ICS_ARCIN_V6_INTRSTAT_1) & 1 ||
119
               inb(ide_base_port + ICS_ARCIN_V6_INTRSTAT_2) & 1;
120
}
121
 
122
static const expansioncard_ops_t icside_ops_arcin_v6 = {
123
        icside_irqenable_arcin_v6,
124
        icside_irqdisable_arcin_v6,
125
        icside_irqprobe_arcin_v6,
126
        NULL,
127
        NULL,
128
        NULL
129
};
130
 
131
 
132
 
133
/* Prototype: icside_identifyif (struct expansion_card *ec)
134
 * Purpose  : identify IDE interface type
135
 * Notes    : checks the description string
136
 */
137
static iftype_t icside_identifyif (struct expansion_card *ec)
138
{
139
        unsigned int addr;
140
        iftype_t iftype;
141
        int id = 0;
142
 
143
        iftype = ics_if_unknown;
144
 
145
        addr = ecard_address (ec, ECARD_IOC, ECARD_FAST) + ICS_IDENT_OFFSET;
146
 
147
        id = inb (addr) & 1;
148
        id |= (inb (addr + 1) & 1) << 1;
149
        id |= (inb (addr + 2) & 1) << 2;
150
        id |= (inb (addr + 3) & 1) << 3;
151
 
152
        switch (id) {
153
        case 0: /* A3IN */
154
                printk ("icside: A3IN unsupported\n");
155
                break;
156
 
157
        case 1: /* A3USER */
158
                printk ("icside: A3USER unsupported\n");
159
                break;
160
 
161
        case 3: /* ARCIN V6 */
162
                printk ("icside: detected ARCIN V6 in slot %d\n", ec->slot_no);
163
                iftype = ics_if_arcin_v6;
164
                break;
165
 
166
        case 15:/* ARCIN V5 (no id) */
167
                printk ("icside: detected ARCIN V5 in slot %d\n", ec->slot_no);
168
                iftype = ics_if_arcin_v5;
169
                break;
170
 
171
        default:/* we don't know - complain very loudly */
172
                printk ("icside: ***********************************\n");
173
                printk ("icside: *** UNKNOWN ICS INTERFACE id=%d ***\n", id);
174
                printk ("icside: ***********************************\n");
175
                printk ("icside: please report this to: linux@arm.linux.org.uk\n");
176
                break;
177
        }
178
 
179
        return iftype;
180
}
181
 
182
/* Prototype: icside_register (struct expansion_card *ec)
183
 * Purpose  : register an ICS IDE card with the IDE driver
184
 * Notes    : we make sure that interrupts are disabled from the card
185
 */
186
static inline void icside_register (struct expansion_card *ec, int index)
187
{
188
        unsigned long port = 0, latch;
189
 
190
        result[index][0] = -1;
191
        result[index][1] = -1;
192
 
193
        switch (icside_identifyif (ec)) {
194
        case ics_if_unknown:
195
        default:
196
                printk ("icside: *** Warning: ICS IDE Interface unrecognised! ***\n");
197
                break;
198
 
199
        case ics_if_arcin_v5:
200
                port = ecard_address (ec, ECARD_MEMC, 0);
201
                ec->irqaddr = (unsigned char *)ioaddr(port + ICS_ARCIN_V5_INTRSTAT);
202
                ec->irqmask = 1;
203
                ec->irq_data = (void *)port;
204
                ec->ops = (expansioncard_ops_t *)&icside_ops_arcin_v5;
205
 
206
                /*
207
                 * Be on the safe side - disable interrupts
208
                 */
209
                inb (port + ICS_ARCIN_V5_INTROFFSET);
210
                result[index][0] =
211
                        ide_register_port(port + ICS_ARCIN_V5_IDEOFFSET,
212
                                          port + ICS_ARCIN_V5_IDEALTOFFSET,
213
                                          ICS_ARCIN_V5_IDESTEPPING,
214
                                          ec->irq);
215
                break;
216
 
217
        case ics_if_arcin_v6:
218
                latch = ecard_address (ec, ECARD_IOC, ECARD_FAST);
219
                if (ec->dma == NO_DMA)
220
                        port = ecard_address (ec, ECARD_EASI, ECARD_FAST);
221
                if (port)
222
                        outb(0x20, latch);
223
                else {
224
                        port = latch;
225
                        outb(0, port);
226
                }
227
                ec->irq_data = (void *)port;
228
                ec->ops = (expansioncard_ops_t *)&icside_ops_arcin_v6;
229
 
230
                /*
231
                 * Be on the safe side - disable interrupts
232
                 */
233
                inb (port + ICS_ARCIN_V6_INTROFFSET_1);
234
                inb (port + ICS_ARCIN_V6_INTROFFSET_2);
235
                result[index][0] =
236
                        ide_register_port(port + ICS_ARCIN_V6_IDEOFFSET_1,
237
                                          port + ICS_ARCIN_V6_IDEALTOFFSET_1,
238
                                          ICS_ARCIN_V6_IDESTEPPING,
239
                                          ec->irq);
240
                result[index][1] =
241
                        ide_register_port(port + ICS_ARCIN_V6_IDEOFFSET_2,
242
                                          port + ICS_ARCIN_V6_IDEALTOFFSET_2,
243
                                          ICS_ARCIN_V6_IDESTEPPING,
244
                                          ec->irq);
245
                break;
246
        }
247
}
248
 
249
int icside_init (void)
250
{
251
        int i;
252
 
253
        for (i = 0; i < MAX_ECARDS; i++)
254
                ec[i] = NULL;
255
 
256
        ecard_startfind ();
257
 
258
        for (i = 0; ; i++) {
259
                if ((ec[i] = ecard_find (0, icside_cids)) == NULL)
260
                        break;
261
 
262
                ecard_claim (ec[i]);
263
                icside_register (ec[i], i);
264
        }
265
 
266
        for (i = 0; i < MAX_ECARDS; i++)
267
                if (ec[i] && result[i][0] < 0 && result[i][1] < 0) {
268
                        ecard_release (ec[i]);
269
                        ec[i] = NULL;
270
                }
271
        return 0;
272
}
273
 
274
#ifdef MODULE
275
int init_module (void)
276
{
277
        return icside_init();
278
}
279
 
280
void cleanup_module (void)
281
{
282
        int i;
283
 
284
        for (i = 0; i < MAX_ECARDS; i++)
285
                if (ec[i]) {
286
                        if (result[i][0] >= 0)
287
                                ide_unregister (result[i][0]);
288
 
289
                        if (result[i][1] >= 0)
290
                                ide_unregister (result[i][1]);
291
 
292
                        ecard_release (ec[i]);
293
                        ec[i] = NULL;
294
                }
295
}
296
#endif
297
 

powered by: WebSVN 2.1.0

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