1 |
1275 |
phoenix |
/*
|
2 |
|
|
* linux/drivers/message/fusion/mptbase.h
|
3 |
|
|
* High performance SCSI + LAN / Fibre Channel device drivers.
|
4 |
|
|
* For use with PCI chip/adapter(s):
|
5 |
|
|
* LSIFC9xx/LSI409xx Fibre Channel
|
6 |
|
|
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
|
7 |
|
|
*
|
8 |
|
|
* Credits:
|
9 |
|
|
* (see mptbase.c)
|
10 |
|
|
*
|
11 |
|
|
* Copyright (c) 1999-2002 LSI Logic Corporation
|
12 |
|
|
* Originally By: Steven J. Ralston
|
13 |
|
|
* (mailto:sjralston1@netscape.net)
|
14 |
|
|
* (mailto:mpt_linux_developer@lsil.com)
|
15 |
|
|
*
|
16 |
|
|
* $Id: mptbase.h,v 1.1.1.1 2004-04-15 02:27:32 phoenix Exp $
|
17 |
|
|
*/
|
18 |
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
19 |
|
|
/*
|
20 |
|
|
This program is free software; you can redistribute it and/or modify
|
21 |
|
|
it under the terms of the GNU General Public License as published by
|
22 |
|
|
the Free Software Foundation; version 2 of the License.
|
23 |
|
|
|
24 |
|
|
This program is distributed in the hope that it will be useful,
|
25 |
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
26 |
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
27 |
|
|
GNU General Public License for more details.
|
28 |
|
|
|
29 |
|
|
NO WARRANTY
|
30 |
|
|
THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
31 |
|
|
CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
32 |
|
|
LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
33 |
|
|
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
34 |
|
|
solely responsible for determining the appropriateness of using and
|
35 |
|
|
distributing the Program and assumes all risks associated with its
|
36 |
|
|
exercise of rights under this Agreement, including but not limited to
|
37 |
|
|
the risks and costs of program errors, damage to or loss of data,
|
38 |
|
|
programs or equipment, and unavailability or interruption of operations.
|
39 |
|
|
|
40 |
|
|
DISCLAIMER OF LIABILITY
|
41 |
|
|
NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
42 |
|
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
43 |
|
|
DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
44 |
|
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
45 |
|
|
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
46 |
|
|
USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
47 |
|
|
HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
48 |
|
|
|
49 |
|
|
You should have received a copy of the GNU General Public License
|
50 |
|
|
along with this program; if not, write to the Free Software
|
51 |
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
52 |
|
|
*/
|
53 |
|
|
|
54 |
|
|
#ifndef MPTBASE_H_INCLUDED
|
55 |
|
|
#define MPTBASE_H_INCLUDED
|
56 |
|
|
/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
57 |
|
|
|
58 |
|
|
#include "linux_compat.h" /* linux-2.2.x (vs. -2.4.x) tweaks */
|
59 |
|
|
#include "scsi3.h" /* SCSI defines */
|
60 |
|
|
|
61 |
|
|
#include "lsi/mpi_type.h"
|
62 |
|
|
#include "lsi/mpi.h" /* Fusion MPI(nterface) basic defs */
|
63 |
|
|
#include "lsi/mpi_ioc.h" /* Fusion MPT IOC(ontroller) defs */
|
64 |
|
|
#include "lsi/mpi_cnfg.h" /* IOC configuration support */
|
65 |
|
|
#include "lsi/mpi_init.h" /* SCSI Host (initiator) protocol support */
|
66 |
|
|
#include "lsi/mpi_lan.h" /* LAN over FC protocol support */
|
67 |
|
|
#include "lsi/mpi_raid.h" /* Integrated Mirroring support */
|
68 |
|
|
|
69 |
|
|
#include "lsi/mpi_fc.h" /* Fibre Channel (lowlevel) support */
|
70 |
|
|
#include "lsi/mpi_targ.h" /* SCSI/FCP Target protcol support */
|
71 |
|
|
#include "lsi/fc_log.h"
|
72 |
|
|
|
73 |
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
74 |
|
|
|
75 |
|
|
#ifndef MODULEAUTHOR
|
76 |
|
|
#define MODULEAUTHOR "LSI Logic Corporation"
|
77 |
|
|
#endif
|
78 |
|
|
|
79 |
|
|
#ifndef COPYRIGHT
|
80 |
|
|
#define COPYRIGHT "Copyright (c) 1999-2003 " MODULEAUTHOR
|
81 |
|
|
#endif
|
82 |
|
|
|
83 |
|
|
#define MPT_LINUX_VERSION_COMMON "2.05.11.03"
|
84 |
|
|
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-2.05.11.03"
|
85 |
|
|
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
|
86 |
|
|
|
87 |
|
|
#define show_mptmod_ver(s,ver) \
|
88 |
|
|
printk(KERN_INFO "%s %s\n", s, ver);
|
89 |
|
|
|
90 |
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
91 |
|
|
/*
|
92 |
|
|
* Fusion MPT(linux) driver configurable stuff...
|
93 |
|
|
*/
|
94 |
|
|
#define MPT_MAX_ADAPTERS 18
|
95 |
|
|
#define MPT_MAX_PROTOCOL_DRIVERS 16
|
96 |
|
|
#define MPT_MAX_BUS 1 /* Do not change */
|
97 |
|
|
#define MPT_MAX_FC_DEVICES 255
|
98 |
|
|
#define MPT_MAX_SCSI_DEVICES 16
|
99 |
|
|
#define MPT_LAST_LUN 255
|
100 |
|
|
#define MPT_SENSE_BUFFER_ALLOC 64
|
101 |
|
|
/* allow for 256 max sense alloc, but only 255 max request */
|
102 |
|
|
#if MPT_SENSE_BUFFER_ALLOC >= 256
|
103 |
|
|
# undef MPT_SENSE_BUFFER_ALLOC
|
104 |
|
|
# define MPT_SENSE_BUFFER_ALLOC 256
|
105 |
|
|
# define MPT_SENSE_BUFFER_SIZE 255
|
106 |
|
|
#else
|
107 |
|
|
# define MPT_SENSE_BUFFER_SIZE MPT_SENSE_BUFFER_ALLOC
|
108 |
|
|
#endif
|
109 |
|
|
|
110 |
|
|
#define MPT_NAME_LENGTH 32
|
111 |
|
|
|
112 |
|
|
#define MPT_PROCFS_MPTBASEDIR "mpt"
|
113 |
|
|
/* chg it to "driver/fusion" ? */
|
114 |
|
|
#define MPT_PROCFS_SUMMARY_ALL_NODE MPT_PROCFS_MPTBASEDIR "/summary"
|
115 |
|
|
#define MPT_PROCFS_SUMMARY_ALL_PATHNAME "/proc/" MPT_PROCFS_SUMMARY_ALL_NODE
|
116 |
|
|
#define MPT_FW_REV_MAGIC_ID_STRING "FwRev="
|
117 |
|
|
|
118 |
|
|
#define MPT_MAX_REQ_DEPTH 1023
|
119 |
|
|
#define MPT_DEFAULT_REQ_DEPTH 256
|
120 |
|
|
#define MPT_MIN_REQ_DEPTH 128
|
121 |
|
|
|
122 |
|
|
#define MPT_MAX_REPLY_DEPTH MPT_MAX_REQ_DEPTH
|
123 |
|
|
#define MPT_DEFAULT_REPLY_DEPTH 128
|
124 |
|
|
#define MPT_MIN_REPLY_DEPTH 8
|
125 |
|
|
#define MPT_MAX_REPLIES_PER_ISR 32
|
126 |
|
|
|
127 |
|
|
#define MPT_MAX_FRAME_SIZE 128
|
128 |
|
|
#define MPT_DEFAULT_FRAME_SIZE 128
|
129 |
|
|
|
130 |
|
|
#define MPT_REPLY_FRAME_SIZE 0x40 /* Must be a multiple of 8 */
|
131 |
|
|
|
132 |
|
|
#define MPT_SG_REQ_128_SCALE 1
|
133 |
|
|
#define MPT_SG_REQ_96_SCALE 2
|
134 |
|
|
#define MPT_SG_REQ_64_SCALE 4
|
135 |
|
|
|
136 |
|
|
#define CAN_SLEEP 1
|
137 |
|
|
#define NO_SLEEP 0
|
138 |
|
|
|
139 |
|
|
#define MPT_COALESCING_TIMEOUT 0x10
|
140 |
|
|
|
141 |
|
|
/*
|
142 |
|
|
* SCSI transfer rate defines.
|
143 |
|
|
*/
|
144 |
|
|
#define MPT_ULTRA320 0x08
|
145 |
|
|
#define MPT_ULTRA160 0x09
|
146 |
|
|
#define MPT_ULTRA2 0x0A
|
147 |
|
|
#define MPT_ULTRA 0x0C
|
148 |
|
|
#define MPT_FAST 0x19
|
149 |
|
|
#define MPT_SCSI 0x32
|
150 |
|
|
#define MPT_ASYNC 0xFF
|
151 |
|
|
|
152 |
|
|
#define MPT_NARROW 0
|
153 |
|
|
#define MPT_WIDE 1
|
154 |
|
|
|
155 |
|
|
#ifdef __KERNEL__ /* { */
|
156 |
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
157 |
|
|
|
158 |
|
|
#include <linux/proc_fs.h>
|
159 |
|
|
|
160 |
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
161 |
|
|
/*
|
162 |
|
|
* Attempt semi-consistent error & warning msgs across
|
163 |
|
|
* MPT drivers. NOTE: Users of these macro defs must
|
164 |
|
|
* themselves define their own MYNAM.
|
165 |
|
|
*/
|
166 |
|
|
#define MYIOC_s_INFO_FMT KERN_INFO MYNAM ": %s: "
|
167 |
|
|
#define MYIOC_s_NOTE_FMT KERN_NOTICE MYNAM ": %s: "
|
168 |
|
|
#define MYIOC_s_WARN_FMT KERN_WARNING MYNAM ": %s: WARNING - "
|
169 |
|
|
#define MYIOC_s_ERR_FMT KERN_ERR MYNAM ": %s: ERROR - "
|
170 |
|
|
|
171 |
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
172 |
|
|
/*
|
173 |
|
|
* MPT protocol driver defs...
|
174 |
|
|
*/
|
175 |
|
|
typedef enum {
|
176 |
|
|
MPTBASE_DRIVER, /* MPT base class */
|
177 |
|
|
MPTCTL_DRIVER, /* MPT ioctl class */
|
178 |
|
|
MPTSCSIH_DRIVER, /* MPT SCSI host (initiator) class */
|
179 |
|
|
MPTLAN_DRIVER, /* MPT LAN class */
|
180 |
|
|
MPTSTM_DRIVER, /* MPT SCSI target mode class */
|
181 |
|
|
MPTDMP_DRIVER, /* MPT Dynamic Multi-pathing class */
|
182 |
|
|
MPTUNKNOWN_DRIVER
|
183 |
|
|
} MPT_DRIVER_CLASS;
|
184 |
|
|
|
185 |
|
|
/*
|
186 |
|
|
* MPT adapter / port / bus / device info structures...
|
187 |
|
|
*/
|
188 |
|
|
|
189 |
|
|
typedef union _MPT_FRAME_TRACKER {
|
190 |
|
|
struct {
|
191 |
|
|
struct _MPT_FRAME_HDR *forw;
|
192 |
|
|
struct _MPT_FRAME_HDR *back;
|
193 |
|
|
u32 arg1;
|
194 |
|
|
u32 pad;
|
195 |
|
|
void *argp1;
|
196 |
|
|
#ifndef MPT_SCSI_USE_NEW_EH
|
197 |
|
|
void *argp2;
|
198 |
|
|
#endif
|
199 |
|
|
} linkage;
|
200 |
|
|
/*
|
201 |
|
|
* NOTE: When request frames are free, on the linkage structure
|
202 |
|
|
* contets are valid. All other values are invalid.
|
203 |
|
|
* In particular, do NOT reply on offset [2]
|
204 |
|
|
* (in words) being the * message context.
|
205 |
|
|
* The message context must be reset (computed via base address
|
206 |
|
|
* + an offset) prior to issuing any command.
|
207 |
|
|
*
|
208 |
|
|
* NOTE2: On non-32-bit systems, where pointers are LARGE,
|
209 |
|
|
* using the linkage pointers destroys our sacred MsgContext
|
210 |
|
|
* field contents. But we don't care anymore because these
|
211 |
|
|
* are now reset in mpt_put_msg_frame() just prior to sending
|
212 |
|
|
* a request off to the IOC.
|
213 |
|
|
*/
|
214 |
|
|
struct {
|
215 |
|
|
u32 __hdr[2];
|
216 |
|
|
/*
|
217 |
|
|
* The following _MUST_ match the location of the
|
218 |
|
|
* MsgContext field in the MPT message headers.
|
219 |
|
|
*/
|
220 |
|
|
union {
|
221 |
|
|
u32 MsgContext;
|
222 |
|
|
struct {
|
223 |
|
|
u16 req_idx; /* Request index */
|
224 |
|
|
u8 cb_idx; /* callback function index */
|
225 |
|
|
u8 rsvd;
|
226 |
|
|
} fld;
|
227 |
|
|
} msgctxu;
|
228 |
|
|
} hwhdr;
|
229 |
|
|
/*
|
230 |
|
|
* Remark: 32 bit identifier:
|
231 |
|
|
* 31-24: reserved
|
232 |
|
|
* 23-16: call back index
|
233 |
|
|
* 15-0 : request index
|
234 |
|
|
*/
|
235 |
|
|
} MPT_FRAME_TRACKER;
|
236 |
|
|
|
237 |
|
|
/*
|
238 |
|
|
* We might want to view/access a frame as:
|
239 |
|
|
* 1) generic request header
|
240 |
|
|
* 2) SCSIIORequest
|
241 |
|
|
* 3) SCSIIOReply
|
242 |
|
|
* 4) MPIDefaultReply
|
243 |
|
|
* 5) frame tracker
|
244 |
|
|
*/
|
245 |
|
|
typedef struct _MPT_FRAME_HDR {
|
246 |
|
|
union {
|
247 |
|
|
MPIHeader_t hdr;
|
248 |
|
|
SCSIIORequest_t scsireq;
|
249 |
|
|
SCSIIOReply_t sreply;
|
250 |
|
|
ConfigReply_t configreply;
|
251 |
|
|
MPIDefaultReply_t reply;
|
252 |
|
|
MPT_FRAME_TRACKER frame;
|
253 |
|
|
} u;
|
254 |
|
|
} MPT_FRAME_HDR;
|
255 |
|
|
|
256 |
|
|
#define MPT_REQ_MSGFLAGS_DROPME 0x80
|
257 |
|
|
|
258 |
|
|
/* Used for tracking the free request frames
|
259 |
|
|
* and free reply frames.
|
260 |
|
|
*/
|
261 |
|
|
typedef struct _MPT_Q_TRACKER {
|
262 |
|
|
MPT_FRAME_HDR *head;
|
263 |
|
|
MPT_FRAME_HDR *tail;
|
264 |
|
|
} MPT_Q_TRACKER;
|
265 |
|
|
|
266 |
|
|
|
267 |
|
|
typedef struct _MPT_SGL_HDR {
|
268 |
|
|
SGESimple32_t sge[1];
|
269 |
|
|
} MPT_SGL_HDR;
|
270 |
|
|
|
271 |
|
|
typedef struct _MPT_SGL64_HDR {
|
272 |
|
|
SGESimple64_t sge[1];
|
273 |
|
|
} MPT_SGL64_HDR;
|
274 |
|
|
|
275 |
|
|
|
276 |
|
|
typedef struct _Q_ITEM {
|
277 |
|
|
struct _Q_ITEM *forw;
|
278 |
|
|
struct _Q_ITEM *back;
|
279 |
|
|
} Q_ITEM;
|
280 |
|
|
|
281 |
|
|
typedef struct _Q_TRACKER {
|
282 |
|
|
struct _Q_ITEM *head;
|
283 |
|
|
struct _Q_ITEM *tail;
|
284 |
|
|
} Q_TRACKER;
|
285 |
|
|
|
286 |
|
|
typedef struct _MPT_DONE_Q {
|
287 |
|
|
struct _MPT_DONE_Q *forw;
|
288 |
|
|
struct _MPT_DONE_Q *back;
|
289 |
|
|
void *argp;
|
290 |
|
|
} MPT_DONE_Q;
|
291 |
|
|
|
292 |
|
|
typedef struct _DONE_Q_TRACKER {
|
293 |
|
|
MPT_DONE_Q *head;
|
294 |
|
|
MPT_DONE_Q *tail;
|
295 |
|
|
} DONE_Q_TRACKER;
|
296 |
|
|
|
297 |
|
|
/*
|
298 |
|
|
* Chip-specific stuff... FC929 delineates break between
|
299 |
|
|
* FC and Parallel SCSI parts. Do NOT re-order.
|
300 |
|
|
*/
|
301 |
|
|
|
302 |
|
|
typedef enum {
|
303 |
|
|
FC919X = 0x0819,
|
304 |
|
|
FC929X = 0x0829,
|
305 |
|
|
FC909 = 0x0909,
|
306 |
|
|
FC919 = 0x0919,
|
307 |
|
|
FC929 = 0x0929,
|
308 |
|
|
C1030 = 0x1030,
|
309 |
|
|
C1035 = 0x1035,
|
310 |
|
|
FCUNK = 0xFBAD
|
311 |
|
|
} CHIP_TYPE;
|
312 |
|
|
|
313 |
|
|
/*
|
314 |
|
|
* System interface register set
|
315 |
|
|
*/
|
316 |
|
|
|
317 |
|
|
typedef struct _SYSIF_REGS
|
318 |
|
|
{
|
319 |
|
|
u32 Doorbell; /* 00 System<->IOC Doorbell reg */
|
320 |
|
|
u32 WriteSequence; /* 04 Write Sequence register */
|
321 |
|
|
u32 Diagnostic; /* 08 Diagnostic register */
|
322 |
|
|
u32 TestBase; /* 0C Test Base Address */
|
323 |
|
|
u32 DiagRwData; /* 10 Read Write Data (fw download) */
|
324 |
|
|
u32 DiagRwAddress; /* 14 Read Write Address (fw download)*/
|
325 |
|
|
u32 Reserved1[6]; /* 18-2F reserved for future use */
|
326 |
|
|
u32 IntStatus; /* 30 Interrupt Status */
|
327 |
|
|
u32 IntMask; /* 34 Interrupt Mask */
|
328 |
|
|
u32 Reserved2[2]; /* 38-3F reserved for future use */
|
329 |
|
|
u32 RequestFifo; /* 40 Request Post/Free FIFO */
|
330 |
|
|
u32 ReplyFifo; /* 44 Reply Post/Free FIFO */
|
331 |
|
|
u32 Reserved3[2]; /* 48-4F reserved for future use */
|
332 |
|
|
u32 HostIndex; /* 50 Host Index register */
|
333 |
|
|
u32 Reserved4[15]; /* 54-8F */
|
334 |
|
|
u32 Fubar; /* 90 For Fubar usage */
|
335 |
|
|
u32 Reserved5[27]; /* 94-FF */
|
336 |
|
|
} SYSIF_REGS;
|
337 |
|
|
|
338 |
|
|
/*
|
339 |
|
|
* NOTE: Use MPI_{DOORBELL,WRITESEQ,DIAG}_xxx defs in lsi/mpi.h
|
340 |
|
|
* in conjunction with SYSIF_REGS accesses!
|
341 |
|
|
*/
|
342 |
|
|
|
343 |
|
|
|
344 |
|
|
/*
|
345 |
|
|
* Dynamic Multi-Pathing specific stuff...
|
346 |
|
|
*/
|
347 |
|
|
#define DMP_MAX_PATHS 8
|
348 |
|
|
|
349 |
|
|
typedef struct _PathInfo {
|
350 |
|
|
u8 ioc;
|
351 |
|
|
u8 target;
|
352 |
|
|
u8 pad;
|
353 |
|
|
u8 pflags;
|
354 |
|
|
} PathInfo;
|
355 |
|
|
|
356 |
|
|
#define PATHINFO_FLAGS_OWNED 0x01
|
357 |
|
|
#define PATHINFO_FLAGS_EXISTS 0x02
|
358 |
|
|
#define PATHINFO_FLAGS_AVAILABLE 0x04
|
359 |
|
|
#define PATHINFO_FLAGS_SECONDARY 0x08
|
360 |
|
|
|
361 |
|
|
#define PFLAGS_EXISTS_AND_AVAIL (PATHINFO_FLAGS_EXISTS|PATHINFO_FLAGS_AVAILABLE)
|
362 |
|
|
#define PFLAGS_AVAIL_AND_OWNED (PATHINFO_FLAGS_AVAILABLE|PATHINFO_FLAGS_OWNED)
|
363 |
|
|
|
364 |
|
|
typedef struct _ScsiCmndTracker {
|
365 |
|
|
void *head;
|
366 |
|
|
void *tail;
|
367 |
|
|
} ScsiCmndTracker;
|
368 |
|
|
|
369 |
|
|
|
370 |
|
|
/*
|
371 |
|
|
* VirtDevice - FC LUN device or SCSI target device
|
372 |
|
|
* (used to be FCSCSI_TARGET)
|
373 |
|
|
*/
|
374 |
|
|
typedef struct _VirtDevice {
|
375 |
|
|
struct _VirtDevice *forw;
|
376 |
|
|
struct _VirtDevice *back;
|
377 |
|
|
struct scsi_device *device;
|
378 |
|
|
rwlock_t VdevLock;
|
379 |
|
|
int ref_cnt;
|
380 |
|
|
u8 tflags;
|
381 |
|
|
u8 ioc_id;
|
382 |
|
|
u8 target_id;
|
383 |
|
|
u8 bus_id;
|
384 |
|
|
u8 minSyncFactor; /* 0xFF is async */
|
385 |
|
|
u8 maxOffset; /* 0 if async */
|
386 |
|
|
u8 maxWidth; /* 0 if narrow, 1 if wide*/
|
387 |
|
|
u8 negoFlags; /* bit field, 0 if WDTR/SDTR/QAS allowed */
|
388 |
|
|
u8 raidVolume; /* set, if RAID Volume */
|
389 |
|
|
u8 type; /* byte 0 of Inquiry data */
|
390 |
|
|
u8 cflags; /* controller flags */
|
391 |
|
|
u8 rsvd1raid;
|
392 |
|
|
int npaths;
|
393 |
|
|
u16 fc_phys_lun;
|
394 |
|
|
u16 fc_xlat_lun;
|
395 |
|
|
int stall_detected;
|
396 |
|
|
PathInfo path[DMP_MAX_PATHS];
|
397 |
|
|
struct timer_list stall_timer;
|
398 |
|
|
struct timer_list retry_timer;
|
399 |
|
|
struct timer_list gone_timer;
|
400 |
|
|
ScsiCmndTracker WaitQ;
|
401 |
|
|
ScsiCmndTracker SentQ;
|
402 |
|
|
ScsiCmndTracker DoneQ;
|
403 |
|
|
u32 num_luns;
|
404 |
|
|
u32 luns[8]; /* Max LUNs is 256 */
|
405 |
|
|
u8 pad[4];
|
406 |
|
|
u8 inq_data[8];
|
407 |
|
|
/* IEEE Registered Extended Identifier
|
408 |
|
|
obtained via INQUIRY VPD page 0x83 */
|
409 |
|
|
/* NOTE: Do not separate uniq_prepad and uniq_data
|
410 |
|
|
as they are treateed as a single entity in the code */
|
411 |
|
|
u8 uniq_prepad[8];
|
412 |
|
|
u8 uniq_data[20];
|
413 |
|
|
u8 pad2[4];
|
414 |
|
|
} VirtDevice;
|
415 |
|
|
|
416 |
|
|
/*
|
417 |
|
|
* Fibre Channel (SCSI) target device and associated defines...
|
418 |
|
|
*/
|
419 |
|
|
#define MPT_TARGET_DEFAULT_DV_STATUS 0
|
420 |
|
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,55)
|
421 |
|
|
#define MPT_TARGET_FLAGS_CONFIGURED 0x02
|
422 |
|
|
#define MPT_TARGET_FLAGS_Q_YES 0x08
|
423 |
|
|
#else
|
424 |
|
|
#define MPT_TARGET_FLAGS_VALID_NEGO 0x01
|
425 |
|
|
#define MPT_TARGET_FLAGS_VALID_INQUIRY 0x02
|
426 |
|
|
#define MPT_TARGET_FLAGS_Q_YES 0x08
|
427 |
|
|
#define MPT_TARGET_FLAGS_VALID_56 0x10
|
428 |
|
|
#define MPT_TARGET_FLAGS_SAF_TE_ISSUED 0x20
|
429 |
|
|
#endif
|
430 |
|
|
|
431 |
|
|
#define MPT_TARGET_NO_NEGO_WIDE 0x01
|
432 |
|
|
#define MPT_TARGET_NO_NEGO_SYNC 0x02
|
433 |
|
|
#define MPT_TARGET_NO_NEGO_QAS 0x04
|
434 |
|
|
|
435 |
|
|
typedef struct _VirtDevTracker {
|
436 |
|
|
struct _VirtDevice *head;
|
437 |
|
|
struct _VirtDevice *tail;
|
438 |
|
|
rwlock_t VlistLock;
|
439 |
|
|
int pad;
|
440 |
|
|
} VirtDevTracker;
|
441 |
|
|
|
442 |
|
|
|
443 |
|
|
/*
|
444 |
|
|
* /proc/mpt interface
|
445 |
|
|
*/
|
446 |
|
|
typedef struct {
|
447 |
|
|
const char *name;
|
448 |
|
|
mode_t mode;
|
449 |
|
|
int pad;
|
450 |
|
|
read_proc_t *read_proc;
|
451 |
|
|
write_proc_t *write_proc;
|
452 |
|
|
} mpt_proc_entry_t;
|
453 |
|
|
|
454 |
|
|
#define MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len) \
|
455 |
|
|
do { \
|
456 |
|
|
len -= offset; \
|
457 |
|
|
if (len < request) { \
|
458 |
|
|
*eof = 1; \
|
459 |
|
|
if (len <= 0) \
|
460 |
|
|
return 0; \
|
461 |
|
|
} else \
|
462 |
|
|
len = request; \
|
463 |
|
|
*start = buf + offset; \
|
464 |
|
|
return len; \
|
465 |
|
|
} while (0)
|
466 |
|
|
|
467 |
|
|
|
468 |
|
|
/*
|
469 |
|
|
* IOCTL structure and associated defines
|
470 |
|
|
*/
|
471 |
|
|
|
472 |
|
|
#define MPT_IOCTL_STATUS_DID_IOCRESET 0x01 /* IOC Reset occurred on the current*/
|
473 |
|
|
#define MPT_IOCTL_STATUS_RF_VALID 0x02 /* The Reply Frame is VALID */
|
474 |
|
|
#define MPT_IOCTL_STATUS_TIMER_ACTIVE 0x04 /* The timer is running */
|
475 |
|
|
#define MPT_IOCTL_STATUS_SENSE_VALID 0x08 /* Sense data is valid */
|
476 |
|
|
#define MPT_IOCTL_STATUS_COMMAND_GOOD 0x10 /* Command Status GOOD */
|
477 |
|
|
#define MPT_IOCTL_STATUS_TMTIMER_ACTIVE 0x20 /* The TM timer is running */
|
478 |
|
|
#define MPT_IOCTL_STATUS_TM_FAILED 0x40 /* User TM request failed */
|
479 |
|
|
|
480 |
|
|
#define MPTCTL_RESET_OK 0x01 /* Issue Bus Reset */
|
481 |
|
|
|
482 |
|
|
typedef struct _MPT_IOCTL {
|
483 |
|
|
struct _MPT_ADAPTER *ioc;
|
484 |
|
|
struct timer_list timer; /* timer function for this adapter */
|
485 |
|
|
u8 ReplyFrame[MPT_DEFAULT_FRAME_SIZE]; /* reply frame data */
|
486 |
|
|
u8 sense[MPT_SENSE_BUFFER_ALLOC];
|
487 |
|
|
int wait_done; /* wake-up value for this ioc */
|
488 |
|
|
u8 rsvd;
|
489 |
|
|
u8 status; /* current command status */
|
490 |
|
|
u8 reset; /* 1 if bus reset allowed */
|
491 |
|
|
u8 target; /* target for reset */
|
492 |
|
|
void *tmPtr;
|
493 |
|
|
struct timer_list TMtimer; /* timer function for this adapter */
|
494 |
|
|
} MPT_IOCTL;
|
495 |
|
|
|
496 |
|
|
/*
|
497 |
|
|
* Event Structure and define
|
498 |
|
|
*/
|
499 |
|
|
#define MPTCTL_EVENT_LOG_SIZE (0x0000000A)
|
500 |
|
|
typedef struct _mpt_ioctl_events {
|
501 |
|
|
u32 event; /* Specified by define above */
|
502 |
|
|
u32 eventContext; /* Index or counter */
|
503 |
|
|
int data[2]; /* First 8 bytes of Event Data */
|
504 |
|
|
} MPT_IOCTL_EVENTS;
|
505 |
|
|
|
506 |
|
|
/*
|
507 |
|
|
* CONFIGPARM status defines
|
508 |
|
|
*/
|
509 |
|
|
#define MPT_CONFIG_GOOD MPI_IOCSTATUS_SUCCESS
|
510 |
|
|
#define MPT_CONFIG_ERROR 0x002F
|
511 |
|
|
|
512 |
|
|
/*
|
513 |
|
|
* Substructure to store SCSI specific configuration page data
|
514 |
|
|
*/
|
515 |
|
|
/* dvStatus defines: */
|
516 |
|
|
#define MPT_SCSICFG_NEGOTIATE 0x01 /* Negotiate on next IO */
|
517 |
|
|
#define MPT_SCSICFG_NEED_DV 0x02 /* Schedule DV */
|
518 |
|
|
#define MPT_SCSICFG_DV_PENDING 0x04 /* DV on this physical id pending */
|
519 |
|
|
#define MPT_SCSICFG_DV_NOT_DONE 0x08 /* DV has not been performed */
|
520 |
|
|
#define MPT_SCSICFG_BLK_NEGO 0x10 /* WriteSDP1 with WDTR and SDTR disabled */
|
521 |
|
|
#define MPT_SCSICFG_RELOAD_IOC_PG3 0x20 /* IOC Pg 3 data is obsolete */
|
522 |
|
|
/* Args passed to writeSDP1: */
|
523 |
|
|
#define MPT_SCSICFG_USE_NVRAM 0x01 /* WriteSDP1 using NVRAM */
|
524 |
|
|
#define MPT_SCSICFG_ALL_IDS 0x02 /* WriteSDP1 to all IDS */
|
525 |
|
|
/* #define MPT_SCSICFG_BLK_NEGO 0x10 WriteSDP1 with WDTR and SDTR disabled */
|
526 |
|
|
|
527 |
|
|
typedef struct _ScsiCfgData {
|
528 |
|
|
u32 PortFlags;
|
529 |
|
|
int *nvram; /* table of device NVRAM values */
|
530 |
|
|
IOCPage3_t *pIocPg3; /* table of physical disks */
|
531 |
|
|
IOCPage4_t *pIocPg4; /* SEP devices addressing */
|
532 |
|
|
dma_addr_t IocPg4_dma; /* Phys Addr of IOCPage4 data */
|
533 |
|
|
int IocPg4Sz; /* IOCPage4 size */
|
534 |
|
|
u8 dvStatus[MPT_MAX_SCSI_DEVICES];
|
535 |
|
|
int isRaid; /* bit field, 1 if RAID */
|
536 |
|
|
u8 minSyncFactor; /* 0xFF if async */
|
537 |
|
|
u8 maxSyncOffset; /* 0 if async */
|
538 |
|
|
u8 maxBusWidth; /* 0 if narrow, 1 if wide */
|
539 |
|
|
u8 busType; /* SE, LVD, HD */
|
540 |
|
|
u8 sdp1version; /* SDP1 version */
|
541 |
|
|
u8 sdp1length; /* SDP1 length */
|
542 |
|
|
u8 sdp0version; /* SDP0 version */
|
543 |
|
|
u8 sdp0length; /* SDP0 length */
|
544 |
|
|
u8 dvScheduled; /* 1 if scheduled */
|
545 |
|
|
u8 forceDv; /* 1 to force DV scheduling */
|
546 |
|
|
u8 noQas; /* Disable QAS for this adapter */
|
547 |
|
|
u8 Saf_Te; /* 1 to force all Processors as SAF-TE if Inquiry data length is too short to check for SAF-TE */
|
548 |
|
|
u8 rsvd[1];
|
549 |
|
|
} ScsiCfgData;
|
550 |
|
|
|
551 |
|
|
typedef struct _fw_image {
|
552 |
|
|
char *fw;
|
553 |
|
|
dma_addr_t fw_dma;
|
554 |
|
|
u32 size;
|
555 |
|
|
u32 rsvd;
|
556 |
|
|
} fw_image_t;
|
557 |
|
|
|
558 |
|
|
/*
|
559 |
|
|
* Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS
|
560 |
|
|
*/
|
561 |
|
|
typedef struct _MPT_ADAPTER
|
562 |
|
|
{
|
563 |
|
|
struct _MPT_ADAPTER *forw;
|
564 |
|
|
struct _MPT_ADAPTER *back;
|
565 |
|
|
int id; /* Unique adapter id N {0,1,2,...} */
|
566 |
|
|
int pci_irq; /* This irq */
|
567 |
|
|
char name[MPT_NAME_LENGTH]; /* "iocN" */
|
568 |
|
|
char *prod_name; /* "LSIFC9x9" */
|
569 |
|
|
volatile SYSIF_REGS *chip; /* == c8817000 (mmap) */
|
570 |
|
|
volatile SYSIF_REGS *pio_chip; /* Programmed IO (downloadboot) */
|
571 |
|
|
u32 mem_phys; /* == f4020000 (mmap) */
|
572 |
|
|
u32 pio_mem_phys; /* Programmed IO (downloadboot) */
|
573 |
|
|
int mem_size; /* mmap memory size */
|
574 |
|
|
int alloc_total;
|
575 |
|
|
u32 last_state;
|
576 |
|
|
int active;
|
577 |
|
|
u8 *reply_alloc; /* Reply frames alloc ptr */
|
578 |
|
|
dma_addr_t reply_alloc_dma;
|
579 |
|
|
MPT_FRAME_HDR *reply_frames; /* Reply msg frames - rounded up! */
|
580 |
|
|
dma_addr_t reply_frames_dma;
|
581 |
|
|
u32 reply_frames_low_dma;
|
582 |
|
|
int reply_depth; /* Num Allocated reply frames */
|
583 |
|
|
int reply_sz; /* Reply frame size */
|
584 |
|
|
CHIP_TYPE chip_type;
|
585 |
|
|
/* We (host driver) get to manage our own RequestQueue! */
|
586 |
|
|
u8 *req_alloc; /* Request frames alloc ptr */
|
587 |
|
|
dma_addr_t req_alloc_dma;
|
588 |
|
|
MPT_FRAME_HDR *req_frames; /* Request msg frames - rounded up! */
|
589 |
|
|
dma_addr_t req_frames_dma;
|
590 |
|
|
u32 req_frames_low_dma;
|
591 |
|
|
int req_depth; /* Number of request frames */
|
592 |
|
|
int req_sz; /* Request frame size (bytes) */
|
593 |
|
|
spinlock_t FreeQlock;
|
594 |
|
|
MPT_Q_TRACKER FreeQ;
|
595 |
|
|
/* Pool of SCSI sense buffers for commands coming from
|
596 |
|
|
* the SCSI mid-layer. We have one 256 byte sense buffer
|
597 |
|
|
* for each REQ entry.
|
598 |
|
|
*/
|
599 |
|
|
u8 *sense_buf_pool;
|
600 |
|
|
dma_addr_t sense_buf_pool_dma;
|
601 |
|
|
u32 sense_buf_low_dma;
|
602 |
|
|
int mtrr_reg;
|
603 |
|
|
struct pci_dev *pcidev; /* struct pci_dev pointer */
|
604 |
|
|
u8 *memmap; /* mmap address */
|
605 |
|
|
struct Scsi_Host *sh; /* Scsi Host pointer */
|
606 |
|
|
ScsiCfgData spi_data; /* Scsi config. data */
|
607 |
|
|
MPT_IOCTL *ioctl; /* ioctl data pointer */
|
608 |
|
|
struct proc_dir_entry *ioc_dentry;
|
609 |
|
|
struct _MPT_ADAPTER *alt_ioc; /* ptr to 929 bound adapter port */
|
610 |
|
|
spinlock_t diagLock; /* diagnostic reset lock */
|
611 |
|
|
int diagPending;
|
612 |
|
|
u32 biosVersion; /* BIOS version from IO Unit Page 2 */
|
613 |
|
|
int eventTypes; /* Event logging parameters */
|
614 |
|
|
int eventContext; /* Next event context */
|
615 |
|
|
int eventLogSize; /* Max number of cached events */
|
616 |
|
|
#ifdef MPTSCSIH_DBG_TIMEOUT
|
617 |
|
|
int timeout_hard;
|
618 |
|
|
int timeout_delta;
|
619 |
|
|
int timeout_cnt;
|
620 |
|
|
int timeout_maxcnt;
|
621 |
|
|
#endif
|
622 |
|
|
struct _mpt_ioctl_events *events; /* pointer to event log */
|
623 |
|
|
fw_image_t **cached_fw; /* Pointer to FW SG List */
|
624 |
|
|
Q_TRACKER configQ; /* linked list of config. requests */
|
625 |
|
|
int num_fw_frags; /* Number of SGE in FW SG List */
|
626 |
|
|
int hs_reply_idx;
|
627 |
|
|
#ifndef MFCNT
|
628 |
|
|
u32 pad0;
|
629 |
|
|
#else
|
630 |
|
|
u32 mfcnt;
|
631 |
|
|
#endif
|
632 |
|
|
u32 hs_req[MPT_MAX_FRAME_SIZE/sizeof(u32)];
|
633 |
|
|
u16 hs_reply[MPT_MAX_FRAME_SIZE/sizeof(u16)];
|
634 |
|
|
IOCFactsReply_t facts;
|
635 |
|
|
PortFactsReply_t pfacts[2];
|
636 |
|
|
FCPortPage0_t fc_port_page0[2];
|
637 |
|
|
LANPage0_t lan_cnfg_page0;
|
638 |
|
|
LANPage1_t lan_cnfg_page1;
|
639 |
|
|
u8 FirstWhoInit;
|
640 |
|
|
u8 upload_fw; /* If set, do a fw upload */
|
641 |
|
|
u8 reload_fw; /* Force a FW Reload on next reset */
|
642 |
|
|
u8 pad1[5];
|
643 |
|
|
} MPT_ADAPTER;
|
644 |
|
|
|
645 |
|
|
|
646 |
|
|
typedef struct _MPT_ADAPTER_TRACKER {
|
647 |
|
|
MPT_ADAPTER *head;
|
648 |
|
|
MPT_ADAPTER *tail;
|
649 |
|
|
} MPT_ADAPTER_TRACKER;
|
650 |
|
|
|
651 |
|
|
/*
|
652 |
|
|
* New return value convention:
|
653 |
|
|
* 1 = Ok to free associated request frame
|
654 |
|
|
* 0 = not Ok ...
|
655 |
|
|
*/
|
656 |
|
|
typedef int (*MPT_CALLBACK)(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
|
657 |
|
|
typedef int (*MPT_EVHANDLER)(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply);
|
658 |
|
|
typedef int (*MPT_RESETHANDLER)(MPT_ADAPTER *ioc, int reset_phase);
|
659 |
|
|
/* reset_phase defs */
|
660 |
|
|
#define MPT_IOC_PRE_RESET 0
|
661 |
|
|
#define MPT_IOC_POST_RESET 1
|
662 |
|
|
#define MPT_IOC_SETUP_RESET 2
|
663 |
|
|
|
664 |
|
|
/*
|
665 |
|
|
* Invent MPT host event (super-set of MPI Events)
|
666 |
|
|
* Fitted to 1030's 64-byte [max] request frame size
|
667 |
|
|
*/
|
668 |
|
|
typedef struct _MPT_HOST_EVENT {
|
669 |
|
|
EventNotificationReply_t MpiEvent; /* 8 32-bit words! */
|
670 |
|
|
u32 pad[6];
|
671 |
|
|
void *next;
|
672 |
|
|
} MPT_HOST_EVENT;
|
673 |
|
|
|
674 |
|
|
#define MPT_HOSTEVENT_IOC_BRINGUP 0x91
|
675 |
|
|
#define MPT_HOSTEVENT_IOC_RECOVER 0x92
|
676 |
|
|
|
677 |
|
|
/* Define the generic types based on the size
|
678 |
|
|
* of the dma_addr_t type.
|
679 |
|
|
*/
|
680 |
|
|
typedef struct _mpt_sge {
|
681 |
|
|
u32 FlagsLength;
|
682 |
|
|
dma_addr_t Address;
|
683 |
|
|
} MptSge_t;
|
684 |
|
|
|
685 |
|
|
#define mpt_addr_size() \
|
686 |
|
|
((sizeof(dma_addr_t) == sizeof(u64)) ? MPI_SGE_FLAGS_64_BIT_ADDRESSING : \
|
687 |
|
|
MPI_SGE_FLAGS_32_BIT_ADDRESSING)
|
688 |
|
|
|
689 |
|
|
#define mpt_msg_flags() \
|
690 |
|
|
((sizeof(dma_addr_t) == sizeof(u64)) ? MPI_SCSIIO_MSGFLGS_SENSE_WIDTH_64 : \
|
691 |
|
|
MPI_SCSIIO_MSGFLGS_SENSE_WIDTH_32)
|
692 |
|
|
|
693 |
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
694 |
|
|
/*
|
695 |
|
|
* Funky (private) macros...
|
696 |
|
|
*/
|
697 |
|
|
#ifdef MPT_DEBUG
|
698 |
|
|
#define dprintk(x) printk x
|
699 |
|
|
#else
|
700 |
|
|
#define dprintk(x)
|
701 |
|
|
#endif
|
702 |
|
|
|
703 |
|
|
#ifdef MPT_DEBUG_HANDSHAKE
|
704 |
|
|
#define dhsprintk(x) printk x
|
705 |
|
|
#else
|
706 |
|
|
#define dhsprintk(x)
|
707 |
|
|
#endif
|
708 |
|
|
|
709 |
|
|
//#if defined(MPT_DEBUG) || defined(MPT_DEBUG_MSG_FRAME)
|
710 |
|
|
#if defined(MPT_DEBUG_MSG_FRAME)
|
711 |
|
|
#define dmfprintk(x) printk x
|
712 |
|
|
#else
|
713 |
|
|
#define dmfprintk(x)
|
714 |
|
|
#endif
|
715 |
|
|
|
716 |
|
|
#ifdef MPT_DEBUG_IRQ
|
717 |
|
|
#define dirqprintk(x) printk x
|
718 |
|
|
#else
|
719 |
|
|
#define dirqprintk(x)
|
720 |
|
|
#endif
|
721 |
|
|
|
722 |
|
|
#ifdef MPT_DEBUG_SG
|
723 |
|
|
#define dsgprintk(x) printk x
|
724 |
|
|
#else
|
725 |
|
|
#define dsgprintk(x)
|
726 |
|
|
#endif
|
727 |
|
|
|
728 |
|
|
#if defined(MPT_DEBUG_DL) || defined(MPT_DEBUG)
|
729 |
|
|
#define ddlprintk(x) printk x
|
730 |
|
|
#else
|
731 |
|
|
#define ddlprintk(x)
|
732 |
|
|
#endif
|
733 |
|
|
|
734 |
|
|
|
735 |
|
|
#ifdef MPT_DEBUG_DV
|
736 |
|
|
#define ddvprintk(x) printk x
|
737 |
|
|
#else
|
738 |
|
|
#define ddvprintk(x)
|
739 |
|
|
#endif
|
740 |
|
|
|
741 |
|
|
#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
|
742 |
|
|
#define ddvtprintk(x) printk x
|
743 |
|
|
#else
|
744 |
|
|
#define ddvtprintk(x)
|
745 |
|
|
#endif
|
746 |
|
|
|
747 |
|
|
#ifdef MPT_DEBUG_IOCTL
|
748 |
|
|
#define dctlprintk(x) printk x
|
749 |
|
|
#else
|
750 |
|
|
#define dctlprintk(x)
|
751 |
|
|
#endif
|
752 |
|
|
|
753 |
|
|
#ifdef MPT_DEBUG_RESET
|
754 |
|
|
#define dtmprintk(x) printk x
|
755 |
|
|
#else
|
756 |
|
|
#define dtmprintk(x)
|
757 |
|
|
#endif
|
758 |
|
|
|
759 |
|
|
#ifdef MPT_DEBUG_NEH
|
760 |
|
|
#define nehprintk(x) printk x
|
761 |
|
|
#else
|
762 |
|
|
#define nehprintk(x)
|
763 |
|
|
#endif
|
764 |
|
|
|
765 |
|
|
#if defined(MPT_DEBUG_CONFIG) || defined(MPT_DEBUG)
|
766 |
|
|
#define dcprintk(x) printk x
|
767 |
|
|
#else
|
768 |
|
|
#define dcprintk(x)
|
769 |
|
|
#endif
|
770 |
|
|
|
771 |
|
|
#if defined(MPT_DEBUG_SCSI) || defined(MPT_DEBUG) || defined(MPT_DEBUG_MSG_FRAME)
|
772 |
|
|
#define dsprintk(x) printk x
|
773 |
|
|
#else
|
774 |
|
|
#define dsprintk(x)
|
775 |
|
|
#endif
|
776 |
|
|
|
777 |
|
|
|
778 |
|
|
#define MPT_INDEX_2_MFPTR(ioc,idx) \
|
779 |
|
|
(MPT_FRAME_HDR*)( (u8*)(ioc)->req_frames + (ioc)->req_sz * (idx) )
|
780 |
|
|
|
781 |
|
|
#define MFPTR_2_MPT_INDEX(ioc,mf) \
|
782 |
|
|
(int)( ((u8*)mf - (u8*)(ioc)->req_frames) / (ioc)->req_sz )
|
783 |
|
|
|
784 |
|
|
#define MPT_INDEX_2_RFPTR(ioc,idx) \
|
785 |
|
|
(MPT_FRAME_HDR*)( (u8*)(ioc)->reply_frames + (ioc)->req_sz * (idx) )
|
786 |
|
|
|
787 |
|
|
#define Q_INIT(q,type) (q)->head = (q)->tail = (type*)(q)
|
788 |
|
|
#define Q_IS_EMPTY(q) ((Q_ITEM*)(q)->head == (Q_ITEM*)(q))
|
789 |
|
|
|
790 |
|
|
#define Q_ADD_TAIL(qt,i,type) { \
|
791 |
|
|
Q_TRACKER *_qt = (Q_TRACKER*)(qt); \
|
792 |
|
|
Q_ITEM *oldTail = _qt->tail; \
|
793 |
|
|
(i)->forw = (type*)_qt; \
|
794 |
|
|
(i)->back = (type*)oldTail; \
|
795 |
|
|
oldTail->forw = (Q_ITEM*)(i); \
|
796 |
|
|
_qt->tail = (Q_ITEM*)(i); \
|
797 |
|
|
}
|
798 |
|
|
|
799 |
|
|
#define Q_ADD_HEAD(qt,i,type) { \
|
800 |
|
|
Q_TRACKER *_qt = (Q_TRACKER*)(qt); \
|
801 |
|
|
Q_ITEM *oldHead = _qt->head; \
|
802 |
|
|
(i)->forw = (type*)oldHead; \
|
803 |
|
|
(i)->back = (type*)_qt; \
|
804 |
|
|
oldHead->back = (Q_ITEM*)(i); \
|
805 |
|
|
_qt->head = (Q_ITEM*)(i); \
|
806 |
|
|
}
|
807 |
|
|
|
808 |
|
|
#define Q_DEL_ITEM(i) { \
|
809 |
|
|
Q_ITEM *_forw = (Q_ITEM*)(i)->forw; \
|
810 |
|
|
Q_ITEM *_back = (Q_ITEM*)(i)->back; \
|
811 |
|
|
_back->forw = _forw; \
|
812 |
|
|
_forw->back = _back; \
|
813 |
|
|
}
|
814 |
|
|
|
815 |
|
|
#define SWAB4(value) \
|
816 |
|
|
(u32)( (((value) & 0x000000ff) << 24) \
|
817 |
|
|
| (((value) & 0x0000ff00) << 8) \
|
818 |
|
|
| (((value) & 0x00ff0000) >> 8) \
|
819 |
|
|
| (((value) & 0xff000000) >> 24) )
|
820 |
|
|
|
821 |
|
|
|
822 |
|
|
#if defined(MPT_DEBUG) || defined(MPT_DEBUG_MSG_FRAME)
|
823 |
|
|
#define DBG_DUMP_REPLY_FRAME(mfp) \
|
824 |
|
|
{ u32 *m = (u32 *)(mfp); \
|
825 |
|
|
int i, n = (le32_to_cpu(m[0]) & 0x00FF0000) >> 16; \
|
826 |
|
|
printk(KERN_INFO " "); \
|
827 |
|
|
for (i=0; i<n; i++) \
|
828 |
|
|
printk(" %08x", le32_to_cpu(m[i])); \
|
829 |
|
|
printk("\n"); \
|
830 |
|
|
}
|
831 |
|
|
#define DBG_DUMP_REQUEST_FRAME_HDR(mfp) \
|
832 |
|
|
{ int i, n = 3; \
|
833 |
|
|
u32 *m = (u32 *)(mfp); \
|
834 |
|
|
printk(KERN_INFO " "); \
|
835 |
|
|
for (i=0; i<n; i++) \
|
836 |
|
|
printk(" %08x", le32_to_cpu(m[i])); \
|
837 |
|
|
printk("\n"); \
|
838 |
|
|
}
|
839 |
|
|
#else
|
840 |
|
|
#define DBG_DUMP_REPLY_FRAME(mfp)
|
841 |
|
|
#define DBG_DUMP_REQUEST_FRAME_HDR(mfp)
|
842 |
|
|
#endif
|
843 |
|
|
|
844 |
|
|
|
845 |
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
846 |
|
|
|
847 |
|
|
/*
|
848 |
|
|
* MPT_SCSI_HOST defines - Used by the IOCTL and the SCSI drivers
|
849 |
|
|
* Private to the driver.
|
850 |
|
|
*/
|
851 |
|
|
/* LOCAL structure and fields used when processing
|
852 |
|
|
* internally generated commands. These include:
|
853 |
|
|
* bus scan, dv and config requests.
|
854 |
|
|
*/
|
855 |
|
|
typedef struct _MPT_LOCAL_REPLY {
|
856 |
|
|
ConfigPageHeader_t header;
|
857 |
|
|
int completion;
|
858 |
|
|
u8 sense[SCSI_STD_SENSE_BYTES];
|
859 |
|
|
u8 scsiStatus;
|
860 |
|
|
u8 skip;
|
861 |
|
|
u32 pad;
|
862 |
|
|
} MPT_LOCAL_REPLY;
|
863 |
|
|
|
864 |
|
|
#define MPT_HOST_BUS_UNKNOWN (0xFF)
|
865 |
|
|
#define MPT_HOST_TOO_MANY_TM (0x05)
|
866 |
|
|
#define MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
|
867 |
|
|
#define MPT_HOST_NO_CHAIN (0xFFFFFFFF)
|
868 |
|
|
#define MPT_NVRAM_MASK_TIMEOUT (0x000000FF)
|
869 |
|
|
#define MPT_NVRAM_SYNC_MASK (0x0000FF00)
|
870 |
|
|
#define MPT_NVRAM_SYNC_SHIFT (8)
|
871 |
|
|
#define MPT_NVRAM_DISCONNECT_ENABLE (0x00010000)
|
872 |
|
|
#define MPT_NVRAM_ID_SCAN_ENABLE (0x00020000)
|
873 |
|
|
#define MPT_NVRAM_LUN_SCAN_ENABLE (0x00040000)
|
874 |
|
|
#define MPT_NVRAM_TAG_QUEUE_ENABLE (0x00080000)
|
875 |
|
|
#define MPT_NVRAM_WIDE_DISABLE (0x00100000)
|
876 |
|
|
#define MPT_NVRAM_BOOT_CHOICE (0x00200000)
|
877 |
|
|
|
878 |
|
|
#ifdef MPT_SCSI_USE_NEW_EH
|
879 |
|
|
/* The TM_STATE variable is used to provide strict single threading of TM
|
880 |
|
|
* requests as well as communicate TM error conditions.
|
881 |
|
|
*/
|
882 |
|
|
#define TM_STATE_NONE (0)
|
883 |
|
|
#define TM_STATE_IN_PROGRESS (1)
|
884 |
|
|
#define TM_STATE_ERROR (2)
|
885 |
|
|
#endif
|
886 |
|
|
|
887 |
|
|
typedef struct _MPT_SCSI_HOST {
|
888 |
|
|
MPT_ADAPTER *ioc;
|
889 |
|
|
int port;
|
890 |
|
|
u32 pad0;
|
891 |
|
|
struct scsi_cmnd **ScsiLookup;
|
892 |
|
|
/* Pool of buffers for chaining. ReqToChain
|
893 |
|
|
* and ChainToChain track index of chain buffers.
|
894 |
|
|
* ChainBuffer (DMA) virt/phys addresses.
|
895 |
|
|
* FreeChainQ (lock) locking mechanisms.
|
896 |
|
|
*/
|
897 |
|
|
int *ReqToChain;
|
898 |
|
|
int *ChainToChain;
|
899 |
|
|
u8 *ChainBuffer;
|
900 |
|
|
dma_addr_t ChainBufferDMA;
|
901 |
|
|
MPT_Q_TRACKER FreeChainQ;
|
902 |
|
|
spinlock_t FreeChainQlock;
|
903 |
|
|
u32 qtag_tick;
|
904 |
|
|
VirtDevice **Targets;
|
905 |
|
|
MPT_LOCAL_REPLY *pLocal; /* used for internal commands */
|
906 |
|
|
struct timer_list timer;
|
907 |
|
|
struct timer_list TMtimer; /* Timer for TM commands ONLY */
|
908 |
|
|
/* Pool of memory for holding SCpnts before doing
|
909 |
|
|
* OS callbacks. freeQ is the free pool.
|
910 |
|
|
*/
|
911 |
|
|
u8 *memQ;
|
912 |
|
|
DONE_Q_TRACKER freeQ;
|
913 |
|
|
DONE_Q_TRACKER doneQ; /* Holds Linux formmatted requests */
|
914 |
|
|
DONE_Q_TRACKER pendingQ; /* Holds MPI formmatted requests */
|
915 |
|
|
MPT_Q_TRACKER taskQ; /* TM request Q */
|
916 |
|
|
spinlock_t freedoneQlock;
|
917 |
|
|
int taskQcnt;
|
918 |
|
|
int num_chain; /* Number of chain buffers */
|
919 |
|
|
int max_sge; /* Max No of SGE*/
|
920 |
|
|
u8 numTMrequests;
|
921 |
|
|
u8 tmPending;
|
922 |
|
|
u8 resetPending;
|
923 |
|
|
u8 is_spi; /* Parallel SCSI i/f */
|
924 |
|
|
u8 negoNvram; /* DV disabled, nego NVRAM */
|
925 |
|
|
u8 is_multipath; /* Multi-path compatible */
|
926 |
|
|
#ifdef MPT_SCSI_USE_NEW_EH
|
927 |
|
|
u8 tmState;
|
928 |
|
|
u8 rsvd[1];
|
929 |
|
|
#else
|
930 |
|
|
u8 rsvd[2];
|
931 |
|
|
#endif
|
932 |
|
|
MPT_FRAME_HDR *tmPtr; /* Ptr to TM request*/
|
933 |
|
|
MPT_FRAME_HDR *cmdPtr; /* Ptr to nonOS request */
|
934 |
|
|
struct scsi_cmnd *abortSCpnt;
|
935 |
|
|
MPT_LOCAL_REPLY localReply; /* internal cmd reply struct */
|
936 |
|
|
unsigned long hard_resets; /* driver forced bus resets count */
|
937 |
|
|
unsigned long soft_resets; /* fw/external bus resets count */
|
938 |
|
|
unsigned long timeouts; /* cmd timeouts */
|
939 |
|
|
ushort sel_timeout[MPT_MAX_FC_DEVICES];
|
940 |
|
|
} MPT_SCSI_HOST;
|
941 |
|
|
|
942 |
|
|
/*
|
943 |
|
|
* Structure for overlaying onto scsi_cmnd->SCp area
|
944 |
|
|
* NOTE: SCp area is 36 bytes min, 44 bytes max?
|
945 |
|
|
*/
|
946 |
|
|
typedef struct _scPrivate {
|
947 |
|
|
struct scsi_cmnd *forw;
|
948 |
|
|
struct scsi_cmnd *back;
|
949 |
|
|
void *p1;
|
950 |
|
|
void *p2;
|
951 |
|
|
u8 io_path_id; /* DMP */
|
952 |
|
|
u8 pad[7];
|
953 |
|
|
} scPrivate;
|
954 |
|
|
|
955 |
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
956 |
|
|
/*
|
957 |
|
|
* More Dynamic Multi-Pathing stuff...
|
958 |
|
|
*/
|
959 |
|
|
|
960 |
|
|
/* Forward decl, a strange C thing, to prevent gcc compiler warnings */
|
961 |
|
|
struct scsi_cmnd;
|
962 |
|
|
|
963 |
|
|
/*
|
964 |
|
|
* DMP service layer structure / API interface
|
965 |
|
|
*/
|
966 |
|
|
typedef struct _DmpServices {
|
967 |
|
|
VirtDevTracker VdevList;
|
968 |
|
|
struct semaphore *Daemon;
|
969 |
|
|
int (*ScsiPathSelect)
|
970 |
|
|
(struct scsi_cmnd *, MPT_SCSI_HOST **hd, int *target, int *lun);
|
971 |
|
|
int (*DmpIoDoneChk)
|
972 |
|
|
(MPT_SCSI_HOST *, struct scsi_cmnd *,
|
973 |
|
|
SCSIIORequest_t *,
|
974 |
|
|
SCSIIOReply_t *);
|
975 |
|
|
void (*mptscsih_scanVlist)
|
976 |
|
|
(MPT_SCSI_HOST *, int portnum);
|
977 |
|
|
int (*ScsiAbort)
|
978 |
|
|
(struct scsi_cmnd *);
|
979 |
|
|
int (*ScsiBusReset)
|
980 |
|
|
(struct scsi_cmnd *);
|
981 |
|
|
} DmpServices_t;
|
982 |
|
|
|
983 |
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
984 |
|
|
/*
|
985 |
|
|
* Generic structure passed to the base mpt_config function.
|
986 |
|
|
*/
|
987 |
|
|
typedef struct _x_config_parms {
|
988 |
|
|
Q_ITEM linkage; /* linked list */
|
989 |
|
|
struct timer_list timer; /* timer function for this request */
|
990 |
|
|
ConfigPageHeader_t *hdr;
|
991 |
|
|
dma_addr_t physAddr;
|
992 |
|
|
int wait_done; /* wait for this request */
|
993 |
|
|
u32 pageAddr; /* properly formatted */
|
994 |
|
|
u8 action;
|
995 |
|
|
u8 dir;
|
996 |
|
|
u8 timeout; /* seconds */
|
997 |
|
|
u8 pad1;
|
998 |
|
|
u16 status;
|
999 |
|
|
u16 pad2;
|
1000 |
|
|
} CONFIGPARMS;
|
1001 |
|
|
|
1002 |
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
1003 |
|
|
/*
|
1004 |
|
|
* Public entry points...
|
1005 |
|
|
*/
|
1006 |
|
|
extern int mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass);
|
1007 |
|
|
extern void mpt_deregister(int cb_idx);
|
1008 |
|
|
extern int mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc);
|
1009 |
|
|
extern void mpt_event_deregister(int cb_idx);
|
1010 |
|
|
extern int mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func);
|
1011 |
|
|
extern void mpt_reset_deregister(int cb_idx);
|
1012 |
|
|
extern int mpt_register_ascqops_strings(void *ascqTable, int ascqtbl_sz, const char **opsTable);
|
1013 |
|
|
extern void mpt_deregister_ascqops_strings(void);
|
1014 |
|
|
extern MPT_FRAME_HDR *mpt_get_msg_frame(int handle, int iocid);
|
1015 |
|
|
extern void mpt_free_msg_frame(int handle, int iocid, MPT_FRAME_HDR *mf);
|
1016 |
|
|
extern void mpt_put_msg_frame(int handle, int iocid, MPT_FRAME_HDR *mf);
|
1017 |
|
|
extern void mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr);
|
1018 |
|
|
extern void mpt_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr);
|
1019 |
|
|
|
1020 |
|
|
extern int mpt_send_handshake_request(int handle, int iocid, int reqBytes, u32 *req, int sleepFlag);
|
1021 |
|
|
extern int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply, int maxwait, int sleepFlag);
|
1022 |
|
|
extern int mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp);
|
1023 |
|
|
extern MPT_ADAPTER *mpt_adapter_find_first(void);
|
1024 |
|
|
extern MPT_ADAPTER *mpt_adapter_find_next(MPT_ADAPTER *prev);
|
1025 |
|
|
extern u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
|
1026 |
|
|
extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan);
|
1027 |
|
|
extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
|
1028 |
|
|
extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
|
1029 |
|
|
extern void *mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size, int *frags, int *alloc_sz);
|
1030 |
|
|
extern void mpt_free_fw_memory(MPT_ADAPTER *ioc, fw_image_t **alt_img);
|
1031 |
|
|
extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
|
1032 |
|
|
|
1033 |
|
|
/*
|
1034 |
|
|
* Public data decl's...
|
1035 |
|
|
*/
|
1036 |
|
|
extern MPT_ADAPTER *mpt_adapters[MPT_MAX_ADAPTERS];
|
1037 |
|
|
extern struct proc_dir_entry *mpt_proc_root_dir;
|
1038 |
|
|
extern DmpServices_t *DmpService;
|
1039 |
|
|
|
1040 |
|
|
extern int mpt_lan_index; /* needed by mptlan.c */
|
1041 |
|
|
extern int mpt_stm_index; /* needed by mptstm.c */
|
1042 |
|
|
|
1043 |
|
|
extern void *mpt_v_ASCQ_TablePtr;
|
1044 |
|
|
extern const char **mpt_ScsiOpcodesPtr;
|
1045 |
|
|
extern int mpt_ASCQ_TableSz;
|
1046 |
|
|
|
1047 |
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
1048 |
|
|
#endif /* } __KERNEL__ */
|
1049 |
|
|
|
1050 |
|
|
/*
|
1051 |
|
|
* More (public) macros...
|
1052 |
|
|
*/
|
1053 |
|
|
#ifndef MIN
|
1054 |
|
|
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
1055 |
|
|
#endif
|
1056 |
|
|
#ifndef MAX
|
1057 |
|
|
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
1058 |
|
|
#endif
|
1059 |
|
|
|
1060 |
|
|
#ifndef offsetof
|
1061 |
|
|
#define offsetof(t, m) ((size_t) (&((t *)0)->m))
|
1062 |
|
|
#endif
|
1063 |
|
|
|
1064 |
|
|
#if defined(__alpha__) || defined(__sparc_v9__) || defined(__ia64__) || defined(__x86_64__)
|
1065 |
|
|
#define CAST_U32_TO_PTR(x) ((void *)(u64)x)
|
1066 |
|
|
#define CAST_PTR_TO_U32(x) ((u32)(u64)x)
|
1067 |
|
|
#else
|
1068 |
|
|
#define CAST_U32_TO_PTR(x) ((void *)x)
|
1069 |
|
|
#define CAST_PTR_TO_U32(x) ((u32)x)
|
1070 |
|
|
#endif
|
1071 |
|
|
|
1072 |
|
|
#define MPT_PROTOCOL_FLAGS_c_c_c_c(pflags) \
|
1073 |
|
|
((pflags) & MPI_PORTFACTS_PROTOCOL_INITIATOR) ? 'I' : 'i', \
|
1074 |
|
|
((pflags) & MPI_PORTFACTS_PROTOCOL_TARGET) ? 'T' : 't', \
|
1075 |
|
|
((pflags) & MPI_PORTFACTS_PROTOCOL_LAN) ? 'L' : 'l', \
|
1076 |
|
|
((pflags) & MPI_PORTFACTS_PROTOCOL_LOGBUSADDR) ? 'B' : 'b'
|
1077 |
|
|
|
1078 |
|
|
/*
|
1079 |
|
|
* Shifted SGE Defines - Use in SGE with FlagsLength member.
|
1080 |
|
|
* Otherwise, use MPI_xxx defines (refer to "lsi/mpi.h" header).
|
1081 |
|
|
* Defaults: 32 bit SGE, SYSTEM_ADDRESS if direction bit is 0, read
|
1082 |
|
|
*/
|
1083 |
|
|
#define MPT_TRANSFER_IOC_TO_HOST (0x00000000)
|
1084 |
|
|
#define MPT_TRANSFER_HOST_TO_IOC (0x04000000)
|
1085 |
|
|
#define MPT_SGE_FLAGS_LAST_ELEMENT (0x80000000)
|
1086 |
|
|
#define MPT_SGE_FLAGS_END_OF_BUFFER (0x40000000)
|
1087 |
|
|
#define MPT_SGE_FLAGS_LOCAL_ADDRESS (0x08000000)
|
1088 |
|
|
#define MPT_SGE_FLAGS_DIRECTION (0x04000000)
|
1089 |
|
|
#define MPT_SGE_FLAGS_ADDRESSING (mpt_addr_size() << MPI_SGE_FLAGS_SHIFT)
|
1090 |
|
|
#define MPT_SGE_FLAGS_END_OF_LIST (0x01000000)
|
1091 |
|
|
|
1092 |
|
|
#define MPT_SGE_FLAGS_TRANSACTION_ELEMENT (0x00000000)
|
1093 |
|
|
#define MPT_SGE_FLAGS_SIMPLE_ELEMENT (0x10000000)
|
1094 |
|
|
#define MPT_SGE_FLAGS_CHAIN_ELEMENT (0x30000000)
|
1095 |
|
|
#define MPT_SGE_FLAGS_ELEMENT_MASK (0x30000000)
|
1096 |
|
|
|
1097 |
|
|
#define MPT_SGE_FLAGS_SSIMPLE_READ \
|
1098 |
|
|
(MPT_SGE_FLAGS_LAST_ELEMENT | \
|
1099 |
|
|
MPT_SGE_FLAGS_END_OF_BUFFER | \
|
1100 |
|
|
MPT_SGE_FLAGS_END_OF_LIST | \
|
1101 |
|
|
MPT_SGE_FLAGS_SIMPLE_ELEMENT | \
|
1102 |
|
|
MPT_SGE_FLAGS_ADDRESSING | \
|
1103 |
|
|
MPT_TRANSFER_IOC_TO_HOST)
|
1104 |
|
|
#define MPT_SGE_FLAGS_SSIMPLE_WRITE \
|
1105 |
|
|
(MPT_SGE_FLAGS_LAST_ELEMENT | \
|
1106 |
|
|
MPT_SGE_FLAGS_END_OF_BUFFER | \
|
1107 |
|
|
MPT_SGE_FLAGS_END_OF_LIST | \
|
1108 |
|
|
MPT_SGE_FLAGS_SIMPLE_ELEMENT | \
|
1109 |
|
|
MPT_SGE_FLAGS_ADDRESSING | \
|
1110 |
|
|
MPT_TRANSFER_HOST_TO_IOC)
|
1111 |
|
|
|
1112 |
|
|
/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
1113 |
|
|
#endif
|
1114 |
|
|
|