Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
block
smart1,2.h
Go to the documentation of this file.
1
/*
2
* Disk Array driver for Compaq SMART2 Controllers
3
* Copyright 1998 Compaq Computer Corporation
4
*
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
9
*
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
13
* NON INFRINGEMENT. See the GNU General Public License for more details.
14
*
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
*
19
* Questions/Comments/Bugfixes to
[email protected]
20
*
21
* If you want to make changes, improve or add functionality to this
22
* driver, you'll probably need the Compaq Array Controller Interface
23
* Specificiation (Document number ECG086/1198)
24
*/
25
26
/*
27
* This file contains the controller communication implementation for
28
* Compaq SMART-1 and SMART-2 controllers. To the best of my knowledge,
29
* this should support:
30
*
31
* PCI:
32
* SMART-2/P, SMART-2DH, SMART-2SL, SMART-221, SMART-3100ES, SMART-3200
33
* Integerated SMART Array Controller, SMART-4200, SMART-4250ES
34
*
35
* EISA:
36
* SMART-2/E, SMART, IAES, IDA-2, IDA
37
*/
38
39
/*
40
* Memory mapped FIFO interface (SMART 42xx cards)
41
*/
42
static
void
smart4_submit_command(
ctlr_info_t
*
h
,
cmdlist_t
*
c
)
43
{
44
writel
(c->
busaddr
, h->
vaddr
+
S42XX_REQUEST_PORT_OFFSET
);
45
}
46
47
/*
48
* This card is the opposite of the other cards.
49
* 0 turns interrupts on...
50
* 0x08 turns them off...
51
*/
52
static
void
smart4_intr_mask(
ctlr_info_t
*
h
,
unsigned
long
val
)
53
{
54
if
(val)
55
{
/* Turn interrupts on */
56
writel
(0, h->
vaddr
+
S42XX_REPLY_INTR_MASK_OFFSET
);
57
}
else
/* Turn them off */
58
{
59
writel
(
S42XX_INTR_OFF
,
60
h->
vaddr
+
S42XX_REPLY_INTR_MASK_OFFSET
);
61
}
62
}
63
64
/*
65
* For older cards FIFO Full = 0.
66
* On this card 0 means there is room, anything else FIFO Full.
67
*
68
*/
69
static
unsigned
long
smart4_fifo_full(
ctlr_info_t
*h)
70
{
71
72
return
(!
readl
(h->
vaddr
+
S42XX_REQUEST_PORT_OFFSET
));
73
}
74
75
/* This type of controller returns -1 if the fifo is empty,
76
* Not 0 like the others.
77
* And we need to let it know we read a value out
78
*/
79
static
unsigned
long
smart4_completed(
ctlr_info_t
*h)
80
{
81
long
register_value
82
=
readl
(h->
vaddr
+
S42XX_REPLY_PORT_OFFSET
);
83
84
/* Fifo is empty */
85
if
( register_value == 0xffffffff)
86
return
0;
87
88
/* Need to let it know we got the reply */
89
/* We do this by writing a 0 to the port we just read from */
90
writel
(0, h->
vaddr
+
S42XX_REPLY_PORT_OFFSET
);
91
92
return
((
unsigned
long
) register_value);
93
}
94
95
/*
96
* This hardware returns interrupt pending at a different place and
97
* it does not tell us if the fifo is empty, we will have check
98
* that by getting a 0 back from the command_completed call.
99
*/
100
static
unsigned
long
smart4_intr_pending(
ctlr_info_t
*h)
101
{
102
unsigned
long
register_value =
103
readl
(h->
vaddr
+
S42XX_INTR_STATUS
);
104
105
if
( register_value &
S42XX_INTR_PENDING
)
106
return
FIFO_NOT_EMPTY
;
107
return
0 ;
108
}
109
110
static
struct
access_method
smart4_access = {
111
smart4_submit_command,
112
smart4_intr_mask,
113
smart4_fifo_full,
114
smart4_intr_pending,
115
smart4_completed,
116
};
117
118
/*
119
* Memory mapped FIFO interface (PCI SMART2 and SMART 3xxx cards)
120
*/
121
static
void
smart2_submit_command(
ctlr_info_t
*h,
cmdlist_t
*
c
)
122
{
123
writel
(c->
busaddr
, h->
vaddr
+
COMMAND_FIFO
);
124
}
125
126
static
void
smart2_intr_mask(
ctlr_info_t
*h,
unsigned
long
val)
127
{
128
writel
(val, h->
vaddr
+
INTR_MASK
);
129
}
130
131
static
unsigned
long
smart2_fifo_full(
ctlr_info_t
*h)
132
{
133
return
readl
(h->
vaddr
+
COMMAND_FIFO
);
134
}
135
136
static
unsigned
long
smart2_completed(
ctlr_info_t
*h)
137
{
138
return
readl
(h->
vaddr
+
COMMAND_COMPLETE_FIFO
);
139
}
140
141
static
unsigned
long
smart2_intr_pending(
ctlr_info_t
*h)
142
{
143
return
readl
(h->
vaddr
+
INTR_PENDING
);
144
}
145
146
static
struct
access_method
smart2_access = {
147
smart2_submit_command,
148
smart2_intr_mask,
149
smart2_fifo_full,
150
smart2_intr_pending,
151
smart2_completed,
152
};
153
154
/*
155
* IO access for SMART-2/E cards
156
*/
157
static
void
smart2e_submit_command(
ctlr_info_t
*h,
cmdlist_t
*
c
)
158
{
159
outl
(c->
busaddr
, h->io_mem_addr +
COMMAND_FIFO
);
160
}
161
162
static
void
smart2e_intr_mask(
ctlr_info_t
*h,
unsigned
long
val)
163
{
164
outl
(val, h->io_mem_addr +
INTR_MASK
);
165
}
166
167
static
unsigned
long
smart2e_fifo_full(
ctlr_info_t
*h)
168
{
169
return
inl
(h->io_mem_addr +
COMMAND_FIFO
);
170
}
171
172
static
unsigned
long
smart2e_completed(
ctlr_info_t
*h)
173
{
174
return
inl
(h->io_mem_addr +
COMMAND_COMPLETE_FIFO
);
175
}
176
177
static
unsigned
long
smart2e_intr_pending(
ctlr_info_t
*h)
178
{
179
return
inl
(h->io_mem_addr +
INTR_PENDING
);
180
}
181
182
static
struct
access_method
smart2e_access = {
183
smart2e_submit_command,
184
smart2e_intr_mask,
185
smart2e_fifo_full,
186
smart2e_intr_pending,
187
smart2e_completed,
188
};
189
190
/*
191
* IO access for older SMART-1 type cards
192
*/
193
#define SMART1_SYSTEM_MASK 0xC8E
194
#define SMART1_SYSTEM_DOORBELL 0xC8F
195
#define SMART1_LOCAL_MASK 0xC8C
196
#define SMART1_LOCAL_DOORBELL 0xC8D
197
#define SMART1_INTR_MASK 0xC89
198
#define SMART1_LISTADDR 0xC90
199
#define SMART1_LISTLEN 0xC94
200
#define SMART1_TAG 0xC97
201
#define SMART1_COMPLETE_ADDR 0xC98
202
#define SMART1_LISTSTATUS 0xC9E
203
204
#define CHANNEL_BUSY 0x01
205
#define CHANNEL_CLEAR 0x02
206
207
static
void
smart1_submit_command(
ctlr_info_t
*h,
cmdlist_t
*
c
)
208
{
209
/*
210
* This __u16 is actually a bunch of control flags on SMART
211
* and below. We want them all to be zero.
212
*/
213
c->
hdr
.
size
= 0;
214
215
outb
(
CHANNEL_CLEAR
, h->io_mem_addr +
SMART1_SYSTEM_DOORBELL
);
216
217
outl
(c->
busaddr
, h->io_mem_addr +
SMART1_LISTADDR
);
218
outw
(c->
size
, h->io_mem_addr +
SMART1_LISTLEN
);
219
220
outb
(
CHANNEL_BUSY
, h->io_mem_addr +
SMART1_LOCAL_DOORBELL
);
221
}
222
223
static
void
smart1_intr_mask(
ctlr_info_t
*h,
unsigned
long
val)
224
{
225
if
(val == 1) {
226
outb
(0xFD, h->io_mem_addr +
SMART1_SYSTEM_DOORBELL
);
227
outb
(
CHANNEL_BUSY
, h->io_mem_addr +
SMART1_LOCAL_DOORBELL
);
228
outb
(0x01, h->io_mem_addr +
SMART1_INTR_MASK
);
229
outb
(0x01, h->io_mem_addr +
SMART1_SYSTEM_MASK
);
230
}
else
{
231
outb
(0, h->io_mem_addr + 0xC8E);
232
}
233
}
234
235
static
unsigned
long
smart1_fifo_full(
ctlr_info_t
*h)
236
{
237
unsigned
char
chan
;
238
chan =
inb
(h->io_mem_addr +
SMART1_SYSTEM_DOORBELL
) &
CHANNEL_CLEAR
;
239
return
chan;
240
}
241
242
static
unsigned
long
smart1_completed(
ctlr_info_t
*h)
243
{
244
unsigned
char
status
;
245
unsigned
long
cmd
;
246
247
if
(
inb
(h->io_mem_addr +
SMART1_SYSTEM_DOORBELL
) &
CHANNEL_BUSY
) {
248
outb
(CHANNEL_BUSY, h->io_mem_addr +
SMART1_SYSTEM_DOORBELL
);
249
250
cmd =
inl
(h->io_mem_addr +
SMART1_COMPLETE_ADDR
);
251
status =
inb
(h->io_mem_addr +
SMART1_LISTSTATUS
);
252
253
outb
(
CHANNEL_CLEAR
, h->io_mem_addr +
SMART1_LOCAL_DOORBELL
);
254
255
/*
256
* this is x86 (actually compaq x86) only, so it's ok
257
*/
258
if
(cmd) ((
cmdlist_t
*)
bus_to_virt
(cmd))->
req
.hdr.rcode = status;
259
}
else
{
260
cmd = 0;
261
}
262
return
cmd
;
263
}
264
265
static
unsigned
long
smart1_intr_pending(
ctlr_info_t
*h)
266
{
267
unsigned
char
chan
;
268
chan =
inb
(h->io_mem_addr +
SMART1_SYSTEM_DOORBELL
) &
CHANNEL_BUSY
;
269
return
chan;
270
}
271
272
static
struct
access_method
smart1_access = {
273
smart1_submit_command,
274
smart1_intr_mask,
275
smart1_fifo_full,
276
smart1_intr_pending,
277
smart1_completed,
278
};
Generated on Thu Jan 10 2013 13:26:59 for Linux Kernel by
1.8.2