1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
|
/* $OpenBSD: twereg.h,v 1.9 2008/09/01 17:30:56 deraadt Exp $ */
/*
* Copyright (c) 2000 Michael Shalayeff
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* most of the meaning for registers were taken from
* freebsd driver, which in turn got 'em from linux.
* it seems those got 'em from windows driver, in turn.
*/
/* general parameters */
#define TWE_MAX_UNITS 16
#define TWE_MAXOFFSETS 62
#define TWE_MAXCMDS 255
#define TWE_SECTOR_SIZE 512
#define TWE_ALIGN 512
#define TWE_MAXFER (TWE_MAXOFFSETS * PAGE_SIZE)
/* registers */
#define TWE_CONTROL 0x00
#define TWE_CTRL_CHOSTI 0x00080000 /* clear host int */
#define TWE_CTRL_CATTNI 0x00040000 /* clear attention int */
#define TWE_CTRL_MCMDI 0x00020000 /* mask cmd int */
#define TWE_CTRL_MRDYI 0x00010000 /* mask ready int */
#define TWE_CTRL_ECMDI 0x00008000 /* enable cmd int */
#define TWE_CTRL_ERDYI 0x00004000 /* enable ready int */
#define TWE_CTRL_CERR 0x00000200 /* clear error status */
#define TWE_CTRL_SRST 0x00000100 /* soft reset */
#define TWE_CTRL_EINT 0x00000080 /* enable ints */
#define TWE_CTRL_MINT 0x00000040 /* mask ints */
#define TWE_CTRL_HOSTI 0x00000020 /* generate host int */
#define TWE_STATUS 0x04
#define TWE_STAT_MAJV 0xf0000000
#define TWE_MAJV(st) (((st) >> 28) & 0xf)
#define TWE_STAT_MINV 0x0f000000
#define TWE_MINV(st) (((st) >> 24) & 0xf)
#define TWE_STAT_PCIPAR 0x00800000
#define TWE_STAT_QUEUEE 0x00400000
#define TWE_STAT_CPUERR 0x00200000
#define TWE_STAT_PCIABR 0x00100000
#define TWE_STAT_HOSTI 0x00080000
#define TWE_STAT_ATTNI 0x00040000
#define TWE_STAT_CMDI 0x00020000
#define TWE_STAT_RDYI 0x00010000
#define TWE_STAT_CQF 0x00008000 /* cmd queue full */
#define TWE_STAT_RQE 0x00004000 /* ready queue empty */
#define TWE_STAT_CPURDY 0x00002000 /* cpu ready */
#define TWE_STAT_CQR 0x00001000 /* cmd queue ready */
#define TWE_STAT_FLAGS 0x00fff000 /* mask out other stuff */
#define TWE_STAT_BITS "\020\015cqr\016cpurdy\017rqe\20cqf" \
"\021rdyi\022cmdi\023attni\024hosti\025pciabr\026cpuerr\027queuee\030pcipar"
#define TWE_COMMANDQUEUE 0x08
/*
* the segs offset is encoded into upper 3 bits of the opcode.
* i bet other bits mean something too
* upper 8 bits is the command size in 32bit words.
*/
#define TWE_CMD_NOP 0x0200
#define TWE_CMD_INIT 0x0301
#define TWE_CMD_READ 0x0362
#define TWE_CMD_WRITE 0x0363
#define TWE_CMD_RDVRFY 0x0364
#define TWE_CMD_VERIFY 0x0365
#define TWE_CMD_ZRFUNIT 0x0208
#define TWE_CMD_RPLUNIT 0x0209
#define TWE_CMD_HOTSWAP 0x020a
#define TWE_CMD_SETATA 0x020c
#define TWE_CMD_FLUSH 0x020e
#define TWE_CMD_ABORT 0x020f
#define TWE_CMD_QSTAT 0x0210
#define TWE_CMD_GPARAM 0x0252
#define TWE_CMD_SPARAM 0x0253
#define TWE_CMD_NEWUNIT 0x0214
#define TWE_CMD_DELUNIT 0x0215
#define TWE_CMD_RBLUNIT 0x0217 /* rebuild */
#define TWE_CMD_SECINF 0x021a
#define TWE_CMD_AEN 0x021c
#define TWE_CMD_CMDPK 0x021d
#define TWE_READYQUEUE 0x0c
#define TWE_READYID(u) (((u) >> 4) & 0xff)
/*
* From 3ware's documentation:
*
* All parameters maintained by the controller are grouped into related
* tables. Tables are are accessed indirectly via get and set parameter
* commands. To access a specific parameter in a table, the table ID and
* parameter index are used to uniquely identify a parameter. Table
* 0xffff is the directory table and provides a list of the table IDs and
* sizes of all other tables. Index zero in each table specifies the
* entire table, and index one specifies the size of the table. An entire
* table can be read or set by using index zero.
*/
/* get/set param table ids */
#define TWE_PARAM_ALL 0x000 /* everything */
#define TWE_PARAM_DSUM 0x002 /* drive summary */
#define TWE_PARAM_UC 0x003 /* unit config */
#define TWE_PARAM_DC 0x200 /* + 15 -- drive config (doc says 0x100) */
#define TWE_PARAM_UI 0x300 /* + 16 -- unit information */
#define TWE_PARAM_AEN 0x401
#define TWE_PARAM_VER 0x402 /* version info */
#define TWE_PARAM_CTRL 0x403 /* controller info */
#define TWE_PARAM_FTRS 0x404 /* features */
#define TWE_PARAM_DIR 0xffff /* param table directory */
#define TWE_AEN_QEMPTY 0x0000
#define TWE_AEN_SRST 0x0001 /* soft reset */
#define TWE_AEN_DMIRROR 0x0002 /* degraded mirror */
#define TWE_AEN_CERROR 0x0003 /* controller error */
#define TWE_AEN_RBFAIL 0x0004 /* rebuild failed */
#define TWE_AEN_RBDONE 0x0005 /* rebuild done */
#define TWE_AEN_ILLUN 0x0006 /* incompatible unit */
#define TWE_AEN_INDONE 0x0007 /* init done */
#define TWE_AEN_DSHUT 0x0008 /* unclean shutdown */
#define TWE_AEN_APORT 0x0009 /* aport timeout */
#define TWE_AEN_DRVERR 0x000a /* drive error */
#define TWE_AEN_RBSTART 0x000b /* rebuild start */
#define TWE_AEN_ISTART 0x000c /* init started */
#define TWE_AEN_TUN 0x0015 /* table undefined */
/* TWE_AEN_ 0x0000 * dunno what this is (yet) */
#define TWE_AEN_QFULL 0x00ff
/* struct definitions */
struct twe_param {
u_int16_t table_id;
u_int8_t param_id;
u_int8_t param_size;
u_int8_t data[1];
} __packed;
struct twe_segs {
u_int32_t twes_addr;
u_int32_t twes_len;
} __packed;
struct twe_cmd {
u_int16_t cmd_op;
u_int8_t cmd_index;
u_int8_t cmd_unit_host;
#define TWE_UNITHOST(u, h) (((u) & 0xf) | ((h) << 4))
u_int8_t cmd_status;
u_int8_t cmd_flags;
#define TWE_FLAGS_CACHEDISABLE 0x01
union {
struct {
u_int16_t count;
u_int32_t lba;
struct twe_segs segs[TWE_MAXOFFSETS];
u_int32_t pad;
} __packed _cmd_io;
#define cmd_io _._cmd_io
struct {
u_int16_t count;
struct twe_segs segs[TWE_MAXOFFSETS];
} __packed _cmd_param;
#define cmd_param _._cmd_param
struct {
u_int16_t msgcr;
u_int32_t rdy_q_ptr;
} __packed _cmd_init;
#define cmd_init _._cmd_init
struct {
u_int8_t action;
#define TWE_HSWAP_REMOVE 0
#define TWE_HSWAP_ADDCBOD 1
#define TWE_HSWAP_ADDSPARE 2
u_int8_t port;
} __packed _cmd_aport;
#define cmd_hswap _._cmd_hswap
struct {
u_int8_t feature;
#define TWE_ATA_WCE 0x02
#define TWE_ATA_NWCE 0x82
u_int8_t mode;
u_int16_t units;
u_int16_t persist;
} __packed _cmd_ata;
#define cmd_ata _._cmd_ata
u_int16_t cmd_status;
struct {
u_int8_t action;
#define TWE_REBUILD_NOP 0
#define TWE_REBUILD_STOP 2
#define TWE_REBUILD_START 4
#define TWE_REBUILD_STARTU 5
#define TWE_REBUILD_CS 0x80
u_int8_t subunit; /* raid10 lu rebuild */
} __packed _cmd_rebuild;
#define cmd_rebuild _._cmd_rebuild
} _;
} __packed; /* 512 bytes */
|