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
scsi
aic94xx
aic94xx_hwi.h
Go to the documentation of this file.
1
/*
2
* Aic94xx SAS/SATA driver hardware interface header file.
3
*
4
* Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5
* Copyright (C) 2005 Luben Tuikov <
[email protected]
>
6
*
7
* This file is licensed under GPLv2.
8
*
9
* This file is part of the aic94xx driver.
10
*
11
* The aic94xx driver is free software; you can redistribute it and/or
12
* modify it under the terms of the GNU General Public License as
13
* published by the Free Software Foundation; version 2 of the
14
* License.
15
*
16
* The aic94xx driver is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
* General Public License for more details.
20
*
21
* You should have received a copy of the GNU General Public License
22
* along with the aic94xx driver; if not, write to the Free Software
23
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
*
25
*/
26
27
#ifndef _AIC94XX_HWI_H_
28
#define _AIC94XX_HWI_H_
29
30
#include <
linux/interrupt.h
>
31
#include <linux/pci.h>
32
#include <
linux/dma-mapping.h
>
33
34
#include <
scsi/libsas.h
>
35
36
#include "
aic94xx.h
"
37
#include "
aic94xx_sas.h
"
38
39
/* Define ASD_MAX_PHYS to the maximum phys ever. Currently 8. */
40
#define ASD_MAX_PHYS 8
41
#define ASD_PCBA_SN_SIZE 12
42
43
struct
asd_ha_addrspace
{
44
void
__iomem
*
addr
;
45
unsigned
long
start
;
/* pci resource start */
46
unsigned
long
len
;
/* pci resource len */
47
unsigned
long
flags
;
/* pci resource flags */
48
49
/* addresses internal to the host adapter */
50
u32
swa_base
;
/* mmspace 1 (MBAR1) uses this only */
51
u32
swb_base
;
52
u32
swc_base
;
53
};
54
55
struct
bios_struct
{
56
int
present
;
57
u8
maj
;
58
u8
min
;
59
u32
bld
;
60
};
61
62
struct
unit_element_struct
{
63
u16
num
;
64
u16
size
;
65
void
*
area
;
66
};
67
68
struct
flash_struct
{
69
u32
bar
;
70
int
present
;
71
int
wide
;
72
u8
manuf
;
73
u8
dev_id
;
74
u8
sec_prot
;
75
u8
method
;
76
77
u32
dir_offs
;
78
};
79
80
struct
asd_phy_desc
{
81
/* From CTRL-A settings, then set to what is appropriate */
82
u8
sas_addr
[
SAS_ADDR_SIZE
];
83
u8
max_sas_lrate
;
84
u8
min_sas_lrate
;
85
u8
max_sata_lrate
;
86
u8
min_sata_lrate
;
87
u8
flags
;
88
#define ASD_CRC_DIS 1
89
#define ASD_SATA_SPINUP_HOLD 2
90
91
u8
phy_control_0
;
/* mode 5 reg 0x160 */
92
u8
phy_control_1
;
/* mode 5 reg 0x161 */
93
u8
phy_control_2
;
/* mode 5 reg 0x162 */
94
u8
phy_control_3
;
/* mode 5 reg 0x163 */
95
};
96
97
struct
asd_dma_tok
{
98
void
*
vaddr
;
99
dma_addr_t
dma_handle
;
100
size_t
size
;
101
};
102
103
struct
hw_profile
{
104
struct
bios_struct
bios
;
105
struct
unit_element_struct
ue
;
106
struct
flash_struct
flash
;
107
108
u8
sas_addr
[
SAS_ADDR_SIZE
];
109
char
pcba_sn
[
ASD_PCBA_SN_SIZE
+1];
110
111
u8
enabled_phys
;
/* mask of enabled phys */
112
struct
asd_phy_desc
phy_desc
[
ASD_MAX_PHYS
];
113
u32
max_scbs
;
/* absolute sequencer scb queue size */
114
struct
asd_dma_tok
*
scb_ext
;
115
u32
max_ddbs
;
116
struct
asd_dma_tok
*
ddb_ext
;
117
118
spinlock_t
ddb_lock
;
119
void
*
ddb_bitmap
;
120
121
int
num_phys
;
/* ENABLEABLE */
122
int
max_phys
;
/* REPORTED + ENABLEABLE */
123
124
unsigned
addr_range
;
/* max # of addrs; max # of possible ports */
125
unsigned
port_name_base
;
126
unsigned
dev_name_base
;
127
unsigned
sata_name_base
;
128
};
129
130
struct
asd_ascb
{
131
struct
list_head
list
;
132
struct
asd_ha_struct
*
ha
;
133
134
struct
scb
*
scb
;
/* equals dma_scb->vaddr */
135
struct
asd_dma_tok
dma_scb
;
136
struct
asd_dma_tok
*
sg_arr
;
137
138
void
(*
tasklet_complete
)(
struct
asd_ascb
*,
struct
done_list_struct
*);
139
u8
uldd_timer
:1;
140
141
/* internally generated command */
142
struct
timer_list
timer
;
143
struct
completion
*
completion
;
144
u8
tag_valid
:1;
145
__be16
tag
;
/* error recovery only */
146
147
/* If this is an Empty SCB, index of first edb in seq->edb_arr. */
148
int
edb_index
;
149
150
/* Used by the timer timeout function. */
151
int
tc_index
;
152
153
void
*
uldd_task
;
154
};
155
156
#define ASD_DL_SIZE_BITS 0x8
157
#define ASD_DL_SIZE (1<<(2+ASD_DL_SIZE_BITS))
158
#define ASD_DEF_DL_TOGGLE 0x01
159
160
struct
asd_seq_data
{
161
spinlock_t
pend_q_lock
;
162
u16
scbpro
;
163
int
pending
;
164
struct
list_head
pend_q
;
165
int
can_queue
;
/* per adapter */
166
struct
asd_dma_tok
next_scb
;
/* next scb to be delivered to CSEQ */
167
168
spinlock_t
tc_index_lock
;
169
void
**
tc_index_array
;
170
void
*
tc_index_bitmap
;
171
int
tc_index_bitmap_bits
;
172
173
struct
tasklet_struct
dl_tasklet
;
174
struct
done_list_struct
*
dl
;
/* array of done list entries, equals */
175
struct
asd_dma_tok
*
actual_dl
;
/* actual_dl->vaddr */
176
int
dl_toggle
;
177
int
dl_next
;
178
179
int
num_edbs
;
180
struct
asd_dma_tok
**
edb_arr
;
181
int
num_escbs
;
182
struct
asd_ascb
**
escb_arr
;
/* array of pointers to escbs */
183
};
184
185
/* This is an internal port structure. These are used to get accurate
186
* phy_mask for updating DDB 0.
187
*/
188
struct
asd_port
{
189
u8
sas_addr
[
SAS_ADDR_SIZE
];
190
u8
attached_sas_addr
[
SAS_ADDR_SIZE
];
191
u32
phy_mask
;
192
int
num_phys
;
193
};
194
195
/* This is the Host Adapter structure. It describes the hardware
196
* SAS adapter.
197
*/
198
struct
asd_ha_struct
{
199
struct
pci_dev
*
pcidev
;
200
const
char
*
name
;
201
202
struct
sas_ha_struct
sas_ha
;
203
204
u8
revision_id
;
205
206
int
iospace
;
207
spinlock_t
iolock
;
208
struct
asd_ha_addrspace
io_handle
[2];
209
210
struct
hw_profile
hw_prof
;
211
212
struct
asd_phy
phys
[
ASD_MAX_PHYS
];
213
spinlock_t
asd_ports_lock
;
214
struct
asd_port
asd_ports
[
ASD_MAX_PHYS
];
215
struct
asd_sas_port
ports
[
ASD_MAX_PHYS
];
216
217
struct
dma_pool
*
scb_pool
;
218
219
struct
asd_seq_data
seq
;
/* sequencer related */
220
u32
bios_status
;
221
const
struct
firmware
*
bios_image
;
222
};
223
224
/* ---------- Common macros ---------- */
225
226
#define ASD_BUSADDR_LO(__dma_handle) ((u32)(__dma_handle))
227
#define ASD_BUSADDR_HI(__dma_handle) (((sizeof(dma_addr_t))==8) \
228
? ((u32)((__dma_handle) >> 32)) \
229
: ((u32)0))
230
231
#define dev_to_asd_ha(__dev) pci_get_drvdata(to_pci_dev(__dev))
232
#define SCB_SITE_VALID(__site_no) (((__site_no) & 0xF0FF) != 0x00FF \
233
&& ((__site_no) & 0xF0FF) > 0x001F)
234
/* For each bit set in __lseq_mask, set __lseq to equal the bit
235
* position of the set bit and execute the statement following.
236
* __mc is the temporary mask, used as a mask "counter".
237
*/
238
#define for_each_sequencer(__lseq_mask, __mc, __lseq) \
239
for ((__mc)=(__lseq_mask),(__lseq)=0;(__mc)!=0;(__lseq++),(__mc)>>=1)\
240
if (((__mc) & 1))
241
#define for_each_phy(__lseq_mask, __mc, __lseq) \
242
for ((__mc)=(__lseq_mask),(__lseq)=0;(__mc)!=0;(__lseq++),(__mc)>>=1)\
243
if (((__mc) & 1))
244
245
#define PHY_ENABLED(_HA, _I) ((_HA)->hw_prof.enabled_phys & (1<<(_I)))
246
247
/* ---------- DMA allocs ---------- */
248
249
static
inline
struct
asd_dma_tok
*asd_dmatok_alloc(
gfp_t
flags
)
250
{
251
return
kmem_cache_alloc
(
asd_dma_token_cache
, flags);
252
}
253
254
static
inline
void
asd_dmatok_free(
struct
asd_dma_tok
*
token
)
255
{
256
kmem_cache_free
(
asd_dma_token_cache
, token);
257
}
258
259
static
inline
struct
asd_dma_tok
*asd_alloc_coherent(
struct
asd_ha_struct
*
260
asd_ha,
size_t
size
,
261
gfp_t
flags
)
262
{
263
struct
asd_dma_tok
*
token
= asd_dmatok_alloc(flags);
264
if
(token) {
265
token->
size
=
size
;
266
token->
vaddr
=
dma_alloc_coherent
(&asd_ha->
pcidev
->dev,
267
token->
size
,
268
&token->
dma_handle
,
269
flags);
270
if
(!token->
vaddr
) {
271
asd_dmatok_free(token);
272
token =
NULL
;
273
}
274
}
275
return
token
;
276
}
277
278
static
inline
void
asd_free_coherent(
struct
asd_ha_struct
*asd_ha,
279
struct
asd_dma_tok
*token)
280
{
281
if
(token) {
282
dma_free_coherent
(&asd_ha->
pcidev
->dev, token->
size
,
283
token->
vaddr
, token->
dma_handle
);
284
asd_dmatok_free(token);
285
}
286
}
287
288
static
inline
void
asd_init_ascb(
struct
asd_ha_struct
*asd_ha,
289
struct
asd_ascb
*ascb)
290
{
291
INIT_LIST_HEAD(&ascb->
list
);
292
ascb->
scb
= ascb->
dma_scb
.vaddr;
293
ascb->
ha
= asd_ha;
294
ascb->
timer
.function =
NULL
;
295
init_timer
(&ascb->
timer
);
296
ascb->
tc_index
= -1;
297
}
298
299
/* Must be called with the tc_index_lock held!
300
*/
301
static
inline
void
asd_tc_index_release(
struct
asd_seq_data
*seq,
int
index
)
302
{
303
seq->
tc_index_array
[
index
] =
NULL
;
304
clear_bit
(index, seq->
tc_index_bitmap
);
305
}
306
307
/* Must be called with the tc_index_lock held!
308
*/
309
static
inline
int
asd_tc_index_get(
struct
asd_seq_data
*seq,
void
*
ptr
)
310
{
311
int
index
;
312
313
index =
find_first_zero_bit
(seq->
tc_index_bitmap
,
314
seq->
tc_index_bitmap_bits
);
315
if
(index == seq->
tc_index_bitmap_bits
)
316
return
-1;
317
318
seq->
tc_index_array
[
index
] =
ptr
;
319
set_bit
(index, seq->
tc_index_bitmap
);
320
321
return
index
;
322
}
323
324
/* Must be called with the tc_index_lock held!
325
*/
326
static
inline
void
*asd_tc_index_find(
struct
asd_seq_data
*seq,
int
index)
327
{
328
return
seq->
tc_index_array
[
index
];
329
}
330
338
static
inline
void
asd_ascb_free(
struct
asd_ascb
*ascb)
339
{
340
if
(ascb) {
341
struct
asd_ha_struct
*asd_ha = ascb->
ha
;
342
unsigned
long
flags
;
343
344
BUG_ON
(!list_empty(&ascb->
list
));
345
spin_lock_irqsave
(&ascb->
ha
->seq.tc_index_lock, flags);
346
asd_tc_index_release(&ascb->
ha
->seq, ascb->
tc_index
);
347
spin_unlock_irqrestore(&ascb->
ha
->seq.tc_index_lock, flags);
348
dma_pool_free
(asd_ha->
scb_pool
, ascb->
dma_scb
.vaddr,
349
ascb->
dma_scb
.dma_handle);
350
kmem_cache_free
(
asd_ascb_cache
, ascb);
351
}
352
}
353
362
static
inline
void
asd_ascb_free_list(
struct
asd_ascb
*ascb_list)
363
{
364
LIST_HEAD
(
list
);
365
struct
list_head
*
n
, *
pos
;
366
367
__list_add
(&
list
, ascb_list->
list
.prev, &ascb_list->
list
);
368
list_for_each_safe
(pos, n, &
list
) {
369
list_del_init(pos);
370
asd_ascb_free(
list_entry
(pos,
struct
asd_ascb
,
list
));
371
}
372
}
373
374
/* ---------- Function declarations ---------- */
375
376
int
asd_init_hw
(
struct
asd_ha_struct
*asd_ha);
377
irqreturn_t
asd_hw_isr
(
int
irq,
void
*
dev_id
);
378
379
380
struct
asd_ascb
*
asd_ascb_alloc_list
(
struct
asd_ha_struct
381
*asd_ha,
int
*num,
382
gfp_t
gfp_mask
);
383
384
int
asd_post_ascb_list
(
struct
asd_ha_struct
*asd_ha,
struct
asd_ascb
*ascb,
385
int
num);
386
int
asd_post_escb_list
(
struct
asd_ha_struct
*asd_ha,
struct
asd_ascb
*ascb,
387
int
num);
388
389
int
asd_init_post_escbs
(
struct
asd_ha_struct
*asd_ha);
390
void
asd_build_control_phy
(
struct
asd_ascb
*ascb,
int
phy_id
,
u8
subfunc
);
391
void
asd_control_led
(
struct
asd_ha_struct
*asd_ha,
int
phy_id
,
int
op
);
392
void
asd_turn_led
(
struct
asd_ha_struct
*asd_ha,
int
phy_id
,
int
op
);
393
int
asd_enable_phys
(
struct
asd_ha_struct
*asd_ha,
const
u8
phy_mask
);
394
395
void
asd_ascb_timedout
(
unsigned
long
data
);
396
int
asd_chip_hardrst
(
struct
asd_ha_struct
*asd_ha);
397
398
#endif
Generated on Thu Jan 10 2013 14:19:16 for Linux Kernel by
1.8.2