1 diff -Nur linux-2.4.20.org/drivers/scsi/i2odef.h linux-2.4.20/drivers/scsi/i2odef.h
2 --- linux-2.4.20.org/drivers/scsi/i2odef.h Wed Nov 5 08:47:58 2003
3 +++ linux-2.4.20/drivers/scsi/i2odef.h Wed Oct 16 00:00:00 2002
6 -#if !defined(_I2ODEF_H_)
10 -#if !defined(_I2OTYPES_)
15 - * Pragma macros. These are to assure appropriate alignment between
16 - * host/IOP as defined by the I2O Specification. Each one of the shared
17 - * header files includes these macros.
20 -#define PRAGMA_ALIGN_PUSH \
22 -#define PRAGMA_ALIGN_POP \
24 -#define PRAGMA_PACK_PUSH \
26 -#define PRAGMA_PACK_POP \
29 -/* Setup the basics */
34 -typedef unsigned char U8;
35 -typedef unsigned short U16;
37 -//typedef unsigned int U32;
39 -typedef unsigned long U32;
72 -/**************************************************************************/
76 -typedef struct _S64 {
81 -typedef struct _U64 {
86 -/* Pointer to Basics */
94 -/* Pointer to Unsigned Basics */
103 -typedef S32 I2O_ARG;
104 -typedef U32 I2O_COUNT;
105 -typedef U32 I2O_USECS;
106 -typedef U32 I2O_ADDR32;
107 -typedef U32 I2O_SIZE;
109 -#endif /* _I2OTYPES_ */
111 -/**************************************************************************/
113 -/* I2O BSA Block Read Message Control Flags */
115 -typedef U16 I2O_BSA_READ_FLAGS;
116 -#define I2O_BSA_RD_FLAG_DONT_RETRY 0x0001
117 -#define I2O_BSA_RD_FLAG_SOLO 0x0002
118 -#define I2O_BSA_RD_FLAG_CACHE_READ 0x0004
119 -#define I2O_BSA_RD_FLAG_READ_PREFETCH 0x0008
120 -#define I2O_BSA_RD_FLAG_CACHE_DATA 0x0010
122 -/* I2O BSA Block Write Message Control Flags */
124 -typedef U16 I2O_BSA_WRITE_FLAGS;
125 -#define I2O_BSA_WR_FLAG_DONT_RETRY 0x0001
126 -#define I2O_BSA_WR_FLAG_SOLO 0x0002
127 -#define I2O_BSA_WR_FLAG_DONT_CACHE 0x0004
128 -#define I2O_BSA_WR_FLAG_WRITE_THRU 0x0008
129 -#define I2O_BSA_WR_FLAG_WRITE_TO 0x0010
131 -/****************************************************************************/
133 -typedef U32 I2O_INITIATOR_CONTEXT;
134 -typedef U32 I2O_TRANSACTION_CONTEXT;
136 -typedef U32 I2O_PARAMETER_TID;
138 -/****************************************************************************/
139 -/* Message Frame defines and structures */
141 -/* Defines for the Version_Status field. */
143 -#define I2O_VERSION_10 0x00
144 -#define I2O_VERSION_11 0x01
146 -#define I2O_VERSION_OFFSET_NUMBER_MASK 0x07
147 -#define I2O_VERSION_OFFSET_SGL_TRL_OFFSET_MASK 0xF0
149 -/* Defines for the Message Flags Field. */
150 -/* Please Note the the FAIL bit is only set in the Transport Fail Message. */
151 -#define I2O_MESSAGE_FLAGS_STATIC 0x01
152 -#define I2O_MESSAGE_FLAGS_64BIT_CONTEXT 0x02
153 -#define I2O_MESSAGE_FLAGS_MULTIPLE 0x10
154 -#define I2O_MESSAGE_FLAGS_FAIL 0x20
155 -#define I2O_MESSAGE_FLAGS_LAST 0x40
156 -#define I2O_MESSAGE_FLAGS_REPLY 0x80
158 -/* Defines for Request Status Codes: Table 3-1 Reply Status Codes. */
160 -#define I2O_REPLY_STATUS_SUCCESS 0x00
161 -#define I2O_REPLY_STATUS_ABORT_DIRTY 0x01
162 -#define I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER 0x02
163 -#define I2O_REPLY_STATUS_ABORT_PARTIAL_TRANSFER 0x03
164 -#define I2O_REPLY_STATUS_ERROR_DIRTY 0x04
165 -#define I2O_REPLY_STATUS_ERROR_NO_DATA_TRANSFER 0x05
166 -#define I2O_REPLY_STATUS_ERROR_PARTIAL_TRANSFER 0x06
167 -#define I2O_REPLY_STATUS_PROCESS_ABORT_DIRTY 0x08
168 -#define I2O_REPLY_STATUS_PROCESS_ABORT_NO_DATA_TRANSFER 0x09
169 -#define I2O_REPLY_STATUS_PROCESS_ABORT_PARTIAL_TRANSFER 0x0A
170 -#define I2O_REPLY_STATUS_TRANSACTION_ERROR 0x0B
171 -#define I2O_REPLY_STATUS_PROGRESS_REPORT 0x80
173 -/* DetailedStatusCode defines for ALL messages: Table 3-2 Detailed Status Codes. */
175 -#define I2O_DETAIL_STATUS_SUCCESS 0x0000
176 -#define I2O_DETAIL_STATUS_BAD_KEY 0x0002
177 -#define I2O_DETAIL_STATUS_TCL_ERROR 0x0003
178 -#define I2O_DETAIL_STATUS_REPLY_BUFFER_FULL 0x0004
179 -#define I2O_DETAIL_STATUS_NO_SUCH_PAGE 0x0005
180 -#define I2O_DETAIL_STATUS_INSUFFICIENT_RESOURCE_SOFT 0x0006
181 -#define I2O_DETAIL_STATUS_INSUFFICIENT_RESOURCE_HARD 0x0007
182 -#define I2O_DETAIL_STATUS_CHAIN_BUFFER_TOO_LARGE 0x0009
183 -#define I2O_DETAIL_STATUS_UNSUPPORTED_FUNCTION 0x000A
184 -#define I2O_DETAIL_STATUS_DEVICE_LOCKED 0x000B
185 -#define I2O_DETAIL_STATUS_DEVICE_RESET 0x000C
186 -#define I2O_DETAIL_STATUS_INAPPROPRIATE_FUNCTION 0x000D
187 -#define I2O_DETAIL_STATUS_INVALID_INITIATOR_ADDRESS 0x000E
188 -#define I2O_DETAIL_STATUS_INVALID_MESSAGE_FLAGS 0x000F
189 -#define I2O_DETAIL_STATUS_INVALID_OFFSET 0x0010
190 -#define I2O_DETAIL_STATUS_INVALID_PARAMETER 0x0011
191 -#define I2O_DETAIL_STATUS_INVALID_REQUEST 0x0012
192 -#define I2O_DETAIL_STATUS_INVALID_TARGET_ADDRESS 0x0013
193 -#define I2O_DETAIL_STATUS_MESSAGE_TOO_LARGE 0x0014
194 -#define I2O_DETAIL_STATUS_MESSAGE_TOO_SMALL 0x0015
195 -#define I2O_DETAIL_STATUS_MISSING_PARAMETER 0x0016
196 -#define I2O_DETAIL_STATUS_TIMEOUT 0x0017
197 -#define I2O_DETAIL_STATUS_UNKNOWN_ERROR 0x0018
198 -#define I2O_DETAIL_STATUS_UNKNOWN_FUNCTION 0x0019
199 -#define I2O_DETAIL_STATUS_UNSUPPORTED_VERSION 0x001A
200 -#define I2O_DEATIL_STATUS_DEVICE_BUSY 0x001B
201 -#define I2O_DETAIL_STATUS_DEVICE_NOT_AVAILABLE 0x001C
203 -/* Common I2O Field sizes */
205 -#define I2O_TID_SZ 12
206 -#define I2O_FUNCTION_SZ 8
207 -#define I2O_UNIT_ID_SZ 16
208 -#define I2O_SEGMENT_NUMBER_SZ 12
210 -#define I2O_IOP_ID_SZ 12
211 -#define I2O_GROUP_ID_SZ 16
212 -#define I2O_IOP_STATE_SZ 8
213 -#define I2O_MESSENGER_TYPE_SZ 8
215 -#define I2O_CLASS_ID_SZ 12
216 -#define I2O_CLASS_ORGANIZATION_ID_SZ 16
218 -#define I2O_4BIT_VERSION_SZ 4
219 -#define I2O_8BIT_FLAGS_SZ 8
220 -#define I2O_COMMON_LENGTH_FIELD_SZ 16
223 -#define I2O_DEVID_DESCRIPTION_SZ 16
224 -#define I2O_DEVID_VENDOR_INFO_SZ 16
225 -#define I2O_DEVID_PRODUCT_INFO_SZ 16
226 -#define I2O_DEVID_REV_LEVEL_SZ 8
227 -#define I2O_MODULE_NAME_SZ 24
229 -#define I2O_BIOS_INFO_SZ 8
231 -#define I2O_RESERVED_4BITS 4
232 -#define I2O_RESERVED_8BITS 8
233 -#define I2O_RESERVED_12BITS 12
234 -#define I2O_RESERVED_16BITS 16
235 -#define I2O_RESERVED_20BITS 20
236 -#define I2O_RESERVED_24BITS 24
237 -#define I2O_RESERVED_28BITS 28
239 -/****************************************************************************/
241 -/* Common functions accross all classes. */
243 -#define I2O_PRIVATE_MESSAGE 0xFF
245 -/****************************************************************************/
246 -/* Class ID and Code Assignments */
249 -#define I2O_CLASS_VERSION_10 0x00
250 -#define I2O_CLASS_VERSION_11 0x01
252 -/* Class Code Names: Table 6-1 Class Code Assignments. */
253 -#define I2O_CLASS_EXECUTIVE 0x000
254 -#define I2O_CLASS_DDM 0x001
255 -#define I2O_CLASS_RANDOM_BLOCK_STORAGE 0x010
256 -#define I2O_CLASS_SEQUENTIAL_STORAGE 0x011
257 -#define I2O_CLASS_LAN 0x020
258 -#define I2O_CLASS_WAN 0x030
259 -#define I2O_CLASS_FIBRE_CHANNEL_PORT 0x040
260 -#define I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL 0x041
261 -#define I2O_CLASS_SCSI_PERIPHERAL 0x051
262 -#define I2O_CLASS_ATE_PORT 0x060
263 -#define I2O_CLASS_ATE_PERIPHERAL 0x061
264 -#define I2O_CLASS_FLOPPY_CONTROLLER 0x070
265 -#define I2O_CLASS_FLOPPY_DEVICE 0x071
266 -#define I2O_CLASS_BUS_ADAPTER_PORT 0x080
267 -/* Class Codes 0x090 - 0x09f are reserved for Peer-to-Peer classes */
268 -#define I2O_CLASS_MATCH_ANYCLASS 0xffffffff
270 -#define I2O_SUBCLASS_i960 0x001
271 -#define I2O_SUBCLASS_HDM 0x020
272 -#define I2O_SUBCLASS_ISM 0x021
275 -/*********************************************************************/
277 -#define I2O_MAX_SERIAL_NUMBER_SZ 256
279 -/****************************************************************************/
281 -/* I2O Message Frame common for all messages */
283 -typedef struct _I2O_MESSAGE_FRAME {
287 - BF TargetAddress:I2O_TID_SZ;
288 - BF InitiatorAddress:I2O_TID_SZ;
289 - BF Function:I2O_FUNCTION_SZ;
290 - I2O_INITIATOR_CONTEXT InitiatorContext;
291 -} I2O_MESSAGE_FRAME, *PI2O_MESSAGE_FRAME;
294 -/****************************************************************************/
296 -/* I2O Successful Single Transaction Reply Message Frame structure. */
298 -typedef struct _I2O_SINGLE_REPLY_MESSAGE_FRAME {
299 - I2O_MESSAGE_FRAME StdMessageFrame;
300 - I2O_TRANSACTION_CONTEXT TransactionContext;
301 - U16 DetailedStatusCode;
305 -} I2O_SINGLE_REPLY_MESSAGE_FRAME, *PI2O_SINGLE_REPLY_MESSAGE_FRAME;
308 -/****************************************************************************/
310 -/* I2O Private Message Frame structure. */
311 -typedef struct _I2O_PRIVATE_MESSAGE_FRAME {
312 - I2O_MESSAGE_FRAME StdMessageFrame;
313 - I2O_TRANSACTION_CONTEXT TransactionContext;
315 - U16 OrganizationID;
316 -/* PrivatePayload[] */
317 -} I2O_PRIVATE_MESSAGE_FRAME, *PI2O_PRIVATE_MESSAGE_FRAME;
319 -/****************************************************************************/
322 - Random Block Storage Class specific functions
324 - Although the names are block storage class specific, the values
325 - assigned are common with other classes when applicable.
328 -#define I2O_BSA_BLOCK_READ 0x30
329 -#define I2O_BSA_BLOCK_REASSIGN 0x71
330 -#define I2O_BSA_BLOCK_WRITE 0x31
331 -#define I2O_BSA_BLOCK_WRITE_VERIFY 0x33
332 -#define I2O_BSA_CACHE_FLUSH 0x37
333 -#define I2O_BSA_DEVICE_RESET 0x27
334 -#define I2O_BSA_MEDIA_EJECT 0x43
335 -#define I2O_BSA_MEDIA_FORMAT 0x45
336 -#define I2O_BSA_MEDIA_LOCK 0x49
337 -#define I2O_BSA_MEDIA_MOUNT 0x41
338 -#define I2O_BSA_MEDIA_UNLOCK 0x4B
339 -#define I2O_BSA_MEDIA_VERIFY 0x35
340 -#define I2O_BSA_POWER_MANAGEMENT 0x70
341 -#define I2O_BSA_STATUS_CHECK 0x25
343 -/****************************************************************************/
345 -/* Memory Addressing structures and defines. */
347 -/* SglFlags defines. */
349 -#define I2O_SGL_FLAGS_LAST_ELEMENT 0x80
350 -#define I2O_SGL_FLAGS_END_OF_BUFFER 0x40
352 -#define I2O_SGL_FLAGS_IGNORE_ELEMENT 0x00
353 -#define I2O_SGL_FLAGS_TRANSPORT_ELEMENT 0x04
354 -#define I2O_SGL_FLAGS_BIT_BUCKET_ELEMENT 0x08
355 -#define I2O_SGL_FLAGS_IMMEDIATE_DATA_ELEMENT 0x0C
356 -#define I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT 0x10
357 -#define I2O_SGL_FLAGS_PAGE_LIST_ADDRESS_ELEMENT 0x20
358 -#define I2O_SGL_FLAGS_CHAIN_POINTER_ELEMENT 0x30
359 -#define I2O_SGL_FLAGS_LONG_TRANSACTION_ELEMENT 0x40
360 -#define I2O_SGL_FLAGS_SHORT_TRANSACTION_ELEMENT 0x70
361 -#define I2O_SGL_FLAGS_SGL_ATTRIBUTES_ELEMENT 0x7C
363 -#define I2O_SGL_FLAGS_BC0 0x01
364 -#define I2O_SGL_FLAGS_BC1 0x02
365 -#define I2O_SGL_FLAGS_DIR 0x04
366 -#define I2O_SGL_FLAGS_LOCAL_ADDRESS 0x08
368 -#define I2O_SGL_FLAGS_CONTEXT_COUNT_MASK 0x03
369 -#define I2O_SGL_FLAGS_ADDRESS_MODE_MASK 0x3C
370 -#define I2O_SGL_FLAGS_NO_CONTEXT 0x00
372 -/* 32 Bit Context Field defines */
374 -#define I2O_SGL_FLAGS_CONTEXT32_NULL 0x00
375 -#define I2O_SGL_FLAGS_CONTEXT32_U32 0x01
376 -#define I2O_SGL_FLAGS_CONTEXT32_U64 0x02
377 -#define I2O_SGL_FLAGS_CONTEXT32_U96 0x03
379 -#define I2O_SGL_FLAGS_CONTEXT32_NULL_SZ 0x00
380 -#define I2O_SGL_FLAGS_CONTEXT32_U32_SZ 0x04
381 -#define I2O_SGL_FLAGS_CONTEXT32_U64_SZ 0x08
382 -#define I2O_SGL_FLAGS_CONTEXT32_U96_SZ 0x0C
384 -/* 64 Bit Context Field defines */
386 -#define I2O_SGL_FLAGS_CONTEXT64_NULL 0x00
387 -#define I2O_SGL_FLAGS_CONTEXT64_U64 0x01
388 -#define I2O_SGL_FLAGS_CONTEXT64_U128 0x02
389 -#define I2O_SGL_FLAGS_CONTEXT64_U192 0x03
391 -#define I2O_SGL_FLAGS_CONTEXT64_NULL_SZ 0x00
392 -#define I2O_SGL_FLAGS_CONTEXT64_U64_SZ 0x08
393 -#define I2O_SGL_FLAGS_CONTEXT64_U128_SZ 0x10
394 -#define I2O_SGL_FLAGS_CONTEXT64_U192_SZ 0x18
396 -/* SGL Attribute Element defines */
398 -#define I2O_SGL_ATTRIBUTE_FLAGS_BIT_BUCKET_HINT 0x0400
399 -#define I2O_SGL_ATTRIBUTE_FLAGS_IMMEDIATE_DATA_HINT 0x0200
400 -#define I2O_SGL_ATTRIBUTE_FLAGS_LOCAL_ADDRESS_HINT 0x0100
401 -#define I2O_SGL_ATTRIBUTE_FLAGS_32BIT_TRANSACTION 0x0000
402 -#define I2O_SGL_ATTRIBUTE_FLAGS_64BIT_TRANSACTION 0x0004
403 -#define I2O_SGL_ATTRIBUTE_FLAGS_32BIT_LOCAL_ADDRESS 0x0000
405 -/* SG Size defines */
407 -#define I2O_SG_COUNT_SZ 24
408 -#define I2O_SG_FLAGS_SZ 8
410 -/* Standard Flags and Count fields for SG Elements */
412 -typedef struct _I2O_FLAGS_COUNT {
413 - BF Count:I2O_SG_COUNT_SZ;
414 - BF Flags:I2O_SG_FLAGS_SZ;
415 -} I2O_FLAGS_COUNT, *PI2O_FLAGS_COUNT;
417 -/* Bit Bucket Element */
418 -typedef struct _I2O_SGE_BIT_BUCKET_ELEMENT {
419 - I2O_FLAGS_COUNT FlagsCount;
421 -} I2O_SGE_BIT_BUCKET_ELEMENT, *PI2O_SGE_BIT_BUCKET_ELEMENT;
423 -/* Chain Addressing Scatter-Gather Element */
425 -typedef struct _I2O_SGE_CHAIN_ELEMENT {
426 - I2O_FLAGS_COUNT FlagsCount;
427 - U32 PhysicalAddress;
428 -} I2O_SGE_CHAIN_ELEMENT, *PI2O_SGE_CHAIN_ELEMENT;
430 -/* Chain Addressing with Context Scatter-Gather Element */
432 -typedef struct _I2O_SGE_CHAIN_CONTEXT_ELEMENT {
433 - I2O_FLAGS_COUNT FlagsCount;
435 - U32 PhysicalAddress;
436 -} I2O_SGE_CHAIN_CONTEXT_ELEMENT, *PI2O_SGE_CHAIN_CONTEXT_ELEMENT;
438 -/* Ignore Scatter-Gather Element */
440 -typedef struct _I2O_SGE_IGNORE_ELEMENT {
441 - I2O_FLAGS_COUNT FlagsCount;
442 -} I2O_SGE_IGNORE_ELEMENT, *PI2O_SGE_IGNORE_ELEMENT;
444 -/* Immediate Data Element */
446 -typedef struct _I2O_SGE_IMMEDIATE_DATA_ELEMENT {
447 - I2O_FLAGS_COUNT FlagsCount;
448 -} I2O_SGE_IMMEDIATE_DATA_ELEMENT, *PI2O_SGE_IMMEDIATE_DATA_ELEMENT;
450 -/* Immediate Data with Context Element */
452 -typedef struct _I2O_SGE_IMMEDIATE_DATA_CONTEXT_ELEMENT {
453 - I2O_FLAGS_COUNT FlagsCount;
455 -} I2O_SGE_IMMEDIATE_DATA_CONTEXT_ELEMENT, *PI2O_SGE_IMMEDIATE_DATA_CONTEXT_ELEMENT;
457 -/* Long Transaction Parameters Element */
459 -typedef struct _I2O_SGE_LONG_TRANSACTION_ELEMENT {
460 - BF LongElementLength:I2O_SG_COUNT_SZ;
461 - BF Flags:I2O_SG_FLAGS_SZ;
463 -} I2O_SGE_LONG_TRANSACTION_ELEMENT, *PI2O_SGE_LONG_TRANSACTION_ELEMENT;
465 -/* Page List Scatter-Gather Element */
467 -typedef struct _I2O_SGE_PAGE_ELEMENT {
468 - I2O_FLAGS_COUNT FlagsCount;
469 - U32 PhysicalAddress[1];
470 -} I2O_SGE_PAGE_ELEMENT , *PI2O_SGE_PAGE_ELEMENT ;
472 -/* Page List with Context Scatter-Gather Element */
474 -typedef struct _I2O_SGE_PAGE_CONTEXT_ELEMENT {
475 - I2O_FLAGS_COUNT FlagsCount;
476 - U32 BufferContext[1];
477 - U32 PhysicalAddress[1];
478 -} I2O_SGE_PAGE_CONTEXT_ELEMENT, *PI2O_SGE_PAGE_CONTEXT_ELEMENT;
480 -/* SGL Attribute Element */
482 -typedef struct _I2O_SGE_SGL_ATTRIBUTES_ELEMENT {
483 - U16 SglAttributeFlags;
487 -} I2O_SGE_SGL_ATTRIBUTES_ELEMENT, *PI2O_SGE_SGL_ATTRIBUTES_ELEMENT;
489 -/* Short Transaction Parameters Element */
491 -typedef struct _I2O_SGE_SHORT_TRANSACTION_ELEMENT {
496 -} I2O_SGE_SHORT_TRANSACTION_ELEMENT, *PI2O_SGE_SHORT_TRANSACTION_ELEMENT;
498 -/* Simple Addressing Scatter-Gather Element */
500 -typedef struct _I2O_SGE_SIMPLE_ELEMENT {
501 - I2O_FLAGS_COUNT FlagsCount;
502 - U32 PhysicalAddress;
503 -} I2O_SGE_SIMPLE_ELEMENT, *PI2O_SGE_SIMPLE_ELEMENT;
505 -/* Simple Addressing with Context Scatter-Gather Element */
507 -typedef struct _I2O_SGE_SIMPLE_CONTEXT_ELEMENT {
508 - I2O_FLAGS_COUNT FlagsCount;
509 - U32 BufferContext[1];
510 - U32 PhysicalAddress;
511 -} I2O_SGE_SIMPLE_CONTEXT_ELEMENT, *PI2O_SGE_SIMPLE_CONTEXT_ELEMENT;
513 -/* Transport Detail Element */
515 -typedef struct _I2O_SGE_TRANSPORT_ELEMENT {
516 - BF LongElementLength:I2O_SG_COUNT_SZ;
517 - BF Flags:I2O_SG_FLAGS_SZ;
518 -} I2O_SGE_TRANSPORT_ELEMENT, *PI2O_SGE_TRANSPORT_ELEMENT;
521 -typedef struct _I2O_SG_ELEMENT {
523 - /* Bit Bucket Element */
524 - I2O_SGE_BIT_BUCKET_ELEMENT BitBucket;
526 - /* Chain Addressing Element */
527 - I2O_SGE_CHAIN_ELEMENT Chain;
529 - /* Chain Addressing with Context Element */
530 - I2O_SGE_CHAIN_CONTEXT_ELEMENT ChainContext;
532 - /* Ignore Scatter-Gather Element */
533 - I2O_SGE_IGNORE_ELEMENT Ignore;
535 - /* Immediate Data Element */
536 - I2O_SGE_IMMEDIATE_DATA_ELEMENT ImmediateData;
538 - /* Immediate Data with Context Element */
539 - I2O_SGE_IMMEDIATE_DATA_CONTEXT_ELEMENT ImmediateDataContext;
541 - /* Long Transaction Parameters Element */
542 - I2O_SGE_LONG_TRANSACTION_ELEMENT LongTransaction;
544 - /* Page List Element */
545 - I2O_SGE_PAGE_ELEMENT Page;
547 - /* Page List with Context Element */
548 - I2O_SGE_PAGE_CONTEXT_ELEMENT PageContext;
550 - /* SGL Attribute Element */
551 - I2O_SGE_SGL_ATTRIBUTES_ELEMENT SGLAttribute;
553 - /* Short Transaction Parameters Element */
554 - I2O_SGE_SHORT_TRANSACTION_ELEMENT ShortTransaction;
556 - /* Simple Addressing Element */
557 - I2O_SGE_SIMPLE_ELEMENT Simple[1];
559 - /* Simple Addressing with Context Element */
560 - I2O_SGE_SIMPLE_CONTEXT_ELEMENT SimpleContext[1];
562 - /* Transport Detail Element */
563 - I2O_SGE_TRANSPORT_ELEMENT Transport;
565 -} I2O_SG_ELEMENT, *PI2O_SG_ELEMENT;
567 -/* I2O BSA Block Read Message Frame */
568 -typedef struct _I2O_BSA_READ_MESSAGE {
569 - I2O_MESSAGE_FRAME StdMessageFrame;
570 - I2O_TRANSACTION_CONTEXT TransactionContext;
571 - I2O_BSA_READ_FLAGS ControlFlags;
574 - U32 TransferByteCount;
575 - U64 LogicalByteAddress;
576 - I2O_SG_ELEMENT SGL;
577 -} I2O_BSA_READ_MESSAGE, *PI2O_BSA_READ_MESSAGE;
580 -/***********************************************************************/
582 -/* Class ID Block */
584 -typedef struct _I2O_CLASS_ID {
585 - BF Class:I2O_CLASS_ID_SZ;
586 - BF Version:I2O_4BIT_VERSION_SZ;
587 - BF OrganizationID:I2O_CLASS_ORGANIZATION_ID_SZ;
588 -} I2O_CLASS_ID, *PI2O_CLASS_ID;
591 -/****************************************************************************/
592 -/* Logical Configuration Table */
593 -/****************************************************************************/
595 -/* I2O Logical Configuration Table structures. */
597 -#define I2O_IDENTITY_TAG_SZ 8
599 -/* I2O Logical Configuration Table Device Flags */
601 -#define I2O_LCT_DEVICE_FLAGS_CONF_DIALOG_REQUEST 0x01
602 -#define I2O_LCT_DEVICE_FLAGS_MORE_THAN_1_USER 0x02
603 -#define I2O_LCT_DEVICE_FLAGS_PEER_SERVICE_DISABLED 0x10
604 -#define I2O_LCT_DEVICE_FLAGS_MANAGEMENT_SERVICE_DISABLED 0x20
606 -/* LCT Entry Block */
608 -typedef struct _I2O_LCT_ENTRY {
609 - BF TableEntrySize:I2O_COMMON_LENGTH_FIELD_SZ;
610 - BF LocalTID:I2O_TID_SZ;
611 - BF reserved:I2O_4BIT_VERSION_SZ;
612 - U32 ChangeIndicator;
614 - I2O_CLASS_ID ClassID;
616 - BF UserTID:I2O_TID_SZ;
617 - BF ParentTID:I2O_TID_SZ;
618 - BF BiosInfo:I2O_BIOS_INFO_SZ;
619 - U8 IdentityTag[I2O_IDENTITY_TAG_SZ];
620 - U32 EventCapabilities;
621 -} I2O_LCT_ENTRY, *PI2O_LCT_ENTRY;
623 -/* I2O Logical Configuration Table structure. */
624 -typedef struct _I2O_LCT {
625 - BF TableSize:I2O_COMMON_LENGTH_FIELD_SZ;
626 - BF BootDeviceTID:I2O_TID_SZ;
627 - BF LctVer:I2O_4BIT_VERSION_SZ;
629 - U32 CurrentChangeIndicator;
630 - I2O_LCT_ENTRY LCTEntry[1];
631 -} I2O_LCT, *PI2O_LCT;
634 -/****************************************************************************/
636 -/* I2O Executive Function Codes. */
638 -#define I2O_EXEC_ADAPTER_ASSIGN 0xB3
639 -#define I2O_EXEC_ADAPTER_READ 0xB2
640 -#define I2O_EXEC_ADAPTER_RELEASE 0xB5
641 -#define I2O_EXEC_BIOS_INFO_SET 0xA5
642 -#define I2O_EXEC_BOOT_DEVICE_SET 0xA7
643 -#define I2O_EXEC_CONFIG_VALIDATE 0xBB
644 -#define I2O_EXEC_CONN_SETUP 0xCA
645 -#define I2O_EXEC_DDM_DESTROY 0xB1
646 -#define I2O_EXEC_DDM_ENABLE 0xD5
647 -#define I2O_EXEC_DDM_QUIESCE 0xC7
648 -#define I2O_EXEC_DDM_RESET 0xD9
649 -#define I2O_EXEC_DDM_SUSPEND 0xAF
650 -#define I2O_EXEC_DEVICE_ASSIGN 0xB7
651 -#define I2O_EXEC_DEVICE_RELEASE 0xB9
652 -#define I2O_EXEC_HRT_GET 0xA8
653 -#define I2O_EXEC_IOP_CLEAR 0xBE
654 -#define I2O_EXEC_IOP_CONNECT 0xC9
655 -#define I2O_EXEC_IOP_RESET 0xBD
656 -#define I2O_EXEC_LCT_NOTIFY 0xA2
657 -#define I2O_EXEC_OUTBOUND_INIT 0xA1
658 -#define I2O_EXEC_PATH_ENABLE 0xD3
659 -#define I2O_EXEC_PATH_QUIESCE 0xC5
660 -#define I2O_EXEC_PATH_RESET 0xD7
661 -#define I2O_EXEC_STATIC_MF_CREATE 0xDD
662 -#define I2O_EXEC_STATIC_MF_RELEASE 0xDF
663 -#define I2O_EXEC_STATUS_GET 0xA0
664 -#define I2O_EXEC_SW_DOWNLOAD 0xA9
665 -#define I2O_EXEC_SW_UPLOAD 0xAB
666 -#define I2O_EXEC_SW_REMOVE 0xAD
667 -#define I2O_EXEC_SYS_ENABLE 0xD1
668 -#define I2O_EXEC_SYS_MODIFY 0xC1
669 -#define I2O_EXEC_SYS_QUIESCE 0xC3
670 -#define I2O_EXEC_SYS_TAB_SET 0xA3
673 -/* I2O Get Status State values */
675 -#define I2O_IOP_STATE_INITIALIZING 0x01
676 -#define I2O_IOP_STATE_RESET 0x02
677 -#define I2O_IOP_STATE_HOLD 0x04
678 -#define I2O_IOP_STATE_READY 0x05
679 -#define I2O_IOP_STATE_OPERATIONAL 0x08
680 -#define I2O_IOP_STATE_FAILED 0x10
681 -#define I2O_IOP_STATE_FAULTED 0x11
684 -#define I2O_EXEC_STATUS_GET_RESERVED_SZ 16
686 -/* ExecStatusGet Function Message Frame structure. */
688 -typedef struct _I2O_EXEC_STATUS_GET_MESSAGE {
692 - BF TargetAddress:I2O_TID_SZ;
693 - BF InitiatorAddress:I2O_TID_SZ;
694 - BF Function:I2O_FUNCTION_SZ;
695 - U8 Reserved[I2O_EXEC_STATUS_GET_RESERVED_SZ];
696 - U32 ReplyBufferAddressLow;
697 - U32 ReplyBufferAddressHigh;
698 - U32 ReplyBufferLength;
699 -} I2O_EXEC_STATUS_GET_MESSAGE, *PI2O_EXEC_STATUS_GET_MESSAGE;
702 -#define I2O_IOP_STATUS_PROD_ID_STR_SZ 24
703 -#define I2O_EXEC_STATUS_GET_REPLY_RESERVED_SZ 6
705 -/* ExecStatusGet reply Structure */
707 -#define I2O_IOP_CAP_CONTEXT_32_ONLY 0x00000000
708 -#define I2O_IOP_CAP_CONTEXT_64_ONLY 0x00000001
709 -#define I2O_IOP_CAP_CONTEXT_32_64_NOT_CURRENTLY 0x00000002
710 -#define I2O_IOP_CAP_CONTEXT_32_64_CURRENTLY 0x00000003
711 -#define I2O_IOP_CAP_CURRENT_CONTEXT_NOT_CONFIG 0x00000000
712 -#define I2O_IOP_CAP_CURRENT_CONTEXT_32_ONLY 0x00000004
713 -#define I2O_IOP_CAP_CURRENT_CONTEXT_64_ONLY 0x00000008
714 -#define I2O_IOP_CAP_CURRENT_CONTEXT_32_64 0x0000000C
715 -#define I2O_IOP_CAP_INBOUND_PEER_SUPPORT 0x00000010
716 -#define I2O_IOP_CAP_OUTBOUND_PEER_SUPPORT 0x00000020
717 -#define I2O_IOP_CAP_PEER_TO_PEER_SUPPORT 0x00000040
719 -typedef struct _I2O_EXEC_STATUS_GET_REPLY {
720 - U16 OrganizationID;
722 - BF IOP_ID:I2O_IOP_ID_SZ;
723 - BF reserved1:I2O_RESERVED_4BITS;
724 - BF HostUnitID:I2O_UNIT_ID_SZ;
725 - BF SegmentNumber:I2O_SEGMENT_NUMBER_SZ;
726 - BF I2oVersion:I2O_4BIT_VERSION_SZ;
727 - BF IopState:I2O_IOP_STATE_SZ;
728 - BF MessengerType:I2O_MESSENGER_TYPE_SZ;
729 - U16 InboundMFrameSize;
732 - U32 MaxInboundMFrames;
733 - U32 CurrentInboundMFrames;
734 - U32 MaxOutboundMFrames;
735 - U8 ProductIDString[I2O_IOP_STATUS_PROD_ID_STR_SZ];
736 - U32 ExpectedLCTSize;
737 - U32 IopCapabilities;
738 - U32 DesiredPrivateMemSize;
739 - U32 CurrentPrivateMemSize;
740 - U32 CurrentPrivateMemBase;
741 - U32 DesiredPrivateIOSize;
742 - U32 CurrentPrivateIOSize;
743 - U32 CurrentPrivateIOBase;
746 -} I2O_EXEC_STATUS_GET_REPLY, *PI2O_EXEC_STATUS_GET_REPLY;
749 -/***************************************************************************/
751 -/* ExecSysTabSet (System Table) Function Message Frame structure. */
753 -#define I2O_EXEC_SYS_TAB_IOP_ID_LOCAL_IOP 0x000
754 -#define I2O_EXEC_SYS_TAB_IOP_ID_LOCAL_HOST 0x001
755 -#define I2O_EXEC_SYS_TAB_IOP_ID_UNKNOWN_IOP 0xFFF
756 -#define I2O_EXEC_SYS_TAB_HOST_UNIT_ID_LOCAL_UNIT 0x0000
757 -#define I2O_EXEC_SYS_TAB_HOST_UNIT_ID_UNKNOWN_UNIT 0xffff
758 -#define I2O_EXEC_SYS_TAB_SEG_NUMBER_LOCAL_SEGMENT 0x000
759 -#define I2O_EXEC_SYS_TAB_SEG_NUMBER_UNKNOWN_SEGMENT 0xfff
761 -typedef struct _I2O_EXEC_SYS_TAB_SET_MESSAGE {
762 - I2O_MESSAGE_FRAME StdMessageFrame;
763 - I2O_TRANSACTION_CONTEXT TransactionContext;
764 - BF IOP_ID:I2O_IOP_ID_SZ;
765 - BF reserved:I2O_RESERVED_4BITS;
766 - BF HostUnitID:I2O_UNIT_ID_SZ;
767 - BF SegmentNumber:I2O_SEGMENT_NUMBER_SZ;
768 - BF reserved2:I2O_RESERVED_20BITS;
769 - I2O_SG_ELEMENT SGL;
770 -} I2O_EXEC_SYS_TAB_SET_MESSAGE, *PI2O_EXEC_SYS_TAB_SET_MESSAGE;
773 -/****************************************************************************/
775 -/* Operation Function Numbers */
777 -#define I2O_PARAMS_OPERATION_FIELD_GET 0x0001
778 -#define I2O_PARAMS_OPERATION_LIST_GET 0x0002
779 -#define I2O_PARAMS_OPERATION_MORE_GET 0x0003
780 -#define I2O_PARAMS_OPERATION_SIZE_GET 0x0004
781 -#define I2O_PARAMS_OPERATION_TABLE_GET 0x0005
782 -#define I2O_PARAMS_OPERATION_FIELD_SET 0x0006
783 -#define I2O_PARAMS_OPERATION_LIST_SET 0x0007
784 -#define I2O_PARAMS_OPERATION_ROW_ADD 0x0008
785 -#define I2O_PARAMS_OPERATION_ROW_DELETE 0x0009
786 -#define I2O_PARAMS_OPERATION_TABLE_CLEAR 0x000A
788 -/* Operations List Header */
790 -typedef struct _I2O_PARAM_OPERATIONS_LIST_HEADER {
791 - U16 OperationCount;
793 -} I2O_PARAM_OPERATIONS_LIST_HEADER, *PI2O_PARAM_OPERATIONS_LIST_HEADER;
795 -/* Results List Header */
797 -typedef struct _I2O_PARAM_RESULTS_LIST_HEADER {
800 -} I2O_PARAM_RESULTS_LIST_HEADER, *PI2O_PARAM_RESULTS_LIST_HEADER;
802 -/* Read Operation Result Block Template Structure */
804 -typedef struct _I2O_PARAM_READ_OPERATION_RESULT {
808 - /* Operations Results */
810 - /* ErrorInformation (if any) */
811 -} I2O_PARAM_READ_OPERATION_RESULT, *PI2O_PARAM_READ_OPERATION_RESULT;
813 -/* Operation Template for Specific Fields */
815 -typedef struct _I2O_PARAM_OPERATION_SPECIFIC_TEMPLATE {
821 -} I2O_PARAM_OPERATION_SPECIFIC_TEMPLATE, *PI2O_PARAM_OPERATION_SPECIFIC_TEMPLATE;
823 -/* Operation Template for All Fields */
825 -typedef struct _I2O_PARAM_OPERATION_ALL_TEMPLATE {
830 -} I2O_PARAM_OPERATION_ALL_TEMPLATE, *PI2O_PARAM_OPERATION_ALL_TEMPLATE;
832 -/****************************************************************************/
834 -/* Utility Message class functions. */
836 -#define I2O_UTIL_NOP 0x00
837 -#define I2O_UTIL_ABORT 0x01
838 -#define I2O_UTIL_CLAIM 0x09
839 -#define I2O_UTIL_CLAIM_RELEASE 0x0B
840 -#define I2O_UTIL_CONFIG_DIALOG 0x10
841 -#define I2O_UTIL_DEVICE_RESERVE 0x0D
842 -#define I2O_UTIL_DEVICE_RELEASE 0x0F
843 -#define I2O_UTIL_EVENT_ACKNOWLEDGE 0x14
844 -#define I2O_UTIL_EVENT_REGISTER 0x13
845 -#define I2O_UTIL_LOCK 0x17
846 -#define I2O_UTIL_LOCK_RELEASE 0x19
847 -#define I2O_UTIL_PARAMS_GET 0x06
848 -#define I2O_UTIL_PARAMS_SET 0x05
849 -#define I2O_UTIL_REPLY_FAULT_NOTIFY 0x15
851 -/****************************************************************************/
853 -/* UtilNOP Function Message Frame structure. */
855 -typedef struct _I2O_UTIL_NOP_MESSAGE {
856 - I2O_MESSAGE_FRAME StdMessageFrame;
857 -} I2O_UTIL_NOP_MESSAGE, *PI2O_UTIL_NOP_MESSAGE;
860 -/*************************************************************************/
862 -/* UtilParamsGet Message Frame structure. */
864 -typedef struct _I2O_UTIL_PARAMS_GET_MESSAGE {
865 - I2O_MESSAGE_FRAME StdMessageFrame;
866 - I2O_TRANSACTION_CONTEXT TransactionContext;
867 - U32 OperationFlags;
868 - I2O_SG_ELEMENT SGL;
869 -} I2O_UTIL_PARAMS_GET_MESSAGE, *PI2O_UTIL_PARAMS_GET_MESSAGE;
872 -/****************************************************************************/
873 -/* GROUP Parameter Groups */
874 -/****************************************************************************/
876 -/* GROUP Configuration and Operating Structures and Defines */
878 -/* Groups Numbers */
880 -#define I2O_UTIL_PARAMS_DESCRIPTOR_GROUP_NO 0xF000
881 -#define I2O_UTIL_PHYSICAL_DEVICE_TABLE_GROUP_NO 0xF001
882 -#define I2O_UTIL_CLAIMED_TABLE_GROUP_NO 0xF002
883 -#define I2O_UTIL_USER_TABLE_GROUP_NO 0xF003
884 -#define I2O_UTIL_PRIVATE_MESSAGE_EXTENSIONS_GROUP_NO 0xF005
885 -#define I2O_UTIL_AUTHORIZED_USER_TABLE_GROUP_NO 0xF006
886 -#define I2O_UTIL_DEVICE_IDENTITY_GROUP_NO 0xF100
887 -#define I2O_UTIL_DDM_IDENTITY_GROUP_NO 0xF101
888 -#define I2O_UTIL_USER_INFORMATION_GROUP_NO 0xF102
889 -#define I2O_UTIL_SGL_OPERATING_LIMITS_GROUP_NO 0xF103
890 -#define I2O_UTIL_SENSORS_GROUP_NO 0xF200
892 -/* UTIL Group F000h - GROUP DESCRIPTORS Parameter Group */
894 -#define I2O_UTIL_GROUP_PROPERTIES_GROUP_TABLE 0x01
895 -#define I2O_UTIL_GROUP_PROPERTIES_ROW_ADDITION 0x02
896 -#define I2O_UTIL_GROUP_PROPERTIES_ROW_DELETION 0x04
897 -#define I2O_UTIL_GROUP_PROPERTIES_CLEAR_OPERATION 0x08
899 -/* UTIL Group F100h - Device Identity Parameter Group */
901 -typedef struct _I2O_UTIL_DEVICE_IDENTITY_SCALAR {
905 - U8 VendorInfo[I2O_DEVID_VENDOR_INFO_SZ];
906 - U8 ProductInfo[I2O_DEVID_PRODUCT_INFO_SZ];
907 - U8 Description[I2O_DEVID_DESCRIPTION_SZ];
908 - U8 ProductRevLevel[I2O_DEVID_REV_LEVEL_SZ];
910 - U8 SerialNumber[I2O_MAX_SERIAL_NUMBER_SZ];
911 -} I2O_UTIL_DEVICE_IDENTITY_SCALAR, *PI2O_UTIL_DEVICE_IDENTITY_SCALAR;
913 -/* UTIL Group F101h - DDM Identity Parameter Group */
915 -typedef struct _I2O_UTIL_DDM_IDENTITY_SCALAR {
917 - U8 ModuleName[I2O_MODULE_NAME_SZ];
918 - U8 ModuleRevLevel[I2O_DEVID_REV_LEVEL_SZ];
920 - U8 SerialNumber[I2O_MAX_SERIAL_NUMBER_SZ];
921 -} I2O_UTIL_DDM_IDENTITY_SCALAR, *PI2O_UTIL_DDM_IDENTITY_SCALAR;
923 -/****************************************************************************/
925 -/* Block Storage Parameter Groups */
927 -#define I2O_BSA_DEVICE_INFO_GROUP_NO 0x0000
928 -#define I2O_BSA_OPERATIONAL_CONTROL_GROUP_NO 0x0001
929 -#define I2O_BSA_POWER_CONTROL_GROUP_NO 0x0002
930 -#define I2O_BSA_CACHE_CONTROL_GROUP_NO 0x0003
931 -#define I2O_BSA_MEDIA_INFO_GROUP_NO 0x0004
932 -#define I2O_BSA_ERROR_LOG_GROUP_NO 0x0005
934 -/***************************************************************************/
936 -/* I2O Block Storage Reply Message Frame Template */
938 -typedef struct _I2O_BSA_REPLY_MESSAGE_FRAME {
939 - I2O_MESSAGE_FRAME StdMessageFrame;
940 - I2O_TRANSACTION_CONTEXT TransactionContext;
941 - U16 DetailedStatusCode;
945 -} I2O_BSA_REPLY_MESSAGE_FRAME, *PI2O_BSA_REPLY_MESSAGE_FRAME;
947 -/**************************************************************************/
949 -/* Block Storage Group 0000h - Device Information Parameter Group */
951 -typedef struct _I2O_BSA_DEVICE_INFO_SCALAR {
956 - U64 DeviceCapacity;
957 - U32 DeviceCapabilitySupport;
959 -} I2O_BSA_DEVICE_INFO_SCALAR, *PI2O_BSA_DEVICE_INFO_SCALAR;
962 -/****************************************************************************/
965 -/* ExecOutboundInit Function Message Frame structure. */
967 -typedef struct _I2O_EXEC_OUTBOUND_INIT_MESSAGE {
968 - I2O_MESSAGE_FRAME StdMessageFrame;
969 - I2O_TRANSACTION_CONTEXT TransactionContext;
970 - U32 HostPageFrameSize;
973 - U16 OutboundMFrameSize;
974 - I2O_SG_ELEMENT SGL;
975 -} I2O_EXEC_OUTBOUND_INIT_MESSAGE, *PI2O_EXEC_OUTBOUND_INIT_MESSAGE;
978 -#define I2O_EXEC_OUTBOUND_INIT_IN_PROGRESS 0x01
979 -#define I2O_EXEC_OUTBOUND_INIT_REJECTED 0x02
980 -#define I2O_EXEC_OUTBOUND_INIT_FAILED 0x03
981 -#define I2O_EXEC_OUTBOUND_INIT_COMPLETE 0x04
983 -#define I2O_EXEC_OUTBOUND_INIT_RESERVED_SZ 3
986 -typedef struct _I2O_EXEC_OUTBOUND_INIT_STATUS {
988 - U8 reserved[I2O_EXEC_OUTBOUND_INIT_RESERVED_SZ];
989 -} I2O_EXEC_OUTBOUND_INIT_STATUS, *PI2O_EXEC_OUTBOUND_INIT_STATUS;
992 -typedef struct _I2O_EXEC_OUTBOUND_INIT_RECLAIM_LIST {
994 - U32 MFAReleaseCount;
996 -} I2O_EXEC_OUTBOUND_INIT_RECLAIM_LIST, *PI2O_EXEC_OUTBOUND_INIT_RECLAIM_LIST;
998 -/****************************************************************************/
1001 -/* ExecSysEnable Function Message Frame structure. */
1003 -typedef struct _I2O_EXEC_SYS_ENABLE_MESSAGE {
1004 - I2O_MESSAGE_FRAME StdMessageFrame;
1005 - I2O_TRANSACTION_CONTEXT TransactionContext;
1006 -} I2O_EXEC_SYS_ENABLE_MESSAGE, *PI2O_EXEC_SYS_ENABLE_MESSAGE;
1009 -/****************************************************************************/
1011 -/* ExecLCTNotify Function Message Frame structure. */
1013 -typedef struct _I2O_EXEC_LCT_NOTIFY_MESSAGE {
1014 - I2O_MESSAGE_FRAME StdMessageFrame;
1015 - I2O_TRANSACTION_CONTEXT TransactionContext;
1016 - U32 ClassIdentifier;
1017 - U32 LastReportedChangeIndicator;
1018 - I2O_SG_ELEMENT SGL;
1019 -} I2O_EXEC_LCT_NOTIFY_MESSAGE, *PI2O_EXEC_LCT_NOTIFY_MESSAGE;
1021 -/****************************************************************************/
1023 -/* ExecSysTabSet (System Table) Header Reply structure. */
1025 -#define I2O_SET_SYSTAB_RESERVED_SZ 8
1027 -typedef struct _I2O_SET_SYSTAB_HEADER {
1031 - U32 CurrentChangeIndicator;
1032 - U8 reserved1[I2O_SET_SYSTAB_RESERVED_SZ];
1033 -/* I2O_SYSTAB_ENTRY SysTabEntry[1]; */
1034 -} I2O_SET_SYSTAB_HEADER, *PI2O_SET_SYSTAB_HEADER;
1037 -#define I2O_RESOURCE_MANAGER_VERSION 0
1039 -typedef struct _MESSENGER_INFO {
1040 - U32 InboundMessagePortAddressLow;
1041 - U32 InboundMessagePortAddressHigh;
1042 - } I2O_MESSENGER_INFO, *PI2O_MESSENGER_INFO;
1044 -/* ExecSysTabSet IOP Descriptor Entry structure. */
1046 -typedef struct _I2O_IOP_ENTRY {
1047 - U16 OrganizationID;
1049 - BF IOP_ID:I2O_IOP_ID_SZ;
1050 - BF reserved1:I2O_RESERVED_20BITS;
1051 - BF SegmentNumber:I2O_SEGMENT_NUMBER_SZ;
1052 - BF I2oVersion:I2O_4BIT_VERSION_SZ;
1053 - BF IopState:I2O_IOP_STATE_SZ;
1054 - BF MessengerType:I2O_MESSENGER_TYPE_SZ;
1055 - U16 InboundMessageFrameSize;
1058 - U32 IopCapabilities;
1059 - I2O_MESSENGER_INFO MessengerInfo;
1060 -} I2O_IOP_ENTRY, *PI2O_IOP_ENTRY;
1063 -/****************************************************************************/
1066 -#define I2O_EXEC_IOP_RESET_RESERVED_SZ 16
1068 -#define I2O_EXEC_IOP_RESET_IN_PROGRESS 0x01
1069 -#define I2O_EXEC_IOP_RESET_REJECTED 0x02
1071 -#define I2O_EXEC_IOP_RESET_STATUS_RESERVED_SZ 3
1073 -typedef struct _I2O_EXEC_IOP_RESET_STATUS {
1075 - U8 reserved[I2O_EXEC_IOP_RESET_STATUS_RESERVED_SZ];
1076 -} I2O_EXEC_IOP_RESET_STATUS, *PI2O_EXEC_IOP_RESET_STATUS;
1079 -/* ExecIopReset Function Message Frame structure. */
1081 -typedef struct _I2O_EXEC_IOP_RESET_MESSAGE {
1085 - BF TargetAddress:I2O_TID_SZ;
1086 - BF InitiatorAddress:I2O_TID_SZ;
1087 - BF Function:I2O_FUNCTION_SZ;
1088 - U8 Reserved[I2O_EXEC_IOP_RESET_RESERVED_SZ];
1089 - U32 StatusWordLowAddress;
1090 - U32 StatusWordHighAddress;
1091 -} I2O_EXEC_IOP_RESET_MESSAGE, *PI2O_EXEC_IOP_RESET_MESSAGE;
1094 -/****************************************************************************/
1095 -/* EXEC Group 0001h - IOP Message Interface Parameter Group */
1097 -/* InitCode defines */
1098 -#define I2O_MESSAGE_IF_INIT_CODE_NO_OWNER 0x00
1099 -#define I2O_MESSAGE_IF_INIT_CODE_BIOS 0x10
1100 -#define I2O_MESSAGE_IF_INIT_CODE_OEM_BIOS_EXTENSION 0x20
1101 -#define I2O_MESSAGE_IF_INIT_CODE_ROM_BIOS_EXTENSION 0x30
1102 -#define I2O_MESSAGE_IF_INIT_CODE_OS 0x80
1104 -/****************************************************************************/
1106 -#endif /* _I2ODEF_H_ */
1108 +#if !defined(_I2ODEF_H_)
\r
1110 +#define _I2ODEF_H
\r
1112 +#if !defined(_I2OTYPES_)
\r
1114 +#define _I2OTYPES_
\r
1117 + * Pragma macros. These are to assure appropriate alignment between
\r
1118 + * host/IOP as defined by the I2O Specification. Each one of the shared
\r
1119 + * header files includes these macros.
\r
1122 +#define PRAGMA_ALIGN_PUSH \
\r
1124 +#define PRAGMA_ALIGN_POP \
\r
1126 +#define PRAGMA_PACK_PUSH \
\r
1128 +#define PRAGMA_PACK_POP \
\r
1131 +/* Setup the basics */
\r
1134 +typedef short S16;
\r
1136 +typedef unsigned char U8;
\r
1137 +typedef unsigned short U16;
\r
1139 +//typedef unsigned int U32;
\r
1140 +//typedef int S32;
\r
1141 +typedef unsigned long U32;
\r
1142 +typedef long S32;
\r
1152 +typedef void VOID;
\r
1174 +/**************************************************************************/
\r
1176 +/* 64 bit defines */
\r
1178 +typedef struct _S64 {
\r
1183 +typedef struct _U64 {
\r
1188 +/* Pointer to Basics */
\r
1190 +typedef VOID *PVOID;
\r
1192 +typedef S16 *PS16;
\r
1193 +typedef S32 *PS32;
\r
1194 +typedef S64 *PS64;
\r
1196 +/* Pointer to Unsigned Basics */
\r
1199 +typedef U16 *PU16;
\r
1200 +typedef U32 *PU32;
\r
1201 +typedef U64 *PU64;
\r
1205 +typedef S32 I2O_ARG;
\r
1206 +typedef U32 I2O_COUNT;
\r
1207 +typedef U32 I2O_USECS;
\r
1208 +typedef U32 I2O_ADDR32;
\r
1209 +typedef U32 I2O_SIZE;
\r
1211 +#endif /* _I2OTYPES_ */
\r
1213 +/**************************************************************************/
\r
1215 +/* I2O BSA Block Read Message Control Flags */
\r
1217 +typedef U16 I2O_BSA_READ_FLAGS;
\r
1218 +#define I2O_BSA_RD_FLAG_DONT_RETRY 0x0001
\r
1219 +#define I2O_BSA_RD_FLAG_SOLO 0x0002
\r
1220 +#define I2O_BSA_RD_FLAG_CACHE_READ 0x0004
\r
1221 +#define I2O_BSA_RD_FLAG_READ_PREFETCH 0x0008
\r
1222 +#define I2O_BSA_RD_FLAG_CACHE_DATA 0x0010
\r
1224 +/* I2O BSA Block Write Message Control Flags */
\r
1226 +typedef U16 I2O_BSA_WRITE_FLAGS;
\r
1227 +#define I2O_BSA_WR_FLAG_DONT_RETRY 0x0001
\r
1228 +#define I2O_BSA_WR_FLAG_SOLO 0x0002
\r
1229 +#define I2O_BSA_WR_FLAG_DONT_CACHE 0x0004
\r
1230 +#define I2O_BSA_WR_FLAG_WRITE_THRU 0x0008
\r
1231 +#define I2O_BSA_WR_FLAG_WRITE_TO 0x0010
\r
1233 +/****************************************************************************/
\r
1235 +typedef U32 I2O_INITIATOR_CONTEXT;
\r
1236 +typedef U32 I2O_TRANSACTION_CONTEXT;
\r
1238 +typedef U32 I2O_PARAMETER_TID;
\r
1240 +/****************************************************************************/
\r
1241 +/* Message Frame defines and structures */
\r
1243 +/* Defines for the Version_Status field. */
\r
1245 +#define I2O_VERSION_10 0x00
\r
1246 +#define I2O_VERSION_11 0x01
\r
1248 +#define I2O_VERSION_OFFSET_NUMBER_MASK 0x07
\r
1249 +#define I2O_VERSION_OFFSET_SGL_TRL_OFFSET_MASK 0xF0
\r
1251 +/* Defines for the Message Flags Field. */
\r
1252 +/* Please Note the the FAIL bit is only set in the Transport Fail Message. */
\r
1253 +#define I2O_MESSAGE_FLAGS_STATIC 0x01
\r
1254 +#define I2O_MESSAGE_FLAGS_64BIT_CONTEXT 0x02
\r
1255 +#define I2O_MESSAGE_FLAGS_MULTIPLE 0x10
\r
1256 +#define I2O_MESSAGE_FLAGS_FAIL 0x20
\r
1257 +#define I2O_MESSAGE_FLAGS_LAST 0x40
\r
1258 +#define I2O_MESSAGE_FLAGS_REPLY 0x80
\r
1260 +/* Defines for Request Status Codes: Table 3-1 Reply Status Codes. */
\r
1262 +#define I2O_REPLY_STATUS_SUCCESS 0x00
\r
1263 +#define I2O_REPLY_STATUS_ABORT_DIRTY 0x01
\r
1264 +#define I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER 0x02
\r
1265 +#define I2O_REPLY_STATUS_ABORT_PARTIAL_TRANSFER 0x03
\r
1266 +#define I2O_REPLY_STATUS_ERROR_DIRTY 0x04
\r
1267 +#define I2O_REPLY_STATUS_ERROR_NO_DATA_TRANSFER 0x05
\r
1268 +#define I2O_REPLY_STATUS_ERROR_PARTIAL_TRANSFER 0x06
\r
1269 +#define I2O_REPLY_STATUS_PROCESS_ABORT_DIRTY 0x08
\r
1270 +#define I2O_REPLY_STATUS_PROCESS_ABORT_NO_DATA_TRANSFER 0x09
\r
1271 +#define I2O_REPLY_STATUS_PROCESS_ABORT_PARTIAL_TRANSFER 0x0A
\r
1272 +#define I2O_REPLY_STATUS_TRANSACTION_ERROR 0x0B
\r
1273 +#define I2O_REPLY_STATUS_PROGRESS_REPORT 0x80
\r
1275 +/* DetailedStatusCode defines for ALL messages: Table 3-2 Detailed Status Codes. */
\r
1277 +#define I2O_DETAIL_STATUS_SUCCESS 0x0000
\r
1278 +#define I2O_DETAIL_STATUS_BAD_KEY 0x0002
\r
1279 +#define I2O_DETAIL_STATUS_TCL_ERROR 0x0003
\r
1280 +#define I2O_DETAIL_STATUS_REPLY_BUFFER_FULL 0x0004
\r
1281 +#define I2O_DETAIL_STATUS_NO_SUCH_PAGE 0x0005
\r
1282 +#define I2O_DETAIL_STATUS_INSUFFICIENT_RESOURCE_SOFT 0x0006
\r
1283 +#define I2O_DETAIL_STATUS_INSUFFICIENT_RESOURCE_HARD 0x0007
\r
1284 +#define I2O_DETAIL_STATUS_CHAIN_BUFFER_TOO_LARGE 0x0009
\r
1285 +#define I2O_DETAIL_STATUS_UNSUPPORTED_FUNCTION 0x000A
\r
1286 +#define I2O_DETAIL_STATUS_DEVICE_LOCKED 0x000B
\r
1287 +#define I2O_DETAIL_STATUS_DEVICE_RESET 0x000C
\r
1288 +#define I2O_DETAIL_STATUS_INAPPROPRIATE_FUNCTION 0x000D
\r
1289 +#define I2O_DETAIL_STATUS_INVALID_INITIATOR_ADDRESS 0x000E
\r
1290 +#define I2O_DETAIL_STATUS_INVALID_MESSAGE_FLAGS 0x000F
\r
1291 +#define I2O_DETAIL_STATUS_INVALID_OFFSET 0x0010
\r
1292 +#define I2O_DETAIL_STATUS_INVALID_PARAMETER 0x0011
\r
1293 +#define I2O_DETAIL_STATUS_INVALID_REQUEST 0x0012
\r
1294 +#define I2O_DETAIL_STATUS_INVALID_TARGET_ADDRESS 0x0013
\r
1295 +#define I2O_DETAIL_STATUS_MESSAGE_TOO_LARGE 0x0014
\r
1296 +#define I2O_DETAIL_STATUS_MESSAGE_TOO_SMALL 0x0015
\r
1297 +#define I2O_DETAIL_STATUS_MISSING_PARAMETER 0x0016
\r
1298 +#define I2O_DETAIL_STATUS_TIMEOUT 0x0017
\r
1299 +#define I2O_DETAIL_STATUS_UNKNOWN_ERROR 0x0018
\r
1300 +#define I2O_DETAIL_STATUS_UNKNOWN_FUNCTION 0x0019
\r
1301 +#define I2O_DETAIL_STATUS_UNSUPPORTED_VERSION 0x001A
\r
1302 +#define I2O_DEATIL_STATUS_DEVICE_BUSY 0x001B
\r
1303 +#define I2O_DETAIL_STATUS_DEVICE_NOT_AVAILABLE 0x001C
\r
1305 +/* Common I2O Field sizes */
\r
1307 +#define I2O_TID_SZ 12
\r
1308 +#define I2O_FUNCTION_SZ 8
\r
1309 +#define I2O_UNIT_ID_SZ 16
\r
1310 +#define I2O_SEGMENT_NUMBER_SZ 12
\r
1312 +#define I2O_IOP_ID_SZ 12
\r
1313 +#define I2O_GROUP_ID_SZ 16
\r
1314 +#define I2O_IOP_STATE_SZ 8
\r
1315 +#define I2O_MESSENGER_TYPE_SZ 8
\r
1317 +#define I2O_CLASS_ID_SZ 12
\r
1318 +#define I2O_CLASS_ORGANIZATION_ID_SZ 16
\r
1320 +#define I2O_4BIT_VERSION_SZ 4
\r
1321 +#define I2O_8BIT_FLAGS_SZ 8
\r
1322 +#define I2O_COMMON_LENGTH_FIELD_SZ 16
\r
1325 +#define I2O_DEVID_DESCRIPTION_SZ 16
\r
1326 +#define I2O_DEVID_VENDOR_INFO_SZ 16
\r
1327 +#define I2O_DEVID_PRODUCT_INFO_SZ 16
\r
1328 +#define I2O_DEVID_REV_LEVEL_SZ 8
\r
1329 +#define I2O_MODULE_NAME_SZ 24
\r
1331 +#define I2O_BIOS_INFO_SZ 8
\r
1333 +#define I2O_RESERVED_4BITS 4
\r
1334 +#define I2O_RESERVED_8BITS 8
\r
1335 +#define I2O_RESERVED_12BITS 12
\r
1336 +#define I2O_RESERVED_16BITS 16
\r
1337 +#define I2O_RESERVED_20BITS 20
\r
1338 +#define I2O_RESERVED_24BITS 24
\r
1339 +#define I2O_RESERVED_28BITS 28
\r
1341 +/****************************************************************************/
\r
1343 +/* Common functions accross all classes. */
\r
1345 +#define I2O_PRIVATE_MESSAGE 0xFF
\r
1347 +/****************************************************************************/
\r
1348 +/* Class ID and Code Assignments */
\r
1351 +#define I2O_CLASS_VERSION_10 0x00
\r
1352 +#define I2O_CLASS_VERSION_11 0x01
\r
1354 +/* Class Code Names: Table 6-1 Class Code Assignments. */
\r
1355 +#define I2O_CLASS_EXECUTIVE 0x000
\r
1356 +#define I2O_CLASS_DDM 0x001
\r
1357 +#define I2O_CLASS_RANDOM_BLOCK_STORAGE 0x010
\r
1358 +#define I2O_CLASS_SEQUENTIAL_STORAGE 0x011
\r
1359 +#define I2O_CLASS_LAN 0x020
\r
1360 +#define I2O_CLASS_WAN 0x030
\r
1361 +#define I2O_CLASS_FIBRE_CHANNEL_PORT 0x040
\r
1362 +#define I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL 0x041
\r
1363 +#define I2O_CLASS_SCSI_PERIPHERAL 0x051
\r
1364 +#define I2O_CLASS_ATE_PORT 0x060
\r
1365 +#define I2O_CLASS_ATE_PERIPHERAL 0x061
\r
1366 +#define I2O_CLASS_FLOPPY_CONTROLLER 0x070
\r
1367 +#define I2O_CLASS_FLOPPY_DEVICE 0x071
\r
1368 +#define I2O_CLASS_BUS_ADAPTER_PORT 0x080
\r
1369 +/* Class Codes 0x090 - 0x09f are reserved for Peer-to-Peer classes */
\r
1370 +#define I2O_CLASS_MATCH_ANYCLASS 0xffffffff
\r
1372 +#define I2O_SUBCLASS_i960 0x001
\r
1373 +#define I2O_SUBCLASS_HDM 0x020
\r
1374 +#define I2O_SUBCLASS_ISM 0x021
\r
1377 +/*********************************************************************/
\r
1379 +#define I2O_MAX_SERIAL_NUMBER_SZ 256
\r
1381 +/****************************************************************************/
\r
1383 +/* I2O Message Frame common for all messages */
\r
1385 +typedef struct _I2O_MESSAGE_FRAME {
\r
1386 + U8 VersionOffset;
\r
1388 + U16 MessageSize;
\r
1389 + BF TargetAddress:I2O_TID_SZ;
\r
1390 + BF InitiatorAddress:I2O_TID_SZ;
\r
1391 + BF Function:I2O_FUNCTION_SZ;
\r
1392 + I2O_INITIATOR_CONTEXT InitiatorContext;
\r
1393 +} I2O_MESSAGE_FRAME, *PI2O_MESSAGE_FRAME;
\r
1396 +/****************************************************************************/
\r
1398 +/* I2O Successful Single Transaction Reply Message Frame structure. */
\r
1400 +typedef struct _I2O_SINGLE_REPLY_MESSAGE_FRAME {
\r
1401 + I2O_MESSAGE_FRAME StdMessageFrame;
\r
1402 + I2O_TRANSACTION_CONTEXT TransactionContext;
\r
1403 + U16 DetailedStatusCode;
\r
1406 +/* ReplyPayload */
\r
1407 +} I2O_SINGLE_REPLY_MESSAGE_FRAME, *PI2O_SINGLE_REPLY_MESSAGE_FRAME;
\r
1410 +/****************************************************************************/
\r
1412 +/* I2O Private Message Frame structure. */
\r
1413 +typedef struct _I2O_PRIVATE_MESSAGE_FRAME {
\r
1414 + I2O_MESSAGE_FRAME StdMessageFrame;
\r
1415 + I2O_TRANSACTION_CONTEXT TransactionContext;
\r
1416 + U16 XFunctionCode;
\r
1417 + U16 OrganizationID;
\r
1418 +/* PrivatePayload[] */
\r
1419 +} I2O_PRIVATE_MESSAGE_FRAME, *PI2O_PRIVATE_MESSAGE_FRAME;
\r
1421 +/****************************************************************************/
\r
1424 + Random Block Storage Class specific functions
\r
1426 + Although the names are block storage class specific, the values
\r
1427 + assigned are common with other classes when applicable.
\r
1430 +#define I2O_BSA_BLOCK_READ 0x30
\r
1431 +#define I2O_BSA_BLOCK_REASSIGN 0x71
\r
1432 +#define I2O_BSA_BLOCK_WRITE 0x31
\r
1433 +#define I2O_BSA_BLOCK_WRITE_VERIFY 0x33
\r
1434 +#define I2O_BSA_CACHE_FLUSH 0x37
\r
1435 +#define I2O_BSA_DEVICE_RESET 0x27
\r
1436 +#define I2O_BSA_MEDIA_EJECT 0x43
\r
1437 +#define I2O_BSA_MEDIA_FORMAT 0x45
\r
1438 +#define I2O_BSA_MEDIA_LOCK 0x49
\r
1439 +#define I2O_BSA_MEDIA_MOUNT 0x41
\r
1440 +#define I2O_BSA_MEDIA_UNLOCK 0x4B
\r
1441 +#define I2O_BSA_MEDIA_VERIFY 0x35
\r
1442 +#define I2O_BSA_POWER_MANAGEMENT 0x70
\r
1443 +#define I2O_BSA_STATUS_CHECK 0x25
\r
1445 +/****************************************************************************/
\r
1447 +/* Memory Addressing structures and defines. */
\r
1449 +/* SglFlags defines. */
\r
1451 +#define I2O_SGL_FLAGS_LAST_ELEMENT 0x80
\r
1452 +#define I2O_SGL_FLAGS_END_OF_BUFFER 0x40
\r
1454 +#define I2O_SGL_FLAGS_IGNORE_ELEMENT 0x00
\r
1455 +#define I2O_SGL_FLAGS_TRANSPORT_ELEMENT 0x04
\r
1456 +#define I2O_SGL_FLAGS_BIT_BUCKET_ELEMENT 0x08
\r
1457 +#define I2O_SGL_FLAGS_IMMEDIATE_DATA_ELEMENT 0x0C
\r
1458 +#define I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT 0x10
\r
1459 +#define I2O_SGL_FLAGS_PAGE_LIST_ADDRESS_ELEMENT 0x20
\r
1460 +#define I2O_SGL_FLAGS_CHAIN_POINTER_ELEMENT 0x30
\r
1461 +#define I2O_SGL_FLAGS_LONG_TRANSACTION_ELEMENT 0x40
\r
1462 +#define I2O_SGL_FLAGS_SHORT_TRANSACTION_ELEMENT 0x70
\r
1463 +#define I2O_SGL_FLAGS_SGL_ATTRIBUTES_ELEMENT 0x7C
\r
1465 +#define I2O_SGL_FLAGS_BC0 0x01
\r
1466 +#define I2O_SGL_FLAGS_BC1 0x02
\r
1467 +#define I2O_SGL_FLAGS_DIR 0x04
\r
1468 +#define I2O_SGL_FLAGS_LOCAL_ADDRESS 0x08
\r
1470 +#define I2O_SGL_FLAGS_CONTEXT_COUNT_MASK 0x03
\r
1471 +#define I2O_SGL_FLAGS_ADDRESS_MODE_MASK 0x3C
\r
1472 +#define I2O_SGL_FLAGS_NO_CONTEXT 0x00
\r
1474 +/* 32 Bit Context Field defines */
\r
1476 +#define I2O_SGL_FLAGS_CONTEXT32_NULL 0x00
\r
1477 +#define I2O_SGL_FLAGS_CONTEXT32_U32 0x01
\r
1478 +#define I2O_SGL_FLAGS_CONTEXT32_U64 0x02
\r
1479 +#define I2O_SGL_FLAGS_CONTEXT32_U96 0x03
\r
1481 +#define I2O_SGL_FLAGS_CONTEXT32_NULL_SZ 0x00
\r
1482 +#define I2O_SGL_FLAGS_CONTEXT32_U32_SZ 0x04
\r
1483 +#define I2O_SGL_FLAGS_CONTEXT32_U64_SZ 0x08
\r
1484 +#define I2O_SGL_FLAGS_CONTEXT32_U96_SZ 0x0C
\r
1486 +/* 64 Bit Context Field defines */
\r
1488 +#define I2O_SGL_FLAGS_CONTEXT64_NULL 0x00
\r
1489 +#define I2O_SGL_FLAGS_CONTEXT64_U64 0x01
\r
1490 +#define I2O_SGL_FLAGS_CONTEXT64_U128 0x02
\r
1491 +#define I2O_SGL_FLAGS_CONTEXT64_U192 0x03
\r
1493 +#define I2O_SGL_FLAGS_CONTEXT64_NULL_SZ 0x00
\r
1494 +#define I2O_SGL_FLAGS_CONTEXT64_U64_SZ 0x08
\r
1495 +#define I2O_SGL_FLAGS_CONTEXT64_U128_SZ 0x10
\r
1496 +#define I2O_SGL_FLAGS_CONTEXT64_U192_SZ 0x18
\r
1498 +/* SGL Attribute Element defines */
\r
1500 +#define I2O_SGL_ATTRIBUTE_FLAGS_BIT_BUCKET_HINT 0x0400
\r
1501 +#define I2O_SGL_ATTRIBUTE_FLAGS_IMMEDIATE_DATA_HINT 0x0200
\r
1502 +#define I2O_SGL_ATTRIBUTE_FLAGS_LOCAL_ADDRESS_HINT 0x0100
\r
1503 +#define I2O_SGL_ATTRIBUTE_FLAGS_32BIT_TRANSACTION 0x0000
\r
1504 +#define I2O_SGL_ATTRIBUTE_FLAGS_64BIT_TRANSACTION 0x0004
\r
1505 +#define I2O_SGL_ATTRIBUTE_FLAGS_32BIT_LOCAL_ADDRESS 0x0000
\r
1507 +/* SG Size defines */
\r
1509 +#define I2O_SG_COUNT_SZ 24
\r
1510 +#define I2O_SG_FLAGS_SZ 8
\r
1512 +/* Standard Flags and Count fields for SG Elements */
\r
1514 +typedef struct _I2O_FLAGS_COUNT {
\r
1515 + BF Count:I2O_SG_COUNT_SZ;
\r
1516 + BF Flags:I2O_SG_FLAGS_SZ;
\r
1517 +} I2O_FLAGS_COUNT, *PI2O_FLAGS_COUNT;
\r
1519 +/* Bit Bucket Element */
\r
1520 +typedef struct _I2O_SGE_BIT_BUCKET_ELEMENT {
\r
1521 + I2O_FLAGS_COUNT FlagsCount;
\r
1522 + U32 BufferContext;
\r
1523 +} I2O_SGE_BIT_BUCKET_ELEMENT, *PI2O_SGE_BIT_BUCKET_ELEMENT;
\r
1525 +/* Chain Addressing Scatter-Gather Element */
\r
1527 +typedef struct _I2O_SGE_CHAIN_ELEMENT {
\r
1528 + I2O_FLAGS_COUNT FlagsCount;
\r
1529 + U32 PhysicalAddress;
\r
1530 +} I2O_SGE_CHAIN_ELEMENT, *PI2O_SGE_CHAIN_ELEMENT;
\r
1532 +/* Chain Addressing with Context Scatter-Gather Element */
\r
1534 +typedef struct _I2O_SGE_CHAIN_CONTEXT_ELEMENT {
\r
1535 + I2O_FLAGS_COUNT FlagsCount;
\r
1537 + U32 PhysicalAddress;
\r
1538 +} I2O_SGE_CHAIN_CONTEXT_ELEMENT, *PI2O_SGE_CHAIN_CONTEXT_ELEMENT;
\r
1540 +/* Ignore Scatter-Gather Element */
\r
1542 +typedef struct _I2O_SGE_IGNORE_ELEMENT {
\r
1543 + I2O_FLAGS_COUNT FlagsCount;
\r
1544 +} I2O_SGE_IGNORE_ELEMENT, *PI2O_SGE_IGNORE_ELEMENT;
\r
1546 +/* Immediate Data Element */
\r
1548 +typedef struct _I2O_SGE_IMMEDIATE_DATA_ELEMENT {
\r
1549 + I2O_FLAGS_COUNT FlagsCount;
\r
1550 +} I2O_SGE_IMMEDIATE_DATA_ELEMENT, *PI2O_SGE_IMMEDIATE_DATA_ELEMENT;
\r
1552 +/* Immediate Data with Context Element */
\r
1554 +typedef struct _I2O_SGE_IMMEDIATE_DATA_CONTEXT_ELEMENT {
\r
1555 + I2O_FLAGS_COUNT FlagsCount;
\r
1556 + U32 BufferContext;
\r
1557 +} I2O_SGE_IMMEDIATE_DATA_CONTEXT_ELEMENT, *PI2O_SGE_IMMEDIATE_DATA_CONTEXT_ELEMENT;
\r
1559 +/* Long Transaction Parameters Element */
\r
1561 +typedef struct _I2O_SGE_LONG_TRANSACTION_ELEMENT {
\r
1562 + BF LongElementLength:I2O_SG_COUNT_SZ;
\r
1563 + BF Flags:I2O_SG_FLAGS_SZ;
\r
1564 + U32 BufferContext;
\r
1565 +} I2O_SGE_LONG_TRANSACTION_ELEMENT, *PI2O_SGE_LONG_TRANSACTION_ELEMENT;
\r
1567 +/* Page List Scatter-Gather Element */
\r
1569 +typedef struct _I2O_SGE_PAGE_ELEMENT {
\r
1570 + I2O_FLAGS_COUNT FlagsCount;
\r
1571 + U32 PhysicalAddress[1];
\r
1572 +} I2O_SGE_PAGE_ELEMENT , *PI2O_SGE_PAGE_ELEMENT ;
\r
1574 +/* Page List with Context Scatter-Gather Element */
\r
1576 +typedef struct _I2O_SGE_PAGE_CONTEXT_ELEMENT {
\r
1577 + I2O_FLAGS_COUNT FlagsCount;
\r
1578 + U32 BufferContext[1];
\r
1579 + U32 PhysicalAddress[1];
\r
1580 +} I2O_SGE_PAGE_CONTEXT_ELEMENT, *PI2O_SGE_PAGE_CONTEXT_ELEMENT;
\r
1582 +/* SGL Attribute Element */
\r
1584 +typedef struct _I2O_SGE_SGL_ATTRIBUTES_ELEMENT {
\r
1585 + U16 SglAttributeFlags;
\r
1586 + U8 ElementLength;
\r
1588 + U32 PageFrameSize;
\r
1589 +} I2O_SGE_SGL_ATTRIBUTES_ELEMENT, *PI2O_SGE_SGL_ATTRIBUTES_ELEMENT;
\r
1591 +/* Short Transaction Parameters Element */
\r
1593 +typedef struct _I2O_SGE_SHORT_TRANSACTION_ELEMENT {
\r
1594 + U16 ClassFields;
\r
1595 + U8 ElementLength;
\r
1597 + U32 BufferContext;
\r
1598 +} I2O_SGE_SHORT_TRANSACTION_ELEMENT, *PI2O_SGE_SHORT_TRANSACTION_ELEMENT;
\r
1600 +/* Simple Addressing Scatter-Gather Element */
\r
1602 +typedef struct _I2O_SGE_SIMPLE_ELEMENT {
\r
1603 + I2O_FLAGS_COUNT FlagsCount;
\r
1604 + U32 PhysicalAddress;
\r
1605 +} I2O_SGE_SIMPLE_ELEMENT, *PI2O_SGE_SIMPLE_ELEMENT;
\r
1607 +/* Simple Addressing with Context Scatter-Gather Element */
\r
1609 +typedef struct _I2O_SGE_SIMPLE_CONTEXT_ELEMENT {
\r
1610 + I2O_FLAGS_COUNT FlagsCount;
\r
1611 + U32 BufferContext[1];
\r
1612 + U32 PhysicalAddress;
\r
1613 +} I2O_SGE_SIMPLE_CONTEXT_ELEMENT, *PI2O_SGE_SIMPLE_CONTEXT_ELEMENT;
\r
1615 +/* Transport Detail Element */
\r
1617 +typedef struct _I2O_SGE_TRANSPORT_ELEMENT {
\r
1618 + BF LongElementLength:I2O_SG_COUNT_SZ;
\r
1619 + BF Flags:I2O_SG_FLAGS_SZ;
\r
1620 +} I2O_SGE_TRANSPORT_ELEMENT, *PI2O_SGE_TRANSPORT_ELEMENT;
\r
1623 +typedef struct _I2O_SG_ELEMENT {
\r
1625 + /* Bit Bucket Element */
\r
1626 + I2O_SGE_BIT_BUCKET_ELEMENT BitBucket;
\r
1628 + /* Chain Addressing Element */
\r
1629 + I2O_SGE_CHAIN_ELEMENT Chain;
\r
1631 + /* Chain Addressing with Context Element */
\r
1632 + I2O_SGE_CHAIN_CONTEXT_ELEMENT ChainContext;
\r
1634 + /* Ignore Scatter-Gather Element */
\r
1635 + I2O_SGE_IGNORE_ELEMENT Ignore;
\r
1637 + /* Immediate Data Element */
\r
1638 + I2O_SGE_IMMEDIATE_DATA_ELEMENT ImmediateData;
\r
1640 + /* Immediate Data with Context Element */
\r
1641 + I2O_SGE_IMMEDIATE_DATA_CONTEXT_ELEMENT ImmediateDataContext;
\r
1643 + /* Long Transaction Parameters Element */
\r
1644 + I2O_SGE_LONG_TRANSACTION_ELEMENT LongTransaction;
\r
1646 + /* Page List Element */
\r
1647 + I2O_SGE_PAGE_ELEMENT Page;
\r
1649 + /* Page List with Context Element */
\r
1650 + I2O_SGE_PAGE_CONTEXT_ELEMENT PageContext;
\r
1652 + /* SGL Attribute Element */
\r
1653 + I2O_SGE_SGL_ATTRIBUTES_ELEMENT SGLAttribute;
\r
1655 + /* Short Transaction Parameters Element */
\r
1656 + I2O_SGE_SHORT_TRANSACTION_ELEMENT ShortTransaction;
\r
1658 + /* Simple Addressing Element */
\r
1659 + I2O_SGE_SIMPLE_ELEMENT Simple[1];
\r
1661 + /* Simple Addressing with Context Element */
\r
1662 + I2O_SGE_SIMPLE_CONTEXT_ELEMENT SimpleContext[1];
\r
1664 + /* Transport Detail Element */
\r
1665 + I2O_SGE_TRANSPORT_ELEMENT Transport;
\r
1667 +} I2O_SG_ELEMENT, *PI2O_SG_ELEMENT;
\r
1669 +/* I2O BSA Block Read Message Frame */
\r
1670 +typedef struct _I2O_BSA_READ_MESSAGE {
\r
1671 + I2O_MESSAGE_FRAME StdMessageFrame;
\r
1672 + I2O_TRANSACTION_CONTEXT TransactionContext;
\r
1673 + I2O_BSA_READ_FLAGS ControlFlags;
\r
1674 + U8 TimeMultiplier;
\r
1676 + U32 TransferByteCount;
\r
1677 + U64 LogicalByteAddress;
\r
1678 + I2O_SG_ELEMENT SGL;
\r
1679 +} I2O_BSA_READ_MESSAGE, *PI2O_BSA_READ_MESSAGE;
\r
1682 +/***********************************************************************/
\r
1684 +/* Class ID Block */
\r
1686 +typedef struct _I2O_CLASS_ID {
\r
1687 + BF Class:I2O_CLASS_ID_SZ;
\r
1688 + BF Version:I2O_4BIT_VERSION_SZ;
\r
1689 + BF OrganizationID:I2O_CLASS_ORGANIZATION_ID_SZ;
\r
1690 +} I2O_CLASS_ID, *PI2O_CLASS_ID;
\r
1693 +/****************************************************************************/
\r
1694 +/* Logical Configuration Table */
\r
1695 +/****************************************************************************/
\r
1697 +/* I2O Logical Configuration Table structures. */
\r
1699 +#define I2O_IDENTITY_TAG_SZ 8
\r
1701 +/* I2O Logical Configuration Table Device Flags */
\r
1703 +#define I2O_LCT_DEVICE_FLAGS_CONF_DIALOG_REQUEST 0x01
\r
1704 +#define I2O_LCT_DEVICE_FLAGS_MORE_THAN_1_USER 0x02
\r
1705 +#define I2O_LCT_DEVICE_FLAGS_PEER_SERVICE_DISABLED 0x10
\r
1706 +#define I2O_LCT_DEVICE_FLAGS_MANAGEMENT_SERVICE_DISABLED 0x20
\r
1708 +/* LCT Entry Block */
\r
1710 +typedef struct _I2O_LCT_ENTRY {
\r
1711 + BF TableEntrySize:I2O_COMMON_LENGTH_FIELD_SZ;
\r
1712 + BF LocalTID:I2O_TID_SZ;
\r
1713 + BF reserved:I2O_4BIT_VERSION_SZ;
\r
1714 + U32 ChangeIndicator;
\r
1715 + U32 DeviceFlags;
\r
1716 + I2O_CLASS_ID ClassID;
\r
1717 + U32 SubClassInfo;
\r
1718 + BF UserTID:I2O_TID_SZ;
\r
1719 + BF ParentTID:I2O_TID_SZ;
\r
1720 + BF BiosInfo:I2O_BIOS_INFO_SZ;
\r
1721 + U8 IdentityTag[I2O_IDENTITY_TAG_SZ];
\r
1722 + U32 EventCapabilities;
\r
1723 +} I2O_LCT_ENTRY, *PI2O_LCT_ENTRY;
\r
1725 +/* I2O Logical Configuration Table structure. */
\r
1726 +typedef struct _I2O_LCT {
\r
1727 + BF TableSize:I2O_COMMON_LENGTH_FIELD_SZ;
\r
1728 + BF BootDeviceTID:I2O_TID_SZ;
\r
1729 + BF LctVer:I2O_4BIT_VERSION_SZ;
\r
1731 + U32 CurrentChangeIndicator;
\r
1732 + I2O_LCT_ENTRY LCTEntry[1];
\r
1733 +} I2O_LCT, *PI2O_LCT;
\r
1736 +/****************************************************************************/
\r
1738 +/* I2O Executive Function Codes. */
\r
1740 +#define I2O_EXEC_ADAPTER_ASSIGN 0xB3
\r
1741 +#define I2O_EXEC_ADAPTER_READ 0xB2
\r
1742 +#define I2O_EXEC_ADAPTER_RELEASE 0xB5
\r
1743 +#define I2O_EXEC_BIOS_INFO_SET 0xA5
\r
1744 +#define I2O_EXEC_BOOT_DEVICE_SET 0xA7
\r
1745 +#define I2O_EXEC_CONFIG_VALIDATE 0xBB
\r
1746 +#define I2O_EXEC_CONN_SETUP 0xCA
\r
1747 +#define I2O_EXEC_DDM_DESTROY 0xB1
\r
1748 +#define I2O_EXEC_DDM_ENABLE 0xD5
\r
1749 +#define I2O_EXEC_DDM_QUIESCE 0xC7
\r
1750 +#define I2O_EXEC_DDM_RESET 0xD9
\r
1751 +#define I2O_EXEC_DDM_SUSPEND 0xAF
\r
1752 +#define I2O_EXEC_DEVICE_ASSIGN 0xB7
\r
1753 +#define I2O_EXEC_DEVICE_RELEASE 0xB9
\r
1754 +#define I2O_EXEC_HRT_GET 0xA8
\r
1755 +#define I2O_EXEC_IOP_CLEAR 0xBE
\r
1756 +#define I2O_EXEC_IOP_CONNECT 0xC9
\r
1757 +#define I2O_EXEC_IOP_RESET 0xBD
\r
1758 +#define I2O_EXEC_LCT_NOTIFY 0xA2
\r
1759 +#define I2O_EXEC_OUTBOUND_INIT 0xA1
\r
1760 +#define I2O_EXEC_PATH_ENABLE 0xD3
\r
1761 +#define I2O_EXEC_PATH_QUIESCE 0xC5
\r
1762 +#define I2O_EXEC_PATH_RESET 0xD7
\r
1763 +#define I2O_EXEC_STATIC_MF_CREATE 0xDD
\r
1764 +#define I2O_EXEC_STATIC_MF_RELEASE 0xDF
\r
1765 +#define I2O_EXEC_STATUS_GET 0xA0
\r
1766 +#define I2O_EXEC_SW_DOWNLOAD 0xA9
\r
1767 +#define I2O_EXEC_SW_UPLOAD 0xAB
\r
1768 +#define I2O_EXEC_SW_REMOVE 0xAD
\r
1769 +#define I2O_EXEC_SYS_ENABLE 0xD1
\r
1770 +#define I2O_EXEC_SYS_MODIFY 0xC1
\r
1771 +#define I2O_EXEC_SYS_QUIESCE 0xC3
\r
1772 +#define I2O_EXEC_SYS_TAB_SET 0xA3
\r
1775 +/* I2O Get Status State values */
\r
1777 +#define I2O_IOP_STATE_INITIALIZING 0x01
\r
1778 +#define I2O_IOP_STATE_RESET 0x02
\r
1779 +#define I2O_IOP_STATE_HOLD 0x04
\r
1780 +#define I2O_IOP_STATE_READY 0x05
\r
1781 +#define I2O_IOP_STATE_OPERATIONAL 0x08
\r
1782 +#define I2O_IOP_STATE_FAILED 0x10
\r
1783 +#define I2O_IOP_STATE_FAULTED 0x11
\r
1786 +#define I2O_EXEC_STATUS_GET_RESERVED_SZ 16
\r
1788 +/* ExecStatusGet Function Message Frame structure. */
\r
1790 +typedef struct _I2O_EXEC_STATUS_GET_MESSAGE {
\r
1791 + U8 VersionOffset;
\r
1793 + U16 MessageSize;
\r
1794 + BF TargetAddress:I2O_TID_SZ;
\r
1795 + BF InitiatorAddress:I2O_TID_SZ;
\r
1796 + BF Function:I2O_FUNCTION_SZ;
\r
1797 + U8 Reserved[I2O_EXEC_STATUS_GET_RESERVED_SZ];
\r
1798 + U32 ReplyBufferAddressLow;
\r
1799 + U32 ReplyBufferAddressHigh;
\r
1800 + U32 ReplyBufferLength;
\r
1801 +} I2O_EXEC_STATUS_GET_MESSAGE, *PI2O_EXEC_STATUS_GET_MESSAGE;
\r
1804 +#define I2O_IOP_STATUS_PROD_ID_STR_SZ 24
\r
1805 +#define I2O_EXEC_STATUS_GET_REPLY_RESERVED_SZ 6
\r
1807 +/* ExecStatusGet reply Structure */
\r
1809 +#define I2O_IOP_CAP_CONTEXT_32_ONLY 0x00000000
\r
1810 +#define I2O_IOP_CAP_CONTEXT_64_ONLY 0x00000001
\r
1811 +#define I2O_IOP_CAP_CONTEXT_32_64_NOT_CURRENTLY 0x00000002
\r
1812 +#define I2O_IOP_CAP_CONTEXT_32_64_CURRENTLY 0x00000003
\r
1813 +#define I2O_IOP_CAP_CURRENT_CONTEXT_NOT_CONFIG 0x00000000
\r
1814 +#define I2O_IOP_CAP_CURRENT_CONTEXT_32_ONLY 0x00000004
\r
1815 +#define I2O_IOP_CAP_CURRENT_CONTEXT_64_ONLY 0x00000008
\r
1816 +#define I2O_IOP_CAP_CURRENT_CONTEXT_32_64 0x0000000C
\r
1817 +#define I2O_IOP_CAP_INBOUND_PEER_SUPPORT 0x00000010
\r
1818 +#define I2O_IOP_CAP_OUTBOUND_PEER_SUPPORT 0x00000020
\r
1819 +#define I2O_IOP_CAP_PEER_TO_PEER_SUPPORT 0x00000040
\r
1821 +typedef struct _I2O_EXEC_STATUS_GET_REPLY {
\r
1822 + U16 OrganizationID;
\r
1824 + BF IOP_ID:I2O_IOP_ID_SZ;
\r
1825 + BF reserved1:I2O_RESERVED_4BITS;
\r
1826 + BF HostUnitID:I2O_UNIT_ID_SZ;
\r
1827 + BF SegmentNumber:I2O_SEGMENT_NUMBER_SZ;
\r
1828 + BF I2oVersion:I2O_4BIT_VERSION_SZ;
\r
1829 + BF IopState:I2O_IOP_STATE_SZ;
\r
1830 + BF MessengerType:I2O_MESSENGER_TYPE_SZ;
\r
1831 + U16 InboundMFrameSize;
\r
1834 + U32 MaxInboundMFrames;
\r
1835 + U32 CurrentInboundMFrames;
\r
1836 + U32 MaxOutboundMFrames;
\r
1837 + U8 ProductIDString[I2O_IOP_STATUS_PROD_ID_STR_SZ];
\r
1838 + U32 ExpectedLCTSize;
\r
1839 + U32 IopCapabilities;
\r
1840 + U32 DesiredPrivateMemSize;
\r
1841 + U32 CurrentPrivateMemSize;
\r
1842 + U32 CurrentPrivateMemBase;
\r
1843 + U32 DesiredPrivateIOSize;
\r
1844 + U32 CurrentPrivateIOSize;
\r
1845 + U32 CurrentPrivateIOBase;
\r
1846 + U8 reserved3[3];
\r
1848 +} I2O_EXEC_STATUS_GET_REPLY, *PI2O_EXEC_STATUS_GET_REPLY;
\r
1851 +/***************************************************************************/
\r
1853 +/* ExecSysTabSet (System Table) Function Message Frame structure. */
\r
1855 +#define I2O_EXEC_SYS_TAB_IOP_ID_LOCAL_IOP 0x000
\r
1856 +#define I2O_EXEC_SYS_TAB_IOP_ID_LOCAL_HOST 0x001
\r
1857 +#define I2O_EXEC_SYS_TAB_IOP_ID_UNKNOWN_IOP 0xFFF
\r
1858 +#define I2O_EXEC_SYS_TAB_HOST_UNIT_ID_LOCAL_UNIT 0x0000
\r
1859 +#define I2O_EXEC_SYS_TAB_HOST_UNIT_ID_UNKNOWN_UNIT 0xffff
\r
1860 +#define I2O_EXEC_SYS_TAB_SEG_NUMBER_LOCAL_SEGMENT 0x000
\r
1861 +#define I2O_EXEC_SYS_TAB_SEG_NUMBER_UNKNOWN_SEGMENT 0xfff
\r
1863 +typedef struct _I2O_EXEC_SYS_TAB_SET_MESSAGE {
\r
1864 + I2O_MESSAGE_FRAME StdMessageFrame;
\r
1865 + I2O_TRANSACTION_CONTEXT TransactionContext;
\r
1866 + BF IOP_ID:I2O_IOP_ID_SZ;
\r
1867 + BF reserved:I2O_RESERVED_4BITS;
\r
1868 + BF HostUnitID:I2O_UNIT_ID_SZ;
\r
1869 + BF SegmentNumber:I2O_SEGMENT_NUMBER_SZ;
\r
1870 + BF reserved2:I2O_RESERVED_20BITS;
\r
1871 + I2O_SG_ELEMENT SGL;
\r
1872 +} I2O_EXEC_SYS_TAB_SET_MESSAGE, *PI2O_EXEC_SYS_TAB_SET_MESSAGE;
\r
1875 +/****************************************************************************/
\r
1877 +/* Operation Function Numbers */
\r
1879 +#define I2O_PARAMS_OPERATION_FIELD_GET 0x0001
\r
1880 +#define I2O_PARAMS_OPERATION_LIST_GET 0x0002
\r
1881 +#define I2O_PARAMS_OPERATION_MORE_GET 0x0003
\r
1882 +#define I2O_PARAMS_OPERATION_SIZE_GET 0x0004
\r
1883 +#define I2O_PARAMS_OPERATION_TABLE_GET 0x0005
\r
1884 +#define I2O_PARAMS_OPERATION_FIELD_SET 0x0006
\r
1885 +#define I2O_PARAMS_OPERATION_LIST_SET 0x0007
\r
1886 +#define I2O_PARAMS_OPERATION_ROW_ADD 0x0008
\r
1887 +#define I2O_PARAMS_OPERATION_ROW_DELETE 0x0009
\r
1888 +#define I2O_PARAMS_OPERATION_TABLE_CLEAR 0x000A
\r
1890 +/* Operations List Header */
\r
1892 +typedef struct _I2O_PARAM_OPERATIONS_LIST_HEADER {
\r
1893 + U16 OperationCount;
\r
1895 +} I2O_PARAM_OPERATIONS_LIST_HEADER, *PI2O_PARAM_OPERATIONS_LIST_HEADER;
\r
1897 +/* Results List Header */
\r
1899 +typedef struct _I2O_PARAM_RESULTS_LIST_HEADER {
\r
1900 + U16 ResultCount;
\r
1902 +} I2O_PARAM_RESULTS_LIST_HEADER, *PI2O_PARAM_RESULTS_LIST_HEADER;
\r
1904 +/* Read Operation Result Block Template Structure */
\r
1906 +typedef struct _I2O_PARAM_READ_OPERATION_RESULT {
\r
1909 + U8 ErrorInfoSize;
\r
1910 + /* Operations Results */
\r
1911 + /* Pad (if any) */
\r
1912 + /* ErrorInformation (if any) */
\r
1913 +} I2O_PARAM_READ_OPERATION_RESULT, *PI2O_PARAM_READ_OPERATION_RESULT;
\r
1915 +/* Operation Template for Specific Fields */
\r
1917 +typedef struct _I2O_PARAM_OPERATION_SPECIFIC_TEMPLATE {
\r
1919 + U16 GroupNumber;
\r
1921 + U16 FieldIdx[1];
\r
1922 + /* Pad (if any) */
\r
1923 +} I2O_PARAM_OPERATION_SPECIFIC_TEMPLATE, *PI2O_PARAM_OPERATION_SPECIFIC_TEMPLATE;
\r
1925 +/* Operation Template for All Fields */
\r
1927 +typedef struct _I2O_PARAM_OPERATION_ALL_TEMPLATE {
\r
1929 + U16 GroupNumber;
\r
1931 + /* Pad (if any) */
\r
1932 +} I2O_PARAM_OPERATION_ALL_TEMPLATE, *PI2O_PARAM_OPERATION_ALL_TEMPLATE;
\r
1934 +/****************************************************************************/
\r
1936 +/* Utility Message class functions. */
\r
1938 +#define I2O_UTIL_NOP 0x00
\r
1939 +#define I2O_UTIL_ABORT 0x01
\r
1940 +#define I2O_UTIL_CLAIM 0x09
\r
1941 +#define I2O_UTIL_CLAIM_RELEASE 0x0B
\r
1942 +#define I2O_UTIL_CONFIG_DIALOG 0x10
\r
1943 +#define I2O_UTIL_DEVICE_RESERVE 0x0D
\r
1944 +#define I2O_UTIL_DEVICE_RELEASE 0x0F
\r
1945 +#define I2O_UTIL_EVENT_ACKNOWLEDGE 0x14
\r
1946 +#define I2O_UTIL_EVENT_REGISTER 0x13
\r
1947 +#define I2O_UTIL_LOCK 0x17
\r
1948 +#define I2O_UTIL_LOCK_RELEASE 0x19
\r
1949 +#define I2O_UTIL_PARAMS_GET 0x06
\r
1950 +#define I2O_UTIL_PARAMS_SET 0x05
\r
1951 +#define I2O_UTIL_REPLY_FAULT_NOTIFY 0x15
\r
1953 +/****************************************************************************/
\r
1955 +/* UtilNOP Function Message Frame structure. */
\r
1957 +typedef struct _I2O_UTIL_NOP_MESSAGE {
\r
1958 + I2O_MESSAGE_FRAME StdMessageFrame;
\r
1959 +} I2O_UTIL_NOP_MESSAGE, *PI2O_UTIL_NOP_MESSAGE;
\r
1962 +/*************************************************************************/
\r
1964 +/* UtilParamsGet Message Frame structure. */
\r
1966 +typedef struct _I2O_UTIL_PARAMS_GET_MESSAGE {
\r
1967 + I2O_MESSAGE_FRAME StdMessageFrame;
\r
1968 + I2O_TRANSACTION_CONTEXT TransactionContext;
\r
1969 + U32 OperationFlags;
\r
1970 + I2O_SG_ELEMENT SGL;
\r
1971 +} I2O_UTIL_PARAMS_GET_MESSAGE, *PI2O_UTIL_PARAMS_GET_MESSAGE;
\r
1974 +/****************************************************************************/
\r
1975 +/* GROUP Parameter Groups */
\r
1976 +/****************************************************************************/
\r
1978 +/* GROUP Configuration and Operating Structures and Defines */
\r
1980 +/* Groups Numbers */
\r
1982 +#define I2O_UTIL_PARAMS_DESCRIPTOR_GROUP_NO 0xF000
\r
1983 +#define I2O_UTIL_PHYSICAL_DEVICE_TABLE_GROUP_NO 0xF001
\r
1984 +#define I2O_UTIL_CLAIMED_TABLE_GROUP_NO 0xF002
\r
1985 +#define I2O_UTIL_USER_TABLE_GROUP_NO 0xF003
\r
1986 +#define I2O_UTIL_PRIVATE_MESSAGE_EXTENSIONS_GROUP_NO 0xF005
\r
1987 +#define I2O_UTIL_AUTHORIZED_USER_TABLE_GROUP_NO 0xF006
\r
1988 +#define I2O_UTIL_DEVICE_IDENTITY_GROUP_NO 0xF100
\r
1989 +#define I2O_UTIL_DDM_IDENTITY_GROUP_NO 0xF101
\r
1990 +#define I2O_UTIL_USER_INFORMATION_GROUP_NO 0xF102
\r
1991 +#define I2O_UTIL_SGL_OPERATING_LIMITS_GROUP_NO 0xF103
\r
1992 +#define I2O_UTIL_SENSORS_GROUP_NO 0xF200
\r
1994 +/* UTIL Group F000h - GROUP DESCRIPTORS Parameter Group */
\r
1996 +#define I2O_UTIL_GROUP_PROPERTIES_GROUP_TABLE 0x01
\r
1997 +#define I2O_UTIL_GROUP_PROPERTIES_ROW_ADDITION 0x02
\r
1998 +#define I2O_UTIL_GROUP_PROPERTIES_ROW_DELETION 0x04
\r
1999 +#define I2O_UTIL_GROUP_PROPERTIES_CLEAR_OPERATION 0x08
\r
2001 +/* UTIL Group F100h - Device Identity Parameter Group */
\r
2003 +typedef struct _I2O_UTIL_DEVICE_IDENTITY_SCALAR {
\r
2007 + U8 VendorInfo[I2O_DEVID_VENDOR_INFO_SZ];
\r
2008 + U8 ProductInfo[I2O_DEVID_PRODUCT_INFO_SZ];
\r
2009 + U8 Description[I2O_DEVID_DESCRIPTION_SZ];
\r
2010 + U8 ProductRevLevel[I2O_DEVID_REV_LEVEL_SZ];
\r
2012 + U8 SerialNumber[I2O_MAX_SERIAL_NUMBER_SZ];
\r
2013 +} I2O_UTIL_DEVICE_IDENTITY_SCALAR, *PI2O_UTIL_DEVICE_IDENTITY_SCALAR;
\r
2015 +/* UTIL Group F101h - DDM Identity Parameter Group */
\r
2017 +typedef struct _I2O_UTIL_DDM_IDENTITY_SCALAR {
\r
2019 + U8 ModuleName[I2O_MODULE_NAME_SZ];
\r
2020 + U8 ModuleRevLevel[I2O_DEVID_REV_LEVEL_SZ];
\r
2022 + U8 SerialNumber[I2O_MAX_SERIAL_NUMBER_SZ];
\r
2023 +} I2O_UTIL_DDM_IDENTITY_SCALAR, *PI2O_UTIL_DDM_IDENTITY_SCALAR;
\r
2025 +/****************************************************************************/
\r
2027 +/* Block Storage Parameter Groups */
\r
2029 +#define I2O_BSA_DEVICE_INFO_GROUP_NO 0x0000
\r
2030 +#define I2O_BSA_OPERATIONAL_CONTROL_GROUP_NO 0x0001
\r
2031 +#define I2O_BSA_POWER_CONTROL_GROUP_NO 0x0002
\r
2032 +#define I2O_BSA_CACHE_CONTROL_GROUP_NO 0x0003
\r
2033 +#define I2O_BSA_MEDIA_INFO_GROUP_NO 0x0004
\r
2034 +#define I2O_BSA_ERROR_LOG_GROUP_NO 0x0005
\r
2036 +/***************************************************************************/
\r
2038 +/* I2O Block Storage Reply Message Frame Template */
\r
2040 +typedef struct _I2O_BSA_REPLY_MESSAGE_FRAME {
\r
2041 + I2O_MESSAGE_FRAME StdMessageFrame;
\r
2042 + I2O_TRANSACTION_CONTEXT TransactionContext;
\r
2043 + U16 DetailedStatusCode;
\r
2046 +/* ReplyPayload */
\r
2047 +} I2O_BSA_REPLY_MESSAGE_FRAME, *PI2O_BSA_REPLY_MESSAGE_FRAME;
\r
2049 +/**************************************************************************/
\r
2051 +/* Block Storage Group 0000h - Device Information Parameter Group */
\r
2053 +typedef struct _I2O_BSA_DEVICE_INFO_SCALAR {
\r
2055 + U8 NumberOfPaths;
\r
2056 + U16 PowerState;
\r
2058 + U64 DeviceCapacity;
\r
2059 + U32 DeviceCapabilitySupport;
\r
2060 + U32 DeviceState;
\r
2061 +} I2O_BSA_DEVICE_INFO_SCALAR, *PI2O_BSA_DEVICE_INFO_SCALAR;
\r
2064 +/****************************************************************************/
\r
2066 +/* I2O BSA Control Flags */
\r
2068 +typedef U16 I2O_BSA_CTL_FLAGS;
\r
2070 +/* I2O BSA Cache Flush Message Frame */
\r
2072 +typedef struct _I2O_BSA_CACHE_FLUSH_MESSAGE {
\r
2073 + I2O_MESSAGE_FRAME StdMessageFrame;
\r
2074 + I2O_TRANSACTION_CONTEXT TransactionContext;
\r
2075 + I2O_BSA_CTL_FLAGS ControlFlags;
\r
2076 + U8 TimeMultiplier;
\r
2078 +} I2O_BSA_CACHE_FLUSH_MESSAGE, *PI2O_BSA_CACHE_FLUSH_MESSAGE;
\r
2081 +/****************************************************************************/
\r
2084 +/* ExecOutboundInit Function Message Frame structure. */
\r
2086 +typedef struct _I2O_EXEC_OUTBOUND_INIT_MESSAGE {
\r
2087 + I2O_MESSAGE_FRAME StdMessageFrame;
\r
2088 + I2O_TRANSACTION_CONTEXT TransactionContext;
\r
2089 + U32 HostPageFrameSize;
\r
2092 + U16 OutboundMFrameSize;
\r
2093 + I2O_SG_ELEMENT SGL;
\r
2094 +} I2O_EXEC_OUTBOUND_INIT_MESSAGE, *PI2O_EXEC_OUTBOUND_INIT_MESSAGE;
\r
2097 +#define I2O_EXEC_OUTBOUND_INIT_IN_PROGRESS 0x01
\r
2098 +#define I2O_EXEC_OUTBOUND_INIT_REJECTED 0x02
\r
2099 +#define I2O_EXEC_OUTBOUND_INIT_FAILED 0x03
\r
2100 +#define I2O_EXEC_OUTBOUND_INIT_COMPLETE 0x04
\r
2102 +#define I2O_EXEC_OUTBOUND_INIT_RESERVED_SZ 3
\r
2105 +typedef struct _I2O_EXEC_OUTBOUND_INIT_STATUS {
\r
2107 + U8 reserved[I2O_EXEC_OUTBOUND_INIT_RESERVED_SZ];
\r
2108 +} I2O_EXEC_OUTBOUND_INIT_STATUS, *PI2O_EXEC_OUTBOUND_INIT_STATUS;
\r
2111 +typedef struct _I2O_EXEC_OUTBOUND_INIT_RECLAIM_LIST {
\r
2113 + U32 MFAReleaseCount;
\r
2114 + U32 MFAAddress[1];
\r
2115 +} I2O_EXEC_OUTBOUND_INIT_RECLAIM_LIST, *PI2O_EXEC_OUTBOUND_INIT_RECLAIM_LIST;
\r
2117 +/****************************************************************************/
\r
2120 +/* ExecSysEnable Function Message Frame structure. */
\r
2122 +typedef struct _I2O_EXEC_SYS_ENABLE_MESSAGE {
\r
2123 + I2O_MESSAGE_FRAME StdMessageFrame;
\r
2124 + I2O_TRANSACTION_CONTEXT TransactionContext;
\r
2125 +} I2O_EXEC_SYS_ENABLE_MESSAGE, *PI2O_EXEC_SYS_ENABLE_MESSAGE;
\r
2128 +/****************************************************************************/
\r
2130 +/* ExecLCTNotify Function Message Frame structure. */
\r
2132 +typedef struct _I2O_EXEC_LCT_NOTIFY_MESSAGE {
\r
2133 + I2O_MESSAGE_FRAME StdMessageFrame;
\r
2134 + I2O_TRANSACTION_CONTEXT TransactionContext;
\r
2135 + U32 ClassIdentifier;
\r
2136 + U32 LastReportedChangeIndicator;
\r
2137 + I2O_SG_ELEMENT SGL;
\r
2138 +} I2O_EXEC_LCT_NOTIFY_MESSAGE, *PI2O_EXEC_LCT_NOTIFY_MESSAGE;
\r
2140 +/****************************************************************************/
\r
2142 +/* ExecSysTabSet (System Table) Header Reply structure. */
\r
2144 +#define I2O_SET_SYSTAB_RESERVED_SZ 8
\r
2146 +typedef struct _I2O_SET_SYSTAB_HEADER {
\r
2147 + U8 NumberEntries;
\r
2148 + U8 SysTabVersion;
\r
2150 + U32 CurrentChangeIndicator;
\r
2151 + U8 reserved1[I2O_SET_SYSTAB_RESERVED_SZ];
\r
2152 +/* I2O_SYSTAB_ENTRY SysTabEntry[1]; */
\r
2153 +} I2O_SET_SYSTAB_HEADER, *PI2O_SET_SYSTAB_HEADER;
\r
2156 +#define I2O_RESOURCE_MANAGER_VERSION 0
\r
2158 +typedef struct _MESSENGER_INFO {
\r
2159 + U32 InboundMessagePortAddressLow;
\r
2160 + U32 InboundMessagePortAddressHigh;
\r
2161 + } I2O_MESSENGER_INFO, *PI2O_MESSENGER_INFO;
\r
2163 +/* ExecSysTabSet IOP Descriptor Entry structure. */
\r
2165 +typedef struct _I2O_IOP_ENTRY {
\r
2166 + U16 OrganizationID;
\r
2168 + BF IOP_ID:I2O_IOP_ID_SZ;
\r
2169 + BF reserved1:I2O_RESERVED_20BITS;
\r
2170 + BF SegmentNumber:I2O_SEGMENT_NUMBER_SZ;
\r
2171 + BF I2oVersion:I2O_4BIT_VERSION_SZ;
\r
2172 + BF IopState:I2O_IOP_STATE_SZ;
\r
2173 + BF MessengerType:I2O_MESSENGER_TYPE_SZ;
\r
2174 + U16 InboundMessageFrameSize;
\r
2176 + U32 LastChanged;
\r
2177 + U32 IopCapabilities;
\r
2178 + I2O_MESSENGER_INFO MessengerInfo;
\r
2179 +} I2O_IOP_ENTRY, *PI2O_IOP_ENTRY;
\r
2182 +/****************************************************************************/
\r
2185 +#define I2O_EXEC_IOP_RESET_RESERVED_SZ 16
\r
2187 +#define I2O_EXEC_IOP_RESET_IN_PROGRESS 0x01
\r
2188 +#define I2O_EXEC_IOP_RESET_REJECTED 0x02
\r
2190 +#define I2O_EXEC_IOP_RESET_STATUS_RESERVED_SZ 3
\r
2192 +typedef struct _I2O_EXEC_IOP_RESET_STATUS {
\r
2194 + U8 reserved[I2O_EXEC_IOP_RESET_STATUS_RESERVED_SZ];
\r
2195 +} I2O_EXEC_IOP_RESET_STATUS, *PI2O_EXEC_IOP_RESET_STATUS;
\r
2198 +/* ExecIopReset Function Message Frame structure. */
\r
2200 +typedef struct _I2O_EXEC_IOP_RESET_MESSAGE {
\r
2201 + U8 VersionOffset;
\r
2203 + U16 MessageSize;
\r
2204 + BF TargetAddress:I2O_TID_SZ;
\r
2205 + BF InitiatorAddress:I2O_TID_SZ;
\r
2206 + BF Function:I2O_FUNCTION_SZ;
\r
2207 + U8 Reserved[I2O_EXEC_IOP_RESET_RESERVED_SZ];
\r
2208 + U32 StatusWordLowAddress;
\r
2209 + U32 StatusWordHighAddress;
\r
2210 +} I2O_EXEC_IOP_RESET_MESSAGE, *PI2O_EXEC_IOP_RESET_MESSAGE;
\r
2213 +/****************************************************************************/
\r
2214 +/* EXEC Group 0001h - IOP Message Interface Parameter Group */
\r
2216 +/* InitCode defines */
\r
2217 +#define I2O_MESSAGE_IF_INIT_CODE_NO_OWNER 0x00
\r
2218 +#define I2O_MESSAGE_IF_INIT_CODE_BIOS 0x10
\r
2219 +#define I2O_MESSAGE_IF_INIT_CODE_OEM_BIOS_EXTENSION 0x20
\r
2220 +#define I2O_MESSAGE_IF_INIT_CODE_ROM_BIOS_EXTENSION 0x30
\r
2221 +#define I2O_MESSAGE_IF_INIT_CODE_OS 0x80
\r
2223 +/****************************************************************************/
\r
2225 +#endif /* _I2ODEF_H_ */
\r
2226 diff -Nur linux-2.4.20.org/drivers/scsi/pti_st.c linux-2.4.20/drivers/scsi/pti_st.c
2227 --- linux-2.4.20.org/drivers/scsi/pti_st.c Wed Nov 5 08:47:58 2003
2228 +++ linux-2.4.20/drivers/scsi/pti_st.c Mon Oct 21 00:00:00 2002
2229 @@ -1,3521 +1,3792 @@
2230 -/*+M*************************************************************************
2231 - * Promise SuperTrak device driver for Linux.
2233 - * Copyright (c) 2001 Promise Technology, Inc.
2235 - * This program is free software; you can redistribute it and/or modify
2236 - * it under the terms of the GNU General Public License as published by
2237 - * the Free Software Foundation; either version 2 of the License, or
2238 - * (at your option) any later version.
2240 - * This program is distributed in the hope that it will be useful,
2241 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
2242 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2243 - * GNU General Public License for more details.
2245 - * You should have received a copy of the GNU General Public License
2246 - * along with this program; if not, write to the Free Software
2247 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2249 - * --------------------------------------------------------------------------
2250 - * Copyright (c) 1999-2001 Promise Technology, Inc.
2251 - * All rights reserved.
2253 - * Redistribution and use in source and binary forms, with or without
2254 - * modification, are permitted provided that the following conditions
2256 - * 1. Redistributions of source code must retain the above copyright
2257 - * notice, this list of conditions, and the following disclaimer,
2258 - * without modification, immediately at the beginning of the file.
2259 - * 2. Redistributions in binary form must reproduce the above copyright
2260 - * notice, this list of conditions and the following disclaimer in the
2261 - * documentation and/or other materials provided with the distribution.
2262 - * 3. The name of the author may not be used to endorse or promote products
2263 - * derived from this software without specific prior written permission.
2265 - * Where this Software is combined with software released under the terms of
2266 - * the GNU Public License ("GPL") and the terms of the GPL would require the
2267 - * combined work to also be released under the terms of the GPL, the terms
2268 - * and conditions of this License will apply in addition to those of the
2269 - * GPL with the exception of any terms or conditions of this License that
2270 - * conflict with, or are expressly prohibited by, the GPL.
2272 - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2273 - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2274 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2275 - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
2276 - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2277 - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2278 - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2279 - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2280 - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2281 - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2285 - *-M*************************************************************************/
2287 -#include <linux/string.h>
2288 -#include <linux/errno.h>
2291 -#include <linux/module.h>
2294 -#ifndef KERNEL_VERSION
2295 -# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
2298 -#if defined(MODULE)
2299 -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,0)
2300 -#include <linux/init.h>
2304 -#include <stdarg.h>
2305 -#include <asm/io.h>
2306 -#include <asm/irq.h>
2307 -#include <asm/byteorder.h>
2308 -#include <linux/version.h>
2309 -#include <linux/kernel.h>
2310 -#include <linux/ioport.h>
2311 -#include <linux/delay.h>
2312 -#include <linux/sched.h>
2313 -#include <linux/pci.h>
2314 -#include <linux/proc_fs.h>
2315 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
2316 -#include <linux/fs.h>
2318 -#include <linux/blk.h>
2319 -#include <linux/blkdev.h>
2320 -#include <linux/tqueue.h>
2321 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
2322 -#include <linux/tasks.h>
2324 -#include <linux/stat.h>
2325 -#include <linux/malloc.h> /* for kmalloc() */
2326 -#include <linux/config.h> /* for CONFIG_PCI */
2327 -#include <asm/segment.h>
2333 - __asm__ __volatile__("lock ; addl $0,0(%%esp)": : :"memory")
2335 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,16)
2336 -# include <asm/spinlock.h>
2338 -# include <linux/spinlock.h>
2340 -# include <linux/smp.h>
2341 -# define cpuid smp_processor_id()
2343 -#if defined(__SMP__)
2344 -# if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
2345 -# define DRIVER_LOCK_INIT \
2346 - spin_lock_init(&p->spin_lock);
2347 -# define DRIVER_LOCK \
2348 - if(!p->cpu_lock_count[cpuid]) { \
2349 - spin_lock_irqsave(&p->spin_lock, cpu_flags); \
2350 - p->cpu_lock_count[cpuid]++; \
2352 - p->cpu_lock_count[cpuid]++; \
2354 -# define DRIVER_UNLOCK \
2355 - if(--p->cpu_lock_count[cpuid] == 0) \
2356 - spin_unlock_irqrestore(&p->spin_lock, cpu_flags);
2358 -# define DRIVER_LOCK_INIT spin_lock_init(&p->spin_lock);
2359 -# define DRIVER_LOCK spin_lock(&p->spin_lock);
2360 -# define DRIVER_UNLOCK spin_unlock(&p->spin_lock);
2362 -#else /* __SMP__ */
2363 -#define DRIVER_LOCK_INIT
2364 -#define DRIVER_LOCK
2365 -#define DRIVER_UNLOCK
2366 -#endif /* __SMP__ */
2368 -#include <asm/uaccess.h>
2374 -#include "pti_st.h"
2375 -#include "pti_stdev.h"
2377 -#define PTI_ST_VERBOSE_DEBUGGING
2379 -#define PCI_DEVICE_ID_INTEL_i960 0x1960
2380 -#define PCI_DEVICE_ID_INTEL_i962 0x1962
2382 -#define VIRT_TO_BUS(a) (unsigned int)virt_to_bus((void *)(a))
2386 -struct proc_dir_entry proc_root =
2390 - * Inode number - ignore, it will be filled by
2391 - * proc_register[_dynamic]
2395 - * Length of the proc-file name
2399 - * The proc-file name
2401 - S_IFREG | S_IRUGO,
2403 - * File mode - this is a regular
2404 - * file which can be read by its
2405 - * owner, its group, and everybody
2410 - * Number of links (directories where the
2411 - * file is referenced)
2415 - * The uid and gid for the file - we give it
2420 - * The size of the file reported by ls.
2424 - * functions which can be done on the inode
2425 - * (linking, removing, etc.) - we don't
2428 - NULL, // procfile_read,
2430 - * The read function for this file,
2431 - * the function called when somebody
2432 - * tries to read something from it.
2436 - * We could have here a function to fill the
2437 - * file's inode, to enable us to play with
2438 - * permissions, ownership, etc.
2444 -struct proc_dir_entry proc_scsi_pti_st =
2446 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
2447 - PROC_SCSI_NOT_PRESENT,
2451 - * Inode number - ignore, it will be filled by
2452 - * proc_register[_dynamic]
2457 - * Length of the proc-file name
2461 - * The proc-file name
2463 - S_IFDIR | S_IRUGO | S_IXUGO,
2465 - * File mode - this is a regular
2466 - * file which can be read by its
2467 - * owner, its group, and everybody
2472 - * Number of links (directories where the
2473 - * file is referenced)
2477 - * The uid and gid for the file - we give it
2482 - * The size of the file reported by ls.
2486 - * functions which can be done on the inode
2487 - * (linking, removing, etc.) - we don't
2492 - * The read function for this file,
2493 - * the function called when somebody
2494 - * tries to read something from it.
2498 - * We could have here a function to fill the
2499 - * file's inode, to enable us to play with
2500 - * permissions, ownership, etc.
2504 -#define ALL_TARGETS -1
2505 -#define ALL_CHANNELS -1
2506 -#define ALL_LUNS -1
2508 -#define MAX_ARRAYS 8
2510 -#define MAX_LUNS MAX_ARRAYS
2512 -#define PTI_ST_CMDS_PER_LUN 24
2515 - * The position of the SCSI commands scb within the scb array.
2517 -#define pti_st_position(cmd) ((cmd)->SCp.have_data_in)
2519 -/* This variable is global and very important, control all module !!! */
2520 -struct pti_st_host *pti_st_hostp[MAX_ADAPTORS] = {0};
2522 -#define CTL_OF_CMD(cmd) ((cmd->channel) & 0x01), \
2523 - ((cmd->target) & 0x0f), \
2524 - ((cmd->lun) & 0x07)
2527 - * A nice little define to make doing our printks a little easier
2530 -#define WARN_LEAD KERN_WARNING "(scsi%d:%d:%d:%d) "
2531 -#define INFO_LEAD KERN_INFO "(scsi%d:%d:%d:%d) "
2535 -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,18)
2536 -MODULE_PARM(pti_st, "s");
2542 -static int pti_st_install(Scsi_Host_Template *, struct pci_dev *, int *);
2543 -static void PTI_PrivateMessageCall(struct pti_st_host *, ULONG, U16, U16, ULONG, UCHAR *, ULONG, UCHAR *, UCHAR, ULONG);
2546 - * Declaration for EXECUTIVE Class Message
2548 -static unsigned int GetStatusCall(struct pti_st_host *, void *);
2549 -static void OutboundInitCall(struct pti_st_host *);
2550 -static void SysTabSetCall(struct pti_st_host *, PI2O_EXEC_SYS_TAB_SET_MESSAGE, void *);
2551 -static int IOP_init(struct pti_st_host *);
2552 -static void EnableSysCall(struct pti_st_host *);
2553 -static void LCTNotifyCall(struct pti_st_host *);
2555 -static unsigned long CreatSysTable(struct pti_st_host *, void *, PI2O_EXEC_STATUS_GET_REPLY);
2556 -static void ExecIOPReset(struct pti_st_host *);
2557 -static void PTI_UtilParamsGet(struct pti_st_host *, ULONG, ULONG, UCHAR, ULONG, UCHAR *);
2560 - * Declare Utility Message Functions:
2562 -static unsigned long pti_st_waitreplymsg(struct pti_st_host *);
2563 -static void PTI_UtilParamGetCall(struct pti_st_host *,
2564 - PI2O_UTIL_PARAMS_GET_MESSAGE,
2565 - void *, void *, PI2ODISK);
2566 -static void UtilNOPCall(struct pti_st_host *);
2568 -static int ComposeDiskInfo(struct pti_st_host *, void *, void *, PI2ODISK);
2569 -static void GetInfoFromLCT(struct pti_st_host *, void *, PI2ODISK, unsigned int *);
2570 -static void ZeroMemory(unsigned long *, unsigned int);
2572 -#define ADDTOPROCBUFFER(d, s) { if((strlen(d)+strlen(s)) < 4095) strcat(d, s); else goto proc_out; }
2575 - * PTI_procfile_read:
2576 - * inout : decides on the direction of the dataflow and the meaning of the
2578 - * buffer: If inout==FALSE data is being written to it else read from it
2579 - * *start: If inout==FALSE start of the valid data in the buffer
2580 - * offset: If inout==FALSE offset from the beginning of the imaginary file
2581 - * from which we start writing into the buffer
2582 - * length: If inout==FALSE max number of bytes to be written into the buffer
2583 - * else number of bytes in the buffer
2585 -int PTI_procfile_read(char *buffer,
2586 - char **buffer_location,
2588 - int buffer_length,
2593 - * The number of bytes actually used
2598 - * This is static so it will still be in memory
2599 - * when we leave this function
2601 - static char my_buffer[4096] = {0};
2602 - char tmp_buffer[256] = {0};
2603 - char *ptr = my_buffer;
2607 - * We give all of our information in one go, so if the
2608 - * user asks us if we have more information the
2609 - * answer should always be no.
2611 - * This is important because the standard read
2612 - * function from the library would continue to issue
2613 - * the read system call until the kernel replies
2614 - * that it has no more information, or until its
2615 - * buffer is filled.
2621 - * Fill the buffer and get its length
2623 - sprintf(ptr,"***** SuperTrak SX6000 Driver Version %2d.%2d *****\n", VERSIONHI, VERSIONLO);
2624 - ptr += strlen(ptr);
2625 - sprintf(ptr,"***** Copyright 1999-2001 by Promise Technology, Inc. *****\n\n");
2626 - ptr += strlen(ptr);
2628 - for(i = 0; i < MAX_ADAPTORS && (len = strlen(my_buffer)) < 4095; i++) {
2629 - if(!pti_st_hostp[i])
2631 - sprintf(tmp_buffer, "\n\tIOP Number: %d\n", i);
2632 - ADDTOPROCBUFFER(my_buffer, tmp_buffer);
2633 - sprintf(tmp_buffer, "\tCapabilities: %d",
2634 - pti_st_hostp[i]->IopStatus.IopCapabilities);
2635 - ADDTOPROCBUFFER(my_buffer, tmp_buffer);
2636 - sprintf(tmp_buffer, "\t\tState: %d\n",
2637 - pti_st_hostp[i]->IopStatus.IopState);
2638 - ADDTOPROCBUFFER(my_buffer, tmp_buffer);
2639 - sprintf(tmp_buffer, "\tI2OVersion: %d",
2640 - pti_st_hostp[i]->IopStatus.I2oVersion);
2641 - ADDTOPROCBUFFER(my_buffer, tmp_buffer);
2642 - sprintf(tmp_buffer, "\t\t\tMessengerType: 0x%x\n",
2643 - pti_st_hostp[i]->IopStatus.MessengerType);
2644 - ADDTOPROCBUFFER(my_buffer, tmp_buffer);
2645 - sprintf(tmp_buffer, "\tMaxMessageFrameSize: 0x%x",
2646 - pti_st_hostp[i]->IopStatus.InboundMFrameSize);
2647 - ADDTOPROCBUFFER(my_buffer, tmp_buffer);
2648 - sprintf(tmp_buffer, "\tExpectedLCTSize: 0x%x\n",
2649 - pti_st_hostp[i]->IopStatus.ExpectedLCTSize);
2650 - ADDTOPROCBUFFER(my_buffer, tmp_buffer);
2651 - sprintf(tmp_buffer, "\tMaxInboundMFrames: 0x%x",
2652 - pti_st_hostp[i]->IopStatus.MaxInboundMFrames);
2653 - ADDTOPROCBUFFER(my_buffer, tmp_buffer);
2654 - sprintf(tmp_buffer, "\tInitialInboundMFrames: 0x%x\n",
2655 - pti_st_hostp[i]->IopStatus.CurrentInboundMFrames);
2656 - ADDTOPROCBUFFER(my_buffer, tmp_buffer);
2657 - sprintf(tmp_buffer, "\n\tLCT Entry:\n");
2658 - ADDTOPROCBUFFER(my_buffer, tmp_buffer);
2661 - while(pti_st_hostp[i]->LctEntryTable[j].TableEntrySize == 0x09)
2663 - sprintf(tmp_buffer, "\n\tClass: 0x%x",
2664 - pti_st_hostp[i]->LctEntryTable[j].ClassID.Class);
2665 - ADDTOPROCBUFFER(my_buffer, tmp_buffer);
2666 - sprintf(tmp_buffer, "\t\tVersion: %d\n",
2667 - pti_st_hostp[i]->LctEntryTable[j].ClassID.Version);
2668 - ADDTOPROCBUFFER(my_buffer, tmp_buffer);
2669 - sprintf(tmp_buffer, "\tOrganizationID: 0x%x",
2670 - pti_st_hostp[i]->LctEntryTable[j].ClassID.Version);
2671 - ADDTOPROCBUFFER(my_buffer, tmp_buffer);
2672 - sprintf(tmp_buffer, "\tLocalTID: 0x%x\n",
2673 - pti_st_hostp[i]->LctEntryTable[j].LocalTID);
2674 - ADDTOPROCBUFFER(my_buffer, tmp_buffer);
2675 - sprintf(tmp_buffer, "\tChangeIndicator: 0x%x",
2676 - pti_st_hostp[i]->LctEntryTable[j].ChangeIndicator);
2677 - ADDTOPROCBUFFER(my_buffer, tmp_buffer);
2678 - sprintf(tmp_buffer, "\tDeviceFlags: 0x%x\n",
2679 - pti_st_hostp[i]->LctEntryTable[j].DeviceFlags);
2680 - ADDTOPROCBUFFER(my_buffer, tmp_buffer);
2681 - sprintf(tmp_buffer, "\tSubClassInfo: 0x%x",
2682 - pti_st_hostp[i]->LctEntryTable[j].SubClassInfo);
2683 - ADDTOPROCBUFFER(my_buffer, tmp_buffer);
2684 - sprintf(tmp_buffer, "\tUserTID: 0x%x\n",
2685 - pti_st_hostp[i]->LctEntryTable[j].UserTID);
2686 - ADDTOPROCBUFFER(my_buffer, tmp_buffer);
2687 - sprintf(tmp_buffer, "\tParentTID: 0x%x",
2688 - pti_st_hostp[i]->LctEntryTable[j].ParentTID);
2689 - ADDTOPROCBUFFER(my_buffer, tmp_buffer);
2690 - sprintf(tmp_buffer, "\t\tBiosInfo: 0x%x\n",
2691 - pti_st_hostp[i]->LctEntryTable[j].BiosInfo);
2692 - ADDTOPROCBUFFER(my_buffer, tmp_buffer);
2693 - sprintf(tmp_buffer, "\tEventCapabilities: 0x%x\n",
2694 - pti_st_hostp[i]->LctEntryTable[j].EventCapabilities);
2695 - ADDTOPROCBUFFER(my_buffer, tmp_buffer);
2702 - * Tell the function which called us where the
2705 - len = strlen(my_buffer);
2706 - if(len < buffer_length)
2707 - buffer_length = len;
2708 - else if(len >= buffer_length) {
2709 - my_buffer[buffer_length-1] = 0;
2710 - len = buffer_length - 1;
2713 - *buffer_location = my_buffer;
2716 - * Return the length
2721 -/*+F*************************************************************************
2726 - * Return a string describing the driver.
2727 - *-F*************************************************************************/
2728 -const char *PTI_ST_info(struct Scsi_Host *dooh)
2730 - static char buffer[256];
2734 - memset(bp, 0, sizeof(buffer));
2735 - strcpy(bp, "PROMISE SuperTrak SX6000 Driver");
2742 -Routine Description:
2744 - This routine will write data specified by Buffer to PCIConfig Space
2752 - Length of data which has been written
2756 -static ULONG PTI_ST_SetBusDataByOffset(
2758 - ULONG DeviceNumber,
2759 - ULONG FunctionNumber,
2768 - (BusNumber << 16) |
2769 - (DeviceNumber<<11) |
2770 - (FunctionNumber<<8) |
2776 - outl(*((ULONG *)Buffer), 0xcfc);
2777 - else if (Length == 2)
2781 - data = (inl(0xCfC) & (Offset&0x3 ? 0xFFFF : 0xFFFF0000));
2782 - data |= (((ULONG)(*(USHORT *)Buffer)) << (Offset&0x3 ? 16 : 0));
2783 - outl(data, 0xcfc);
2794 - * Function: scbq_init(volatile scb_queue_type *queue)
2795 - * Description: SCB queue initialization.
2798 -scbq_init(volatile scb_queue_type *queue)
2800 - queue->head = NULL;
2801 - queue->tail = NULL;
2805 - * Function: scbq_insert_head(volatile scb_queue_type, struct pti_st_scb)
2806 - * Description: Add an SCB to the head of the list.
2809 -scbq_insert_head(struct pti_st_host *p, volatile scb_queue_type *queue, struct pti_st_scb *scb)
2812 - scb->q_next = queue->head;
2813 - queue->head = scb;
2814 - if (queue->tail == NULL) /* If list was empty, update tail. */
2815 - queue->tail = queue->head;
2820 - * Function: scbq_remove_head(volatile scb_queue_type)
2821 - * Description: Remove an SCB from the head of the list.
2823 -static inline struct pti_st_scb *
2824 -scbq_remove_head(struct pti_st_host *p, volatile scb_queue_type *queue)
2826 - struct pti_st_scb * scbp;
2829 - scbp = queue->head;
2830 - if (queue->head != NULL)
2831 - queue->head = queue->head->q_next;
2832 - if (queue->head == NULL) /* If list is now empty, update tail. */
2833 - queue->tail = NULL;
2839 - * Function: scbq_remove(volatile scb_queue_type, struct pti_st_scb)
2840 - * Description: Removes an SCB from the list.
2843 -scbq_remove(struct pti_st_host *p, volatile scb_queue_type *queue, struct pti_st_scb *scb)
2845 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
2846 - unsigned long cpu_flags;
2850 - if (queue->head == scb)
2852 - /* At beginning of queue, remove from head. */
2853 - scbq_remove_head(p, queue);
2857 - struct pti_st_scb *curscb = queue->head;
2860 - * Search until the next scb is the one we're looking for, or
2861 - * we run out of queue.
2863 - while ((curscb != NULL) && (curscb->q_next != scb))
2865 - curscb = curscb->q_next;
2867 - if (curscb != NULL)
2870 - curscb->q_next = scb->q_next;
2871 - if (scb->q_next == NULL)
2873 - /* Update the tail when removing the tail. */
2874 - queue->tail = curscb;
2882 - * Function: scbq_insert_tail(volatile scb_queue_type, struct pti_st_scb)
2883 - * Description: Add an SCB at the tail of the list.
2886 -scbq_insert_tail(struct pti_st_host *p, volatile scb_queue_type *queue, struct pti_st_scb *scb)
2888 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
2889 - unsigned long cpu_flags;
2893 - scb->q_next = NULL;
2894 - if (queue->tail != NULL) /* Add the scb at the end of the list. */
2895 - queue->tail->q_next = scb;
2896 - queue->tail = scb; /* Update the tail. */
2897 - if (queue->head == NULL) /* If list was empty, update head. */
2898 - queue->head = queue->tail;
2903 - * Function: pti_st_allocate_scb(struct pti_st_host *, struct pti_st_scb *)
2904 - * Description: Free the scb and insert into the free scb list.
2907 -pti_st_allocate_scb(struct pti_st_host *p)
2909 - struct pti_st_scb *scbp = NULL;
2910 - int scb_size = sizeof(struct pti_st_scb);
2912 - unsigned long scb_count = 0;
2913 - struct pti_st_scb *scb_ap;
2915 - scb_count = p->scb_data->maxscbs;
2916 - scb_ap = (struct pti_st_scb *)kmalloc(scb_size * scb_count, GFP_ATOMIC);
2917 - if (scb_ap != NULL)
2919 - memset(scb_ap, 0, scb_count * scb_size);
2920 - for (i=0; i < scb_count; i++)
2922 - scbp = &scb_ap[i];
2927 - * Place in the scb array; never is removed
2929 - p->scb_data->scb_array[i] = scbp;
2930 - scbq_insert_head(p, &p->scb_data->free_scbs, scbp);
2932 - scbp->kmalloc_ptr = scb_ap;
2938 - return(scb_count);
2942 - * Function: pti_st_queue_cmd_complete(struct pti_st_host *, Scsi_Cmnd *)
2943 - * Description: Due to race conditions present in the SCSI subsystem, it is
2944 - * easier to queue completed commands, then call scsi_done() on
2945 - * them when we're finished.
2946 - * This function queues the completed commands.
2949 -pti_st_queue_cmd_complete(struct pti_st_host *p, Scsi_Cmnd *cmd)
2951 - cmd->host_scribble = (char *)p->completeq.head;
2952 - p->completeq.head = cmd;
2956 - * Function: pti_st_done_cmds_complete(struct pti_st_host *)
2957 - * Description: Process the completed command queue.
2960 -pti_st_done_cmds_complete(struct pti_st_host *p)
2964 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
2965 - unsigned int cpu_flags = 0;
2968 - while (p->completeq.head != NULL)
2970 - cmd = p->completeq.head;
2971 - p->completeq.head = (Scsi_Cmnd *)cmd->host_scribble;
2972 - cmd->host_scribble = NULL;
2974 - cmd->scsi_done(cmd);
2981 - while (p->completeq.head != NULL)
2983 - cmd = p->completeq.head;
2984 - p->completeq.head = (Scsi_Cmnd *)cmd->host_scribble;
2985 - cmd->host_scribble = NULL;
2986 - cmd->scsi_done(cmd);
2993 - * Function: pti_st_free_scb(struct pti_st_host *, struct pti_st_scb *)
2994 - * Description: Free the scb and insert into the free scb list.
2997 -pti_st_free_scb(struct pti_st_host *p, struct pti_st_scb *scb)
3000 - scb->flags = SCB_FREE;
3002 - scb->sg_count = 0;
3003 - scb->sg_length = 0;
3005 -// scb->mf->target_channel_lun = SCB_LIST_NULL;
3007 - scbq_insert_head(p, &p->scb_data->free_scbs, scb);
3011 - * Function: pti_st_done(struct pti_st_host *, struct pti_st_scb *)
3012 - * Description: Calls the higher level scsi done function and frees the scb.
3015 -pti_st_done(struct pti_st_host *p, struct pti_st_scb *scb)
3017 - Scsi_Cmnd *cmd = scb->cmd;
3019 - if (scb->flags & SCB_RESET)
3021 - cmd->result = (DID_RESET << 16) | (cmd->result & 0xffff);
3023 - else if (scb->flags & SCB_ABORT)
3025 - cmd->result = (DID_RESET << 16) | (cmd->result & 0xffff);
3028 - pti_st_free_scb(p, scb);
3029 - pti_st_queue_cmd_complete(p, cmd);
3033 - * Function: pti_st_run_done_queue(struct pti_st_host *, int)
3034 - * Description: Calls the pti_st_done() for the Scsi_Cmnd of each scb in the
3035 - * aborted list, and adds each scb to the free list. If complete
3036 - * is TRUE, we also process the commands complete list.
3039 -pti_st_run_done_queue(struct pti_st_host *p, int complete)
3041 - struct pti_st_scb *scb;
3044 - for (i = 0; i < p->scb_data->maxscbs; i++)
3046 - scb = p->scb_data->scb_array[i];
3047 - if (scb->flags & SCB_QUEUED_FOR_DONE)
3048 - pti_st_done(p, scb);
3052 - pti_st_done_cmds_complete(p);
3057 - * Function: pti_st_isr(int, void, struct pt_regs)
3058 - * Description: i960 controller interrupt handler.
3061 -pti_st_isr(int irq, void *dev_id, struct pt_regs *regs)
3063 - volatile U32 phyAddrMsg = 0xffffffff;
3066 - struct pti_st_host *p;
3067 - struct pti_st_scb *scbp;
3068 - PI2O_BSA_REPLY_MESSAGE_FRAME rmfp = NULL;
3072 - p = (struct pti_st_host *)dev_id;
3076 - for(i = 0; i < MAX_ADAPTORS; i++)
3077 - if(pti_st_hostp[i] == p)
3080 - if(i >= MAX_ADAPTORS || !p->p_atu)
3083 - phyAddrMsg = p->p_atu->OutQueue;
3088 - (phyAddrMsg == 0xffffffff) && (testtime < 3);
3091 - phyAddrMsg = p->p_atu->OutQueue;
3094 - if(phyAddrMsg == 0xffffffff) {
3098 - rmfp = (PI2O_BSA_REPLY_MESSAGE_FRAME)(bus_to_virt(phyAddrMsg));
3100 - scb_index = rmfp->StdMessageFrame.InitiatorContext;
3101 - scbp = p->scb_data->scb_array[scb_index];
3104 - /* return MFA to outbound free Q*/
3105 - p->p_atu->OutQueue = phyAddrMsg;
3107 - /* any more msgs? */
3108 - phyAddrMsg = p->p_atu->OutQueue;
3114 - //printk("return cmd= 0x%x, mfp= 0x%x, sno= 0x%x tag= 0x%x ind= 0x%x scb= 0x%x\n",
3115 - // cmd, rmfp, cmd->serial_number, scbp->tag, scb_index, scbp);
3116 - if (cmd->serial_number != rmfp->TransactionContext)
3118 - printk("Error in cmd%2x, mismatch sn 0x%x, mfp 0x%x scbi= %x\n",
3119 - cmd->cmnd[0], (int)cmd->serial_number,
3120 - (int)rmfp->TransactionContext,
3122 - /* return MFA to outbound free Q*/
3123 - p->p_atu->OutQueue = phyAddrMsg;
3125 - /* any more msgs? */
3126 - phyAddrMsg = p->p_atu->OutQueue;
3130 - if (rmfp->ReqStatus != I2O_REPLY_STATUS_SUCCESS) {
3131 - cmd->result = DID_ERROR;
3133 - printk("pti_st_isr: Reply Status Fail, ReqStatus[%x], DetailedStatus[%x]\n", rmfp->ReqStatus, rmfp->DetailedStatusCode);
3137 - pti_st_free_scb(p, scbp);
3138 - pti_st_queue_cmd_complete(p, cmd);
3139 - /* return MFA to outbound free Q*/
3140 - p->p_atu->OutQueue = phyAddrMsg;
3142 - /* any more msgs? */
3143 - phyAddrMsg = p->p_atu->OutQueue;
3150 - * Function: do_pti_st_isr(int, void *, struct pt_regs *)
3152 - * This is a gross hack to solve a problem in linux kernels 2.1.85 and
3153 - * above. Please, children, do not try this at home, and if you ever see
3154 - * anything like it, please inform the Gross Hack Police immediately
3156 -void do_pti_st_isr( int irq, void *dev_id, struct pt_regs * regs )
3158 - unsigned long cpu_flags = 0;
3159 - struct pti_st_host *p;
3163 - p = (struct pti_st_host *)dev_id;
3167 - for(i = 0; i < MAX_ADAPTORS; i++)
3168 - if(p == pti_st_hostp[i])
3171 - if(i >= MAX_ADAPTORS)
3174 - OutIntStat = p->p_atu->OutIntStat;
3176 - if (OutIntStat==0)
3179 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,95)
3180 - if(test_and_set_bit(PSTC_IN_ISR_BIT, &p->flags))
3184 - spin_lock_irqsave(&io_request_lock, cpu_flags);
3185 - pti_st_isr(irq, dev_id, regs);
3186 - pti_st_done_cmds_complete(p);
3187 - clear_bit(PSTC_IN_ISR_BIT, &p->flags);
3188 - spin_unlock_irqrestore(&io_request_lock, cpu_flags);
3190 - if(set_bit(PSTC_IN_ISR_BIT, (int *)&p->flags))
3195 - pti_st_isr(irq, dev_id, regs);
3197 - pti_st_done_cmds_complete(p);
3198 - clear_bit(PSTC_IN_ISR_BIT, (int *)&p->flags);
3203 - * Function: pti_st_register(Scsi_Host_Template *, struct pti_st_host *)
3204 - * Description: Register i960 controller with the kernel.
3207 -pti_st_register(Scsi_Host_Template *template, struct pti_st_host *p)
3210 - struct Scsi_Host *host;
3214 - p->scb_data->maxscbs = PTI_ST_MAXSCB;
3215 - host->can_queue = PTI_ST_MAXSCB;
3216 - host->cmd_per_lun = 3;
3217 - host->sg_tablesize = PTI_ST_MAX_SG;
3218 - host->this_id = p->scsi_id;
3219 - host->irq = p->pci_irq;
3222 - p->host_no = host->host_no;
3223 - p->completeq.head = NULL;
3224 - p->completeq.tail = NULL;
3227 - * Initialize the Super Track hardware controler, procedure as the
3228 - * typical system initialization of I2O
3230 - p->maddr = ioremap(p->mbase, 4*1024*1024);
3237 - p->p_atu = (PATU)p->maddr;
3238 - p->LinBaseAddr = (PU8)p->maddr;
3240 - p->outboundBufferp = (outboundBuff_t *)kmalloc((16*1024+256+32*32*4), GFP_ATOMIC);
3241 - if(p->outboundBufferp == NULL) {
3243 - printk("Allocating buffer fails!\n");
3246 - p->replyBufferp = (PU8)((PU8)p->outboundBufferp + 32*32*4);
3247 - p->messageBufferp = p->replyBufferp + (16*1024);
3249 - p->outMsgBlockPhyAddr = virt_to_bus(p->outboundBufferp);
3250 - p->pLinOutMsgBlock = (PU8)(p->outboundBufferp);
3253 - * Allocate the set of scbs for this controller. This is to stream-
3254 - * line code elsewhere in the driver. If we have to check for the existence
3255 - * of scbs in certain code sections, it slows things down. However, as
3256 - * soon as we register the IRQ for this card, we could get an interrupt that
3257 - * includes possibly the SCSI_RSTI interrupt. If we catch that interrupt
3258 - * then we are likely to segfault if we don't have at least one chunk of
3259 - * SCBs allocated or add checks all through the reset code to make sure
3260 - * that the SCBs have been allocated which is an invalid running condition
3261 - * and therefore I think it's preferable to simply pre-allocate the first
3265 - result = pti_st_allocate_scb(p);
3269 - printk("Allocating scbs fails!\n");
3274 - * Disable interrupt
3276 - p->p_atu->OutIntMask = 0xffffffff;
3285 - * Clear out any possible pending interrupts, again.
3287 - /* pti_st_clear_intstat(p); */
3290 - * Register IRQ with the kernel. Only allow sharing IRQs with
3293 - result = (request_irq(p->pci_irq, do_pti_st_isr, SA_SHIRQ, "pti_st", p));
3296 - result = (request_irq(p->pci_irq, do_pti_st_isr,
3297 - (SA_INTERRUPT | SA_SHIRQ), "pti_st", p));
3302 - printk(KERN_WARNING "(scsi%d) Couldn't register IRQ %d, ignoring "
3303 - "controller.\n", p->host_no, p->pci_irq);
3308 - * Enable interrupt
3310 - p->p_atu->OutIntMask = 0x00000000;
3313 - host->max_id = MAX_ARRAYS;
3314 - host->max_channel = 0;
3315 - host->max_lun = p->max_lun = 1;
3321 - * Function: pti_st_free(struct pti_st_host *)
3322 - * Description: Frees and releases all resources associated with an instance of
3323 - * the driver (struct pti_st_host *).
3326 -pti_st_free(struct pti_st_host *p)
3330 - if (p->scb_data != NULL)
3334 - * Free the driver SCBs. These were allocated on an as-need
3335 - * basis. We allocated these in groups depending on how many
3336 - * we could fit into a given amount of RAM. The tail SCB for
3337 - * these allocations has a pointer to the alloced area.
3339 - for (i = 0; i < p->scb_data->maxscbs; i++)
3341 - if (p->scb_data->scb_array[i]->kmalloc_ptr != NULL)
3342 - kfree(p->scb_data->scb_array[i]->kmalloc_ptr);
3343 - p->scb_data->scb_array[i] = NULL;
3347 - * Free the SCB data area.
3349 - kfree(p->scb_data);
3354 - * Function: pti_st_release(struct Scsi_Host *)
3355 - * Description: Free the passed in Scsi_Host memory structures prior to
3356 - * unloading the module.
3359 -pti_st_release(struct Scsi_Host *host)
3361 - struct pti_st_host *p = (struct pti_st_host *) host->hostdata;
3364 - for(i = 0; i < MAX_ADAPTORS; i++)
3365 - if(p == pti_st_hostp[i])
3368 - if(!p || i >= MAX_ADAPTORS)
3372 - free_irq(p->pci_irq, p);
3375 - * Disbale interrupt
3377 - p->p_atu->OutIntMask = 0x000000fc;
3381 - iounmap((void *) (((unsigned long) p->maddr)));
3384 - if(p->outboundBufferp) {
3385 - kfree(p->outboundBufferp);
3386 - p->outboundBufferp = NULL;
3388 - if(p->pti_stdev_bufferp) {
3389 - kfree(p->pti_stdev_bufferp);
3390 - p->pti_stdev_bufferp = NULL;
3393 - pti_st_hostp[i] = NULL;
3398 - * Function: pti_st_alloc(Scsi_Host_Template *, struct pti_st_host *)
3399 - * Description: Allocate and initialize a host structure.
3400 - * Returns NULL upon error and a pointer to a pti_st_host struct
3403 -static struct pti_st_host *
3404 -pti_st_alloc(Scsi_Host_Template *sht, struct pti_st_host *temp)
3406 - struct pti_st_host *p = NULL;
3407 - struct Scsi_Host *host;
3410 - * Allocate a storage area by registering us with the mid-level
3413 - host = scsi_register(sht, sizeof(struct pti_st_host));
3417 - p = (struct pti_st_host *) host->hostdata;
3418 - memset(p, 0, sizeof(struct pti_st_host));
3422 - p->host_no = host->host_no;
3423 - p->scb_data = kmalloc(sizeof(scb_data_type), GFP_ATOMIC);
3424 - if (p->scb_data != NULL)
3426 - memset(p->scb_data, 0, sizeof(scb_data_type));
3427 - scbq_init (&p->scb_data->free_scbs);
3432 - * For some reason we don't have enough memory. Free the
3433 - * allocated memory for the pti_st_host struct, and return NULL.
3435 - scsi_unregister(host);
3438 - p->pti_stdev_bufferp = kmalloc(sizeof(PTI_STDEV_INBUFFER), GFP_ATOMIC);
3439 - if(p->pti_stdev_bufferp != NULL)
3441 - memset(p->pti_stdev_bufferp, 0, sizeof(PTI_STDEV_INBUFFER));
3443 - scsi_unregister(host);
3452 - * Function: pti_st_detect(Scsi_Host_Template *)
3453 - * Description: Try to detect and register i960 controller.
3454 - * This should really be called pti_st_probe(). A sequence of
3455 - * probe(), attach()/detach(), and init() makes more sense than
3456 - * one do-it-all function. This may be useful when (and if) the
3457 - * mid-level SCSI code is overhauled.
3459 -int pti_st_detect(Scsi_Host_Template *template)
3461 - struct pci_dev *pdev;
3464 - if (!pci_present())
3467 - // printk("pti_st.c: PCI bios is present, checking for devices ...\n");
3469 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3470 - pci_for_each_dev(pdev)
3472 - for(pdev = pci_devices, found = 0;
3473 - found < MAX_ADAPTORS && pdev != NULL;
3474 - pdev = pdev->next)
3477 - if(pdev->vendor != PCI_VENDOR_ID_INTEL ||
3478 - (pdev->device != PCI_DEVICE_ID_INTEL_i960 && /* ST100 */
3479 - pdev->device != PCI_DEVICE_ID_INTEL_i962)) /* ST100SX6 */
3482 - pti_st_install(template, pdev, &found);
3488 -static int pti_st_install(Scsi_Host_Template *template, struct pci_dev *pdev, int *aptno)
3490 - struct pti_st_host *p = NULL;
3491 - struct pti_st_host *temp_p = NULL;
3492 - unsigned short command;
3493 - unsigned long cmd;
3494 - unsigned long devicenumber, functionnumber;
3496 - devicenumber = PCI_SLOT(pdev->devfn);
3497 - functionnumber = 0;
3500 - * Expose the ship behind i960 for initialization, or it will failed
3503 - PTI_ST_SetBusDataByOffset(pdev->bus->number,
3510 - template->sg_tablesize = PTI_ST_MAX_SG;
3511 - template->proc_dir = &proc_scsi_pti_st;
3512 - template->proc_info = PTI_procfile_read;
3513 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3514 - if(!template->proc_name) {
3515 - if(template->name)
3516 - template->proc_name = (char *)template->name;
3518 - template->proc_name = "pti_st";
3522 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3523 - pci_enable_device(pdev);
3526 - if ( !(temp_p = kmalloc(sizeof(struct pti_st_host), GFP_ATOMIC)))
3528 - printk("pti_st_host data structure memory alloc error!!!\n");
3530 - PTI_ST_SetBusDataByOffset(pdev->bus->number,
3538 - memset(temp_p, 0, sizeof(struct pti_st_host));
3540 - temp_p->pci_irq = pdev->irq;
3541 - temp_p->pdev = pdev;
3542 - temp_p->pci_bus = pdev->bus->number;
3543 - temp_p->pci_device_fn = pdev->devfn;
3544 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3545 - temp_p->mbase = pci_resource_start(pdev, 0);
3546 - template->name = "pti_st";
3548 - temp_p->mbase = pdev->base_address[0];
3550 - pci_read_config_word(pdev, PCI_COMMAND, &command);
3552 - command |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
3553 - pci_write_config_word(pdev, PCI_COMMAND, command);
3555 - temp_p->mbase &= PCI_BASE_ADDRESS_MEM_MASK;
3557 - printk("Found PTI SuperTrak at mbase: %#x, irq %d.\n",
3558 - temp_p->mbase, temp_p->pci_irq);
3560 - pti_st_hostp[*aptno] = p = pti_st_alloc(template, temp_p);
3566 - if (!pti_st_register(template, p))
3568 - pti_st_release(p->host);
3569 - scsi_unregister(p->host);
3571 - pti_st_hostp[*aptno] = NULL;
3576 - PTI_ST_SetBusDataByOffset(pdev->bus->number,
3588 - * Function: pti_st_copy_internal_data(Scsi_Cmnd *, char *, unsigned short)
3589 - * Description: Queue a SCB to the controller.
3592 -pti_st_copy_internal_data(Scsi_Cmnd *scp, char *buffer, unsigned short count)
3594 - unsigned short cpcount,i;
3595 - unsigned short cpsum,cpnow;
3596 - struct scatterlist *sl;
3598 - cpcount = count<=(ushort)scp->bufflen ? count:(ushort)scp->bufflen;
3601 - sl = (struct scatterlist *)scp->request_buffer;
3602 - for (i=0,cpsum=0; i<scp->use_sg; ++i,++sl)
3604 - cpnow = (ushort)sl->length;
3605 - if (cpsum+cpnow > cpcount)
3606 - cpnow = cpcount - cpsum;
3608 - memcpy((char*)sl->address,buffer,cpnow);
3609 - if (cpsum == cpcount)
3616 - memcpy((char*)scp->request_buffer,buffer,cpcount);
3622 - * Function: pti_st_rw_cmd(Scsi_Cmnd *, void (*fn)(Scsi_Cmnd *)) * Description: Translate Scsi Command to I2O Message Frame.
3625 -pti_st_rw_cmd(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *))
3627 - struct pti_st_host *p;
3628 - struct pti_st_scb *scb;
3629 - unsigned long msgoffset;
3630 - unsigned long blk_nr = 0;
3631 - unsigned long blk_count = 0;
3632 - PI2O_BSA_RW_MESSAGE mfp;
3633 - unsigned char *cmnd;
3634 - unsigned long pBaseAddrReg;
3637 - p = (struct pti_st_host *) cmd->host->hostdata;
3639 - for(i = 0; i < MAX_ADAPTORS; i++)
3640 - if(p == pti_st_hostp[i])
3643 - if(i >= MAX_ADAPTORS || !p) {
3644 - cmd->result = (DID_BAD_TARGET << 16);
3649 - scb = scbq_remove_head(p, &p->scb_data->free_scbs);
3653 - cmd->result = (DID_BUS_BUSY << 16);
3654 - printk(WARN_LEAD"Couldn't get a free SCB.\n", p->host_no,
3660 - if (cmd->target >= MAX_DRIVES || p->I2ODisk[cmd->target].present != TRUE)
3662 - cmd->result = (DID_BAD_TARGET << 16);
3669 - pBaseAddrReg = (U32)p->maddr;
3670 - msgoffset = * (U32 *)(pBaseAddrReg+INBOUNDQPORT);
3671 - if (msgoffset == 0xFFFFFFFF)
3673 - printk(INFO_LEAD"Couldn't get a free MF from inboundqport.\n",
3674 - p->host_no, CTL_OF_CMD(cmd));
3675 - cmd->result = (DID_BUS_BUSY << 16);
3679 - scbq_insert_head(p, &p->scb_data->free_scbs, scb);
3685 - pti_st_position(cmd) = scb->tag;
3687 - p->scb_data->scb_array[scb->tag] = scb;
3690 - * Make sure the Scsi_Cmnd pointer is saved, the struct it points to
3691 - * is set up properly, and the parity error flag is reset, then send
3692 - * the SCB to the sequencer and watch the fun begin.
3694 - cmd->scsi_done = fn;
3695 - cmd->result = DID_OK;
3696 - memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
3697 - cmd->host_scribble = NULL;
3699 - scb->flags |= SCB_ACTIVE;
3700 - mfp = (PI2O_BSA_RW_MESSAGE)(pBaseAddrReg + msgoffset);
3701 - memset((char *)mfp, 0, sizeof(I2O_BSA_READ_MESSAGE));
3702 - cmnd = (unsigned char *)cmd->cmnd;
3707 - blk_nr = cmnd[3] + (cmnd[2] << 8) + ((cmnd[1] & 0x1f) << 16);
3708 - blk_count = cmnd[4];
3710 - mfp->StdMessageFrame.Function = I2O_BSA_BLOCK_READ;
3711 - mfp->FetchAhead = 0;
3716 - blk_nr = ntohl(*(PU32)&cmnd[2]);
3717 - blk_count = cmnd[8] + (cmnd[7] << 8);
3719 - mfp->StdMessageFrame.Function = I2O_BSA_BLOCK_READ;
3720 - mfp->FetchAhead = 0;
3725 - blk_nr = cmnd[3] + (cmnd[2] << 8) + ((cmnd[1] & 0x1f) << 16);
3726 - blk_count = cmnd[4];
3728 - mfp->StdMessageFrame.Function = I2O_BSA_BLOCK_WRITE;
3733 - blk_nr = ntohl(*(PU32)&cmnd[2]);
3734 - blk_count = cmnd[8] + (cmnd[7] << 8);
3736 - mfp->StdMessageFrame.Function = I2O_BSA_BLOCK_WRITE;
3739 - mfp->LogicalByteAddress.HighPart = blk_nr >> (32 - 9);
3740 - mfp->LogicalByteAddress.LowPart = blk_nr << 9;
3741 - mfp->TransferByteCount = blk_count << 9;
3742 - mfp->TransactionContext = cmd->serial_number;
3743 - mfp->StdMessageFrame.InitiatorContext = scb->tag;
3744 - mfp->StdMessageFrame.VersionOffset=0x81;
3745 - mfp->StdMessageFrame.MsgFlags=0;
3746 - mfp->StdMessageFrame.MessageSize=sizeof(I2O_BSA_READ_MESSAGE)>>2;
3747 - mfp->StdMessageFrame.TargetAddress=p->I2ODisk[cmd->target].LocalTID;
3748 - mfp->StdMessageFrame.InitiatorAddress = 0x01;
3749 - mfp->ControlFlags = 0;
3750 - mfp->TimeMultiplier = 0x31; /*0;*/
3753 - //printk("Issue cmd= %x, mfp 0x%x, sno= 0x%x tag= 0x%x scb=0x%x\n",
3754 - // cmd, mfp, cmd->serial_number, scb->tag, scb);
3757 - * The interpretation of request_buffer and request_bufflen
3758 - * changes depending on whether or not use_sg is zero; a
3759 - * non-zero use_sg indicates the number of elements in the
3760 - * scatter-gather array.
3765 - struct scatterlist *sg; /* Must be mid-level SCSI code scatterlist */
3768 - * We must build an SG list in I2O SGL format, as the kernel's SG list
3769 - * cannot be used directly
3773 - sg = (struct scatterlist *)cmd->request_buffer;
3775 - * Copy the segments into the SG array. NOTE!!! - We used to
3776 - * have the first entry both in the data_pointer area and the first
3777 - * SG element. That has changed somewhat. We still have the first
3778 - * entry in both places, but now we download the address of
3779 - * scb->sg_list[1] instead of 0 to the sg pointer in the mf.
3781 - for (i = 0; i < (cmd->use_sg); i++)
3783 - mfp->SGL.u.Simple[i].FlagsCount.Count = cpu_to_le32(sg[i].length);
3784 - mfp->SGL.u.Simple[i].FlagsCount.Flags =
3785 - (I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT);
3786 - mfp->SGL.u.Simple[i].PhysicalAddress =
3787 - cpu_to_le32(VIRT_TO_BUS(sg[i].address));
3789 - mfp->SGL.u.Simple[cmd->use_sg - 1].FlagsCount.Flags |=
3790 - ( I2O_SGL_FLAGS_LAST_ELEMENT |
3791 - I2O_SGL_FLAGS_END_OF_BUFFER);
3795 - mfp->SGL.u.Simple[0].FlagsCount.Count =
3796 - cpu_to_le32(cmd->request_bufflen);
3797 - mfp->SGL.u.Simple[0].FlagsCount.Flags =
3798 - ( I2O_SGL_FLAGS_LAST_ELEMENT |
3799 - I2O_SGL_FLAGS_END_OF_BUFFER |
3800 - I2O_SGL_FLAGS_TRANSPORT_ELEMENT |
3801 - I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT);
3802 - mfp->SGL.u.Simple[0].PhysicalAddress =
3803 - cpu_to_le32(VIRT_TO_BUS(cmd->request_buffer));
3806 - * (U32 *)(pBaseAddrReg+INBOUNDQPORT) = msgoffset;
3814 - * Function: pti_st_internal_cmd(Scsi_Cmnd *, void (*fn)(Scsi_Cmnd *))
3815 - * Description: Excuting TEST_UNIT_READY, INQUIRY, READ_CAPACITY, etc.
3819 -pti_st_internal_cmd(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *))
3821 - struct pti_st_host *p;
3823 - // struct pti_st_scb *scb;
3824 - // unsigned long cpu_flags = 0;
3826 - pti_rdcap_data rdc;
3829 - p = (struct pti_st_host *) cmd->host->hostdata;
3831 - for(i = 0; i < MAX_ADAPTORS; i++)
3832 - if(p == pti_st_hostp[i])
3835 - if(i >= MAX_ADAPTORS) {
3836 - cmd->result = (DID_BAD_TARGET << 16);
3841 - switch (cmd->cmnd[0])
3843 - case TEST_UNIT_READY:
3844 - cmd->result = DID_OK << 16;
3848 - memset((void *)&inq, 0, sizeof(inq));
3849 - inq.type_qual = TYPE_DISK;
3851 - * you can here set all disks to removable, if you want to do
3852 - * a flush using the ALLOW_MEDIUM_REMOVAL command
3854 - inq.modif_rmb = 0x00;
3856 - inq.resp_aenc = 2;
3857 - inq.add_length= 32;
3858 - strcpy(inq.vendor,"PTI ");
3859 - strcpy(inq.product,"SuperTrak");
3860 - strcpy(inq.revision," ");
3861 - if(cmd->target < MAX_DRIVES && p->I2ODisk[cmd->target].present == TRUE)
3863 - pti_st_copy_internal_data(cmd,(char*)&inq, sizeof(pti_inq_data));
3864 - cmd->result = DID_OK << 16;
3866 - pti_st_copy_internal_data(cmd,(char*)&inq, sizeof(pti_inq_data));
3867 - cmd->result = DID_BAD_TARGET << 16;
3872 - case REQUEST_SENSE:
3873 - sd.errorcode = 0x70;
3875 - sd.key = NO_SENSE;
3878 - pti_copy_internal_data(scp,(char*)&sd,sizeof(gdth_sense_data));
3879 - cmd->result = DID_OK << 16;
3882 - memset((char*)&mpd,0,sizeof(gdth_modep_data));
3883 - mpd.hd.data_length = sizeof(gdth_modep_data);
3884 - mpd.hd.dev_par = (ha->id[b][t].devtype&2) ? 0x80:0;
3885 - mpd.hd.bd_length = sizeof(mpd.bd);
3886 - mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16;
3887 - mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8;
3888 - mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff);
3889 - pti_copy_internal_data(scp,(char*)&mpd,sizeof(gdth_modep_data));
3890 - cmd->result = DID_OK << 16;
3894 - case READ_CAPACITY:
3895 - if(cmd->target < MAX_DRIVES && p->I2ODisk[cmd->target].present)
3897 - rdc.last_block_no = ntohl(p->I2ODisk[cmd->target].lastLBA);
3898 - rdc.block_length = ntohl(SECTOR_SIZE);
3899 - pti_st_copy_internal_data(cmd,(char*)&rdc, sizeof(pti_rdcap_data));
3900 - cmd->result = DID_OK << 16;
3902 - cmd->result = DID_BAD_TARGET;
3907 - printk("!!!!!!!!PTI: Unknown SCSI command 0x%x to cache service !\n",
3909 - cmd->result = DID_ABORT << 16;
3918 - * Function: pti_st_queue(Scsi_Cmnd *, void (*fn)(Scsi_Cmnd *))
3919 - * Description: Queue a SCB to the controller.
3922 -pti_st_queue(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *))
3926 - switch (cmd->cmnd[0])
3933 - ret = pti_st_rw_cmd(cmd, fn);
3935 - case TEST_UNIT_READY:
3937 - case READ_CAPACITY:
3938 - return(pti_st_internal_cmd(cmd, fn));
3940 -// case START_STOP:
3941 -// case REQUEST_SENSE:
3942 -// case MODE_SENSE:
3947 - printk("PTI: Unknown SCSI command 0x%x to cache service!\n", cmd->cmnd[0]);
3948 - cmd->result = DID_ABORT << 16;
3954 - * Function: pti_st_abort(Scsi_Cmnd *)
3955 - * Description: Abort the current SCSI command(s).
3958 -pti_st_abort(Scsi_Cmnd *cmd)
3960 - struct pti_st_scb *scb = NULL;
3961 - struct pti_st_host *p;
3962 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
3963 - unsigned long cpu_flags = 0;
3965 - Scsi_Cmnd *cmd_next, *cmd_prev;
3968 - p = (struct pti_st_host *) cmd->host->hostdata;
3969 - for(i = 0; i < MAX_ADAPTORS; i++)
3970 - if(p == pti_st_hostp[i])
3973 - if(i >= MAX_ADAPTORS || !p) {
3974 - return(SCSI_ABORT_NOT_RUNNING);
3977 - scb = (p->scb_data->scb_array[pti_st_position(cmd)]);
3983 - * Run the isr to grab any command in the QOUTFIFO and any other misc.
3984 - * assundry tasks. This should also set up the bh handler if there is
3985 - * anything to be done, but it won't run until we are done here since
3986 - * we are following a straight code path without entering the scheduler
3991 - pti_st_isr(p->pci_irq, p, (void *)NULL);
3992 - pti_st_done_cmds_complete(p);
3995 - if ((scb == NULL) || (cmd->serial_number != cmd->serial_number_at_timeout))
3996 - /* Totally bogus cmd since it points beyond our */
3997 - { /* valid SCB range or doesn't even match it's own*/
3998 - /* timeout serial number. */
4000 - return(SCSI_ABORT_NOT_RUNNING);
4003 - if (scb->cmd != cmd) /* Hmmm...either this SCB is currently free with a */
4004 - { /* NULL cmd pointer (NULLed out when freed) or it */
4005 - /* has already been recycled for another command */
4006 - /* Either way, this SCB has nothing to do with this*/
4007 - /* command and we need to deal with cmd without */
4008 - /* touching the SCB. */
4009 - /* The theory here is to return a value that will */
4010 - /* make the queued for complete command actually */
4011 - /* finish successfully, or to indicate that we */
4012 - /* don't have this cmd any more and the mid level */
4013 - /* code needs to find it. */
4014 - cmd_next = p->completeq.head;
4016 - while (cmd_next != NULL)
4018 - if (cmd_next == cmd)
4020 -// if (pti_st_verbose & VERBOSE_ABORT_PROCESS)
4021 - printk(INFO_LEAD "Abort called for command "
4022 - "on completeq, completing.\n", p->host_no, CTL_OF_CMD(cmd));
4023 - if ( cmd_prev == NULL )
4024 - p->completeq.head = (Scsi_Cmnd *)cmd_next->host_scribble;
4026 - cmd_prev->host_scribble = cmd_next->host_scribble;
4027 - cmd_next->scsi_done(cmd_next);
4030 - return(SCSI_ABORT_NOT_RUNNING); /* It's already back as a successful
4033 - cmd_prev = cmd_next;
4034 - cmd_next = (Scsi_Cmnd *)cmd_next->host_scribble;
4037 -// if (pti_st_verbose & VERBOSE_ABORT_MID)
4038 - printk(INFO_LEAD "Abort called for already completed"
4039 - " command.\n", p->host_no, CTL_OF_CMD(cmd));
4041 - return(SCSI_ABORT_NOT_RUNNING);
4045 - * Hmmm...completeq, QOUTFIFO, QINFIFO, WAITING_SCBH, waitingq all checked.
4046 - * OK...the sequencer's paused, interrupts are off, and we haven't found the
4047 - * command anyplace where it could be easily aborted. Time for the hard
4048 - * work. We also know the command is valid. This essentially means the
4049 - * command is disconnected, or connected but not into any phases yet, which
4050 - * we know due to the tests we ran earlier on the current active scb phase.
4051 - * At this point we can queue the abort tag and go on with life.
4053 - if (scb->flags & SCB_WAITINGQ)
4055 - scbq_remove(p, &p->waiting_scbs, scb);
4057 - scb->flags &= ~(SCB_WAITINGQ | SCB_ACTIVE);
4058 - scb->flags |= SCB_ABORT;
4059 - pti_st_done(p, scb);
4060 - pti_st_done_cmds_complete(p);
4061 -// pti_st_run_waiting_queues(p);
4065 - * On the return value. If we found the command and aborted it, then we know
4066 - * it's already sent back and there is no reason for a further timeout, so
4067 - * we use SCSI_ABORT_SUCCESS. On the queued abort side, we aren't so certain
4068 - * there hasn't been a bus hang or something that might keep the abort from
4069 - * from completing. Therefore, we use SCSI_ABORT_PENDING. The first time
4071 - * is passed back, the timeout on the command gets extended, the second time
4072 - * we pass this back, the mid level SCSI code calls our reset function, which
4073 - * would shake loose a hung bus.
4075 - return(SCSI_ABORT_SUCCESS);
4079 - * Function: pti_st_reset(Scsi_Cmnd *, unsigned int)
4080 - * Description: Resetting the bus always succeeds - is has to, otherwise the
4081 - * kernel will panic! Try a surgical technique: sending ARRAY
4082 - * RESET message frame
4085 -pti_st_reset(Scsi_Cmnd *cmd, unsigned int flags)
4087 - struct pti_st_scb *scb = NULL;
4088 - struct pti_st_host *p;
4090 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
4091 - unsigned long cpu_flags = 0;
4093 - Scsi_Cmnd *cmd_prev, *cmd_next;
4096 - if ( cmd == NULL )
4098 - return(SCSI_RESET_SNOOZE);
4101 - p = (struct pti_st_host *) cmd->host->hostdata;
4102 - for(i = 0; i < MAX_ADAPTORS; i++)
4103 - if(p == pti_st_hostp[i])
4106 - if(!p || i >= MAX_ADAPTORS)
4107 - return(SCSI_RESET_NOT_RUNNING);
4109 - scb = (p->scb_data->scb_array[pti_st_position(cmd)]);
4113 - pti_st_isr(p->pci_irq, p, (void *)NULL );
4114 - pti_st_done_cmds_complete(p);
4118 -// if (pti_st_verbose & VERBOSE_RESET_MID)
4119 - printk(INFO_LEAD "Reset called with bogus Scsi_Cmnd"
4120 - "->SCB mapping, improvising.\n", p->host_no, CTL_OF_CMD(cmd));
4122 - else if (scb->cmd != cmd)
4124 -// if (pti_st_verbose & VERBOSE_RESET_MID)
4125 - printk(INFO_LEAD "Reset called with recycled SCB "
4126 - "for cmd.\n", p->host_no, CTL_OF_CMD(cmd));
4128 - cmd_next = p->completeq.head;
4129 - while ( cmd_next != NULL )
4131 - if (cmd_next == cmd)
4133 -// if (pti_st_verbose & VERBOSE_RESET_RETURN)
4134 - printk(INFO_LEAD "Reset, found cmd on completeq"
4135 - ", completing.\n", p->host_no, CTL_OF_CMD(cmd));
4137 - return(SCSI_RESET_NOT_RUNNING);
4139 - cmd_prev = cmd_next;
4140 - cmd_next = (Scsi_Cmnd *)cmd_next->host_scribble;
4144 - * By this point, we want to already know what we are going to do and
4145 - * only have the following code implement our course of action.
4147 - for (i = 0; i < p->scb_data->maxscbs; i++)
4149 - scb = p->scb_data->scb_array[i];
4150 - if (scb->flags & SCB_ACTIVE)
4152 - scb->flags |= SCB_RESET | SCB_QUEUED_FOR_DONE;
4153 - scb->flags &= ~(SCB_ACTIVE | SCB_WAITINGQ);
4156 - scbq_init(&p->waiting_scbs);
4157 - pti_st_run_done_queue(p, TRUE);
4158 - /* We can't rely on run_waiting_queues to unpause the sequencer for
4159 - * PCI based controllers since we use AAP */
4161 - return (SCSI_RESET_SUCCESS);
4165 - * Function: pti_st_biosparam(Disk *, kdev_t, int[])
4166 - * Description: Return the disk geometry for the given SCSI device.
4169 -pti_st_biosparam(Disk *disk, kdev_t dev, int geom[])
4174 - struct pti_st_host *p;
4176 - p = (struct pti_st_host *) disk->device->host->hostdata;
4179 - * XXX - if I could portably find the card's configuration
4180 - * information, then this could be autodetected instead
4181 - * of left to a boot-time switch.
4185 - cylinders = disk->capacity / (heads * sectors);
4188 - geom[1] = sectors;
4189 - geom[2] = cylinders;
4197 -/***************************************************************************
4198 - Hardware Interface Functions
4199 -****************************************************************************/
4202 - * Function : static int IOP_init(struct pti_st_host *);
4203 - * Description: just initialize the hardware, fetch parameters from PCI.
4205 -static int IOP_init(struct pti_st_host *hostp)
4209 - unsigned long pBaseAddrReg = (U32)hostp->maddr;
4210 - unsigned long pMFA_Inbound;
4212 - // printk("Initializing i960! pBaseAddrReg :%lx\n", pBaseAddrReg);
4214 - // Until the Inbound Queue is available:
4215 - pMFA_Inbound = *(U32 *)(pBaseAddrReg+INBOUNDQPORT);
4216 - while (((U32) pMFA_Inbound == -1))
4217 - pMFA_Inbound = * (U32 *)(pBaseAddrReg+INBOUNDQPORT);
4218 - UtilNOPCall(hostp);
4220 - ExecIOPReset(hostp);
4222 - IopStatus = GetStatusCall(hostp, (void *)hostp->replyBufferp);
4224 - OutboundInitCall(hostp);
4226 - UtilNOPCall(hostp);
4227 - IopStatus = GetStatusCall(hostp, (void *)hostp->replyBufferp);
4229 - /* Outbound Queue is now available! */
4231 - SysTabSetCall(hostp, (PI2O_EXEC_SYS_TAB_SET_MESSAGE)hostp->messageBufferp,
4232 - (void *)hostp->replyBufferp);
4233 - if (pti_st_waitreplymsg(hostp) != I2O_REPLY_STATUS_SUCCESS)
4235 - printk("!BAD reply after sending ExecSysTabSet Message!\n");
4239 - IopStatus = GetStatusCall(hostp, (void *)hostp->replyBufferp);
4241 - if (IopStatus == I2O_IOP_STATE_READY)
4244 - * Send ExecSysEnable message, wait for reply
4247 - EnableSysCall(hostp);
4248 - if (pti_st_waitreplymsg(hostp) != I2O_REPLY_STATUS_SUCCESS)
4250 - printk("!BAD reply after sending ExecSysEnable Message!\n");
4253 - if (GetStatusCall(hostp, (void *)hostp->replyBufferp) != I2O_IOP_STATE_OPERATIONAL)
4259 - /* IOP is in OPERATIONAL state! */
4261 - LCTNotifyCall(hostp);
4262 - if (pti_st_waitreplymsg(hostp) != I2O_REPLY_STATUS_SUCCESS)
4264 - printk("!BAD reply after sending ExecLctNotify Message!\n");
4269 - /* IOP is now initialized! */
4271 - GetInfoFromLCT(hostp,
4272 - (void *)hostp->replyBufferp,
4273 - (PI2ODISK)hostp->I2ODisk,
4274 - (unsigned int *)&hostp->TotalDiskCount);
4276 - for (index = 0; index < hostp->TotalDiskCount; index++)
4278 - ComposeDiskInfo(hostp,
4279 - (PI2O_UTIL_PARAMS_GET_MESSAGE)hostp->messageBufferp,
4280 - (void *)hostp->replyBufferp,
4281 - (PI2ODISK)&hostp->I2ODisk[index] );
4282 - hostp->I2ODisk[index].present = TRUE;
4289 - * Function: unsigned int GetStatusCall(void *)
4290 - * Description: get IOP's state.
4291 - * Return : IOP's current state.
4293 -static unsigned int GetStatusCall(struct pti_st_host *hostp, void * replyBuffer)
4296 - volatile int state;
4299 - unsigned long pBaseAddrReg = (U32)hostp->maddr;
4300 - PI2O_EXEC_STATUS_GET_MESSAGE pMsg;
4301 - PI2O_EXEC_STATUS_GET_REPLY reply =
4302 - (PI2O_EXEC_STATUS_GET_REPLY)replyBuffer;
4304 - msgOffset = hostp->p_atu->InQueue;
4305 - pMsg = (PI2O_EXEC_STATUS_GET_MESSAGE)(hostp->LinBaseAddr + msgOffset);
4307 - memset((void *)reply, 0, sizeof(PI2O_EXEC_STATUS_GET_REPLY));
4309 - pMsg->ReplyBufferLength=0x100;
4310 - pMsg->ReplyBufferAddressLow = virt_to_bus(reply);
4311 - pMsg->VersionOffset=0x01;
4312 - pMsg->MsgFlags=0; /* No flag to set */
4313 - pMsg->MessageSize=(sizeof(I2O_EXEC_STATUS_GET_MESSAGE)>>2);
4314 - pMsg->TargetAddress=0;
4315 - pMsg->InitiatorAddress=0x1; /* from host */
4316 - pMsg->Function=I2O_EXEC_STATUS_GET;
4318 - *(U32 *)(pBaseAddrReg+INBOUNDQPORT) = msgOffset; /* YBM: ... = pMFA_Inbound;*/
4323 - for (i=0; i<1000; i++) /* please don't hog the bus! */
4325 - if ((state=reply->IopState) != 0)
4329 - printk(" Timeout wait for IOP Status Get Ready!\n");
4334 - memcpy((void *)(&hostp->IopStatus),
4336 - sizeof(I2O_EXEC_STATUS_GET_REPLY));
4338 - return (unsigned int) reply->IopState;
4343 -** =========================================================================
4344 -** SendI2OOutboundQInitMsg()
4346 -** =========================================================================
4350 -SendI2OOutboundQInitMsg(PPAB pPab)
4352 - U32 msgOffset, timeout, phyOutQFrames, i;
4353 - volatile PU32 pMsg;
4354 - volatile PU32 p32;
4358 - msgOffset = pPab->p_atu->InQueue;
4361 - if (msgOffset == 0xFFFFFFFF)
4364 - kprintf("SendI2OOutboundQInitMsg(): Inbound Free Q empty!\n");
4366 - return RC_RTN_FREE_Q_EMPTY;
4370 - pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
4373 - kprintf("SendI2OOutboundQInitMsg - pMsg = 0x%08.8ulx, InQ msgOffset = 0x%08.8ulx\n", pMsg, msgOffset);
4376 - pMsg[0] = EIGHT_WORD_MSG_SIZE | TRL_OFFSET_6;
4377 - pMsg[1] = I2O_EXEC_OUTBOUND_INIT << 24 | I2O_HOST_TID << 12 | I2O_IOP_TID;
4378 - pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
4381 - pMsg[5] = MSG_FRAME_SIZE << 16 | 0x80;
4382 - pMsg[6] = 0xD0000004;
4383 - pMsg[7] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB);
4385 - p32 = (PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
4388 - pPab->p_atu->InQueue = msgOffset;
4393 - for (i = 0; i < 1000; i++)
4402 - kprintf("Timeout wait for InitOutQ InPrgress status from IOP\n");
4404 - return RC_RTN_NO_I2O_STATUS;
4411 - for (i = 0; i < 1000; i++)
4414 - if (p32[0] == I2O_EXEC_OUTBOUND_INIT_COMPLETE)
4420 - kprintf("Timeout wait for InitOutQ Complete status from IOP\n");
4422 - return RC_RTN_NO_I2O_STATUS;
4426 - phyOutQFrames = pPab->outMsgBlockPhyAddr;
4428 - for (i = 0; i < NMBR_MSG_FRAMES; i++)
4430 - pPab->p_atu->OutQueue = phyOutQFrames;
4431 - phyOutQFrames += MSG_FRAME_SIZE;
4433 - return RC_RTN_NO_ERROR;
4440 -static void OutboundInitCall(struct pti_st_host *hostp)
4446 - PI2O_EXEC_OUTBOUND_INIT_MESSAGE pMsg;
4447 - unsigned long pBaseAddrReg = (U32)hostp->maddr;
4448 - unsigned long pMFA_Outbound = 0;
4450 - msgOffset = hostp->p_atu->InQueue;
4451 - pMsg = (PI2O_EXEC_OUTBOUND_INIT_MESSAGE)(hostp->LinBaseAddr+msgOffset);
4453 - memset((void *)hostp->replyBufferp, 0, 16*1024);
4455 - pMsg->StdMessageFrame.VersionOffset=0x61; // 32 bit frame
4456 - pMsg->StdMessageFrame.MsgFlags=0;
4457 - pMsg->StdMessageFrame.MessageSize=sizeof(I2O_EXEC_OUTBOUND_INIT_MESSAGE)>>2;
4459 - pMsg->StdMessageFrame.TargetAddress=0; // IXWork
4460 - pMsg->StdMessageFrame.InitiatorAddress = 0x01; // from Host
4461 - pMsg->StdMessageFrame.Function = I2O_EXEC_OUTBOUND_INIT;
4462 - pMsg->HostPageFrameSize = 4096;
4463 - pMsg->InitCode = I2O_MESSAGE_IF_INIT_CODE_NO_OWNER;
4464 - pMsg->OutboundMFrameSize = 0x20; //each frame 32 * 4 bytes
4465 - // the sgl for OutboundInitStatus Word, only 4 bytes.
4466 - pMsg->SGL.u.Simple[0].FlagsCount.Count=4;
4467 - pMsg->SGL.u.Simple[0].FlagsCount.Flags=(I2O_SGL_FLAGS_LAST_ELEMENT |
4468 - I2O_SGL_FLAGS_END_OF_BUFFER |
4469 - I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT);
4471 - pMsg->SGL.u.Simple[0].PhysicalAddress=virt_to_bus(hostp->replyBufferp);
4473 - * (U32 *)(pBaseAddrReg+INBOUNDQPORT) = msgOffset; // YBM: ... = pMFA_Inbound;
4475 - // wait for response:
4476 - timeout = 0x100000;
4479 - for (i=0; i<1000; i++) // please don't hog the bus!!!
4481 - if (*((U8*)hostp->replyBufferp) != 0)
4486 - printk("Timeout wait for I2O_EXEC_OUTBOUND_INIT_IN_PROGRESS status!\n");
4494 - for (i= 0; i<1000; i++) // please don't hog the bus!!!
4496 - if (*((U8*)hostp->replyBufferp) == I2O_EXEC_OUTBOUND_INIT_COMPLETE)
4501 - printk("Timeout wait for I2O_EXEC_OUTBOUND_INIT_COMPLETE status!\n");
4506 - for(x=0; x < 32; x++)
4508 - pMFA_Outbound = (U32)&(hostp->outboundBufferp->outboundBuff[x]);
4509 - *((U32 *)(pBaseAddrReg+OUTBOUNDQPORT))=virt_to_bus((void *)pMFA_Outbound);
4510 - for (i=0; i<1000; i++) // just for waitting!
4514 - printk("Write to Outbound port, MFAs are : \n");
4515 - printk("%lx", pMFA_Outbound);
4518 - // printk(" DONE!\n");
4524 -static void SysTabSetCall(struct pti_st_host *hostp,
4525 - PI2O_EXEC_SYS_TAB_SET_MESSAGE MF,
4528 - U8 tempMemPool[0x200];
4530 - void *tlsgl = lsgl;
4531 - unsigned long pBaseAddrReg = (U32)hostp->maddr;
4532 - unsigned long pMFA_Inbound;
4534 - PI2O_EXEC_STATUS_GET_REPLY ptReplyMemPool =
4535 - (PI2O_EXEC_STATUS_GET_REPLY)tempMemPool;
4537 - PI2O_SGE_SIMPLE_ELEMENT ptsgl =
4538 - (PI2O_SGE_SIMPLE_ELEMENT)MF->SGL.u.Simple;
4541 - tempMemPool[count] = ((char*)tlsgl)[count];
4543 - pMFA_Inbound = * (U32 *)(pBaseAddrReg+INBOUNDQPORT);
4545 - ZeroMemory((U32*) MF, sizeof(I2O_EXEC_SYS_TAB_SET_MESSAGE)+0x10);
4546 - ZeroMemory((U32*) lsgl, 0x200);
4548 - MF->StdMessageFrame.VersionOffset=0x61; // 32 bit frame
4549 - MF->StdMessageFrame.MsgFlags=0;
4550 - MF->StdMessageFrame.MessageSize=sizeof(I2O_EXEC_SYS_TAB_SET_MESSAGE) >> 2;
4552 - MF->StdMessageFrame.TargetAddress=0; // IXWork
4553 - MF->StdMessageFrame.InitiatorAddress = 0x01; // from Host
4554 - MF->StdMessageFrame.Function = I2O_EXEC_SYS_TAB_SET;
4556 - MF->IOP_ID = MY_IOP_ID; //I2O_EXEC_SYS_TAB_IOP_ID_LOCAL_HOST;
4557 - MF->HostUnitID = I2O_EXEC_SYS_TAB_HOST_UNIT_ID_LOCAL_UNIT;
4558 - MF->SegmentNumber = I2O_EXEC_SYS_TAB_SEG_NUMBER_LOCAL_SEGMENT;
4560 - MF->SGL.u.Simple[0].FlagsCount.Count=
4561 - CreatSysTable(hostp, lsgl, (PI2O_EXEC_STATUS_GET_REPLY)tempMemPool);
4563 - // 1st element: YBM: need I2O_SGL_FLAGS_END_OF_BUFFER ?
4564 - ptsgl->FlagsCount.Flags = (I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT |
4565 - I2O_SGL_FLAGS_END_OF_BUFFER) ;
4567 - MF->SGL.u.Simple[0].PhysicalAddress = (U32)(virt_to_bus(lsgl));
4569 - // 2nd element: YBM: need I2O_SGL_FLAGS_END_OF_BUFFER ?
4571 - ptsgl->FlagsCount.Flags = (I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT |
4572 - I2O_SGL_FLAGS_END_OF_BUFFER) ;
4573 - ptsgl->FlagsCount.Count = ptReplyMemPool->CurrentPrivateMemSize;
4574 - ptsgl->PhysicalAddress = ptReplyMemPool->CurrentPrivateMemBase;
4577 -#if defined(MYDEBUG) && 0
4578 - MF->SGL.u.SimpleContext[0].FlagsCount.Count=
4579 - ptReplyMemPool->CurrentPrivateIOSize;
4581 - MF->SGL.u.SimpleContext[0].FlagsCount.Flags =
4582 - (I2O_SGL_FLAGS_LAST_ELEMENT |
4583 - I2O_SGL_FLAGS_END_OF_BUFFER |
4584 - I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT);
4586 - MF->SGL.u.SimpleContext[0].PhysicalAddress = ptReplyMemPool->CurrentPrivateIOBase;
4589 - ptsgl->FlagsCount.Count=
4590 - ptReplyMemPool->CurrentPrivateIOSize;
4592 - ptsgl->FlagsCount.Flags =
4593 - (I2O_SGL_FLAGS_LAST_ELEMENT |
4594 - I2O_SGL_FLAGS_END_OF_BUFFER |
4595 - I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT);
4597 - ptsgl->PhysicalAddress = ptReplyMemPool->CurrentPrivateIOBase;
4600 - memcpy( (void *)(pMFA_Inbound+pBaseAddrReg), (void *)MF,
4601 - (sizeof(I2O_EXEC_OUTBOUND_INIT_MESSAGE)+
4602 - (sizeof(I2O_SGE_SIMPLE_ELEMENT) * 2)) );
4604 - * (U32 *)(pBaseAddrReg+INBOUNDQPORT) = pMFA_Inbound;
4611 -static void EnableSysCall(struct pti_st_host *hostp)
4614 - PI2O_EXEC_SYS_ENABLE_MESSAGE pMsg;
4616 - msgOffset = hostp->p_atu->InQueue;
4618 - pMsg = (PI2O_EXEC_SYS_ENABLE_MESSAGE)(hostp->LinBaseAddr + msgOffset);
4620 - pMsg->StdMessageFrame.VersionOffset=0x1;
4621 - pMsg->StdMessageFrame.MsgFlags=0;
4622 - pMsg->StdMessageFrame.MessageSize=sizeof(I2O_EXEC_SYS_ENABLE_MESSAGE) >> 2;
4624 - pMsg->StdMessageFrame.TargetAddress=0; // IXWork
4625 - pMsg->StdMessageFrame.InitiatorAddress = 0x01; // from Host
4626 - pMsg->StdMessageFrame.Function = I2O_EXEC_SYS_ENABLE;
4628 - *(U32 *)(hostp->LinBaseAddr+INBOUNDQPORT) = msgOffset; // YBM: ... = pMFA_Inbound;
4634 -static void LCTNotifyCall(struct pti_st_host *hostp)
4637 - PI2O_EXEC_LCT_NOTIFY_MESSAGE pMsg;
4638 - unsigned long pBaseAddrReg = (U32)hostp->maddr;
4640 - msgOffset = hostp->p_atu->InQueue;
4642 - pMsg = (PI2O_EXEC_LCT_NOTIFY_MESSAGE)(hostp->LinBaseAddr + msgOffset);
4643 - pMsg->StdMessageFrame.VersionOffset=0x61;
4644 - pMsg->StdMessageFrame.MsgFlags=0;
4645 - pMsg->StdMessageFrame.MessageSize=sizeof(I2O_EXEC_LCT_NOTIFY_MESSAGE)>>2;
4647 - pMsg->StdMessageFrame.TargetAddress=0; // IXWork
4648 - pMsg->StdMessageFrame.InitiatorAddress = 0x01; // from Host
4649 - pMsg->StdMessageFrame.Function = I2O_EXEC_LCT_NOTIFY;
4650 - pMsg->ClassIdentifier = 0xffffffff; // all class
4651 - // I2O_CLASS_RANDOM_BLOCK_STORAGE;
4652 - pMsg->LastReportedChangeIndicator = 0;
4653 - pMsg->SGL.u.Simple[0].FlagsCount.Count=0x1000;
4654 - pMsg->SGL.u.Simple[0].FlagsCount.Flags=(I2O_SGL_FLAGS_LAST_ELEMENT |
4655 - I2O_SGL_FLAGS_END_OF_BUFFER |
4656 - I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT);
4657 - pMsg->SGL.u.Simple[0].PhysicalAddress=virt_to_bus(hostp->replyBufferp);
4659 - * (U32 *)(pBaseAddrReg+INBOUNDQPORT) = msgOffset; // YBM: ... = pMFA_Inbound;
4665 -static U32 CreatSysTable(struct pti_st_host *hostp,
4667 - PI2O_EXEC_STATUS_GET_REPLY ltMemPool)
4669 - PI2O_SET_SYSTAB_HEADER pPacket = (PI2O_SET_SYSTAB_HEADER) llsgl;
4670 - PI2O_IOP_ENTRY pEntry = (PI2O_IOP_ENTRY) ((U8 *) llsgl + sizeof(PI2O_SET_SYSTAB_HEADER));
4672 - pPacket->NumberEntries=0x1;
4673 - pPacket->SysTabVersion=I2O_RESOURCE_MANAGER_VERSION;
4674 - pPacket->CurrentChangeIndicator=0;
4676 - // pEntry->OrganizationID = ltMemPool->OrganizationID;
4677 - pEntry->OrganizationID = PROMISE_ORG_ID;
4678 - pEntry->IOP_ID = MY_IOP_ID; //ltMemPool->IOP_ID;
4679 - pEntry->SegmentNumber = ltMemPool->SegmentNumber;
4680 - pEntry->I2oVersion = ltMemPool->I2oVersion;
4681 - pEntry->IopState = ltMemPool->IopState;
4682 - pEntry->MessengerType = ltMemPool->MessengerType;
4683 - pEntry->InboundMessageFrameSize = ltMemPool->InboundMFrameSize;
4684 - pEntry->LastChanged = 0;
4685 - pEntry->IopCapabilities = ltMemPool->IopCapabilities;
4686 - pEntry->MessengerInfo.InboundMessagePortAddressLow = (U32)hostp->maddr;
4687 - pEntry->MessengerInfo.InboundMessagePortAddressHigh = 0;
4689 - return sizeof(I2O_IOP_ENTRY)+sizeof(I2O_SET_SYSTAB_HEADER);
4693 -/*****************************************************************************
4694 - I2O EXECUTIVE CLASS MESSAGE
4695 -*****************************************************************************/
4700 -static void ExecIOPReset(struct pti_st_host *hostp)
4704 - PI2O_EXEC_IOP_RESET_MESSAGE pMsg;
4705 - volatile PU32 p32;
4706 - unsigned long pBaseAddrReg = (U32)hostp->maddr;
4708 - msgOffset = hostp->p_atu->InQueue;
4710 - pMsg = (PI2O_EXEC_IOP_RESET_MESSAGE)(hostp->LinBaseAddr + msgOffset);
4711 - memset((void *)hostp->replyBufferp, 0, 16*1024);
4713 - pMsg->VersionOffset=0x01;
4715 - pMsg->MessageSize= sizeof(I2O_EXEC_IOP_RESET_MESSAGE) >> 2;
4717 - pMsg->TargetAddress=0; // IXWork
4718 - pMsg->InitiatorAddress = 0x01; // from Host
4719 - pMsg->Function = I2O_EXEC_IOP_RESET;
4721 - pMsg->StatusWordHighAddress = 0;
4722 - pMsg->StatusWordLowAddress =
4723 - (U32)(virt_to_bus((void *)hostp->replyBufferp));
4725 - p32 = (volatile PU32)hostp->replyBufferp;
4727 - *(U32 *)(pBaseAddrReg+INBOUNDQPORT) = msgOffset;
4729 - /* wait for response: */
4730 - timeout = 1000000;
4734 - for (i=0; i<1000; i++) /* please don't hog the bus ! */
4736 - if(p32[0] || p32[1])
4740 - printk("Timeout while Resetting IOP !\n");
4746 -static void PTI_StringCutBlank(char * strBuffer, U32 strLength)
4748 - U32 i = strLength - 2;
4750 - while (i >= 0 && strBuffer[i] == ' ')
4752 - strBuffer[i] = '\0';
4760 -static void GetInfoFromLCT(struct pti_st_host *hostp,
4763 - unsigned int *diskcount)
4765 - PI2O_LCT pTable = (PI2O_LCT)lMemPool;
4766 - PI2O_LCT_ENTRY pLCTEntry;
4767 - PI2O_LCT_ENTRY HeadpLCTEntry = pTable->LCTEntry;
4768 - U16 ParentID=0xffff;
4772 - *diskcount = 0; // initial count
4773 - memset((void *)hostp->LctEntryTable, 0, (sizeof(I2O_LCT_ENTRY) * MAX_LCT_ENTRY));
4775 - while(pTable->TableSize==0) // wait ready
4777 - pLCTEntry=HeadpLCTEntry;
4780 - while (pLCTEntry->TableEntrySize==0x9)
4782 - if(pLCTEntry->ClassID.Class==I2O_CLASS_DDM &&
4783 - pLCTEntry->SubClassInfo==I2O_SUBCLASS_ISM)
4785 - ParentID=(U16) pLCTEntry->LocalTID;
4791 - if (ParentID == 0xffff)
4793 - printk("ISM DDM ID not found!\n");
4797 - /* scan all ISM children first: */
4798 - pLCTEntry=HeadpLCTEntry;
4801 - while(pLCTEntry->TableEntrySize == 0x9)
4804 - * Insert the LCT Entry to LCT Entry Description
4806 - memcpy((void*)&hostp->LctEntryTable[i],
4807 - (void *)pLCTEntry,
4808 - sizeof(I2O_LCT_ENTRY));
4810 - if((pLCTEntry->ClassID.Class==I2O_CLASS_RANDOM_BLOCK_STORAGE) &&
4811 - (pLCTEntry->ParentTID==ParentID))
4813 - pmydisk->LocalTID = (unsigned int) pLCTEntry->LocalTID;
4821 - /* if no ISM child: */
4822 - if(*diskcount == 0)
4823 - { /* parent not exist */
4824 - pLCTEntry = HeadpLCTEntry;
4825 - while(pLCTEntry->TableEntrySize == 0x9)
4827 - if(pLCTEntry->ClassID.Class==I2O_CLASS_RANDOM_BLOCK_STORAGE)
4829 - pmydisk->LocalTID = (unsigned int) pLCTEntry->LocalTID;
4840 - * Starting lMemBuf = 0
4841 - * 0 ~ 3 bytes -- Request Header (0-1) Op Cnt (2-3) Res
4842 - * 4 ~ 9 bytes -- first operation list
4843 - * a ~10 bytes -- second operation list
4845 - * Result starts at lMemBuf+4+6+6
4846 - * 0 ~ 3 -- result header (0-1) Result Cnt
4847 - * 4 ~ n -- first result (first 4 byte, byte cnt in result+status)
4849 -static int ComposeDiskInfo(struct pti_st_host *hostp,
4854 - PI2O_UTIL_DEVICE_IDENTITY_SCALAR pResult1;
4855 - PI2O_BSA_DEVICE_INFO_SCALAR pResult2;
4856 - PI2O_PARAM_READ_OPERATION_RESULT pOpResult;
4857 - PI2O_PARAM_RESULTS_LIST_HEADER pResHeader =
4858 - (PI2O_PARAM_RESULTS_LIST_HEADER) (((U8 *) lMemBuf)+8+4);
4860 - void * ptMemBuf = lMemBuf;
4861 - PI2O_PARAM_OPERATION_ALL_TEMPLATE ptsgl =
4862 - (PI2O_PARAM_OPERATION_ALL_TEMPLATE) (((U8*) lMemBuf) + 4);
4866 - unsigned int Sctr = 0x3f;
4869 - * Note:General and Specific parameter get must invoke separately
4870 - * General Parameter Get
4872 - ZeroMemory(lMemBuf, 0x200);
4874 - *((unsigned int *) ptMemBuf) = 0x1;
4875 - ptsgl->Operation = I2O_PARAMS_OPERATION_FIELD_GET;
4876 - ptsgl->GroupNumber = I2O_UTIL_DEVICE_IDENTITY_GROUP_NO;
4877 - ptsgl->FieldCount = 0xffff;
4879 - PTI_UtilParamGetCall(hostp,
4880 - (PI2O_UTIL_PARAMS_GET_MESSAGE) MF,
4881 - (void *) ptMemBuf,
4882 - (void *) (((U8 *) ptMemBuf)+0x4+0x8),
4884 - if (pti_st_waitreplymsg(hostp) != I2O_REPLY_STATUS_SUCCESS)
4886 - printk("!BAD reply after sending UtilParamsGetMessage!\n");
4890 - pOpResult = (PI2O_PARAM_READ_OPERATION_RESULT) (++pResHeader);
4891 - if(pOpResult->ErrorInfoSize != 0)
4893 - return(FALSE); /* Error Action */
4895 - pResult1 = (PI2O_UTIL_DEVICE_IDENTITY_SCALAR) (++pOpResult);
4897 - memcpy( &(pmydisk->Vendor), &(pResult1->VendorInfo),
4898 - I2O_DEVID_VENDOR_INFO_SZ );
4900 - pmydisk->Vendor[I2O_DEVID_VENDOR_INFO_SZ] = (char) 0;
4902 - PTI_StringCutBlank(pmydisk->Vendor, I2O_DEVID_VENDOR_INFO_SZ);
4904 - memcpy( &(pmydisk->DiskModel), &(pResult1->ProductInfo),
4905 - I2O_DEVID_PRODUCT_INFO_SZ );
4907 - pmydisk->DiskModel[I2O_DEVID_PRODUCT_INFO_SZ] = (char) 0;
4909 - PTI_StringCutBlank(pmydisk->DiskModel, I2O_DEVID_PRODUCT_INFO_SZ);
4911 - memcpy( &(pmydisk->ProductRevLevel), &(pResult1->ProductRevLevel),
4912 - I2O_DEVID_REV_LEVEL_SZ );
4913 - pmydisk->ProductRevLevel[I2O_DEVID_REV_LEVEL_SZ] = '\0';
4915 - PTI_StringCutBlank(pmydisk->ProductRevLevel, I2O_DEVID_REV_LEVEL_SZ);
4918 - * Device Information (Storage Parameter Get)
4920 - ZeroMemory(lMemBuf, 0x200);
4922 - *((unsigned int *) ptMemBuf) = 0x1;
4924 - ptsgl->Operation = I2O_PARAMS_OPERATION_FIELD_GET;
4925 - ptsgl->GroupNumber = I2O_BSA_DEVICE_INFO_GROUP_NO;
4926 - ptsgl->FieldCount = 0xffff;
4928 - PTI_UtilParamGetCall(hostp,
4929 - (PI2O_UTIL_PARAMS_GET_MESSAGE) MF,
4930 - (void *) ptMemBuf,
4931 - (void *) (((U8 *) ptMemBuf)+0x4+0x8),
4933 - if (pti_st_waitreplymsg(hostp) != I2O_REPLY_STATUS_SUCCESS)
4935 - printk("!BAD reply after sending UtilParamsGetMessage!\n");
4939 - pResHeader=(PI2O_PARAM_RESULTS_LIST_HEADER) (((U8 *) lMemBuf)+8+4);
4940 - pOpResult = (PI2O_PARAM_READ_OPERATION_RESULT) (++pResHeader);
4941 - if(pOpResult->ErrorInfoSize != 0)
4943 - return(FALSE); // Error Action
4945 - pResult2 = (PI2O_BSA_DEVICE_INFO_SCALAR) (++pOpResult);
4947 - wSize = (long) ((pResult2->DeviceCapacity.HighPart << (32-9)) |
4948 - (pResult2->DeviceCapacity.LowPart >> 9));
4950 - pmydisk->lastLBA = (U32) wSize - 1;
4952 - // convert LBA to CHS
4953 - if(wSize <= (U32) 0x3f*0x10*0x400)
4956 - while((wSize/(Hd*Sctr) > 0x400) && (Hd < 0x80))
4959 - else if (wSize <= (U32) (0x3fl*0x20l*0x400l)) Hd = 0x20;
4960 - else if (wSize <= (U32) (0x3fl*0x40l*0x400l)) Hd = 0x40;
4961 - else if (wSize <= (U32) (0x3fl*0x80l*0x400l)) Hd = 0x80;
4964 - pmydisk->lastcyl = (unsigned int) ((wSize/ (Hd*Sctr)) - 1);/*starting from 0*/
4965 - pmydisk->lasthead = (U8) (Hd - 1); /*starting from 0*/
4966 - pmydisk->sector = (U8) Sctr; /*starting from 0*/
4972 - * Function: unsigned long pti_st_waitreplymsg(struct pti_st_host *)
4973 - * Description: wait reply message from i960.
4974 - * Return : Error code (0 represent I2O_REPLY_STATUS_SUCCESS)
4976 -unsigned long pti_st_waitreplymsg(struct pti_st_host *hostp)
4981 - PI2O_SINGLE_REPLY_MESSAGE_FRAME replyPointer;
4982 - unsigned long pBaseAddrReg = (U32)hostp->maddr;
4983 - unsigned long pMFA_Outbound;
4985 - // wait for response:
4986 - timeout = 0x1000000;
4989 - for (i=0; i<1000; i++) // please don't hog the bus!!!
4991 - if((pMFA_Outbound=(*(volatile U32 *)(pBaseAddrReg+OUTBOUNDQPORT)))!=-1)
4996 - printk("Timeout wait for Reply Message from IOP!\n");
5001 - replyPointer=(PI2O_SINGLE_REPLY_MESSAGE_FRAME)(bus_to_virt(pMFA_Outbound));
5003 - ReqStatus = replyPointer->ReqStatus;
5005 - * (U32 *)(pBaseAddrReg+OUTBOUNDQPORT) = pMFA_Outbound;
5007 - return (unsigned long) ReqStatus;
5011 -/*****************************************************************************
5012 - I2O UTILITY CLASS MESSAGE
5013 -*****************************************************************************/
5015 - * THis is used for ComposeDiskInfo()
5017 -static void PTI_UtilParamGetCall(struct pti_st_host *hostp,
5018 - PI2O_UTIL_PARAMS_GET_MESSAGE MF,
5023 - PI2O_SGE_SIMPLE_ELEMENT sglentry =
5024 - (PI2O_SGE_SIMPLE_ELEMENT)MF->SGL.u.Simple; // YBM: )&MF->SGL.u.Simple;
5025 - unsigned long pBaseAddrReg = (U32)hostp->maddr;
5026 - unsigned long pMFA_Inbound = * (U32 *)(pBaseAddrReg+INBOUNDQPORT);
5028 - ZeroMemory((U32*) MF, sizeof(I2O_UTIL_PARAMS_GET_MESSAGE)+0x10);
5030 - MF->StdMessageFrame.VersionOffset=0x51;
5031 - MF->StdMessageFrame.MsgFlags=0;
5032 - MF->StdMessageFrame.MessageSize=
5033 - (sizeof(I2O_UTIL_PARAMS_GET_MESSAGE)+sizeof(I2O_SG_ELEMENT)) >> 2;
5035 - MF->StdMessageFrame.TargetAddress=mydisk->LocalTID;
5036 - MF->StdMessageFrame.InitiatorAddress = 0x01; // from Host
5037 - MF->StdMessageFrame.Function = I2O_UTIL_PARAMS_GET;
5039 - MF->OperationFlags = 0; // reserved
5042 - sglentry->FlagsCount.Flags = (I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT |
5043 - I2O_SGL_FLAGS_END_OF_BUFFER );
5044 - sglentry->FlagsCount.Count = 0x0c ;
5045 - sglentry->PhysicalAddress = (U32)(virt_to_bus(req)); // YBM: *(U32 *)req ;
5047 - // Sencond buffer:
5049 - sglentry->FlagsCount.Flags = (I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT |
5050 - I2O_SGL_FLAGS_LAST_ELEMENT |
5051 - I2O_SGL_FLAGS_END_OF_BUFFER );
5052 - sglentry->FlagsCount.Count = 0x100;
5053 - //sizeof(I2O_UTIL_DEVICE_IDENTITY_SCALAR);
5054 - sglentry->PhysicalAddress = (U32)(virt_to_bus(buf)); // YBM: *(U32 *)buf;
5056 - memcpy( (void *)(pMFA_Inbound+pBaseAddrReg), (void *)MF,
5057 - (sizeof(I2O_UTIL_PARAMS_GET_MESSAGE)+16) );
5059 - * (U32 *)(pBaseAddrReg+INBOUNDQPORT) = pMFA_Inbound;
5064 - * This is used for pti_stdev_ioctl()
5066 - * Routine Description:
5068 - * message allows parameter values to be retrieved from
5069 - * device parameter groups.
5071 -static void PTI_UtilParamsGet(
5072 - struct pti_st_host *hostp,
5080 - PI2O_UTIL_PARAMS_GET_MESSAGE MsgPtr;
5081 - PI2O_SGE_SIMPLE_ELEMENT SGLPtr;
5083 - ULONG ParamOffset = 0;
5086 - msgOffset = hostp->p_atu->InQueue;
5087 - MsgPtr = (PI2O_UTIL_PARAMS_GET_MESSAGE)(hostp->LinBaseAddr+msgOffset);
5088 - memset((ULONG *)MsgPtr,0,sizeof(I2O_UTIL_PARAMS_GET_MESSAGE)+0x10);
5089 - SGLPtr = (PI2O_SGE_SIMPLE_ELEMENT)MsgPtr->SGL.u.Simple;
5091 - ParamOffset = sizeof(I2O_PARAM_SCALAR_OPERATION);
5092 - if (FieldCount != (USHORT)-1)
5093 - ParamOffset = ParamOffset + (FieldCount-1)*sizeof(USHORT);
5096 - * fill the message frame
5098 - MsgPtr->StdMessageFrame.VersionOffset = 0x51;
5099 - MsgPtr->StdMessageFrame.MsgFlags = 0;
5100 - MsgPtr->StdMessageFrame.MessageSize =
5101 - (sizeof(I2O_UTIL_PARAMS_GET_MESSAGE)+sizeof(I2O_SG_ELEMENT)) >> 2;
5102 - MsgPtr->StdMessageFrame.TargetAddress = LocalTID;
5103 - MsgPtr->StdMessageFrame.InitiatorAddress = 0x01; /* from Host */
5104 - MsgPtr->StdMessageFrame.Function = I2O_UTIL_PARAMS_GET;
5105 - MsgPtr->StdMessageFrame.InitiatorContext = SrbTag;
5107 - MsgPtr->TransactionContext = SrbID;
5108 - MsgPtr->OperationFlags = 0; /* reserved */
5111 - * fill the SGL frame
5112 - * the first buffer contains the operation list that
5113 - * identifies which parameters are to be returned
5115 - SGLPtr->FlagsCount.Flags = (I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT |
5116 - I2O_SGL_FLAGS_END_OF_BUFFER );
5117 - SGLPtr->FlagsCount.Count = ParamOffset;
5118 - SGLPtr->PhysicalAddress = cpu_to_le32(VIRT_TO_BUS(Address));
5120 - /* the second buffer is for target to place the results */
5122 - SGLPtr->FlagsCount.Flags = (I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT |
5123 - I2O_SGL_FLAGS_LAST_ELEMENT |
5124 - I2O_SGL_FLAGS_END_OF_BUFFER );
5125 - SGLPtr->FlagsCount.Count = 0x100;
5126 - SGLPtr->PhysicalAddress = cpu_to_le32(VIRT_TO_BUS(Address+ParamOffset));
5129 - * send the message
5131 - hostp->p_atu->InQueue = msgOffset;
5138 -static void UtilNOPCall(struct pti_st_host *hostp)
5141 - PI2O_UTIL_NOP_MESSAGE pMsg;
5143 - msgOffset = hostp->p_atu->InQueue;
5145 - pMsg = (PI2O_UTIL_NOP_MESSAGE)(hostp->LinBaseAddr + msgOffset);
5146 - pMsg->StdMessageFrame.VersionOffset=0x1;
5147 - pMsg->StdMessageFrame.MsgFlags=0;
5148 - pMsg->StdMessageFrame.MessageSize= sizeof(I2O_UTIL_NOP_MESSAGE) >> 2;
5149 - pMsg->StdMessageFrame.TargetAddress=0;
5150 - pMsg->StdMessageFrame.InitiatorAddress = 0x1; // from Host
5151 - pMsg->StdMessageFrame.Function = I2O_UTIL_NOP;
5153 - hostp->p_atu->InQueue = msgOffset;
5157 -/********************************************************************
5159 - * Private Messages
5161 - ********************************************************************/
5163 -static void PTI_PrivateMessageCall(
5164 - struct pti_st_host *hostp,
5166 - U16 XFunctionCode,
5167 - U16 OrganizationID,
5170 - ULONG OutputCount,
5171 - UCHAR *OutputAddr,
5176 - PPTI_ST_PRIVATE_MESSAGE MsgPtr;
5177 - unsigned long msgOffset;
5179 - msgOffset = hostp->p_atu->InQueue;
5180 - MsgPtr = (PPTI_ST_PRIVATE_MESSAGE)(hostp->LinBaseAddr+msgOffset);
5181 - memset((UCHAR *)MsgPtr,0,sizeof(PTI_ST_PRIVATE_MESSAGE)+0x10);
5184 - * Fill the message frame
5186 - MsgPtr->MyStandMsg.StdMessageFrame.VersionOffset = 0x1;
5187 - MsgPtr->MyStandMsg.StdMessageFrame.MsgFlags = 0;
5188 - MsgPtr->MyStandMsg.StdMessageFrame.MessageSize = (sizeof(PTI_ST_PRIVATE_MESSAGE) >> 2);
5190 - MsgPtr->MyStandMsg.StdMessageFrame.TargetAddress = TargetTID; /* IXWork */
5191 - MsgPtr->MyStandMsg.StdMessageFrame.InitiatorAddress = 0x01;
5192 - MsgPtr->MyStandMsg.StdMessageFrame.Function = I2O_PRIVATE_MESSAGE;
5193 - MsgPtr->MyStandMsg.StdMessageFrame.InitiatorContext = SrbTag;
5195 - MsgPtr->MyStandMsg.XFunctionCode = (U16)(((XFunctionCode >> 8) & 0x00ff) | ((XFunctionCode << 8) & 0xff00));
5197 - MsgPtr->MyStandMsg.OrganizationID = (U16)(((OrganizationID >> 8) & 0x00ff) | ((OrganizationID << 8) & 0xff00));
5199 - MsgPtr->MyStandMsg.TransactionContext = SrbID;
5201 - * Fill the private Payload
5203 - MsgPtr->InSGL.FlagsCount.Count = InputCount;
5204 - MsgPtr->InSGL.FlagsCount.Flags = I2O_SGL_FLAGS_PAGE_LIST_ADDRESS_ELEMENT | I2O_SGL_FLAGS_END_OF_BUFFER;
5205 - MsgPtr->InSGL.PhysicalAddress[0] =
5206 - cpu_to_le32(VIRT_TO_BUS(InputAddr));
5208 - MsgPtr->OutSGL.FlagsCount.Count = OutputCount;
5209 - MsgPtr->OutSGL.FlagsCount.Flags = I2O_SGL_FLAGS_PAGE_LIST_ADDRESS_ELEMENT | I2O_SGL_FLAGS_LAST_ELEMENT | I2O_SGL_FLAGS_END_OF_BUFFER;
5210 - MsgPtr->OutSGL.PhysicalAddress[0] =
5211 - cpu_to_le32(VIRT_TO_BUS(OutputAddr));
5214 - * send the message
5216 - hostp->p_atu->InQueue = msgOffset;
5220 -/****************************************************************************
5222 -****************************************************************************/
5226 -static void ZeroMemory(unsigned long *zeroBuffer, unsigned int count)
5228 - count = count >> 2; // count/4
5236 -/************************************************************
5237 - * Device File Function *
5238 - ************************************************************/
5240 -static int pti_stdev_strncmp(char *s, char *d, int n)
5252 - /* both not null */
5254 - /* check length 0 */
5265 - /* both length not 0 */
5267 - return(strncmp(s,d,n));
5273 -int pti_stdev_open(struct inode *inodep, struct file *filep)
5275 - int aptno = MINOR(inodep->i_rdev);
5276 -#if defined(__SMP__)
5277 - struct pti_st_host *p = pti_st_hostp[aptno];
5280 - if(!pti_st_hostp[aptno] ||
5281 - pti_st_hostp[aptno]->major <= 0 ||
5282 - pti_st_hostp[aptno]->major != MAJOR(inodep->i_rdev))
5286 - if(pti_st_hostp[aptno]->counter != 0) {
5290 - pti_st_hostp[aptno]->counter++;
5293 - MOD_INC_USE_COUNT;
5297 -int pti_stdev_release(struct inode *inodep, struct file *filep)
5299 - int aptno = MINOR(inodep->i_rdev);
5300 -#if defined(__SMP__)
5301 - struct pti_st_host *p = pti_st_hostp[aptno];
5304 - if(!pti_st_hostp[aptno] ||
5305 - pti_st_hostp[aptno]->major <= 0 ||
5306 - pti_st_hostp[aptno]->major != MAJOR(inodep->i_rdev))
5310 - if(pti_st_hostp[aptno]->counter <= 0) {
5314 - pti_st_hostp[aptno]->counter = 0;
5318 - MOD_DEC_USE_COUNT;
5322 -int pti_stdev_ioctl(struct inode *inodep,
5323 - struct file *filep,
5325 - unsigned long arg)
5327 - SRB_IO_CONTROL *usr_srbp = (SRB_IO_CONTROL *)arg;
5328 - PTI_STDEV_GET_CONFIG_BUFFER *usr_confbufp =
5329 - (PTI_STDEV_GET_CONFIG_BUFFER *)arg;
5330 - PTI_STDEV_INBUFFER *usr_inbufp = (PTI_STDEV_INBUFFER *)arg;
5332 - SRB_IO_CONTROL *srbp = NULL;
5333 - PTI_STDEV_GET_CONFIG_BUFFER *confbufp = NULL;
5334 - PTI_STDEV_INBUFFER *inbufp = NULL;
5336 - PI2O_CONFIG_QUERY ConfigQuyPtr = NULL;
5337 - PI2O_DEVICE_DESCRIPTOR DevDescriptorPtr = NULL;
5338 - PI2O_PARAM_SCALAR_OPERATION ParamScalarPtr = NULL;
5339 - USHORT *TargetTIDp = NULL;
5340 - USHORT *OrganizationIDp = NULL;
5341 - USHORT *XFunctionCodep = NULL;
5342 - UCHAR *InputAddr = NULL;
5343 - UCHAR *OutputAddr = NULL;
5345 - void *bufferp = NULL;
5346 - unsigned long offset;
5347 - unsigned long ret;
5349 - int aptno = MINOR(inodep->i_rdev);
5350 - struct pti_st_host *p = pti_st_hostp[aptno];
5352 - if(!pti_st_hostp[aptno] ||
5353 - pti_st_hostp[aptno]->major <= 0 ||
5354 - pti_st_hostp[aptno]->major != MAJOR(inodep->i_rdev))
5357 - if(pti_st_hostp[aptno]->counter <= 0) {
5361 - bufferp = pti_st_hostp[aptno]->pti_stdev_bufferp;
5362 - memset(bufferp, 0, sizeof(PTI_STDEV_INBUFFER));
5364 - srbp = (SRB_IO_CONTROL *)bufferp;
5367 - case IOCTL_SUPERTRAK_GETVERSION:
5368 - ret = copy_from_user(srbp,
5370 - sizeof(SRB_IO_CONTROL));
5375 - case IOCTL_GET_CONFIG_INFO:
5376 - confbufp = (PTI_STDEV_GET_CONFIG_BUFFER *)bufferp;
5378 - ret = copy_from_user(confbufp,
5380 - sizeof(PTI_STDEV_GET_CONFIG_BUFFER));
5386 - case IOCTL_PRIVATE_MESSAGE_CODE:
5387 - case IOCTL_PARAMS_GET_REQUEST:
5388 - inbufp = (PTI_STDEV_INBUFFER *)bufferp;
5390 - ret = copy_from_user(inbufp,
5392 - sizeof(PTI_STDEV_INBUFFER));
5402 - if(pti_stdev_strncmp(srbp->Signature, SUPERTRAK_SIGNATURE, SUPERTRAK_SIG_LEN))
5406 - case IOCTL_SUPERTRAK_GETVERSION:
5407 - srbp->ControlCode = (VERSIONHI | (VERSIONLO << 16));
5408 - ret = copy_to_user(usr_srbp,
5410 - sizeof(SRB_IO_CONTROL));
5416 - case IOCTL_GET_CONFIG_INFO:
5417 - ConfigQuyPtr = (PI2O_CONFIG_QUERY)((UCHAR *)confbufp+sizeof(SRB_IO_CONTROL));
5418 - DevDescriptorPtr = (PI2O_DEVICE_DESCRIPTOR)((UCHAR *)confbufp+
5419 - + sizeof(SRB_IO_CONTROL)
5420 - + sizeof(I2O_CONFIG_QUERY));
5423 - * fill the I2O_DEVICE_DESCRIPTOR structure
5427 - while(pti_st_hostp[aptno]->LctEntryTable[i].TableEntrySize == 0x09)
5429 - if (pti_st_hostp[aptno]->LctEntryTable[i].ClassID.Class==ConfigQuyPtr->ClassID.Class &&
5430 - pti_st_hostp[aptno]->LctEntryTable[i].SubClassInfo==ConfigQuyPtr->SubClassID)
5433 - * fill the LCT structure
5435 - memcpy((void*)&DevDescriptorPtr->LCT,
5436 - (void*)&pti_st_hostp[aptno]->LctEntryTable[i],
5437 - sizeof(I2O_LCT_ENTRY));
5445 - * Get IOP Description
5447 - DevDescriptorPtr->IOP.IOPNumber = ConfigQuyPtr->IOPNumber;
5448 - DevDescriptorPtr->IOP.IOPCapabilities = pti_st_hostp[aptno]->IopStatus.IopCapabilities;
5449 - DevDescriptorPtr->IOP.IOPState = pti_st_hostp[aptno]->IopStatus.IopState;
5450 - DevDescriptorPtr->IOP.I2OVersion = pti_st_hostp[aptno]->IopStatus.I2oVersion;
5451 - DevDescriptorPtr->IOP.MessengerType = pti_st_hostp[aptno]->IopStatus.MessengerType;
5452 - DevDescriptorPtr->IOP.MaxMessageFrameSize = pti_st_hostp[aptno]->IopStatus.InboundMFrameSize;
5453 - DevDescriptorPtr->IOP.ExpectedLCTSize = pti_st_hostp[aptno]->IopStatus.ExpectedLCTSize;
5454 - DevDescriptorPtr->IOP.MaxInboundMFrames = pti_st_hostp[aptno]->IopStatus.MaxInboundMFrames;
5455 - DevDescriptorPtr->IOP.InitialInboundMFrames = pti_st_hostp[aptno]->IopStatus.CurrentInboundMFrames;
5456 - DevDescriptorPtr->IOP.Reserved = pti_st_hostp[aptno]->IopStatus.reserved;
5458 - ret = copy_to_user(usr_confbufp,
5460 - sizeof(PTI_STDEV_GET_CONFIG_BUFFER));
5466 - case IOCTL_PRIVATE_MESSAGE_CODE:
5468 - * read the TargetTID, OrganizationID and XFunctionCode
5470 - offset = sizeof(SRB_IO_CONTROL) + sizeof(ULONG);
5471 - TargetTIDp = (USHORT *)((UCHAR *)inbufp + offset);
5473 - offset += sizeof(USHORT);
5474 - OrganizationIDp = (USHORT *) ((UCHAR *)inbufp + offset);
5476 - offset += sizeof(USHORT);
5477 - XFunctionCodep = (USHORT *) ((UCHAR *)inbufp + offset);
5479 - offset += sizeof(USHORT);
5480 - InputAddr = (UCHAR *)inbufp + offset;
5481 - OutputAddr = InputAddr + 0x800;
5484 - * Send Private Message
5488 - for(ret = 0; ret < 5; ret++)
5490 - for(i = 0; i < p->scb_data->maxscbs; i++)
5491 - if(p->scb_data->scb_array[i]->flags&SCB_ACTIVE)
5493 - if(i >= p->scb_data->maxscbs) { /* card is idel */
5499 - if(ret >= 5) { /* the cards is busy */
5504 - * Disable interrupt
5506 - pti_st_hostp[aptno]->p_atu->OutIntMask = 0x000000fc;
5508 - PTI_PrivateMessageCall(pti_st_hostp[aptno],
5513 - 0x800, OutputAddr,
5516 - if (pti_st_waitreplymsg(pti_st_hostp[aptno])
5517 - != I2O_REPLY_STATUS_SUCCESS)
5519 - printk("!BAD reply after sending UtilParamsGetMessage!\n");
5526 - * Enable interrupt
5528 - pti_st_hostp[aptno]->p_atu->OutIntMask = 0x00000000;
5533 - ret = copy_to_user(usr_inbufp,
5535 - sizeof(PTI_STDEV_INBUFFER));
5544 - case IOCTL_PARAMS_GET_REQUEST:
5545 - offset = sizeof(SRB_IO_CONTROL) + sizeof(ULONG);
5546 - TargetTIDp = (USHORT *)((UCHAR *)inbufp + offset);
5548 - offset += sizeof(USHORT);
5549 - ParamScalarPtr = (PI2O_PARAM_SCALAR_OPERATION)((UCHAR *)inbufp + offset);
5551 - InputAddr = (UCHAR *)((UCHAR *)inbufp + offset);
5553 - for(ret = 0; ret < 5; ret++)
5555 - for(i = 0; i < p->scb_data->maxscbs; i++)
5556 - if(p->scb_data->scb_array[i]->flags&SCB_ACTIVE)
5558 - if(i >= p->scb_data->maxscbs) { /* card is idel */
5564 - if(ret >= 5) { /* the cards is busy */
5571 - * Disable interrupt
5573 - pti_st_hostp[aptno]->p_atu->OutIntMask = 0x000000fc;
5575 - PTI_UtilParamsGet(pti_st_hostp[aptno],
5577 - ParamScalarPtr->OpBlock.FieldCount,
5581 - if (pti_st_waitreplymsg(pti_st_hostp[aptno])
5582 - != I2O_REPLY_STATUS_SUCCESS)
5584 - printk("!BAD reply after sending UtilParamsGetMessage!\n");
5591 - * Enable interrupt
5593 - pti_st_hostp[aptno]->p_atu->OutIntMask = 0x00000000;
5598 - ret = copy_to_user(usr_inbufp,
5600 - sizeof(PTI_STDEV_INBUFFER));
5616 - * Support for loading low-level scsi drivers using the linux kernel loadable
5617 - * module interface.
5619 - * To use, the host adapter should first define and initialize the variable
5620 - * driver_template (datatype Scsi_Host_Template), and then include this file.
5621 - * This should also be wrapped in a #ifdef MODULE/#endif.
5623 - * The low -level driver must also define a release function which will
5624 - * free any irq assignments, release any dma channels, release any I/O
5625 - * address space that might be reserved, and otherwise clean up after itself.
5626 - * The idea is that the same driver should be able to be reloaded without
5627 - * any difficulty. This makes debugging new drivers easier, as you should
5628 - * be able to load the driver, test it, unload, modify and reload.
5630 - * One *very* important caveat. If the driver may need to do DMA on the
5631 - * ISA bus, you must have unchecked_isa_dma set in the device template,
5632 - * even if this might be changed during the detect routine. This is
5633 - * because the shpnt structure will be allocated in a special way so that
5634 - * it will be below the appropriate DMA limit - thus if your driver uses
5635 - * the hostdata field of shpnt, and the board must be able to access this
5636 - * via DMA, the shpnt structure must be in a DMA accessible region of
5637 - * memory. This comment would be relevant for something like the buslogic
5638 - * driver where there are many boards, only some of which do DMA onto the
5639 - * ISA bus. There is no convenient way of specifying whether the host
5640 - * needs to be in a ISA DMA accessible region of memory when you call
5644 -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,0) /* > 2.4.0 */
5646 -static Scsi_Host_Template pti_st_driver_template = PTI_ST;
5648 -static int __init init_this_scsi_driver(void)
5651 - pti_st_driver_template.module = THIS_MODULE;
5652 - scsi_register_module(MODULE_SCSI_HA, &pti_st_driver_template);
5654 - if (!pti_st_driver_template.present ||
5655 - (major = register_blkdev(0, PTCNTL_DEV_NAME, (struct block_device_operations *)&pti_stdev_fops)) < 0)
5657 - if(pti_st_driver_template.present)
5658 - scsi_unregister_module(MODULE_SCSI_HA, &pti_st_driver_template);
5662 - for(i = 0; i < MAX_ADAPTORS; i++)
5664 - if(pti_st_hostp[i])
5666 - pti_st_hostp[i]->counter = 0;
5667 - pti_st_hostp[i]->major = major;
5675 -static void __exit exit_this_scsi_driver(void)
5679 - for(i = 0; i < MAX_ADAPTORS; i++)
5680 - if(pti_st_hostp[i])
5683 - if(i < MAX_ADAPTORS) {
5684 - if(pti_st_hostp[i]->major > 0)
5685 - unregister_blkdev(pti_st_hostp[i]->major,PTCNTL_DEV_NAME);
5686 - if(pti_st_hostp[i]) {
5687 - scsi_unregister_module(MODULE_SCSI_HA, &pti_st_driver_template);
5693 -module_init(init_this_scsi_driver);
5694 -module_exit(exit_this_scsi_driver);
5696 -#else /* > 2.4.0 */
5698 -Scsi_Host_Template pti_st_driver_template = PTI_ST;
5700 -int init_module(void)
5703 - pti_st_driver_template.module = &__this_module;
5704 - scsi_register_module(MODULE_SCSI_HA, &pti_st_driver_template);
5706 - if (!pti_st_driver_template.present ||
5707 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
5708 - (major = register_blkdev(0, PTCNTL_DEV_NAME, (struct file_operations *)&pti_stdev_fops)) < 0)
5710 - (major = register_blkdev(0, PTCNTL_DEV_NAME, (struct block_device_operations *)&pti_stdev_fops)) < 0)
5713 - if(pti_st_driver_template.present)
5714 - scsi_unregister_module(MODULE_SCSI_HA, &pti_st_driver_template);
5718 - for(i = 0; i < MAX_ADAPTORS; i++)
5720 - if(pti_st_hostp[i])
5722 - pti_st_hostp[i]->counter = 0;
5723 - pti_st_hostp[i]->major = major;
5730 -void cleanup_module(void)
5734 - for(i = 0; i < MAX_ADAPTORS; i++)
5735 - if(pti_st_hostp[i])
5738 - if(i < MAX_ADAPTORS) {
5739 - if(pti_st_hostp[i]->major > 0)
5740 - unregister_blkdev(pti_st_hostp[i]->major,PTCNTL_DEV_NAME);
5741 - if(pti_st_hostp[i]) {
5742 - scsi_unregister_module(MODULE_SCSI_HA, &pti_st_driver_template);
5748 -#endif /* > 2.4.0 */
5751 +/*+M*************************************************************************
\r
5752 + * Promise SuperTrak device driver for Linux.
\r
5754 + * Copyright (c) 2001 Promise Technology, Inc.
\r
5756 + * This program is free software; you can redistribute it and/or modify
\r
5757 + * it under the terms of the GNU General Public License as published by
\r
5758 + * the Free Software Foundation; either version 2 of the License, or
\r
5759 + * (at your option) any later version.
\r
5761 + * This program is distributed in the hope that it will be useful,
\r
5762 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
5763 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
5764 + * GNU General Public License for more details.
\r
5766 + * You should have received a copy of the GNU General Public License
\r
5767 + * along with this program; if not, write to the Free Software
\r
5768 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
5770 + * --------------------------------------------------------------------------
\r
5771 + * Copyright (c) 1999-2001 Promise Technology, Inc.
\r
5772 + * All rights reserved.
\r
5774 + * Redistribution and use in source and binary forms, with or without
\r
5775 + * modification, are permitted provided that the following conditions
\r
5777 + * 1. Redistributions of source code must retain the above copyright
\r
5778 + * notice, this list of conditions, and the following disclaimer,
\r
5779 + * without modification, immediately at the beginning of the file.
\r
5780 + * 2. Redistributions in binary form must reproduce the above copyright
\r
5781 + * notice, this list of conditions and the following disclaimer in the
\r
5782 + * documentation and/or other materials provided with the distribution.
\r
5783 + * 3. The name of the author may not be used to endorse or promote products
\r
5784 + * derived from this software without specific prior written permission.
\r
5786 + * Where this Software is combined with software released under the terms of
\r
5787 + * the GNU Public License ("GPL") and the terms of the GPL would require the
\r
5788 + * combined work to also be released under the terms of the GPL, the terms
\r
5789 + * and conditions of this License will apply in addition to those of the
\r
5790 + * GPL with the exception of any terms or conditions of this License that
\r
5791 + * conflict with, or are expressly prohibited by, the GPL.
\r
5793 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
\r
5794 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
\r
5795 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
\r
5796 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
\r
5797 + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\r
5798 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
\r
5799 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
\r
5800 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
\r
5801 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
\r
5802 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
\r
5806 + *-M*************************************************************************/
\r
5807 +#include <linux/string.h>
\r
5808 +#include <linux/errno.h>
\r
5811 +#include <linux/module.h>
\r
5814 +#ifndef KERNEL_VERSION
\r
5815 +# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
\r
5818 +#if defined(MODULE)
\r
5819 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,0)
\r
5820 +#include <linux/init.h>
\r
5824 +#include <stdarg.h>
\r
5825 +#include <asm/io.h>
\r
5826 +#include <asm/irq.h>
\r
5827 +#include <asm/byteorder.h>
\r
5828 +#include <asm/string.h>
\r
5829 +#include <linux/version.h>
\r
5830 +#include <linux/kernel.h>
\r
5831 +#include <linux/ioport.h>
\r
5832 +#include <linux/delay.h>
\r
5833 +#include <linux/sched.h>
\r
5834 +#include <linux/pci.h>
\r
5835 +#include <linux/proc_fs.h>
\r
5836 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
\r
5837 +#include <linux/fs.h>
\r
5839 +#include <linux/blk.h>
\r
5840 +#include <linux/blkdev.h>
\r
5841 +#include <linux/tqueue.h>
\r
5842 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
\r
5843 +#include <linux/tasks.h>
\r
5844 +#include <linux/malloc.h> /* for kmalloc() */
\r
5846 +#include <linux/slab.h> /* for kmalloc() */
\r
5848 +#include <linux/stat.h>
\r
5849 +#include <linux/config.h> /* for CONFIG_PCI */
\r
5850 +#include <asm/segment.h>
\r
5851 +#include <linux/timer.h>
\r
5852 +#include <linux/notifier.h>
\r
5853 +#include <linux/reboot.h>
\r
5859 + __asm__ __volatile__("lock ; addl $0,0(%%esp)": : :"memory")
\r
5861 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,16)
\r
5862 +# include <asm/spinlock.h>
\r
5864 +# include <linux/spinlock.h>
\r
5866 +# include <linux/smp.h>
\r
5867 +# define cpuid smp_processor_id()
\r
5869 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,0)
\r
5871 +# define DRIVER_LOCK_INIT spin_lock_init(&p->spin_lock);
\r
5872 +# define DRIVER_LOCK spin_lock(&p->spin_lock);
\r
5873 +# define DRIVER_UNLOCK spin_unlock(&p->spin_lock);
\r
5875 +#else /* < KERNEL_VERSION(2,4,0) */
\r
5877 +#if defined(__SMP__)
\r
5878 +# if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
\r
5879 +# define DRIVER_LOCK_INIT \
\r
5880 + spin_lock_init(&p->spin_lock);
\r
5881 +# define DRIVER_LOCK \
\r
5882 + if(!p->cpu_lock_count[cpuid]) { \
\r
5883 + spin_lock_irqsave(&p->spin_lock, cpu_flags); \
\r
5884 + p->cpu_lock_count[cpuid]++; \
\r
5886 + p->cpu_lock_count[cpuid]++; \
\r
5888 +# define DRIVER_UNLOCK \
\r
5889 + if(--p->cpu_lock_count[cpuid] == 0) \
\r
5890 + spin_unlock_irqrestore(&p->spin_lock, cpu_flags);
\r
5892 +# define DRIVER_LOCK_INIT spin_lock_init(&p->spin_lock);
\r
5893 +# define DRIVER_LOCK spin_lock(&p->spin_lock);
\r
5894 +# define DRIVER_UNLOCK spin_unlock(&p->spin_lock);
\r
5896 +#else /* __SMP__ */
\r
5897 +#define DRIVER_LOCK_INIT
\r
5898 +#define DRIVER_LOCK
\r
5899 +#define DRIVER_UNLOCK
\r
5900 +#endif /* __SMP__ */
\r
5902 +#endif /* < KERNEL(VERSION(2,4,0) */
\r
5904 +#include <asm/uaccess.h>
\r
5907 +#include "scsi.h"
\r
5908 +#include "hosts.h"
\r
5910 +#include "pti_st.h"
\r
5911 +#include "pti_stdev.h"
\r
5913 +#define PTI_ST_VERBOSE_DEBUGGING
\r
5915 +#define PCI_DEVICE_ID_INTEL_i960 0x1960
\r
5916 +#define PCI_DEVICE_ID_INTEL_i962 0x1962
\r
5918 +#define VIRT_TO_BUS(a) (unsigned int)virt_to_bus((void *)(a))
\r
5922 +struct proc_dir_entry proc_root =
\r
5926 + * Inode number - ignore, it will be filled by
\r
5927 + * proc_register[_dynamic]
\r
5931 + * Length of the proc-file name
\r
5935 + * The proc-file name
\r
5937 + S_IFREG | S_IRUGO,
\r
5939 + * File mode - this is a regular
\r
5940 + * file which can be read by its
\r
5941 + * owner, its group, and everybody
\r
5946 + * Number of links (directories where the
\r
5947 + * file is referenced)
\r
5951 + * The uid and gid for the file - we give it
\r
5956 + * The size of the file reported by ls.
\r
5960 + * functions which can be done on the inode
\r
5961 + * (linking, removing, etc.) - we don't
\r
5964 + NULL, // procfile_read,
\r
5966 + * The read function for this file,
\r
5967 + * the function called when somebody
\r
5968 + * tries to read something from it.
\r
5972 + * We could have here a function to fill the
\r
5973 + * file's inode, to enable us to play with
\r
5974 + * permissions, ownership, etc.
\r
5980 +struct proc_dir_entry proc_scsi_pti_st =
\r
5982 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
\r
5983 + PROC_SCSI_NOT_PRESENT,
\r
5987 + * Inode number - ignore, it will be filled by
\r
5988 + * proc_register[_dynamic]
\r
5993 + * Length of the proc-file name
\r
5997 + * The proc-file name
\r
5999 + S_IFDIR | S_IRUGO | S_IXUGO,
\r
6001 + * File mode - this is a regular
\r
6002 + * file which can be read by its
\r
6003 + * owner, its group, and everybody
\r
6008 + * Number of links (directories where the
\r
6009 + * file is referenced)
\r
6013 + * The uid and gid for the file - we give it
\r
6018 + * The size of the file reported by ls.
\r
6022 + * functions which can be done on the inode
\r
6023 + * (linking, removing, etc.) - we don't
\r
6028 + * The read function for this file,
\r
6029 + * the function called when somebody
\r
6030 + * tries to read something from it.
\r
6034 + * We could have here a function to fill the
\r
6035 + * file's inode, to enable us to play with
\r
6036 + * permissions, ownership, etc.
\r
6040 +#define ALL_TARGETS -1
\r
6041 +#define ALL_CHANNELS -1
\r
6042 +#define ALL_LUNS -1
\r
6044 +#define MAX_ARRAYS 8
\r
6046 +#define MAX_LUNS MAX_ARRAYS
\r
6048 +#define PTI_ST_CMDS_PER_LUN 24
\r
6051 + * The position of the SCSI commands scb within the scb array.
\r
6053 +#define pti_st_position(cmd) ((cmd)->SCp.have_data_in)
\r
6055 +/* This variable is global and very important, control all module !!! */
\r
6056 +struct pti_st_host *pti_st_hostp[MAX_ADAPTORS] = {0};
\r
6059 + * The following are used for Buffer Flush in ioctl
\r
6061 +static struct timer_list bufflsh_timer;
\r
6062 +static struct timer_list priv_msg_timer;
\r
6064 +#define FLUSHCACHE_TIMEOUT_DEFULT 60
\r
6067 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,0)
\r
6068 + static DECLARE_WAIT_QUEUE_HEAD(WaitQ);
\r
6069 + static DECLARE_WAIT_QUEUE_HEAD(PrivMsgWaitQ);
\r
6071 + static struct wait_queue *WaitQ=NULL;
\r
6072 + static struct wait_queue *PrivMsgWaitQ=NULL;
\r
6076 +#define CTL_OF_CMD(cmd) ((cmd->channel) & 0x01), \
\r
6077 + ((cmd->target) & 0x0f), \
\r
6078 + ((cmd->lun) & 0x07)
\r
6081 + * A nice little define to make doing our printks a little easier
\r
6084 +#define WARN_LEAD KERN_WARNING "(scsi%d:%d:%d:%d) "
\r
6085 +#define INFO_LEAD KERN_INFO "(scsi%d:%d:%d:%d) "
\r
6088 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,18)
\r
6089 +MODULE_LICENSE("GPL");
\r
6094 +static int pti_st_install(Scsi_Host_Template *, struct pci_dev *, int *);
\r
6095 +static int PTI_PrivateMessageCall(struct pti_st_host *, ULONG, U16, U16, ULONG, UCHAR *, ULONG, UCHAR *, UCHAR, ULONG);
\r
6098 + * Declaration for EXECUTIVE Class Message
\r
6100 +static unsigned int GetStatusCall(struct pti_st_host *, void *);
\r
6101 +static void OutboundInitCall(struct pti_st_host *);
\r
6102 +static void SysTabSetCall(struct pti_st_host *, PI2O_EXEC_SYS_TAB_SET_MESSAGE, void *);
\r
6103 +static int IOP_init(struct pti_st_host *);
\r
6104 +static void EnableSysCall(struct pti_st_host *);
\r
6105 +static void LCTNotifyCall(struct pti_st_host *);
\r
6107 +static unsigned long CreatSysTable(struct pti_st_host *, void *, PI2O_EXEC_STATUS_GET_REPLY);
\r
6108 +static void ExecIOPReset(struct pti_st_host *);
\r
6109 +static void PTI_UtilParamsGet(struct pti_st_host *, ULONG, ULONG, UCHAR, ULONG, UCHAR *);
\r
6112 + * Declare Utility Message Functions:
\r
6114 +static unsigned long pti_st_waitreplymsg(struct pti_st_host *);
\r
6115 +static void PTI_UtilParamGetCall(struct pti_st_host *,
\r
6116 + PI2O_UTIL_PARAMS_GET_MESSAGE,
\r
6117 + void *, void *, PI2ODISK);
\r
6118 +static void UtilNOPCall(struct pti_st_host *);
\r
6120 +static int ComposeDiskInfo(struct pti_st_host *, void *, void *, PI2ODISK);
\r
6121 +static void GetInfoFromLCT(struct pti_st_host *, void *, PI2ODISK, unsigned int *);
\r
6122 +static void ZeroMemory(unsigned long *, unsigned int);
\r
6123 +static int pti_st_flushcache(int);
\r
6124 +static void pti_st_flushcache_respond(Scsi_Cmnd *);
\r
6125 +static void pti_st_wait_flushcache(unsigned long);
\r
6126 +static int pti_st_send_flushcache_cmd(struct pti_st_host *, struct pti_st_scb *, Scsi_Cmnd *, int);
\r
6128 +#define ADDTOPROCBUFFER(d, s) { if((strlen(d)+strlen(s)) < 4095) strcat(d, s); else goto proc_out; }
\r
6131 + * PTI_procfile_read:
\r
6132 + * inout : decides on the direction of the dataflow and the meaning of the
\r
6134 + * buffer: If inout==FALSE data is being written to it else read from it
\r
6135 + * *start: If inout==FALSE start of the valid data in the buffer
\r
6136 + * offset: If inout==FALSE offset from the beginning of the imaginary file
\r
6137 + * from which we start writing into the buffer
\r
6138 + * length: If inout==FALSE max number of bytes to be written into the buffer
\r
6139 + * else number of bytes in the buffer
\r
6141 +int PTI_procfile_read(char *buffer,
\r
6142 + char **buffer_location,
\r
6144 + int buffer_length,
\r
6149 + * The number of bytes actually used
\r
6154 + * This is static so it will still be in memory
\r
6155 + * when we leave this function
\r
6157 + static char my_buffer[4096] = {0};
\r
6158 + char tmp_buffer[256] = {0};
\r
6159 + char *ptr = my_buffer;
\r
6163 + * We give all of our information in one go, so if the
\r
6164 + * user asks us if we have more information the
\r
6165 + * answer should always be no.
\r
6167 + * This is important because the standard read
\r
6168 + * function from the library would continue to issue
\r
6169 + * the read system call until the kernel replies
\r
6170 + * that it has no more information, or until its
\r
6171 + * buffer is filled.
\r
6177 + * Fill the buffer and get its length
\r
6179 + sprintf(ptr,"***** SuperTrak SX6000 Driver Version %2d.%2d *****\n", VERSIONHI, VERSIONLO);
\r
6180 + ptr += strlen(ptr);
\r
6181 + sprintf(ptr,"***** Copyright 1999-2001 by Promise Technology, Inc. *****\n\n");
\r
6182 + ptr += strlen(ptr);
\r
6184 + for(i = 0; i < MAX_ADAPTORS && (len = strlen(my_buffer)) < 4095; i++) {
\r
6185 + if(!pti_st_hostp[i])
\r
6187 + sprintf(tmp_buffer, "\n\tIOP Number: %d\n", i);
\r
6188 + ADDTOPROCBUFFER(my_buffer, tmp_buffer);
\r
6189 + sprintf(tmp_buffer, "\tCapabilities: %ld",
\r
6190 + pti_st_hostp[i]->IopStatus.IopCapabilities);
\r
6191 + ADDTOPROCBUFFER(my_buffer, tmp_buffer);
\r
6192 + sprintf(tmp_buffer, "\t\tState: %d\n",
\r
6193 + pti_st_hostp[i]->IopStatus.IopState);
\r
6194 + ADDTOPROCBUFFER(my_buffer, tmp_buffer);
\r
6195 + sprintf(tmp_buffer, "\tI2OVersion: %d",
\r
6196 + pti_st_hostp[i]->IopStatus.I2oVersion);
\r
6197 + ADDTOPROCBUFFER(my_buffer, tmp_buffer);
\r
6198 + sprintf(tmp_buffer, "\t\t\tMessengerType: 0x%x\n",
\r
6199 + pti_st_hostp[i]->IopStatus.MessengerType);
\r
6200 + ADDTOPROCBUFFER(my_buffer, tmp_buffer);
\r
6201 + sprintf(tmp_buffer, "\tMaxMessageFrameSize: 0x%x",
\r
6202 + pti_st_hostp[i]->IopStatus.InboundMFrameSize);
\r
6203 + ADDTOPROCBUFFER(my_buffer, tmp_buffer);
\r
6204 + sprintf(tmp_buffer, "\tExpectedLCTSize: 0x%lx\n",
\r
6205 + pti_st_hostp[i]->IopStatus.ExpectedLCTSize);
\r
6206 + ADDTOPROCBUFFER(my_buffer, tmp_buffer);
\r
6207 + sprintf(tmp_buffer, "\tMaxInboundMFrames: 0x%lx",
\r
6208 + pti_st_hostp[i]->IopStatus.MaxInboundMFrames);
\r
6209 + ADDTOPROCBUFFER(my_buffer, tmp_buffer);
\r
6210 + sprintf(tmp_buffer, "\tInitialInboundMFrames: 0x%lx\n",
\r
6211 + pti_st_hostp[i]->IopStatus.CurrentInboundMFrames);
\r
6212 + ADDTOPROCBUFFER(my_buffer, tmp_buffer);
\r
6213 + sprintf(tmp_buffer, "\n\tLCT Entry:\n");
\r
6214 + ADDTOPROCBUFFER(my_buffer, tmp_buffer);
\r
6217 + while(pti_st_hostp[i]->LctEntryTable[j].TableEntrySize == 0x09)
\r
6219 + sprintf(tmp_buffer, "\n\tClass: 0x%x",
\r
6220 + pti_st_hostp[i]->LctEntryTable[j].ClassID.Class);
\r
6221 + ADDTOPROCBUFFER(my_buffer, tmp_buffer);
\r
6222 + sprintf(tmp_buffer, "\t\tVersion: %d\n",
\r
6223 + pti_st_hostp[i]->LctEntryTable[j].ClassID.Version);
\r
6224 + ADDTOPROCBUFFER(my_buffer, tmp_buffer);
\r
6225 + sprintf(tmp_buffer, "\tOrganizationID: 0x%x",
\r
6226 + pti_st_hostp[i]->LctEntryTable[j].ClassID.Version);
\r
6227 + ADDTOPROCBUFFER(my_buffer, tmp_buffer);
\r
6228 + sprintf(tmp_buffer, "\tLocalTID: 0x%x\n",
\r
6229 + pti_st_hostp[i]->LctEntryTable[j].LocalTID);
\r
6230 + ADDTOPROCBUFFER(my_buffer, tmp_buffer);
\r
6231 + sprintf(tmp_buffer, "\tChangeIndicator: 0x%lx",
\r
6232 + pti_st_hostp[i]->LctEntryTable[j].ChangeIndicator);
\r
6233 + ADDTOPROCBUFFER(my_buffer, tmp_buffer);
\r
6234 + sprintf(tmp_buffer, "\tDeviceFlags: 0x%lx\n",
\r
6235 + pti_st_hostp[i]->LctEntryTable[j].DeviceFlags);
\r
6236 + ADDTOPROCBUFFER(my_buffer, tmp_buffer);
\r
6237 + sprintf(tmp_buffer, "\tSubClassInfo: 0x%lx",
\r
6238 + pti_st_hostp[i]->LctEntryTable[j].SubClassInfo);
\r
6239 + ADDTOPROCBUFFER(my_buffer, tmp_buffer);
\r
6240 + sprintf(tmp_buffer, "\tUserTID: 0x%x\n",
\r
6241 + pti_st_hostp[i]->LctEntryTable[j].UserTID);
\r
6242 + ADDTOPROCBUFFER(my_buffer, tmp_buffer);
\r
6243 + sprintf(tmp_buffer, "\tParentTID: 0x%x",
\r
6244 + pti_st_hostp[i]->LctEntryTable[j].ParentTID);
\r
6245 + ADDTOPROCBUFFER(my_buffer, tmp_buffer);
\r
6246 + sprintf(tmp_buffer, "\t\tBiosInfo: 0x%x\n",
\r
6247 + pti_st_hostp[i]->LctEntryTable[j].BiosInfo);
\r
6248 + ADDTOPROCBUFFER(my_buffer, tmp_buffer);
\r
6249 + sprintf(tmp_buffer, "\tEventCapabilities: 0x%lx\n",
\r
6250 + pti_st_hostp[i]->LctEntryTable[j].EventCapabilities);
\r
6251 + ADDTOPROCBUFFER(my_buffer, tmp_buffer);
\r
6258 + * Tell the function which called us where the
\r
6261 + len = strlen(my_buffer);
\r
6262 + if(len < buffer_length)
\r
6263 + buffer_length = len;
\r
6264 + else if(len >= buffer_length) {
\r
6265 + my_buffer[buffer_length-1] = 0;
\r
6266 + len = buffer_length - 1;
\r
6269 + *buffer_location = my_buffer;
\r
6272 + * Return the length
\r
6277 +/*+F*************************************************************************
\r
6282 + * Return a string describing the driver.
\r
6283 + *-F*************************************************************************/
\r
6284 +const char *PTI_ST_info(struct Scsi_Host *dooh)
\r
6286 + static char buffer[256];
\r
6289 + bp = &buffer[0];
\r
6290 + memset(bp, 0, sizeof(buffer));
\r
6291 + strcpy(bp, "PROMISE SuperTrak SX6000 Driver");
\r
6298 +Routine Description:
\r
6300 + This routine will write data specified by Buffer to PCIConfig Space
\r
6308 + Length of data which has been written
\r
6312 +static ULONG PTI_ST_SetBusDataByOffset(
\r
6313 + ULONG BusNumber,
\r
6314 + ULONG DeviceNumber,
\r
6315 + ULONG FunctionNumber,
\r
6323 + cr = 0x80000000 |
\r
6324 + (BusNumber << 16) |
\r
6325 + (DeviceNumber<<11) |
\r
6326 + (FunctionNumber<<8) |
\r
6327 + (Offset & 0xFC);
\r
6329 + outl(cr, 0xCf8);
\r
6331 + if (Length == 4)
\r
6332 + outl(*((ULONG *)Buffer), 0xcfc);
\r
6333 + else if (Length == 2)
\r
6337 + data = (inl(0xCfC) & (Offset&0x3 ? 0xFFFF : 0xFFFF0000));
\r
6338 + data |= (((ULONG)(*(USHORT *)Buffer)) << (Offset&0x3 ? 16 : 0));
\r
6339 + outl(data, 0xcfc);
\r
6350 + * Function: scbq_init(volatile scb_queue_type *queue)
\r
6351 + * Description: SCB queue initialization.
\r
6354 +scbq_init(volatile scb_queue_type *queue)
\r
6356 + queue->head = NULL;
\r
6357 + queue->tail = NULL;
\r
6361 + * Function: scbq_insert_head(volatile scb_queue_type, struct pti_st_scb)
\r
6362 + * Description: Add an SCB to the head of the list.
\r
6364 +static inline void
\r
6365 +scbq_insert_head(struct pti_st_host *p, volatile scb_queue_type *queue, struct pti_st_scb *scb)
\r
6368 + scb->q_next = queue->head;
\r
6369 + queue->head = scb;
\r
6370 + if (queue->tail == NULL) /* If list was empty, update tail. */
\r
6371 + queue->tail = queue->head;
\r
6376 + * Function: scbq_remove_head(volatile scb_queue_type)
\r
6377 + * Description: Remove an SCB from the head of the list.
\r
6379 +static inline struct pti_st_scb *
\r
6380 +scbq_remove_head(struct pti_st_host *p, volatile scb_queue_type *queue)
\r
6382 + struct pti_st_scb * scbp;
\r
6385 + scbp = queue->head;
\r
6386 + if (queue->head != NULL)
\r
6387 + queue->head = queue->head->q_next;
\r
6388 + if (queue->head == NULL) /* If list is now empty, update tail. */
\r
6389 + queue->tail = NULL;
\r
6395 + * Function: scbq_remove(volatile scb_queue_type, struct pti_st_scb)
\r
6396 + * Description: Removes an SCB from the list.
\r
6398 +static inline void
\r
6399 +scbq_remove(struct pti_st_host *p, volatile scb_queue_type *queue, struct pti_st_scb *scb)
\r
6401 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
\r
6402 + unsigned long cpu_flags;
\r
6406 + if (queue->head == scb)
\r
6408 + /* At beginning of queue, remove from head. */
\r
6409 + scbq_remove_head(p, queue);
\r
6413 + struct pti_st_scb *curscb = queue->head;
\r
6416 + * Search until the next scb is the one we're looking for, or
\r
6417 + * we run out of queue.
\r
6419 + while ((curscb != NULL) && (curscb->q_next != scb))
\r
6421 + curscb = curscb->q_next;
\r
6423 + if (curscb != NULL)
\r
6426 + curscb->q_next = scb->q_next;
\r
6427 + if (scb->q_next == NULL)
\r
6429 + /* Update the tail when removing the tail. */
\r
6430 + queue->tail = curscb;
\r
6438 + * Function: scbq_insert_tail(volatile scb_queue_type, struct pti_st_scb)
\r
6439 + * Description: Add an SCB at the tail of the list.
\r
6441 +static inline void
\r
6442 +scbq_insert_tail(struct pti_st_host *p, volatile scb_queue_type *queue, struct pti_st_scb *scb)
\r
6444 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
\r
6445 + unsigned long cpu_flags;
\r
6449 + scb->q_next = NULL;
\r
6450 + if (queue->tail != NULL) /* Add the scb at the end of the list. */
\r
6451 + queue->tail->q_next = scb;
\r
6452 + queue->tail = scb; /* Update the tail. */
\r
6453 + if (queue->head == NULL) /* If list was empty, update head. */
\r
6454 + queue->head = queue->tail;
\r
6459 + * Function: pti_st_allocate_scb(struct pti_st_host *, struct pti_st_scb *)
\r
6460 + * Description: Free the scb and insert into the free scb list.
\r
6463 +pti_st_allocate_scb(struct pti_st_host *p)
\r
6465 + struct pti_st_scb *scbp = NULL;
\r
6466 + int scb_size = sizeof(struct pti_st_scb);
\r
6468 + unsigned long scb_count = 0;
\r
6469 + struct pti_st_scb *scb_ap;
\r
6471 + scb_count = p->scb_data->maxscbs;
\r
6472 + scb_ap = (struct pti_st_scb *)kmalloc(scb_size * scb_count, GFP_ATOMIC);
\r
6473 + if (scb_ap != NULL)
\r
6475 + memset(scb_ap, 0, scb_count * scb_size);
\r
6476 + for (i=0; i < scb_count; i++)
\r
6478 + scbp = &scb_ap[i];
\r
6479 + scbp->mf = NULL;
\r
6483 + * Place in the scb array; never is removed
\r
6485 + p->scb_data->scb_array[i] = scbp;
\r
6486 + scbq_insert_head(p, &p->scb_data->free_scbs, scbp);
\r
6488 + scbp->kmalloc_ptr = scb_ap;
\r
6494 + return(scb_count);
\r
6498 + * Function: pti_st_queue_cmd_complete(struct pti_st_host *, Scsi_Cmnd *)
\r
6499 + * Description: Due to race conditions present in the SCSI subsystem, it is
\r
6500 + * easier to queue completed commands, then call scsi_done() on
\r
6501 + * them when we're finished.
\r
6502 + * This function queues the completed commands.
\r
6505 +pti_st_queue_cmd_complete(struct pti_st_host *p, Scsi_Cmnd *cmd)
\r
6507 + cmd->host_scribble = (char *)p->completeq.head;
\r
6508 + p->completeq.head = cmd;
\r
6512 + * Function: pti_st_done_cmds_complete(struct pti_st_host *)
\r
6513 + * Description: Process the completed command queue.
\r
6516 +pti_st_done_cmds_complete(struct pti_st_host *p)
\r
6520 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
\r
6521 + unsigned int cpu_flags = 0;
\r
6524 + while (p->completeq.head != NULL)
\r
6526 + cmd = p->completeq.head;
\r
6527 + p->completeq.head = (Scsi_Cmnd *)cmd->host_scribble;
\r
6528 + cmd->host_scribble = NULL;
\r
6530 + cmd->scsi_done(cmd);
\r
6537 + while (p->completeq.head != NULL)
\r
6539 + cmd = p->completeq.head;
\r
6540 + p->completeq.head = (Scsi_Cmnd *)cmd->host_scribble;
\r
6541 + cmd->host_scribble = NULL;
\r
6542 + cmd->scsi_done(cmd);
\r
6549 + * Function: pti_st_free_scb(struct pti_st_host *, struct pti_st_scb *)
\r
6550 + * Description: Free the scb and insert into the free scb list.
\r
6553 +pti_st_free_scb(struct pti_st_host *p, struct pti_st_scb *scb)
\r
6556 + scb->flags = SCB_FREE;
\r
6557 + scb->cmd = NULL;
\r
6558 + scb->sg_count = 0;
\r
6559 + scb->sg_length = 0;
\r
6561 +// scb->mf->target_channel_lun = SCB_LIST_NULL;
\r
6563 + scbq_insert_head(p, &p->scb_data->free_scbs, scb);
\r
6567 + * Function: pti_st_done(struct pti_st_host *, struct pti_st_scb *)
\r
6568 + * Description: Calls the higher level scsi done function and frees the scb.
\r
6571 +pti_st_done(struct pti_st_host *p, struct pti_st_scb *scb)
\r
6573 + Scsi_Cmnd *cmd = scb->cmd;
\r
6575 + if (scb->flags & SCB_RESET)
\r
6577 + cmd->result = (DID_RESET << 16) | (cmd->result & 0xffff);
\r
6579 + else if (scb->flags & SCB_ABORT)
\r
6581 + cmd->result = (DID_RESET << 16) | (cmd->result & 0xffff);
\r
6584 + pti_st_free_scb(p, scb);
\r
6585 + pti_st_queue_cmd_complete(p, cmd);
\r
6589 + * Function: pti_st_run_done_queue(struct pti_st_host *, int)
\r
6590 + * Description: Calls the pti_st_done() for the Scsi_Cmnd of each scb in the
\r
6591 + * aborted list, and adds each scb to the free list. If complete
\r
6592 + * is TRUE, we also process the commands complete list.
\r
6595 +pti_st_run_done_queue(struct pti_st_host *p, int complete)
\r
6597 + struct pti_st_scb *scb;
\r
6600 + for (i = 0; i < p->scb_data->maxscbs; i++)
\r
6602 + scb = p->scb_data->scb_array[i];
\r
6603 + if (scb->flags & SCB_QUEUED_FOR_DONE)
\r
6604 + pti_st_done(p, scb);
\r
6608 + pti_st_done_cmds_complete(p);
\r
6613 + * Function: pti_st_isr(int, void, struct pt_regs)
\r
6614 + * Description: i960 controller interrupt handler.
\r
6617 +pti_st_isr(int irq, void *dev_id, struct pt_regs *regs)
\r
6619 + volatile U32 phyAddrMsg = 0xffffffff;
\r
6622 + struct pti_st_host *p;
\r
6623 + struct pti_st_scb *scbp;
\r
6624 + PI2O_BSA_REPLY_MESSAGE_FRAME rmfp = NULL;
\r
6625 + int testtime = 0;
\r
6629 + p = (struct pti_st_host *)dev_id;
\r
6633 + for(i = 0; i < MAX_ADAPTORS; i++)
\r
6634 + if(pti_st_hostp[i] == p)
\r
6637 + if(i >= MAX_ADAPTORS || !p->p_atu)
\r
6640 + phyAddrMsg = p->p_atu->OutQueue;
\r
6644 + for(testtime = 1;
\r
6645 + (phyAddrMsg == 0xffffffff) && (testtime < 3);
\r
6648 + phyAddrMsg = p->p_atu->OutQueue;
\r
6651 + if(phyAddrMsg == 0xffffffff) {
\r
6655 + rmfp = (PI2O_BSA_REPLY_MESSAGE_FRAME)(bus_to_virt(phyAddrMsg));
\r
6657 + scb_index = rmfp->StdMessageFrame.InitiatorContext;
\r
6658 + // we handle ioctl scsi command here, the command is sent by the
\r
6659 + // InitiatorContext of standard message frame, we send the message
\r
6660 + // in pti_st_send_private_message_code_cmd function.
\r
6661 + tmp = rmfp->TransactionContext;
\r
6662 + if(scb_index == 0xfd && tmp ){
\r
6663 + cmd = (Scsi_Cmnd *)tmp;
\r
6664 + if(cmd->scsi_done && cmd->cmnd[0] == 0xfd){
\r
6665 + cmd->scsi_done(cmd);
\r
6668 + printk("cmd->scsi_done is NULL in pti_st_isr.\n");
\r
6670 + /* return MFA to outbound free Q*/
\r
6671 + p->p_atu->OutQueue = phyAddrMsg;
\r
6672 + /* any more msgs? */
\r
6673 + phyAddrMsg = p->p_atu->OutQueue;
\r
6676 + ///////////////////////////////////////
\r
6677 + scbp = p->scb_data->scb_array[scb_index];
\r
6680 + /* return MFA to outbound free Q*/
\r
6681 + p->p_atu->OutQueue = phyAddrMsg;
\r
6683 + /* any more msgs? */
\r
6684 + phyAddrMsg = p->p_atu->OutQueue;
\r
6688 + cmd = scbp->cmd;
\r
6690 + //printk("return cmd= 0x%x, mfp= 0x%x, sno= 0x%x tag= 0x%x ind= 0x%x scb= 0x%x\n",
\r
6691 + // cmd, rmfp, cmd->serial_number, scbp->tag, scb_index, scbp);
\r
6692 + if (cmd->serial_number != rmfp->TransactionContext)
\r
6694 + printk("Error in cmd%2x, mismatch sn 0x%x, mfp 0x%x scbi= %x\n",
\r
6695 + cmd->cmnd[0], (int)cmd->serial_number,
\r
6696 + (int)rmfp->TransactionContext,
\r
6697 + (int)scb_index);
\r
6698 + /* return MFA to outbound free Q*/
\r
6699 + p->p_atu->OutQueue = phyAddrMsg;
\r
6701 + /* any more msgs? */
\r
6702 + phyAddrMsg = p->p_atu->OutQueue;
\r
6706 + if (rmfp->ReqStatus != I2O_REPLY_STATUS_SUCCESS) {
\r
6707 + cmd->result = DID_ERROR;
\r
6708 +#if defined(DEBUG)
\r
6709 + printk("pti_st_isr: Reply Status Fail, ReqStatus[%x], DetailedStatus[%x]\n", rmfp->ReqStatus, rmfp->DetailedStatusCode);
\r
6713 + pti_st_free_scb(p, scbp);
\r
6714 + pti_st_queue_cmd_complete(p, cmd);
\r
6715 + /* return MFA to outbound free Q*/
\r
6716 + p->p_atu->OutQueue = phyAddrMsg;
\r
6718 + /* any more msgs? */
\r
6719 + phyAddrMsg = p->p_atu->OutQueue;
\r
6726 + * Function: do_pti_st_isr(int, void *, struct pt_regs *)
\r
6728 + * This is a gross hack to solve a problem in linux kernels 2.1.85 and
\r
6729 + * above. Please, children, do not try this at home, and if you ever see
\r
6730 + * anything like it, please inform the Gross Hack Police immediately
\r
6732 +void do_pti_st_isr( int irq, void *dev_id, struct pt_regs * regs )
\r
6734 + unsigned long cpu_flags = 0;
\r
6735 + struct pti_st_host *p;
\r
6739 + p = (struct pti_st_host *)dev_id;
\r
6743 + for(i = 0; i < MAX_ADAPTORS; i++)
\r
6744 + if(p == pti_st_hostp[i])
\r
6747 + if(i >= MAX_ADAPTORS)
\r
6750 + OutIntStat = p->p_atu->OutIntStat;
\r
6752 + if (OutIntStat==0)
\r
6755 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,95)
\r
6756 + if(test_and_set_bit(PSTC_IN_ISR_BIT, &p->flags))
\r
6760 + spin_lock_irqsave(&io_request_lock, cpu_flags);
\r
6761 + pti_st_isr(irq, dev_id, regs);
\r
6762 + pti_st_done_cmds_complete(p);
\r
6763 + clear_bit(PSTC_IN_ISR_BIT, &p->flags);
\r
6764 + spin_unlock_irqrestore(&io_request_lock, cpu_flags);
\r
6766 + if(set_bit(PSTC_IN_ISR_BIT, (int *)&p->flags))
\r
6771 + pti_st_isr(irq, dev_id, regs);
\r
6773 + pti_st_done_cmds_complete(p);
\r
6774 + clear_bit(PSTC_IN_ISR_BIT, (int *)&p->flags);
\r
6779 + * Function: pti_st_register(Scsi_Host_Template *, struct pti_st_host *)
\r
6780 + * Description: Register i960 controller with the kernel.
\r
6783 +pti_st_register(Scsi_Host_Template *template, struct pti_st_host *p)
\r
6786 + struct Scsi_Host *host;
\r
6790 + p->scb_data->maxscbs = PTI_ST_MAXSCB;
\r
6793 + * On some new SMP motherboard, there are some problem when huge
\r
6794 + * data are readed/written, so we should reduce the limit of request
\r
6798 + host->can_queue = PTI_ST_MAXSCB;
\r
6800 +// host->can_queue = 16;
\r
6801 + host->can_queue = 12;
\r
6804 + host->cmd_per_lun = 3;
\r
6805 + host->sg_tablesize = PTI_ST_MAX_SG;
\r
6806 + host->this_id = p->scsi_id;
\r
6807 + host->irq = p->pci_irq;
\r
6810 + p->host_no = host->host_no;
\r
6811 + p->completeq.head = NULL;
\r
6812 + p->completeq.tail = NULL;
\r
6815 + * Initialize the Super Track hardware controler, procedure as the
\r
6816 + * typical system initialization of I2O
\r
6818 + p->maddr = ioremap(p->mbase, 4*1024*1024);
\r
6821 + p->pci_irq = 0;
\r
6825 + p->p_atu = (PATU)p->maddr;
\r
6826 + p->LinBaseAddr = (PU8)p->maddr;
\r
6828 + p->outboundBufferp = (outboundBuff_t *)kmalloc((16*1024+256+32*32*4), GFP_ATOMIC);
\r
6829 + if(p->outboundBufferp == NULL) {
\r
6831 + printk("Allocating buffer fails!\n");
\r
6834 + p->replyBufferp = (PU8)((PU8)p->outboundBufferp + 32*32*4);
\r
6835 + p->messageBufferp = p->replyBufferp + (16*1024);
\r
6837 + p->outMsgBlockPhyAddr = virt_to_bus(p->outboundBufferp);
\r
6838 + p->pLinOutMsgBlock = (PU8)(p->outboundBufferp);
\r
6841 + * Allocate the set of scbs for this controller. This is to stream-
\r
6842 + * line code elsewhere in the driver. If we have to check for the existence
\r
6843 + * of scbs in certain code sections, it slows things down. However, as
\r
6844 + * soon as we register the IRQ for this card, we could get an interrupt that
\r
6845 + * includes possibly the SCSI_RSTI interrupt. If we catch that interrupt
\r
6846 + * then we are likely to segfault if we don't have at least one chunk of
\r
6847 + * SCBs allocated or add checks all through the reset code to make sure
\r
6848 + * that the SCBs have been allocated which is an invalid running condition
\r
6849 + * and therefore I think it's preferable to simply pre-allocate the first
\r
6850 + * chunk of SCBs.
\r
6853 + result = pti_st_allocate_scb(p);
\r
6857 + printk("Allocating scbs fails!\n");
\r
6862 + * Disable interrupt
\r
6864 + p->p_atu->OutIntMask = 0xffffffff;
\r
6866 + if(!IOP_init(p))
\r
6873 + * Clear out any possible pending interrupts, again.
\r
6875 + /* pti_st_clear_intstat(p); */
\r
6878 + * Register IRQ with the kernel. Only allow sharing IRQs with
\r
6881 + result = (request_irq(p->pci_irq, do_pti_st_isr, SA_SHIRQ, "pti_st", p));
\r
6884 + result = (request_irq(p->pci_irq, do_pti_st_isr,
\r
6885 + (SA_INTERRUPT | SA_SHIRQ), "pti_st", p));
\r
6890 + printk(KERN_WARNING "(scsi%d) Couldn't register IRQ %d, ignoring "
\r
6891 + "controller.\n", p->host_no, p->pci_irq);
\r
6896 + * Enable interrupt
\r
6898 + p->p_atu->OutIntMask = 0x00000000;
\r
6901 + host->max_id = MAX_ARRAYS;
\r
6902 + host->max_channel = 0;
\r
6903 + host->max_lun = p->max_lun = 1;
\r
6909 + * Function: pti_st_free(struct pti_st_host *)
\r
6910 + * Description: Frees and releases all resources associated with an instance of
\r
6911 + * the driver (struct pti_st_host *).
\r
6914 +pti_st_free(struct pti_st_host *p)
\r
6918 + if (p->scb_data != NULL)
\r
6922 + * Free the driver SCBs. These were allocated on an as-need
\r
6923 + * basis. We allocated these in groups depending on how many
\r
6924 + * we could fit into a given amount of RAM. The tail SCB for
\r
6925 + * these allocations has a pointer to the alloced area.
\r
6927 + for (i = 0; i < p->scb_data->maxscbs; i++)
\r
6929 + if (p->scb_data->scb_array[i]->kmalloc_ptr != NULL)
\r
6930 + kfree(p->scb_data->scb_array[i]->kmalloc_ptr);
\r
6931 + p->scb_data->scb_array[i] = NULL;
\r
6935 + * Free the SCB data area.
\r
6937 + kfree(p->scb_data);
\r
6942 + * Function: pti_st_release(struct Scsi_Host *)
\r
6943 + * Description: Free the passed in Scsi_Host memory structures prior to
\r
6944 + * unloading the module.
\r
6947 +pti_st_release(struct Scsi_Host *host)
\r
6949 + struct pti_st_host *p = (struct pti_st_host *) host->hostdata;
\r
6952 + for(i = 0; i < MAX_ADAPTORS; i++)
\r
6953 + if(p == pti_st_hostp[i])
\r
6956 + if(!p || i >= MAX_ADAPTORS)
\r
6959 + if(p->pci_irq) {
\r
6960 + free_irq(p->pci_irq, p);
\r
6963 + * Disbale interrupt
\r
6965 + p->p_atu->OutIntMask = 0x000000fc;
\r
6969 + iounmap((void *) (((unsigned long) p->maddr)));
\r
6972 + if(p->outboundBufferp) {
\r
6973 + kfree(p->outboundBufferp);
\r
6974 + p->outboundBufferp = NULL;
\r
6976 + if(p->pti_stdev_bufferp) {
\r
6977 + kfree(p->pti_stdev_bufferp);
\r
6978 + p->pti_stdev_bufferp = NULL;
\r
6981 + pti_st_hostp[i] = NULL;
\r
6986 + * Function: pti_st_alloc(Scsi_Host_Template *, struct pti_st_host *)
\r
6987 + * Description: Allocate and initialize a host structure.
\r
6988 + * Returns NULL upon error and a pointer to a pti_st_host struct
\r
6991 +static struct pti_st_host *
\r
6992 +pti_st_alloc(Scsi_Host_Template *sht, struct pti_st_host *temp)
\r
6994 + struct pti_st_host *p = NULL;
\r
6995 + struct Scsi_Host *host;
\r
6998 + * Allocate a storage area by registering us with the mid-level
\r
7001 + host = scsi_register(sht, sizeof(struct pti_st_host));
\r
7003 + if (host != NULL)
\r
7005 + p = (struct pti_st_host *) host->hostdata;
\r
7006 + memset(p, 0, sizeof(struct pti_st_host));
\r
7009 + p->scsi_id = -1;
\r
7010 + p->host_no = host->host_no;
\r
7011 + p->scb_data = kmalloc(sizeof(scb_data_type), GFP_ATOMIC);
\r
7012 + if (p->scb_data != NULL)
\r
7014 + memset(p->scb_data, 0, sizeof(scb_data_type));
\r
7015 + scbq_init (&p->scb_data->free_scbs);
\r
7020 + * For some reason we don't have enough memory. Free the
\r
7021 + * allocated memory for the pti_st_host struct, and return NULL.
\r
7023 + scsi_unregister(host);
\r
7026 + p->pti_stdev_bufferp = kmalloc(sizeof(PTI_STDEV_INBUFFER), GFP_ATOMIC);
\r
7027 + if(p->pti_stdev_bufferp != NULL)
\r
7029 + memset(p->pti_stdev_bufferp, 0, sizeof(PTI_STDEV_INBUFFER));
\r
7031 + scsi_unregister(host);
\r
7040 + * Function: pti_st_detect(Scsi_Host_Template *)
\r
7041 + * Description: Try to detect and register i960 controller.
\r
7042 + * This should really be called pti_st_probe(). A sequence of
\r
7043 + * probe(), attach()/detach(), and init() makes more sense than
\r
7044 + * one do-it-all function. This may be useful when (and if) the
\r
7045 + * mid-level SCSI code is overhauled.
\r
7047 +int pti_st_detect(Scsi_Host_Template *template)
\r
7049 + struct pci_dev *pdev;
\r
7052 + if (!pci_present())
\r
7055 + // printk("pti_st.c: PCI bios is present, checking for devices ...\n");
\r
7057 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
\r
7058 + pci_for_each_dev(pdev)
\r
7060 + for(pdev = pci_devices, found = 0;
\r
7061 + found < MAX_ADAPTORS && pdev != NULL;
\r
7062 + pdev = pdev->next)
\r
7065 + if(pdev->vendor != PCI_VENDOR_ID_INTEL ||
\r
7066 + (pdev->device != PCI_DEVICE_ID_INTEL_i960 && /* ST100 */
\r
7067 + pdev->device != PCI_DEVICE_ID_INTEL_i962)) /* ST100SX6 */
\r
7070 + pti_st_install(template, pdev, &found);
\r
7076 +static int pti_st_install(Scsi_Host_Template *template, struct pci_dev *pdev, int *aptno)
\r
7078 + struct pti_st_host *p = NULL;
\r
7079 + struct pti_st_host *temp_p = NULL;
\r
7080 + unsigned short command;
\r
7081 + unsigned long cmd;
\r
7082 + unsigned long devicenumber, functionnumber;
\r
7084 + devicenumber = PCI_SLOT(pdev->devfn);
\r
7085 + functionnumber = 0;
\r
7088 + * Expose the ship behind i960 for initialization, or it will failed
\r
7091 + PTI_ST_SetBusDataByOffset(pdev->bus->number,
\r
7098 + template->sg_tablesize = PTI_ST_MAX_SG;
\r
7099 + template->proc_dir = &proc_scsi_pti_st;
\r
7100 + template->proc_info = PTI_procfile_read;
\r
7101 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
\r
7102 + if(!template->proc_name) {
\r
7103 + if(template->name)
\r
7104 + template->proc_name = (char *)template->name;
\r
7106 + template->proc_name = "pti_st";
\r
7110 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
\r
7111 + pci_enable_device(pdev);
\r
7114 + if ( !(temp_p = kmalloc(sizeof(struct pti_st_host), GFP_ATOMIC)))
\r
7116 + printk("pti_st_host data structure memory alloc error!!!\n");
\r
7118 + PTI_ST_SetBusDataByOffset(pdev->bus->number,
\r
7126 + memset(temp_p, 0, sizeof(struct pti_st_host));
\r
7128 + temp_p->pci_irq = pdev->irq;
\r
7129 + temp_p->pdev = pdev;
\r
7130 + temp_p->pci_bus = pdev->bus->number;
\r
7131 + temp_p->pci_device_fn = pdev->devfn;
\r
7132 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
\r
7133 + temp_p->mbase = pci_resource_start(pdev, 0);
\r
7134 + template->name = "pti_st";
\r
7136 + temp_p->mbase = pdev->base_address[0];
\r
7138 + pci_read_config_word(pdev, PCI_COMMAND, &command);
\r
7140 + command |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
\r
7141 + pci_write_config_word(pdev, PCI_COMMAND, command);
\r
7143 + temp_p->mbase &= PCI_BASE_ADDRESS_MEM_MASK;
\r
7145 + printk("Found PTI SuperTrak at mbase: %#x, irq %d.\n",
\r
7146 + temp_p->mbase, temp_p->pci_irq);
\r
7148 + pti_st_hostp[*aptno] = p = pti_st_alloc(template, temp_p);
\r
7152 + DRIVER_LOCK_INIT
\r
7154 + if (!pti_st_register(template, p))
\r
7156 + pti_st_release(p->host);
\r
7157 + scsi_unregister(p->host);
\r
7159 + pti_st_hostp[*aptno] = NULL;
\r
7164 + PTI_ST_SetBusDataByOffset(pdev->bus->number,
\r
7172 + return (*aptno);
\r
7176 + * Function: pti_st_copy_internal_data(Scsi_Cmnd *, char *, unsigned short)
\r
7177 + * Description: Queue a SCB to the controller.
\r
7180 +pti_st_copy_internal_data(Scsi_Cmnd *scp, char *buffer, unsigned short count)
\r
7182 + unsigned short cpcount,i;
\r
7183 + unsigned short cpsum,cpnow;
\r
7184 + struct scatterlist *sl;
\r
7186 + cpcount = count<=(ushort)scp->bufflen ? count:(ushort)scp->bufflen;
\r
7187 + if (scp->use_sg)
\r
7189 + sl = (struct scatterlist *)scp->request_buffer;
\r
7190 + for (i=0,cpsum=0; i<scp->use_sg; ++i,++sl)
\r
7192 + cpnow = (ushort)sl->length;
\r
7193 + if (cpsum+cpnow > cpcount)
\r
7194 + cpnow = cpcount - cpsum;
\r
7196 + memcpy((char*)sl->address,buffer,cpnow);
\r
7197 + if (cpsum == cpcount)
\r
7199 + buffer += cpnow;
\r
7204 + memcpy((char*)scp->request_buffer,buffer,cpcount);
\r
7209 + * Function: pti_st_rw_cmd(Scsi_Cmnd *, void (*fn)(Scsi_Cmnd *)) * Description: Translate Scsi Command to I2O Message Frame.
\r
7212 +pti_st_rw_cmd(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *))
\r
7214 + struct pti_st_host *p;
\r
7215 + struct pti_st_scb *scb;
\r
7216 + unsigned long msgoffset;
\r
7217 + unsigned long blk_nr = 0;
\r
7218 + unsigned long blk_count = 0;
\r
7219 + PI2O_BSA_RW_MESSAGE mfp;
\r
7220 + unsigned char *cmnd;
\r
7221 + unsigned long pBaseAddrReg;
\r
7223 + unsigned long cpuflags;
\r
7225 + p = (struct pti_st_host *) cmd->host->hostdata;
\r
7227 + for(i = 0; i < MAX_ADAPTORS; i++)
\r
7228 + if(p == pti_st_hostp[i])
\r
7231 + if(i >= MAX_ADAPTORS || !p) {
\r
7232 + cmd->result = (DID_BAD_TARGET << 16);
\r
7237 + scb = scbq_remove_head(p, &p->scb_data->free_scbs);
\r
7239 + if (scb == NULL)
\r
7241 + cmd->result = (DID_BUS_BUSY << 16);
\r
7242 + printk(WARN_LEAD"Couldn't get a free SCB.\n", p->host_no,
\r
7243 + CTL_OF_CMD(cmd));
\r
7248 + if (cmd->target >= MAX_DRIVES || p->I2ODisk[cmd->target].present != TRUE)
\r
7250 + cmd->result = (DID_BAD_TARGET << 16);
\r
7255 + spin_lock_irqsave(&p->spin_lock, cpuflags);
\r
7257 + pBaseAddrReg = (U32)p->maddr;
\r
7258 + msgoffset = * (U32 *)(pBaseAddrReg+INBOUNDQPORT);
\r
7259 + if (msgoffset == 0xFFFFFFFF)
\r
7261 + printk(INFO_LEAD"Couldn't get a free MF from inboundqport.\n",
\r
7262 + p->host_no, CTL_OF_CMD(cmd));
\r
7263 + cmd->result = (DID_BUS_BUSY << 16);
\r
7264 + spin_unlock_irqrestore(&p->spin_lock, cpuflags);
\r
7265 + scbq_insert_head(p, &p->scb_data->free_scbs, scb);
\r
7270 + pti_st_position(cmd) = scb->tag;
\r
7272 + p->scb_data->scb_array[scb->tag] = scb;
\r
7275 + * Make sure the Scsi_Cmnd pointer is saved, the struct it points to
\r
7276 + * is set up properly, and the parity error flag is reset, then send
\r
7277 + * the SCB to the sequencer and watch the fun begin.
\r
7279 + cmd->scsi_done = fn;
\r
7280 + cmd->result = DID_OK;
\r
7281 + memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
\r
7282 + cmd->host_scribble = NULL;
\r
7284 + scb->flags |= SCB_ACTIVE;
\r
7285 + mfp = (PI2O_BSA_RW_MESSAGE)(pBaseAddrReg + msgoffset);
\r
7286 + memset((char *)mfp, 0, sizeof(I2O_BSA_READ_MESSAGE));
\r
7287 + cmnd = (unsigned char *)cmd->cmnd;
\r
7292 + blk_nr = cmnd[3] + (cmnd[2] << 8) + ((cmnd[1] & 0x1f) << 16);
\r
7293 + blk_count = cmnd[4];
\r
7295 + mfp->StdMessageFrame.Function = I2O_BSA_BLOCK_READ;
\r
7296 + mfp->FetchAhead = 0;
\r
7301 + blk_nr = ntohl(*(PU32)&cmnd[2]);
\r
7302 + blk_count = cmnd[8] + (cmnd[7] << 8);
\r
7304 + mfp->StdMessageFrame.Function = I2O_BSA_BLOCK_READ;
\r
7305 + mfp->FetchAhead = 0;
\r
7310 + blk_nr = cmnd[3] + (cmnd[2] << 8) + ((cmnd[1] & 0x1f) << 16);
\r
7311 + blk_count = cmnd[4];
\r
7313 + mfp->StdMessageFrame.Function = I2O_BSA_BLOCK_WRITE;
\r
7318 + blk_nr = ntohl(*(PU32)&cmnd[2]);
\r
7319 + blk_count = cmnd[8] + (cmnd[7] << 8);
\r
7321 + mfp->StdMessageFrame.Function = I2O_BSA_BLOCK_WRITE;
\r
7324 + mfp->LogicalByteAddress.HighPart = blk_nr >> (32 - 9);
\r
7325 + mfp->LogicalByteAddress.LowPart = blk_nr << 9;
\r
7326 + mfp->TransferByteCount = blk_count << 9;
\r
7327 + mfp->TransactionContext = cmd->serial_number;
\r
7328 + mfp->StdMessageFrame.InitiatorContext = scb->tag;
\r
7329 + mfp->StdMessageFrame.VersionOffset=0x81;
\r
7330 + mfp->StdMessageFrame.MsgFlags=0;
\r
7331 + mfp->StdMessageFrame.MessageSize=sizeof(I2O_BSA_READ_MESSAGE)>>2;
\r
7332 + mfp->StdMessageFrame.TargetAddress=p->I2ODisk[cmd->target].LocalTID;
\r
7333 + mfp->StdMessageFrame.InitiatorAddress = 0x01;
\r
7334 + mfp->ControlFlags = 0;
\r
7335 + mfp->TimeMultiplier = 0x31; /*0;*/
\r
7338 + //printk("Issue cmd= %x, mfp 0x%x, sno= 0x%x tag= 0x%x scb=0x%x\n",
\r
7339 + // cmd, mfp, cmd->serial_number, scb->tag, scb);
\r
7342 + * The interpretation of request_buffer and request_bufflen
\r
7343 + * changes depending on whether or not use_sg is zero; a
\r
7344 + * non-zero use_sg indicates the number of elements in the
\r
7345 + * scatter-gather array.
\r
7348 + if (cmd->use_sg)
\r
7350 + struct scatterlist *sg; /* Must be mid-level SCSI code scatterlist */
\r
7353 + * We must build an SG list in I2O SGL format, as the kernel's SG list
\r
7354 + * cannot be used directly
\r
7358 + sg = (struct scatterlist *)cmd->request_buffer;
\r
7360 + * Copy the segments into the SG array. NOTE!!! - We used to
\r
7361 + * have the first entry both in the data_pointer area and the first
\r
7362 + * SG element. That has changed somewhat. We still have the first
\r
7363 + * entry in both places, but now we download the address of
\r
7364 + * scb->sg_list[1] instead of 0 to the sg pointer in the mf.
\r
7366 + for (i = 0; i < (cmd->use_sg); i++)
\r
7368 + mfp->SGL.u.Simple[i].FlagsCount.Count = cpu_to_le32(sg[i].length);
\r
7369 + mfp->SGL.u.Simple[i].FlagsCount.Flags =
\r
7370 + (I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT);
\r
7371 + mfp->SGL.u.Simple[i].PhysicalAddress =
\r
7372 + cpu_to_le32(VIRT_TO_BUS(sg[i].address));
\r
7374 + mfp->SGL.u.Simple[cmd->use_sg - 1].FlagsCount.Flags |=
\r
7375 + ( I2O_SGL_FLAGS_LAST_ELEMENT |
\r
7376 + I2O_SGL_FLAGS_END_OF_BUFFER);
\r
7380 + mfp->SGL.u.Simple[0].FlagsCount.Count =
\r
7381 + cpu_to_le32(cmd->request_bufflen);
\r
7382 + mfp->SGL.u.Simple[0].FlagsCount.Flags =
\r
7383 + ( I2O_SGL_FLAGS_LAST_ELEMENT |
\r
7384 + I2O_SGL_FLAGS_END_OF_BUFFER |
\r
7385 + I2O_SGL_FLAGS_TRANSPORT_ELEMENT |
\r
7386 + I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT);
\r
7387 + mfp->SGL.u.Simple[0].PhysicalAddress =
\r
7388 + cpu_to_le32(VIRT_TO_BUS(cmd->request_buffer));
\r
7391 + * (U32 *)(pBaseAddrReg+INBOUNDQPORT) = msgoffset;
\r
7393 + spin_unlock_irqrestore(&p->spin_lock, cpuflags);
\r
7399 + * Function: pti_st_internal_cmd(Scsi_Cmnd *, void (*fn)(Scsi_Cmnd *))
\r
7400 + * Description: Excuting TEST_UNIT_READY, INQUIRY, READ_CAPACITY, etc.
\r
7404 +pti_st_internal_cmd(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *))
\r
7406 + struct pti_st_host *p;
\r
7408 + // struct pti_st_scb *scb;
\r
7409 + // unsigned long cpu_flags = 0;
\r
7410 + pti_inq_data inq;
\r
7411 + pti_rdcap_data rdc;
\r
7414 + p = (struct pti_st_host *) cmd->host->hostdata;
\r
7416 + for(i = 0; i < MAX_ADAPTORS; i++)
\r
7417 + if(p == pti_st_hostp[i])
\r
7420 + if(i >= MAX_ADAPTORS) {
\r
7421 + cmd->result = (DID_BAD_TARGET << 16);
\r
7426 + switch (cmd->cmnd[0])
\r
7428 + case TEST_UNIT_READY:
\r
7429 + cmd->result = DID_OK << 16;
\r
7433 + memset((void *)&inq, 0, sizeof(inq));
\r
7434 + inq.type_qual = TYPE_DISK;
\r
7436 + * you can here set all disks to removable, if you want to do
\r
7437 + * a flush using the ALLOW_MEDIUM_REMOVAL command
\r
7439 + inq.modif_rmb = 0x00;
\r
7440 + inq.version = 2;
\r
7441 + inq.resp_aenc = 2;
\r
7442 + inq.add_length= 32;
\r
7443 + strcpy(inq.vendor,"PTI ");
\r
7444 + strcpy(inq.product,"SuperTrak");
\r
7445 + strcpy(inq.revision," ");
\r
7446 + if(cmd->target < MAX_DRIVES && p->I2ODisk[cmd->target].present == TRUE)
\r
7448 + pti_st_copy_internal_data(cmd,(char*)&inq, sizeof(pti_inq_data));
\r
7449 + cmd->result = DID_OK << 16;
\r
7451 + pti_st_copy_internal_data(cmd,(char*)&inq, sizeof(pti_inq_data));
\r
7452 + cmd->result = DID_BAD_TARGET << 16;
\r
7457 + case REQUEST_SENSE:
\r
7458 + sd.errorcode = 0x70;
\r
7459 + sd.segno = 0x00;
\r
7460 + sd.key = NO_SENSE;
\r
7462 + sd.add_length= 0;
\r
7463 + pti_copy_internal_data(scp,(char*)&sd,sizeof(gdth_sense_data));
\r
7464 + cmd->result = DID_OK << 16;
\r
7466 + case MODE_SENSE:
\r
7467 + memset((char*)&mpd,0,sizeof(gdth_modep_data));
\r
7468 + mpd.hd.data_length = sizeof(gdth_modep_data);
\r
7469 + mpd.hd.dev_par = (ha->id[b][t].devtype&2) ? 0x80:0;
\r
7470 + mpd.hd.bd_length = sizeof(mpd.bd);
\r
7471 + mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16;
\r
7472 + mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8;
\r
7473 + mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff);
\r
7474 + pti_copy_internal_data(scp,(char*)&mpd,sizeof(gdth_modep_data));
\r
7475 + cmd->result = DID_OK << 16;
\r
7479 + case READ_CAPACITY:
\r
7480 + if(cmd->target < MAX_DRIVES && p->I2ODisk[cmd->target].present)
\r
7482 + rdc.last_block_no = ntohl(p->I2ODisk[cmd->target].lastLBA);
\r
7483 + rdc.block_length = ntohl(SECTOR_SIZE);
\r
7484 + pti_st_copy_internal_data(cmd,(char*)&rdc, sizeof(pti_rdcap_data));
\r
7485 + cmd->result = DID_OK << 16;
\r
7487 + cmd->result = DID_BAD_TARGET;
\r
7492 + printk("!!!!!!!!PTI: Unknown SCSI command 0x%x to cache service !\n",
\r
7494 + cmd->result = DID_ABORT << 16;
\r
7503 + * Function: pti_st_queue(Scsi_Cmnd *, void (*fn)(Scsi_Cmnd *))
\r
7504 + * Description: Queue a SCB to the controller.
\r
7507 +pti_st_queue(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *))
\r
7511 + switch (cmd->cmnd[0])
\r
7518 + ret = pti_st_rw_cmd(cmd, fn);
\r
7520 + case TEST_UNIT_READY:
\r
7522 + case READ_CAPACITY:
\r
7523 + return(pti_st_internal_cmd(cmd, fn));
\r
7525 +// case START_STOP:
\r
7526 +// case REQUEST_SENSE:
\r
7527 +// case MODE_SENSE:
\r
7532 + printk("PTI: Unknown SCSI command 0x%x to cache service!\n", cmd->cmnd[0]);
\r
7533 + cmd->result = DID_ABORT << 16;
\r
7539 + * Function: pti_st_abort(Scsi_Cmnd *)
\r
7540 + * Description: Abort the current SCSI command(s).
\r
7543 +pti_st_abort(Scsi_Cmnd *cmd)
\r
7545 + struct pti_st_scb *scb = NULL;
\r
7546 + struct pti_st_host *p;
\r
7547 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
\r
7548 + unsigned long cpu_flags = 0;
\r
7550 + Scsi_Cmnd *cmd_next, *cmd_prev;
\r
7553 + p = (struct pti_st_host *) cmd->host->hostdata;
\r
7554 + for(i = 0; i < MAX_ADAPTORS; i++)
\r
7555 + if(p == pti_st_hostp[i])
\r
7558 + if(i >= MAX_ADAPTORS || !p) {
\r
7559 + return(SCSI_ABORT_NOT_RUNNING);
\r
7562 + scb = (p->scb_data->scb_array[pti_st_position(cmd)]);
\r
7568 + * Run the isr to grab any command in the QOUTFIFO and any other misc.
\r
7569 + * assundry tasks. This should also set up the bh handler if there is
\r
7570 + * anything to be done, but it won't run until we are done here since
\r
7571 + * we are following a straight code path without entering the scheduler
\r
7576 + pti_st_isr(p->pci_irq, p, (void *)NULL);
\r
7577 + pti_st_done_cmds_complete(p);
\r
7580 + if ((scb == NULL) || (cmd->serial_number != cmd->serial_number_at_timeout))
\r
7581 + /* Totally bogus cmd since it points beyond our */
\r
7582 + { /* valid SCB range or doesn't even match it's own*/
\r
7583 + /* timeout serial number. */
\r
7585 + return(SCSI_ABORT_NOT_RUNNING);
\r
7588 + if (scb->cmd != cmd) /* Hmmm...either this SCB is currently free with a */
\r
7589 + { /* NULL cmd pointer (NULLed out when freed) or it */
\r
7590 + /* has already been recycled for another command */
\r
7591 + /* Either way, this SCB has nothing to do with this*/
\r
7592 + /* command and we need to deal with cmd without */
\r
7593 + /* touching the SCB. */
\r
7594 + /* The theory here is to return a value that will */
\r
7595 + /* make the queued for complete command actually */
\r
7596 + /* finish successfully, or to indicate that we */
\r
7597 + /* don't have this cmd any more and the mid level */
\r
7598 + /* code needs to find it. */
\r
7599 + cmd_next = p->completeq.head;
\r
7600 + cmd_prev = NULL;
\r
7601 + while (cmd_next != NULL)
\r
7603 + if (cmd_next == cmd)
\r
7605 +// if (pti_st_verbose & VERBOSE_ABORT_PROCESS)
\r
7606 + printk(INFO_LEAD "Abort called for command "
\r
7607 + "on completeq, completing.\n", p->host_no, CTL_OF_CMD(cmd));
\r
7608 + if ( cmd_prev == NULL )
\r
7609 + p->completeq.head = (Scsi_Cmnd *)cmd_next->host_scribble;
\r
7611 + cmd_prev->host_scribble = cmd_next->host_scribble;
\r
7612 + cmd_next->scsi_done(cmd_next);
\r
7615 + return(SCSI_ABORT_NOT_RUNNING); /* It's already back as a successful
\r
7618 + cmd_prev = cmd_next;
\r
7619 + cmd_next = (Scsi_Cmnd *)cmd_next->host_scribble;
\r
7622 +// if (pti_st_verbose & VERBOSE_ABORT_MID)
\r
7623 + printk(INFO_LEAD "Abort called for already completed"
\r
7624 + " command.\n", p->host_no, CTL_OF_CMD(cmd));
\r
7626 + return(SCSI_ABORT_NOT_RUNNING);
\r
7630 + * Hmmm...completeq, QOUTFIFO, QINFIFO, WAITING_SCBH, waitingq all checked.
\r
7631 + * OK...the sequencer's paused, interrupts are off, and we haven't found the
\r
7632 + * command anyplace where it could be easily aborted. Time for the hard
\r
7633 + * work. We also know the command is valid. This essentially means the
\r
7634 + * command is disconnected, or connected but not into any phases yet, which
\r
7635 + * we know due to the tests we ran earlier on the current active scb phase.
\r
7636 + * At this point we can queue the abort tag and go on with life.
\r
7638 + if (scb->flags & SCB_WAITINGQ)
\r
7640 + scbq_remove(p, &p->waiting_scbs, scb);
\r
7642 + scb->flags &= ~(SCB_WAITINGQ | SCB_ACTIVE);
\r
7643 + scb->flags |= SCB_ABORT;
\r
7644 + pti_st_done(p, scb);
\r
7645 + pti_st_done_cmds_complete(p);
\r
7646 +// pti_st_run_waiting_queues(p);
\r
7650 + * On the return value. If we found the command and aborted it, then we know
\r
7651 + * it's already sent back and there is no reason for a further timeout, so
\r
7652 + * we use SCSI_ABORT_SUCCESS. On the queued abort side, we aren't so certain
\r
7653 + * there hasn't been a bus hang or something that might keep the abort from
\r
7654 + * from completing. Therefore, we use SCSI_ABORT_PENDING. The first time
\r
7656 + * is passed back, the timeout on the command gets extended, the second time
\r
7657 + * we pass this back, the mid level SCSI code calls our reset function, which
\r
7658 + * would shake loose a hung bus.
\r
7660 + return(SCSI_ABORT_SUCCESS);
\r
7664 + * Function: pti_st_reset(Scsi_Cmnd *, unsigned int)
\r
7665 + * Description: Resetting the bus always succeeds - is has to, otherwise the
\r
7666 + * kernel will panic! Try a surgical technique: sending ARRAY
\r
7667 + * RESET message frame
\r
7670 +pti_st_reset(Scsi_Cmnd *cmd, unsigned int flags)
\r
7672 + struct pti_st_scb *scb = NULL;
\r
7673 + struct pti_st_host *p;
\r
7675 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
\r
7676 + unsigned long cpu_flags = 0;
\r
7678 + Scsi_Cmnd *cmd_prev, *cmd_next;
\r
7681 + if ( cmd == NULL )
\r
7683 + return(SCSI_RESET_SNOOZE);
\r
7686 + p = (struct pti_st_host *) cmd->host->hostdata;
\r
7687 + for(i = 0; i < MAX_ADAPTORS; i++)
\r
7688 + if(p == pti_st_hostp[i])
\r
7691 + if(!p || i >= MAX_ADAPTORS)
\r
7692 + return(SCSI_RESET_NOT_RUNNING);
\r
7694 + scb = (p->scb_data->scb_array[pti_st_position(cmd)]);
\r
7698 + pti_st_isr(p->pci_irq, p, (void *)NULL );
\r
7699 + pti_st_done_cmds_complete(p);
\r
7701 + if (scb == NULL)
\r
7703 +// if (pti_st_verbose & VERBOSE_RESET_MID)
\r
7704 + printk(INFO_LEAD "Reset called with bogus Scsi_Cmnd"
\r
7705 + "->SCB mapping, improvising.\n", p->host_no, CTL_OF_CMD(cmd));
\r
7707 + else if (scb->cmd != cmd)
\r
7709 +// if (pti_st_verbose & VERBOSE_RESET_MID)
\r
7710 + printk(INFO_LEAD "Reset called with recycled SCB "
\r
7711 + "for cmd.\n", p->host_no, CTL_OF_CMD(cmd));
\r
7712 + cmd_prev = NULL;
\r
7713 + cmd_next = p->completeq.head;
\r
7714 + while ( cmd_next != NULL )
\r
7716 + if (cmd_next == cmd)
\r
7718 +// if (pti_st_verbose & VERBOSE_RESET_RETURN)
\r
7719 + printk(INFO_LEAD "Reset, found cmd on completeq"
\r
7720 + ", completing.\n", p->host_no, CTL_OF_CMD(cmd));
\r
7722 + return(SCSI_RESET_NOT_RUNNING);
\r
7724 + cmd_prev = cmd_next;
\r
7725 + cmd_next = (Scsi_Cmnd *)cmd_next->host_scribble;
\r
7729 + * By this point, we want to already know what we are going to do and
\r
7730 + * only have the following code implement our course of action.
\r
7732 + for (i = 0; i < p->scb_data->maxscbs; i++)
\r
7734 + scb = p->scb_data->scb_array[i];
\r
7735 + if (scb->flags & SCB_ACTIVE)
\r
7737 + scb->flags |= SCB_RESET | SCB_QUEUED_FOR_DONE;
\r
7738 + scb->flags &= ~(SCB_ACTIVE | SCB_WAITINGQ);
\r
7741 + scbq_init(&p->waiting_scbs);
\r
7742 + pti_st_run_done_queue(p, TRUE);
\r
7743 + /* We can't rely on run_waiting_queues to unpause the sequencer for
\r
7744 + * PCI based controllers since we use AAP */
\r
7746 + return (SCSI_RESET_SUCCESS);
\r
7750 + * Function: pti_st_biosparam(Disk *, kdev_t, int[])
\r
7751 + * Description: Return the disk geometry for the given SCSI device.
\r
7754 +pti_st_biosparam(Disk *disk, kdev_t dev, int geom[])
\r
7759 + struct pti_st_host *p;
\r
7761 + p = (struct pti_st_host *) disk->device->host->hostdata;
\r
7764 + * XXX - if I could portably find the card's configuration
\r
7765 + * information, then this could be autodetected instead
\r
7766 + * of left to a boot-time switch.
\r
7770 + cylinders = disk->capacity / (heads * sectors);
\r
7772 + geom[0] = heads;
\r
7773 + geom[1] = sectors;
\r
7774 + geom[2] = cylinders;
\r
7782 +/***************************************************************************
\r
7783 + Hardware Interface Functions
\r
7784 +****************************************************************************/
\r
7787 + * Function : static int IOP_init(struct pti_st_host *);
\r
7788 + * Description: just initialize the hardware, fetch parameters from PCI.
\r
7790 +static int IOP_init(struct pti_st_host *hostp)
\r
7794 + unsigned long pBaseAddrReg = (U32)hostp->maddr;
\r
7795 + unsigned long pMFA_Inbound;
\r
7797 + // printk("Initializing i960! pBaseAddrReg :%lx\n", pBaseAddrReg);
\r
7799 + // Until the Inbound Queue is available:
\r
7800 + pMFA_Inbound = *(U32 *)(pBaseAddrReg+INBOUNDQPORT);
\r
7801 + while (((U32) pMFA_Inbound == -1))
\r
7802 + pMFA_Inbound = * (U32 *)(pBaseAddrReg+INBOUNDQPORT);
\r
7803 + UtilNOPCall(hostp);
\r
7805 + ExecIOPReset(hostp);
\r
7807 + IopStatus = GetStatusCall(hostp, (void *)hostp->replyBufferp);
\r
7809 + OutboundInitCall(hostp);
\r
7811 + UtilNOPCall(hostp);
\r
7812 + IopStatus = GetStatusCall(hostp, (void *)hostp->replyBufferp);
\r
7814 + /* Outbound Queue is now available! */
\r
7816 + SysTabSetCall(hostp, (PI2O_EXEC_SYS_TAB_SET_MESSAGE)hostp->messageBufferp,
\r
7817 + (void *)hostp->replyBufferp);
\r
7818 + if (pti_st_waitreplymsg(hostp) != I2O_REPLY_STATUS_SUCCESS)
\r
7820 + printk("!BAD reply after sending ExecSysTabSet Message!\n");
\r
7824 + IopStatus = GetStatusCall(hostp, (void *)hostp->replyBufferp);
\r
7826 + if (IopStatus == I2O_IOP_STATE_READY)
\r
7829 + * Send ExecSysEnable message, wait for reply
\r
7832 + EnableSysCall(hostp);
\r
7833 + if (pti_st_waitreplymsg(hostp) != I2O_REPLY_STATUS_SUCCESS)
\r
7835 + printk("!BAD reply after sending ExecSysEnable Message!\n");
\r
7838 + if (GetStatusCall(hostp, (void *)hostp->replyBufferp) != I2O_IOP_STATE_OPERATIONAL)
\r
7844 + /* IOP is in OPERATIONAL state! */
\r
7846 + LCTNotifyCall(hostp);
\r
7847 + if (pti_st_waitreplymsg(hostp) != I2O_REPLY_STATUS_SUCCESS)
\r
7849 + printk("!BAD reply after sending ExecLctNotify Message!\n");
\r
7854 + /* IOP is now initialized! */
\r
7856 + GetInfoFromLCT(hostp,
\r
7857 + (void *)hostp->replyBufferp,
\r
7858 + (PI2ODISK)hostp->I2ODisk,
\r
7859 + (unsigned int *)&hostp->TotalDiskCount);
\r
7861 + for (index = 0; index < hostp->TotalDiskCount; index++)
\r
7863 + ComposeDiskInfo(hostp,
\r
7864 + (PI2O_UTIL_PARAMS_GET_MESSAGE)hostp->messageBufferp,
\r
7865 + (void *)hostp->replyBufferp,
\r
7866 + (PI2ODISK)&hostp->I2ODisk[index] );
\r
7867 + hostp->I2ODisk[index].present = TRUE;
\r
7874 + * Function: unsigned int GetStatusCall(void *)
\r
7875 + * Description: get IOP's state.
\r
7876 + * Return : IOP's current state.
\r
7878 +static unsigned int GetStatusCall(struct pti_st_host *hostp, void * replyBuffer)
\r
7881 + volatile int state;
\r
7884 + unsigned long pBaseAddrReg = (U32)hostp->maddr;
\r
7885 + PI2O_EXEC_STATUS_GET_MESSAGE pMsg;
\r
7886 + volatile PI2O_EXEC_STATUS_GET_REPLY reply =
\r
7887 + (PI2O_EXEC_STATUS_GET_REPLY)replyBuffer;
\r
7889 + msgOffset = hostp->p_atu->InQueue;
\r
7890 + pMsg = (PI2O_EXEC_STATUS_GET_MESSAGE)(hostp->LinBaseAddr + msgOffset);
\r
7892 + memset((void *)reply, 0, sizeof(PI2O_EXEC_STATUS_GET_REPLY));
\r
7894 + pMsg->ReplyBufferLength=0x100;
\r
7895 + pMsg->ReplyBufferAddressLow = virt_to_bus(reply);
\r
7896 + pMsg->VersionOffset=0x01;
\r
7897 + pMsg->MsgFlags=0; /* No flag to set */
\r
7898 + pMsg->MessageSize=(sizeof(I2O_EXEC_STATUS_GET_MESSAGE)>>2);
\r
7899 + pMsg->TargetAddress=0;
\r
7900 + pMsg->InitiatorAddress=0x1; /* from host */
\r
7901 + pMsg->Function=I2O_EXEC_STATUS_GET;
\r
7903 + *(U32 *)(pBaseAddrReg+INBOUNDQPORT) = msgOffset; /* YBM: ... = pMFA_Inbound;*/
\r
7905 + timeout = 100000;
\r
7908 + for (i=0; i<1000; i++) /* please don't hog the bus! */
\r
7910 + if ((state=reply->IopState) != 0)
\r
7914 + printk(" Timeout wait for IOP Status Get Ready!\n");
\r
7919 + memcpy((void *)(&hostp->IopStatus),
\r
7921 + sizeof(I2O_EXEC_STATUS_GET_REPLY));
\r
7923 + return (unsigned int) reply->IopState;
\r
7928 +** =========================================================================
\r
7929 +** SendI2OOutboundQInitMsg()
\r
7931 +** =========================================================================
\r
7935 +SendI2OOutboundQInitMsg(PPAB pPab)
\r
7937 + U32 msgOffset, timeout, phyOutQFrames, i;
\r
7938 + volatile PU32 pMsg;
\r
7939 + volatile PU32 p32;
\r
7943 + msgOffset = pPab->p_atu->InQueue;
\r
7946 + if (msgOffset == 0xFFFFFFFF)
\r
7949 + kprintf("SendI2OOutboundQInitMsg(): Inbound Free Q empty!\n");
\r
7951 + return RC_RTN_FREE_Q_EMPTY;
\r
7955 + pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
\r
7958 + kprintf("SendI2OOutboundQInitMsg - pMsg = 0x%08.8ulx, InQ msgOffset = 0x%08.8ulx\n", pMsg, msgOffset);
\r
7961 + pMsg[0] = EIGHT_WORD_MSG_SIZE | TRL_OFFSET_6;
\r
7962 + pMsg[1] = I2O_EXEC_OUTBOUND_INIT << 24 | I2O_HOST_TID << 12 | I2O_IOP_TID;
\r
7963 + pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
\r
7964 + pMsg[3] = 0x106;
\r
7965 + pMsg[4] = 4096;
\r
7966 + pMsg[5] = MSG_FRAME_SIZE << 16 | 0x80;
\r
7967 + pMsg[6] = 0xD0000004;
\r
7968 + pMsg[7] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB);
\r
7970 + p32 = (PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
\r
7973 + pPab->p_atu->InQueue = msgOffset;
\r
7975 + timeout = 100000;
\r
7978 + for (i = 0; i < 1000; i++)
\r
7987 + kprintf("Timeout wait for InitOutQ InPrgress status from IOP\n");
\r
7989 + return RC_RTN_NO_I2O_STATUS;
\r
7993 + timeout = 100000;
\r
7996 + for (i = 0; i < 1000; i++)
\r
7999 + if (p32[0] == I2O_EXEC_OUTBOUND_INIT_COMPLETE)
\r
8005 + kprintf("Timeout wait for InitOutQ Complete status from IOP\n");
\r
8007 + return RC_RTN_NO_I2O_STATUS;
\r
8011 + phyOutQFrames = pPab->outMsgBlockPhyAddr;
\r
8013 + for (i = 0; i < NMBR_MSG_FRAMES; i++)
\r
8015 + pPab->p_atu->OutQueue = phyOutQFrames;
\r
8016 + phyOutQFrames += MSG_FRAME_SIZE;
\r
8018 + return RC_RTN_NO_ERROR;
\r
8025 +static void OutboundInitCall(struct pti_st_host *hostp)
\r
8031 + PI2O_EXEC_OUTBOUND_INIT_MESSAGE pMsg;
\r
8032 + unsigned long pBaseAddrReg = (U32)hostp->maddr;
\r
8033 + unsigned long pMFA_Outbound = 0;
\r
8035 + msgOffset = hostp->p_atu->InQueue;
\r
8036 + pMsg = (PI2O_EXEC_OUTBOUND_INIT_MESSAGE)(hostp->LinBaseAddr+msgOffset);
\r
8038 + memset((void *)hostp->replyBufferp, 0, 16*1024);
\r
8040 + pMsg->StdMessageFrame.VersionOffset=0x61; // 32 bit frame
\r
8041 + pMsg->StdMessageFrame.MsgFlags=0;
\r
8042 + pMsg->StdMessageFrame.MessageSize=sizeof(I2O_EXEC_OUTBOUND_INIT_MESSAGE)>>2;
\r
8044 + pMsg->StdMessageFrame.TargetAddress=0; // IXWork
\r
8045 + pMsg->StdMessageFrame.InitiatorAddress = 0x01; // from Host
\r
8046 + pMsg->StdMessageFrame.Function = I2O_EXEC_OUTBOUND_INIT;
\r
8047 + pMsg->HostPageFrameSize = 4096;
\r
8048 + pMsg->InitCode = I2O_MESSAGE_IF_INIT_CODE_NO_OWNER;
\r
8049 + pMsg->OutboundMFrameSize = 0x20; //each frame 32 * 4 bytes
\r
8050 + // the sgl for OutboundInitStatus Word, only 4 bytes.
\r
8051 + pMsg->SGL.u.Simple[0].FlagsCount.Count=4;
\r
8052 + pMsg->SGL.u.Simple[0].FlagsCount.Flags=(I2O_SGL_FLAGS_LAST_ELEMENT |
\r
8053 + I2O_SGL_FLAGS_END_OF_BUFFER |
\r
8054 + I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT);
\r
8056 + pMsg->SGL.u.Simple[0].PhysicalAddress=virt_to_bus(hostp->replyBufferp);
\r
8058 + * (U32 *)(pBaseAddrReg+INBOUNDQPORT) = msgOffset; // YBM: ... = pMFA_Inbound;
\r
8060 + // wait for response:
\r
8061 + timeout = 0x100000;
\r
8064 + for (i=0; i<1000; i++) // please don't hog the bus!!!
\r
8066 + if (*((U8*)hostp->replyBufferp) != 0)
\r
8071 + printk("Timeout wait for I2O_EXEC_OUTBOUND_INIT_IN_PROGRESS status!\n");
\r
8076 + timeout = 100000;
\r
8079 + for (i= 0; i<1000; i++) // please don't hog the bus!!!
\r
8081 + if (*((U8*)hostp->replyBufferp) == I2O_EXEC_OUTBOUND_INIT_COMPLETE)
\r
8086 + printk("Timeout wait for I2O_EXEC_OUTBOUND_INIT_COMPLETE status!\n");
\r
8091 + for(x=0; x < 32; x++)
\r
8093 + pMFA_Outbound = (U32)&(hostp->outboundBufferp->outboundBuff[x]);
\r
8094 + *((U32 *)(pBaseAddrReg+OUTBOUNDQPORT))=virt_to_bus((void *)pMFA_Outbound);
\r
8095 + for (i=0; i<1000; i++) // just for waitting!
\r
8099 + printk("Write to Outbound port, MFAs are : \n");
\r
8100 + printk("%lx", pMFA_Outbound);
\r
8103 + // printk(" DONE!\n");
\r
8109 +static void SysTabSetCall(struct pti_st_host *hostp,
\r
8110 + PI2O_EXEC_SYS_TAB_SET_MESSAGE MF,
\r
8113 + U8 tempMemPool[0x200];
\r
8114 + int count=0x200;
\r
8115 + void *tlsgl = lsgl;
\r
8116 + unsigned long pBaseAddrReg = (U32)hostp->maddr;
\r
8117 + unsigned long pMFA_Inbound;
\r
8119 + PI2O_EXEC_STATUS_GET_REPLY ptReplyMemPool =
\r
8120 + (PI2O_EXEC_STATUS_GET_REPLY)tempMemPool;
\r
8122 + PI2O_SGE_SIMPLE_ELEMENT ptsgl =
\r
8123 + (PI2O_SGE_SIMPLE_ELEMENT)MF->SGL.u.Simple;
\r
8126 + tempMemPool[count] = ((char*)tlsgl)[count];
\r
8128 + pMFA_Inbound = * (U32 *)(pBaseAddrReg+INBOUNDQPORT);
\r
8130 + ZeroMemory((U32*) MF, sizeof(I2O_EXEC_SYS_TAB_SET_MESSAGE)+0x10);
\r
8131 + ZeroMemory((U32*) lsgl, 0x200);
\r
8133 + MF->StdMessageFrame.VersionOffset=0x61; // 32 bit frame
\r
8134 + MF->StdMessageFrame.MsgFlags=0;
\r
8135 + MF->StdMessageFrame.MessageSize=sizeof(I2O_EXEC_SYS_TAB_SET_MESSAGE) >> 2;
\r
8137 + MF->StdMessageFrame.TargetAddress=0; // IXWork
\r
8138 + MF->StdMessageFrame.InitiatorAddress = 0x01; // from Host
\r
8139 + MF->StdMessageFrame.Function = I2O_EXEC_SYS_TAB_SET;
\r
8141 + MF->IOP_ID = MY_IOP_ID; //I2O_EXEC_SYS_TAB_IOP_ID_LOCAL_HOST;
\r
8142 + MF->HostUnitID = I2O_EXEC_SYS_TAB_HOST_UNIT_ID_LOCAL_UNIT;
\r
8143 + MF->SegmentNumber = I2O_EXEC_SYS_TAB_SEG_NUMBER_LOCAL_SEGMENT;
\r
8145 + MF->SGL.u.Simple[0].FlagsCount.Count=
\r
8146 + CreatSysTable(hostp, lsgl, (PI2O_EXEC_STATUS_GET_REPLY)tempMemPool);
\r
8148 + // 1st element: YBM: need I2O_SGL_FLAGS_END_OF_BUFFER ?
\r
8149 + ptsgl->FlagsCount.Flags = (I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT |
\r
8150 + I2O_SGL_FLAGS_END_OF_BUFFER) ;
\r
8152 + MF->SGL.u.Simple[0].PhysicalAddress = (U32)(virt_to_bus(lsgl));
\r
8154 + // 2nd element: YBM: need I2O_SGL_FLAGS_END_OF_BUFFER ?
\r
8156 + ptsgl->FlagsCount.Flags = (I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT |
\r
8157 + I2O_SGL_FLAGS_END_OF_BUFFER) ;
\r
8158 + ptsgl->FlagsCount.Count = ptReplyMemPool->CurrentPrivateMemSize;
\r
8159 + ptsgl->PhysicalAddress = ptReplyMemPool->CurrentPrivateMemBase;
\r
8162 +#if defined(MYDEBUG) && 0
\r
8163 + MF->SGL.u.SimpleContext[0].FlagsCount.Count=
\r
8164 + ptReplyMemPool->CurrentPrivateIOSize;
\r
8166 + MF->SGL.u.SimpleContext[0].FlagsCount.Flags =
\r
8167 + (I2O_SGL_FLAGS_LAST_ELEMENT |
\r
8168 + I2O_SGL_FLAGS_END_OF_BUFFER |
\r
8169 + I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT);
\r
8171 + MF->SGL.u.SimpleContext[0].PhysicalAddress = ptReplyMemPool->CurrentPrivateIOBase;
\r
8174 + ptsgl->FlagsCount.Count=
\r
8175 + ptReplyMemPool->CurrentPrivateIOSize;
\r
8177 + ptsgl->FlagsCount.Flags =
\r
8178 + (I2O_SGL_FLAGS_LAST_ELEMENT |
\r
8179 + I2O_SGL_FLAGS_END_OF_BUFFER |
\r
8180 + I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT);
\r
8182 + ptsgl->PhysicalAddress = ptReplyMemPool->CurrentPrivateIOBase;
\r
8185 + memcpy( (void *)(pMFA_Inbound+pBaseAddrReg), (void *)MF,
\r
8186 + (sizeof(I2O_EXEC_OUTBOUND_INIT_MESSAGE)+
\r
8187 + (sizeof(I2O_SGE_SIMPLE_ELEMENT) * 2)) );
\r
8189 + * (U32 *)(pBaseAddrReg+INBOUNDQPORT) = pMFA_Inbound;
\r
8196 +static void EnableSysCall(struct pti_st_host *hostp)
\r
8199 + PI2O_EXEC_SYS_ENABLE_MESSAGE pMsg;
\r
8201 + msgOffset = hostp->p_atu->InQueue;
\r
8203 + pMsg = (PI2O_EXEC_SYS_ENABLE_MESSAGE)(hostp->LinBaseAddr + msgOffset);
\r
8205 + pMsg->StdMessageFrame.VersionOffset=0x1;
\r
8206 + pMsg->StdMessageFrame.MsgFlags=0;
\r
8207 + pMsg->StdMessageFrame.MessageSize=sizeof(I2O_EXEC_SYS_ENABLE_MESSAGE) >> 2;
\r
8209 + pMsg->StdMessageFrame.TargetAddress=0; // IXWork
\r
8210 + pMsg->StdMessageFrame.InitiatorAddress = 0x01; // from Host
\r
8211 + pMsg->StdMessageFrame.Function = I2O_EXEC_SYS_ENABLE;
\r
8213 + *(U32 *)(hostp->LinBaseAddr+INBOUNDQPORT) = msgOffset; // YBM: ... = pMFA_Inbound;
\r
8219 +static void LCTNotifyCall(struct pti_st_host *hostp)
\r
8222 + PI2O_EXEC_LCT_NOTIFY_MESSAGE pMsg;
\r
8223 + unsigned long pBaseAddrReg = (U32)hostp->maddr;
\r
8225 + msgOffset = hostp->p_atu->InQueue;
\r
8227 + pMsg = (PI2O_EXEC_LCT_NOTIFY_MESSAGE)(hostp->LinBaseAddr + msgOffset);
\r
8228 + pMsg->StdMessageFrame.VersionOffset=0x61;
\r
8229 + pMsg->StdMessageFrame.MsgFlags=0;
\r
8230 + pMsg->StdMessageFrame.MessageSize=sizeof(I2O_EXEC_LCT_NOTIFY_MESSAGE)>>2;
\r
8232 + pMsg->StdMessageFrame.TargetAddress=0; // IXWork
\r
8233 + pMsg->StdMessageFrame.InitiatorAddress = 0x01; // from Host
\r
8234 + pMsg->StdMessageFrame.Function = I2O_EXEC_LCT_NOTIFY;
\r
8235 + pMsg->ClassIdentifier = 0xffffffff; // all class
\r
8236 + // I2O_CLASS_RANDOM_BLOCK_STORAGE;
\r
8237 + pMsg->LastReportedChangeIndicator = 0;
\r
8238 + pMsg->SGL.u.Simple[0].FlagsCount.Count=0x1000;
\r
8239 + pMsg->SGL.u.Simple[0].FlagsCount.Flags=(I2O_SGL_FLAGS_LAST_ELEMENT |
\r
8240 + I2O_SGL_FLAGS_END_OF_BUFFER |
\r
8241 + I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT);
\r
8242 + pMsg->SGL.u.Simple[0].PhysicalAddress=virt_to_bus(hostp->replyBufferp);
\r
8244 + * (U32 *)(pBaseAddrReg+INBOUNDQPORT) = msgOffset; // YBM: ... = pMFA_Inbound;
\r
8250 +static U32 CreatSysTable(struct pti_st_host *hostp,
\r
8252 + PI2O_EXEC_STATUS_GET_REPLY ltMemPool)
\r
8254 + PI2O_SET_SYSTAB_HEADER pPacket = (PI2O_SET_SYSTAB_HEADER) llsgl;
\r
8255 + PI2O_IOP_ENTRY pEntry = (PI2O_IOP_ENTRY) ((U8 *) llsgl + sizeof(PI2O_SET_SYSTAB_HEADER));
\r
8257 + pPacket->NumberEntries=0x1;
\r
8258 + pPacket->SysTabVersion=I2O_RESOURCE_MANAGER_VERSION;
\r
8259 + pPacket->CurrentChangeIndicator=0;
\r
8261 + // pEntry->OrganizationID = ltMemPool->OrganizationID;
\r
8262 + pEntry->OrganizationID = PROMISE_ORG_ID;
\r
8263 + pEntry->IOP_ID = MY_IOP_ID; //ltMemPool->IOP_ID;
\r
8264 + pEntry->SegmentNumber = ltMemPool->SegmentNumber;
\r
8265 + pEntry->I2oVersion = ltMemPool->I2oVersion;
\r
8266 + pEntry->IopState = ltMemPool->IopState;
\r
8267 + pEntry->MessengerType = ltMemPool->MessengerType;
\r
8268 + pEntry->InboundMessageFrameSize = ltMemPool->InboundMFrameSize;
\r
8269 + pEntry->LastChanged = 0;
\r
8270 + pEntry->IopCapabilities = ltMemPool->IopCapabilities;
\r
8271 + pEntry->MessengerInfo.InboundMessagePortAddressLow = (U32)hostp->maddr;
\r
8272 + pEntry->MessengerInfo.InboundMessagePortAddressHigh = 0;
\r
8274 + return sizeof(I2O_IOP_ENTRY)+sizeof(I2O_SET_SYSTAB_HEADER);
\r
8278 +/*****************************************************************************
\r
8279 + I2O EXECUTIVE CLASS MESSAGE
\r
8280 +*****************************************************************************/
\r
8285 +static void ExecIOPReset(struct pti_st_host *hostp)
\r
8289 + PI2O_EXEC_IOP_RESET_MESSAGE pMsg;
\r
8290 + volatile PU32 p32;
\r
8291 + unsigned long pBaseAddrReg = (U32)hostp->maddr;
\r
8293 + msgOffset = hostp->p_atu->InQueue;
\r
8295 + pMsg = (PI2O_EXEC_IOP_RESET_MESSAGE)(hostp->LinBaseAddr + msgOffset);
\r
8296 + memset((void *)hostp->replyBufferp, 0, 16*1024);
\r
8298 + pMsg->VersionOffset=0x01;
\r
8299 + pMsg->MsgFlags=0;
\r
8300 + pMsg->MessageSize= sizeof(I2O_EXEC_IOP_RESET_MESSAGE) >> 2;
\r
8302 + pMsg->TargetAddress=0; // IXWork
\r
8303 + pMsg->InitiatorAddress = 0x01; // from Host
\r
8304 + pMsg->Function = I2O_EXEC_IOP_RESET;
\r
8306 + pMsg->StatusWordHighAddress = 0;
\r
8307 + pMsg->StatusWordLowAddress =
\r
8308 + (U32)(virt_to_bus((void *)hostp->replyBufferp));
\r
8310 + p32 = (volatile PU32)hostp->replyBufferp;
\r
8312 + *(U32 *)(pBaseAddrReg+INBOUNDQPORT) = msgOffset;
\r
8314 + /* wait for response: */
\r
8315 + timeout = 1000000;
\r
8319 + for (i=0; i<1000; i++) /* please don't hog the bus ! */
\r
8321 + if(p32[0] || p32[1])
\r
8325 + printk("Timeout while Resetting IOP !\n");
\r
8331 +static void PTI_StringCutBlank(char * strBuffer, U32 strLength)
\r
8333 + U32 i = strLength - 2;
\r
8335 + while (i >= 0 && strBuffer[i] == ' ')
\r
8337 + strBuffer[i] = '\0';
\r
8345 +static void GetInfoFromLCT(struct pti_st_host *hostp,
\r
8347 + PI2ODISK pmydisk,
\r
8348 + unsigned int *diskcount)
\r
8350 + PI2O_LCT pTable = (PI2O_LCT)lMemPool;
\r
8351 + PI2O_LCT_ENTRY pLCTEntry;
\r
8352 + PI2O_LCT_ENTRY HeadpLCTEntry = pTable->LCTEntry;
\r
8353 + U16 ParentID=0xffff;
\r
8357 + *diskcount = 0; // initial count
\r
8358 + memset((void *)hostp->LctEntryTable, 0, (sizeof(I2O_LCT_ENTRY) * MAX_LCT_ENTRY));
\r
8360 + while(pTable->TableSize==0) // wait ready
\r
8362 + pLCTEntry=HeadpLCTEntry;
\r
8365 + while (pLCTEntry->TableEntrySize==0x9)
\r
8367 + if(pLCTEntry->ClassID.Class==I2O_CLASS_DDM &&
\r
8368 + pLCTEntry->SubClassInfo==I2O_SUBCLASS_ISM)
\r
8370 + ParentID=(U16) pLCTEntry->LocalTID;
\r
8376 + if (ParentID == 0xffff)
\r
8378 + printk("ISM DDM ID not found!\n");
\r
8382 + /* scan all ISM children first: */
\r
8383 + pLCTEntry=HeadpLCTEntry;
\r
8386 + while(pLCTEntry->TableEntrySize == 0x9)
\r
8389 + * Insert the LCT Entry to LCT Entry Description
\r
8391 + memcpy((void*)&hostp->LctEntryTable[i],
\r
8392 + (void *)pLCTEntry,
\r
8393 + sizeof(I2O_LCT_ENTRY));
\r
8395 + if((pLCTEntry->ClassID.Class==I2O_CLASS_RANDOM_BLOCK_STORAGE) &&
\r
8396 + (pLCTEntry->ParentTID==ParentID))
\r
8398 + pmydisk->LocalTID = (unsigned int) pLCTEntry->LocalTID;
\r
8409 + * Starting lMemBuf = 0
\r
8410 + * 0 ~ 3 bytes -- Request Header (0-1) Op Cnt (2-3) Res
\r
8411 + * 4 ~ 9 bytes -- first operation list
\r
8412 + * a ~10 bytes -- second operation list
\r
8414 + * Result starts at lMemBuf+4+6+6
\r
8415 + * 0 ~ 3 -- result header (0-1) Result Cnt
\r
8416 + * 4 ~ n -- first result (first 4 byte, byte cnt in result+status)
\r
8418 +static int ComposeDiskInfo(struct pti_st_host *hostp,
\r
8421 + PI2ODISK pmydisk)
\r
8423 + PI2O_UTIL_DEVICE_IDENTITY_SCALAR pResult1;
\r
8424 + PI2O_BSA_DEVICE_INFO_SCALAR pResult2;
\r
8425 + PI2O_PARAM_READ_OPERATION_RESULT pOpResult;
\r
8426 + PI2O_PARAM_RESULTS_LIST_HEADER pResHeader =
\r
8427 + (PI2O_PARAM_RESULTS_LIST_HEADER) (((U8 *) lMemBuf)+8+4);
\r
8429 + void * ptMemBuf = lMemBuf;
\r
8430 + PI2O_PARAM_OPERATION_ALL_TEMPLATE ptsgl =
\r
8431 + (PI2O_PARAM_OPERATION_ALL_TEMPLATE) (((U8*) lMemBuf) + 4);
\r
8434 + unsigned int Hd;
\r
8435 + unsigned int Sctr = 0x3f;
\r
8438 + * Note:General and Specific parameter get must invoke separately
\r
8439 + * General Parameter Get
\r
8441 + ZeroMemory(lMemBuf, 0x200);
\r
8443 + *((unsigned int *) ptMemBuf) = 0x1;
\r
8444 + ptsgl->Operation = I2O_PARAMS_OPERATION_FIELD_GET;
\r
8445 + ptsgl->GroupNumber = I2O_UTIL_DEVICE_IDENTITY_GROUP_NO;
\r
8446 + ptsgl->FieldCount = 0xffff;
\r
8448 + PTI_UtilParamGetCall(hostp,
\r
8449 + (PI2O_UTIL_PARAMS_GET_MESSAGE) MF,
\r
8450 + (void *) ptMemBuf,
\r
8451 + (void *) (((U8 *) ptMemBuf)+0x4+0x8),
\r
8453 + if (pti_st_waitreplymsg(hostp) != I2O_REPLY_STATUS_SUCCESS)
\r
8455 + printk("!BAD reply after sending UtilParamsGetMessage!\n");
\r
8459 + pOpResult = (PI2O_PARAM_READ_OPERATION_RESULT) (++pResHeader);
\r
8460 + if(pOpResult->ErrorInfoSize != 0)
\r
8462 + return(FALSE); /* Error Action */
\r
8464 + pResult1 = (PI2O_UTIL_DEVICE_IDENTITY_SCALAR) (++pOpResult);
\r
8466 + memcpy( &(pmydisk->Vendor), &(pResult1->VendorInfo),
\r
8467 + I2O_DEVID_VENDOR_INFO_SZ );
\r
8469 + pmydisk->Vendor[I2O_DEVID_VENDOR_INFO_SZ] = (char) 0;
\r
8471 + PTI_StringCutBlank(pmydisk->Vendor, I2O_DEVID_VENDOR_INFO_SZ);
\r
8473 + memcpy( &(pmydisk->DiskModel), &(pResult1->ProductInfo),
\r
8474 + I2O_DEVID_PRODUCT_INFO_SZ );
\r
8476 + pmydisk->DiskModel[I2O_DEVID_PRODUCT_INFO_SZ] = (char) 0;
\r
8478 + PTI_StringCutBlank(pmydisk->DiskModel, I2O_DEVID_PRODUCT_INFO_SZ);
\r
8480 + memcpy( &(pmydisk->ProductRevLevel), &(pResult1->ProductRevLevel),
\r
8481 + I2O_DEVID_REV_LEVEL_SZ );
\r
8482 + pmydisk->ProductRevLevel[I2O_DEVID_REV_LEVEL_SZ] = '\0';
\r
8484 + PTI_StringCutBlank(pmydisk->ProductRevLevel, I2O_DEVID_REV_LEVEL_SZ);
\r
8487 + * Device Information (Storage Parameter Get)
\r
8489 + ZeroMemory(lMemBuf, 0x200);
\r
8491 + *((unsigned int *) ptMemBuf) = 0x1;
\r
8493 + ptsgl->Operation = I2O_PARAMS_OPERATION_FIELD_GET;
\r
8494 + ptsgl->GroupNumber = I2O_BSA_DEVICE_INFO_GROUP_NO;
\r
8495 + ptsgl->FieldCount = 0xffff;
\r
8497 + PTI_UtilParamGetCall(hostp,
\r
8498 + (PI2O_UTIL_PARAMS_GET_MESSAGE) MF,
\r
8499 + (void *) ptMemBuf,
\r
8500 + (void *) (((U8 *) ptMemBuf)+0x4+0x8),
\r
8502 + if (pti_st_waitreplymsg(hostp) != I2O_REPLY_STATUS_SUCCESS)
\r
8504 + printk("!BAD reply after sending UtilParamsGetMessage!\n");
\r
8508 + pResHeader=(PI2O_PARAM_RESULTS_LIST_HEADER) (((U8 *) lMemBuf)+8+4);
\r
8509 + pOpResult = (PI2O_PARAM_READ_OPERATION_RESULT) (++pResHeader);
\r
8510 + if(pOpResult->ErrorInfoSize != 0)
\r
8512 + return(FALSE); // Error Action
\r
8514 + pResult2 = (PI2O_BSA_DEVICE_INFO_SCALAR) (++pOpResult);
\r
8516 + wSize = (long) ((pResult2->DeviceCapacity.HighPart << (32-9)) |
\r
8517 + (pResult2->DeviceCapacity.LowPart >> 9));
\r
8519 + pmydisk->lastLBA = (U32) wSize - 1;
\r
8521 + // convert LBA to CHS
\r
8522 + if(wSize <= (U32) 0x3f*0x10*0x400)
\r
8525 + while((wSize/(Hd*Sctr) > 0x400) && (Hd < 0x80))
\r
8528 + else if (wSize <= (U32) (0x3fl*0x20l*0x400l)) Hd = 0x20;
\r
8529 + else if (wSize <= (U32) (0x3fl*0x40l*0x400l)) Hd = 0x40;
\r
8530 + else if (wSize <= (U32) (0x3fl*0x80l*0x400l)) Hd = 0x80;
\r
8533 + pmydisk->lastcyl = (unsigned int) ((wSize/ (Hd*Sctr)) - 1);/*starting from 0*/
\r
8534 + pmydisk->lasthead = (U8) (Hd - 1); /*starting from 0*/
\r
8535 + pmydisk->sector = (U8) Sctr; /*starting from 0*/
\r
8541 + * Function: unsigned long pti_st_waitreplymsg(struct pti_st_host *)
\r
8542 + * Description: wait reply message from i960.
\r
8543 + * Return : Error code (0 represent I2O_REPLY_STATUS_SUCCESS)
\r
8545 +unsigned long pti_st_waitreplymsg(struct pti_st_host *hostp)
\r
8550 + PI2O_SINGLE_REPLY_MESSAGE_FRAME replyPointer;
\r
8551 + unsigned long pBaseAddrReg = (U32)hostp->maddr;
\r
8552 + unsigned long pMFA_Outbound;
\r
8554 + // wait for response:
\r
8555 + timeout = 0x1000000;
\r
8558 + for (i=0; i<1000; i++) // please don't hog the bus!!!
\r
8560 + if((pMFA_Outbound=(*(volatile U32 *)(pBaseAddrReg+OUTBOUNDQPORT)))!=-1)
\r
8565 + printk("Timeout wait for Reply Message from IOP!\n");
\r
8570 + replyPointer=(PI2O_SINGLE_REPLY_MESSAGE_FRAME)(bus_to_virt(pMFA_Outbound));
\r
8572 + ReqStatus = replyPointer->ReqStatus;
\r
8574 + * (U32 *)(pBaseAddrReg+OUTBOUNDQPORT) = pMFA_Outbound;
\r
8576 + return (unsigned long) ReqStatus;
\r
8580 +/*****************************************************************************
\r
8581 + I2O UTILITY CLASS MESSAGE
\r
8582 +*****************************************************************************/
\r
8584 + * THis is used for ComposeDiskInfo()
\r
8586 +static void PTI_UtilParamGetCall(struct pti_st_host *hostp,
\r
8587 + PI2O_UTIL_PARAMS_GET_MESSAGE MF,
\r
8590 + PI2ODISK mydisk)
\r
8592 + PI2O_SGE_SIMPLE_ELEMENT sglentry =
\r
8593 + (PI2O_SGE_SIMPLE_ELEMENT)MF->SGL.u.Simple; // YBM: )&MF->SGL.u.Simple;
\r
8594 + unsigned long pBaseAddrReg = (U32)hostp->maddr;
\r
8595 + unsigned long pMFA_Inbound = * (U32 *)(pBaseAddrReg+INBOUNDQPORT);
\r
8597 + ZeroMemory((U32*) MF, sizeof(I2O_UTIL_PARAMS_GET_MESSAGE)+0x10);
\r
8599 + MF->StdMessageFrame.VersionOffset=0x51;
\r
8600 + MF->StdMessageFrame.MsgFlags=0;
\r
8601 + MF->StdMessageFrame.MessageSize=
\r
8602 + (sizeof(I2O_UTIL_PARAMS_GET_MESSAGE)+sizeof(I2O_SG_ELEMENT)) >> 2;
\r
8604 + MF->StdMessageFrame.TargetAddress=mydisk->LocalTID;
\r
8605 + MF->StdMessageFrame.InitiatorAddress = 0x01; // from Host
\r
8606 + MF->StdMessageFrame.Function = I2O_UTIL_PARAMS_GET;
\r
8608 + MF->OperationFlags = 0; // reserved
\r
8610 + // First buffer:
\r
8611 + sglentry->FlagsCount.Flags = (I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT |
\r
8612 + I2O_SGL_FLAGS_END_OF_BUFFER );
\r
8613 + sglentry->FlagsCount.Count = 0x0c ;
\r
8614 + sglentry->PhysicalAddress = (U32)(virt_to_bus(req)); // YBM: *(U32 *)req ;
\r
8616 + // Sencond buffer:
\r
8618 + sglentry->FlagsCount.Flags = (I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT |
\r
8619 + I2O_SGL_FLAGS_LAST_ELEMENT |
\r
8620 + I2O_SGL_FLAGS_END_OF_BUFFER );
\r
8621 + sglentry->FlagsCount.Count = 0x100;
\r
8622 + //sizeof(I2O_UTIL_DEVICE_IDENTITY_SCALAR);
\r
8623 + sglentry->PhysicalAddress = (U32)(virt_to_bus(buf)); // YBM: *(U32 *)buf;
\r
8625 + memcpy( (void *)(pMFA_Inbound+pBaseAddrReg), (void *)MF,
\r
8626 + (sizeof(I2O_UTIL_PARAMS_GET_MESSAGE)+16) );
\r
8628 + * (U32 *)(pBaseAddrReg+INBOUNDQPORT) = pMFA_Inbound;
\r
8633 + * This is used for pti_stdev_ioctl()
\r
8635 + * Routine Description:
\r
8637 + * message allows parameter values to be retrieved from
\r
8638 + * device parameter groups.
\r
8640 +static void PTI_UtilParamsGet(
\r
8641 + struct pti_st_host *hostp,
\r
8643 + ULONG FieldCount,
\r
8649 + PI2O_UTIL_PARAMS_GET_MESSAGE MsgPtr;
\r
8650 + PI2O_SGE_SIMPLE_ELEMENT SGLPtr;
\r
8651 + ULONG msgOffset;
\r
8652 + ULONG ParamOffset = 0;
\r
8655 + msgOffset = hostp->p_atu->InQueue;
\r
8656 + MsgPtr = (PI2O_UTIL_PARAMS_GET_MESSAGE)(hostp->LinBaseAddr+msgOffset);
\r
8657 + memset((ULONG *)MsgPtr,0,sizeof(I2O_UTIL_PARAMS_GET_MESSAGE)+0x10);
\r
8658 + SGLPtr = (PI2O_SGE_SIMPLE_ELEMENT)MsgPtr->SGL.u.Simple;
\r
8660 + ParamOffset = sizeof(I2O_PARAM_SCALAR_OPERATION);
\r
8661 + if (FieldCount != (USHORT)-1)
\r
8662 + ParamOffset = ParamOffset + (FieldCount-1)*sizeof(USHORT);
\r
8665 + * fill the message frame
\r
8667 + MsgPtr->StdMessageFrame.VersionOffset = 0x51;
\r
8668 + MsgPtr->StdMessageFrame.MsgFlags = 0;
\r
8669 + MsgPtr->StdMessageFrame.MessageSize =
\r
8670 + (sizeof(I2O_UTIL_PARAMS_GET_MESSAGE)+sizeof(I2O_SG_ELEMENT)) >> 2;
\r
8671 + MsgPtr->StdMessageFrame.TargetAddress = LocalTID;
\r
8672 + MsgPtr->StdMessageFrame.InitiatorAddress = 0x01; /* from Host */
\r
8673 + MsgPtr->StdMessageFrame.Function = I2O_UTIL_PARAMS_GET;
\r
8674 + MsgPtr->StdMessageFrame.InitiatorContext = SrbTag;
\r
8676 + MsgPtr->TransactionContext = SrbID;
\r
8677 + MsgPtr->OperationFlags = 0; /* reserved */
\r
8680 + * fill the SGL frame
\r
8681 + * the first buffer contains the operation list that
\r
8682 + * identifies which parameters are to be returned
\r
8684 + SGLPtr->FlagsCount.Flags = (I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT |
\r
8685 + I2O_SGL_FLAGS_END_OF_BUFFER );
\r
8686 + SGLPtr->FlagsCount.Count = ParamOffset;
\r
8687 + SGLPtr->PhysicalAddress = cpu_to_le32(VIRT_TO_BUS(Address));
\r
8689 + /* the second buffer is for target to place the results */
\r
8691 + SGLPtr->FlagsCount.Flags = (I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT |
\r
8692 + I2O_SGL_FLAGS_LAST_ELEMENT |
\r
8693 + I2O_SGL_FLAGS_END_OF_BUFFER );
\r
8694 + SGLPtr->FlagsCount.Count = 0x100;
\r
8695 + SGLPtr->PhysicalAddress = cpu_to_le32(VIRT_TO_BUS(Address+ParamOffset));
\r
8698 + * send the message
\r
8700 + hostp->p_atu->InQueue = msgOffset;
\r
8707 +static void UtilNOPCall(struct pti_st_host *hostp)
\r
8710 + PI2O_UTIL_NOP_MESSAGE pMsg;
\r
8712 + msgOffset = hostp->p_atu->InQueue;
\r
8714 + pMsg = (PI2O_UTIL_NOP_MESSAGE)(hostp->LinBaseAddr + msgOffset);
\r
8715 + pMsg->StdMessageFrame.VersionOffset=0x1;
\r
8716 + pMsg->StdMessageFrame.MsgFlags=0;
\r
8717 + pMsg->StdMessageFrame.MessageSize= sizeof(I2O_UTIL_NOP_MESSAGE) >> 2;
\r
8718 + pMsg->StdMessageFrame.TargetAddress=0;
\r
8719 + pMsg->StdMessageFrame.InitiatorAddress = 0x1; // from Host
\r
8720 + pMsg->StdMessageFrame.Function = I2O_UTIL_NOP;
\r
8722 + hostp->p_atu->InQueue = msgOffset;
\r
8726 +/********************************************************************
\r
8728 + * Private Messages
\r
8730 + ********************************************************************/
\r
8732 +static int PTI_PrivateMessageCall(
\r
8733 + struct pti_st_host *hostp,
\r
8734 + ULONG TargetTID,
\r
8735 + U16 XFunctionCode,
\r
8736 + U16 OrganizationID,
\r
8737 + ULONG InputCount,
\r
8738 + UCHAR *InputAddr,
\r
8739 + ULONG OutputCount,
\r
8740 + UCHAR *OutputAddr,
\r
8745 + PPTI_ST_PRIVATE_MESSAGE MsgPtr;
\r
8746 + unsigned long msgOffset;
\r
8750 + msgOffset = hostp->p_atu->InQueue;
\r
8751 + if(msgOffset != -1){
\r
8756 + if( i >= 10) return -1;
\r
8757 + MsgPtr = (PPTI_ST_PRIVATE_MESSAGE)(hostp->LinBaseAddr+msgOffset);
\r
8758 + memset((UCHAR *)MsgPtr,0,sizeof(PTI_ST_PRIVATE_MESSAGE)+0x10);
\r
8761 + * Fill the message frame
\r
8763 + MsgPtr->MyStandMsg.StdMessageFrame.VersionOffset = 0x1;
\r
8764 + MsgPtr->MyStandMsg.StdMessageFrame.MsgFlags = 0;
\r
8765 + MsgPtr->MyStandMsg.StdMessageFrame.MessageSize = (sizeof(PTI_ST_PRIVATE_MESSAGE) >> 2);
\r
8767 + MsgPtr->MyStandMsg.StdMessageFrame.TargetAddress = TargetTID; /* IXWork */
\r
8768 + MsgPtr->MyStandMsg.StdMessageFrame.InitiatorAddress = 0x01;
\r
8769 + MsgPtr->MyStandMsg.StdMessageFrame.Function = I2O_PRIVATE_MESSAGE;
\r
8770 + MsgPtr->MyStandMsg.StdMessageFrame.InitiatorContext = SrbTag;
\r
8772 + MsgPtr->MyStandMsg.XFunctionCode = (U16)(((XFunctionCode >> 8) & 0x00ff) | ((XFunctionCode << 8) & 0xff00));
\r
8774 + MsgPtr->MyStandMsg.OrganizationID = (U16)(((OrganizationID >> 8) & 0x00ff) | ((OrganizationID << 8) & 0xff00));
\r
8776 + MsgPtr->MyStandMsg.TransactionContext = SrbID;
\r
8778 + `a* Fill the private Payload
\r
8780 + MsgPtr->InSGL.FlagsCount.Count = InputCount;
\r
8781 + MsgPtr->InSGL.FlagsCount.Flags = I2O_SGL_FLAGS_PAGE_LIST_ADDRESS_ELEMENT | I2O_SGL_FLAGS_END_OF_BUFFER;
\r
8782 + MsgPtr->InSGL.PhysicalAddress[0] =
\r
8783 + cpu_to_le32(VIRT_TO_BUS(InputAddr));
\r
8785 + MsgPtr->OutSGL.FlagsCount.Count = OutputCount;
\r
8786 + MsgPtr->OutSGL.FlagsCount.Flags = I2O_SGL_FLAGS_PAGE_LIST_ADDRESS_ELEMENT | I2O_SGL_FLAGS_LAST_ELEMENT | I2O_SGL_FLAGS_END_OF_BUFFER;
\r
8787 + MsgPtr->OutSGL.PhysicalAddress[0] =
\r
8788 + cpu_to_le32(VIRT_TO_BUS(OutputAddr));
\r
8791 + * send the message
\r
8793 + hostp->p_atu->InQueue = msgOffset;
\r
8798 +/****************************************************************************
\r
8800 +****************************************************************************/
\r
8804 +static void ZeroMemory(unsigned long *zeroBuffer, unsigned int count)
\r
8806 + count = count >> 2; // count/4
\r
8809 + * zeroBuffer = 0;
\r
8814 +static void pti_st_flushcache_respond(Scsi_Cmnd *cmd)
\r
8816 + cmd->result = DID_OK;
\r
8817 + wake_up(&WaitQ);
\r
8821 +static void pti_st_wait_flushcache(unsigned long data)
\r
8823 + struct pti_st_scb *scb;
\r
8826 + scb = (struct pti_st_scb *)data;
\r
8829 + cmd->result = DID_ERROR;
\r
8831 + wake_up(&WaitQ);
\r
8836 +static int pti_st_send_flushcache_cmd(struct pti_st_host *p,
\r
8837 + struct pti_st_scb *scb,
\r
8841 + unsigned long pBaseAddrReg;
\r
8842 + unsigned long msgoffset;
\r
8843 + PI2O_BSA_CACHE_FLUSH_MESSAGE mfp;
\r
8844 + unsigned long cpuflags;
\r
8846 + spin_lock_irqsave(&p->spin_lock, cpuflags);
\r
8848 + pBaseAddrReg = (U32)p->maddr;
\r
8849 + msgoffset = * (U32 *)(pBaseAddrReg+INBOUNDQPORT);
\r
8850 + if (msgoffset == 0xFFFFFFFF)
\r
8852 + spin_unlock_irqrestore(&p->spin_lock, cpuflags);
\r
8853 + scbq_insert_head(p, &p->scb_data->free_scbs, scb);
\r
8854 + printk("pti_st_send_flushcache_cmd: Couldn't get a free MF from inboundqport on scsi No. %d.\n", p->host_no);
\r
8859 + pti_st_position(cmd) = scb->tag;
\r
8860 + p->scb_data->scb_array[scb->tag] = scb;
\r
8863 + * Make sure the Scsi_Cmnd pointer is saved, the struct it points to
\r
8864 + * is set up properly, and the parity error flag is reset, then send
\r
8865 + * the SCB to the sequencer and watch the fun begin.
\r
8867 + cmd->scsi_done = pti_st_flushcache_respond;
\r
8868 + cmd->result = DID_OK;
\r
8869 + memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
\r
8870 + cmd->host_scribble = NULL;
\r
8872 + scb->flags |= SCB_ACTIVE;
\r
8874 + mfp = (PI2O_BSA_CACHE_FLUSH_MESSAGE)(pBaseAddrReg + msgoffset);
\r
8876 + memset((unsigned long *)mfp, 0, sizeof(I2O_BSA_CACHE_FLUSH_MESSAGE)+0x10);
\r
8878 + /* Fill the message frame */
\r
8879 + mfp->StdMessageFrame.Function = I2O_BSA_CACHE_FLUSH;
\r
8880 + mfp->StdMessageFrame.VersionOffset = 0x01;
\r
8881 + mfp->StdMessageFrame.MsgFlags = 0;
\r
8882 + mfp->StdMessageFrame.MessageSize = sizeof(I2O_BSA_CACHE_FLUSH_MESSAGE) >> 2;
\r
8883 + mfp->StdMessageFrame.TargetAddress = p->I2ODisk[cmd->target].LocalTID;
\r
8884 + mfp->StdMessageFrame.InitiatorAddress = 0x01;
\r
8885 + mfp->StdMessageFrame.InitiatorContext = scb->tag;
\r
8886 + mfp->TransactionContext = cmd->serial_number;
\r
8887 + mfp->ControlFlags = 0;
\r
8888 + mfp->TimeMultiplier = 0;
\r
8890 + /* Start timer for timeout */
\r
8891 + init_timer(&bufflsh_timer);
\r
8892 + bufflsh_timer.expires = (jiffies + time*HZ);
\r
8893 + bufflsh_timer.data = (unsigned long)scb;
\r
8894 + bufflsh_timer.function=pti_st_wait_flushcache;
\r
8896 + /* modified for shutdown flag */
\r
8897 + mfp->Reserved = cmd->cmnd[2];
\r
8899 + /* send the message */
\r
8900 + * (U32 *)(pBaseAddrReg+INBOUNDQPORT) = msgoffset;
\r
8902 + spin_unlock_irqrestore(&p->spin_lock, cpuflags);
\r
8904 + add_timer(&bufflsh_timer);
\r
8905 + interruptible_sleep_on(&WaitQ);
\r
8907 + del_timer(&bufflsh_timer);
\r
8909 + if(cmd->result != DID_OK)
\r
8916 +static int pti_st_flushcache(int time)
\r
8918 + struct pti_st_host *p;
\r
8919 + struct pti_st_scb *scb;
\r
8920 + static Scsi_Cmnd scsicmd = {0};
\r
8924 + for(i = 0, err = 0; i < MAX_ADAPTORS; i++)
\r
8926 + p = (struct pti_st_host *) pti_st_hostp[i];
\r
8930 + scb = scbq_remove_head(p, &p->scb_data->free_scbs);
\r
8932 + if (scb == NULL)
\r
8938 + scsicmd.cmnd[0] = 0xfe;
\r
8939 + scsicmd.cmnd[2] = 0xfe;
\r
8940 + scsicmd.serial_number = 0xfe;
\r
8941 + if(p->TotalDiskCount <= 0 || p->I2ODisk[0].present != TRUE)
\r
8946 + * if raid exist, raid 0 should be exist
\r
8947 + * because raid is sorted from 0
\r
8949 + scsicmd.target = 0;
\r
8952 + ret = pti_st_send_flushcache_cmd(p, scb, &scsicmd, time);
\r
8965 +/************************************************************
\r
8966 + * Device File Function *
\r
8967 + ************************************************************/
\r
8969 +static int pti_stdev_strncmp(char *s, char *d, int n)
\r
8971 + /* check null */
\r
8981 + /* both not null */
\r
8983 + /* check length 0 */
\r
8994 + /* both length not 0 */
\r
8996 + return(strncmp(s,d,n));
\r
9002 +int pti_stdev_open(struct inode *inodep, struct file *filep)
\r
9004 + unsigned long cpuflags;
\r
9006 + int aptno = MINOR(inodep->i_rdev);
\r
9007 + struct pti_st_host *p = pti_st_hostp[aptno];
\r
9009 + if(!pti_st_hostp[aptno] ||
\r
9010 + pti_st_hostp[aptno]->major <= 0 ||
\r
9011 + pti_st_hostp[aptno]->major != MAJOR(inodep->i_rdev))
\r
9012 + return(-ENODEV);
\r
9014 + spin_lock_irqsave(&p->spin_lock, cpuflags);
\r
9015 + if(pti_st_hostp[aptno]->counter != 0) {
\r
9016 + spin_unlock_irqrestore(&p->spin_lock, cpuflags);
\r
9019 + pti_st_hostp[aptno]->counter++;
\r
9020 + spin_unlock_irqrestore(&p->spin_lock, cpuflags);
\r
9021 + MOD_INC_USE_COUNT;
\r
9025 +int pti_stdev_release(struct inode *inodep, struct file *filep)
\r
9027 + int aptno = MINOR(inodep->i_rdev);
\r
9028 + struct pti_st_host *p = pti_st_hostp[aptno];
\r
9029 + unsigned long cpuflags;
\r
9031 + if(!pti_st_hostp[aptno] ||
\r
9032 + pti_st_hostp[aptno]->major <= 0 ||
\r
9033 + pti_st_hostp[aptno]->major != MAJOR(inodep->i_rdev))
\r
9034 + return(-ENODEV);
\r
9036 + spin_lock_irqsave(&p->spin_lock, cpuflags);
\r
9037 + if(pti_st_hostp[aptno]->counter <= 0) {
\r
9038 + spin_unlock_irqrestore(&p->spin_lock, cpuflags);
\r
9041 + pti_st_hostp[aptno]->counter = 0;
\r
9042 + spin_unlock_irqrestore(&p->spin_lock, cpuflags);
\r
9044 + MOD_DEC_USE_COUNT;
\r
9047 +//------------------ added by dingo, 2002/8/14 --------------------
\r
9048 +static void pti_st_private_message_code_respond(Scsi_Cmnd *cmd)
\r
9050 + cmd->result = DID_OK;
\r
9051 + del_timer(&priv_msg_timer);
\r
9052 + wake_up(&PrivMsgWaitQ);
\r
9056 +static void pti_st_private_message_code_wait(unsigned long data)
\r
9060 + del_timer(&priv_msg_timer);
\r
9061 + cmd = (Scsi_Cmnd *) data;
\r
9062 + cmd->result = DID_ERROR;
\r
9063 + wake_up(&PrivMsgWaitQ);
\r
9067 +static int pti_st_send_private_message_code_cmd(struct pti_st_host *p,
\r
9069 + ULONG TargetTID,
\r
9070 + U16 XFunctionCode,
\r
9071 + U16 OrganizationID,
\r
9072 + ULONG InputCount,
\r
9073 + UCHAR *InputAddr,
\r
9074 + ULONG OutputCount,
\r
9075 + UCHAR *OutputAddr)
\r
9077 + unsigned long pBaseAddrReg;
\r
9078 + unsigned long msgoffset;
\r
9079 + PI2O_BSA_CACHE_FLUSH_MESSAGE mfp;
\r
9080 + static Scsi_Cmnd scsicmd = {0};
\r
9082 + unsigned long cpu_flags;
\r
9085 + scsicmd.cmnd[0] = 0xfd;
\r
9086 + scsicmd.cmnd[2] = 0xfd;
\r
9087 + scsicmd.serial_number = 0xfd;
\r
9089 + cmd->scsi_done = pti_st_private_message_code_respond;
\r
9090 + cmd->result = DID_OK;
\r
9091 + memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
\r
9092 + cmd->host_scribble = NULL;
\r
9094 + spin_lock_irqsave(&p->spin_lock, cpu_flags);
\r
9095 + /* Start timer for timeout */
\r
9096 + init_timer(&priv_msg_timer);
\r
9097 + priv_msg_timer.expires = (jiffies + time*HZ);
\r
9098 + priv_msg_timer.data = (unsigned long)cmd;
\r
9099 + priv_msg_timer.function= pti_st_private_message_code_wait;
\r
9100 + // we send the cmd variable by a standard message frame directly.
\r
9101 + if (PTI_PrivateMessageCall(p, TargetTID, XFunctionCode, OrganizationID, InputCount,
\r
9102 + InputAddr, OutputCount, OutputAddr, (U32)scsicmd.cmnd[0], (U32)cmd))
\r
9104 + spin_unlock_irqrestore(&p->spin_lock, cpu_flags);
\r
9105 + printk("pti_st_send_private_message_code_cmd Couldn't get a free MF from inboundqport on scsi No. %d.\n", p->host_no);
\r
9108 + add_timer(&priv_msg_timer);
\r
9109 + spin_unlock_irqrestore(&p->spin_lock, cpu_flags);
\r
9111 + interruptible_sleep_on(&PrivMsgWaitQ);
\r
9113 + if(cmd->result != DID_OK)
\r
9121 +//-----------------------------------------------------------------
\r
9123 +int pti_stdev_ioctl(struct inode *inodep,
\r
9124 + struct file *filep,
\r
9125 + unsigned int req,
\r
9126 + unsigned long arg)
\r
9128 + SRB_IO_CONTROL *usr_srbp = (SRB_IO_CONTROL *)arg;
\r
9129 + PTI_STDEV_GET_CONFIG_BUFFER *usr_confbufp =
\r
9130 + (PTI_STDEV_GET_CONFIG_BUFFER *)arg;
\r
9131 + PTI_STDEV_INBUFFER *usr_inbufp = (PTI_STDEV_INBUFFER *)arg;
\r
9133 + SRB_IO_CONTROL *srbp = NULL;
\r
9134 + PTI_STDEV_GET_CONFIG_BUFFER *confbufp = NULL;
\r
9135 + PTI_STDEV_INBUFFER *inbufp = NULL;
\r
9137 + PI2O_CONFIG_QUERY ConfigQuyPtr = NULL;
\r
9138 + PI2O_DEVICE_DESCRIPTOR DevDescriptorPtr = NULL;
\r
9139 + PI2O_PARAM_SCALAR_OPERATION ParamScalarPtr = NULL;
\r
9140 + USHORT *TargetTIDp = NULL;
\r
9141 + USHORT *OrganizationIDp = NULL;
\r
9142 + USHORT *XFunctionCodep = NULL;
\r
9143 + UCHAR *InputAddr = NULL;
\r
9144 + UCHAR *OutputAddr = NULL;
\r
9146 + void *bufferp = NULL;
\r
9147 + unsigned long offset;
\r
9148 + unsigned long ret;
\r
9150 + int aptno = MINOR(inodep->i_rdev);
\r
9151 + struct pti_st_host *p = pti_st_hostp[aptno];
\r
9153 + if(!pti_st_hostp[aptno] ||
\r
9154 + pti_st_hostp[aptno]->major <= 0 ||
\r
9155 + pti_st_hostp[aptno]->major != MAJOR(inodep->i_rdev))
\r
9156 + return(-ENODEV);
\r
9158 + if(pti_st_hostp[aptno]->counter <= 0) {
\r
9162 + bufferp = pti_st_hostp[aptno]->pti_stdev_bufferp;
\r
9163 + memset(bufferp, 0, sizeof(PTI_STDEV_INBUFFER));
\r
9165 + srbp = (SRB_IO_CONTROL *)bufferp;
\r
9168 + case IOCTL_SUPERTRAK_GETVERSION:
\r
9169 + case IOCTL_FLUSH_CACHE_REQUEST:
\r
9170 + ret = copy_from_user(srbp,
\r
9172 + sizeof(SRB_IO_CONTROL));
\r
9174 + return(-EFAULT);
\r
9177 + case IOCTL_GET_CONFIG_INFO:
\r
9178 + confbufp = (PTI_STDEV_GET_CONFIG_BUFFER *)bufferp;
\r
9180 + ret = copy_from_user(confbufp,
\r
9182 + sizeof(PTI_STDEV_GET_CONFIG_BUFFER));
\r
9184 + return(-EFAULT);
\r
9188 + case IOCTL_PRIVATE_MESSAGE_CODE:
\r
9189 + case IOCTL_PARAMS_GET_REQUEST:
\r
9190 + inbufp = (PTI_STDEV_INBUFFER *)bufferp;
\r
9192 + ret = copy_from_user(inbufp,
\r
9194 + sizeof(PTI_STDEV_INBUFFER));
\r
9196 + return(-EFAULT);
\r
9201 + return(-EINVAL);
\r
9204 + if(pti_stdev_strncmp(srbp->Signature, SUPERTRAK_SIGNATURE, SUPERTRAK_SIG_LEN))
\r
9205 + return(-EINVAL);
\r
9208 + case IOCTL_SUPERTRAK_GETVERSION:
\r
9209 + srbp->ControlCode = (VERSIONHI | (VERSIONLO << 16));
\r
9210 + ret = copy_to_user(usr_srbp,
\r
9212 + sizeof(SRB_IO_CONTROL));
\r
9214 + return(-EINVAL);
\r
9218 + case IOCTL_GET_CONFIG_INFO:
\r
9219 + ConfigQuyPtr = (PI2O_CONFIG_QUERY)((UCHAR *)confbufp+sizeof(SRB_IO_CONTROL));
\r
9220 + DevDescriptorPtr = (PI2O_DEVICE_DESCRIPTOR)((UCHAR *)confbufp+
\r
9221 + + sizeof(SRB_IO_CONTROL)
\r
9222 + + sizeof(I2O_CONFIG_QUERY));
\r
9225 + * fill the I2O_DEVICE_DESCRIPTOR structure
\r
9229 + while(pti_st_hostp[aptno]->LctEntryTable[i].TableEntrySize == 0x09)
\r
9231 + if (pti_st_hostp[aptno]->LctEntryTable[i].ClassID.Class==ConfigQuyPtr->ClassID.Class &&
\r
9232 + pti_st_hostp[aptno]->LctEntryTable[i].SubClassInfo==ConfigQuyPtr->SubClassID)
\r
9235 + * fill the LCT structure
\r
9237 + memcpy((void*)&DevDescriptorPtr->LCT,
\r
9238 + (void*)&pti_st_hostp[aptno]->LctEntryTable[i],
\r
9239 + sizeof(I2O_LCT_ENTRY));
\r
9247 + * Get IOP Description
\r
9249 + DevDescriptorPtr->IOP.IOPNumber = ConfigQuyPtr->IOPNumber;
\r
9250 + DevDescriptorPtr->IOP.IOPCapabilities = pti_st_hostp[aptno]->IopStatus.IopCapabilities;
\r
9251 + DevDescriptorPtr->IOP.IOPState = pti_st_hostp[aptno]->IopStatus.IopState;
\r
9252 + DevDescriptorPtr->IOP.I2OVersion = pti_st_hostp[aptno]->IopStatus.I2oVersion;
\r
9253 + DevDescriptorPtr->IOP.MessengerType = pti_st_hostp[aptno]->IopStatus.MessengerType;
\r
9254 + DevDescriptorPtr->IOP.MaxMessageFrameSize = pti_st_hostp[aptno]->IopStatus.InboundMFrameSize;
\r
9255 + DevDescriptorPtr->IOP.ExpectedLCTSize = pti_st_hostp[aptno]->IopStatus.ExpectedLCTSize;
\r
9256 + DevDescriptorPtr->IOP.MaxInboundMFrames = pti_st_hostp[aptno]->IopStatus.MaxInboundMFrames;
\r
9257 + DevDescriptorPtr->IOP.InitialInboundMFrames = pti_st_hostp[aptno]->IopStatus.CurrentInboundMFrames;
\r
9258 + DevDescriptorPtr->IOP.Reserved = pti_st_hostp[aptno]->IopStatus.reserved;
\r
9260 + ret = copy_to_user(usr_confbufp,
\r
9262 + sizeof(PTI_STDEV_GET_CONFIG_BUFFER));
\r
9264 + return(-EINVAL);
\r
9268 + case IOCTL_PRIVATE_MESSAGE_CODE:
\r
9270 + * read the TargetTID, OrganizationID and XFunctionCode
\r
9272 + offset = sizeof(SRB_IO_CONTROL) + sizeof(ULONG);
\r
9273 + TargetTIDp = (USHORT *)((UCHAR *)inbufp + offset);
\r
9275 + offset += sizeof(USHORT);
\r
9276 + OrganizationIDp = (USHORT *) ((UCHAR *)inbufp + offset);
\r
9278 + offset += sizeof(USHORT);
\r
9279 + XFunctionCodep = (USHORT *) ((UCHAR *)inbufp + offset);
\r
9281 + offset += sizeof(USHORT);
\r
9282 + InputAddr = (UCHAR *)inbufp + offset;
\r
9283 + OutputAddr = InputAddr + 0x800;
\r
9285 + /*** Send Private Message ***/
\r
9286 + retval = pti_st_send_private_message_code_cmd(pti_st_hostp[aptno], 20, *TargetTIDp,
\r
9287 + *XFunctionCodep, *OrganizationIDp,
\r
9288 + 0x800, InputAddr, 0x800, OutputAddr);
\r
9289 + if(retval == 0) {
\r
9290 + ret = copy_to_user(usr_inbufp, inbufp,sizeof(PTI_STDEV_INBUFFER));
\r
9292 + return(-EINVAL);
\r
9300 + case IOCTL_PARAMS_GET_REQUEST:
\r
9302 + offset = sizeof(SRB_IO_CONTROL) + sizeof(ULONG);
\r
9303 + TargetTIDp = (USHORT *)((UCHAR *)inbufp + offset);
\r
9305 + offset += sizeof(USHORT);
\r
9306 + ParamScalarPtr = (PI2O_PARAM_SCALAR_OPERATION)((UCHAR *)inbufp + offset);
\r
9308 + InputAddr = (UCHAR *)((UCHAR *)inbufp + offset);
\r
9310 + for(ret = 0; ret < 5; ret++)
\r
9312 + for(i = 0; i < p->scb_data->maxscbs; i++)
\r
9313 + if(p->scb_data->scb_array[i]->flags&SCB_ACTIVE)
\r
9315 + if(i >= p->scb_data->maxscbs) { /* card is idel */
\r
9321 + if(ret >= 5) { /* the cards is busy */
\r
9328 + * Disable interrupt
\r
9330 + pti_st_hostp[aptno]->p_atu->OutIntMask = 0x000000fc;
\r
9332 + PTI_UtilParamsGet(pti_st_hostp[aptno],
\r
9334 + ParamScalarPtr->OpBlock.FieldCount,
\r
9338 + if (pti_st_waitreplymsg(pti_st_hostp[aptno])
\r
9339 + != I2O_REPLY_STATUS_SUCCESS)
\r
9341 + printk("!BAD reply after sending UtilParamsGetMessage!\n");
\r
9348 + * Enable interrupt
\r
9350 + pti_st_hostp[aptno]->p_atu->OutIntMask = 0x00000000;
\r
9354 + if(retval == 0) {
\r
9355 + ret = copy_to_user(usr_inbufp,
\r
9357 + sizeof(PTI_STDEV_INBUFFER));
\r
9359 + return(-EINVAL);
\r
9366 + case IOCTL_FLUSH_CACHE_REQUEST:
\r
9367 + if(srbp->TimeOut) {
\r
9368 + ret = pti_st_flushcache(srbp->TimeOut);
\r
9370 + ret = pti_st_flushcache(FLUSHCACHE_TIMEOUT_DEFULT);
\r
9379 + * Support for loading low-level scsi drivers using the linux kernel loadable
\r
9380 + * module interface.
\r
9382 + * To use, the host adapter should first define and initialize the variable
\r
9383 + * driver_template (datatype Scsi_Host_Template), and then include this file.
\r
9384 + * This should also be wrapped in a #ifdef MODULE/#endif.
\r
9386 + * The low -level driver must also define a release function which will
\r
9387 + * free any irq assignments, release any dma channels, release any I/O
\r
9388 + * address space that might be reserved, and otherwise clean up after itself.
\r
9389 + * The idea is that the same driver should be able to be reloaded without
\r
9390 + * any difficulty. This makes debugging new drivers easier, as you should
\r
9391 + * be able to load the driver, test it, unload, modify and reload.
\r
9393 + * One *very* important caveat. If the driver may need to do DMA on the
\r
9394 + * ISA bus, you must have unchecked_isa_dma set in the device template,
\r
9395 + * even if this might be changed during the detect routine. This is
\r
9396 + * because the shpnt structure will be allocated in a special way so that
\r
9397 + * it will be below the appropriate DMA limit - thus if your driver uses
\r
9398 + * the hostdata field of shpnt, and the board must be able to access this
\r
9399 + * via DMA, the shpnt structure must be in a DMA accessible region of
\r
9400 + * memory. This comment would be relevant for something like the buslogic
\r
9401 + * driver where there are many boards, only some of which do DMA onto the
\r
9402 + * ISA bus. There is no convenient way of specifying whether the host
\r
9403 + * needs to be in a ISA DMA accessible region of memory when you call
\r
9404 + * scsi_register.
\r
9407 +//------------- Added by dingo, 2002/7/22 -------------
\r
9408 +static int power_off_notifier_func(struct notifier_block *pnb,
\r
9409 + unsigned long code, void *unused)
\r
9411 + pti_st_flushcache(FLUSHCACHE_TIMEOUT_DEFULT);
\r
9412 + return NOTIFY_DONE;
\r
9415 +static struct notifier_block pti_power_off_nb={
\r
9416 + power_off_notifier_func, NULL, 0
\r
9418 +//-----------------------------------------------------
\r
9420 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,0) /* > 2.4.0 */
\r
9422 +static Scsi_Host_Template pti_st_driver_template = PTI_ST;
\r
9424 +static int __init init_this_scsi_driver(void)
\r
9427 + pti_st_driver_template.module = THIS_MODULE;
\r
9428 + scsi_register_module(MODULE_SCSI_HA, &pti_st_driver_template);
\r
9430 + pti_st_fops.owner= THIS_MODULE;
\r
9431 + if (!pti_st_driver_template.present ||
\r
9432 + (major = register_chrdev(0, PTCNTL_DEV_NAME, (struct file_operations *)&pti_st_fops)) < 0)
\r
9434 + if(pti_st_driver_template.present)
\r
9435 + scsi_unregister_module(MODULE_SCSI_HA, &pti_st_driver_template);
\r
9436 + return(-ENODEV);
\r
9439 + for(i = 0; i < MAX_ADAPTORS; i++)
\r
9441 + if(pti_st_hostp[i])
\r
9443 + pti_st_hostp[i]->counter = 0;
\r
9444 + pti_st_hostp[i]->major = major;
\r
9447 + //------------ added by dingo, 2002/7/22 ------------
\r
9448 + if(register_reboot_notifier(&pti_power_off_nb)){
\r
9449 + printk(KERN_ERR"pti_st: Can not register power notifer notifer!\n");
\r
9452 + //---------------------------------------------------
\r
9458 +static void __exit exit_this_scsi_driver(void)
\r
9462 + unregister_reboot_notifier(&pti_power_off_nb); // added by dingo, 2002/7/22
\r
9464 + for(i = 0; i < MAX_ADAPTORS; i++)
\r
9465 + if(pti_st_hostp[i])
\r
9468 + if(i < MAX_ADAPTORS) {
\r
9469 + if(pti_st_hostp[i]->major > 0)
\r
9470 + unregister_chrdev(pti_st_hostp[i]->major,PTCNTL_DEV_NAME);
\r
9471 + if(pti_st_hostp[i]) {
\r
9472 + scsi_unregister_module(MODULE_SCSI_HA, &pti_st_driver_template);
\r
9478 +module_init(init_this_scsi_driver);
\r
9479 +module_exit(exit_this_scsi_driver);
\r
9481 +#else /* > 2.4.0 */
\r
9482 +Scsi_Host_Template pti_st_driver_template = PTI_ST;
\r
9484 +int init_module(void)
\r
9487 + pti_st_driver_template.module = &__this_module;
\r
9488 + scsi_register_module(MODULE_SCSI_HA, &pti_st_driver_template);
\r
9490 + if (!pti_st_driver_template.present ||
\r
9491 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
\r
9492 + (major = register_chrdev(0, PTCNTL_DEV_NAME, (struct file_operations *)&pti_st_fops)) < 0)
\r
9494 + (major = register_chrdev(0, PTCNTL_DEV_NAME, (struct file_operations *)&pti_st_fops)) < 0)
\r
9497 + if(pti_st_driver_template.present)
\r
9498 + scsi_unregister_module(MODULE_SCSI_HA, &pti_st_driver_template);
\r
9502 + for(i = 0; i < MAX_ADAPTORS; i++)
\r
9504 + if(pti_st_hostp[i])
\r
9506 + pti_st_hostp[i]->counter = 0;
\r
9507 + pti_st_hostp[i]->major = major;
\r
9510 + //------------ added by dingo, 2002/7/22 ------------
\r
9511 + if(register_reboot_notifier(&pti_power_off_nb)){
\r
9512 + printk(KERN_ERR"pti_st: Can not register power notifer notifer!\n");
\r
9515 + //---------------------------------------------------
\r
9520 +void cleanup_module(void)
\r
9524 + unregister_reboot_notifier(&pti_power_off_nb); // added by dingo, 2002/7/22
\r
9526 + for(i = 0; i < MAX_ADAPTORS; i++)
\r
9527 + if(pti_st_hostp[i])
\r
9530 + if(i < MAX_ADAPTORS) {
\r
9531 + if(pti_st_hostp[i]->major > 0)
\r
9532 + unregister_chrdev(pti_st_hostp[i]->major,PTCNTL_DEV_NAME);
\r
9533 + if(pti_st_hostp[i]) {
\r
9534 + scsi_unregister_module(MODULE_SCSI_HA, &pti_st_driver_template);
\r
9540 +#endif /* > 2.4.0 */
\r
9543 diff -Nur linux-2.4.20.org/drivers/scsi/pti_st.h linux-2.4.20/drivers/scsi/pti_st.h
9544 --- linux-2.4.20.org/drivers/scsi/pti_st.h Wed Nov 5 08:47:58 2003
9545 +++ linux-2.4.20/drivers/scsi/pti_st.h Wed Oct 16 00:00:00 2002
9547 -/*+M*************************************************************************
9548 - * Promise SuperTrak device driver for Linux.
9550 - * Copyright (c) 2001 Promise Technology, Inc.
9552 - * This program is free software; you can redistribute it and/or modify
9553 - * it under the terms of the GNU General Public License as published by
9554 - * the Free Software Foundation; either version 2 of the License, or
9555 - * (at your option) any later version.
9557 - * This program is distributed in the hope that it will be useful,
9558 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
9559 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9560 - * GNU General Public License for more details.
9562 - * You should have received a copy of the GNU General Public License
9563 - * along with this program; if not, write to the Free Software
9564 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
9566 - * --------------------------------------------------------------------------
9567 - * Copyright (c) 1999-2001 Promise Technology, Inc.
9568 - * All rights reserved.
9570 - * Redistribution and use in source and binary forms, with or without
9571 - * modification, are permitted provided that the following conditions
9573 - * 1. Redistributions of source code must retain the above copyright
9574 - * notice, this list of conditions, and the following disclaimer,
9575 - * without modification, immediately at the beginning of the file.
9576 - * 2. Redistributions in binary form must reproduce the above copyright
9577 - * notice, this list of conditions and the following disclaimer in the
9578 - * documentation and/or other materials provided with the distribution.
9579 - * 3. The name of the author may not be used to endorse or promote products
9580 - * derived from this software without specific prior written permission.
9582 - * Where this Software is combined with software released under the terms of
9583 - * the GNU Public License ("GPL") and the terms of the GPL would require the
9584 - * combined work to also be released under the terms of the GPL, the terms
9585 - * and conditions of this License will apply in addition to those of the
9586 - * GPL with the exception of any terms or conditions of this License that
9587 - * conflict with, or are expressly prohibited by, the GPL.
9589 - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
9590 - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9591 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
9592 - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
9593 - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
9594 - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
9595 - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
9596 - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
9597 - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
9598 - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
9602 - *-M*************************************************************************/
9604 -/**************************************************************************
9605 - * File: pti_st.h Driver Declaraitons for pti_st.c.
9606 - **************************************************************************/
9609 -#include "i2omstor.h"
9610 -#include "i2oexec.h"
9612 -#include "i2odef.h"
9618 -#ifndef LINUX_VERSION_CODE
9619 -#include <linux/version.h>
9622 -#ifndef KERNEL_VERSION
9623 -#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
9626 -/* INQUIRY data format */
9633 - unchar add_length;
9638 - unchar product[16];
9639 - unchar revision[4];
9642 -/* READ_CAPACITY data format */
9645 - u32 last_block_no;
9649 -/* REQUEST_SENSE data format */
9656 - unchar add_length;
9661 - unchar key_spec[3];
9664 -/* MODE_SENSE data format */
9669 - unchar data_length;
9677 - unchar block_count[3];
9679 - unchar block_length[3];
9683 -extern int PTI_procfile_read(char *, char **, off_t, int, int, int);
9684 -extern const char *PTI_ST_info(struct Scsi_Host *);
9685 -extern int pti_st_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
9686 -extern int pti_st_biosparam(Disk *, kdev_t, int[]);
9687 -extern int pti_st_detect(Scsi_Host_Template *);
9688 -extern int pti_st_reset(Scsi_Cmnd *, unsigned int);
9689 -extern int pti_st_abort(Scsi_Cmnd *);
9692 -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,65)
9697 - proc_info: PTI_procfile_read, \
9699 - detect: pti_st_detect, \
9700 - release: pti_st_release, \
9701 - info: PTI_ST_info, \
9703 - queuecommand: pti_st_queue, \
9704 - eh_strategy_handler: NULL, \
9705 - eh_abort_handler: NULL, \
9706 - eh_device_reset_handler: NULL, \
9707 - eh_bus_reset_handler: NULL, \
9708 - eh_host_reset_handler: NULL, \
9709 - abort: pti_st_abort, \
9710 - reset: pti_st_reset, \
9711 - slave_attach: NULL, \
9712 - bios_param: pti_st_biosparam, \
9715 - sg_tablesize: 0, \
9718 - unchecked_isa_dma: 0, \
9719 - use_clustering: ENABLE_CLUSTERING, \
9720 - use_new_eh_code: 0 \
9725 - usage_count: NULL, \
9727 - proc_info: PTI_procfile_read, \
9729 - detect: pti_st_detect, \
9730 - release: pti_st_release, \
9731 - info: PTI_ST_info, \
9733 - queuecommand: pti_st_queue, \
9734 - abort: pti_st_abort, \
9735 - reset: pti_st_reset, \
9736 - slave_attach: NULL, \
9737 - bios_param: pti_st_biosparam, \
9738 - can_queue: 32, /* max simultaneous cmds */ \
9739 - this_id: -1, /* scsi id of host adapter */ \
9740 - sg_tablesize: 0, /* max scatter-gather cmds */ \
9741 - cmd_per_lun: 3, /* cmds per lun (linked cmds) */ \
9742 - present: 0, /* number of 7xxx's present */ \
9743 - unchecked_isa_dma: 0, /* no memory DMA restrictions */ \
9744 - use_clustering: ENABLE_CLUSTERING \
9752 -#define NULL ((void *) 0)
9754 -#define DEBUG (FALSE)
9756 -#define MAX(x,y) (((x) > (y)) ? (x) : (y))
9757 -#define MIN(x,y) (((x) < (y)) ? (x) : (y))
9758 -#define ABSDIFF(x, y) (((x) > (y)) ? ((x) - (y)) : ((y) - (x)))
9759 -#define APOGEE(this,max) ((this>max) ? max : this)
9761 -#if !defined(MAX_ADAPTORS)
9762 -#define MAX_ADAPTORS 4
9765 -#define MAX_DRIVES (8)
9766 -#define SECTOR_SIZE (0x200)
9767 -// 512 byte sectors
9769 -// Promise Organization ID
9770 -#define MY_IOP_ID 0x10
9771 -#define PROMISE_ORG_ID 0x91
9773 -// ISM String Identity
9774 -#define PTI_RAID 'I2O RAID DEVICE'
9775 -#define PTI_IDE 'IDE DEVICE'
9777 -#define VERSIONHI (0x0001)
9778 -#define VERSIONLO (0x000B)
9780 -typedef struct _DRIVE
9782 - char present; // boolean set if drive present
9783 - unsigned long sectors; // LBA drive size in sectors
9786 -typedef struct _I2ODISK
9788 - int present; /* TRUE / FALSE */
9789 - char DiskModel[I2O_DEVID_PRODUCT_INFO_SZ+4];
9790 - char Vendor[I2O_DEVID_VENDOR_INFO_SZ+4];
9791 - char ProductRevLevel[I2O_DEVID_REV_LEVEL_SZ+4];
9792 - unsigned int LocalTID;
9793 - unsigned int lastcyl; // total cyl cnt - 1 = last cyl position
9794 - unsigned char lasthead; // total head cnt - 1 = last head position
9795 - unsigned char sector; // sector starts at position 1
9796 - unsigned short resvered; // Padding with two bytes
9797 - unsigned long lastLBA; // total LBA cnt - 1 = last LBA position
9798 - unsigned long DeviceFlag;
9799 -}I2ODISK, *PI2ODISK;
9801 -typedef struct _I2OARRAY
9803 - unsigned int RaidMode;
9804 -}I2OARRAY, *PI2OARRAY;
9806 -/* PTI_ST Private Message Structure */
9807 -typedef struct _PTI_ST_PRIVATE_MESSAGE {
9808 - I2O_PRIVATE_MESSAGE_FRAME MyStandMsg;
9809 - I2O_SGE_PAGE_ELEMENT InSGL;
9810 - I2O_SGE_PAGE_ELEMENT OutSGL;
9811 -} PTI_ST_PRIVATE_MESSAGE, *PPTI_ST_PRIVATE_MESSAGE;
9814 - * Maximum number of SG segments these cards can support.
9816 -#define PTI_ST_MAX_SG 12 /* 16 */
9817 -#define PTI_ST_MAXSCB 32
9819 -#define PTI_ST_RESET_DELAY 5
9821 -typedef PI2O_BSA_READ_MESSAGE PI2O_BSA_RW_MESSAGE;
9825 - SCB_FREE = 0x0000,
9826 - SCB_WAITINGQ = 0x0002,
9827 - SCB_ACTIVE = 0x0004,
9828 - SCB_SENSE = 0x0008,
9829 - SCB_ABORT = 0x0010,
9830 - SCB_DEVICE_RESET = 0x0020,
9831 - SCB_RESET = 0x0040,
9832 - SCB_RECOVERY_SCB = 0x0080,
9833 - SCB_WAS_BUSY = 0x0100,
9834 - SCB_MSGOUT_SENT = 0x0200,
9835 - SCB_MSGOUT_SDTR = 0x0400,
9836 - SCB_MSGOUT_WDTR = 0x0800,
9837 - SCB_MSGOUT_BITS = SCB_MSGOUT_SENT |
9840 - SCB_QUEUED_ABORT = 0x1000,
9841 - SCB_QUEUED_FOR_DONE = 0x2000
9847 - PI2O_MESSAGE_FRAME *mf; /* corresponding hardware scb */
9848 - Scsi_Cmnd *cmd; /* Scsi_Cmnd for this scb */
9849 - struct pti_st_scb *q_next; /* next scb in queue */
9850 - volatile scb_flag_type flags; /* current state of scb */
9851 - unsigned char tag;
9852 - unsigned char sg_count;
9853 - unsigned char sense_cmd[6]; /*
9854 - * Allocate 6 characters for
9857 - unsigned int sg_length; /* We init this during buildscb so we
9858 - * don't have to calculate anything
9859 - * during underflow/overflow/stat
9862 - void *kmalloc_ptr;
9867 - struct pti_st_scb *head;
9868 - struct pti_st_scb *tail;
9873 - scb_queue_type free_scbs; /*
9874 - * SCBs assigned to free slot on
9875 - * card (no paging required)
9877 - struct pti_st_scb *scb_array[PTI_ST_MAXSCB];
9878 - unsigned char maxmfs; /* hardware scbs */
9879 - unsigned char maxscbs; /* max scbs including pageable scbs */
9884 - * Message Unit CSR definitions for RedCreek PCI45 board
9886 -typedef struct tag_atu
9888 - volatile unsigned long APICRegSel; /* APIC Register Select */
9889 - volatile unsigned long reserved0;
9890 - volatile unsigned long APICWinReg; /* APIC Window Register */
9891 - volatile unsigned long reserved1;
9892 - volatile unsigned long InMsgReg0; /* inbound message register 0 */
9893 - volatile unsigned long InMsgReg1; /* inbound message register 1 */
9894 - volatile unsigned long OutMsgReg0; /* outbound message register 0 */
9895 - volatile unsigned long OutMsgReg1; /* outbound message register 1 */
9896 - volatile unsigned long InDoorReg; /* inbound doorbell register */
9897 - volatile unsigned long InIntStat; /* inbound interrupt status register */
9898 - volatile unsigned long InIntMask; /* inbound interrupt mask register */
9899 - volatile unsigned long OutDoorReg; /* outbound doorbell register */
9900 - volatile unsigned long OutIntStat; /* outbound interrupt status register */
9901 - volatile unsigned long OutIntMask; /* outbound interrupt mask register */
9902 - volatile unsigned long reserved2;
9903 - volatile unsigned long reserved3;
9904 - volatile unsigned long InQueue; /* inbound queue port */
9905 - volatile unsigned long OutQueue; /* outbound queue port */
9906 - volatile unsigned long reserved4;
9907 - volatile unsigned long reserver5;
9908 - /* RedCreek extension */
9909 - volatile unsigned long EtherMacLow;
9910 - volatile unsigned long EtherMacHi;
9911 - volatile unsigned long IPaddr;
9912 - volatile unsigned long IPmask;
9917 - PSTC_FNONE = 0x00000000,
9918 - PSTC_PAGESCBS = 0x00000001,
9919 - PSTC_CHANNEL_B_PRIMARY = 0x00000002,
9920 - PSTC_USEDEFAULTS = 0x00000004,
9921 - PSTC_INDIRECT_PAGING = 0x00000008,
9922 - PSTC_CHNLB = 0x00000020,
9923 - PSTC_CHNLC = 0x00000040,
9924 - PSTC_EXTEND_TRANS_A = 0x00000100,
9925 - PSTC_EXTEND_TRANS_B = 0x00000200,
9926 - PSTC_TERM_ENB_A = 0x00000400,
9927 - PSTC_TERM_ENB_SE_LOW = 0x00000400,
9928 - PSTC_TERM_ENB_B = 0x00000800,
9929 - PSTC_TERM_ENB_SE_HIGH = 0x00000800,
9930 - PSTC_HANDLING_REQINITS = 0x00001000,
9931 -#define PSTC_IN_IOCTL_BIT PSTC_HANDLING_REQINITS
9932 - PSTC_TARGETMODE = 0x00002000,
9933 - PSTC_NEWEEPROM_FMT = 0x00004000,
9935 - * Here ends the FreeBSD defined flags and here begins the linux defined
9936 - * flags. NOTE: I did not preserve the old flag name during this change
9937 - * specifically to force me to evaluate what flags were being used properly
9938 - * and what flags weren't. This way, I could clean up the flag usage on
9939 - * a use by use basis. Doug Ledford
9941 - PSTC_RESET_DELAY = 0x00080000,
9942 - PSTC_A_SCANNED = 0x00100000,
9943 - PSTC_B_SCANNED = 0x00200000,
9944 - PSTC_MULTI_CHANNEL = 0x00400000,
9945 - PSTC_BIOS_ENABLED = 0x00800000,
9946 - PSTC_SEEPROM_FOUND = 0x01000000,
9947 - PSTC_TERM_ENB_LVD = 0x02000000,
9948 - PSTC_ABORT_PENDING = 0x04000000,
9949 - PSTC_RESET_PENDING = 0x08000000,
9950 -#define PSTC_IN_ISR_BIT 28
9951 - PSTC_IN_ISR = 0x10000000,
9952 - PSTC_IN_ABORT = 0x20000000,
9953 - PSTC_IN_RESET = 0x40000000,
9954 - PSTC_EXTERNAL_SRAM = 0x80000000
9957 -#define MAX_LCT_ENTRY 32
9959 -typedef struct _outboundBuff_t {
9960 - U8 outboundBuff[32][32*4];
9966 - * This is the first 64 bytes in the host struct
9970 - * We are grouping things here....first, items that get either read or
9971 - * written with nearly every interrupt
9973 - volatile pstc_flag_type flags;
9974 - unsigned int mbase; /* card base address */
9975 - volatile unsigned char *maddr;
9976 - PATU p_atu; /* ptr to ATU register block */
9978 -#if defined(MYDEBUG) && 0
9979 - U8 replyBuffer[16*1024];
9980 - U8 messageBuffer[256];
9981 - U8 outboundBuffer[32][32*4];
9983 - outboundBuff_t *outboundBufferp;
9985 - U8 *messageBufferp;
9987 - PU8 pLinOutMsgBlock;
9988 - U32 outMsgBlockPhyAddr;
9989 - scb_data_type *scb_data;
9990 - struct pti_st_cmd_queue
9996 - volatile scb_queue_type waiting_scbs;
9999 - * Things read/written on nearly every entry into pti_st_queue()
10001 - volatile unsigned char activescbs; /* active scbs */
10002 - volatile unsigned char max_activescbs;
10005 -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0)
10006 - spinlock_t spin_lock;
10007 - volatile unsigned char cpu_lock_count[NR_CPUS];
10011 - * We put the less frequently used host structure items after the more
10012 - * frequently used items to try and ease the burden on the cache subsystem.
10013 - * These entries are not *commonly* accessed, whereas the preceding entries
10014 - * are accessed very often. The only exceptions are the qinfifo, qoutfifo,
10015 - * and untagged_scbs array. But, they are often accessed only once and each
10016 - * access into these arrays is likely to blow a cache line, so they are put
10017 - * down here so we can minimize the number of cache lines required to hold
10018 - * the preceeding entries.
10021 - unsigned char pci_irq; /* IRQ for this adapter */
10022 - int scsi_id; /* host adapter SCSI ID */
10024 -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
10025 - struct pci_dev *pdev;
10028 - unsigned char pci_bus;
10029 - unsigned char pci_device_fn;
10030 - struct Scsi_Host *host; /* pointer to scsi host */
10031 - int host_no; /* SCSI host number */
10033 - I2O_LCT_ENTRY LctEntryTable[MAX_LCT_ENTRY];
10034 - I2O_EXEC_STATUS_GET_REPLY IopStatus;
10036 - int TotalDiskCount;
10037 - I2ODISK I2ODisk[MAX_DRIVES];
10039 - /* PTI_STCNTL device Variable */
10040 - void *pti_stdev_bufferp;
10041 - int major; /* control device's major */
10042 - int counter; /*counter of using control device*/
10045 -extern struct pti_st_host *pti_st_hostp[MAX_ADAPTORS];
10048 -//---------------------------------------------------------------------------
10049 -// I960RP Memory-Mapper Register PCI Addressing Offset
10050 -#define ARSR_OFFSET 0 //APICReg
10051 -#define AWR_OFFSET 0x08 //APCIWinReg
10052 -#define IMR0_OFFSET 0x10 //InboundMsgReg0
10053 -#define IMR1_OFFSET 0x14 //InboundMsgReg1
10054 -#define OMR0_OFFSET 0x18 //OutboundMsgReg0
10055 -#define OMR1_OFFSET 0x1c //OutboundMsgReg1
10056 -#define IDR_OFFSET 0x20 //InboundDBellReg
10057 -#define IISR_OFFSET 0x24 //InboundIntStatusReg
10058 -#define IIMR_OFFSET 0x28 //InboundIntMaskReg
10059 -#define ODR_OFFSET 0x2c //OutboundDBellReg
10060 -#define OISR_OFFSET 0x30 //OutboundIntStatusReg
10061 -#define OIMR_OFFSET 0x34 //OutboundIntMaskReg
10062 -#define INBOUNDQPORT 0x40
10063 -#define OUTBOUNDQPORT 0x44
10064 -#define MUCR_OFFSET 0x50 //MUConfReg
10065 -#define QBAR_OFFSET 0x54 //QueueBaseAddReg
10067 -//---------------------------------------------------------------------------
10068 -// Bit Definition for InboundIntStatusReg (IISR)
10069 -#define APICW_Status 0x100 //APIC Window Interrupt (R/C)
10070 -#define APICR_Status 0x80 //APIC Register Select Interrupt (R/C)
10071 -#define IR_Status 0x40 //Index Register Interrupt (R/C)
10072 -#define OBFQ_OF_Status 0x20 //Outbound Free Queue OverFlow Interrupt (R/C)
10073 -#define IBPQ_Status 0x10 //Inbound Post Queue Interrupt (R/C)
10074 -#define NMI_DB_Status 0x08 //NMI Doorbell Interrupt (R/O)
10075 -#define IB_DB_Status 0x04 //Inbound Doorbell Interrupt (R/O)
10076 -#define IB_MSG1_Status 0x02 //Inbound Message 1 Interrupt (R/C)
10077 -#define IB_MSG0_Status 0x01 //Inbound Message 0 Interrupt (R/C)
10079 -// Bit Definition for InboundIntMaskReg (IIMR)
10080 -#define APICW_Mask 0x100 //APIC Windows Interrupt Mask (R/W)
10081 -#define APICRSI_Mask 0x80 //APIC Register Select Interrupt Mask (R/W)
10082 -#define IR_Mask 0x40 //Index Register Interrupt Mask (R/W)
10083 -#define OBFQ_OF_Mask 0x20 //Outbound Free Queue Overflow Interrupt Mask (R/W)
10084 -#define IBPQ_Mask 0x10 //Inbound Post Queue Interrupt Mask (R/W)
10085 -#define NMI_DB_Mask 0x08 //NMI Doorbell Interrupt Mask (R/W)
10086 -#define IB_DB_Mask 0x04 //Inbound DoorbellInterrupt Mask (R/W)
10087 -#define IB_MSG1_Mask 0x02 //Inbound Message 1 Interrupt Mask (R/W)
10088 -#define IB_MSG0_Mask 0x01 //Inbound Message 0 Interrupt Mask (R/W)
10090 -// Bit Definition for Outbound Interrupt Status Register (OISR)
10091 -#define PCI_INT_D_Status 0x80 //PCI Interrupt D (RO)
10092 -#define PCI_INT_C_Status 0x40 //PCI Interrupt C (RO)
10093 -#define PCI_INT_B_Status 0x20 //PCI Interrupt B (RO)
10094 -#define PCI_INT_A_Status 0x10 //PCI Interrupt A (RO)
10095 -#define OBPQ_INT_Status 0x08 //Outbound Post Queue Interrupt (RO)
10096 -#define OBDB_INT_Status 0x04 //Outbound Doorbell Interrupt (RO)
10097 -#define OBMSG1_INT_Status 0x02 //Outbound Message 1 Interrupt (PCI R/C)
10098 -#define OBMSG0_INT_Status 0x01 //Outbound Message 0 Interrupt (PCI R/C)
10100 -// Bit Definition for Outbound Interrupt Mask Register
10101 -#define PCI_INT_D_Mask 0x80 //PCI Interrupt D (RW)
10102 -#define PCI_INT_C_Mask 0x40 //PCI Interrupt C (RW)
10103 -#define PCI_INT_B_Mask 0x20 //PCI Interrupt B (RW)
10104 -#define PCI_INT_A_Mask 0x10 //PCI Interrupt A (RW)
10105 -#define OBPQ_INT_Mask 0x08 //Outbound Post Queue Interrupt Mask (RW)
10106 -#define OBDB_INT_Mask 0x04 //Outbound Doorbell Interrupt Mask (RW)
10107 -#define OBMSG1_INT_Mask 0x02 //Outbound Message 1 Interrupt Mask (RW)
10108 -#define OBMSG0_INT_Mask 0x01 //Outbound Message 0 Interrupt Mask (RW)
10110 -//---------------------------------------------------------------------------
10112 -#define IOPSTATE_INIT 0x01
10113 -#define IOPSTATE_RESET 0x02
10114 -#define IOPSTATE_HOLD 0x04
10115 -#define IOPSTATE_READY 0x05
10116 -#define IOPSTATE_OP 0x08
10117 -#define IOPSTATE_FAILED 0x10
10118 -#define IOPSTATE_FAULTED 0x11
10122 -#endif /* _pti_st_h */
10124 +/*+M*************************************************************************
\r
10125 + * Promise SuperTrak device driver for Linux.
\r
10127 + * Copyright (c) 2001 Promise Technology, Inc.
\r
10129 + * This program is free software; you can redistribute it and/or modify
\r
10130 + * it under the terms of the GNU General Public License as published by
\r
10131 + * the Free Software Foundation; either version 2 of the License, or
\r
10132 + * (at your option) any later version.
\r
10134 + * This program is distributed in the hope that it will be useful,
\r
10135 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
10136 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
10137 + * GNU General Public License for more details.
\r
10139 + * You should have received a copy of the GNU General Public License
\r
10140 + * along with this program; if not, write to the Free Software
\r
10141 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
10143 + * --------------------------------------------------------------------------
\r
10144 + * Copyright (c) 1999-2001 Promise Technology, Inc.
\r
10145 + * All rights reserved.
\r
10147 + * Redistribution and use in source and binary forms, with or without
\r
10148 + * modification, are permitted provided that the following conditions
\r
10150 + * 1. Redistributions of source code must retain the above copyright
\r
10151 + * notice, this list of conditions, and the following disclaimer,
\r
10152 + * without modification, immediately at the beginning of the file.
\r
10153 + * 2. Redistributions in binary form must reproduce the above copyright
\r
10154 + * notice, this list of conditions and the following disclaimer in the
\r
10155 + * documentation and/or other materials provided with the distribution.
\r
10156 + * 3. The name of the author may not be used to endorse or promote products
\r
10157 + * derived from this software without specific prior written permission.
\r
10159 + * Where this Software is combined with software released under the terms of
\r
10160 + * the GNU Public License ("GPL") and the terms of the GPL would require the
\r
10161 + * combined work to also be released under the terms of the GPL, the terms
\r
10162 + * and conditions of this License will apply in addition to those of the
\r
10163 + * GPL with the exception of any terms or conditions of this License that
\r
10164 + * conflict with, or are expressly prohibited by, the GPL.
\r
10166 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
\r
10167 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
\r
10168 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
\r
10169 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
\r
10170 + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\r
10171 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
\r
10172 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
\r
10173 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
\r
10174 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
\r
10175 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
\r
10179 + *-M*************************************************************************/
\r
10181 +/**************************************************************************
\r
10182 + * File: pti_st.h Driver Declaraitons for pti_st.c.
\r
10183 + **************************************************************************/
\r
10186 +#include "i2omstor.h"
\r
10187 +#include "i2oexec.h"
\r
10189 +#include "i2odef.h"
\r
10192 +#ifndef _pti_st_h
\r
10193 +#define _pti_st_h
\r
10195 +#ifndef LINUX_VERSION_CODE
\r
10196 +#include <linux/version.h>
\r
10199 +#ifndef KERNEL_VERSION
\r
10200 +#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
\r
10203 +/* INQUIRY data format */
\r
10206 + unchar type_qual;
\r
10207 + unchar modif_rmb;
\r
10208 + unchar version;
\r
10209 + unchar resp_aenc;
\r
10210 + unchar add_length;
\r
10211 + unchar reserved1;
\r
10212 + unchar reserved2;
\r
10214 + unchar vendor[8];
\r
10215 + unchar product[16];
\r
10216 + unchar revision[4];
\r
10219 +/* READ_CAPACITY data format */
\r
10222 + u32 last_block_no;
\r
10223 + u32 block_length;
\r
10224 +}pti_rdcap_data;
\r
10226 +/* REQUEST_SENSE data format */
\r
10229 + unchar errorcode;
\r
10233 + unchar add_length;
\r
10238 + unchar key_spec[3];
\r
10239 +}pti_sense_data;
\r
10241 +/* MODE_SENSE data format */
\r
10246 + unchar data_length;
\r
10247 + unchar med_type;
\r
10248 + unchar dev_par;
\r
10249 + unchar bd_length;
\r
10253 + unchar dens_code;
\r
10254 + unchar block_count[3];
\r
10255 + unchar reserved;
\r
10256 + unchar block_length[3];
\r
10258 +}pti_modep_data;
\r
10260 +extern int PTI_procfile_read(char *, char **, off_t, int, int, int);
\r
10261 +extern const char *PTI_ST_info(struct Scsi_Host *);
\r
10262 +extern int pti_st_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
\r
10263 +extern int pti_st_biosparam(Disk *, kdev_t, int[]);
\r
10264 +extern int pti_st_detect(Scsi_Host_Template *);
\r
10265 +extern int pti_st_reset(Scsi_Cmnd *, unsigned int);
\r
10266 +extern int pti_st_abort(Scsi_Cmnd *);
\r
10269 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,65)
\r
10270 +#define PTI_ST { \
\r
10272 + module: NULL, \
\r
10273 + proc_dir: NULL, \
\r
10274 + proc_info: PTI_procfile_read, \
\r
10276 + detect: pti_st_detect, \
\r
10277 + release: pti_st_release, \
\r
10278 + info: PTI_ST_info, \
\r
10279 + command: NULL, \
\r
10280 + queuecommand: pti_st_queue, \
\r
10281 + eh_strategy_handler: NULL, \
\r
10282 + eh_abort_handler: NULL, \
\r
10283 + eh_device_reset_handler: NULL, \
\r
10284 + eh_bus_reset_handler: NULL, \
\r
10285 + eh_host_reset_handler: NULL, \
\r
10286 + abort: pti_st_abort, \
\r
10287 + reset: pti_st_reset, \
\r
10288 + slave_attach: NULL, \
\r
10289 + bios_param: pti_st_biosparam, \
\r
10290 + can_queue: 12, \
\r
10292 + sg_tablesize: 0, \
\r
10293 + cmd_per_lun: 3, \
\r
10295 + unchecked_isa_dma: 0, \
\r
10296 + use_clustering: 0, \
\r
10297 + use_new_eh_code: 0, \
\r
10300 +#define PTI_ST { \
\r
10302 + usage_count: NULL, \
\r
10303 + proc_dir: NULL, \
\r
10304 + proc_info: PTI_procfile_read, \
\r
10306 + detect: pti_st_detect, \
\r
10307 + release: pti_st_release, \
\r
10308 + info: PTI_ST_info, \
\r
10309 + command: NULL, \
\r
10310 + queuecommand: pti_st_queue, \
\r
10311 + abort: pti_st_abort, \
\r
10312 + reset: pti_st_reset, \
\r
10313 + slave_attach: NULL, \
\r
10314 + bios_param: pti_st_biosparam, \
\r
10315 + can_queue: 12, /* max simultaneous cmds */ \
\r
10316 + this_id: -1, /* scsi id of host adapter */ \
\r
10317 + sg_tablesize: 0, /* max scatter-gather cmds */ \
\r
10318 + cmd_per_lun: 3, /* cmds per lun (linked cmds) */ \
\r
10319 + present: 0, /* number of 7xxx's present */ \
\r
10320 + unchecked_isa_dma: 0, /* no memory DMA restrictions */ \
\r
10321 + use_clustering: 0 \
\r
10329 +#define NULL ((void *) 0)
\r
10331 +#define DEBUG (FALSE)
\r
10333 +#define MAX(x,y) (((x) > (y)) ? (x) : (y))
\r
10334 +#define MIN(x,y) (((x) < (y)) ? (x) : (y))
\r
10335 +#define ABSDIFF(x, y) (((x) > (y)) ? ((x) - (y)) : ((y) - (x)))
\r
10336 +#define APOGEE(this,max) ((this>max) ? max : this)
\r
10338 +#if !defined(MAX_ADAPTORS)
\r
10339 +#define MAX_ADAPTORS 4
\r
10342 +#define MAX_DRIVES (8)
\r
10343 +#define SECTOR_SIZE (0x200)
\r
10344 +// 512 byte sectors
\r
10346 +// Promise Organization ID
\r
10347 +#define MY_IOP_ID 0x10
\r
10348 +#define PROMISE_ORG_ID 0x91
\r
10350 +// ISM String Identity
\r
10351 +#define PTI_RAID 'I2O RAID DEVICE'
\r
10352 +#define PTI_IDE 'IDE DEVICE'
\r
10354 +#define VERSIONHI (0x0001)
\r
10355 +#define VERSIONLO (0x0022)
\r
10357 +typedef struct _DRIVE
\r
10359 + char present; // boolean set if drive present
\r
10360 + unsigned long sectors; // LBA drive size in sectors
\r
10361 +}DRIVE, *ptrDRIVE;
\r
10363 +typedef struct _I2ODISK
\r
10365 + int present; /* TRUE / FALSE */
\r
10366 + char DiskModel[I2O_DEVID_PRODUCT_INFO_SZ+4];
\r
10367 + char Vendor[I2O_DEVID_VENDOR_INFO_SZ+4];
\r
10368 + char ProductRevLevel[I2O_DEVID_REV_LEVEL_SZ+4];
\r
10369 + unsigned int LocalTID;
\r
10370 + unsigned int lastcyl; // total cyl cnt - 1 = last cyl position
\r
10371 + unsigned char lasthead; // total head cnt - 1 = last head position
\r
10372 + unsigned char sector; // sector starts at position 1
\r
10373 + unsigned short resvered; // Padding with two bytes
\r
10374 + unsigned long lastLBA; // total LBA cnt - 1 = last LBA position
\r
10375 + unsigned long DeviceFlag;
\r
10376 +}I2ODISK, *PI2ODISK;
\r
10378 +typedef struct _I2OARRAY
\r
10380 + unsigned int RaidMode;
\r
10381 +}I2OARRAY, *PI2OARRAY;
\r
10383 +/* PTI_ST Private Message Structure */
\r
10384 +typedef struct _PTI_ST_PRIVATE_MESSAGE {
\r
10385 + I2O_PRIVATE_MESSAGE_FRAME MyStandMsg;
\r
10386 + I2O_SGE_PAGE_ELEMENT InSGL;
\r
10387 + I2O_SGE_PAGE_ELEMENT OutSGL;
\r
10388 +} PTI_ST_PRIVATE_MESSAGE, *PPTI_ST_PRIVATE_MESSAGE;
\r
10391 + * Maximum number of SG segments these cards can support.
\r
10393 +#define PTI_ST_MAX_SG 12 /* 16 */
\r
10394 +#define PTI_ST_MAXSCB 32
\r
10396 +#define PTI_ST_RESET_DELAY 5
\r
10398 +typedef PI2O_BSA_READ_MESSAGE PI2O_BSA_RW_MESSAGE;
\r
10402 + SCB_FREE = 0x0000,
\r
10403 + SCB_WAITINGQ = 0x0002,
\r
10404 + SCB_ACTIVE = 0x0004,
\r
10405 + SCB_SENSE = 0x0008,
\r
10406 + SCB_ABORT = 0x0010,
\r
10407 + SCB_DEVICE_RESET = 0x0020,
\r
10408 + SCB_RESET = 0x0040,
\r
10409 + SCB_RECOVERY_SCB = 0x0080,
\r
10410 + SCB_WAS_BUSY = 0x0100,
\r
10411 + SCB_MSGOUT_SENT = 0x0200,
\r
10412 + SCB_MSGOUT_SDTR = 0x0400,
\r
10413 + SCB_MSGOUT_WDTR = 0x0800,
\r
10414 + SCB_MSGOUT_BITS = SCB_MSGOUT_SENT |
\r
10415 + SCB_MSGOUT_SDTR |
\r
10416 + SCB_MSGOUT_WDTR,
\r
10417 + SCB_QUEUED_ABORT = 0x1000,
\r
10418 + SCB_QUEUED_FOR_DONE = 0x2000
\r
10419 +} scb_flag_type;
\r
10422 +struct pti_st_scb
\r
10424 + PI2O_MESSAGE_FRAME *mf; /* corresponding hardware scb */
\r
10425 + Scsi_Cmnd *cmd; /* Scsi_Cmnd for this scb */
\r
10426 + struct pti_st_scb *q_next; /* next scb in queue */
\r
10427 + volatile scb_flag_type flags; /* current state of scb */
\r
10428 + unsigned char tag;
\r
10429 + unsigned char sg_count;
\r
10430 + unsigned char sense_cmd[6]; /*
\r
10431 + * Allocate 6 characters for
\r
10432 + * sense command.
\r
10434 + unsigned int sg_length; /* We init this during buildscb so we
\r
10435 + * don't have to calculate anything
\r
10436 + * during underflow/overflow/stat
\r
10439 + void *kmalloc_ptr;
\r
10444 + struct pti_st_scb *head;
\r
10445 + struct pti_st_scb *tail;
\r
10446 +} scb_queue_type;
\r
10450 + scb_queue_type free_scbs; /*
\r
10451 + * SCBs assigned to free slot on
\r
10452 + * card (no paging required)
\r
10454 + struct pti_st_scb *scb_array[PTI_ST_MAXSCB];
\r
10455 + unsigned char maxmfs; /* hardware scbs */
\r
10456 + unsigned char maxscbs; /* max scbs including pageable scbs */
\r
10457 +} scb_data_type;
\r
10461 + * Message Unit CSR definitions for RedCreek PCI45 board
\r
10463 +typedef struct tag_atu
\r
10465 + volatile unsigned long APICRegSel; /* APIC Register Select */
\r
10466 + volatile unsigned long reserved0;
\r
10467 + volatile unsigned long APICWinReg; /* APIC Window Register */
\r
10468 + volatile unsigned long reserved1;
\r
10469 + volatile unsigned long InMsgReg0; /* inbound message register 0 */
\r
10470 + volatile unsigned long InMsgReg1; /* inbound message register 1 */
\r
10471 + volatile unsigned long OutMsgReg0; /* outbound message register 0 */
\r
10472 + volatile unsigned long OutMsgReg1; /* outbound message register 1 */
\r
10473 + volatile unsigned long InDoorReg; /* inbound doorbell register */
\r
10474 + volatile unsigned long InIntStat; /* inbound interrupt status register */
\r
10475 + volatile unsigned long InIntMask; /* inbound interrupt mask register */
\r
10476 + volatile unsigned long OutDoorReg; /* outbound doorbell register */
\r
10477 + volatile unsigned long OutIntStat; /* outbound interrupt status register */
\r
10478 + volatile unsigned long OutIntMask; /* outbound interrupt mask register */
\r
10479 + volatile unsigned long reserved2;
\r
10480 + volatile unsigned long reserved3;
\r
10481 + volatile unsigned long InQueue; /* inbound queue port */
\r
10482 + volatile unsigned long OutQueue; /* outbound queue port */
\r
10483 + volatile unsigned long reserved4;
\r
10484 + volatile unsigned long reserver5;
\r
10485 + /* RedCreek extension */
\r
10486 + volatile unsigned long EtherMacLow;
\r
10487 + volatile unsigned long EtherMacHi;
\r
10488 + volatile unsigned long IPaddr;
\r
10489 + volatile unsigned long IPmask;
\r
10494 + PSTC_FNONE = 0x00000000,
\r
10495 + PSTC_PAGESCBS = 0x00000001,
\r
10496 + PSTC_CHANNEL_B_PRIMARY = 0x00000002,
\r
10497 + PSTC_USEDEFAULTS = 0x00000004,
\r
10498 + PSTC_INDIRECT_PAGING = 0x00000008,
\r
10499 + PSTC_CHNLB = 0x00000020,
\r
10500 + PSTC_CHNLC = 0x00000040,
\r
10501 + PSTC_EXTEND_TRANS_A = 0x00000100,
\r
10502 + PSTC_EXTEND_TRANS_B = 0x00000200,
\r
10503 + PSTC_TERM_ENB_A = 0x00000400,
\r
10504 + PSTC_TERM_ENB_SE_LOW = 0x00000400,
\r
10505 + PSTC_TERM_ENB_B = 0x00000800,
\r
10506 + PSTC_TERM_ENB_SE_HIGH = 0x00000800,
\r
10507 + PSTC_HANDLING_REQINITS = 0x00001000,
\r
10508 +#define PSTC_IN_IOCTL_BIT PSTC_HANDLING_REQINITS
\r
10509 + PSTC_TARGETMODE = 0x00002000,
\r
10510 + PSTC_NEWEEPROM_FMT = 0x00004000,
\r
10512 + * Here ends the FreeBSD defined flags and here begins the linux defined
\r
10513 + * flags. NOTE: I did not preserve the old flag name during this change
\r
10514 + * specifically to force me to evaluate what flags were being used properly
\r
10515 + * and what flags weren't. This way, I could clean up the flag usage on
\r
10516 + * a use by use basis. Doug Ledford
\r
10518 + PSTC_RESET_DELAY = 0x00080000,
\r
10519 + PSTC_A_SCANNED = 0x00100000,
\r
10520 + PSTC_B_SCANNED = 0x00200000,
\r
10521 + PSTC_MULTI_CHANNEL = 0x00400000,
\r
10522 + PSTC_BIOS_ENABLED = 0x00800000,
\r
10523 + PSTC_SEEPROM_FOUND = 0x01000000,
\r
10524 + PSTC_TERM_ENB_LVD = 0x02000000,
\r
10525 + PSTC_ABORT_PENDING = 0x04000000,
\r
10526 + PSTC_RESET_PENDING = 0x08000000,
\r
10527 +#define PSTC_IN_ISR_BIT 28
\r
10528 + PSTC_IN_ISR = 0x10000000,
\r
10529 + PSTC_IN_ABORT = 0x20000000,
\r
10530 + PSTC_IN_RESET = 0x40000000,
\r
10531 + PSTC_EXTERNAL_SRAM = 0x80000000
\r
10532 +} pstc_flag_type;
\r
10534 +#define MAX_LCT_ENTRY 32
\r
10536 +typedef struct _outboundBuff_t {
\r
10537 + U8 outboundBuff[32][32*4];
\r
10538 +} outboundBuff_t;
\r
10540 +struct pti_st_host
\r
10543 + * This is the first 64 bytes in the host struct
\r
10547 + * We are grouping things here....first, items that get either read or
\r
10548 + * written with nearly every interrupt
\r
10550 + volatile pstc_flag_type flags;
\r
10551 + unsigned int mbase; /* card base address */
\r
10552 + volatile unsigned char *maddr;
\r
10553 + PATU p_atu; /* ptr to ATU register block */
\r
10554 + PU8 LinBaseAddr;
\r
10555 +#if defined(MYDEBUG) && 0
\r
10556 + U8 replyBuffer[16*1024];
\r
10557 + U8 messageBuffer[256];
\r
10558 + U8 outboundBuffer[32][32*4];
\r
10560 + outboundBuff_t *outboundBufferp;
\r
10561 + U8 *replyBufferp;
\r
10562 + U8 *messageBufferp;
\r
10564 + PU8 pLinOutMsgBlock;
\r
10565 + U32 outMsgBlockPhyAddr;
\r
10566 + scb_data_type *scb_data;
\r
10567 + struct pti_st_cmd_queue
\r
10569 + Scsi_Cmnd *head;
\r
10570 + Scsi_Cmnd *tail;
\r
10573 + volatile scb_queue_type waiting_scbs;
\r
10576 + * Things read/written on nearly every entry into pti_st_queue()
\r
10578 + volatile unsigned char activescbs; /* active scbs */
\r
10579 + volatile unsigned char max_activescbs;
\r
10582 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0)
\r
10583 + spinlock_t spin_lock;
\r
10584 + volatile unsigned char cpu_lock_count[NR_CPUS];
\r
10588 + * We put the less frequently used host structure items after the more
\r
10589 + * frequently used items to try and ease the burden on the cache subsystem.
\r
10590 + * These entries are not *commonly* accessed, whereas the preceding entries
\r
10591 + * are accessed very often. The only exceptions are the qinfifo, qoutfifo,
\r
10592 + * and untagged_scbs array. But, they are often accessed only once and each
\r
10593 + * access into these arrays is likely to blow a cache line, so they are put
\r
10594 + * down here so we can minimize the number of cache lines required to hold
\r
10595 + * the preceeding entries.
\r
10598 + unsigned char pci_irq; /* IRQ for this adapter */
\r
10599 + int scsi_id; /* host adapter SCSI ID */
\r
10601 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
\r
10602 + struct pci_dev *pdev;
\r
10605 + unsigned char pci_bus;
\r
10606 + unsigned char pci_device_fn;
\r
10607 + struct Scsi_Host *host; /* pointer to scsi host */
\r
10608 + int host_no; /* SCSI host number */
\r
10610 + I2O_LCT_ENTRY LctEntryTable[MAX_LCT_ENTRY];
\r
10611 + I2O_EXEC_STATUS_GET_REPLY IopStatus;
\r
10613 + int TotalDiskCount;
\r
10614 + I2ODISK I2ODisk[MAX_DRIVES];
\r
10616 + /* PTI_STCNTL device Variable */
\r
10617 + void *pti_stdev_bufferp;
\r
10618 + int major; /* control device's major */
\r
10619 + int counter; /*counter of using control device*/
\r
10622 +extern struct pti_st_host *pti_st_hostp[MAX_ADAPTORS];
\r
10625 +//---------------------------------------------------------------------------
\r
10626 +// I960RP Memory-Mapper Register PCI Addressing Offset
\r
10627 +#define ARSR_OFFSET 0 //APICReg
\r
10628 +#define AWR_OFFSET 0x08 //APCIWinReg
\r
10629 +#define IMR0_OFFSET 0x10 //InboundMsgReg0
\r
10630 +#define IMR1_OFFSET 0x14 //InboundMsgReg1
\r
10631 +#define OMR0_OFFSET 0x18 //OutboundMsgReg0
\r
10632 +#define OMR1_OFFSET 0x1c //OutboundMsgReg1
\r
10633 +#define IDR_OFFSET 0x20 //InboundDBellReg
\r
10634 +#define IISR_OFFSET 0x24 //InboundIntStatusReg
\r
10635 +#define IIMR_OFFSET 0x28 //InboundIntMaskReg
\r
10636 +#define ODR_OFFSET 0x2c //OutboundDBellReg
\r
10637 +#define OISR_OFFSET 0x30 //OutboundIntStatusReg
\r
10638 +#define OIMR_OFFSET 0x34 //OutboundIntMaskReg
\r
10639 +#define INBOUNDQPORT 0x40
\r
10640 +#define OUTBOUNDQPORT 0x44
\r
10641 +#define MUCR_OFFSET 0x50 //MUConfReg
\r
10642 +#define QBAR_OFFSET 0x54 //QueueBaseAddReg
\r
10644 +//---------------------------------------------------------------------------
\r
10645 +// Bit Definition for InboundIntStatusReg (IISR)
\r
10646 +#define APICW_Status 0x100 //APIC Window Interrupt (R/C)
\r
10647 +#define APICR_Status 0x80 //APIC Register Select Interrupt (R/C)
\r
10648 +#define IR_Status 0x40 //Index Register Interrupt (R/C)
\r
10649 +#define OBFQ_OF_Status 0x20 //Outbound Free Queue OverFlow Interrupt (R/C)
\r
10650 +#define IBPQ_Status 0x10 //Inbound Post Queue Interrupt (R/C)
\r
10651 +#define NMI_DB_Status 0x08 //NMI Doorbell Interrupt (R/O)
\r
10652 +#define IB_DB_Status 0x04 //Inbound Doorbell Interrupt (R/O)
\r
10653 +#define IB_MSG1_Status 0x02 //Inbound Message 1 Interrupt (R/C)
\r
10654 +#define IB_MSG0_Status 0x01 //Inbound Message 0 Interrupt (R/C)
\r
10656 +// Bit Definition for InboundIntMaskReg (IIMR)
\r
10657 +#define APICW_Mask 0x100 //APIC Windows Interrupt Mask (R/W)
\r
10658 +#define APICRSI_Mask 0x80 //APIC Register Select Interrupt Mask (R/W)
\r
10659 +#define IR_Mask 0x40 //Index Register Interrupt Mask (R/W)
\r
10660 +#define OBFQ_OF_Mask 0x20 //Outbound Free Queue Overflow Interrupt Mask (R/W)
\r
10661 +#define IBPQ_Mask 0x10 //Inbound Post Queue Interrupt Mask (R/W)
\r
10662 +#define NMI_DB_Mask 0x08 //NMI Doorbell Interrupt Mask (R/W)
\r
10663 +#define IB_DB_Mask 0x04 //Inbound DoorbellInterrupt Mask (R/W)
\r
10664 +#define IB_MSG1_Mask 0x02 //Inbound Message 1 Interrupt Mask (R/W)
\r
10665 +#define IB_MSG0_Mask 0x01 //Inbound Message 0 Interrupt Mask (R/W)
\r
10667 +// Bit Definition for Outbound Interrupt Status Register (OISR)
\r
10668 +#define PCI_INT_D_Status 0x80 //PCI Interrupt D (RO)
\r
10669 +#define PCI_INT_C_Status 0x40 //PCI Interrupt C (RO)
\r
10670 +#define PCI_INT_B_Status 0x20 //PCI Interrupt B (RO)
\r
10671 +#define PCI_INT_A_Status 0x10 //PCI Interrupt A (RO)
\r
10672 +#define OBPQ_INT_Status 0x08 //Outbound Post Queue Interrupt (RO)
\r
10673 +#define OBDB_INT_Status 0x04 //Outbound Doorbell Interrupt (RO)
\r
10674 +#define OBMSG1_INT_Status 0x02 //Outbound Message 1 Interrupt (PCI R/C)
\r
10675 +#define OBMSG0_INT_Status 0x01 //Outbound Message 0 Interrupt (PCI R/C)
\r
10677 +// Bit Definition for Outbound Interrupt Mask Register
\r
10678 +#define PCI_INT_D_Mask 0x80 //PCI Interrupt D (RW)
\r
10679 +#define PCI_INT_C_Mask 0x40 //PCI Interrupt C (RW)
\r
10680 +#define PCI_INT_B_Mask 0x20 //PCI Interrupt B (RW)
\r
10681 +#define PCI_INT_A_Mask 0x10 //PCI Interrupt A (RW)
\r
10682 +#define OBPQ_INT_Mask 0x08 //Outbound Post Queue Interrupt Mask (RW)
\r
10683 +#define OBDB_INT_Mask 0x04 //Outbound Doorbell Interrupt Mask (RW)
\r
10684 +#define OBMSG1_INT_Mask 0x02 //Outbound Message 1 Interrupt Mask (RW)
\r
10685 +#define OBMSG0_INT_Mask 0x01 //Outbound Message 0 Interrupt Mask (RW)
\r
10687 +//---------------------------------------------------------------------------
\r
10689 +#define IOPSTATE_INIT 0x01
\r
10690 +#define IOPSTATE_RESET 0x02
\r
10691 +#define IOPSTATE_HOLD 0x04
\r
10692 +#define IOPSTATE_READY 0x05
\r
10693 +#define IOPSTATE_OP 0x08
\r
10694 +#define IOPSTATE_FAILED 0x10
\r
10695 +#define IOPSTATE_FAULTED 0x11
\r
10699 +#endif /* _pti_st_h */
\r
10701 diff -Nur linux-2.4.20.org/drivers/scsi/pti_stdev.h linux-2.4.20/drivers/scsi/pti_stdev.h
10702 --- linux-2.4.20.org/drivers/scsi/pti_stdev.h Wed Nov 5 08:47:58 2003
10703 +++ linux-2.4.20/drivers/scsi/pti_stdev.h Wed Oct 16 00:00:00 2002
10704 @@ -1,255 +1,264 @@
10705 -/*+M*************************************************************************
10706 - * Promise SuperTrak device driver for Linux.
10708 - * Copyright (c) 2001 Promise Technology, Inc.
10710 - * This program is free software; you can redistribute it and/or modify
10711 - * it under the terms of the GNU General Public License as published by
10712 - * the Free Software Foundation; either version 2 of the License, or
10713 - * (at your option) any later version.
10715 - * This program is distributed in the hope that it will be useful,
10716 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
10717 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10718 - * GNU General Public License for more details.
10720 - * You should have received a copy of the GNU General Public License
10721 - * along with this program; if not, write to the Free Software
10722 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
10724 - * --------------------------------------------------------------------------
10725 - * Copyright (c) 1999-2001 Promise Technology, Inc.
10726 - * All rights reserved.
10728 - * Redistribution and use in source and binary forms, with or without
10729 - * modification, are permitted provided that the following conditions
10731 - * 1. Redistributions of source code must retain the above copyright
10732 - * notice, this list of conditions, and the following disclaimer,
10733 - * without modification, immediately at the beginning of the file.
10734 - * 2. Redistributions in binary form must reproduce the above copyright
10735 - * notice, this list of conditions and the following disclaimer in the
10736 - * documentation and/or other materials provided with the distribution.
10737 - * 3. The name of the author may not be used to endorse or promote products
10738 - * derived from this software without specific prior written permission.
10740 - * Where this Software is combined with software released under the terms of
10741 - * the GNU Public License ("GPL") and the terms of the GPL would require the
10742 - * combined work to also be released under the terms of the GPL, the terms
10743 - * and conditions of this License will apply in addition to those of the
10744 - * GPL with the exception of any terms or conditions of this License that
10745 - * conflict with, or are expressly prohibited by, the GPL.
10747 - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
10748 - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
10749 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
10750 - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
10751 - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
10752 - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
10753 - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
10754 - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
10755 - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
10756 - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
10760 - *-M*************************************************************************/
10762 -/**************************************************************************
10763 - * File: pti_stdev.h Device Declaraitons for pti_st.c.
10764 - **************************************************************************/
10765 -#include <linux/ioctl.h>
10767 -#if !defined(PTI_STDEV_H)
10768 -#define PTI_STDEV_H
10770 -#if !defined(__KERNEL__)
10772 -#include "i2omsg.h"
10774 -#include "i2odef.h"
10776 -#endif /* __KERNEL__ */
10778 -#if !defined(ULOG)
10779 -#define ULONG unsigned long
10782 -#if !defined(USHORT)
10783 -#define USHORT unsigned short
10786 -#if !defined(UCHAR)
10787 -#define UCHAR unsigned char
10791 - * I2O IOP Descriptor
10794 -typedef struct _I2O_IOP_DESCRIPTOR {
10796 - ULONG IOPCapabilities;
10798 - ULONG I2OVersion;
10799 - ULONG MessengerType;
10800 - ULONG MaxMessageFrameSize;
10801 - ULONG ExpectedLCTSize;
10802 - ULONG MaxInboundMFrames;
10803 - ULONG InitialInboundMFrames;
10805 -} I2O_IOP_DESCRIPTOR, *PI2O_IOP_DESCRIPTOR;
10808 - * I2O IOP and LCT Configuration data
10811 -typedef struct _I2O_DEVICE_DESCRIPTOR {
10812 - ULONG ChangeIndicator;
10813 - I2O_LCT_ENTRY LCT;
10814 - I2O_IOP_DESCRIPTOR IOP;
10815 -} I2O_DEVICE_DESCRIPTOR, *PI2O_DEVICE_DESCRIPTOR;
10818 - * I2O Query Configuration Record structure
10821 -#define I2O_CLASS_MATCH_ANY_BITS (((1<<I2O_CLASS_ID_SZ)-1) & I2O_CLASS_MATCH_ANYCLASS)
10823 -typedef struct _I2O_CONFIG_QUERY {
10825 - I2O_CLASS_ID ClassID;
10826 - ULONG SubClassID;
10828 -} I2O_CONFIG_QUERY, *PI2O_CONFIG_QUERY;
10830 -typedef struct _I2O_IOCTL_GET_CONFIG {
10831 - I2O_CONFIG_QUERY config_query;
10832 - I2O_DEVICE_DESCRIPTOR device_descriptor;
10833 -} I2O_IOCTL_GET_CONFIG, *PI2O_IOCTL_GET_CONFIG;
10836 - * Useful define in get/set operations
10839 -typedef struct _I2O_PARAM_SCALAR_OPERATION {
10840 - I2O_PARAM_OPERATIONS_LIST_HEADER OpList;
10841 - I2O_PARAM_OPERATION_SPECIFIC_TEMPLATE OpBlock;
10842 -} I2O_PARAM_SCALAR_OPERATION, *PI2O_PARAM_SCALAR_OPERATION;
10845 - * Defines for the interface to the I2OExec driver.
10849 -#define I2O_GET_CONFIG_INFO 0xBA0
10850 -#define I2O_PRIVATE_MESSAGE_CODE 0xBB0
10851 -#define I2O_EXEC_REQUEST 0xBC0
10852 -#define I2O_PARAMS_GET_REQUEST 0xBD0
10853 -#define I2O_PARAMS_SET_REQUEST 0xBE0
10854 -#define I2O_GET_LCT 0xBF0
10855 -#define I2O_GET_IOPCOUNT 0xC00
10856 -#define I2O_GET_CONFIGDIALOG 0xC10
10858 -#define I2O_GET_CONFIG_INFO 0xBA
10859 -#define I2O_PRIVATE_MESSAGE_CODE 0xBB
10860 -#define I2O_EXEC_REQUEST 0xBC
10861 -#define I2O_PARAMS_GET_REQUEST 0xBD
10862 -#define I2O_PARAMS_SET_REQUEST 0xBE
10863 -#define I2O_GET_LCT 0xBF
10864 -#define I2O_GET_IOPCOUNT 0xC0
10865 -#define I2O_GET_CONFIGDIALOG 0xC1
10868 -/**************************************************
10869 - * THe following are for IOCTL *
10870 - **************************************************/
10872 -#define SUPERTRAK_GETVERSION 0x01
10877 -#define SUPERTRAK_SIGNATURE "SUPRTRAK"
10878 -#define SUPERTRAK_SIG_LEN 0x8
10881 - * The following are for IOCTL data buffer
10883 -typedef struct _SRB_IO_CONTROL {
10884 - ULONG HeaderLength;
10885 - UCHAR Signature[8];
10887 - ULONG ControlCode;
10888 - ULONG ReturnCode;
10890 -} SRB_IO_CONTROL, *PSRB_IO_CONTROL;
10893 - * Parameter structure for Get/Set Parameters call.
10896 -typedef struct _I2O_PARAM_BLOCK {
10898 - USHORT TargetTID;
10899 - UCHAR ParamData[1];
10900 -} I2O_PARAM_BLOCK, *PI2O_PARAM_BLOCK;
10903 - * The structure is for IOCTL_GET_CONFIG_INFO
10905 -typedef struct _PTI_STDEV_GET_CONFIG_BUFFER {
10906 - SRB_IO_CONTROL buf;
10907 - char payload[sizeof(I2O_CONFIG_QUERY)+sizeof(I2O_DEVICE_DESCRIPTOR)];
10908 -} PTI_STDEV_GET_CONFIG_BUFFER;
10911 - * The stucture is for IOCTL_PARAMS_GET_REQUEST and IOCTL_PRIVATE_MESSAGE
10913 -typedef struct _PTI_STDEV_INBUFFER {
10914 - SRB_IO_CONTROL srb;
10915 - I2O_PARAM_BLOCK block;
10916 - char payload[4096-1];
10917 -} PTI_STDEV_INBUFFER;
10919 -#if !defined(MAX_ADAPTORS)
10920 -#define MAX_ADAPTORS 4
10924 - * The following are the definition of ioctl command
10926 -#define PTI_ST_MAGIC 's'
10928 -#define IOCTL_SUPERTRAK_GETVERSION _IOR(PTI_ST_MAGIC, SUPERTRAK_GETVERSION, SRB_IO_CONTROL)
10930 -#define IOCTL_GET_CONFIG_INFO _IOR(PTI_ST_MAGIC, I2O_GET_CONFIG_INFO, PTI_STDEV_GET_CONFIG_BUFFER)
10932 -#define IOCTL_PRIVATE_MESSAGE_CODE _IOWR(PTI_ST_MAGIC, I2O_PRIVATE_MESSAGE_CODE, PTI_STDEV_INBUFFER)
10934 -#define IOCTL_PARAMS_GET_REQUEST _IOWR(PTI_ST_MAGIC, I2O_PARAMS_GET_REQUEST, PTI_STDEV_INBUFFER)
10936 -#if defined(__KERNEL__)
10938 -#define PTCNTL_DEV_NAME "pti_st"
10940 -int pti_stdev_open(struct inode *, struct file *);
10941 -int pti_stdev_release(struct inode *, struct file *);
10942 -int pti_stdev_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
10944 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
10945 -struct block_device_operations pti_stdev_fops = {
10946 - open: pti_stdev_open,
10947 - release: pti_stdev_release,
10948 - ioctl: pti_stdev_ioctl,
10951 -struct file_operations pti_stdev_fops = {
10952 - NULL, NULL, NULL, NULL, NULL, pti_stdev_ioctl, NULL,
10953 - pti_stdev_open, NULL, pti_stdev_release, NULL, NULL, NULL, NULL};
10956 -#endif /* __KERNEL__ */
10958 -#endif /* PTI_STDEV_H */
10960 +/*+M*************************************************************************
\r
10961 + * Promise SuperTrak device driver for Linux.
\r
10963 + * Copyright (c) 2001 Promise Technology, Inc.
\r
10965 + * This program is free software; you can redistribute it and/or modify
\r
10966 + * it under the terms of the GNU General Public License as published by
\r
10967 + * the Free Software Foundation; either version 2 of the License, or
\r
10968 + * (at your option) any later version.
\r
10970 + * This program is distributed in the hope that it will be useful,
\r
10971 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
10972 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
10973 + * GNU General Public License for more details.
\r
10975 + * You should have received a copy of the GNU General Public License
\r
10976 + * along with this program; if not, write to the Free Software
\r
10977 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
10979 + * --------------------------------------------------------------------------
\r
10980 + * Copyright (c) 1999-2001 Promise Technology, Inc.
\r
10981 + * All rights reserved.
\r
10983 + * Redistribution and use in source and binary forms, with or without
\r
10984 + * modification, are permitted provided that the following conditions
\r
10986 + * 1. Redistributions of source code must retain the above copyright
\r
10987 + * notice, this list of conditions, and the following disclaimer,
\r
10988 + * without modification, immediately at the beginning of the file.
\r
10989 + * 2. Redistributions in binary form must reproduce the above copyright
\r
10990 + * notice, this list of conditions and the following disclaimer in the
\r
10991 + * documentation and/or other materials provided with the distribution.
\r
10992 + * 3. The name of the author may not be used to endorse or promote products
\r
10993 + * derived from this software without specific prior written permission.
\r
10995 + * Where this Software is combined with software released under the terms of
\r
10996 + * the GNU Public License ("GPL") and the terms of the GPL would require the
\r
10997 + * combined work to also be released under the terms of the GPL, the terms
\r
10998 + * and conditions of this License will apply in addition to those of the
\r
10999 + * GPL with the exception of any terms or conditions of this License that
\r
11000 + * conflict with, or are expressly prohibited by, the GPL.
\r
11002 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
\r
11003 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
\r
11004 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
\r
11005 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
\r
11006 + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\r
11007 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
\r
11008 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
\r
11009 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
\r
11010 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
\r
11011 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
\r
11015 + *-M*************************************************************************/
\r
11017 +/**************************************************************************
\r
11018 + * File: pti_stdev.h Device Declaraitons for pti_st.c.
\r
11019 + **************************************************************************/
\r
11020 +#include <linux/ioctl.h>
\r
11022 +#if !defined(PTI_STDEV_H)
\r
11023 +#define PTI_STDEV_H
\r
11025 +#if !defined(__KERNEL__)
\r
11027 +#include "i2omsg.h"
\r
11029 +#include "i2odef.h"
\r
11031 +#endif /* __KERNEL__ */
\r
11033 +#if !defined(ULOG)
\r
11034 +#define ULONG unsigned long
\r
11037 +#if !defined(USHORT)
\r
11038 +#define USHORT unsigned short
\r
11041 +#if !defined(UCHAR)
\r
11042 +#define UCHAR unsigned char
\r
11046 + * I2O IOP Descriptor
\r
11049 +typedef struct _I2O_IOP_DESCRIPTOR {
\r
11050 + ULONG IOPNumber;
\r
11051 + ULONG IOPCapabilities;
\r
11052 + ULONG IOPState;
\r
11053 + ULONG I2OVersion;
\r
11054 + ULONG MessengerType;
\r
11055 + ULONG MaxMessageFrameSize;
\r
11056 + ULONG ExpectedLCTSize;
\r
11057 + ULONG MaxInboundMFrames;
\r
11058 + ULONG InitialInboundMFrames;
\r
11059 + ULONG Reserved;
\r
11060 +} I2O_IOP_DESCRIPTOR, *PI2O_IOP_DESCRIPTOR;
\r
11063 + * I2O IOP and LCT Configuration data
\r
11066 +typedef struct _I2O_DEVICE_DESCRIPTOR {
\r
11067 + ULONG ChangeIndicator;
\r
11068 + I2O_LCT_ENTRY LCT;
\r
11069 + I2O_IOP_DESCRIPTOR IOP;
\r
11070 +} I2O_DEVICE_DESCRIPTOR, *PI2O_DEVICE_DESCRIPTOR;
\r
11073 + * I2O Query Configuration Record structure
\r
11076 +#define I2O_CLASS_MATCH_ANY_BITS (((1<<I2O_CLASS_ID_SZ)-1) & I2O_CLASS_MATCH_ANYCLASS)
\r
11078 +typedef struct _I2O_CONFIG_QUERY {
\r
11079 + ULONG IOPNumber;
\r
11080 + I2O_CLASS_ID ClassID;
\r
11081 + ULONG SubClassID;
\r
11083 +} I2O_CONFIG_QUERY, *PI2O_CONFIG_QUERY;
\r
11085 +typedef struct _I2O_IOCTL_GET_CONFIG {
\r
11086 + I2O_CONFIG_QUERY config_query;
\r
11087 + I2O_DEVICE_DESCRIPTOR device_descriptor;
\r
11088 +} I2O_IOCTL_GET_CONFIG, *PI2O_IOCTL_GET_CONFIG;
\r
11091 + * Useful define in get/set operations
\r
11094 +typedef struct _I2O_PARAM_SCALAR_OPERATION {
\r
11095 + I2O_PARAM_OPERATIONS_LIST_HEADER OpList;
\r
11096 + I2O_PARAM_OPERATION_SPECIFIC_TEMPLATE OpBlock;
\r
11097 +} I2O_PARAM_SCALAR_OPERATION, *PI2O_PARAM_SCALAR_OPERATION;
\r
11100 + * Defines for the interface to the I2OExec driver.
\r
11104 +#define I2O_GET_CONFIG_INFO 0xBA0
\r
11105 +#define I2O_PRIVATE_MESSAGE_CODE 0xBB0
\r
11106 +#define I2O_EXEC_REQUEST 0xBC0
\r
11107 +#define I2O_PARAMS_GET_REQUEST 0xBD0
\r
11108 +#define I2O_PARAMS_SET_REQUEST 0xBE0
\r
11109 +#define I2O_GET_LCT 0xBF0
\r
11110 +#define I2O_GET_IOPCOUNT 0xC00
\r
11111 +#define I2O_GET_CONFIGDIALOG 0xC10
\r
11113 +#define I2O_GET_CONFIG_INFO 0xBA
\r
11114 +#define I2O_PRIVATE_MESSAGE_CODE 0xBB
\r
11115 +#define I2O_EXEC_REQUEST 0xBC
\r
11116 +#define I2O_PARAMS_GET_REQUEST 0xBD
\r
11117 +#define I2O_PARAMS_SET_REQUEST 0xBE
\r
11118 +#define I2O_GET_LCT 0xBF
\r
11119 +#define I2O_GET_IOPCOUNT 0xC0
\r
11120 +#define I2O_GET_CONFIGDIALOG 0xC1
\r
11121 +#define I2O_FLUSH_CACHE_REQ 0xFE
\r
11124 +/**************************************************
\r
11125 + * THe following are for IOCTL *
\r
11126 + **************************************************/
\r
11128 +#define SUPERTRAK_GETVERSION 0x01
\r
11133 +#define SUPERTRAK_SIGNATURE "SUPRTRAK"
\r
11134 +#define SUPERTRAK_SIG_LEN 0x8
\r
11137 + * The following are for IOCTL data buffer
\r
11139 +typedef struct _SRB_IO_CONTROL {
\r
11140 + ULONG HeaderLength;
\r
11141 + UCHAR Signature[8];
\r
11143 + ULONG ControlCode;
\r
11144 + ULONG ReturnCode;
\r
11146 +} SRB_IO_CONTROL, *PSRB_IO_CONTROL;
\r
11149 + * Parameter structure for Get/Set Parameters call.
\r
11152 +typedef struct _I2O_PARAM_BLOCK {
\r
11154 + USHORT TargetTID;
\r
11155 + UCHAR ParamData[1];
\r
11156 +} I2O_PARAM_BLOCK, *PI2O_PARAM_BLOCK;
\r
11159 + * The structure is for IOCTL_GET_CONFIG_INFO
\r
11161 +typedef struct _PTI_STDEV_GET_CONFIG_BUFFER {
\r
11162 + SRB_IO_CONTROL buf;
\r
11163 + char payload[sizeof(I2O_CONFIG_QUERY)+sizeof(I2O_DEVICE_DESCRIPTOR)];
\r
11164 +} PTI_STDEV_GET_CONFIG_BUFFER;
\r
11167 + * The stucture is for IOCTL_PARAMS_GET_REQUEST and IOCTL_PRIVATE_MESSAGE
\r
11169 +typedef struct _PTI_STDEV_INBUFFER {
\r
11170 + SRB_IO_CONTROL srb;
\r
11171 + I2O_PARAM_BLOCK block;
\r
11172 + char payload[4096-1];
\r
11173 +} PTI_STDEV_INBUFFER;
\r
11175 +#if !defined(MAX_ADAPTORS)
\r
11176 +#define MAX_ADAPTORS 4
\r
11180 + * The following are the definition of ioctl command
\r
11182 +#define PTI_ST_MAGIC 's'
\r
11184 +#define IOCTL_SUPERTRAK_GETVERSION _IOR(PTI_ST_MAGIC, SUPERTRAK_GETVERSION, SRB_IO_CONTROL)
\r
11186 +#define IOCTL_GET_CONFIG_INFO _IOR(PTI_ST_MAGIC, I2O_GET_CONFIG_INFO, PTI_STDEV_GET_CONFIG_BUFFER)
\r
11188 +#define IOCTL_PRIVATE_MESSAGE_CODE _IOWR(PTI_ST_MAGIC, I2O_PRIVATE_MESSAGE_CODE, PTI_STDEV_INBUFFER)
\r
11190 +#define IOCTL_PARAMS_GET_REQUEST _IOWR(PTI_ST_MAGIC, I2O_PARAMS_GET_REQUEST, PTI_STDEV_INBUFFER)
\r
11192 +#define IOCTL_FLUSH_CACHE_REQUEST _IOWR(PTI_ST_MAGIC, I2O_FLUSH_CACHE_REQ, SRB_IO_CONTROL)
\r
11194 +#if defined(__KERNEL__)
\r
11196 +#define PTCNTL_DEV_NAME "pti_st"
\r
11198 +int pti_stdev_open(struct inode *, struct file *);
\r
11199 +int pti_stdev_release(struct inode *, struct file *);
\r
11200 +int pti_stdev_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
\r
11202 +struct file_operations pti_st_fops={
\r
11203 + open: pti_stdev_open,
\r
11204 + release: pti_stdev_release,
\r
11205 + ioctl: pti_stdev_ioctl,
\r
11208 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
\r
11209 +struct block_device_operations pti_stdev_fops = {
\r
11210 + open: pti_stdev_open,
\r
11211 + release: pti_stdev_release,
\r
11212 + ioctl: pti_stdev_ioctl,
\r
11215 +struct file_operations pti_stdev_fops = {
\r
11216 + NULL, NULL, NULL, NULL, NULL, pti_stdev_ioctl, NULL,
\r
11217 + pti_stdev_open, NULL, pti_stdev_release, NULL, NULL, NULL, NULL};
\r
11220 +#endif /* __KERNEL__ */
\r
11222 +#endif /* PTI_STDEV_H */
\r