This source file includes following definitions.
- advansys_proc_info
- advansys_detect
- advansys_release
- advansys_info
- advansys_command
- advansys_queuecommand
- advansys_abort
- advansys_reset
- advansys_biosparam
- advansys_setup
- asc_proc_copy
- advansys_interrupt
- advansys_command_done
- asc_execute_scsi_cmnd
- asc_isr_callback
- asc_execute_pending
- asc_init_dev
- asc_srch_pci_dev
- asc_scan_method
- asc_pci_find_dev
- asc_get_pci_cfg
- asc_get_cfg_word
- asc_get_cfg_byte
- asc_enqueue
- asc_dequeue
- asc_rmqueue
- DvcSleepMilliSecond
- DvcDisplayString
- DvcEnterCritical
- DvcLeaveCritical
- DvcGetPhyAddr
- DvcGetSGList
- DvcPutScsiQ
- DvcGetQinfo
- DvcOutPortWords
- DvcInPortWords
- DvcOutPortDWords
- asc_prt_stats
- asc_prt_stats_line
- asc_prt_scsi_host
- asc_prt_dvc_var
- asc_prt_dvc_cfg
- asc_prt_scsi_q
- asc_prt_qdone_info
- asc_prt_hex
- interrupts_enabled
- AscGetEisaChipCfg
- AscSetChipScsiID
- AscGetChipBiosAddress
- AscGetChipVersion
- AscGetChipBusType
- AscEnableIsaDma
- AscLoadMicroCode
- AscSearchIOPortAddr
- AscSearchIOPortAddr11
- AscFindSignature
- AscToggleIRQAct
- AscSetISAPNPWaitForKey
- AscGetChipIRQ
- AscSetChipIRQ
- AscGetChipScsiCtrl
- AscIsrChipHalted
- _AscCopyLramScsiDoneQ
- AscIsrQDone
- AscISR
- AscScsiSetupCmdQ
- AscExeScsiQueue
- AscSendScsiQueue
- AscSgListToQueue
- AscGetNumOfFreeQueue
- AscPutReadyQueue
- AscPutReadySgListQueue
- AscAbortSRB
- AscResetDevice
- AscResetSB
- AscSetRunChipSynRegAtID
- AscSetChipSynRegAtID
- AscReInitLram
- AscInitLram
- AscInitQLinkVar
- AscSetLibErrorCode
- _AscWaitQDone
- AscMsgOutSDTR
- AscCalSDTRData
- AscSetChipSDTR
- AscGetSynPeriodIndex
- AscAllocFreeQueue
- AscAllocMultipleFreeQueue
- AscRiscHaltedAbortSRB
- AscRiscHaltedAbortTIX
- AscHostReqRiscHalt
- AscStopQueueExe
- AscStartQueueExe
- AscCleanUpBusyQueue
- AscCleanUpDiscQueue
- AscWaitTixISRDone
- AscWaitISRDone
- AscGetOnePhyAddr
- AscGetEisaProductID
- AscSearchIOPortAddrEISA
- AscStartChip
- AscStopChip
- AscIsChipHalted
- AscSetChipIH
- AscAckInterrupt
- AscDisableInterrupt
- AscEnableInterrupt
- AscSetBank
- AscResetChipAndScsiBus
- AscGetIsaDmaChannel
- AscSetIsaDmaChannel
- AscSetIsaDmaSpeed
- AscGetIsaDmaSpeed
- AscGetMaxDmaCount
- AscInitGetConfig
- AscInitSetConfig
- AscInitAsc1000Driver
- AscInitAscDvcVar
- AscInitFromAscDvcVar
- AscInitFromEEP
- AscInitMicroCodeVar
- AscInitPollIsrCallBack
- AscTestExternalLram
- AscWriteEEPCmdReg
- AscWriteEEPDataReg
- AscWaitEEPRead
- AscWaitEEPWrite
- AscReadEEPWord
- AscWriteEEPWord
- AscGetEEPConfig
- AscSetEEPConfigOnce
- AscSetEEPConfig
- AscInitPollBegin
- AscInitPollEnd
- AscInitPollTarget
- PollQueueDone
- PollScsiInquiry
- PollScsiReadCapacity
- swapfarbuf4
- PollScsiTestUnitReady
- PollScsiStartUnit
- InitTestUnitReady
- AscPollQDone
- AscReadLramByte
- AscReadLramWord
- AscReadLramDWord
- AscWriteLramWord
- AscWriteLramDWord
- AscWriteLramByte
- AscVerWriteLramWord
- AscMemWordCopyToLram
- AscMemDWordCopyToLram
- AscMemWordCopyFromLram
- AscMemSumLramWord
- AscMemWordSetLram
- AscScsiInquiry
- AscScsiReadCapacity
- AscScsiTestUnitReady
- AscScsiStartStopUnit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #define ASC_VERSION "1.2"
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394 #if !defined(LINUX_1_2) && !defined(LINUX_1_3)
395 #ifndef LINUX_VERSION_CODE
396 #include <linux/version.h>
397 #endif
398 #if LINUX_VERSION_CODE > 65536 + 3 * 256
399 #define LINUX_1_3
400 #else
401 #define LINUX_1_2
402 #endif
403 #endif
404
405
406
407
408
409
410 #ifdef MODULE
411 #ifdef LINUX_1_3
412 #include <linux/autoconf.h>
413 #endif
414 #include <linux/module.h>
415 #endif
416 #include <linux/string.h>
417 #include <linux/sched.h>
418 #include <linux/kernel.h>
419 #include <linux/head.h>
420 #include <linux/types.h>
421 #include <linux/ioport.h>
422 #include <linux/delay.h>
423 #include <linux/malloc.h>
424 #include <linux/config.h>
425 #ifdef LINUX_1_3
426 #include <linux/proc_fs.h>
427 #endif
428 #include <asm/io.h>
429 #include <asm/system.h>
430 #include <asm/dma.h>
431 #ifdef LINUX_1_2
432 #include "../block/blk.h"
433 #else
434 #include <linux/blk.h>
435 #include <linux/stat.h>
436 #endif
437 #include "scsi.h"
438 #include "hosts.h"
439 #include "sd.h"
440 #include "advansys.h"
441
442
443
444
445
446 #define ADVANSYS_DEBUG
447 #define ADVANSYS_STATS
448 #ifdef LINUX_1_2
449 #undef ADVANSYS_STATS_1_2_PRINT
450 #endif
451
452
453
454
455
456
457 #define ASC_LIB_VERSION_MAJOR 1
458 #define ASC_LIB_VERSION_MINOR 16
459 #define ASC_LIB_SERIAL_NUMBER 53
460
461 typedef unsigned char uchar;
462 typedef unsigned char BYTE;
463 typedef unsigned short WORD;
464 typedef unsigned long DWORD;
465
466 typedef int BOOL;
467
468 #ifndef NULL
469 #define NULL (0)
470 #endif
471
472 #ifndef TRUE
473 #define TRUE (1)
474 #endif
475
476 #ifndef FALSE
477 #define FALSE (0)
478 #endif
479
480 #define REG register
481
482 #define rchar REG char
483 #define rshort REG short
484 #define rint REG int
485 #define rlong REG long
486
487 #define ruchar REG uchar
488 #define rushort REG ushort
489 #define ruint REG uint
490 #define rulong REG ulong
491
492 #define NULLPTR ( void *)0
493 #define FNULLPTR ( void dosfar *)0UL
494 #define EOF (-1)
495 #define EOS '\0'
496 #define ERR (-1)
497 #define UB_ERR (uchar)(0xFF)
498 #define UW_ERR (uint)(0xFFFF)
499 #define UL_ERR (ulong)(0xFFFFFFFFUL)
500
501 #define iseven_word( val ) ( ( ( ( uint )val) & ( uint )0x0001 ) == 0 )
502 #define isodd_word( val ) ( ( ( ( uint )val) & ( uint )0x0001 ) != 0 )
503 #define toeven_word( val ) ( ( ( uint )val ) & ( uint )0xFFFE )
504
505 #define biton( val, bits ) ((( uint )( val >> bits ) & (uint)0x0001 ) != 0 )
506 #define bitoff( val, bits ) ((( uint )( val >> bits ) & (uint)0x0001 ) == 0 )
507 #define lbiton( val, bits ) ((( ulong )( val >> bits ) & (ulong)0x00000001UL ) != 0 )
508 #define lbitoff( val, bits ) ((( ulong )( val >> bits ) & (ulong)0x00000001UL ) == 0 )
509
510 #define absh( val ) ( ( val ) < 0 ? -( val ) : ( val ) )
511
512 #define swapbyte( ch ) ( ( ( (ch) << 4 ) | ( (ch) >> 4 ) ) )
513
514 #ifndef GBYTE
515 #define GBYTE (0x40000000UL)
516 #endif
517
518 #ifndef MBYTE
519 #define MBYTE (0x100000UL)
520 #endif
521
522 #ifndef KBYTE
523 #define KBYTE (0x400)
524 #endif
525
526 #define HI_BYTE(x) ( *( ( BYTE *)(&x)+1 ) )
527 #define LO_BYTE(x) ( *( ( BYTE *)&x ) )
528
529 #define HI_WORD(x) ( *( ( WORD *)(&x)+1 ) )
530 #define LO_WORD(x) ( *( ( WORD *)&x ) )
531
532 #ifndef MAKEWORD
533 #define MAKEWORD(lo, hi) ((WORD) (((WORD) lo) | ((WORD) hi << 8)))
534 #endif
535
536 #ifndef MAKELONG
537 #define MAKELONG(lo, hi) ((DWORD) (((DWORD) lo) | ((DWORD) hi << 16)))
538 #endif
539
540 #define SwapWords(dWord) ((DWORD) ((dWord >> 16) | (dWord << 16)))
541 #define SwapBytes(word) ((WORD) ((word >> 8) | (word << 8)))
542
543 #define BigToLittle(dWord) \
544 ((DWORD) (SwapWords(MAKELONG(SwapBytes(LO_WORD(dWord)), SwapBytes(HI_WORD(dWord))))))
545 #define LittleToBig(dWord) BigToLittle(dWord)
546
547 #define Lptr
548 #define dosfar
549 #define far
550 #define PortAddr unsigned short
551 #define Ptr2Func ulong
552
553 #define inp(port) inb(port)
554 #define inpw(port) inw(port)
555 #define outp(port, byte) outb((byte), (port))
556 #define outpw(port, word) outw((word), (port))
557
558 #define ASC_MAX_SG_QUEUE 5
559 #define ASC_MAX_SG_LIST (1 + ((ASC_SG_LIST_PER_Q) * (ASC_MAX_SG_QUEUE)))
560
561 #define CC_INIT_INQ_DISPLAY FALSE
562
563 #define CC_CLEAR_LRAM_SRB_PTR FALSE
564 #define CC_VERIFY_LRAM_COPY FALSE
565
566 #define CC_DEBUG_SG_LIST FALSE
567 #define CC_FAST_STRING_IO FALSE
568
569 #define CC_WRITE_IO_COUNT FALSE
570 #define CC_CLEAR_DMA_REMAIN FALSE
571
572 #define CC_DISABLE_PCI_PARITY_INT TRUE
573
574 #define CC_LINK_BUSY_Q FALSE
575
576 #define CC_TARGET_MODE FALSE
577
578 #define CC_SCAM FALSE
579
580 #define CC_LITTLE_ENDIAN_HOST TRUE
581
582 #ifndef CC_TEST_LRAM_ENDIAN
583
584 #if CC_LITTLE_ENDIAN_HOST
585 #define CC_TEST_LRAM_ENDIAN FALSE
586 #else
587 #define CC_TEST_LRAM_ENDIAN TRUE
588 #endif
589
590 #endif
591
592 #define CC_STRUCT_ALIGNED TRUE
593
594 #define CC_MEMORY_MAPPED_IO FALSE
595
596 #ifndef CC_TARGET_MODE
597 #define CC_TARGET_MODE FALSE
598 #endif
599
600 #ifndef CC_STRUCT_ALIGNED
601 #define CC_STRUCT_ALIGNED FALSE
602 #endif
603
604 #ifndef CC_LITTLE_ENDIAN_HOST
605 #define CC_LITTLE_ENDIAN_HOST TRUE
606 #endif
607
608 #if !CC_LITTLE_ENDIAN_HOST
609
610 #ifndef CC_TEST_LRAM_ENDIAN
611 #define CC_TEST_LRAM_ENDIAN TRUE
612 #endif
613
614 #endif
615
616 #ifndef CC_MEMORY_MAPPED_IO
617 #define CC_MEMORY_MAPPED_IO FALSE
618 #endif
619
620 #ifndef CC_WRITE_IO_COUNT
621 #define CC_WRITE_IO_COUNT FALSE
622 #endif
623
624 #ifndef CC_CLEAR_DMA_REMAIN
625 #define CC_CLEAR_DMA_REMAIN FALSE
626 #endif
627
628 #define ASC_CS_TYPE unsigned short
629
630 #ifndef asc_ptr_type
631 #define asc_ptr_type
632 #endif
633
634 #ifndef CC_SCAM
635 #define CC_SCAM FALSE
636 #endif
637
638 #ifndef ASC_GET_PTR2FUNC
639 #define ASC_GET_PTR2FUNC( fun ) ( Ptr2Func )( fun )
640 #endif
641
642 #define FLIP_BYTE_NIBBLE( x ) ( ((x<<4)& 0xFF) | (x>>4) )
643
644 #define ASC_IS_ISA (0x0001)
645 #define ASC_IS_ISAPNP (0x0081)
646 #define ASC_IS_EISA (0x0002)
647 #define ASC_IS_PCI (0x0004)
648 #define ASC_IS_PCMCIA (0x0008)
649 #define ASC_IS_PNP (0x0010)
650 #define ASC_IS_MCA (0x0020)
651 #define ASC_IS_VL (0x0040)
652
653 #define ASC_ISA_PNP_PORT_ADDR (0x279)
654 #define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
655
656 #define ASC_IS_WIDESCSI_16 (0x0100)
657 #define ASC_IS_WIDESCSI_32 (0x0200)
658
659 #define ASC_IS_BIG_ENDIAN (0x8000)
660
661 #define ASC_CHIP_MIN_VER_VL (0x01)
662 #define ASC_CHIP_MAX_VER_VL (0x07)
663
664 #define ASC_CHIP_MIN_VER_PCI (0x09)
665 #define ASC_CHIP_MAX_VER_PCI (0x0F)
666 #define ASC_CHIP_VER_PCI_BIT (0x08)
667
668 #define ASC_CHIP_MIN_VER_ISA (0x11)
669 #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
670 #define ASC_CHIP_MAX_VER_ISA (0x27)
671 #define ASC_CHIP_VER_ISA_BIT (0x30)
672 #define ASC_CHIP_VER_ISAPNP_BIT (0x20)
673
674 #define ASC_CHIP_VER_ASYN_BUG (0x21)
675
676 #define ASC_CHIP_MIN_VER_EISA (0x41)
677 #define ASC_CHIP_MAX_VER_EISA (0x47)
678 #define ASC_CHIP_VER_EISA_BIT (0x40)
679
680 #define ASC_MAX_VL_DMA_ADDR (0x07FFFFFFL)
681 #define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
682
683 #define ASC_MAX_PCI_DMA_ADDR (0xFFFFFFFFL)
684 #define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
685
686 #define ASC_MAX_ISA_DMA_ADDR (0x00FFFFFFL)
687 #define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
688
689 #define ASC_MAX_EISA_DMA_ADDR (0x07FFFFFFL)
690 #define ASC_MAX_EISA_DMA_COUNT (0x07FFFFFFL)
691
692 #if !CC_STRUCT_ALIGNED
693
694 #define DvcGetQinfo( iop_base, s_addr, outbuf, words) \
695 AscMemWordCopyFromLram( iop_base, s_addr, outbuf, words)
696
697 #define DvcPutScsiQ( iop_base, s_addr, outbuf, words) \
698 AscMemWordCopyToLram( iop_base, s_addr, outbuf, words)
699
700 #endif
701
702 #define ASC_SCSI_ID_BITS 3
703 #define ASC_SCSI_TIX_TYPE uchar
704 #define ASC_ALL_DEVICE_BIT_SET 0xFF
705
706 #ifdef ASC_WIDESCSI_16
707
708 #undef ASC_SCSI_ID_BITS
709 #define ASC_SCSI_ID_BITS 4
710 #define ASC_ALL_DEVICE_BIT_SET 0xFFFF
711
712 #endif
713
714 #ifdef ASC_WIDESCSI_32
715
716 #undef ASC_SCSI_ID_BITS
717 #define ASC_SCSI_ID_BITS 5
718 #define ASC_ALL_DEVICE_BIT_SET 0xFFFFFFFFL
719
720 #endif
721
722 #if ASC_SCSI_ID_BITS == 3
723
724 #define ASC_SCSI_BIT_ID_TYPE uchar
725 #define ASC_MAX_TID 7
726 #define ASC_MAX_LUN 7
727 #define ASC_SCSI_WIDTH_BIT_SET 0xFF
728
729 #elif ASC_SCSI_ID_BITS == 4
730
731 #define ASC_SCSI_BIT_ID_TYPE ushort
732 #define ASC_MAX_TID 15
733 #define ASC_MAX_LUN 7
734 #define ASC_SCSI_WIDTH_BIT_SET 0xFFFF
735
736 #elif ASC_SCSI_ID_BITS == 5
737
738 #define ASC_SCSI_BIT_ID_TYPE ulong
739 #define ASC_MAX_TID 31
740 #define ASC_MAX_LUN 7
741 #define ASC_SCSI_WIDTH_BIT_SET 0xFFFFFFFF
742
743 #else
744
745 #error ASC_SCSI_ID_BITS definition is wrong
746
747 #endif
748
749 #define ASC_MAX_SENSE_LEN 32
750 #define ASC_MIN_SENSE_LEN 14
751
752 #define ASC_MAX_CDB_LEN 12
753
754 #define SCSICMD_TestUnitReady 0x00
755 #define SCSICMD_Rewind 0x01
756 #define SCSICMD_Rezero 0x01
757 #define SCSICMD_RequestSense 0x03
758 #define SCSICMD_Format 0x04
759 #define SCSICMD_FormatUnit 0x04
760 #define SCSICMD_Read6 0x08
761 #define SCSICMD_Write6 0x0A
762 #define SCSICMD_Seek6 0x0B
763 #define SCSICMD_Inquiry 0x12
764 #define SCSICMD_Verify6 0x13
765 #define SCSICMD_ModeSelect6 0x15
766 #define SCSICMD_ModeSense6 0x1A
767
768 #define SCSICMD_StartStopUnit 0x1B
769 #define SCSICMD_LoadUnloadTape 0x1B
770 #define SCSICMD_ReadCapacity 0x25
771 #define SCSICMD_Read10 0x28
772 #define SCSICMD_Write10 0x2A
773 #define SCSICMD_Seek10 0x2B
774 #define SCSICMD_Erase10 0x2C
775 #define SCSICMD_WriteAndVerify10 0x2E
776 #define SCSICMD_Verify10 0x2F
777
778 #define SCSICMD_ModeSelect10 0x55
779 #define SCSICMD_ModeSense10 0x5A
780
781 #define SCSI_TYPE_DASD 0x00
782 #define SCSI_TYPE_SASD 0x01
783 #define SCSI_TYPE_PRN 0x02
784 #define SCSI_TYPE_PROC 0x03
785
786 #define SCSI_TYPE_WORM 0x04
787 #define SCSI_TYPE_CDROM 0x05
788 #define SCSI_TYPE_SCANNER 0x06
789 #define SCSI_TYPE_OPTMEM 0x07
790 #define SCSI_TYPE_MED_CHG 0x08
791 #define SCSI_TYPE_COMM 0x09
792 #define SCSI_TYPE_UNKNOWN 0x1F
793 #define SCSI_TYPE_NO_DVC 0xFF
794
795 #define ASC_SCSIDIR_NOCHK 0x00
796
797 #define ASC_SCSIDIR_T2H 0x08
798
799 #define ASC_SCSIDIR_H2T 0x10
800
801 #define ASC_SCSIDIR_NODATA 0x18
802
803 #define SCSI_SENKEY_NO_SENSE 0x00
804 #define SCSI_SENKEY_UNDEFINED 0x01
805 #define SCSI_SENKEY_NOT_READY 0x02
806 #define SCSI_SENKEY_MEDIUM_ERR 0x03
807 #define SCSI_SENKEY_HW_ERR 0x04
808 #define SCSI_SENKEY_ILLEGAL 0x05
809 #define SCSI_SENKEY_ATTENSION 0x06
810 #define SCSI_SENKEY_PROTECTED 0x07
811 #define SCSI_SENKEY_BLANK 0x08
812 #define SCSI_SENKEY_V_UNIQUE 0x09
813 #define SCSI_SENKEY_CPY_ABORT 0x0A
814 #define SCSI_SENKEY_ABORT 0x0B
815 #define SCSI_SENKEY_EQUAL 0x0C
816 #define SCSI_SENKEY_VOL_OVERFLOW 0x0D
817 #define SCSI_SENKEY_MISCOMP 0x0E
818 #define SCSI_SENKEY_RESERVED 0x0F
819
820 #define ASC_SRB_HOST( x ) ( ( uchar )( ( uchar )( x ) >> 4 ) )
821 #define ASC_SRB_TID( x ) ( ( uchar )( ( uchar )( x ) & ( uchar )0x0F ) )
822
823 #define ASC_SRB_LUN( x ) ( ( uchar )( ( uint )( x ) >> 13 ) )
824
825 #define PUT_CDB1( x ) ( ( uchar )( ( uint )( x ) >> 8 ) )
826
827 #define SS_GOOD 0x00
828 #define SS_CHK_CONDITION 0x02
829 #define SS_CONDITION_MET 0x04
830 #define SS_TARGET_BUSY 0x08
831 #define SS_INTERMID 0x10
832 #define SS_INTERMID_COND_MET 0x14
833
834 #define SS_RSERV_CONFLICT 0x18
835 #define SS_CMD_TERMINATED 0x22
836
837 #define SS_QUEUE_FULL 0x28
838
839 #define MS_CMD_DONE 0x00
840 #define MS_EXTEND 0x01
841 #define MS_SDTR_LEN 0x03
842 #define MS_SDTR_CODE 0x01
843
844 #define M1_SAVE_DATA_PTR 0x02
845 #define M1_RESTORE_PTRS 0x03
846 #define M1_DISCONNECT 0x04
847 #define M1_INIT_DETECTED_ERR 0x05
848 #define M1_ABORT 0x06
849 #define M1_MSG_REJECT 0x07
850 #define M1_NO_OP 0x08
851 #define M1_MSG_PARITY_ERR 0x09
852 #define M1_LINK_CMD_DONE 0x0A
853 #define M1_LINK_CMD_DONE_WFLAG 0x0B
854 #define M1_BUS_DVC_RESET 0x0C
855 #define M1_ABORT_TAG 0x0D
856 #define M1_CLR_QUEUE 0x0E
857 #define M1_INIT_RECOVERY 0x0F
858 #define M1_RELEASE_RECOVERY 0x10
859 #define M1_KILL_IO_PROC 0x11
860
861 #define M2_QTAG_MSG_SIMPLE 0x20
862 #define M2_QTAG_MSG_HEAD 0x21
863 #define M2_QTAG_MSG_ORDERED 0x22
864 #define M2_IGNORE_WIDE_RESIDUE 0x23
865
866 typedef struct {
867 uchar peri_dvc_type:5;
868 uchar peri_qualifier:3;
869 } ASC_SCSI_INQ0;
870
871 typedef struct {
872 uchar dvc_type_modifier:7;
873 uchar rmb:1;
874 } ASC_SCSI_INQ1;
875
876 typedef struct {
877 uchar ansi_apr_ver:3;
878 uchar ecma_ver:3;
879 uchar iso_ver:2;
880 } ASC_SCSI_INQ2;
881
882 typedef struct {
883 uchar rsp_data_fmt:4;
884
885 uchar res:2;
886 uchar TemIOP:1;
887 uchar aenc:1;
888 } ASC_SCSI_INQ3;
889
890 typedef struct {
891 uchar StfRe:1;
892 uchar CmdQue:1;
893 uchar Reserved:1;
894 uchar Linked:1;
895 uchar Sync:1;
896 uchar WBus16:1;
897 uchar WBus32:1;
898 uchar RelAdr:1;
899 } ASC_SCSI_INQ7;
900
901 typedef struct {
902 ASC_SCSI_INQ0 byte0;
903 ASC_SCSI_INQ1 byte1;
904 ASC_SCSI_INQ2 byte2;
905 ASC_SCSI_INQ3 byte3;
906 uchar add_len;
907 uchar res1;
908 uchar res2;
909 ASC_SCSI_INQ7 byte7;
910 uchar vendor_id[8];
911 uchar product_id[16];
912 uchar product_rev_level[4];
913 } ASC_SCSI_INQUIRY;
914
915 typedef struct asc_req_sense {
916 uchar err_code:7;
917 uchar info_valid:1;
918 uchar segment_no;
919 uchar sense_key:4;
920 uchar reserved_bit:1;
921 uchar sense_ILI:1;
922 uchar sense_EOM:1;
923 uchar file_mark:1;
924 uchar info1[4];
925 uchar add_sense_len;
926 uchar cmd_sp_info[4];
927 uchar asc;
928 uchar ascq;
929
930 uchar fruc;
931 uchar sks_byte0:7;
932 uchar sks_valid:1;
933 uchar sks_bytes[2];
934 uchar notused[2];
935 uchar ex_sense_code;
936 uchar info2[4];
937 } ASC_REQ_SENSE;
938
939 #define ASC_SG_LIST_PER_Q 7
940
941 #define QS_FREE 0x00
942 #define QS_READY 0x01
943 #define QS_DISC1 0x02
944 #define QS_DISC2 0x04
945 #define QS_BUSY 0x08
946
947 #define QS_ABORTED 0x40
948 #define QS_DONE 0x80
949
950 #define QC_NO_CALLBACK 0x01
951
952 #define QC_SG_SWAP_QUEUE 0x02
953 #define QC_SG_HEAD 0x04
954 #define QC_DATA_IN 0x08
955 #define QC_DATA_OUT 0x10
956
957 #define QC_URGENT 0x20
958 #define QC_MSG_OUT 0x40
959 #define QC_REQ_SENSE 0x80
960
961 #define QCSG_SG_XFER_LIST 0x02
962 #define QCSG_SG_XFER_MORE 0x04
963 #define QCSG_SG_XFER_END 0x08
964
965 #define QD_IN_PROGRESS 0x00
966 #define QD_NO_ERROR 0x01
967 #define QD_ABORTED_BY_HOST 0x02
968 #define QD_WITH_ERROR 0x04
969 #define QD_INVALID_REQUEST 0x80
970 #define QD_INVALID_HOST_NUM 0x81
971 #define QD_INVALID_DEVICE 0x82
972 #define QD_ERR_INTERNAL 0xFF
973
974 #define QHSTA_NO_ERROR 0x00
975 #define QHSTA_M_SEL_TIMEOUT 0x11
976 #define QHSTA_M_DATA_OVER_RUN 0x12
977 #define QHSTA_M_DATA_UNDER_RUN 0x12
978 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
979 #define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
980
981 #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
982 #define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
983 #define QHSTA_D_HOST_ABORT_FAILED 0x23
984 #define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
985 #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
986
987 #define QHSTA_D_ASPI_NO_BUF_POOL 0x26
988
989 #define QHSTA_M_WTM_TIMEOUT 0x41
990 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
991 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
992 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
993 #define QHSTA_M_TARGET_STATUS_BUSY 0x45
994 #define QHSTA_M_BAD_TAG_CODE 0x46
995
996 #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
997
998 #define QHSTA_D_LRAM_CMP_ERROR 0x81
999 #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1000
1001 #define ASC_FLAG_SCSIQ_REQ 0x01
1002 #define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
1003 #define ASC_FLAG_BIOS_ASYNC_IO 0x04
1004 #define ASC_FLAG_SRB_LINEAR_ADDR 0x08
1005
1006 #define ASC_FLAG_WIN16 0x10
1007 #define ASC_FLAG_WIN32 0x20
1008
1009 #define ASC_FLAG_DOS_VM_CALLBACK 0x80
1010
1011 #define ASC_TAG_FLAG_ADD_ONE_BYTE 0x10
1012 #define ASC_TAG_FLAG_ISAPNP_ADD_BYTES 0x40
1013
1014 #define ASC_SCSIQ_CPY_BEG 4
1015 #define ASC_SCSIQ_SGHD_CPY_BEG 2
1016
1017 #define ASC_SCSIQ_B_FWD 0
1018 #define ASC_SCSIQ_B_BWD 1
1019
1020 #define ASC_SCSIQ_B_STATUS 2
1021 #define ASC_SCSIQ_B_QNO 3
1022
1023 #define ASC_SCSIQ_B_CNTL 4
1024 #define ASC_SCSIQ_B_SG_QUEUE_CNT 5
1025
1026 #define ASC_SCSIQ_D_DATA_ADDR 8
1027 #define ASC_SCSIQ_D_DATA_CNT 12
1028 #define ASC_SCSIQ_B_SENSE_LEN 20
1029 #define ASC_SCSIQ_DONE_INFO_BEG 22
1030 #define ASC_SCSIQ_D_SRBPTR 22
1031 #define ASC_SCSIQ_B_TARGET_IX 26
1032 #define ASC_SCSIQ_B_CDB_LEN 28
1033 #define ASC_SCSIQ_B_TAG_CODE 29
1034 #define ASC_SCSIQ_W_VM_ID 30
1035 #define ASC_SCSIQ_DONE_STATUS 32
1036 #define ASC_SCSIQ_HOST_STATUS 33
1037 #define ASC_SCSIQ_SCSI_STATUS 34
1038 #define ASC_SCSIQ_CDB_BEG 36
1039 #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1040 #define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
1041 #define ASC_SCSIQ_B_SG_WK_QP 49
1042 #define ASC_SCSIQ_B_SG_WK_IX 50
1043 #define ASC_SCSIQ_W_REQ_COUNT 52
1044 #define ASC_SCSIQ_B_LIST_CNT 6
1045 #define ASC_SCSIQ_B_CUR_LIST_CNT 7
1046
1047 #define ASC_SGQ_B_SG_CNTL 4
1048 #define ASC_SGQ_B_SG_HEAD_QP 5
1049 #define ASC_SGQ_B_SG_LIST_CNT 6
1050 #define ASC_SGQ_B_SG_CUR_LIST_CNT 7
1051 #define ASC_SGQ_LIST_BEG 8
1052
1053 #define ASC_DEF_SCSI1_QNG 2
1054 #define ASC_MAX_SCSI1_QNG 2
1055 #define ASC_DEF_SCSI2_QNG 16
1056 #define ASC_MAX_SCSI2_QNG 32
1057
1058 #define ASC_TAG_CODE_MASK 0x23
1059
1060 #define ASC_STOP_REQ_RISC_STOP 0x01
1061
1062 #define ASC_STOP_ACK_RISC_STOP 0x03
1063
1064 #define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
1065 #define ASC_STOP_CLEAN_UP_DISC_Q 0x20
1066 #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1067 #define ASC_STOP_SEND_INT_TO_HOST 0x80
1068
1069 #define ASC_TIDLUN_TO_IX( tid, lun ) ( ASC_SCSI_TIX_TYPE )( (tid) + ((lun)<<ASC_SCSI_ID_BITS) )
1070
1071 #define ASC_TID_TO_TARGET_ID( tid ) ( ASC_SCSI_BIT_ID_TYPE )( 0x01 << (tid) )
1072 #define ASC_TIX_TO_TARGET_ID( tix ) ( 0x01 << ( (tix) & ASC_MAX_TID ) )
1073 #define ASC_TIX_TO_TID( tix ) ( (tix) & ASC_MAX_TID )
1074 #define ASC_TID_TO_TIX( tid ) ( (tid) & ASC_MAX_TID )
1075 #define ASC_TIX_TO_LUN( tix ) ( ( (tix) >> ASC_SCSI_ID_BITS ) & ASC_MAX_LUN )
1076
1077 #define ASC_QNO_TO_QADDR( q_no ) ( (ASC_QADR_BEG)+( ( int )(q_no) << 6 ) )
1078
1079 typedef struct asc_scisq_1 {
1080 uchar status;
1081 uchar q_no;
1082 uchar cntl;
1083 uchar sg_queue_cnt;
1084
1085 uchar target_id;
1086 uchar target_lun;
1087
1088 ulong data_addr;
1089 ulong data_cnt;
1090 ulong sense_addr;
1091 uchar sense_len;
1092 uchar user_def;
1093 } ASC_SCSIQ_1;
1094
1095 typedef struct asc_scisq_2 {
1096 ulong srb_ptr;
1097 uchar target_ix;
1098
1099 uchar flag;
1100 uchar cdb_len;
1101 uchar tag_code;
1102
1103 ushort vm_id;
1104 } ASC_SCSIQ_2;
1105
1106 typedef struct asc_scsiq_3 {
1107 uchar done_stat;
1108 uchar host_stat;
1109 uchar scsi_stat;
1110 uchar scsi_msg;
1111 } ASC_SCSIQ_3;
1112
1113 typedef struct asc_scsiq_4 {
1114 uchar cdb[ASC_MAX_CDB_LEN];
1115 uchar y_first_sg_list_qp;
1116 uchar y_working_sg_qp;
1117 uchar y_working_sg_ix;
1118 uchar y_cntl;
1119 ushort x_req_count;
1120 ushort x_reconnect_rtn;
1121 ulong x_saved_data_addr;
1122 ulong x_saved_data_cnt;
1123 } ASC_SCSIQ_4;
1124
1125 typedef struct asc_q_done_info {
1126 ASC_SCSIQ_2 d2;
1127 ASC_SCSIQ_3 d3;
1128 uchar q_status;
1129 uchar q_no;
1130 uchar cntl;
1131 uchar sense_len;
1132 uchar user_def;
1133 uchar res;
1134 ulong remain_bytes;
1135 } ASC_QDONE_INFO;
1136
1137 typedef struct asc_sg_list {
1138 ulong addr;
1139 ulong bytes;
1140 } ASC_SG_LIST;
1141
1142 typedef struct asc_sg_head {
1143 uchar entry_cnt;
1144
1145 uchar queue_cnt;
1146
1147 uchar entry_to_copy;
1148 uchar res;
1149 ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
1150 } ASC_SG_HEAD;
1151
1152 #define ASC_MIN_SG_LIST 2
1153
1154 typedef struct asc_min_sg_head {
1155 uchar entry_cnt;
1156
1157 uchar queue_cnt;
1158
1159 uchar entry_to_copy;
1160 uchar res;
1161 ASC_SG_LIST sg_list[ASC_MIN_SG_LIST];
1162 } ASC_MIN_SG_HEAD;
1163
1164 #define QCX_SORT (0x0001)
1165 #define QCX_COALEASE (0x0002)
1166
1167 #if CC_LINK_BUSY_Q
1168 typedef struct asc_ext_scsi_q {
1169 ulong lba;
1170 ushort lba_len;
1171 struct asc_scsi_q dosfar *next;
1172 struct asc_scsi_q dosfar *join;
1173 ushort cntl;
1174 ushort buffer_id;
1175 uchar q_required;
1176 uchar res;
1177 } ASC_EXT_SCSI_Q;
1178
1179 #endif
1180
1181 typedef struct asc_scsi_q {
1182 ASC_SCSIQ_1 q1;
1183 ASC_SCSIQ_2 q2;
1184 uchar dosfar *cdbptr;
1185
1186 ASC_SG_HEAD dosfar *sg_head;
1187
1188 #if CC_LINK_BUSY_Q
1189 ASC_EXT_SCSI_Q ext;
1190 #endif
1191
1192 } ASC_SCSI_Q;
1193
1194 typedef struct asc_scsi_req_q {
1195 ASC_SCSIQ_1 r1;
1196 ASC_SCSIQ_2 r2;
1197 uchar dosfar *cdbptr;
1198 ASC_SG_HEAD dosfar *sg_head;
1199
1200 #if CC_LINK_BUSY_Q
1201 ASC_EXT_SCSI_Q ext;
1202 #endif
1203
1204 uchar dosfar *sense_ptr;
1205
1206 ASC_SCSIQ_3 r3;
1207 uchar cdb[ASC_MAX_CDB_LEN];
1208 uchar sense[ASC_MIN_SENSE_LEN];
1209 } ASC_SCSI_REQ_Q;
1210
1211 typedef struct asc_risc_q {
1212 uchar fwd;
1213 uchar bwd;
1214 ASC_SCSIQ_1 i1;
1215 ASC_SCSIQ_2 i2;
1216 ASC_SCSIQ_3 i3;
1217 ASC_SCSIQ_4 i4;
1218 } ASC_RISC_Q;
1219
1220 typedef struct asc_sg_list_q {
1221
1222 uchar seq_no;
1223 uchar q_no;
1224 uchar cntl;
1225 uchar sg_head_qp;
1226 uchar sg_list_cnt;
1227 uchar sg_cur_list_cnt;
1228
1229 } ASC_SG_LIST_Q;
1230
1231 typedef struct asc_risc_sg_list_q {
1232 uchar fwd;
1233 uchar bwd;
1234 ASC_SG_LIST_Q sg;
1235 ASC_SG_LIST sg_list[7];
1236 } ASC_RISC_SG_LIST_Q;
1237
1238 #define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP 0x1000000UL
1239 #define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP 1024
1240
1241 #define ASCQ_ERR_NO_ERROR 0
1242 #define ASCQ_ERR_IO_NOT_FOUND 1
1243 #define ASCQ_ERR_LOCAL_MEM 2
1244 #define ASCQ_ERR_CHKSUM 3
1245 #define ASCQ_ERR_START_CHIP 4
1246 #define ASCQ_ERR_INT_TARGET_ID 5
1247 #define ASCQ_ERR_INT_LOCAL_MEM 6
1248 #define ASCQ_ERR_HALT_RISC 7
1249 #define ASCQ_ERR_GET_ASPI_ENTRY 8
1250 #define ASCQ_ERR_CLOSE_ASPI 9
1251 #define ASCQ_ERR_HOST_INQUIRY 0x0A
1252 #define ASCQ_ERR_SAVED_SRB_BAD 0x0B
1253 #define ASCQ_ERR_QCNTL_SG_LIST 0x0C
1254 #define ASCQ_ERR_Q_STATUS 0x0D
1255 #define ASCQ_ERR_WR_SCSIQ 0x0E
1256 #define ASCQ_ERR_PC_ADDR 0x0F
1257 #define ASCQ_ERR_SYN_OFFSET 0x10
1258 #define ASCQ_ERR_SYN_XFER_TIME 0x11
1259 #define ASCQ_ERR_LOCK_DMA 0x12
1260 #define ASCQ_ERR_UNLOCK_DMA 0x13
1261 #define ASCQ_ERR_VDS_CHK_INSTALL 0x14
1262 #define ASCQ_ERR_MICRO_CODE_HALT 0x15
1263 #define ASCQ_ERR_SET_LRAM_ADDR 0x16
1264 #define ASCQ_ERR_CUR_QNG 0x17
1265 #define ASCQ_ERR_SG_Q_LINKS 0x18
1266 #define ASCQ_ERR_SCSIQ_PTR 0x19
1267 #define ASCQ_ERR_ISR_RE_ENTRY 0x1A
1268 #define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
1269 #define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
1270 #define ASCQ_ERR_SG_LIST_ODD_ADDRESS 0x1D
1271 #define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1272 #define ASCQ_ERR_SCSIQ_NULL_PTR 0x1F
1273 #define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR 0x20
1274 #define ASCQ_ERR_GET_NUM_OF_FREE_Q 0x21
1275 #define ASCQ_ERR_SEND_SCSI_Q 0x22
1276 #define ASCQ_ERR_HOST_REQ_RISC_HALT 0x23
1277 #define ASCQ_ERR_RESET_SDTR 0x24
1278
1279 #define ASC_WARN_NO_ERROR 0x0000
1280 #define ASC_WARN_IO_PORT_ROTATE 0x0001
1281 #define ASC_WARN_EEPROM_CHKSUM 0x0002
1282 #define ASC_WARN_IRQ_MODIFIED 0x0004
1283 #define ASC_WARN_AUTO_CONFIG 0x0008
1284 #define ASC_WARN_CMD_QNG_CONFLICT 0x0010
1285
1286 #define ASC_WARN_EEPROM_RECOVER 0x0020
1287 #define ASC_WARN_CFG_MSW_RECOVER 0x0040
1288
1289 #define ASC_IERR_WRITE_EEPROM 0x0001
1290 #define ASC_IERR_MCODE_CHKSUM 0x0002
1291 #define ASC_IERR_SET_PC_ADDR 0x0004
1292 #define ASC_IERR_START_STOP_CHIP 0x0008
1293
1294 #define ASC_IERR_IRQ_NO 0x0010
1295
1296 #define ASC_IERR_SET_IRQ_NO 0x0020
1297 #define ASC_IERR_CHIP_VERSION 0x0040
1298 #define ASC_IERR_SET_SCSI_ID 0x0080
1299 #define ASC_IERR_GET_PHY_ADDR 0x0100
1300 #define ASC_IERR_BAD_SIGNATURE 0x0200
1301 #define ASC_IERR_NO_BUS_TYPE 0x0400
1302 #define ASC_IERR_SCAM 0x0800
1303 #define ASC_IERR_SET_SDTR 0x1000
1304 #define ASC_IERR_RW_LRAM 0x8000
1305
1306 #define ASC_DEF_IRQ_NO 10
1307 #define ASC_MAX_IRQ_NO 15
1308 #define ASC_MIN_IRQ_NO 10
1309
1310 #define ASC_MIN_REMAIN_Q (0x02)
1311 #define ASC_DEF_MAX_TOTAL_QNG (0x40)
1312
1313 #define ASC_MIN_TAG_Q_PER_DVC (0x04)
1314 #define ASC_DEF_TAG_Q_PER_DVC (0x04)
1315
1316 #define ASC_MIN_FREE_Q ASC_MIN_REMAIN_Q
1317
1318 #define ASC_MIN_TOTAL_QNG (( ASC_MAX_SG_QUEUE )+( ASC_MIN_FREE_Q ))
1319
1320 #define ASC_MAX_TOTAL_QNG 240
1321 #define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
1322
1323 #define ASC_MAX_INRAM_TAG_QNG 16
1324
1325 typedef struct asc_dvc_cfg {
1326 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1327
1328 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1329 ASC_SCSI_BIT_ID_TYPE disc_enable;
1330 uchar res;
1331 uchar chip_scsi_id:4;
1332
1333 uchar isa_dma_speed:4;
1334
1335 uchar isa_dma_channel;
1336 uchar chip_version;
1337 ushort pci_device_id;
1338 ushort lib_serial_no;
1339 ushort lib_version;
1340 ushort mcode_date;
1341 ushort mcode_version;
1342 uchar sdtr_data[ASC_MAX_TID + 1];
1343 uchar max_tag_qng[ASC_MAX_TID + 1];
1344 uchar dosfar *overrun_buf;
1345
1346 } ASC_DVC_CFG;
1347
1348 #define ASC_DEF_DVC_CNTL 0xFFFF
1349 #define ASC_DEF_CHIP_SCSI_ID 7
1350 #define ASC_DEF_ISA_DMA_SPEED 4
1351
1352 #define ASC_INIT_STATE_NULL 0x0000
1353 #define ASC_INIT_STATE_BEG_GET_CFG 0x0001
1354 #define ASC_INIT_STATE_END_GET_CFG 0x0002
1355 #define ASC_INIT_STATE_BEG_SET_CFG 0x0004
1356 #define ASC_INIT_STATE_END_SET_CFG 0x0008
1357 #define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
1358 #define ASC_INIT_STATE_END_LOAD_MC 0x0020
1359 #define ASC_INIT_STATE_BEG_INQUIRY 0x0040
1360 #define ASC_INIT_STATE_END_INQUIRY 0x0080
1361 #define ASC_INIT_RESET_SCSI_DONE 0x0100
1362
1363 #define ASC_PCI_DEVICE_ID_REV_A 0x1100
1364 #define ASC_PCI_DEVICE_ID_REV_B 0x1200
1365
1366 #define ASC_BUG_FIX_ADD_ONE_BYTE 0x0001
1367
1368 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1369
1370 #define ASC_MIN_TAGGED_CMD 7
1371
1372 typedef struct asc_dvc_var {
1373 PortAddr iop_base;
1374 ushort err_code;
1375 ushort dvc_cntl;
1376 ushort bug_fix_cntl;
1377 ushort bus_type;
1378 Ptr2Func isr_callback;
1379 Ptr2Func exe_callback;
1380
1381 ASC_SCSI_BIT_ID_TYPE init_sdtr;
1382
1383 ASC_SCSI_BIT_ID_TYPE sdtr_done;
1384
1385 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1386
1387 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1388
1389 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1390
1391 ASC_SCSI_BIT_ID_TYPE start_motor;
1392 uchar scsi_reset_wait;
1393 uchar chip_no;
1394
1395 char is_in_int;
1396 uchar max_total_qng;
1397
1398 uchar cur_total_qng;
1399
1400 uchar in_critical_cnt;
1401
1402 uchar irq_no;
1403 uchar last_q_shortage;
1404
1405 ushort init_state;
1406 uchar cur_dvc_qng[ASC_MAX_TID + 1];
1407 uchar max_dvc_qng[ASC_MAX_TID + 1];
1408
1409 ASC_SCSI_Q dosfar *scsiq_busy_head[ASC_MAX_TID + 1];
1410 ASC_SCSI_Q dosfar *scsiq_busy_tail[ASC_MAX_TID + 1];
1411
1412 ulong int_count;
1413 ulong req_count;
1414 ulong busy_count;
1415
1416 ASC_DVC_CFG dosfar *cfg;
1417 Ptr2Func saved_ptr2func;
1418 ulong reserved2;
1419 ulong reserved3;
1420 ulong max_dma_count;
1421 ASC_SCSI_BIT_ID_TYPE no_scam;
1422 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1423 } ASC_DVC_VAR;
1424
1425 typedef int (dosfar * ASC_ISR_CALLBACK) (ASC_DVC_VAR asc_ptr_type *, ASC_QDONE_INFO dosfar *);
1426 typedef int (dosfar * ASC_EXE_CALLBACK) (ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q dosfar *);
1427
1428 typedef struct asc_dvc_inq_info {
1429 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1430 } ASC_DVC_INQ_INFO;
1431
1432 typedef struct asc_cap_info {
1433 ulong lba;
1434 ulong blk_size;
1435 } ASC_CAP_INFO;
1436
1437 typedef struct asc_cap_info_array {
1438 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1439 } ASC_CAP_INFO_ARRAY;
1440
1441 #define ASC_IOADR_TABLE_MAX_IX 11
1442 #define ASC_IOADR_GAP 0x10
1443 #define ASC_SEARCH_IOP_GAP 0x10
1444 #define ASC_MIN_IOP_ADDR ( PortAddr )0x0100
1445 #define ASC_MAX_IOP_ADDR ( PortAddr )0x3F0
1446
1447 #define ASC_IOADR_1 ( PortAddr )0x0110
1448 #define ASC_IOADR_2 ( PortAddr )0x0130
1449 #define ASC_IOADR_3 ( PortAddr )0x0150
1450 #define ASC_IOADR_4 ( PortAddr )0x0190
1451 #define ASC_IOADR_5 ( PortAddr )0x0210
1452 #define ASC_IOADR_6 ( PortAddr )0x0230
1453 #define ASC_IOADR_7 ( PortAddr )0x0250
1454 #define ASC_IOADR_8 ( PortAddr )0x0330
1455 #define ASC_IOADR_DEF ASC_IOADR_8
1456
1457 #define ASC_SYN_XFER_NO 8
1458 #define ASC_MAX_SDTR_PERIOD_INDEX 7
1459 #define ASC_SYN_MAX_OFFSET 0x0F
1460 #define ASC_DEF_SDTR_OFFSET 0x0F
1461 #define ASC_DEF_SDTR_INDEX 0x00
1462
1463 #define SYN_XFER_NS_0 25
1464 #define SYN_XFER_NS_1 30
1465 #define SYN_XFER_NS_2 35
1466 #define SYN_XFER_NS_3 40
1467 #define SYN_XFER_NS_4 50
1468 #define SYN_XFER_NS_5 60
1469 #define SYN_XFER_NS_6 70
1470 #define SYN_XFER_NS_7 85
1471
1472 #define ASC_SDTR_PERIOD_IX_MIN 7
1473
1474 #define SYN_XMSG_WLEN 3
1475
1476 typedef struct sdtr_xmsg {
1477 uchar msg_type;
1478 uchar msg_len;
1479 uchar msg_req;
1480 uchar xfer_period;
1481 uchar req_ack_offset;
1482 uchar res;
1483 } SDTR_XMSG;
1484
1485 #define ASC_MCNTL_NO_SEL_TIMEOUT ( ushort )0x0001
1486 #define ASC_MCNTL_NULL_TARGET ( ushort )0x0002
1487
1488 #define ASC_CNTL_INITIATOR ( ushort )0x0001
1489 #define ASC_CNTL_BIOS_GT_1GB ( ushort )0x0002
1490 #define ASC_CNTL_BIOS_GT_2_DISK ( ushort )0x0004
1491 #define ASC_CNTL_BIOS_REMOVABLE ( ushort )0x0008
1492 #define ASC_CNTL_NO_SCAM ( ushort )0x0010
1493 #define ASC_CNTL_NO_PCI_FIX_ASYN_XFER ( ushort )0x0020
1494
1495 #define ASC_CNTL_INT_MULTI_Q ( ushort )0x0080
1496
1497 #define ASC_CNTL_NO_LUN_SUPPORT ( ushort )0x0040
1498
1499 #define ASC_CNTL_NO_VERIFY_COPY ( ushort )0x0100
1500 #define ASC_CNTL_RESET_SCSI ( ushort )0x0200
1501 #define ASC_CNTL_INIT_INQUIRY ( ushort )0x0400
1502 #define ASC_CNTL_INIT_VERBOSE ( ushort )0x0800
1503
1504 #define ASC_CNTL_SCSI_PARITY ( ushort )0x1000
1505 #define ASC_CNTL_BURST_MODE ( ushort )0x2000
1506
1507 #define ASC_CNTL_USE_8_IOP_BASE ( ushort )0x4000
1508
1509 #define ASC_EEP_DVC_CFG_BEG_VL 2
1510 #define ASC_EEP_MAX_DVC_ADDR_VL 15
1511
1512 #define ASC_EEP_DVC_CFG_BEG 32
1513 #define ASC_EEP_MAX_DVC_ADDR 45
1514
1515 #define ASC_EEP_DEFINED_WORDS 10
1516 #define ASC_EEP_MAX_ADDR 63
1517 #define ASC_EEP_RES_WORDS 0
1518 #define ASC_EEP_MAX_RETRY 20
1519 #define ASC_MAX_INIT_BUSY_RETRY 8
1520
1521 #define ASC_EEP_ISA_PNP_WSIZE 16
1522
1523 typedef struct asceep_config {
1524 ushort cfg_lsw;
1525 ushort cfg_msw;
1526
1527 uchar init_sdtr;
1528 uchar disc_enable;
1529
1530 uchar use_cmd_qng;
1531
1532 uchar start_motor;
1533 uchar max_total_qng;
1534 uchar max_tag_qng;
1535 uchar bios_scan;
1536
1537 uchar power_up_wait;
1538
1539 uchar no_scam;
1540 uchar chip_scsi_id:4;
1541
1542 uchar isa_dma_speed:4;
1543
1544 uchar sdtr_data[ASC_MAX_TID + 1];
1545
1546 uchar adapter_info[6];
1547
1548 ushort cntl;
1549
1550 ushort chksum;
1551 } ASCEEP_CONFIG;
1552
1553 #define ASC_EEP_CMD_READ 0x80
1554 #define ASC_EEP_CMD_WRITE 0x40
1555 #define ASC_EEP_CMD_WRITE_ABLE 0x30
1556 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
1557
1558 #define ASC_OVERRUN_BSIZE 0x00000048UL
1559
1560 #define ASCV_MSGOUT_BEG 0x0000
1561 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1562 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1563
1564 #define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
1565 #define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
1566 #define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
1567
1568 #define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
1569 #define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
1570 #define ASCV_MAX_DVC_QNG_BEG ( ushort )0x0020
1571
1572 #define ASCV_ASCDVC_ERR_CODE_W ( ushort )0x0030
1573 #define ASCV_MCODE_CHKSUM_W ( ushort )0x0032
1574 #define ASCV_MCODE_SIZE_W ( ushort )0x0034
1575 #define ASCV_STOP_CODE_B ( ushort )0x0036
1576 #define ASCV_DVC_ERR_CODE_B ( ushort )0x0037
1577
1578 #define ASCV_OVERRUN_PADDR_D ( ushort )0x0038
1579 #define ASCV_OVERRUN_BSIZE_D ( ushort )0x003C
1580
1581 #define ASCV_HALTCODE_W ( ushort )0x0040
1582 #define ASCV_CHKSUM_W ( ushort )0x0042
1583 #define ASCV_MC_DATE_W ( ushort )0x0044
1584 #define ASCV_MC_VER_W ( ushort )0x0046
1585 #define ASCV_NEXTRDY_B ( ushort )0x0048
1586 #define ASCV_DONENEXT_B ( ushort )0x0049
1587 #define ASCV_USE_TAGGED_QNG_B ( ushort )0x004A
1588 #define ASCV_SCSIBUSY_B ( ushort )0x004B
1589 #define ASCV_CDBCNT_B ( ushort )0x004C
1590 #define ASCV_CURCDB_B ( ushort )0x004D
1591 #define ASCV_RCLUN_B ( ushort )0x004E
1592 #define ASCV_BUSY_QHEAD_B ( ushort )0x004F
1593 #define ASCV_DISC1_QHEAD_B ( ushort )0x0050
1594
1595 #define ASCV_DISC_ENABLE_B ( ushort )0x0052
1596 #define ASCV_CAN_TAGGED_QNG_B ( ushort )0x0053
1597 #define ASCV_HOSTSCSI_ID_B ( ushort )0x0055
1598 #define ASCV_MCODE_CNTL_B ( ushort )0x0056
1599 #define ASCV_NULL_TARGET_B ( ushort )0x0057
1600
1601 #define ASCV_FREE_Q_HEAD_W ( ushort )0x0058
1602 #define ASCV_DONE_Q_TAIL_W ( ushort )0x005A
1603 #define ASCV_FREE_Q_HEAD_B ( ushort )(ASCV_FREE_Q_HEAD_W+1)
1604 #define ASCV_DONE_Q_TAIL_B ( ushort )(ASCV_DONE_Q_TAIL_W+1)
1605
1606 #define ASCV_HOST_FLAG_B ( ushort )0x005D
1607
1608 #define ASCV_TOTAL_READY_Q_B ( ushort )0x0064
1609 #define ASCV_VER_SERIAL_B ( ushort )0x0065
1610 #define ASCV_HALTCODE_SAVED_W ( ushort )0x0066
1611 #define ASCV_WTM_FLAG_B ( ushort )0x0068
1612 #define ASCV_RISC_FLAG_B ( ushort )0x006A
1613 #define ASCV_REQ_SG_LIST_QP ( ushort )0x006B
1614
1615 #define ASC_HOST_FLAG_IN_ISR 0x01
1616 #define ASC_HOST_FLAG_ACK_INT 0x02
1617
1618 #define ASC_RISC_FLAG_GEN_INT 0x01
1619 #define ASC_RISC_FLAG_REQ_SG_LIST 0x02
1620
1621 #define IOP_CTRL (0x0F)
1622 #define IOP_STATUS (0x0E)
1623 #define IOP_INT_ACK IOP_STATUS
1624
1625 #define IOP_REG_IFC (0x0D)
1626
1627 #define IOP_SYN_OFFSET (0x0B)
1628 #define IOP_REG_PC (0x0C)
1629 #define IOP_RAM_ADDR (0x0A)
1630 #define IOP_RAM_DATA (0x08)
1631 #define IOP_EEP_DATA (0x06)
1632 #define IOP_EEP_CMD (0x07)
1633
1634 #define IOP_VERSION (0x03)
1635 #define IOP_CONFIG_HIGH (0x04)
1636 #define IOP_CONFIG_LOW (0x02)
1637 #define IOP_ASPI_ID_LOW (0x01)
1638 #define IOP_ASPI_ID_HIGH (0x00)
1639
1640 #define IOP_REG_DC1 (0x0E)
1641 #define IOP_REG_DC0 (0x0C)
1642 #define IOP_REG_SB (0x0B)
1643 #define IOP_REG_DA1 (0x0A)
1644 #define IOP_REG_DA0 (0x08)
1645 #define IOP_REG_SC (0x09)
1646 #define IOP_DMA_SPEED (0x07)
1647 #define IOP_REG_FLAG (0x07)
1648 #define IOP_FIFO_H (0x06)
1649 #define IOP_FIFO_L (0x04)
1650 #define IOP_REG_ID (0x05)
1651 #define IOP_REG_QP (0x03)
1652 #define IOP_REG_IH (0x02)
1653 #define IOP_REG_IX (0x01)
1654 #define IOP_REG_AX (0x00)
1655
1656 #define IFC_REG_LOCK (0x00)
1657 #define IFC_REG_UNLOCK (0x09)
1658
1659 #define IFC_WR_EN_FILTER (0x10)
1660 #define IFC_RD_NO_EEPROM (0x10)
1661 #define IFC_SLEW_RATE (0x20)
1662 #define IFC_ACT_NEG (0x40)
1663 #define IFC_INP_FILTER (0x80)
1664
1665 #define IFC_INIT_DEFAULT ( IFC_ACT_NEG | IFC_REG_UNLOCK )
1666
1667 #define SC_SEL (0x80)
1668 #define SC_BSY (0x40)
1669 #define SC_ACK (0x20)
1670 #define SC_REQ (0x10)
1671 #define SC_ATN (0x08)
1672 #define SC_IO (0x04)
1673 #define SC_CD (0x02)
1674 #define SC_MSG (0x01)
1675
1676 #define AscGetVarFreeQHead( port ) AscReadLramWord( port, ASCV_FREE_Q_HEAD_W )
1677 #define AscGetVarDoneQTail( port ) AscReadLramWord( port, ASCV_DONE_Q_TAIL_W )
1678 #define AscPutVarFreeQHead( port, val ) AscWriteLramWord( port, ASCV_FREE_Q_HEAD_W, val )
1679 #define AscPutVarDoneQTail( port, val ) AscWriteLramWord( port, ASCV_DONE_Q_TAIL_W, val )
1680
1681 #define AscGetRiscVarFreeQHead( port ) AscReadLramByte( port, ASCV_NEXTRDY_B )
1682 #define AscGetRiscVarDoneQTail( port ) AscReadLramByte( port, ASCV_DONENEXT_B )
1683 #define AscPutRiscVarFreeQHead( port, val ) AscWriteLramByte( port, ASCV_NEXTRDY_B, val )
1684 #define AscPutRiscVarDoneQTail( port, val ) AscWriteLramByte( port, ASCV_DONENEXT_B, val )
1685
1686 #define AscGetChipIFC( port ) inp( (port)+IOP_REG_IFC )
1687 #define AscPutChipIFC( port, data ) outp( (port)+IOP_REG_IFC, data )
1688
1689 #define AscGetChipLramAddr( port ) ( ushort )inpw( ( PortAddr )((port)+IOP_RAM_ADDR) )
1690 #define AscSetChipLramAddr( port, addr ) outpw( ( PortAddr )( (port)+IOP_RAM_ADDR ), addr )
1691 #define AscPutChipLramData( port, data ) outpw( (port)+IOP_RAM_DATA, data )
1692 #define AscGetChipLramData( port ) inpw( (port)+IOP_RAM_DATA )
1693
1694 #define AscWriteChipSyn( port, data ) outp( (port)+IOP_SYN_OFFSET, data )
1695 #define AscReadChipSyn( port ) inp( (port)+IOP_SYN_OFFSET )
1696
1697 #define AscWriteChipIH( port, data ) outpw( (port)+IOP_REG_IH, data )
1698 #define AscReadChipIH( port ) inpw( (port)+IOP_REG_IH )
1699
1700 #define AscWriteChipScsiID( port, data ) outp( (port)+IOP_REG_ID, data )
1701 #define AscReadChipScsiID( port ) inp( (port)+IOP_REG_ID )
1702
1703 #define AscGetChipDmaSpeed( port ) ( uchar )inp( (port)+IOP_DMA_SPEED )
1704 #define AscSetChipDmaSpeed( port, data ) outp( (port)+IOP_DMA_SPEED, data )
1705 #define AscGetChipQP( port ) ( uchar )inp( (port)+IOP_REG_QP )
1706 #define AscSetPCAddr( port, data ) outpw( (port)+IOP_REG_PC, data )
1707 #define AscGetPCAddr( port ) inpw( (port)+IOP_REG_PC )
1708 #define AscGetChipVerNo( port ) ( uchar )inp( (port)+IOP_VERSION )
1709
1710 #define AscGetChipEEPCmd( port ) ( uchar )inp( (port)+IOP_EEP_CMD )
1711 #define AscSetChipEEPCmd( port, data ) outp( (port)+IOP_EEP_CMD, data )
1712 #define AscGetChipEEPData( port ) inpw( (port)+IOP_EEP_DATA )
1713 #define AscSetChipEEPData( port, data ) outpw( (port)+IOP_EEP_DATA, data )
1714
1715 #define AscGetChipControl( port ) ( uchar )inp( (port)+IOP_CTRL )
1716 #define AscSetChipControl( port, cc_val ) outp( (port)+IOP_CTRL, cc_val )
1717
1718 #define AscGetChipStatus( port ) ( ASC_CS_TYPE )inpw( (port)+IOP_STATUS )
1719 #define AscSetChipStatus( port, cs_val ) outpw( (port)+IOP_STATUS, cs_val )
1720
1721 #define AscGetChipCfgLsw( port ) ( ushort )inpw( (port)+IOP_CONFIG_LOW )
1722 #define AscGetChipCfgMsw( port ) ( ushort )inpw( (port)+IOP_CONFIG_HIGH )
1723 #define AscSetChipCfgLsw( port, data ) outpw( (port)+IOP_CONFIG_LOW, data )
1724 #define AscSetChipCfgMsw( port, data ) outpw( (port)+IOP_CONFIG_HIGH, data )
1725
1726 #define AscIsIntPending( port ) ( AscGetChipStatus( port ) & CSW_INT_PENDING )
1727 #define AscGetChipScsiID( port ) ( ( AscGetChipCfgLsw( port ) >> 8 ) & ASC_MAX_TID )
1728
1729 #define ASC_HALT_EXTMSG_IN ( ushort )0x8000
1730 #define ASC_HALT_CHK_CONDITION ( ushort )0x8100
1731 #define ASC_HALT_SS_QUEUE_FULL ( ushort )0x8200
1732 #define ASC_HALT_SDTR_REJECTED ( ushort )0x4000
1733
1734 #define ASC_MAX_QNO 0xF8
1735 #define ASC_DATA_SEC_BEG ( ushort )0x0080
1736 #define ASC_DATA_SEC_END ( ushort )0x0080
1737 #define ASC_CODE_SEC_BEG ( ushort )0x0080
1738 #define ASC_CODE_SEC_END ( ushort )0x0080
1739 #define ASC_QADR_BEG (0x4000)
1740 #define ASC_QADR_USED ( ushort )( ASC_MAX_QNO * 64 )
1741 #define ASC_QADR_END ( ushort )0x7FFF
1742 #define ASC_QLAST_ADR ( ushort )0x7FC0
1743 #define ASC_QBLK_SIZE 0x40
1744 #define ASC_BIOS_DATA_QBEG 0xF8
1745
1746 #define ASC_MIN_ACTIVE_QNO 0x01
1747
1748 #define ASC_QLINK_END 0xFF
1749 #define ASC_EEPROM_WORDS 0x10
1750 #define ASC_MAX_MGS_LEN 0x10
1751
1752 #define ASC_BIOS_ADDR_DEF 0xDC00
1753 #define ASC_BIOS_SIZE 0x3800
1754 #define ASC_BIOS_RAM_OFF 0x3800
1755 #define ASC_BIOS_RAM_SIZE 0x800
1756 #define ASC_BIOS_MIN_ADDR 0xC000
1757 #define ASC_BIOS_MAX_ADDR 0xEC00
1758 #define ASC_BIOS_BANK_SIZE 0x0400
1759
1760 #define ASC_MCODE_START_ADDR 0x0080
1761
1762 #define ASC_CFG0_HOST_INT_ON 0x0020
1763 #define ASC_CFG0_BIOS_ON 0x0040
1764 #define ASC_CFG0_VERA_BURST_ON 0x0080
1765 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
1766
1767 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
1768 #define ASC_CFG1_LRAM_8BITS_ON 0x0800
1769
1770 #define ASC_CFG_MSW_CLR_MASK 0xF0C0
1771
1772 #define CSW_TEST1 ( ASC_CS_TYPE )0x8000
1773 #define CSW_AUTO_CONFIG ( ASC_CS_TYPE )0x4000
1774 #define CSW_RESERVED1 ( ASC_CS_TYPE )0x2000
1775 #define CSW_IRQ_WRITTEN ( ASC_CS_TYPE )0x1000
1776 #define CSW_33MHZ_SELECTED ( ASC_CS_TYPE )0x0800
1777 #define CSW_TEST2 ( ASC_CS_TYPE )0x0400
1778 #define CSW_TEST3 ( ASC_CS_TYPE )0x0200
1779 #define CSW_RESERVED2 ( ASC_CS_TYPE )0x0100
1780 #define CSW_DMA_DONE ( ASC_CS_TYPE )0x0080
1781 #define CSW_FIFO_RDY ( ASC_CS_TYPE )0x0040
1782
1783 #define CSW_EEP_READ_DONE ( ASC_CS_TYPE )0x0020
1784
1785 #define CSW_HALTED ( ASC_CS_TYPE )0x0010
1786 #define CSW_SCSI_RESET_ACTIVE ( ASC_CS_TYPE )0x0008
1787
1788 #define CSW_PARITY_ERR ( ASC_CS_TYPE )0x0004
1789 #define CSW_SCSI_RESET_LATCH ( ASC_CS_TYPE )0x0002
1790
1791 #define CSW_INT_PENDING ( ASC_CS_TYPE )0x0001
1792
1793 #define CIW_INT_ACK ( ASC_CS_TYPE )0x0100
1794 #define CIW_TEST1 ( ASC_CS_TYPE )0x0200
1795 #define CIW_TEST2 ( ASC_CS_TYPE )0x0400
1796 #define CIW_SEL_33MHZ ( ASC_CS_TYPE )0x0800
1797
1798 #define CIW_IRQ_ACT ( ASC_CS_TYPE )0x1000
1799
1800 #define CC_CHIP_RESET ( uchar )0x80
1801 #define CC_SCSI_RESET ( uchar )0x40
1802 #define CC_HALT ( uchar )0x20
1803 #define CC_SINGLE_STEP ( uchar )0x10
1804 #define CC_DMA_ABLE ( uchar )0x08
1805 #define CC_TEST ( uchar )0x04
1806 #define CC_BANK_ONE ( uchar )0x02
1807 #define CC_DIAG ( uchar )0x01
1808
1809 #define ASC_1000_ID0W 0x04C1
1810 #define ASC_1000_ID0W_FIX 0x00C1
1811 #define ASC_1000_ID1B 0x25
1812
1813 #define ASC_EISA_BIG_IOP_GAP (0x1C30-0x0C50)
1814 #define ASC_EISA_SMALL_IOP_GAP (0x0020)
1815 #define ASC_EISA_MIN_IOP_ADDR (0x0C30)
1816 #define ASC_EISA_MAX_IOP_ADDR (0xFC50)
1817 #define ASC_EISA_REV_IOP_MASK (0x0C83)
1818 #define ASC_EISA_PID_IOP_MASK (0x0C80)
1819 #define ASC_EISA_CFG_IOP_MASK (0x0C86)
1820
1821 #define ASC_GET_EISA_SLOT( iop ) ( PortAddr )( (iop) & 0xF000 )
1822
1823 #define ASC_EISA_ID_740 0x01745004UL
1824 #define ASC_EISA_ID_750 0x01755004UL
1825
1826 #define INS_HALTINT ( ushort )0x6281
1827 #define INS_HALT ( ushort )0x6280
1828 #define INS_SINT ( ushort )0x6200
1829 #define INS_RFLAG_WTM ( ushort )0x7380
1830
1831 #define ASC_MC_SAVE_CODE_WSIZE 0x500
1832 #define ASC_MC_SAVE_DATA_WSIZE 0x40
1833
1834 typedef struct asc_mc_saved {
1835 ushort data[ASC_MC_SAVE_DATA_WSIZE];
1836 ushort code[ASC_MC_SAVE_CODE_WSIZE];
1837 } ASC_MC_SAVED;
1838
1839 int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1840 int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1841 void AscWaitEEPRead(void);
1842 void AscWaitEEPWrite(void);
1843 ushort AscReadEEPWord(PortAddr, uchar);
1844 ushort AscWriteEEPWord(PortAddr, uchar, ushort);
1845 ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG dosfar *, ushort);
1846 int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG dosfar *, ushort);
1847 int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG dosfar *, ushort);
1848 ushort AscEEPSum(PortAddr, uchar, uchar);
1849
1850 int AscStartChip(PortAddr);
1851 int AscStopChip(PortAddr);
1852 void AscSetChipIH(PortAddr, ushort);
1853 int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1854
1855 int AscIsChipHalted(PortAddr);
1856
1857 void AscSetChipCfgDword(PortAddr, ulong);
1858 ulong AscGetChipCfgDword(PortAddr);
1859
1860 void AscAckInterrupt(PortAddr);
1861 void AscDisableInterrupt(PortAddr);
1862 void AscEnableInterrupt(PortAddr);
1863 void AscSetBank(PortAddr, uchar);
1864 uchar AscGetBank(PortAddr);
1865 int AscResetChipAndScsiBus(PortAddr);
1866 ushort AscGetIsaDmaChannel(PortAddr);
1867 ushort AscSetIsaDmaChannel(PortAddr, ushort);
1868 uchar AscSetIsaDmaSpeed(PortAddr, uchar);
1869 uchar AscGetIsaDmaSpeed(PortAddr);
1870
1871 uchar AscReadLramByte(PortAddr, ushort);
1872 ushort AscReadLramWord(PortAddr, ushort);
1873 ulong AscReadLramDWord(PortAddr, ushort);
1874 void AscWriteLramWord(PortAddr, ushort, ushort);
1875 void AscWriteLramDWord(PortAddr, ushort, ulong);
1876 void AscWriteLramByte(PortAddr, ushort, uchar);
1877 int AscVerWriteLramDWord(PortAddr, ushort, ulong);
1878 int AscVerWriteLramWord(PortAddr, ushort, ushort);
1879 int AscVerWriteLramByte(PortAddr, ushort, uchar);
1880
1881 ulong AscMemSumLramWord(PortAddr, ushort, int);
1882 void AscMemWordSetLram(PortAddr, ushort, ushort, int);
1883 void AscMemWordCopyToLram(PortAddr, ushort, ushort dosfar *, int);
1884 void AscMemDWordCopyToLram(PortAddr, ushort, ulong dosfar *, int);
1885 void AscMemWordCopyFromLram(PortAddr, ushort, ushort dosfar *, int);
1886 int AscMemWordCmpToLram(PortAddr, ushort, ushort dosfar *, int);
1887
1888 ushort AscInitAscDvcVar(ASC_DVC_VAR asc_ptr_type *);
1889 ulong AscLoadMicroCode(PortAddr, ushort,
1890 ushort dosfar *, ushort);
1891 ushort AscInitFromEEP(ASC_DVC_VAR asc_ptr_type *);
1892 ushort AscInitFromAscDvcVar(ASC_DVC_VAR asc_ptr_type *);
1893 ushort AscInitMicroCodeVar(ASC_DVC_VAR asc_ptr_type * asc_dvc);
1894
1895 void dosfar AscInitPollIsrCallBack(ASC_DVC_VAR asc_ptr_type *,
1896 ASC_QDONE_INFO dosfar *);
1897 int AscTestExternalLram(ASC_DVC_VAR asc_ptr_type *);
1898 ushort AscTestLramEndian(PortAddr);
1899
1900 uchar AscMsgOutSDTR(PortAddr, uchar, uchar);
1901
1902 uchar AscCalSDTRData(uchar, uchar);
1903 void AscSetChipSDTR(PortAddr, uchar, uchar);
1904 int AscInitChipAllSynReg(ASC_DVC_VAR asc_ptr_type *, uchar);
1905 uchar AscGetSynPeriodIndex(uchar);
1906 uchar AscSynIndexToPeriod(uchar);
1907 uchar AscAllocFreeQueue(PortAddr, uchar);
1908 uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1909 int AscRiscHaltedAbortSRB(ASC_DVC_VAR asc_ptr_type *, ulong);
1910 int AscRiscHaltedAbortTIX(ASC_DVC_VAR asc_ptr_type *, uchar);
1911 int AscRiscHaltedAbortALL(ASC_DVC_VAR asc_ptr_type *);
1912 int AscHostReqRiscHalt(PortAddr);
1913 int AscStopQueueExe(PortAddr);
1914 int AscStartQueueExe(PortAddr);
1915 int AscCleanUpDiscQueue(PortAddr);
1916 int AscCleanUpBusyQueue(PortAddr);
1917 int _AscAbortTidBusyQueue(ASC_DVC_VAR asc_ptr_type *,
1918 ASC_QDONE_INFO dosfar *, uchar);
1919 int _AscAbortSrbBusyQueue(ASC_DVC_VAR asc_ptr_type *,
1920 ASC_QDONE_INFO dosfar *, ulong);
1921 int AscWaitTixISRDone(ASC_DVC_VAR asc_ptr_type *, uchar);
1922 int AscWaitISRDone(ASC_DVC_VAR asc_ptr_type *);
1923 ulong AscGetOnePhyAddr(ASC_DVC_VAR asc_ptr_type *, uchar dosfar *, ulong);
1924
1925 int AscSendScsiQueue(ASC_DVC_VAR asc_ptr_type * asc_dvc,
1926 ASC_SCSI_Q dosfar * scsiq,
1927 uchar n_q_required);
1928 int AscPutReadyQueue(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q dosfar *, uchar);
1929 int AscPutReadySgListQueue(ASC_DVC_VAR asc_ptr_type *,
1930 ASC_SCSI_Q dosfar *, uchar);
1931 int AscAbortScsiIO(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q dosfar *);
1932 void AscExeScsiIO(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q dosfar *);
1933 int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1934 int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1935 ushort AscInitLram(ASC_DVC_VAR asc_ptr_type *);
1936 int AscReInitLram(ASC_DVC_VAR asc_ptr_type *);
1937 ushort AscInitQLinkVar(ASC_DVC_VAR asc_ptr_type *);
1938 int AscSetLibErrorCode(ASC_DVC_VAR asc_ptr_type *, ushort);
1939 int _AscWaitQDone(PortAddr, ASC_SCSI_Q dosfar *);
1940
1941 int AscEnterCritical(void);
1942 void AscLeaveCritical(int);
1943
1944 int AscIsrChipHalted(ASC_DVC_VAR asc_ptr_type *);
1945 uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
1946 ASC_QDONE_INFO dosfar *, ulong);
1947 int AscIsrQDone(ASC_DVC_VAR asc_ptr_type *);
1948 ushort AscIsrExeBusyQueue(ASC_DVC_VAR asc_ptr_type *, uchar);
1949 int AscScsiSetupCmdQ(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_REQ_Q dosfar *,
1950 uchar dosfar *, ulong);
1951
1952 int AscScsiInquiry(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_REQ_Q dosfar *,
1953 uchar dosfar *, int);
1954 int AscScsiTestUnitReady(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_REQ_Q dosfar *);
1955 int AscScsiStartStopUnit(ASC_DVC_VAR asc_ptr_type *,
1956 ASC_SCSI_REQ_Q dosfar *, uchar);
1957 int AscScsiReadCapacity(ASC_DVC_VAR asc_ptr_type *,
1958 ASC_SCSI_REQ_Q dosfar *,
1959 uchar dosfar *);
1960
1961 ulong dosfar *swapfarbuf4(uchar dosfar *);
1962 int PollQueueDone(ASC_DVC_VAR asc_ptr_type *,
1963 ASC_SCSI_REQ_Q dosfar *,
1964 int);
1965 int PollScsiReadCapacity(ASC_DVC_VAR asc_ptr_type *,
1966 ASC_SCSI_REQ_Q dosfar *,
1967 ASC_CAP_INFO dosfar *);
1968 int PollScsiInquiry(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_REQ_Q dosfar *,
1969 uchar dosfar *, int);
1970 int PollScsiTestUnitReady(ASC_DVC_VAR asc_ptr_type *,
1971 ASC_SCSI_REQ_Q dosfar *);
1972 int PollScsiStartUnit(ASC_DVC_VAR asc_ptr_type *,
1973 ASC_SCSI_REQ_Q dosfar *);
1974 int InitTestUnitReady(ASC_DVC_VAR asc_ptr_type *,
1975 ASC_SCSI_REQ_Q dosfar *);
1976 void AscDispInquiry(uchar, uchar, ASC_SCSI_INQUIRY dosfar *);
1977 int AscPollQDone(ASC_DVC_VAR asc_ptr_type *,
1978 ASC_SCSI_REQ_Q dosfar *, int);
1979
1980 int AscSetBIOSBank(PortAddr, int, ushort);
1981 int AscSetVlBIOSBank(PortAddr, int);
1982 int AscSetEisaBIOSBank(PortAddr, int);
1983 int AscSetIsaBIOSBank(PortAddr, int);
1984
1985 int AscIsBiosEnabled(PortAddr, ushort);
1986 void AscResetScsiBus(PortAddr);
1987 void AscClrResetScsiBus(PortAddr);
1988
1989 void AscSingleStepChip(PortAddr);
1990 uchar AscSetChipScsiID(PortAddr, uchar);
1991 ushort AscGetChipBiosAddress(PortAddr, ushort);
1992 ushort AscSetChipBiosAddress(PortAddr, ushort, ushort);
1993 uchar AscGetChipVersion(PortAddr, ushort);
1994 ushort AscGetChipBusType(PortAddr);
1995
1996 PortAddr AscSearchIOPortAddr11(PortAddr);
1997 PortAddr AscSearchIOPortAddr100(PortAddr);
1998 int AscFindSignature(PortAddr);
1999 void AscToggleIRQAct(PortAddr);
2000 int AscResetChip(PortAddr);
2001 void AscClrResetChip(PortAddr);
2002
2003 short itos(ushort, uchar dosfar *, short, short);
2004 int insnchar(uchar dosfar *, short, short, ruchar, short);
2005 void itoh(ushort, ruchar dosfar *);
2006 void btoh(uchar, ruchar dosfar *);
2007 void ltoh(ulong, ruchar dosfar *);
2008 uchar dosfar *todstr(ushort, uchar dosfar *);
2009 uchar dosfar *tohstr(ushort, uchar dosfar *);
2010 uchar dosfar *tobhstr(uchar, uchar dosfar *);
2011 uchar dosfar *tolhstr(ulong, uchar dosfar *);
2012
2013 void AscSetISAPNPWaitForKey(void);
2014 uchar AscGetChipIRQ(PortAddr, ushort);
2015 uchar AscSetChipIRQ(PortAddr, uchar, ushort);
2016 uchar AscGetChipScsiCtrl(PortAddr);
2017
2018 ushort AscGetEisaChipCfg(PortAddr);
2019 ushort AscGetEisaChipGpReg(PortAddr);
2020 ushort AscSetEisaChipCfg(PortAddr, ushort);
2021 ushort AscSetEisaChipGpReg(PortAddr, ushort);
2022
2023 ulong AscGetEisaProductID(PortAddr);
2024 PortAddr AscSearchIOPortAddrEISA(PortAddr);
2025
2026 int AscPollQTailSync(PortAddr);
2027 int AscPollQHeadSync(PortAddr);
2028 int AscWaitQTailSync(PortAddr);
2029
2030 int _AscRestoreMicroCode(PortAddr, ASC_MC_SAVED dosfar *);
2031
2032 int AscSCAM(ASC_DVC_VAR asc_ptr_type *);
2033
2034 ushort SwapByteOfWord(ushort word_val);
2035 ulong SwapWordOfDWord(ulong dword_val);
2036 ulong AdjEndianDword(ulong dword_val);
2037
2038 int AscAdjEndianScsiQ(ASC_SCSI_Q dosfar *);
2039 int AscAdjEndianQDoneInfo(ASC_QDONE_INFO dosfar *);
2040
2041 extern int DvcEnterCritical(void);
2042 extern void DvcLeaveCritical(int);
2043
2044 extern void DvcInPortWords(PortAddr, ushort dosfar *, int);
2045 extern void DvcOutPortWords(PortAddr, ushort dosfar *, int);
2046 extern void DvcOutPortDWords(PortAddr, ulong dosfar *, int);
2047
2048 extern void DvcSleepMilliSecond(ulong);
2049 extern void DvcDisplayString(uchar dosfar *);
2050 extern ulong DvcGetPhyAddr(uchar dosfar * buf_addr, ulong buf_len);
2051 extern ulong DvcGetSGList(ASC_DVC_VAR asc_ptr_type *, uchar dosfar *, ulong,
2052 ASC_SG_HEAD dosfar *);
2053
2054 extern void DvcSCAMDelayMS(ulong);
2055 extern int DvcDisableCPUInterrupt(void);
2056 extern void DvcRestoreCPUInterrupt(int);
2057
2058 void DvcPutScsiQ(PortAddr, ushort, ushort dosfar *, int);
2059 void DvcGetQinfo(PortAddr, ushort, ushort dosfar *, int);
2060
2061 PortAddr AscSearchIOPortAddr(PortAddr, ushort);
2062 ushort AscInitGetConfig(ASC_DVC_VAR asc_ptr_type *);
2063 ushort AscInitSetConfig(ASC_DVC_VAR asc_ptr_type *);
2064 ushort AscInitAsc1000Driver(ASC_DVC_VAR asc_ptr_type *);
2065 int AscInitScsiTarget(ASC_DVC_VAR asc_ptr_type *,
2066 ASC_DVC_INQ_INFO dosfar *,
2067 uchar dosfar *,
2068 ASC_CAP_INFO_ARRAY dosfar *,
2069 ushort);
2070 int AscInitPollBegin(ASC_DVC_VAR asc_ptr_type *);
2071 int AscInitPollEnd(ASC_DVC_VAR asc_ptr_type *);
2072 int AscInitPollTarget(ASC_DVC_VAR asc_ptr_type *,
2073 ASC_SCSI_REQ_Q dosfar *,
2074 ASC_SCSI_INQUIRY dosfar *,
2075 ASC_CAP_INFO dosfar *);
2076 int AscExeScsiQueue(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q dosfar *);
2077
2078 int AscISR(ASC_DVC_VAR asc_ptr_type *);
2079 void AscISR_AckInterrupt(ASC_DVC_VAR asc_ptr_type *);
2080 int AscISR_CheckQDone(ASC_DVC_VAR asc_ptr_type *,
2081 ASC_QDONE_INFO dosfar *,
2082 uchar dosfar *);
2083
2084 int AscStartUnit(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_TIX_TYPE);
2085 int AscStopUnit(
2086 ASC_DVC_VAR asc_ptr_type * asc_dvc,
2087 ASC_SCSI_TIX_TYPE target_ix
2088 );
2089
2090 uint AscGetNumOfFreeQueue(ASC_DVC_VAR asc_ptr_type *, uchar, uchar);
2091 int AscSgListToQueue(int);
2092 int AscQueueToSgList(int);
2093 int AscSetDvcErrorCode(ASC_DVC_VAR asc_ptr_type *, uchar);
2094
2095 int AscAbortSRB(ASC_DVC_VAR asc_ptr_type *, ulong);
2096 int AscResetDevice(ASC_DVC_VAR asc_ptr_type *, uchar);
2097 int AscResetSB(ASC_DVC_VAR asc_ptr_type *);
2098
2099 void AscEnableIsaDma(uchar);
2100 void AscDisableIsaDma(uchar);
2101
2102 ulong AscGetMaxDmaAddress(ushort);
2103 ulong AscGetMaxDmaCount(ushort);
2104
2105 int AscSaveMicroCode(ASC_DVC_VAR asc_ptr_type *, ASC_MC_SAVED dosfar *);
2106 int AscRestoreOldMicroCode(ASC_DVC_VAR asc_ptr_type *, ASC_MC_SAVED dosfar *);
2107 int AscRestoreNewMicroCode(ASC_DVC_VAR asc_ptr_type *, ASC_MC_SAVED dosfar *);
2108
2109
2110
2111
2112
2113 #ifdef ADVANSYS_DEBUG
2114 #define STATIC
2115 #else
2116 #define STATIC static
2117 #endif
2118
2119
2120
2121
2122
2123
2124 #define ASC_NUM_BOARD_SUPPORTED 4
2125 #define ASC_NUM_BUS 4
2126
2127
2128 #define ASC_BOARD(host) ((struct asc_board *) &(host)->hostdata)
2129
2130 #define NO_ISA_DMA 0xff
2131
2132 #ifndef min
2133 #define min(a, b) (((a) < (b)) ? (a) : (b))
2134 #endif
2135
2136
2137 #define ASC_TRUE 1
2138 #define ASC_FALSE 0
2139 #define ASC_NOERROR 1
2140 #define ASC_BUSY 0
2141 #define ASC_ERROR (-1)
2142
2143
2144 #define STATUS_BYTE(byte) (byte)
2145 #define MSG_BYTE(byte) ((byte) << 8)
2146 #define HOST_BYTE(byte) ((byte) << 16)
2147 #define DRIVER_BYTE(byte) ((byte) << 24)
2148
2149
2150 #define ASC_FRONT 1
2151 #define ASC_BACK 2
2152
2153
2154
2155 #define ASC_PCI_REV_A_INIT 0x01
2156 #define ASC_PCI_REV_A_DONE 0x02
2157 #define ASC_PCI_REV_B_INIT 0x04
2158 #define ASC_PCI_REV_B_DONE 0x08
2159
2160 #define PCI_BASE_CLASS_PREDEFINED 0x00
2161 #define PCI_BASE_CLASS_MASS_STORAGE 0x01
2162 #define PCI_BASE_CLASS_NETWORK 0x02
2163 #define PCI_BASE_CLASS_DISPLAY 0x03
2164 #define PCI_BASE_CLASS_MULTIMEDIA 0x04
2165 #define PCI_BASE_CLASS_MEMORY_CONTROLLER 0x05
2166 #define PCI_BASE_CLASS_BRIDGE_DEVICE 0x06
2167
2168
2169 #define PCI_SUB_CLASS_SCSI_CONTROLLER 0x00
2170 #define PCI_SUB_CLASS_IDE_CONTROLLER 0x01
2171 #define PCI_SUB_CLASS_FLOPPY_DISK_CONTROLLER 0x02
2172 #define PCI_SUB_CLASS_IPI_BUS_CONTROLLER 0x03
2173 #define PCI_SUB_CLASS_OTHER_MASS_CONTROLLER 0x80
2174
2175
2176 #define PCI_SUB_CLASS_ETHERNET_CONTROLLER 0x00
2177 #define PCI_SUB_CLASS_TOKEN_RING_CONTROLLER 0x01
2178 #define PCI_SUB_CLASS_FDDI_CONTROLLER 0x02
2179 #define PCI_SUB_CLASS_OTHER_NETWORK_CONTROLLER 0x80
2180
2181
2182 #define PCI_SUB_CLASS_VGA_CONTROLLER 0x00
2183 #define PCI_SUB_CLASS_XGA_CONTROLLER 0x01
2184 #define PCI_SUB_CLASS_OTHER_DISPLAY_CONTROLLER 0x80
2185
2186
2187 #define PCI_SUB_CLASS_VIDEO_DEVICE 0x00
2188 #define PCI_SUB_CLASS_AUDIO_DEVICE 0x01
2189 #define PCI_SUB_CLASS_OTHER_MULTIMEDIA_DEVICE 0x80
2190
2191
2192 #define PCI_SUB_CLASS_RAM_CONTROLLER 0x00
2193 #define PCI_SUB_CLASS_FLASH_CONTROLLER 0x01
2194 #define PCI_SUB_CLASS_OTHER_MEMORY_CONTROLLER 0x80
2195
2196
2197 #define PCI_SUB_CLASS_HOST_BRIDGE_CONTROLLER 0x00
2198 #define PCI_SUB_CLASS_ISA_BRIDGE_CONTROLLER 0x01
2199 #define PCI_SUB_CLASS_EISA_BRIDGE_CONTROLLER 0x02
2200 #define PCI_SUB_CLASS_MC_BRIDGE_CONTROLLER 0x03
2201 #define PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER 0x04
2202 #define PCI_SUB_CLASS_PCMCIA_BRIDGE_CONTROLLER 0x05
2203 #define PCI_SUB_CLASS_OTHER_BRIDGE_CONTROLLER 0x80
2204
2205 #define PCI_MAX_SLOT 0x1F
2206 #define PCI_MAX_BUS 0xFF
2207 #define ASC_PCI_VENDORID 0x10CD
2208 #define PCI_IOADDRESS_MASK 0xFFFE
2209
2210
2211
2212 #define PCI_CONFIG_ADDRESS_MECH1 0x0CF8
2213 #define PCI_CONFIG_DATA_MECH1 0x0CFC
2214
2215 #define PCI_CONFIG_FORWARD_REGISTER 0x0CFA
2216
2217 #define PCI_CONFIG_BUS_NUMBER_MASK 0x00FF0000
2218 #define PCI_CONFIG_DEVICE_FUNCTION_MASK 0x0000FF00
2219 #define PCI_CONFIG_REGISTER_NUMBER_MASK 0x000000F8
2220
2221 #define PCI_DEVICE_FOUND 0x0000
2222 #define PCI_DEVICE_NOT_FOUND 0xffff
2223
2224 #define SUBCLASS_OFFSET 0x0A
2225 #define CLASSCODE_OFFSET 0x0B
2226 #define VENDORID_OFFSET 0x00
2227 #define DEVICEID_OFFSET 0x02
2228
2229
2230
2231
2232
2233 #ifndef ADVANSYS_STATS
2234 #define ASC_STATS(counter)
2235 #define ASC_STATS_ADD(counter, count)
2236 #else
2237 #define ASC_STATS(counter) asc_stats.counter++
2238 #define ASC_STATS_ADD(counter, count) asc_stats.counter += (count)
2239 #endif
2240
2241 #ifndef ADVANSYS_DEBUG
2242
2243 #define ASC_DBG(lvl, s)
2244 #define ASC_DBG1(lvl, s, a1)
2245 #define ASC_DBG2(lvl, s, a1, a2)
2246 #define ASC_DBG3(lvl, s, a1, a2, a3)
2247 #define ASC_DBG4(lvl, s, a1, a2, a3, a4)
2248 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
2249 #define ASC_DBG_PRT_DVC_VAR(lvl, v)
2250 #define ASC_DBG_PRT_DVC_CFG(lvl, c)
2251 #define ASC_DBG_PRT_SCSI_Q(lvl, scsiqp)
2252 #define ASC_DBG_PRT_QDONE_INFO(lvl, qdone)
2253 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
2254 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
2255 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
2256 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
2257 #define ASC_ASSERT(a)
2258
2259 #else
2260
2261
2262
2263
2264
2265
2266
2267
2268 #define ASC_DBG(lvl, s) \
2269 { \
2270 if (asc_dbglvl >= (lvl)) { \
2271 printk(s); \
2272 } \
2273 }
2274
2275 #define ASC_DBG1(lvl, s, a1) \
2276 { \
2277 if (asc_dbglvl >= (lvl)) { \
2278 printk((s), (a1)); \
2279 } \
2280 }
2281
2282 #define ASC_DBG2(lvl, s, a1, a2) \
2283 { \
2284 if (asc_dbglvl >= (lvl)) { \
2285 printk((s), (a1), (a2)); \
2286 } \
2287 }
2288
2289 #define ASC_DBG3(lvl, s, a1, a2, a3) \
2290 { \
2291 if (asc_dbglvl >= (lvl)) { \
2292 printk((s), (a1), (a2), (a3)); \
2293 } \
2294 }
2295
2296 #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
2297 { \
2298 if (asc_dbglvl >= (lvl)) { \
2299 printk((s), (a1), (a2), (a3), (a4)); \
2300 } \
2301 }
2302
2303 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
2304 { \
2305 if (asc_dbglvl >= (lvl)) { \
2306 asc_prt_scsi_host(s); \
2307 } \
2308 }
2309
2310 #define ASC_DBG_PRT_DVC_VAR(lvl, v) \
2311 { \
2312 if (asc_dbglvl >= (lvl)) { \
2313 asc_prt_dvc_var(v); \
2314 } \
2315 }
2316
2317 #define ASC_DBG_PRT_DVC_CFG(lvl, c) \
2318 { \
2319 if (asc_dbglvl >= (lvl)) { \
2320 asc_prt_dvc_cfg(c); \
2321 } \
2322 }
2323
2324 #define ASC_DBG_PRT_SCSI_Q(lvl, scsiqp) \
2325 { \
2326 if (asc_dbglvl >= (lvl)) { \
2327 asc_prt_scsi_q(scsiqp); \
2328 } \
2329 }
2330
2331 #define ASC_DBG_PRT_QDONE_INFO(lvl, qdone) \
2332 { \
2333 if (asc_dbglvl >= (lvl)) { \
2334 asc_prt_qdone_info(qdone); \
2335 } \
2336 }
2337
2338 #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
2339 { \
2340 if (asc_dbglvl >= (lvl)) { \
2341 asc_prt_hex((name), (start), (length)); \
2342 } \
2343 }
2344
2345 #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
2346 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
2347
2348 #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
2349 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
2350
2351 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
2352 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
2353
2354 #define ASC_ASSERT(a) \
2355 { \
2356 if (!(a)) { \
2357 printk("ASC_ASSERT() Failure: file %s, line %d\n", \
2358 __FILE__, __LINE__); \
2359 } \
2360 }
2361 #endif
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375 struct asc_board {
2376
2377 ASC_DVC_VAR board;
2378 ASC_DVC_CFG cfg;
2379 uchar overrun_buf[ASC_OVERRUN_BSIZE];
2380
2381 ASC_SCSI_BIT_ID_TYPE pending_tidmask;
2382 Scsi_Cmnd *pending[ASC_MAX_TID];
2383
2384 ASC_SCSI_BIT_ID_TYPE init_tidmask;
2385 ASC_SCSI_REQ_Q scsireqq;
2386 ASC_CAP_INFO cap_info;
2387 ASC_SCSI_INQUIRY inquiry;
2388 };
2389
2390
2391
2392
2393 typedef struct _PCI_DATA_
2394 {
2395 uchar type;
2396 uchar bus;
2397 uchar slot;
2398 uchar func;
2399 uchar offset;
2400 } PCI_DATA;
2401
2402 typedef struct _PCI_DEVICE_
2403 {
2404 ushort vendorID;
2405 ushort deviceID;
2406 ushort slotNumber;
2407 ushort slotFound;
2408 uchar busNumber;
2409 uchar maxBusNumber;
2410 uchar devFunc;
2411 ushort startSlot;
2412 ushort endSlot;
2413 uchar bridge;
2414 uchar type;
2415 } PCI_DEVICE;
2416
2417 typedef struct _PCI_CONFIG_SPACE_
2418 {
2419 ushort vendorID;
2420 ushort deviceID;
2421 ushort command;
2422 ushort status;
2423 uchar revision;
2424 uchar classCode[3];
2425 uchar cacheSize;
2426 uchar latencyTimer;
2427 uchar headerType;
2428 uchar bist;
2429 ulong baseAddress[6];
2430 ushort reserved[4];
2431 ulong optionRomAddr;
2432 ushort reserved2[4];
2433 uchar irqLine;
2434 uchar irqPin;
2435 uchar minGnt;
2436 uchar maxLatency;
2437 } PCI_CONFIG_SPACE;
2438
2439 #ifdef ADVANSYS_STATS
2440 struct asc_stats {
2441 ulong command;
2442 ulong queuecommand;
2443 ulong abort;
2444 ulong reset;
2445 ulong biosparam;
2446 ulong interrupt;
2447 ulong callback;
2448 ulong cont_cnt;
2449 ulong cont_xfer;
2450 ulong sg_cnt;
2451 ulong sg_elem;
2452 ulong sg_xfer;
2453 ulong error;
2454
2455
2456
2457
2458
2459 ulong cmd_disable;
2460 ulong intr_disable;
2461
2462
2463
2464
2465 ulong enqueue;
2466 ulong dequeue;
2467
2468
2469
2470
2471 ulong rmqueue;
2472 } asc_stats;
2473 #endif
2474
2475
2476
2477
2478
2479
2480 #ifdef LINUX_1_3
2481 struct proc_dir_entry proc_scsi_advansys =
2482 {
2483 PROC_SCSI_ADVANSYS,
2484 8,
2485 "advansys",
2486 S_IFDIR | S_IRUGO | S_IXUGO,
2487 2
2488 };
2489 #endif
2490
2491 STATIC int asc_board_count;
2492 STATIC struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED];
2493 STATIC Scsi_Cmnd *asc_scsi_done;
2494
2495 STATIC ushort asc_bus[ASC_NUM_BUS] = {
2496 ASC_IS_ISA,
2497 ASC_IS_VL,
2498 ASC_IS_EISA,
2499 ASC_IS_PCI,
2500 };
2501
2502
2503
2504
2505
2506 int asc_iopflag = ASC_FALSE;
2507 int asc_ioport[ASC_NUM_BOARD_SUPPORTED] = { 0, 0, 0, 0 };
2508
2509 #ifdef ADVANSYS_DEBUG
2510 char *
2511 asc_bus_name[ASC_NUM_BUS] = {
2512 "ASC_IS_ISA",
2513 "ASC_IS_VL",
2514 "ASC_IS_EISA",
2515 "ASC_IS_PCI",
2516 };
2517
2518 int asc_dbglvl = 0;
2519 #endif
2520
2521
2522
2523
2524
2525
2526
2527
2528 #ifdef LINUX_1_3
2529 STATIC int asc_proc_copy(off_t, off_t, char *, int , char *, int);
2530 #endif
2531 STATIC void advansys_interrupt(int, struct pt_regs *);
2532 STATIC void advansys_command_done(Scsi_Cmnd *);
2533 STATIC int asc_execute_scsi_cmnd(Scsi_Cmnd *);
2534 STATIC void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
2535 STATIC void asc_execute_pending(struct Scsi_Host *);
2536 STATIC int asc_init_dev(ASC_DVC_VAR *, Scsi_Cmnd *);
2537 STATIC int asc_srch_pci_dev(PCI_DEVICE *);
2538 STATIC uchar asc_scan_method(PCI_DEVICE *);
2539 STATIC int asc_pci_find_dev(PCI_DEVICE *);
2540 STATIC void asc_get_pci_cfg(PCI_DEVICE *, PCI_CONFIG_SPACE *);
2541 STATIC ushort asc_get_cfg_word(PCI_DATA *);
2542 STATIC uchar asc_get_cfg_byte(PCI_DATA *);
2543 STATIC void asc_enqueue(struct Scsi_Host *, Scsi_Cmnd *, int, int);
2544 STATIC Scsi_Cmnd *asc_dequeue(struct Scsi_Host *, int);
2545 STATIC int asc_rmqueue(struct Scsi_Host *, Scsi_Cmnd *, int);
2546
2547
2548 ushort AscGetChipBiosAddress(PortAddr, ushort);
2549 int AscFindSignature(PortAddr);
2550
2551 #ifdef ADVANSYS_STATS
2552 STATIC int asc_prt_stats(char *, int);
2553 STATIC int asc_prt_stats_line(char *, int, char *fmt, ...);
2554 #endif
2555 #ifdef ADVANSYS_DEBUG
2556 STATIC void asc_prt_scsi_host(struct Scsi_Host *);
2557 STATIC void asc_prt_dvc_cfg(ASC_DVC_CFG *);
2558 STATIC void asc_prt_dvc_var(ASC_DVC_VAR *);
2559 STATIC void asc_prt_scsi_q(ASC_SCSI_Q *);
2560 STATIC void asc_prt_qdone_info(ASC_QDONE_INFO *);
2561 STATIC void asc_prt_hex(char *f, uchar *, int);
2562 STATIC int interrupts_enabled(void);
2563 #endif
2564
2565
2566
2567
2568
2569
2570 #ifdef LINUX_1_3
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584 int
2585 advansys_proc_info(char *buffer, char **start, off_t offset, int length,
2586 int hostno, int inout)
2587 {
2588 struct Scsi_Host *shp;
2589 int i;
2590 char *cp;
2591 int cplen;
2592 int cnt;
2593 int totcnt;
2594 int leftlen;
2595 char *curbuf;
2596 off_t advoffset;
2597 Scsi_Device *scd;
2598 char prtbuf[480];
2599
2600 ASC_DBG(1, "advansys_proc_info: begin\n");
2601
2602
2603
2604
2605 if (inout == TRUE) {
2606 return(-ENOSYS);
2607 }
2608
2609
2610
2611
2612
2613
2614 for (i = 0; i < asc_board_count; i++) {
2615 if (asc_host[i]->host_no == hostno) {
2616 break;
2617 }
2618 }
2619 if (i == asc_board_count) {
2620 return(-ENOENT);
2621 }
2622 shp = asc_host[i];
2623
2624
2625 *start = buffer;
2626
2627 curbuf = buffer;
2628 advoffset = 0;
2629 totcnt = 0;
2630 leftlen = length;
2631
2632
2633 cp = (char *) advansys_info(shp);
2634 strcat(cp, "\n");
2635 cplen = strlen(cp);
2636
2637
2638 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
2639 totcnt += cnt;
2640 leftlen -= cnt;
2641 if (leftlen == 0) {
2642 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2643 return totcnt;
2644 }
2645 advoffset += cplen;
2646 curbuf += cnt;
2647
2648
2649
2650
2651 cp = &prtbuf[0];
2652 sprintf(cp, "\nDevices attached to SCSI Host %d:\n", shp->host_no);
2653 cplen = strlen(cp);
2654 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
2655 totcnt += cnt;
2656 leftlen -= cnt;
2657 if (leftlen == 0) {
2658 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2659 return totcnt;
2660 }
2661 advoffset += cplen;
2662 curbuf += cnt;
2663
2664 cp = &prtbuf[0];
2665 for (scd = scsi_devices; scd; scd = scd->next) {
2666 if (scd->host == shp) {
2667 proc_print_scsidevice(scd, cp, &cplen, 0);
2668 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
2669 totcnt += cnt;
2670 leftlen -= cnt;
2671 if (leftlen == 0) {
2672 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2673 return totcnt;
2674 }
2675 advoffset += cplen;
2676 curbuf += cnt;
2677 }
2678 }
2679
2680 #ifdef ADVANSYS_STATS
2681
2682
2683
2684
2685
2686
2687 cp = &prtbuf[0];
2688 cplen = asc_prt_stats(cp, sizeof(prtbuf));
2689 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
2690 totcnt += cnt;
2691 leftlen -= cnt;
2692 if (leftlen == 0) {
2693 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2694 return totcnt;
2695 }
2696 advoffset += cplen;
2697 curbuf += cnt;
2698 #endif
2699
2700 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2701
2702 return totcnt;
2703 }
2704 #endif
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720 int
2721 advansys_detect(Scsi_Host_Template *tpnt)
2722 {
2723 static int detect_called = ASC_FALSE;
2724 int iop;
2725 int bus;
2726 struct Scsi_Host *shp;
2727 ASC_DVC_VAR *boardp;
2728 int ioport = 0;
2729 PCI_DEVICE pciDevice;
2730 PCI_CONFIG_SPACE pciConfig;
2731 int ret;
2732 extern PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX];
2733
2734
2735 if (detect_called == ASC_FALSE) {
2736 detect_called = ASC_TRUE;
2737 } else {
2738 printk("AdvanSys SCSI: advansys_detect() mulitple calls ignored\n");
2739 return 0;
2740 }
2741
2742 ASC_DBG(1, "advansys_detect: begin\n");
2743
2744 #ifdef LINUX_1_3
2745 tpnt->proc_dir = &proc_scsi_advansys;
2746 #endif
2747
2748 #ifdef ADVANSYS_STATS
2749 memset(&asc_stats, 0, sizeof(asc_stats));
2750 #endif
2751
2752 asc_board_count = 0;
2753
2754
2755
2756
2757
2758 if (asc_iopflag == ASC_TRUE) {
2759 for (ioport = 0; ioport < ASC_NUM_BOARD_SUPPORTED; ioport++) {
2760 ASC_DBG2(1, "asdvansys_detect: asc_ioport[%d] %x\n",
2761 ioport, asc_ioport[ioport]);
2762 if (asc_ioport[ioport] != 0) {
2763 for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX; iop++) {
2764 if (_asc_def_iop_base[iop] == asc_ioport[ioport]) {
2765 break;
2766 }
2767 }
2768 if (iop == ASC_IOADR_TABLE_MAX_IX) {
2769 printk("AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
2770 asc_ioport[ioport]);
2771 asc_ioport[ioport] = 0;
2772 }
2773 }
2774 }
2775 ioport = 0;
2776 }
2777
2778 memset(&pciDevice, 0, sizeof(PCI_DEVICE));
2779 memset(&pciConfig, 0, sizeof(PCI_CONFIG_SPACE));
2780 pciDevice.maxBusNumber = PCI_MAX_BUS;
2781 pciDevice.endSlot = PCI_MAX_SLOT;
2782
2783 for (bus = 0; bus < ASC_NUM_BUS; bus++) {
2784
2785 ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n",
2786 bus, asc_bus_name[bus]);
2787 iop = 0;
2788
2789 while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) {
2790
2791 ASC_DBG1(2, "advansys_detect: asc_board_count %d\n",
2792 asc_board_count);
2793
2794 switch (asc_bus[bus]) {
2795 case ASC_IS_ISA:
2796 case ASC_IS_VL:
2797 if (asc_iopflag == ASC_FALSE) {
2798 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
2799 } else {
2800
2801
2802
2803
2804
2805
2806 ASC_DBG(1, "advansys_detect: I/O port scanning modified\n");
2807 ioport_try_again:
2808 iop = 0;
2809 for (; ioport < ASC_NUM_BOARD_SUPPORTED; ioport++) {
2810 if ((iop = asc_ioport[ioport]) != 0) {
2811 break;
2812 }
2813 }
2814 if (iop) {
2815 ASC_DBG1(1, "advansys_detect: probing I/O port %x...\n",
2816 iop);
2817 if (check_region(iop, ASC_IOADR_GAP) != 0) {
2818 printk("AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop);
2819
2820 asc_ioport[ioport] = 0;
2821 goto ioport_try_again;
2822 } else if (AscFindSignature(iop) == ASC_FALSE) {
2823 printk("AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop);
2824
2825 asc_ioport[ioport] = 0;
2826 goto ioport_try_again;
2827 } else {
2828
2829
2830
2831
2832
2833
2834 if (asc_bus[bus] == ASC_IS_ISA &&
2835 (AscGetChipVersion(iop, ASC_IS_ISA) &
2836 ASC_CHIP_VER_ISA_BIT) == 0) {
2837
2838
2839
2840
2841
2842 ioport++;
2843 goto ioport_try_again;
2844 }
2845 }
2846
2847
2848
2849
2850
2851 asc_ioport[ioport++] = 0;
2852 }
2853 }
2854 break;
2855
2856 case ASC_IS_EISA:
2857 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
2858 break;
2859
2860 case ASC_IS_PCI:
2861 if (asc_srch_pci_dev(&pciDevice) != PCI_DEVICE_FOUND) {
2862 iop = 0;
2863 } else {
2864 ASC_DBG2(2,
2865 "advansys_detect: slotFound %d, busNumber %d\n",
2866 pciDevice.slotFound, pciDevice.busNumber);
2867 asc_get_pci_cfg(&pciDevice, &pciConfig);
2868 iop = pciConfig.baseAddress[0] & PCI_IOADDRESS_MASK;
2869 ASC_DBG2(2, "advansys_detect: iop %x, irqLine %d\n",
2870 iop, pciConfig.irqLine);
2871 }
2872 break;
2873
2874 default:
2875 ASC_DBG(0, "advansys_detect: unknown bus type\n");
2876 break;
2877 }
2878 ASC_DBG1(1, "advansys_detect: iop %x\n", iop);
2879
2880
2881
2882
2883 if (iop == 0) {
2884 break;
2885 }
2886
2887
2888
2889
2890
2891
2892
2893 ASC_DBG(2, "advansys_detect: scsi_register()\n");
2894 shp = scsi_register(tpnt, sizeof(struct asc_board));
2895
2896
2897 asc_host[asc_board_count++] = shp;
2898
2899
2900 memset(ASC_BOARD(shp), 0, sizeof(struct asc_board));
2901 boardp = &ASC_BOARD(shp)->board;
2902 boardp->cfg = &ASC_BOARD(shp)->cfg;
2903 boardp->cfg->overrun_buf = &ASC_BOARD(shp)->overrun_buf[0];
2904 boardp->iop_base = iop;
2905
2906
2907
2908
2909 boardp->bus_type = asc_bus[bus];
2910 switch (boardp->bus_type) {
2911 case ASC_IS_ISA:
2912 shp->unchecked_isa_dma = TRUE;
2913 break;
2914 case ASC_IS_EISA:
2915 shp->unchecked_isa_dma = FALSE;
2916 break;
2917 case ASC_IS_VL:
2918 shp->unchecked_isa_dma = FALSE;
2919 break;
2920 case ASC_IS_PCI:
2921 shp->irq = boardp->irq_no = pciConfig.irqLine;
2922 boardp->cfg->pci_device_id = pciConfig.deviceID;
2923 shp->unchecked_isa_dma = FALSE;
2924 break;
2925 default:
2926 ASC_DBG(0, "advansys_detect: unknown adapter type");
2927 shp->unchecked_isa_dma = TRUE;
2928 break;
2929 }
2930
2931
2932
2933
2934
2935
2936 ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n");
2937 switch(ret = AscInitGetConfig(boardp)) {
2938 case 0:
2939 break;
2940 case ASC_WARN_IO_PORT_ROTATE:
2941 ASC_DBG(0, "AscInitGetConfig: I/O port address modified\n");
2942 break;
2943 case ASC_WARN_EEPROM_CHKSUM:
2944 ASC_DBG(0, "AscInitGetConfig: EEPROM checksum error\n");
2945 break;
2946 case ASC_WARN_IRQ_MODIFIED:
2947 ASC_DBG(0, "AscInitGetConfig: IRQ modified\n");
2948 break;
2949 case ASC_WARN_CMD_QNG_CONFLICT:
2950 ASC_DBG(0,
2951 "AscInitGetConfig: Tag queuing enabled w/o disconnects\n");
2952 break;
2953 default:
2954 ASC_DBG1(0, "AscInitGetConfig: Unknown warning: %x\n", ret);
2955 break;
2956 }
2957 if (boardp->err_code != 0) {
2958 ASC_DBG2(0,
2959 "AscInitGetConfig: error: init_state %x, err_code %x\n",
2960 boardp->init_state, boardp->err_code);
2961 scsi_unregister(shp);
2962 asc_board_count--;
2963 continue;
2964 }
2965
2966
2967
2968
2969 boardp->isr_callback = (Ptr2Func) asc_isr_callback;
2970 boardp->exe_callback = (Ptr2Func) NULL;
2971
2972 ASC_DBG(2, "advansys_detect: AscInitSetConfig()\n");
2973 switch (ret = AscInitSetConfig(boardp)) {
2974 case 0:
2975 break;
2976 case ASC_WARN_IO_PORT_ROTATE:
2977 ASC_DBG(0, "AscInitSetConfig: I/O port address modified\n");
2978 break;
2979 case ASC_WARN_EEPROM_CHKSUM:
2980 ASC_DBG(0, "AscInitSetConfig: EEPROM checksum error\n");
2981 break;
2982 case ASC_WARN_IRQ_MODIFIED:
2983 ASC_DBG(0, "AscInitSetConfig: IRQ modified\n");
2984 break;
2985 case ASC_WARN_CMD_QNG_CONFLICT:
2986 ASC_DBG(0, "AscInitSetConfig: Tag queuing w/o disconnects\n");
2987 break;
2988 default:
2989 ASC_DBG1(0, "AscInitSetConfig: Unknown warning: %x\n", ret);
2990 break;
2991 }
2992 if (boardp->err_code != 0) {
2993 ASC_DBG2(0,
2994 "AscInitSetConfig: error: init_state %x, err_code %x\n",
2995 boardp->init_state, boardp->err_code);
2996 scsi_unregister(shp);
2997 asc_board_count--;
2998 continue;
2999 }
3000
3001
3002
3003
3004
3005
3006 if (boardp->bus_type != ASC_IS_PCI) {
3007 shp->irq = boardp->irq_no;
3008 }
3009
3010 shp->io_port = boardp->iop_base;
3011 shp->n_io_port = ASC_IOADR_GAP;
3012 shp->this_id = boardp->cfg->chip_scsi_id;
3013
3014
3015 shp->can_queue = boardp->max_total_qng;
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034 #ifdef MODULE
3035 shp->cmd_per_lun = 1;
3036 #else
3037 shp->cmd_per_lun = 4;
3038 #endif
3039 ASC_DBG1(1, "advansys_detect: cmd_per_lun: %d\n", shp->cmd_per_lun);
3040
3041
3042
3043
3044
3045
3046
3047 #ifdef MODULE
3048 shp->sg_tablesize = 8;
3049 #else
3050 shp->sg_tablesize = ASC_MAX_SG_LIST;
3051 #endif
3052 ASC_DBG1(1, "advansys_detect: sg_tablesize: %d\n",
3053 shp->sg_tablesize);
3054
3055
3056 shp->base = (char *) ((ulong) AscGetChipBiosAddress(
3057 boardp->iop_base,
3058 boardp->bus_type));
3059
3060
3061
3062
3063
3064
3065 ASC_DBG(2, "advansys_detect: request_region()\n");
3066 request_region(shp->io_port, shp->n_io_port, "advansys");
3067
3068
3069 if ((boardp->bus_type & ASC_IS_ISA) == 0) {
3070 shp->dma_channel = NO_ISA_DMA;
3071 } else {
3072 shp->dma_channel = boardp->cfg->isa_dma_channel;
3073 if ((ret = request_dma(shp->dma_channel, "advansys")) != 0) {
3074 ASC_DBG2(0, "advansys_detect: request_dma() %d failed %d\n",
3075 shp->dma_channel, ret);
3076 release_region(shp->io_port, shp->n_io_port);
3077 scsi_unregister(shp);
3078 asc_board_count--;
3079 continue;
3080 }
3081 AscEnableIsaDma(shp->dma_channel);
3082 }
3083
3084
3085 ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq);
3086 if ((ret = request_irq(shp->irq, advansys_interrupt,
3087 SA_INTERRUPT, "advansys")) != 0) {
3088 ASC_DBG1(0, "advansys_detect: request_irq() failed %d\n", ret);
3089 release_region(shp->io_port, shp->n_io_port);
3090 if (shp->dma_channel != NO_ISA_DMA) {
3091 free_dma(shp->dma_channel);
3092 }
3093 scsi_unregister(shp);
3094 asc_board_count--;
3095 continue;
3096 }
3097
3098
3099
3100
3101 ASC_DBG(2, "advansys_detect: AscInitAsc1000Driver()\n");
3102 if (AscInitAsc1000Driver(boardp)) {
3103 ASC_DBG2(0,
3104 "AscInitAsc1000Driver: error: init_state %x, err_code %x\n",
3105 boardp->init_state, boardp->err_code);
3106 release_region(shp->io_port, shp->n_io_port);
3107 if (shp->dma_channel != NO_ISA_DMA) {
3108 free_dma(shp->dma_channel);
3109 }
3110 free_irq(shp->irq);
3111 scsi_unregister(shp);
3112 asc_board_count--;
3113 continue;
3114 }
3115 ASC_DBG_PRT_SCSI_HOST(2, shp);
3116 }
3117 }
3118
3119 ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", asc_board_count);
3120 return asc_board_count;
3121 }
3122
3123
3124
3125
3126
3127
3128 int
3129 advansys_release(struct Scsi_Host *shp)
3130 {
3131 ASC_DBG(1, "advansys_release: begin\n");
3132 free_irq(shp->irq);
3133 if (shp->dma_channel != NO_ISA_DMA) {
3134 ASC_DBG(1, "advansys_release: free_dma()\n");
3135 free_dma(shp->dma_channel);
3136 }
3137 release_region(shp->io_port, shp->n_io_port);
3138 scsi_unregister(shp);
3139 ASC_DBG(1, "advansys_release: end\n");
3140 return 0;
3141 }
3142
3143
3144
3145
3146
3147
3148
3149 const char *
3150 advansys_info(struct Scsi_Host *shp)
3151 {
3152 static char info[128];
3153 ASC_DVC_VAR *boardp;
3154 char *busname;
3155
3156 boardp = &ASC_BOARD(shp)->board;
3157 ASC_DBG(1, "advansys_info: begin\n");
3158 if (boardp->bus_type & ASC_IS_ISA) {
3159 sprintf(info,
3160 "AdvanSys SCSI %s: ISA (%u CDB): BIOS %X, IO %X-%X, IRQ %u, DMA %u",
3161 ASC_VERSION, ASC_BOARD(shp)->board.max_total_qng,
3162 (unsigned) shp->base, shp->io_port,
3163 shp->io_port + (shp->n_io_port - 1), shp->irq, shp->dma_channel);
3164 } else {
3165 switch (boardp->bus_type) {
3166 case ASC_IS_EISA:
3167 busname = "EISA";
3168 break;
3169 case ASC_IS_VL:
3170 busname = "VL";
3171 break;
3172 case ASC_IS_PCI:
3173 busname = "PCI";
3174 break;
3175 default:
3176 busname = "?";
3177 ASC_DBG1(0, "advansys_info: unknown bus type %d\n",
3178 boardp->bus_type);
3179 break;
3180 }
3181
3182 sprintf(info,
3183 "AdvanSys SCSI %s: %s (%u CDB): BIOS %X, IO %X-%X, IRQ %u",
3184 ASC_VERSION, busname, ASC_BOARD(shp)->board.max_total_qng,
3185 (unsigned) shp->base, shp->io_port,
3186 shp->io_port + (shp->n_io_port - 1), shp->irq);
3187 }
3188 ASC_DBG(1, "advansys_info: end\n");
3189 return info;
3190 }
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200 int
3201 advansys_command(Scsi_Cmnd *scp)
3202 {
3203 ASC_DBG1(1, "advansys_command: scp %x\n", (unsigned) scp);
3204 ASC_STATS(command);
3205 scp->SCp.Status = 0;
3206 advansys_queuecommand(scp, advansys_command_done);
3207 while (scp->SCp.Status == 0) {
3208 continue;
3209 }
3210 ASC_DBG1(1, "advansys_command: result %x\n", scp->result);
3211 return scp->result;
3212 }
3213
3214
3215
3216
3217
3218
3219
3220 int
3221 advansys_queuecommand(Scsi_Cmnd *scp, void (*done)(Scsi_Cmnd *))
3222 {
3223 struct Scsi_Host *shp;
3224 int flags = 0;
3225 int interrupts_disabled;
3226
3227 ASC_STATS(queuecommand);
3228 shp = scp->host;
3229
3230 #ifdef LINUX_1_2
3231
3232
3233
3234
3235 #ifdef ADVANSYS_STATS_1_2_PRINT
3236
3237 if ((asc_stats.queuecommand % 10000) == 0) {
3238 printk("\n");
3239 (void) asc_prt_stats(NULL, 0);
3240 printk("\n");
3241 }
3242 #endif
3243 #endif
3244
3245
3246
3247
3248
3249
3250
3251
3252 if (ASC_BOARD(shp)->pending_tidmask == 0) {
3253 interrupts_disabled = ASC_FALSE;
3254 } else {
3255 ASC_STATS(cmd_disable);
3256
3257 interrupts_disabled = ASC_TRUE;
3258 save_flags(flags);
3259 cli();
3260 ASC_DBG1(1, "advansys_queuecommand: asc_execute_pending() %x\n",
3261 ASC_BOARD(shp)->pending_tidmask);
3262 asc_execute_pending(shp);
3263 }
3264
3265
3266
3267
3268
3269 scp->scsi_done = done;
3270 if (asc_execute_scsi_cmnd(scp) == ASC_BUSY) {
3271 if (interrupts_disabled == ASC_FALSE) {
3272 save_flags(flags);
3273 cli();
3274 interrupts_disabled = ASC_TRUE;
3275 }
3276 asc_enqueue(shp, scp, scp->target, ASC_BACK);
3277 }
3278
3279 if (interrupts_disabled == ASC_TRUE) {
3280 restore_flags(flags);
3281 }
3282
3283 return 0;
3284 }
3285
3286
3287
3288
3289
3290
3291
3292 int
3293 advansys_abort(Scsi_Cmnd *scp)
3294 {
3295 ASC_DVC_VAR *boardp;
3296 int flags;
3297 int ret;
3298
3299 ASC_DBG1(1, "advansys_abort: scp %x\n", (unsigned) scp);
3300 save_flags(flags);
3301 cli();
3302 ASC_STATS(abort);
3303 if (scp->host == NULL) {
3304 scp->result = HOST_BYTE(DID_ERROR);
3305 ret = SCSI_ABORT_ERROR;
3306 } else if (asc_rmqueue(scp->host, scp, scp->target) == ASC_TRUE) {
3307 scp->result = HOST_BYTE(DID_ABORT);
3308 ret = SCSI_ABORT_SUCCESS;
3309 (void) AscResetDevice(&ASC_BOARD(scp->host)->board, scp->target);
3310 } else {
3311
3312 sti();
3313 boardp = &ASC_BOARD(scp->host)->board;
3314 scp->result = HOST_BYTE(DID_ABORT);
3315 switch (AscAbortSRB(boardp, (ulong) scp)) {
3316 case ASC_TRUE:
3317
3318 ASC_DBG(1, "advansys_abort: AscAbortSRB() TRUE\n");
3319 ret = SCSI_ABORT_PENDING;
3320 break;
3321 case ASC_FALSE:
3322
3323 ASC_DBG(1, "advansys_abort: AscAbortSRB() FALSE\n");
3324 ret = SCSI_ABORT_NOT_RUNNING;
3325 break;
3326 case ASC_ERROR:
3327 default:
3328 ASC_DBG(1, "advansys_abort: AscAbortSRB() ERROR\n");
3329 ret = SCSI_ABORT_ERROR;
3330 break;
3331 }
3332 (void) AscResetDevice(boardp, scp->target);
3333 }
3334 restore_flags(flags);
3335 ASC_DBG1(1, "advansys_abort: ret %d\n", ret);
3336 return ret;
3337 }
3338
3339
3340
3341
3342
3343
3344
3345 int
3346 advansys_reset(Scsi_Cmnd *scp)
3347 {
3348 ASC_DVC_VAR *boardp;
3349 int flags;
3350 Scsi_Cmnd *tscp;
3351 int i;
3352 int ret;
3353
3354 ASC_DBG1(1, "advansys_reset: %x\n", (unsigned) scp);
3355 save_flags(flags);
3356 cli();
3357 ASC_STATS(reset);
3358 if (scp->host == NULL) {
3359 scp->result = HOST_BYTE(DID_ERROR);
3360 ret = SCSI_RESET_ERROR;
3361 } else {
3362
3363 for (i = 0; i < ASC_MAX_TID; i++) {
3364 while ((tscp = asc_dequeue(scp->host, i)) != NULL) {
3365 tscp->result = HOST_BYTE(DID_RESET);
3366 tscp->scsi_done(tscp);
3367 }
3368 }
3369
3370 sti();
3371 boardp = &ASC_BOARD(scp->host)->board;
3372 scp->result = HOST_BYTE(DID_RESET);
3373 switch (AscResetSB(boardp)) {
3374 case ASC_TRUE:
3375 ASC_DBG(1, "advansys_abort: AscResetSB() TRUE\n");
3376 ret = SCSI_RESET_SUCCESS;
3377 break;
3378 case ASC_ERROR:
3379 default:
3380 ASC_DBG(1, "advansys_abort: AscResetSB() ERROR\n");
3381 ret = SCSI_RESET_ERROR;
3382 break;
3383 }
3384 }
3385 restore_flags(flags);
3386 ASC_DBG1(1, "advansys_reset: ret %d", ret);
3387 return ret;
3388 }
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401 int
3402 #ifdef LINUX_1_2
3403 advansys_biosparam(Disk *dp, int dep, int ip[])
3404 #else
3405 advansys_biosparam(Disk *dp, kdev_t dep, int ip[])
3406 #endif
3407 {
3408 ASC_DBG(1, "advansys_biosparam: begin\n");
3409 ASC_STATS(biosparam);
3410 if ((ASC_BOARD(dp->device->host)->board.dvc_cntl & ASC_CNTL_BIOS_GT_1GB) &&
3411 dp->capacity > 0x200000) {
3412 ip[0] = 255;
3413 ip[1] = 64;
3414 } else {
3415 ip[0] = 64;
3416 ip[1] = 32;
3417 }
3418 ip[2] = dp->capacity / (ip[0] * ip[1]);
3419 ASC_DBG(1, "advansys_biosparam: end\n");
3420 return 0;
3421 }
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457 void
3458 advansys_setup(char *str, int *ints)
3459 {
3460 int i;
3461
3462 if (asc_iopflag == ASC_TRUE) {
3463 printk("AdvanSys SCSI: 'advansys' LILO option may appear only once\n");
3464 return;
3465 }
3466
3467 asc_iopflag = ASC_TRUE;
3468
3469 if (ints[0] > ASC_NUM_BOARD_SUPPORTED) {
3470 #ifdef ADVANSYS_DEBUG
3471 if ((ints[0] == ASC_NUM_BOARD_SUPPORTED + 1) &&
3472 (ints[ASC_NUM_BOARD_SUPPORTED + 1] >> 4 == 0xdeb)) {
3473 asc_dbglvl = ints[ASC_NUM_BOARD_SUPPORTED + 1] & 0xf;
3474 } else {
3475 #endif
3476 printk("AdvanSys SCSI: only %d I/O ports accepted\n",
3477 ASC_NUM_BOARD_SUPPORTED);
3478 #ifdef ADVANSYS_DEBUG
3479 }
3480 #endif
3481 }
3482
3483 #ifdef ADVANSYS_DEBUG
3484 ASC_DBG1(1, "advansys_setup: ints[0] %d\n", ints[0]);
3485 for (i = 1; i < ints[0]; i++) {
3486 ASC_DBG2(1, " ints[%d] %x", i, ints[i]);
3487 }
3488 ASC_DBG(1, "\n");
3489 #endif
3490
3491 for (i = 1; i <= ints[0] && i <= ASC_NUM_BOARD_SUPPORTED; i++) {
3492 asc_ioport[i-1] = ints[i];
3493 ASC_DBG2(1, "advansys_setup: asc_ioport[%d] %x\n",
3494 i - 1, asc_ioport[i-1]);
3495 }
3496 }
3497
3498
3499
3500
3501
3502
3503 #ifdef MODULE
3504 Scsi_Host_Template driver_template = ADVANSYS;
3505 # include "scsi_module.c"
3506 #endif
3507
3508
3509
3510
3511
3512
3513 #ifdef LINUX_1_3
3514
3515
3516
3517
3518
3519
3520 STATIC int
3521 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
3522 char *cp, int cplen)
3523 {
3524 int cnt = 0;
3525
3526 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
3527 (unsigned) offset, (unsigned) advoffset, cplen);
3528 if (offset <= advoffset) {
3529
3530 cnt = min(cplen, leftlen);
3531 ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n",
3532 (unsigned) curbuf, (unsigned) cp, cnt);
3533 memcpy(curbuf, cp, cnt);
3534 } else if (offset < advoffset + cplen) {
3535
3536 cnt = (advoffset + cplen) - offset;
3537 cp = (cp + cplen) - cnt;
3538 cnt = min(cnt, leftlen);
3539 ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n",
3540 (unsigned) curbuf, (unsigned) cp, cnt);
3541 memcpy(curbuf, cp, cnt);
3542 }
3543 return cnt;
3544 }
3545 #endif
3546
3547
3548
3549
3550 STATIC void
3551 advansys_interrupt(int irq, struct pt_regs *regs)
3552 {
3553 int i;
3554 int flags;
3555 Scsi_Cmnd *scp;
3556 Scsi_Cmnd *tscp;
3557
3558
3559 save_flags(flags);
3560 cli();
3561
3562 ASC_DBG(1, "advansys_interrupt: begin\n");
3563 ASC_STATS(interrupt);
3564
3565
3566
3567
3568 for (i = 0; i < asc_board_count; i++) {
3569 while (AscIsIntPending(asc_host[i]->io_port)) {
3570 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
3571 AscISR(&ASC_BOARD(asc_host[i])->board);
3572 }
3573 }
3574 ASC_DBG(1, "advansys_interrupt: end\n");
3575
3576
3577
3578
3579
3580
3581 if ((scp = asc_scsi_done) != NULL) {
3582 asc_scsi_done = NULL;
3583 }
3584
3585
3586 restore_flags(flags);
3587
3588 while (scp) {
3589 tscp = (Scsi_Cmnd *) scp->host_scribble;
3590 scp->scsi_done(scp);
3591 scp = tscp;
3592 }
3593
3594 return;
3595 }
3596
3597
3598
3599
3600
3601 STATIC void
3602 advansys_command_done(Scsi_Cmnd *scp)
3603 {
3604 ASC_DBG1(1, "advansys_command_done: scp %x\n", (unsigned) scp);
3605 scp->SCp.Status = 1;
3606 }
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647 STATIC int
3648 asc_execute_scsi_cmnd(Scsi_Cmnd *scp)
3649 {
3650 ASC_DVC_VAR *boardp;
3651 ASC_SCSI_Q scsiq;
3652 ASC_SG_HEAD sghead;
3653 int ret;
3654
3655 ASC_DBG2(1, "asc_execute_scsi_cmnd: scp %x, done %x\n",
3656 (unsigned) scp, (unsigned) scp->scsi_done);
3657
3658 boardp = &ASC_BOARD(scp->host)->board;
3659
3660
3661
3662
3663
3664 if ((ASC_BOARD(scp->host)->init_tidmask &
3665 ASC_TIX_TO_TARGET_ID(scp->target)) == 0) {
3666 if (asc_init_dev(boardp, scp) == ASC_FALSE) {
3667 scp->result = HOST_BYTE(DID_BAD_TARGET);
3668 scp->scsi_done(scp);
3669 return ASC_ERROR;
3670 }
3671 ASC_BOARD(scp->host)->init_tidmask |= ASC_TIX_TO_TARGET_ID(scp->target);
3672 }
3673
3674 memset(&scsiq, 0, sizeof(ASC_SCSI_Q));
3675
3676
3677
3678
3679 scsiq.q2.srb_ptr = (ulong) scp;
3680
3681
3682
3683
3684 scsiq.cdbptr = &scp->cmnd[0];
3685 scsiq.q2.cdb_len = scp->cmd_len;
3686 scsiq.q1.target_id = ASC_TID_TO_TARGET_ID(scp->target);
3687 scsiq.q1.target_lun = scp->lun;
3688 scsiq.q2.target_ix = ASC_TIDLUN_TO_IX(scp->target, scp->lun);
3689 scsiq.q1.sense_addr = (ulong) &scp->sense_buffer[0];
3690 scsiq.q1.sense_len = sizeof(scp->sense_buffer);
3691 scsiq.q2.tag_code = M2_QTAG_MSG_SIMPLE;
3692
3693
3694
3695
3696
3697 if (scp->use_sg == 0) {
3698
3699
3700
3701 ASC_STATS(cont_cnt);
3702
3703 scsiq.q1.data_addr = (ulong) scp->request_buffer;
3704 scsiq.q1.data_cnt = scp->request_bufflen;
3705 ASC_STATS_ADD(cont_xfer, (scp->request_bufflen + 511) >> 9);
3706 scsiq.q1.sg_queue_cnt = 0;
3707 scsiq.sg_head = NULL;
3708 } else {
3709
3710
3711
3712 int sgcnt;
3713 struct scatterlist *slp;
3714
3715 if (scp->use_sg > ASC_MAX_SG_LIST) {
3716 ASC_DBG2(0, "asc_execute_scsi_cmnd: use_sg %d > %d\n",
3717 scp->use_sg, ASC_MAX_SG_LIST);
3718 scp->result = HOST_BYTE(DID_ERROR);
3719 scp->scsi_done(scp);
3720 return ASC_ERROR;
3721 }
3722
3723 ASC_STATS(sg_cnt);
3724
3725
3726
3727
3728
3729 memset(&sghead, 0, sizeof(ASC_SG_HEAD));
3730
3731 scsiq.q1.cntl |= QC_SG_HEAD;
3732 scsiq.sg_head = &sghead;
3733 scsiq.q1.data_cnt = 0;
3734 scsiq.q1.data_addr = 0;
3735 sghead.entry_cnt = scsiq.q1.sg_queue_cnt = scp->use_sg;
3736 ASC_STATS_ADD(sg_elem, sghead.entry_cnt);
3737
3738
3739
3740
3741 slp = (struct scatterlist *) scp->request_buffer;
3742 for (sgcnt = 0; sgcnt < scp->use_sg; sgcnt++, slp++) {
3743 sghead.sg_list[sgcnt].addr = (ulong) slp->address;
3744 sghead.sg_list[sgcnt].bytes = slp->length;
3745 ASC_STATS_ADD(sg_xfer, (slp->length + 511) >> 9);
3746 }
3747 }
3748
3749 ASC_DBG_PRT_SCSI_Q(2, &scsiq);
3750 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
3751
3752 switch (ret = AscExeScsiQueue(boardp, &scsiq)) {
3753 case ASC_NOERROR:
3754 ASC_DBG(1, "asc_execute_scsi_cmnd: AscExeScsiQueue() ASC_NOERROR\n");
3755 break;
3756 case ASC_BUSY:
3757
3758 break;
3759 case ASC_ERROR:
3760 ASC_DBG1(0,
3761 "asc_execute_scsi_cmnd: AscExeScsiQueue() ASC_ERROR err_code %x\n",
3762 boardp->err_code);
3763 ASC_STATS(error);
3764 scp->result = HOST_BYTE(DID_ERROR);
3765 scp->scsi_done(scp);
3766 break;
3767 }
3768
3769 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
3770 return ret;
3771 }
3772
3773
3774
3775
3776 void
3777 asc_isr_callback(ASC_DVC_VAR *boardp, ASC_QDONE_INFO *qdonep)
3778 {
3779 Scsi_Cmnd *scp;
3780 struct Scsi_Host *shp;
3781 int flags;
3782 Scsi_Cmnd **scpp;
3783
3784 ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
3785 ASC_DBG2(1, "asc_isr_callback: boardp %x, qdonep %x\n",
3786 (unsigned) boardp, (unsigned) qdonep);
3787 ASC_STATS(callback);
3788 ASC_DBG_PRT_QDONE_INFO(2, qdonep);
3789
3790
3791
3792
3793
3794 scp = (Scsi_Cmnd *) qdonep->d2.srb_ptr;
3795 ASC_DBG1(1, "asc_isr_callback: scp %x\n", (unsigned) scp);
3796 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
3797
3798 shp = scp->host;
3799 ASC_ASSERT(shp);
3800 ASC_DBG1(1, "asc_isr_callback: shp %x\n", (unsigned) shp);
3801
3802
3803
3804
3805 switch (qdonep->d3.done_stat) {
3806 case QD_NO_ERROR:
3807 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
3808 switch (qdonep->d3.host_stat) {
3809 case QHSTA_NO_ERROR:
3810 scp->result = 0;
3811 break;
3812 default:
3813
3814 scp->result = HOST_BYTE(DID_ERROR);
3815 break;
3816 }
3817 break;
3818
3819 case QD_WITH_ERROR:
3820 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
3821 switch (qdonep->d3.host_stat) {
3822 case QHSTA_NO_ERROR:
3823 if (qdonep->d3.scsi_stat == SS_CHK_CONDITION) {
3824 ASC_DBG(2, "asc_isr_callback: SS_CHK_CONDITION\n");
3825 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
3826 sizeof(scp->sense_buffer));
3827
3828
3829
3830
3831
3832
3833
3834
3835 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
3836 STATUS_BYTE(qdonep->d3.scsi_stat);
3837 } else {
3838 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
3839 }
3840 break;
3841
3842 default:
3843
3844 ASC_DBG1(2, "asc_isr_callback: host_stat %x\n",
3845 qdonep->d3.host_stat);
3846 scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
3847 STATUS_BYTE(qdonep->d3.scsi_stat);
3848 break;
3849 }
3850 break;
3851
3852 case QD_ABORTED_BY_HOST:
3853 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
3854 scp->result = HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.scsi_msg) |
3855 STATUS_BYTE(qdonep->d3.scsi_stat);
3856 break;
3857
3858 default:
3859 ASC_DBG1(0, "asc_isr_callback: done_stat %x\n", qdonep->d3.done_stat );
3860 scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
3861 STATUS_BYTE(qdonep->d3.scsi_stat);
3862 break;
3863 }
3864
3865
3866
3867
3868
3869
3870 if (ASC_BOARD(shp)->pending_tidmask != 0) {
3871
3872
3873
3874
3875 ASC_STATS(intr_disable);
3876 save_flags(flags);
3877 cli();
3878 ASC_DBG1(1, "asc_isr_callback: asc_execute_pending() %x\n",
3879 ASC_BOARD(shp)->pending_tidmask);
3880 asc_execute_pending(shp);
3881 restore_flags(flags);
3882 }
3883
3884
3885
3886
3887
3888
3889 for (scpp = &asc_scsi_done; *scpp;
3890 scpp = (Scsi_Cmnd **) &(*scpp)->host_scribble) {
3891 ;
3892 }
3893 *scpp = scp;
3894 scp->host_scribble = NULL;
3895 return;
3896 }
3897
3898
3899
3900
3901
3902 STATIC void
3903 asc_execute_pending(struct Scsi_Host *shp)
3904 {
3905 ASC_SCSI_BIT_ID_TYPE scan_tidmask;
3906 Scsi_Cmnd *scp;
3907 int i;
3908
3909 ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
3910
3911
3912
3913
3914 scan_tidmask = ASC_BOARD(shp)->pending_tidmask;
3915 do {
3916 for (i = 0; i < ASC_MAX_TID; i++) {
3917 if (scan_tidmask & ASC_TIX_TO_TARGET_ID(i)) {
3918 if ((scp = asc_dequeue(shp, i)) == NULL) {
3919 scan_tidmask &= ~ASC_TIX_TO_TARGET_ID(i);
3920 } else if (asc_execute_scsi_cmnd(scp) == ASC_BUSY) {
3921 scan_tidmask &= ~ASC_TIX_TO_TARGET_ID(i);
3922
3923 asc_enqueue(shp, scp, i, ASC_FRONT);
3924 }
3925 }
3926 }
3927 } while (scan_tidmask);
3928 return;
3929 }
3930
3931
3932
3933
3934
3935
3936 STATIC int
3937 asc_init_dev(ASC_DVC_VAR *boardp, Scsi_Cmnd *scp)
3938 {
3939 ASC_SCSI_REQ_Q *scsireqq;
3940 ASC_CAP_INFO *cap_info;
3941 ASC_SCSI_INQUIRY *inquiry;
3942 int found;
3943 ASC_SCSI_BIT_ID_TYPE save_use_tagged_qng;
3944 ASC_SCSI_BIT_ID_TYPE save_can_tagged_qng;
3945 int ret;
3946 #ifdef ADVANSYS_DEBUG
3947 ASC_SCSI_BIT_ID_TYPE tidmask;
3948 #endif
3949
3950 ASC_DBG1(1, "asc_init_dev: target %d\n", (unsigned) scp->target);
3951
3952
3953 if (boardp->cfg->chip_scsi_id == scp->target) {
3954 return ASC_TRUE;
3955 }
3956
3957
3958
3959
3960
3961
3962
3963 scp->timeout += 2000;
3964
3965
3966 scsireqq = &ASC_BOARD(scp->host)->scsireqq;
3967 memset(scsireqq, 0, sizeof(ASC_SCSI_REQ_Q));
3968 cap_info = &ASC_BOARD(scp->host)->cap_info;
3969 memset(cap_info, 0, sizeof(ASC_CAP_INFO));
3970 inquiry = &ASC_BOARD(scp->host)->inquiry;
3971 memset(inquiry, 0, sizeof(ASC_SCSI_INQUIRY));
3972
3973
3974
3975
3976
3977
3978
3979 save_use_tagged_qng = boardp->use_tagged_qng;
3980 save_can_tagged_qng = boardp->cfg->can_tagged_qng;
3981
3982 ASC_DBG(2, "asc_init_dev: AscInitPollBegin()\n");
3983 if (AscInitPollBegin(boardp)) {
3984 ASC_DBG(0, "asc_init_dev: AscInitPollBegin() failed\n");
3985 return ASC_FALSE;
3986 }
3987
3988 scsireqq->sense_ptr = &scsireqq->sense[0];
3989 scsireqq->r1.sense_len = ASC_MIN_SENSE_LEN;
3990 scsireqq->r1.target_id = ASC_TID_TO_TARGET_ID(scp->target);
3991 scsireqq->r1.target_lun = 0;
3992 scsireqq->r2.target_ix = ASC_TIDLUN_TO_IX(scp->target, 0);
3993
3994 found = ASC_FALSE;
3995 ASC_DBG(2, "asc_init_dev: AscInitPollTarget()\n");
3996 switch (ret = AscInitPollTarget(boardp, scsireqq, inquiry, cap_info)) {
3997 case ASC_TRUE:
3998 found = ASC_TRUE;
3999 #ifdef ADVANSYS_DEBUG
4000 tidmask = ASC_TIX_TO_TARGET_ID(scp->target);
4001 ASC_DBG2(1, "asc_init_dev: lba %lu, blk_size %lu\n",
4002 cap_info->lba, cap_info->blk_size);
4003 ASC_DBG1(1, "asc_init_dev: peri_dvc_type %x\n",
4004 inquiry->byte0.peri_dvc_type);
4005 if (boardp->use_tagged_qng & tidmask) {
4006 ASC_DBG1(1, "asc_init_dev: command queuing enabled: %d\n",
4007 boardp->max_dvc_qng[scp->target]);
4008 } else {
4009 ASC_DBG(1, "asc_init_dev: command queuing disabled\n");
4010 }
4011 if (boardp->init_sdtr & tidmask) {
4012 ASC_DBG(1, "asc_init_dev: synchronous transfers enabled\n");
4013 } else {
4014 ASC_DBG(1, "asc_init_dev: synchronous transfers disabled\n");
4015 }
4016
4017 if (boardp->pci_fix_asyn_xfer & tidmask) {
4018 ASC_DBG(1, "asc_init_dev: synchronous transfer fix disabled\n");
4019 } else {
4020 ASC_DBG(1, "asc_init_dev: synchronous transfer fix enabled\n");
4021 }
4022 #endif
4023 break;
4024 case ASC_FALSE:
4025 ASC_DBG(1, "asc_init_dev: no device found\n");
4026 break;
4027 case ASC_ERROR:
4028 ASC_DBG(0, "asc_init_dev: AscInitPollTarget() ASC_ERROR\n");
4029 break;
4030 default:
4031 ASC_DBG1(0, "asc_init_dev: AscInitPollTarget() unknown ret %d\n", ret);
4032 break;
4033 }
4034
4035
4036 boardp->use_tagged_qng |= save_use_tagged_qng;
4037 boardp->cfg->can_tagged_qng |= save_can_tagged_qng;
4038
4039 ASC_DBG(2, "asc_init_dev: AscInitPollEnd()\n");
4040 AscInitPollEnd(boardp);
4041
4042 #ifdef ASC_SET_CMD_PER_LUN
4043
4044
4045
4046
4047 for (i = 0; i <= ASC_MAX_TID; i++) {
4048 if (boardp->max_dvc_qng[i] < scp->host->cmd_per_lun) {
4049 scp->host->cmd_per_lun = boardp->max_dvc_qng[i];
4050 }
4051 }
4052 #endif
4053
4054 return found;
4055 }
4056
4057
4058
4059
4060 STATIC int
4061 asc_srch_pci_dev(PCI_DEVICE *pciDevice)
4062 {
4063 int ret;
4064 static int scan = 1;
4065
4066 ASC_DBG(2, "asc_srch_pci_dev: begin\n");
4067
4068 if (scan) {
4069 pciDevice->type = asc_scan_method(pciDevice);
4070 scan = 0;
4071 ASC_DBG1(2, "asc_srch_pci_dev: type %d\n", pciDevice->type);
4072 }
4073 ret = asc_pci_find_dev(pciDevice);
4074 ASC_DBG1(2, "asc_srch_pci_dev: asc_pci_find_dev() return %d\n", ret);
4075 if (ret == PCI_DEVICE_FOUND) {
4076 pciDevice->slotNumber = pciDevice->slotFound + 1;
4077 pciDevice->startSlot = pciDevice->slotFound + 1;
4078 } else {
4079 if (pciDevice->bridge > pciDevice->busNumber) {
4080 ASC_DBG2(2, "asc_srch_pci_dev: bridge %x, busNumber %x\n",
4081 pciDevice->bridge, pciDevice->busNumber);
4082 pciDevice->busNumber++;
4083 pciDevice->slotNumber = 0;
4084 pciDevice->startSlot = 0;
4085 pciDevice->endSlot = 0x0f;
4086 ret = asc_srch_pci_dev(pciDevice);
4087 ASC_DBG1(2, "asc_srch_pci_dev recursive call return %d\n", ret);
4088 }
4089 }
4090 ASC_DBG1(2, "asc_srch_pci_dev: return %d\n", ret);
4091 return ret;
4092 }
4093
4094
4095
4096
4097 STATIC uchar
4098 asc_scan_method(PCI_DEVICE *pciDevice)
4099 {
4100 ushort data;
4101 PCI_DATA pciData;
4102 uchar type;
4103 uchar slot;
4104
4105 ASC_DBG(2, "asc_scan_method: begin\n");
4106 memset(&pciData, 0, sizeof(pciData));
4107 for (type = 1; type < 3; type++) {
4108 pciData.type = type;
4109 for (slot = 0; slot < PCI_MAX_SLOT; slot++) {
4110 pciData.slot = slot;
4111 data = asc_get_cfg_word(&pciData);
4112 if ((data != 0xFFFF) && (data != 0x0000)) {
4113 ASC_DBG2(4, "asc_scan_method: data %x, type %d\n", data, type);
4114 return (type);
4115 }
4116 }
4117 }
4118 ASC_DBG1(4, "asc_scan_method: type %d\n", type);
4119 return (type);
4120 }
4121
4122
4123
4124
4125
4126
4127 STATIC int
4128 asc_pci_find_dev(PCI_DEVICE *pciDevice)
4129 {
4130 PCI_DATA pciData;
4131 ushort vendorid, deviceid;
4132 uchar classcode, subclass;
4133 uchar lslot;
4134
4135 ASC_DBG(3, "asc_pci_find_dev: begin\n");
4136 pciData.type = pciDevice->type;
4137 pciData.bus = pciDevice->busNumber;
4138 pciData.func = pciDevice->devFunc;
4139 lslot = pciDevice->startSlot;
4140 for (; lslot < pciDevice->endSlot; lslot++) {
4141 pciData.slot = lslot;
4142 pciData.offset = VENDORID_OFFSET;
4143 vendorid = asc_get_cfg_word(&pciData);
4144 ASC_DBG1(3, "asc_pci_find_dev: vendorid %x\n", vendorid);
4145 if (vendorid != 0xffff) {
4146 pciData.offset = DEVICEID_OFFSET;
4147 deviceid = asc_get_cfg_word(&pciData);
4148 ASC_DBG1(3, "asc_pci_find_dev: deviceid %x\n", deviceid);
4149 if ((vendorid == ASC_PCI_VENDORID) &&
4150 ((deviceid == ASC_PCI_DEVICE_ID_REV_A) ||
4151 (deviceid == ASC_PCI_DEVICE_ID_REV_B))) {
4152 pciDevice->slotFound = lslot;
4153 ASC_DBG(3, "asc_pci_find_dev: PCI_DEVICE_FOUND\n");
4154 return PCI_DEVICE_FOUND;
4155 } else {
4156 pciData.offset = SUBCLASS_OFFSET;
4157 subclass = asc_get_cfg_byte(&pciData);
4158 pciData.offset = CLASSCODE_OFFSET;
4159 classcode = asc_get_cfg_byte(&pciData);
4160 if ((classcode & PCI_BASE_CLASS_BRIDGE_DEVICE) &&
4161 (subclass & PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER)) {
4162 pciDevice->bridge++;
4163 }
4164 ASC_DBG2(3, "asc_pci_find_dev: subclass %x, classcode %x\n",
4165 subclass, classcode);
4166 }
4167 }
4168 }
4169 return PCI_DEVICE_NOT_FOUND;
4170 }
4171
4172
4173
4174
4175 STATIC void
4176 asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE *pciConfig)
4177 {
4178 PCI_DATA pciData;
4179 uchar counter;
4180 uchar *localConfig;
4181
4182 ASC_DBG1(4, "asc_get_pci_cfg: slot found - %d\n ",
4183 pciDevice->slotFound);
4184
4185 pciData.type = pciDevice->type;
4186 pciData.bus = pciDevice->busNumber;
4187 pciData.slot = pciDevice->slotFound;
4188 pciData.func = pciDevice->devFunc;
4189 localConfig = (uchar *) pciConfig;
4190
4191 for (counter = 0; counter < sizeof(PCI_CONFIG_SPACE); counter++) {
4192 pciData.offset = counter;
4193 *localConfig = asc_get_cfg_byte(&pciData);
4194 ASC_DBG1(4, "asc_get_pci_cfg: byte %x\n", *localConfig);
4195 localConfig++;
4196 }
4197 ASC_DBG1(4, "asc_get_pci_cfg: counter %d\n", counter);
4198 }
4199
4200
4201
4202
4203
4204
4205 STATIC ushort
4206 asc_get_cfg_word(PCI_DATA *pciData)
4207 {
4208 ushort tmp;
4209 ulong address;
4210 ulong lbus = pciData->bus;
4211 ulong lslot = pciData->slot;
4212 ulong lfunc = pciData->func;
4213 uchar t2CFA, t2CF8;
4214 ushort t1CF8, t1CFA, t1CFC, t1CFE;
4215
4216 ASC_DBG4(4, "asc_get_cfg_word: type %d, bus %lu, slot %lu, func %lu\n",
4217 pciData->type, lbus, lslot, lfunc);
4218
4219
4220
4221
4222 if (pciData->type == 2) {
4223
4224
4225
4226 t2CFA = inp(0xCFA);
4227 t2CF8 = inp(0xCF8);
4228
4229
4230
4231
4232
4233 outp(0xCFA, pciData->bus);
4234
4235 outp(0xCF8, 0x10 | (pciData->func << 1)) ;
4236
4237
4238
4239
4240 tmp = (ushort) inpw(0xC000 | ((pciData->slot << 8) + pciData->offset));
4241 } else {
4242
4243
4244
4245
4246
4247 t1CFC = inpw(0xCFC);
4248 t1CFE = inpw(0xCFE);
4249 t1CF8 = inpw(0xCF8);
4250 t1CFA = inpw(0xCFA);
4251
4252
4253
4254
4255
4256 address = (ulong) ((lbus << 16) | (lslot << 11) |
4257 (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L);
4258
4259
4260
4261
4262 outl(address, 0xCF8);
4263
4264
4265
4266
4267 tmp = (ushort) ((inl(0xCFC) >>
4268 ((pciData->offset & 2) * 8)) & 0xFFFF);
4269 }
4270 ASC_DBG1(4, "asc_get_cfg_word: config data: %x\n", tmp);
4271 return tmp;
4272 }
4273
4274
4275
4276
4277
4278
4279 STATIC uchar
4280 asc_get_cfg_byte(PCI_DATA *pciData)
4281 {
4282 uchar tmp;
4283 ulong address;
4284 ulong lbus = pciData->bus, lslot = pciData->slot, lfunc = pciData->func;
4285 uchar t2CFA, t2CF8;
4286 ushort t1CF8, t1CFA, t1CFC, t1CFE;
4287
4288 ASC_DBG1(4, "asc_get_cfg_byte: type: %d\n", pciData->type);
4289
4290
4291
4292
4293 if (pciData->type == 2) {
4294
4295
4296
4297 t2CFA = inp(0xCFA);
4298 t2CF8 = inp(0xCF8);
4299
4300
4301
4302
4303
4304 outp(0xCFA, pciData->bus);
4305
4306 outp(0xCF8, 0x10 | (pciData->func << 1));
4307
4308
4309
4310
4311 tmp = inp(0xC000 | ((pciData->slot << 8) + pciData->offset));
4312
4313
4314
4315
4316 outp(0xCF8, t2CF8);
4317 outp(0xCFA, t2CFA);
4318 } else {
4319
4320
4321
4322
4323
4324 t1CFC = inpw(0xCFC);
4325 t1CFE = inpw(0xCFE);
4326 t1CF8 = inpw(0xCF8);
4327 t1CFA = inpw(0xCFA);
4328
4329
4330
4331
4332
4333 address = (ulong) ((lbus << 16) | (lslot << 11) |
4334 (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L);
4335
4336
4337
4338
4339 outl(address, 0xCF8);
4340
4341
4342
4343
4344 tmp = (uchar) ((inl(0xCFC) >> ((pciData->offset & 3) * 8)) & 0xFF);
4345 }
4346 ASC_DBG1(4, "asc_get_cfg_byte: config data: %x\n", tmp);
4347 return tmp;
4348 }
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359 STATIC void
4360 asc_enqueue(struct Scsi_Host *shp, Scsi_Cmnd *scp, int tid, int flag)
4361 {
4362 Scsi_Cmnd **scpp;
4363
4364 ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
4365 ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
4366 ASC_STATS(enqueue);
4367 if (flag == ASC_FRONT) {
4368 scp->host_scribble = (unsigned char *) ASC_BOARD(shp)->pending[tid];
4369 ASC_BOARD(shp)->pending[tid] = (Scsi_Cmnd *) scp;
4370 } else {
4371 for (scpp = &ASC_BOARD(shp)->pending[tid]; *scpp;
4372 scpp = (Scsi_Cmnd **) &(*scpp)->host_scribble) {
4373 ;
4374 }
4375 *scpp = scp;
4376 scp->host_scribble = NULL;
4377 }
4378 ASC_BOARD(shp)->pending_tidmask |= ASC_TIX_TO_TARGET_ID(tid);
4379 }
4380
4381
4382
4383
4384
4385
4386
4387
4388 STATIC Scsi_Cmnd *
4389 asc_dequeue(struct Scsi_Host *shp, int tid)
4390 {
4391 Scsi_Cmnd *scp;
4392
4393 ASC_STATS(dequeue);
4394 ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
4395 if ((scp = ASC_BOARD(shp)->pending[tid]) != NULL) {
4396 ASC_BOARD(shp)->pending[tid] = (Scsi_Cmnd *) scp->host_scribble;
4397 }
4398 if (ASC_BOARD(shp)->pending[tid] == NULL) {
4399 ASC_BOARD(shp)->pending_tidmask &= ~ASC_TIX_TO_TARGET_ID(tid);
4400 }
4401 return scp;
4402 }
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414 STATIC int
4415 asc_rmqueue(struct Scsi_Host *shp, Scsi_Cmnd *scp, int tid)
4416 {
4417 Scsi_Cmnd **scpp;
4418 int ret;
4419
4420 ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
4421 ret = ASC_FALSE;
4422 for (scpp = &ASC_BOARD(shp)->pending[tid];
4423 *scpp; scpp = (Scsi_Cmnd **) &(*scpp)->host_scribble) {
4424 if (*scpp == scp) {
4425 *scpp = (Scsi_Cmnd *) scp->host_scribble;
4426 scp->host_scribble = NULL;
4427 ASC_STATS(rmqueue);
4428 ret = ASC_TRUE;
4429 }
4430 }
4431 if (ASC_BOARD(shp)->pending[tid] == NULL) {
4432 ASC_BOARD(shp)->pending_tidmask &= ~ASC_TIX_TO_TARGET_ID(tid);
4433 }
4434 return ret;
4435 }
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448 void
4449 DvcSleepMilliSecond(ulong n)
4450 {
4451 ulong i;
4452
4453 ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", n);
4454 for (i = 0; i < n; i++) {
4455 udelay(1000);
4456 }
4457 }
4458
4459 void
4460 DvcDisplayString(uchar *s)
4461 {
4462 printk(s);
4463 }
4464
4465 int
4466 DvcEnterCritical(void)
4467 {
4468 int flags;
4469
4470 save_flags(flags);
4471 cli();
4472 return flags;
4473 }
4474
4475 void
4476 DvcLeaveCritical(int flags)
4477 {
4478 restore_flags(flags);
4479 }
4480
4481
4482
4483
4484
4485
4486
4487 ulong
4488 DvcGetPhyAddr(uchar *buf_addr, ulong buf_len)
4489 {
4490 ulong phys_addr;
4491
4492 phys_addr = (ulong) buf_addr;
4493 return phys_addr;
4494 }
4495
4496 ulong
4497 DvcGetSGList(ASC_DVC_VAR *asc_dvc_sg, uchar *buf_addr, ulong buf_len,
4498 ASC_SG_HEAD *asc_sg_head_ptr)
4499 {
4500 ulong buf_size;
4501
4502 buf_size = buf_len;
4503 asc_sg_head_ptr->entry_cnt = 1;
4504 asc_sg_head_ptr->sg_list[0].addr = (ulong) buf_addr;
4505 asc_sg_head_ptr->sg_list[0].bytes = buf_size;
4506 return buf_size;
4507 }
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519 void
4520 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, ushort *outbuf, int words)
4521 {
4522 int i;
4523
4524 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", (uchar *) outbuf, 2 * words);
4525 AscSetChipLramAddr(iop_base, s_addr);
4526 for (i = 0; i < words; i++, outbuf++) {
4527 if (i == 2 || i == 10) {
4528 continue;
4529 }
4530 AscPutChipLramData(iop_base, *outbuf);
4531 }
4532 }
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544 void
4545 DvcGetQinfo(PortAddr iop_base, ushort s_addr, ushort *inbuf, int words)
4546 {
4547 int i;
4548
4549 AscSetChipLramAddr(iop_base, s_addr);
4550 for (i = 0; i < words; i++, inbuf++) {
4551 if (i == 5) {
4552 continue;
4553 }
4554 *inbuf = AscGetChipLramData(iop_base);
4555 }
4556 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", (uchar *) inbuf, 2 * words);
4557 }
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568 void
4569 DvcOutPortWords(ushort iop_base, ushort *outbuf, int words)
4570 {
4571 int i;
4572
4573 for (i = 0; i < words; i++, outbuf++)
4574 outpw(iop_base, *outbuf);
4575 }
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586 void
4587 DvcInPortWords(ushort iop_base, ushort *inbuf, int words)
4588 {
4589 int i;
4590
4591 for (i = 0; i < words; i++, inbuf++)
4592 *inbuf = inpw(iop_base);
4593 }
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606 void
4607 DvcOutPortDWords(PortAddr port, ulong *pdw, int dwords)
4608 {
4609 int i;
4610 int words;
4611 ushort *pw;
4612
4613 pw = (ushort *) pdw;
4614 words = dwords << 1;
4615 for(i = 0; i < words; i++, pw++) {
4616 outpw(port, *pw);
4617 }
4618 return;
4619 }
4620
4621
4622
4623
4624
4625
4626 #ifdef ADVANSYS_STATS
4627
4628 #define ASC_PRT_STATS_NEXT() \
4629 if (cp) { \
4630 totlen += len; \
4631 leftlen -= len; \
4632 if (leftlen == 0) { \
4633 return totlen; \
4634 } \
4635 cp += len; \
4636 }
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647 STATIC int
4648 asc_prt_stats(char *cp, int cplen)
4649 {
4650 struct asc_stats *s;
4651 int leftlen;
4652 int totlen;
4653 int len;
4654
4655 s = &asc_stats;
4656 leftlen = cplen;
4657 totlen = len = 0;
4658
4659 len = asc_prt_stats_line(cp, leftlen,
4660 "\nAdvanSys SCSI Host Driver Statistics:\n");
4661 ASC_PRT_STATS_NEXT();
4662
4663 len = asc_prt_stats_line(cp, leftlen,
4664 " command %lu, queuecommand %lu, abort %lu, reset %lu, biosparam %lu,\n",
4665 s->command, s->queuecommand, s->abort, s->reset, s->biosparam);
4666 ASC_PRT_STATS_NEXT();
4667
4668 len = asc_prt_stats_line(cp, leftlen,
4669 " interrupt %lu, callback %lu, cmd_disable %lu, intr_disable %lu,\n",
4670 s->interrupt, s->callback, s->cmd_disable, s->intr_disable);
4671 ASC_PRT_STATS_NEXT();
4672
4673 len = asc_prt_stats_line(cp, leftlen,
4674 " error %lu, enqueue %lu, dequeue %lu, rmqueue %lu,\n",
4675 s->error, s->enqueue, s->dequeue, s->rmqueue);
4676 ASC_PRT_STATS_NEXT();
4677
4678 if (s->cont_cnt > 0) {
4679 len = asc_prt_stats_line(cp, leftlen,
4680 " cont_cnt %lu, cont_xfer %lu: avg_xfer=%lu kb\n",
4681 s->cont_cnt, s->cont_xfer, (s->cont_xfer/2)/s->cont_cnt);
4682 ASC_PRT_STATS_NEXT();
4683 }
4684
4685 if (s->sg_cnt > 0) {
4686 len = asc_prt_stats_line(cp, leftlen,
4687 " sg_cnt %lu, sg_elem %lu, sg_xfer %lu: avg_elem=%lu, avg_size=%lu kb\n",
4688 s->sg_cnt, s->sg_elem, s->sg_xfer,
4689 s->sg_elem/s->sg_cnt, (s->sg_xfer/2)/s->sg_cnt);
4690 ASC_PRT_STATS_NEXT();
4691 }
4692
4693 return totlen;
4694 }
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707 int
4708 asc_prt_stats_line(char *buf, int buflen, char *fmt, ...)
4709 {
4710 va_list args;
4711 int ret;
4712 char s[160];
4713
4714 va_start(args, fmt);
4715 ret = vsprintf(s, fmt, args);
4716 if (buf == NULL) {
4717 (void) printk(s);
4718 ret = 0;
4719 } else {
4720 ret = min(buflen, ret);
4721 memcpy(buf, s, ret);
4722 }
4723 va_end(args);
4724 return ret;
4725 }
4726 #endif
4727
4728 #ifdef ADVANSYS_DEBUG
4729
4730
4731
4732 STATIC void
4733 asc_prt_scsi_host(struct Scsi_Host *s)
4734 {
4735 printk("Scsi_Host at addr %x\n", (unsigned) s);
4736 printk(
4737 " next %x, extra_bytes %u, host_busy %u, host_no %d, last_reset %d,\n",
4738 (unsigned) s->next, s->extra_bytes, s->host_busy, s->host_no,
4739 s->last_reset);
4740
4741 printk(
4742 " host_wait %x, host_queue %x, hostt %x, block %x,\n",
4743 (unsigned) s->host_wait, (unsigned) s->host_queue,
4744 (unsigned) s->hostt, (unsigned) s->block);
4745
4746 printk(
4747 " wish_block %d, base %x, io_port %d, n_io_port %d, irq %d, dma_channel %d,\n",
4748 s->wish_block, (unsigned) s->base, s->io_port, s->n_io_port,
4749 s->irq, s->dma_channel);
4750
4751 printk(
4752 " this_id %d, can_queue %d,\n", s->this_id, s->can_queue);
4753
4754 printk(
4755 " cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d, loaded_as_module %d\n",
4756 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma,
4757 s->loaded_as_module);
4758
4759 printk("hostdata (struct asc_board)\n");
4760 asc_prt_dvc_var(&ASC_BOARD(s)->board);
4761 asc_prt_dvc_cfg(&ASC_BOARD(s)->cfg);
4762 printk(" overrun_buf %x\n", (unsigned) &ASC_BOARD(s)->overrun_buf[0]);
4763 }
4764
4765
4766
4767
4768 STATIC void
4769 asc_prt_dvc_var(ASC_DVC_VAR *h)
4770 {
4771 printk("ASC_DVC_VAR at addr %x\n", (unsigned) h);
4772
4773 printk(
4774 " iop_base %x, err_code %x, dvc_cntl %x, bug_fix_cntl %d,\n",
4775 h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
4776
4777 printk(
4778 " bus_type %d, isr_callback %x, exe_callback %x, init_sdtr %x,\n",
4779 h->bus_type, (unsigned) h->isr_callback, (unsigned) h->exe_callback,
4780 (unsigned) h->init_sdtr);
4781
4782 printk(
4783 " sdtr_done %x, use_tagged_qng %x, unit_not_ready %x, chip_no %x,\n",
4784 (unsigned) h->sdtr_done, (unsigned) h->use_tagged_qng,
4785 (unsigned) h->unit_not_ready, (unsigned) h->chip_no);
4786
4787 printk(
4788 " queue_full_or_busy %x, start_motor %x, scsi_reset_wait %x, irq_no %x,\n",
4789 (unsigned) h->queue_full_or_busy, (unsigned) h->start_motor,
4790 (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
4791
4792 printk(
4793 " is_in_int %x, max_total_qng %x, cur_total_qng %x, in_critical_cnt %x,\n",
4794 (unsigned) h->is_in_int, (unsigned) h->max_total_qng,
4795 (unsigned) h->cur_total_qng, (unsigned) h->in_critical_cnt);
4796
4797 printk(
4798 " last_q_shortage %x, init_state %x, no_scam %x, pci_fix_asyn_xfer %x,\n",
4799 (unsigned) h->last_q_shortage, (unsigned) h->init_state,
4800 (unsigned) h->no_scam, (unsigned) h->pci_fix_asyn_xfer);
4801
4802 printk(
4803 " int_count %ld, req_count %ld, busy_count %ld, cfg %x, saved_ptr2func %x\n",
4804 h->int_count, h->req_count, h->busy_count, (unsigned) h->cfg,
4805 (unsigned) h->saved_ptr2func);
4806 }
4807
4808
4809
4810
4811 STATIC void
4812 asc_prt_dvc_cfg(ASC_DVC_CFG *h)
4813 {
4814 printk("ASC_DVC_CFG at addr %x\n", (unsigned) h);
4815
4816 printk(
4817 " can_tagged_qng %x, cmd_qng_enabled %x, disc_enable %x, res %x,\n",
4818 h->can_tagged_qng, h->cmd_qng_enabled, h->disc_enable, h->res);
4819
4820 printk(
4821 " chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
4822 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
4823 h->chip_version);
4824
4825 printk(
4826 " pci_device_id %d, lib_serial_no %d, lib_version %d, mcode_date %d,\n",
4827 h->pci_device_id, h->lib_serial_no, h->lib_version, h->mcode_date);
4828
4829 printk(
4830 " mcode_version %d, overrun_buf %x\n",
4831 h->mcode_version, (unsigned) h->overrun_buf);
4832 }
4833
4834
4835
4836
4837 STATIC void
4838 asc_prt_scsi_q(ASC_SCSI_Q *q)
4839 {
4840 ASC_SG_HEAD *sgp;
4841 int i;
4842
4843 printk("ASC_SCSI_Q at addr %x\n", (unsigned) q);
4844
4845 printk(
4846 " target_ix %u, target_lun %u, srb_ptr %x, tag_code %u,\n",
4847 q->q2.target_ix, q->q1.target_lun,
4848 (unsigned) q->q2.srb_ptr, q->q2.tag_code);
4849
4850 printk(
4851 " data_addr %x, data_cnt %lu, sense_addr %x, sense_len %u,\n",
4852 (unsigned) q->q1.data_addr, q->q1.data_cnt,
4853 (unsigned) q->q1.sense_addr, q->q1.sense_len);
4854
4855 printk(
4856 " cdbptr %x, cdb_len %u, sg_head %x, sg_queue_cnt %u\n",
4857 (unsigned) q->cdbptr, q->q2.cdb_len,
4858 (unsigned) q->sg_head, q->q1.sg_queue_cnt);
4859
4860 if (q->sg_head) {
4861 sgp = q->sg_head;
4862 printk("ASC_SG_HEAD at addr %x\n", (unsigned) sgp);
4863 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, sgp->queue_cnt);
4864 for (i = 0; i < sgp->entry_cnt; i++) {
4865 printk(" [%u]: addr %x, bytes %lu\n",
4866 i, (unsigned) sgp->sg_list[i].addr, sgp->sg_list[i].bytes);
4867 }
4868
4869 }
4870 }
4871
4872
4873
4874
4875 STATIC void
4876 asc_prt_qdone_info(ASC_QDONE_INFO *q)
4877 {
4878 printk("ASC_QDONE_INFO at addr %x\n", (unsigned) q);
4879 printk(
4880 " srb_ptr %x, target_ix %u, cdb_len %u, tag_code %u, done_stat %x\n",
4881 (unsigned) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
4882 q->d2.tag_code, q->d3.done_stat);
4883 printk(
4884 " host_stat %x, scsi_stat %x, scsi_msg %x\n",
4885 q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
4886 }
4887
4888
4889
4890
4891
4892
4893
4894 STATIC void
4895 asc_prt_hex(char *f, uchar *s, int l)
4896 {
4897 int i;
4898 int j;
4899 int k;
4900 int m;
4901
4902 printk("%s: (%d bytes)\n", f, l);
4903
4904 for (i = 0; i < l; i += 32) {
4905
4906
4907 if ((k = (l - i) / 4) >= 8) {
4908 k = 8;
4909 m = 0;
4910 } else {
4911 m = (l - i) % 4 ;
4912 }
4913
4914 for (j = 0; j < k; j++) {
4915 printk(" %2.2X%2.2X%2.2X%2.2X",
4916 (unsigned) s[i+(j*4)], (unsigned) s[i+(j*4)+1],
4917 (unsigned) s[i+(j*4)+2], (unsigned) s[i+(j*4)+3]);
4918 }
4919
4920 switch (m) {
4921 case 0:
4922 default:
4923 break;
4924 case 1:
4925 printk(" %2.2X",
4926 (unsigned) s[i+(j*4)+4]);
4927 break;
4928 case 2:
4929 printk(" %2.2X%2.2X",
4930 (unsigned) s[i+(j*4)+4],
4931 (unsigned) s[i+(j*4)+5]);
4932 break;
4933 case 3:
4934 printk(" %2.2X%2.2X%2.2X",
4935 (unsigned) s[i+(j*4)+4],
4936 (unsigned) s[i+(j*4)+5],
4937 (unsigned) s[i+(j*4)+6]);
4938 break;
4939 }
4940
4941 printk("\n");
4942 }
4943 }
4944
4945
4946
4947
4948
4949
4950 STATIC int
4951 interrupts_enabled(void)
4952 {
4953 int flags;
4954
4955 save_flags(flags);
4956 if (flags & 0x0200) {
4957 return ASC_TRUE;
4958 } else {
4959 return ASC_FALSE;
4960 }
4961 }
4962
4963 #endif
4964
4965
4966
4967
4968
4969
4970 ushort
4971 AscGetEisaChipCfg(
4972 PortAddr iop_base
4973 )
4974 {
4975 PortAddr eisa_cfg_iop;
4976
4977 eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
4978 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
4979 return (inpw(eisa_cfg_iop));
4980 }
4981
4982 uchar
4983 AscSetChipScsiID(
4984 PortAddr iop_base,
4985 uchar new_host_id
4986 )
4987 {
4988 ushort cfg_lsw;
4989
4990 if (AscGetChipScsiID(iop_base) == new_host_id) {
4991 return (new_host_id);
4992 }
4993 cfg_lsw = AscGetChipCfgLsw(iop_base);
4994 cfg_lsw &= 0xF8FF;
4995 cfg_lsw |= (ushort) ((new_host_id & ASC_MAX_TID) << 8);
4996 AscSetChipCfgLsw(iop_base, cfg_lsw);
4997 return (AscGetChipScsiID(iop_base));
4998 }
4999
5000 ushort
5001 AscGetChipBiosAddress(
5002 PortAddr iop_base,
5003 ushort bus_type
5004 )
5005 {
5006 ushort cfg_lsw;
5007 ushort bios_addr;
5008
5009 if ((bus_type & ASC_IS_EISA) != 0) {
5010 cfg_lsw = AscGetEisaChipCfg(iop_base);
5011 cfg_lsw &= 0x000F;
5012 bios_addr = (ushort) (ASC_BIOS_MIN_ADDR +
5013 (cfg_lsw * ASC_BIOS_BANK_SIZE));
5014 return (bios_addr);
5015 }
5016 cfg_lsw = AscGetChipCfgLsw(iop_base);
5017 bios_addr = (ushort) (((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) + ASC_BIOS_MIN_ADDR);
5018 return (bios_addr);
5019 }
5020
5021 uchar
5022 AscGetChipVersion(
5023 PortAddr iop_base,
5024 ushort bus_type
5025 )
5026 {
5027 if ((bus_type & ASC_IS_EISA) != 0) {
5028
5029 PortAddr eisa_iop;
5030 uchar revision;
5031
5032 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
5033 (PortAddr) ASC_EISA_REV_IOP_MASK;
5034 revision = inp(eisa_iop);
5035 return ((uchar) ((ASC_CHIP_MIN_VER_EISA - 1) + revision));
5036 }
5037 return (AscGetChipVerNo(iop_base));
5038 }
5039
5040 ushort
5041 AscGetChipBusType(
5042 PortAddr iop_base
5043 )
5044 {
5045 ushort chip_ver;
5046
5047 chip_ver = AscGetChipVerNo(iop_base);
5048 if ((chip_ver >= ASC_CHIP_MIN_VER_VL) &&
5049 (chip_ver <= ASC_CHIP_MAX_VER_VL)) {
5050 if (((iop_base & 0x0C30) == 0x0C30) ||
5051 ((iop_base & 0x0C50) == 0x0C50)) {
5052 return (ASC_IS_EISA);
5053 }
5054 return (ASC_IS_VL);
5055 } else if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
5056 (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
5057 if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
5058 return (ASC_IS_ISAPNP);
5059 }
5060 return (ASC_IS_ISA);
5061 } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
5062 (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
5063 return (ASC_IS_PCI);
5064 } else {
5065 return (0);
5066 }
5067 }
5068
5069 void
5070 AscEnableIsaDma(
5071 uchar dma_channel
5072 )
5073 {
5074 if (dma_channel < 4) {
5075 outp(0x000B, (ushort) (0xC0 | dma_channel));
5076 outp(0x000A, dma_channel);
5077 } else if (dma_channel < 8) {
5078
5079 outp(0x00D6, (ushort) (0xC0 | (dma_channel - 4)));
5080 outp(0x00D4, (ushort) (dma_channel - 4));
5081 }
5082 return;
5083 }
5084
5085 ulong
5086 AscLoadMicroCode(
5087 PortAddr iop_base,
5088 ushort s_addr,
5089 ushort dosfar * mcode_buf,
5090 ushort mcode_size
5091 )
5092 {
5093 ulong chksum;
5094 ushort mcode_word_size;
5095 ushort mcode_chksum;
5096
5097 mcode_word_size = (ushort) (mcode_size >> 1);
5098 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
5099 AscMemWordCopyToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
5100
5101 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
5102 mcode_chksum = (ushort) AscMemSumLramWord(iop_base,
5103 (ushort) ASC_CODE_SEC_BEG,
5104 (ushort) ((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG) / 2));
5105 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
5106 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
5107 return (chksum);
5108 }
5109
5110 uchar _hextbl_[16] =
5111 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
5112 'A', 'B', 'C', 'D', 'E', 'F'};
5113
5114 uchar _isa_pnp_inited = 0;
5115
5116 PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] =
5117 {
5118 0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
5119 ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
5120 };
5121
5122 PortAddr
5123 AscSearchIOPortAddr(
5124 PortAddr iop_beg,
5125 ushort bus_type
5126 )
5127 {
5128 if (bus_type & ASC_IS_VL) {
5129 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
5130 if (AscGetChipVersion(iop_beg, bus_type) <= ASC_CHIP_MAX_VER_VL) {
5131 return (iop_beg);
5132 }
5133 }
5134 return (0);
5135 }
5136 if (bus_type & ASC_IS_ISA) {
5137 if (_isa_pnp_inited == 0) {
5138 AscSetISAPNPWaitForKey();
5139 _isa_pnp_inited++;
5140 }
5141 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
5142 if ((AscGetChipVersion(iop_beg, bus_type) & ASC_CHIP_VER_ISA_BIT) != 0) {
5143 return (iop_beg);
5144 }
5145 }
5146 return (0);
5147 }
5148 if (bus_type & ASC_IS_EISA) {
5149 if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
5150 return (iop_beg);
5151 }
5152 return (0);
5153 }
5154 return (0);
5155 }
5156
5157 PortAddr
5158 AscSearchIOPortAddr11(
5159 PortAddr s_addr
5160 )
5161 {
5162
5163 int i;
5164 PortAddr iop_base;
5165
5166 for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
5167 if (_asc_def_iop_base[i] > s_addr) {
5168 break;
5169 }
5170 }
5171 for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
5172 iop_base = _asc_def_iop_base[i];
5173 if (AscFindSignature(iop_base)) {
5174 return (iop_base);
5175 }
5176 }
5177 return (0);
5178 }
5179
5180 int
5181 AscFindSignature(
5182 PortAddr iop_base
5183 )
5184 {
5185 ushort sig_word;
5186
5187 if ((inp((PortAddr) (iop_base + 1)) & 0xFF) == (uchar) ASC_1000_ID1B) {
5188 sig_word = inpw(iop_base);
5189 if ((sig_word == (ushort) ASC_1000_ID0W) ||
5190 (sig_word == (ushort) ASC_1000_ID0W_FIX)) {
5191 return (1);
5192 }
5193 }
5194 return (0);
5195 }
5196
5197 void
5198 AscToggleIRQAct(
5199 PortAddr iop_base
5200 )
5201 {
5202 AscSetChipStatus(iop_base, CIW_IRQ_ACT);
5203 AscSetChipStatus(iop_base, 0);
5204 return;
5205 }
5206
5207 #if CC_INIT_INQ_DISPLAY
5208
5209 #endif
5210
5211 void
5212 AscSetISAPNPWaitForKey(
5213 void)
5214 {
5215
5216 outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
5217 outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
5218 return;
5219 }
5220
5221 uchar
5222 AscGetChipIRQ(
5223 PortAddr iop_base,
5224 ushort bus_type
5225 )
5226 {
5227 ushort cfg_lsw;
5228 uchar chip_irq;
5229
5230 if ((bus_type & ASC_IS_EISA) != 0) {
5231
5232 cfg_lsw = AscGetEisaChipCfg(iop_base);
5233 chip_irq = (uchar) (((cfg_lsw >> 8) & 0x07) + 10);
5234 if ((chip_irq == 13) || (chip_irq > 15)) {
5235
5236 return (0);
5237 }
5238 return (chip_irq);
5239 } else {
5240
5241 cfg_lsw = AscGetChipCfgLsw(iop_base);
5242
5243 if ((bus_type & ASC_IS_VL) != 0) {
5244
5245 chip_irq = (uchar) (((cfg_lsw >> 2) & 0x07));
5246 if ((chip_irq == 0) ||
5247 (chip_irq == 4) ||
5248 (chip_irq == 7)) {
5249 return (0);
5250 }
5251 return ((uchar) (chip_irq + (ASC_MIN_IRQ_NO - 1)));
5252 }
5253 chip_irq = (uchar) (((cfg_lsw >> 2) & 0x03));
5254 if (chip_irq == 3)
5255 chip_irq += (uchar) 2;
5256 return ((uchar) (chip_irq + ASC_MIN_IRQ_NO));
5257 }
5258 }
5259
5260 uchar
5261 AscSetChipIRQ(
5262 PortAddr iop_base,
5263 uchar irq_no,
5264 ushort bus_type
5265 )
5266 {
5267 ushort cfg_lsw;
5268
5269 if ((bus_type & ASC_IS_VL) != 0) {
5270
5271 if (irq_no != 0) {
5272 if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO)) {
5273 irq_no = 0;
5274 } else {
5275 irq_no -= (uchar) ((ASC_MIN_IRQ_NO - 1));
5276 }
5277 }
5278 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE3);
5279 cfg_lsw |= (ushort) 0x0010;
5280 AscSetChipCfgLsw(iop_base, cfg_lsw);
5281 AscToggleIRQAct(iop_base);
5282
5283 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE0);
5284 cfg_lsw |= (ushort) ((irq_no & 0x07) << 2);
5285 AscSetChipCfgLsw(iop_base, cfg_lsw);
5286 AscToggleIRQAct(iop_base);
5287
5288 return (AscGetChipIRQ(iop_base, bus_type));
5289
5290 } else if ((bus_type & (ASC_IS_ISA)) != 0) {
5291
5292 if (irq_no == 15)
5293 irq_no -= (uchar) 2;
5294 irq_no -= (uchar) ASC_MIN_IRQ_NO;
5295 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFF3);
5296 cfg_lsw |= (ushort) ((irq_no & 0x03) << 2);
5297 AscSetChipCfgLsw(iop_base, cfg_lsw);
5298 return (AscGetChipIRQ(iop_base, bus_type));
5299 } else {
5300
5301 return (0);
5302 }
5303 }
5304
5305 uchar
5306 AscGetChipScsiCtrl(
5307 PortAddr iop_base
5308 )
5309 {
5310 uchar sc;
5311
5312 AscSetBank(iop_base, 1);
5313 sc = inp(iop_base + IOP_REG_SC);
5314 AscSetBank(iop_base, 0);
5315 return (sc);
5316 }
5317
5318 extern uchar _sdtr_period_tbl_[];
5319
5320 int
5321 AscIsrChipHalted(
5322 ASC_DVC_VAR asc_ptr_type * asc_dvc
5323 )
5324 {
5325 SDTR_XMSG sdtr_xmsg;
5326 SDTR_XMSG out_msg;
5327 ushort halt_q_addr;
5328 int sdtr_accept;
5329 ushort int_halt_code;
5330 ASC_SCSI_BIT_ID_TYPE scsi_busy;
5331 ASC_SCSI_BIT_ID_TYPE target_id;
5332 PortAddr iop_base;
5333 uchar tag_code;
5334 uchar q_status;
5335 uchar halt_qp;
5336 uchar sdtr_data;
5337 uchar target_ix;
5338 uchar q_cntl, tid_no;
5339 uchar cur_dvc_qng;
5340 uchar asyn_sdtr;
5341 uchar scsi_status;
5342
5343 iop_base = asc_dvc->iop_base;
5344 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
5345
5346 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
5347 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
5348 target_ix = AscReadLramByte(iop_base,
5349 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TARGET_IX));
5350 q_cntl = AscReadLramByte(iop_base,
5351 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL));
5352 tid_no = ASC_TIX_TO_TID(target_ix);
5353 target_id = (uchar) ASC_TID_TO_TARGET_ID(tid_no);
5354 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
5355
5356 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
5357 } else {
5358 asyn_sdtr = 0;
5359 }
5360 if (int_halt_code == ASC_HALT_EXTMSG_IN) {
5361
5362 AscMemWordCopyFromLram(iop_base,
5363 ASCV_MSGIN_BEG,
5364 (ushort dosfar *) & sdtr_xmsg,
5365 (ushort) (sizeof (SDTR_XMSG) >> 1));
5366 if ((sdtr_xmsg.msg_type == MS_EXTEND) &&
5367 (sdtr_xmsg.msg_len == MS_SDTR_LEN)) {
5368 sdtr_accept = TRUE;
5369 if (sdtr_xmsg.msg_req == MS_SDTR_CODE) {
5370 if (sdtr_xmsg.req_ack_offset > ASC_SYN_MAX_OFFSET) {
5371
5372 sdtr_accept = FALSE;
5373 sdtr_xmsg.req_ack_offset = ASC_SYN_MAX_OFFSET;
5374 }
5375 sdtr_data = AscCalSDTRData(sdtr_xmsg.xfer_period,
5376 sdtr_xmsg.req_ack_offset);
5377 if (sdtr_xmsg.req_ack_offset == 0) {
5378
5379 q_cntl &= ~QC_MSG_OUT;
5380 asc_dvc->init_sdtr &= ~target_id;
5381 asc_dvc->sdtr_done &= ~target_id;
5382 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
5383 } else if ((sdtr_data == 0xFF)) {
5384
5385 q_cntl |= QC_MSG_OUT;
5386 asc_dvc->init_sdtr &= ~target_id;
5387 asc_dvc->sdtr_done &= ~target_id;
5388 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
5389 } else {
5390 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
5391
5392 q_cntl &= ~QC_MSG_OUT;
5393 asc_dvc->sdtr_done |= target_id;
5394 asc_dvc->init_sdtr |= target_id;
5395 asc_dvc->pci_fix_asyn_xfer &= ~target_id;
5396 AscSetChipSDTR(iop_base, sdtr_data, tid_no);
5397 } else {
5398
5399 q_cntl |= QC_MSG_OUT;
5400
5401 AscMsgOutSDTR(iop_base,
5402 sdtr_xmsg.xfer_period,
5403 sdtr_xmsg.req_ack_offset);
5404 asc_dvc->pci_fix_asyn_xfer &= ~target_id;
5405 AscSetChipSDTR(iop_base, sdtr_data, tid_no);
5406 asc_dvc->sdtr_done |= target_id;
5407 asc_dvc->init_sdtr |= target_id;
5408 }
5409 }
5410
5411 AscWriteLramByte(iop_base,
5412 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
5413 q_cntl);
5414 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
5415 return (0);
5416 }
5417 }
5418 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
5419
5420 q_cntl |= QC_REQ_SENSE;
5421 if (((asc_dvc->init_sdtr & target_id) != 0) &&
5422 ((asc_dvc->sdtr_done & target_id) != 0)) {
5423
5424 sdtr_data = AscReadLramByte(iop_base,
5425 (ushort) ((ushort) ASCV_SDTR_DATA_BEG + (ushort) tid_no));
5426 AscMsgOutSDTR(iop_base,
5427 _sdtr_period_tbl_[(sdtr_data >> 4) & (uchar) (ASC_SYN_XFER_NO - 1)],
5428 (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
5429 q_cntl |= QC_MSG_OUT;
5430 }
5431 AscWriteLramByte(iop_base,
5432 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
5433 q_cntl);
5434
5435 tag_code = AscReadLramByte(iop_base,
5436 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE));
5437 tag_code &= 0xDC;
5438 AscWriteLramByte(iop_base,
5439 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE),
5440 tag_code);
5441
5442 q_status = AscReadLramByte(iop_base,
5443 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS));
5444 q_status |= (QS_READY | QS_BUSY);
5445 AscWriteLramByte(iop_base,
5446 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
5447 q_status);
5448
5449 scsi_busy = AscReadLramByte(iop_base,
5450 (ushort) ASCV_SCSIBUSY_B);
5451 scsi_busy &= ~target_id;
5452 AscWriteLramByte(iop_base, (ushort) ASCV_SCSIBUSY_B, scsi_busy);
5453
5454 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
5455 return (0);
5456 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
5457
5458 AscMemWordCopyFromLram(iop_base,
5459 ASCV_MSGOUT_BEG,
5460 (ushort dosfar *) & out_msg,
5461 (ushort) (sizeof (SDTR_XMSG) >> 1));
5462
5463 if ((out_msg.msg_type == MS_EXTEND) &&
5464 (out_msg.msg_len == MS_SDTR_LEN) &&
5465 (out_msg.msg_req == MS_SDTR_CODE)) {
5466
5467 asc_dvc->init_sdtr &= ~target_id;
5468 asc_dvc->sdtr_done &= ~target_id;
5469 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
5470
5471 } else {
5472
5473 }
5474
5475 q_cntl &= ~QC_MSG_OUT;
5476 AscWriteLramByte(iop_base,
5477 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
5478 q_cntl);
5479 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
5480 return (0);
5481 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
5482
5483 scsi_status = AscReadLramByte(iop_base,
5484 (ushort) ((ushort) halt_q_addr + (ushort) ASC_SCSIQ_SCSI_STATUS));
5485 cur_dvc_qng = AscReadLramByte(iop_base,
5486 (ushort) ((ushort) ASC_QADR_BEG + (ushort) target_ix));
5487 if ((cur_dvc_qng > 0) &&
5488 (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
5489
5490 scsi_busy = AscReadLramByte(iop_base,
5491 (ushort) ASCV_SCSIBUSY_B);
5492 scsi_busy |= target_id;
5493 AscWriteLramByte(iop_base,
5494 (ushort) ASCV_SCSIBUSY_B, scsi_busy);
5495 asc_dvc->queue_full_or_busy |= target_id;
5496
5497 if (scsi_status == SS_QUEUE_FULL) {
5498 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
5499 cur_dvc_qng -= 1;
5500 asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng;
5501
5502 AscWriteLramByte(iop_base,
5503 (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG + (ushort) tid_no),
5504 cur_dvc_qng);
5505 }
5506 }
5507 }
5508 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
5509 return (0);
5510 }
5511 return (0);
5512 }
5513
5514 uchar
5515 _AscCopyLramScsiDoneQ(
5516 PortAddr iop_base,
5517 ushort q_addr,
5518 ASC_QDONE_INFO dosfar * scsiq,
5519 ulong max_dma_count
5520 )
5521 {
5522 ushort _val;
5523 uchar sg_queue_cnt;
5524
5525 DvcGetQinfo(iop_base,
5526 (ushort) (q_addr + (ushort) ASC_SCSIQ_DONE_INFO_BEG),
5527 (ushort dosfar *) scsiq,
5528 (ushort) ((sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2));
5529
5530 #if !CC_LITTLE_ENDIAN_HOST
5531 AscAdjEndianQDoneInfo(scsiq);
5532 #endif
5533
5534 _val = AscReadLramWord(iop_base,
5535 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS));
5536 scsiq->q_status = (uchar) _val;
5537 scsiq->q_no = (uchar) (_val >> 8);
5538
5539 _val = AscReadLramWord(iop_base,
5540 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_CNTL));
5541 scsiq->cntl = (uchar) _val;
5542 sg_queue_cnt = (uchar) (_val >> 8);
5543
5544 _val = AscReadLramWord(iop_base,
5545 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SENSE_LEN));
5546 scsiq->sense_len = (uchar) _val;
5547 scsiq->user_def = (uchar) (_val >> 8);
5548
5549 scsiq->remain_bytes = AscReadLramDWord(iop_base,
5550 (ushort) (q_addr + (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT));
5551 scsiq->remain_bytes &= max_dma_count;
5552
5553 return (sg_queue_cnt);
5554 }
5555
5556 int
5557 AscIsrQDone(
5558 ASC_DVC_VAR asc_ptr_type * asc_dvc
5559 )
5560 {
5561 uchar next_qp;
5562 uchar i;
5563 uchar n_q_used;
5564 uchar sg_list_qp;
5565 uchar sg_queue_cnt;
5566 uchar done_q_tail;
5567
5568 uchar tid_no;
5569 ASC_SCSI_BIT_ID_TYPE scsi_busy;
5570 ASC_SCSI_BIT_ID_TYPE target_id;
5571 PortAddr iop_base;
5572 ushort q_addr;
5573 ushort sg_q_addr;
5574 uchar cur_target_qng;
5575 ASC_QDONE_INFO scsiq_buf;
5576 ASC_QDONE_INFO dosfar *scsiq;
5577 int false_overrun;
5578 ASC_ISR_CALLBACK asc_isr_callback;
5579
5580 uchar tag_code;
5581
5582 #if CC_LINK_BUSY_Q
5583 ushort n_busy_q_done;
5584
5585 #endif
5586
5587 iop_base = asc_dvc->iop_base;
5588 asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
5589
5590 n_q_used = 1;
5591 scsiq = (ASC_QDONE_INFO dosfar *) & scsiq_buf;
5592 done_q_tail = (uchar) AscGetVarDoneQTail(iop_base);
5593 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
5594 next_qp = AscReadLramByte(iop_base,
5595 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_FWD));
5596 if (next_qp != ASC_QLINK_END) {
5597
5598 AscPutVarDoneQTail(iop_base, next_qp);
5599 q_addr = ASC_QNO_TO_QADDR(next_qp);
5600
5601 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
5602
5603 AscWriteLramByte(iop_base,
5604 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
5605 (uchar) (scsiq->q_status & (uchar) ~ (QS_READY | QS_ABORTED)));
5606 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
5607 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
5608 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
5609 sg_q_addr = q_addr;
5610 sg_list_qp = next_qp;
5611 for (i = 0; i < sg_queue_cnt; i++) {
5612 sg_list_qp = AscReadLramByte(iop_base,
5613 (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_FWD));
5614 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
5615 if (sg_list_qp == ASC_QLINK_END) {
5616 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_Q_LINKS);
5617 scsiq->d3.done_stat = QD_WITH_ERROR;
5618 scsiq->d3.host_stat = QHSTA_D_QDONE_SG_LIST_CORRUPTED;
5619 goto FATAL_ERR_QDONE;
5620 }
5621 AscWriteLramByte(iop_base,
5622 (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
5623 QS_FREE);
5624 }
5625
5626 n_q_used = sg_queue_cnt + 1;
5627 AscPutVarDoneQTail(iop_base, sg_list_qp);
5628 }
5629 if (asc_dvc->queue_full_or_busy & target_id) {
5630
5631 cur_target_qng = AscReadLramByte(iop_base,
5632 (ushort) ((ushort) ASC_QADR_BEG + (ushort) scsiq->d2.target_ix));
5633 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
5634 scsi_busy = AscReadLramByte(iop_base,
5635 (ushort) ASCV_SCSIBUSY_B);
5636 scsi_busy &= ~target_id;
5637 AscWriteLramByte(iop_base,
5638 (ushort) ASCV_SCSIBUSY_B, scsi_busy);
5639 asc_dvc->queue_full_or_busy &= ~target_id;
5640 }
5641 }
5642 if (asc_dvc->cur_total_qng >= n_q_used) {
5643 asc_dvc->cur_total_qng -= n_q_used;
5644 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
5645 asc_dvc->cur_dvc_qng[tid_no]--;
5646 }
5647 } else {
5648 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
5649 scsiq->d3.done_stat = QD_WITH_ERROR;
5650 goto FATAL_ERR_QDONE;
5651 }
5652
5653 if ((scsiq->d2.srb_ptr == 0UL) ||
5654 ((scsiq->q_status & QS_ABORTED) != 0)) {
5655
5656 return (0x11);
5657 } else if (scsiq->q_status == QS_DONE) {
5658
5659 false_overrun = FALSE;
5660
5661 if (asc_dvc->bug_fix_cntl) {
5662 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ADD_ONE_BYTE) {
5663 tag_code = AscReadLramByte(iop_base,
5664 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE));
5665 if (tag_code & ASC_TAG_FLAG_ADD_ONE_BYTE) {
5666 if (scsiq->remain_bytes != 0UL) {
5667 scsiq->remain_bytes--;
5668 if (scsiq->remain_bytes == 0UL) {
5669 false_overrun = TRUE;
5670 }
5671 }
5672 }
5673 }
5674 }
5675 if ((scsiq->d3.done_stat == QD_WITH_ERROR) &&
5676 (scsiq->d3.host_stat == QHSTA_M_DATA_OVER_RUN)) {
5677 if ((scsiq->cntl & (QC_DATA_IN | QC_DATA_OUT)) == 0) {
5678 scsiq->d3.done_stat = QD_NO_ERROR;
5679 scsiq->d3.host_stat = QHSTA_NO_ERROR;
5680 } else if (false_overrun) {
5681 scsiq->d3.done_stat = QD_NO_ERROR;
5682 scsiq->d3.host_stat = QHSTA_NO_ERROR;
5683 }
5684 }
5685 #if CC_CLEAR_LRAM_SRB_PTR
5686 AscWriteLramDWord(iop_base,
5687 (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR),
5688 asc_dvc->int_count);
5689 #endif
5690
5691 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
5692 (*asc_isr_callback) (asc_dvc, scsiq);
5693 } else {
5694 if ((AscReadLramByte(iop_base,
5695 (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) ==
5696 SCSICMD_StartStopUnit)) {
5697
5698 asc_dvc->unit_not_ready &= ~target_id;
5699 if (scsiq->d3.done_stat != QD_NO_ERROR) {
5700 asc_dvc->start_motor &= ~target_id;
5701 }
5702 }
5703 }
5704
5705 #if CC_LINK_BUSY_Q
5706 n_busy_q_done = AscIsrExeBusyQueue(asc_dvc, tid_no);
5707 if (n_busy_q_done == 0) {
5708
5709 i = tid_no + 1;
5710 while (TRUE) {
5711 if (i > ASC_MAX_TID)
5712 i = 0;
5713 if (i == tid_no)
5714 break;
5715 n_busy_q_done = AscIsrExeBusyQueue(asc_dvc, i);
5716 if (n_busy_q_done != 0)
5717 break;
5718 i++;
5719 }
5720 }
5721 if (n_busy_q_done == 0xFFFF)
5722 return (0x80);
5723 #endif
5724
5725 return (1);
5726 } else {
5727
5728 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
5729
5730 FATAL_ERR_QDONE:
5731 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
5732 (*asc_isr_callback) (asc_dvc, scsiq);
5733 }
5734 return (0x80);
5735 }
5736 }
5737 return (0);
5738 }
5739
5740 int
5741 AscISR(
5742 ASC_DVC_VAR asc_ptr_type * asc_dvc
5743 )
5744 {
5745 ASC_CS_TYPE chipstat;
5746 PortAddr iop_base;
5747 ushort saved_ram_addr;
5748 uchar ctrl_reg;
5749 uchar saved_ctrl_reg;
5750 int int_pending;
5751 int status;
5752 uchar host_flag;
5753
5754 iop_base = asc_dvc->iop_base;
5755 int_pending = FALSE;
5756
5757 asc_dvc->int_count++;
5758
5759 if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) ||
5760 (asc_dvc->isr_callback == 0)) {
5761
5762 return (ERR);
5763 }
5764 if (asc_dvc->in_critical_cnt != 0) {
5765 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
5766 return (ERR);
5767 }
5768 if (asc_dvc->is_in_int) {
5769 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
5770 asc_dvc->busy_count++;
5771 return (ERR);
5772 }
5773 asc_dvc->is_in_int = TRUE;
5774 ctrl_reg = AscGetChipControl(iop_base);
5775 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
5776 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
5777
5778 if ((chipstat = AscGetChipStatus(iop_base)) & CSW_INT_PENDING) {
5779 int_pending = TRUE;
5780 AscAckInterrupt(iop_base);
5781
5782 host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B);
5783 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
5784 (uchar) (host_flag | (uchar) ASC_HOST_FLAG_IN_ISR));
5785 saved_ram_addr = AscGetChipLramAddr(iop_base);
5786
5787 if ((chipstat & CSW_HALTED) &&
5788 (ctrl_reg & CC_SINGLE_STEP)) {
5789 if (AscIsrChipHalted(asc_dvc) == ERR) {
5790
5791 goto ISR_REPORT_QDONE_FATAL_ERROR;
5792
5793 } else {
5794 saved_ctrl_reg &= ~CC_HALT;
5795 }
5796 } else {
5797 ISR_REPORT_QDONE_FATAL_ERROR:
5798 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
5799 while (((status = AscIsrQDone(asc_dvc)) & 0x01) != 0) {
5800
5801 }
5802 } else {
5803 do {
5804 if ((status = AscIsrQDone(asc_dvc)) == 1) {
5805
5806 break;
5807 }
5808 } while (status == 0x11);
5809 }
5810 if ((status & 0x80) != 0)
5811 int_pending = ERR;
5812 }
5813 AscSetChipLramAddr(iop_base, saved_ram_addr);
5814 if (AscGetChipLramAddr(iop_base) != saved_ram_addr) {
5815 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SET_LRAM_ADDR);
5816 }
5817 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
5818 }
5819 AscSetChipControl(iop_base, saved_ctrl_reg);
5820 asc_dvc->is_in_int = FALSE;
5821 return (int_pending);
5822 }
5823
5824 int
5825 AscScsiSetupCmdQ(
5826 ASC_DVC_VAR asc_ptr_type * asc_dvc,
5827 ASC_SCSI_REQ_Q dosfar * scsiq,
5828 uchar dosfar * buf_addr,
5829 ulong buf_len
5830 )
5831 {
5832 ulong phy_addr;
5833
5834 scsiq->r1.cntl = 0;
5835 scsiq->r1.sg_queue_cnt = 0;
5836 scsiq->r1.q_no = 0;
5837 scsiq->r1.user_def = 0;
5838 scsiq->cdbptr = (uchar dosfar *) scsiq->cdb;
5839 scsiq->r3.scsi_stat = 0;
5840 scsiq->r3.scsi_msg = 0;
5841 scsiq->r3.host_stat = 0;
5842 scsiq->r3.done_stat = 0;
5843 scsiq->r2.vm_id = 0;
5844 scsiq->r1.data_cnt = buf_len;
5845
5846 scsiq->r2.tag_code = (uchar) M2_QTAG_MSG_SIMPLE;
5847 scsiq->r2.flag = (uchar) ASC_FLAG_SCSIQ_REQ;
5848 scsiq->r2.srb_ptr = (ulong) scsiq;
5849 scsiq->r1.status = (uchar) QS_READY;
5850 scsiq->r1.data_addr = 0L;
5851
5852 if (buf_len != 0L) {
5853 if ((phy_addr = AscGetOnePhyAddr(asc_dvc,
5854 (uchar dosfar *) buf_addr, scsiq->r1.data_cnt)) == 0L) {
5855 return (ERR);
5856 }
5857 scsiq->r1.data_addr = phy_addr;
5858 }
5859 return (0);
5860 }
5861
5862 uchar _mcode_buf[] =
5863 {
5864 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5865 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5866 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5867 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5868 0x00, 0x00, 0x00, 0x00, 0xDD, 0x0A, 0x01, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
5869 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5870 0x00, 0x00, 0x00, 0x23, 0x00, 0x16, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
5871 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0x88, 0x00, 0x00, 0x00, 0x00,
5872 0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC8, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
5873 0xB6, 0x00, 0x36, 0x00, 0x06, 0xD6, 0x0D, 0xD2, 0x15, 0xDE, 0x12, 0xDA, 0x00, 0xA2, 0xC8, 0x00,
5874 0x92, 0x80, 0xE0, 0x97, 0x50, 0x00, 0xF5, 0x00, 0x0A, 0x98, 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00,
5875 0x92, 0x80, 0x4F, 0x00, 0xF5, 0x00, 0x0A, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80,
5876 0x80, 0x62, 0x92, 0x80, 0x00, 0x62, 0x92, 0x80, 0x00, 0x46, 0x17, 0xEE, 0x13, 0xEA, 0x02, 0x01,
5877 0x09, 0xD8, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDC, 0x00, 0x68, 0x97, 0x7F, 0x23, 0x04, 0x61,
5878 0x84, 0x01, 0xB2, 0x84, 0xCF, 0xC1, 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xE8, 0x01,
5879 0x68, 0x97, 0xD4, 0x81, 0x00, 0x33, 0x02, 0x00, 0x82, 0x88, 0x80, 0x73, 0x80, 0x77, 0x00, 0x01,
5880 0x01, 0xA1, 0x08, 0x01, 0x4F, 0x00, 0x46, 0x97, 0x07, 0xA6, 0x12, 0x01, 0x00, 0x33, 0x03, 0x00,
5881 0x82, 0x88, 0x03, 0x03, 0x03, 0xDE, 0x00, 0x33, 0x05, 0x00, 0x82, 0x88, 0xCE, 0x00, 0x69, 0x60,
5882 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x86, 0x01, 0x80, 0x63, 0x07, 0xA6, 0x32, 0x01,
5883 0x86, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6, 0x42, 0x01, 0x00, 0x33, 0x04, 0x00,
5884 0x82, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23, 0x2A, 0x98, 0x4D, 0x04, 0xD0, 0x84,
5885 0x05, 0xD8, 0x0D, 0x23, 0x2A, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xB8, 0x88, 0xFB, 0x23, 0x02, 0x61,
5886 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x70, 0x01, 0x00, 0x33, 0x0A, 0x00, 0x82, 0x88,
5887 0x4E, 0x00, 0x07, 0xA3, 0x7C, 0x01, 0x00, 0x33, 0x0B, 0x00, 0x82, 0x88, 0xCD, 0x04, 0x36, 0x2D,
5888 0x00, 0x33, 0x1A, 0x00, 0x82, 0x88, 0x50, 0x04, 0x96, 0x81, 0x06, 0xAB, 0x90, 0x01, 0x96, 0x81,
5889 0x4E, 0x00, 0x07, 0xA3, 0xA0, 0x01, 0x50, 0x00, 0x00, 0xA3, 0x4A, 0x01, 0x00, 0x05, 0x8A, 0x81,
5890 0x08, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xCC, 0x81,
5891 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xC2, 0x01,
5892 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00, 0x82, 0x88, 0x06, 0x23, 0x2A, 0x98,
5893 0xCD, 0x04, 0xB2, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xE2, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xE8, 0x01,
5894 0xB2, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xB2, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61, 0x00, 0xA2,
5895 0x10, 0x02, 0x04, 0x01, 0x0D, 0xDE, 0x02, 0x01, 0x03, 0xCC, 0x4F, 0x00, 0x46, 0x97, 0x0A, 0x82,
5896 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x24, 0x97, 0x48, 0x04, 0xFF, 0x23, 0x84, 0x80,
5897 0xB2, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
5898 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x66, 0xEB, 0x11, 0x23, 0xB8, 0x88, 0xC6, 0x97, 0xFA, 0x80,
5899 0x80, 0x73, 0x80, 0x77, 0x06, 0xA6, 0x3E, 0x02, 0x00, 0x33, 0x31, 0x00, 0x82, 0x88, 0x04, 0x01,
5900 0x03, 0xD8, 0x74, 0x98, 0x02, 0x96, 0x50, 0x82, 0xA2, 0x95, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
5901 0xB6, 0x2D, 0x02, 0xA6, 0x7A, 0x02, 0x07, 0xA6, 0x68, 0x02, 0x06, 0xA6, 0x6C, 0x02, 0x03, 0xA6,
5902 0x70, 0x02, 0x00, 0x33, 0x10, 0x00, 0x82, 0x88, 0x4A, 0x95, 0x52, 0x82, 0xF8, 0x95, 0x52, 0x82,
5903 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x16, 0x84, 0x04, 0x01, 0x0C, 0xDC, 0xE0, 0x23,
5904 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01, 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23,
5905 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAC, 0x02, 0x07, 0xA6,
5906 0x68, 0x02, 0x06, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x12, 0x00, 0x82, 0x88, 0x00, 0x0E, 0x80, 0x63,
5907 0x00, 0x43, 0x00, 0xA0, 0x9A, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61,
5908 0x84, 0x01, 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00,
5909 0xEC, 0x82, 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE4, 0x02, 0x04, 0x01, 0x8E, 0xC8, 0x00, 0x33,
5910 0x1F, 0x00, 0x82, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x40, 0x98, 0xB6, 0x2D,
5911 0x01, 0xA6, 0x0E, 0x03, 0x00, 0xA6, 0x1C, 0x03, 0x07, 0xA6, 0x2A, 0x03, 0x06, 0xA6, 0x2E, 0x03,
5912 0x03, 0xA6, 0xFA, 0x03, 0x02, 0xA6, 0x7A, 0x02, 0x00, 0x33, 0x33, 0x00, 0x82, 0x88, 0x08, 0x23,
5913 0xB3, 0x01, 0x04, 0x01, 0x0E, 0xD0, 0x00, 0x33, 0x14, 0x00, 0x82, 0x88, 0x10, 0x23, 0xB3, 0x01,
5914 0x04, 0x01, 0x07, 0xCC, 0x00, 0x33, 0x15, 0x00, 0x82, 0x88, 0x4A, 0x95, 0xF0, 0x82, 0xF8, 0x95,
5915 0xF0, 0x82, 0x44, 0x98, 0x80, 0x42, 0x40, 0x98, 0x48, 0xE4, 0x04, 0x01, 0x29, 0xC8, 0x31, 0x05,
5916 0x07, 0x01, 0x00, 0xA2, 0x72, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x48, 0x98, 0x40, 0x98,
5917 0x00, 0xA6, 0x34, 0x03, 0x07, 0xA6, 0x6A, 0x03, 0x03, 0xA6, 0x16, 0x04, 0x06, 0xA6, 0x6E, 0x03,
5918 0x01, 0xA6, 0x34, 0x03, 0x00, 0x33, 0x25, 0x00, 0x82, 0x88, 0x4A, 0x95, 0x50, 0x83, 0xF8, 0x95,
5919 0x50, 0x83, 0x04, 0x01, 0x0C, 0xCE, 0x03, 0xC8, 0x00, 0x33, 0x42, 0x00, 0x82, 0x88, 0x00, 0x01,
5920 0x05, 0x05, 0xFF, 0xA2, 0x90, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x4C, 0x83, 0x05, 0x05,
5921 0x01, 0xA6, 0x9A, 0x03, 0x00, 0xA6, 0xAA, 0x03, 0xF0, 0x83, 0x68, 0x98, 0x80, 0x42, 0x01, 0xA6,
5922 0x9A, 0x03, 0xBA, 0x83, 0x00, 0x33, 0x2F, 0x00, 0x82, 0x88, 0x68, 0x98, 0x80, 0x42, 0x00, 0xA6,
5923 0xAA, 0x03, 0xBA, 0x83, 0x00, 0x33, 0x26, 0x00, 0x82, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36,
5924 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0xF0, 0x83, 0x04, 0xF0, 0x80, 0x6B, 0x00, 0x33,
5925 0x20, 0x00, 0x82, 0x88, 0x03, 0xA6, 0xEE, 0x03, 0x07, 0xA6, 0xE6, 0x03, 0x06, 0xA6, 0xEA, 0x03,
5926 0x00, 0x33, 0x17, 0x00, 0x82, 0x88, 0x4A, 0x95, 0xD4, 0x83, 0xF8, 0x95, 0xD4, 0x83, 0xFA, 0x83,
5927 0x04, 0xF0, 0x80, 0x6B, 0x00, 0x33, 0x20, 0x00, 0x82, 0x88, 0xB6, 0x2D, 0x03, 0xA6, 0x16, 0x04,
5928 0x07, 0xA6, 0x0E, 0x04, 0x06, 0xA6, 0x12, 0x04, 0x00, 0x33, 0x30, 0x00, 0x82, 0x88, 0x4A, 0x95,
5929 0xFA, 0x83, 0xF8, 0x95, 0xFA, 0x83, 0xA2, 0x0D, 0x80, 0x63, 0x07, 0xA6, 0x24, 0x04, 0x00, 0x33,
5930 0x18, 0x00, 0x82, 0x88, 0x03, 0x03, 0x80, 0x63, 0xA3, 0x01, 0x07, 0xA4, 0x2E, 0x04, 0x23, 0x01,
5931 0x00, 0xA2, 0x50, 0x04, 0x0A, 0xA0, 0x40, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00, 0x82, 0x88,
5932 0x0B, 0xA0, 0x4C, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00, 0x82, 0x88, 0x42, 0x23, 0xB8, 0x88,
5933 0x00, 0x23, 0x22, 0xA3, 0xB2, 0x04, 0x08, 0x23, 0x22, 0xA3, 0x6C, 0x04, 0x28, 0x23, 0x22, 0xA3,
5934 0x78, 0x04, 0x02, 0x23, 0x22, 0xA3, 0x8E, 0x04, 0x42, 0x23, 0xB8, 0x88, 0x4A, 0x00, 0x06, 0x61,
5935 0x00, 0xA0, 0x78, 0x04, 0x45, 0x23, 0xB8, 0x88, 0xC6, 0x97, 0x00, 0xA2, 0x8A, 0x04, 0x74, 0x98,
5936 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20, 0x81, 0x62, 0xF6, 0x81, 0x47, 0x23, 0xB8, 0x88, 0x04, 0x01,
5937 0x0C, 0xDE, 0x14, 0x01, 0x00, 0xA2, 0xA6, 0x04, 0xC6, 0x97, 0x74, 0x98, 0x00, 0x33, 0x00, 0x81,
5938 0xC0, 0x20, 0x81, 0x62, 0x10, 0x82, 0x43, 0x23, 0xB8, 0x88, 0x04, 0x23, 0xA0, 0x01, 0x44, 0x23,
5939 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3, 0xC0, 0x04, 0x00, 0x33, 0x27, 0x00, 0x82, 0x88,
5940 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xC6, 0x97, 0xF4, 0x94,
5941 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0xEE, 0x04, 0x00, 0x05, 0x76, 0x00,
5942 0x06, 0x61, 0x00, 0xA2, 0xE8, 0x04, 0xD6, 0x84, 0x08, 0x97, 0xCD, 0x04, 0xF2, 0x84, 0x48, 0x04,
5943 0xFF, 0x23, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x02, 0x85, 0x02, 0x23,
5944 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x0E, 0x05, 0x1D, 0x01, 0x04, 0xD6, 0xFF, 0x23,
5945 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x49, 0x00, 0x81, 0x01, 0x04, 0x01,
5946 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 0xC9, 0x00,
5947 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x2E, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00, 0x5D, 0x00,
5948 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63, 0x07, 0xA4, 0xA0, 0x05, 0x03, 0x03,
5949 0x02, 0xA0, 0x5C, 0x05, 0x9C, 0x85, 0x00, 0x33, 0x2D, 0x00, 0x82, 0x88, 0x04, 0xA0, 0x82, 0x05,
5950 0x80, 0x63, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x6E, 0x05, 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23,
5951 0x02, 0x41, 0x82, 0x01, 0x50, 0x00, 0x24, 0x97, 0xD0, 0x84, 0x04, 0x23, 0x02, 0x41, 0x82, 0x01,
5952 0xD0, 0x84, 0x08, 0xA0, 0x88, 0x05, 0x9C, 0x85, 0x03, 0xA0, 0x8E, 0x05, 0x9C, 0x85, 0x01, 0xA0,
5953 0x9A, 0x05, 0x88, 0x00, 0x80, 0x63, 0x78, 0x96, 0x4A, 0x85, 0x88, 0x86, 0x80, 0x63, 0x4A, 0x85,
5954 0x00, 0x63, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xDE, 0x05, 0x1D, 0x01, 0x18, 0xD4, 0xC0, 0x23,
5955 0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0xC0, 0x05, 0x00, 0x33, 0x37, 0x00, 0x82, 0x88,
5956 0x1D, 0x01, 0x02, 0xD6, 0x46, 0x23, 0xB8, 0x88, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
5957 0xD8, 0x05, 0x00, 0x33, 0x38, 0x00, 0x82, 0x88, 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00,
5958 0x06, 0x41, 0xCB, 0x00, 0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xF2, 0x05, 0xC0, 0x23, 0x07, 0x41,
5959 0x00, 0x63, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63, 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63,
5960 0x00, 0x63, 0x06, 0xA6, 0x14, 0x06, 0x07, 0xA6, 0x64, 0x06, 0x02, 0xA6, 0xBC, 0x06, 0x00, 0x33,
5961 0x39, 0x00, 0x82, 0x88, 0x00, 0x00, 0x01, 0xA0, 0xD6, 0x06, 0xA2, 0x95, 0x83, 0x03, 0x80, 0x63,
5962 0x06, 0xA6, 0x28, 0x06, 0x07, 0xA6, 0x64, 0x06, 0x00, 0x00, 0x00, 0x2B, 0x40, 0x0E, 0x80, 0x63,
5963 0x01, 0x00, 0x06, 0xA6, 0x40, 0x06, 0x07, 0xA6, 0x64, 0x06, 0x00, 0x33, 0x3A, 0x00, 0x82, 0x88,
5964 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x32, 0x06, 0x06, 0xA6, 0x58, 0x06, 0x07, 0xA6,
5965 0x64, 0x06, 0x00, 0x33, 0x3B, 0x00, 0x82, 0x88, 0x80, 0x67, 0x40, 0x0E, 0x80, 0x63, 0x07, 0xA6,
5966 0x64, 0x06, 0x00, 0x63, 0x03, 0x03, 0x80, 0x63, 0x88, 0x00, 0x01, 0xA2, 0x78, 0x06, 0x07, 0xA2,
5967 0xBC, 0x06, 0x00, 0x33, 0x35, 0x00, 0x82, 0x88, 0x07, 0xA6, 0x82, 0x06, 0x00, 0x33, 0x2A, 0x00,
5968 0x82, 0x88, 0x03, 0x03, 0x03, 0xA2, 0x8E, 0x06, 0x07, 0x23, 0x80, 0x00, 0xC8, 0x86, 0x80, 0x63,
5969 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0x9E, 0x06, 0x00, 0x33, 0x29, 0x00, 0x82, 0x88, 0x00, 0x43,
5970 0x00, 0xA2, 0xAA, 0x06, 0xC0, 0x0E, 0x80, 0x63, 0x94, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80,
5971 0xC0, 0x20, 0x81, 0x62, 0x04, 0x01, 0x08, 0xDA, 0x80, 0x63, 0x00, 0x63, 0x80, 0x67, 0x00, 0x33,
5972 0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x20, 0x06,
5973 0x00, 0x33, 0x2C, 0x00, 0x82, 0x88, 0x0C, 0xA2, 0xF0, 0x06, 0xA2, 0x95, 0x83, 0x03, 0x80, 0x63,
5974 0x06, 0xA6, 0xEE, 0x06, 0x07, 0xA6, 0x64, 0x06, 0x00, 0x33, 0x3D, 0x00, 0x82, 0x88, 0x00, 0x00,
5975 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x06, 0x07, 0x07, 0xA6, 0x64, 0x06, 0xBF, 0x23,
5976 0x04, 0x61, 0x84, 0x01, 0xB2, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01,
5977 0xF2, 0x00, 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04, 0x80, 0x05,
5978 0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00,
5979 0x81, 0x01, 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00,
5980 0x80, 0x01, 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01, 0xF1, 0x00,
5981 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01, 0x71, 0x04,
5982 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01,
5983 0xA2, 0x01, 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1, 0x86, 0x07,
5984 0x00, 0x33, 0x07, 0x00, 0x82, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00,
5985 0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2,
5986 0xA6, 0x07, 0x00, 0x05, 0x9C, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x05, 0x05,
5987 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43, 0x76, 0x08,
5988 0x80, 0x02, 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02,
5989 0x00, 0xA0, 0xD6, 0x07, 0xD8, 0x87, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63,
5990 0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2,
5991 0x06, 0x08, 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0xE6, 0x07,
5992 0xC6, 0x97, 0xF4, 0x94, 0xE6, 0x87, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04, 0x1C, 0x88,
5993 0x02, 0x01, 0x04, 0xD8, 0x08, 0x97, 0xC6, 0x97, 0xF4, 0x94, 0x0C, 0x88, 0x75, 0x00, 0x00, 0xA3,
5994 0x26, 0x08, 0x00, 0x05, 0x10, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6,
5995 0x38, 0x08, 0x00, 0x33, 0x3E, 0x00, 0x82, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63,
5996 0x38, 0x2B, 0x5E, 0x88, 0x38, 0x2B, 0x54, 0x88, 0x32, 0x09, 0x31, 0x05, 0x54, 0x98, 0x05, 0x05,
5997 0xB2, 0x09, 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32,
5998 0x80, 0x36, 0x80, 0x3A, 0x80, 0x3E, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32, 0x40, 0x36, 0x40, 0x3A,
5999 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0x74, 0x08, 0x5D, 0x00, 0xFE, 0xC3,
6000 0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
6001 0x13, 0x23, 0xB8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01, 0xA1, 0x23, 0xA1, 0x01,
6002 0x81, 0x62, 0xA2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2,
6003 0xF1, 0xC7, 0x41, 0x23, 0xB8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xB2, 0x84,
6004
6005 };
6006
6007 ushort _mcode_size = sizeof (_mcode_buf);
6008 ulong _mcode_chksum = 0x012258FBUL;
6009
6010 extern uchar _sdtr_period_tbl_[];
6011
6012 int
6013 AscExeScsiQueue(
6014 ASC_DVC_VAR asc_ptr_type * asc_dvc,
6015 ASC_SCSI_Q dosfar * scsiq
6016 )
6017 {
6018 PortAddr iop_base;
6019 int last_int_level;
6020 int sta;
6021 ulong addr;
6022 uchar sg_entry_cnt;
6023 uchar target_ix;
6024 int n_q_required;
6025 uchar sg_entry_cnt_minus_one;
6026 uchar tid_no;
6027 uchar sdtr_data;
6028 ASC_EXE_CALLBACK asc_exe_callback;
6029
6030 #if CC_DEBUG_SG_LIST
6031 int i;
6032
6033 #endif
6034 #if CC_LINK_BUSY_Q
6035 ASC_SCSI_Q dosfar *scsiq_tail;
6036 ASC_SCSI_Q dosfar *scsiq_next;
6037 ASC_SCSI_Q dosfar *scsiq_prev;
6038
6039 #endif
6040
6041 iop_base = asc_dvc->iop_base;
6042 asc_exe_callback = (ASC_EXE_CALLBACK) asc_dvc->exe_callback;
6043 if (asc_dvc->err_code != 0)
6044 return (ERR);
6045 if (scsiq == (ASC_SCSI_Q dosfar *) 0L) {
6046 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
6047 return (ERR);
6048 }
6049 scsiq->q1.q_no = 0;
6050 sta = 0;
6051 target_ix = scsiq->q2.target_ix;
6052 tid_no = ASC_TIX_TO_TID(target_ix);
6053
6054 n_q_required = 1;
6055
6056 if (scsiq->cdbptr[0] == SCSICMD_RequestSense) {
6057
6058 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
6059 ((asc_dvc->sdtr_done & scsiq->q1.target_id) != 0)) {
6060 sdtr_data = AscReadLramByte(iop_base,
6061 (ushort) ((ushort) ASCV_SDTR_DATA_BEG + (ushort) tid_no));
6062 AscMsgOutSDTR(iop_base,
6063 _sdtr_period_tbl_[(sdtr_data >> 4) & (uchar) (ASC_SYN_XFER_NO - 1)],
6064 (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
6065 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
6066 }
6067 }
6068 last_int_level = DvcEnterCritical();
6069 if (asc_dvc->in_critical_cnt != 0) {
6070 DvcLeaveCritical(last_int_level);
6071 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
6072 return (ERR);
6073 }
6074 asc_dvc->in_critical_cnt++;
6075
6076 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
6077
6078 if ((sg_entry_cnt = scsiq->sg_head->entry_cnt) == 0) {
6079 asc_dvc->in_critical_cnt--;
6080 DvcLeaveCritical(last_int_level);
6081 return (ERR);
6082 }
6083 if (sg_entry_cnt == 1) {
6084 scsiq->q1.data_addr = scsiq->sg_head->sg_list[0].addr;
6085 scsiq->q1.data_cnt = scsiq->sg_head->sg_list[0].bytes;
6086 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
6087 goto NON_SG_LIST_REQ;
6088 }
6089 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
6090
6091 return (ERR);
6092 }
6093 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
6094
6095 #if CC_DEBUG_SG_LIST
6096 if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
6097 for (i = 0; i < sg_entry_cnt_minus_one; i++) {
6098
6099 addr = scsiq->sg_head->sg_list[i].addr +
6100 scsiq->sg_head->sg_list[i].bytes;
6101
6102 if (((ushort) addr & 0x0003) != 0) {
6103 asc_dvc->in_critical_cnt--;
6104 DvcLeaveCritical(last_int_level);
6105 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_LIST_ODD_ADDRESS);
6106 return (ERR);
6107 }
6108 }
6109 }
6110 #endif
6111
6112 if (asc_dvc->bug_fix_cntl) {
6113 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ADD_ONE_BYTE) {
6114
6115 addr = scsiq->sg_head->sg_list[sg_entry_cnt_minus_one].addr +
6116 scsiq->sg_head->sg_list[sg_entry_cnt_minus_one].bytes;
6117 if (((ushort) addr & 0x0003) != 0) {
6118 if ((scsiq->cdbptr[0] == SCSICMD_Read6) ||
6119 (scsiq->cdbptr[0] == SCSICMD_Read10)) {
6120 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_ADD_ONE_BYTE) == 0) {
6121
6122 scsiq->sg_head->sg_list[sg_entry_cnt_minus_one].bytes++;
6123 scsiq->q2.tag_code |= ASC_TAG_FLAG_ADD_ONE_BYTE;
6124 }
6125 }
6126 }
6127 }
6128 }
6129 scsiq->sg_head->entry_to_copy = scsiq->sg_head->entry_cnt;
6130 n_q_required = AscSgListToQueue(sg_entry_cnt);
6131
6132 #if CC_LINK_BUSY_Q
6133 scsiq_next = (ASC_SCSI_Q dosfar *) asc_dvc->scsiq_busy_head[tid_no];
6134 if (scsiq_next != (ASC_SCSI_Q dosfar *) 0L) {
6135 goto link_scisq_to_busy_list;
6136 }
6137 #endif
6138
6139 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required)
6140 >= (uint) n_q_required) ||
6141 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
6142 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
6143 n_q_required)) == 1) {
6144
6145 asc_dvc->in_critical_cnt--;
6146 if (asc_exe_callback != 0) {
6147 (*asc_exe_callback) (asc_dvc, scsiq);
6148 }
6149 DvcLeaveCritical(last_int_level);
6150 return (sta);
6151 }
6152 }
6153 } else {
6154
6155 NON_SG_LIST_REQ:
6156
6157 if (asc_dvc->bug_fix_cntl) {
6158 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ADD_ONE_BYTE) {
6159
6160 addr = scsiq->q1.data_addr + scsiq->q1.data_cnt;
6161 if ((scsiq->cdbptr[0] == SCSICMD_Read6) ||
6162 (scsiq->cdbptr[0] == SCSICMD_Read10)) {
6163 if (((ushort) addr & 0x0003) != 0) {
6164 if (((ushort) scsiq->q1.data_cnt & 0x01FF) == 0) {
6165
6166 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_ADD_ONE_BYTE) == 0) {
6167
6168 scsiq->q2.tag_code |= ASC_TAG_FLAG_ADD_ONE_BYTE;
6169 scsiq->q1.data_cnt++;
6170 }
6171 }
6172 }
6173 }
6174 }
6175 }
6176 n_q_required = 1;
6177
6178 #if CC_LINK_BUSY_Q
6179 scsiq_next = (ASC_SCSI_Q dosfar *) asc_dvc->scsiq_busy_head[tid_no];
6180 if (scsiq_next != (ASC_SCSI_Q dosfar *) 0L) {
6181 goto link_scisq_to_busy_list;
6182 }
6183 #endif
6184 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
6185 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
6186 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
6187 n_q_required)) == 1) {
6188
6189 asc_dvc->in_critical_cnt--;
6190 if (asc_exe_callback != 0) {
6191 (*asc_exe_callback) (asc_dvc, scsiq);
6192 }
6193 DvcLeaveCritical(last_int_level);
6194 return (sta);
6195 }
6196 }
6197 }
6198
6199 #if CC_LINK_BUSY_Q
6200 if (sta == 0) {
6201
6202 link_scisq_to_busy_list:
6203 scsiq->ext.q_required = n_q_required;
6204 if (scsiq_next == (ASC_SCSI_Q dosfar *) 0L) {
6205 asc_dvc->scsiq_busy_head[tid_no] = (ASC_SCSI_Q dosfar *) scsiq;
6206 asc_dvc->scsiq_busy_tail[tid_no] = (ASC_SCSI_Q dosfar *) scsiq;
6207 scsiq->ext.next = (ASC_SCSI_Q dosfar *) 0L;
6208 scsiq->ext.join = (ASC_SCSI_Q dosfar *) 0L;
6209 scsiq->q1.status = QS_BUSY;
6210 sta = 1;
6211 } else {
6212 scsiq_tail = (ASC_SCSI_Q dosfar *) asc_dvc->scsiq_busy_tail[tid_no];
6213 if (scsiq_tail->ext.next == (ASC_SCSI_Q dosfar *) 0L) {
6214 if ((scsiq->q1.cntl & QC_URGENT) != 0) {
6215
6216 asc_dvc->scsiq_busy_head[tid_no] = (ASC_SCSI_Q dosfar *) scsiq;
6217 scsiq->ext.next = scsiq_next;
6218 scsiq->ext.join = (ASC_SCSI_Q dosfar *) 0L;
6219 } else {
6220 if (scsiq->ext.cntl & QCX_SORT) {
6221 do {
6222 scsiq_prev = scsiq_next;
6223 scsiq_next = scsiq_next->ext.next;
6224 if (scsiq->ext.lba < scsiq_prev->ext.lba)
6225 break;
6226 } while (scsiq_next != (ASC_SCSI_Q dosfar *) 0L);
6227
6228 scsiq_prev->ext.next = scsiq;
6229 scsiq->ext.next = scsiq_next;
6230 if (scsiq_next == (ASC_SCSI_Q dosfar *) 0L) {
6231 asc_dvc->scsiq_busy_tail[tid_no] = (ASC_SCSI_Q dosfar *) scsiq;
6232 }
6233 scsiq->ext.join = (ASC_SCSI_Q dosfar *) 0L;
6234 } else {
6235
6236 scsiq_tail->ext.next = (ASC_SCSI_Q dosfar *) scsiq;
6237 asc_dvc->scsiq_busy_tail[tid_no] = (ASC_SCSI_Q dosfar *) scsiq;
6238 scsiq->ext.next = (ASC_SCSI_Q dosfar *) 0L;
6239 scsiq->ext.join = (ASC_SCSI_Q dosfar *) 0L;
6240 }
6241 }
6242 scsiq->q1.status = QS_BUSY;
6243 sta = 1;
6244 } else {
6245
6246 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_BAD_NEXT_PTR);
6247 sta = ERR;
6248 }
6249 }
6250 }
6251 #endif
6252 asc_dvc->in_critical_cnt--;
6253 DvcLeaveCritical(last_int_level);
6254 return (sta);
6255 }
6256
6257 int
6258 AscSendScsiQueue(
6259 ASC_DVC_VAR asc_ptr_type * asc_dvc,
6260 ASC_SCSI_Q dosfar * scsiq,
6261 uchar n_q_required
6262 )
6263 {
6264 PortAddr iop_base;
6265 uchar free_q_head;
6266 uchar next_qp;
6267 uchar tid_no;
6268 uchar target_ix;
6269 int sta;
6270
6271 iop_base = asc_dvc->iop_base;
6272 target_ix = scsiq->q2.target_ix;
6273 tid_no = ASC_TIX_TO_TID(target_ix);
6274 sta = 0;
6275 free_q_head = (uchar) AscGetVarFreeQHead(iop_base);
6276 if (n_q_required > 1) {
6277 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
6278 free_q_head, (uchar) (n_q_required)))
6279 != (uchar) ASC_QLINK_END) {
6280 asc_dvc->last_q_shortage = 0;
6281 scsiq->sg_head->queue_cnt = n_q_required - 1;
6282 scsiq->q1.q_no = free_q_head;
6283
6284 if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
6285 free_q_head)) == 1) {
6286
6287 #if CC_WRITE_IO_COUNT
6288 asc_dvc->req_count++;
6289 #endif
6290
6291 AscPutVarFreeQHead(iop_base, next_qp);
6292 asc_dvc->cur_total_qng += (uchar) (n_q_required);
6293 asc_dvc->cur_dvc_qng[tid_no]++;
6294 }
6295 return (sta);
6296 }
6297 } else if (n_q_required == 1) {
6298
6299 if ((next_qp = AscAllocFreeQueue(iop_base,
6300 free_q_head)) != ASC_QLINK_END) {
6301
6302 scsiq->q1.q_no = free_q_head;
6303 if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
6304 free_q_head)) == 1) {
6305
6306 #if CC_WRITE_IO_COUNT
6307 asc_dvc->req_count++;
6308 #endif
6309
6310 AscPutVarFreeQHead(iop_base, next_qp);
6311 asc_dvc->cur_total_qng++;
6312 asc_dvc->cur_dvc_qng[tid_no]++;
6313 }
6314 return (sta);
6315 }
6316 }
6317 return (sta);
6318 }
6319
6320 int
6321 AscSgListToQueue(
6322 int sg_list
6323 )
6324 {
6325 int n_sg_list_qs;
6326
6327 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
6328 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
6329 n_sg_list_qs++;
6330 return (n_sg_list_qs + 1);
6331 }
6332
6333 uint
6334 AscGetNumOfFreeQueue(
6335 ASC_DVC_VAR asc_ptr_type * asc_dvc,
6336 uchar target_ix, uchar n_qs
6337 )
6338 {
6339 uint cur_used_qs;
6340 uint cur_free_qs;
6341 ASC_SCSI_BIT_ID_TYPE target_id;
6342 uchar tid_no;
6343
6344 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
6345 tid_no = ASC_TIX_TO_TID(target_ix);
6346 if ((asc_dvc->unit_not_ready & target_id) ||
6347 (asc_dvc->queue_full_or_busy & target_id)) {
6348 return (0);
6349 }
6350 if (n_qs == 1) {
6351 cur_used_qs = (uint) asc_dvc->cur_total_qng +
6352 (uint) asc_dvc->last_q_shortage +
6353 (uint) ASC_MIN_FREE_Q;
6354 } else {
6355 cur_used_qs = (uint) asc_dvc->cur_total_qng +
6356 (uint) ASC_MIN_FREE_Q;
6357 }
6358
6359 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
6360 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
6361 if (asc_dvc->cur_dvc_qng[tid_no] >=
6362 asc_dvc->max_dvc_qng[tid_no]) {
6363 return (0);
6364 }
6365 return (cur_free_qs);
6366 }
6367 if (n_qs > 1) {
6368 if (n_qs > asc_dvc->last_q_shortage) {
6369 asc_dvc->last_q_shortage = n_qs;
6370 }
6371 }
6372 return (0);
6373 }
6374
6375 int
6376 AscPutReadyQueue(
6377 ASC_DVC_VAR asc_ptr_type * asc_dvc,
6378 ASC_SCSI_Q dosfar * scsiq,
6379 uchar q_no
6380 )
6381 {
6382 ushort q_addr;
6383 uchar tid_no;
6384 uchar sdtr_data;
6385 uchar syn_period_ix;
6386 uchar syn_offset;
6387 PortAddr iop_base;
6388
6389 iop_base = asc_dvc->iop_base;
6390
6391 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
6392 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
6393
6394 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
6395
6396 sdtr_data = AscReadLramByte(iop_base,
6397 (ushort) ((ushort) ASCV_SDTR_DATA_BEG + (ushort) tid_no));
6398 syn_period_ix = (sdtr_data >> 4) & (ASC_SYN_XFER_NO - 1);
6399 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
6400 AscMsgOutSDTR(iop_base,
6401 _sdtr_period_tbl_[syn_period_ix],
6402 syn_offset);
6403
6404 scsiq->q1.cntl |= QC_MSG_OUT;
6405 }
6406 q_addr = ASC_QNO_TO_QADDR(q_no);
6407
6408 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
6409 scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
6410 }
6411 scsiq->q1.status = QS_FREE;
6412
6413 AscMemWordCopyToLram(iop_base,
6414 (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG),
6415 (ushort dosfar *) scsiq->cdbptr,
6416 (ushort) ((ushort) scsiq->q2.cdb_len >> 1));
6417
6418 #if !CC_LITTLE_ENDIAN_HOST
6419 AscAdjEndianScsiQ(scsiq);
6420 #endif
6421
6422 DvcPutScsiQ(iop_base,
6423 (ushort) (q_addr + (ushort) ASC_SCSIQ_CPY_BEG),
6424 (ushort dosfar *) & scsiq->q1.cntl,
6425 (ushort) ((((sizeof (ASC_SCSIQ_1) + sizeof (ASC_SCSIQ_2)) / 2) - 1)));
6426
6427 #if CC_WRITE_IO_COUNT
6428 AscWriteLramWord(iop_base,
6429 (ushort) (q_addr + (ushort) ASC_SCSIQ_W_REQ_COUNT),
6430 (ushort) asc_dvc->req_count);
6431
6432 #endif
6433
6434 #if CC_VERIFY_LRAM_COPY
6435 if ((asc_dvc->dvc_cntl & ASC_CNTL_NO_VERIFY_COPY) == 0) {
6436
6437 if (AscMemWordCmpToLram(iop_base,
6438 (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG),
6439 (ushort dosfar *) scsiq->cdbptr,
6440 (ushort) (scsiq->q2.cdb_len >> 1)) != 0) {
6441 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_LOCAL_MEM);
6442 return (ERR);
6443 }
6444 if (AscMemWordCmpToLram(iop_base,
6445 (ushort) (q_addr + (ushort) ASC_SCSIQ_CPY_BEG),
6446 (ushort dosfar *) & scsiq->q1.cntl,
6447 (ushort) (((sizeof (ASC_SCSIQ_1) + sizeof (ASC_SCSIQ_2)) / 2) - 1))
6448 != 0) {
6449 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_LOCAL_MEM);
6450 return (ERR);
6451 }
6452 }
6453 #endif
6454
6455 #if CC_CLEAR_DMA_REMAIN
6456
6457 AscWriteLramDWord(iop_base,
6458 (ushort) (q_addr + (ushort) ASC_SCSIQ_DW_REMAIN_XFER_ADDR), 0UL);
6459 AscWriteLramDWord(iop_base,
6460 (ushort) (q_addr + (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT), 0UL);
6461
6462 #endif
6463
6464 AscWriteLramWord(iop_base,
6465 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
6466 (ushort) (((ushort) scsiq->q1.q_no << 8) | (ushort) QS_READY));
6467 return (1);
6468 }
6469
6470 int
6471 AscPutReadySgListQueue(
6472 ASC_DVC_VAR asc_ptr_type * asc_dvc,
6473 ASC_SCSI_Q dosfar * scsiq,
6474 uchar q_no
6475 )
6476 {
6477 uchar sg_list_dwords;
6478 uchar sg_index, i;
6479 uchar sg_entry_cnt;
6480 uchar next_qp;
6481 ushort q_addr;
6482 int sta;
6483 ASC_SG_HEAD dosfar *sg_head;
6484 ASC_SG_LIST_Q scsi_sg_q;
6485 ulong saved_data_addr;
6486 ulong saved_data_cnt;
6487 PortAddr iop_base;
6488
6489 iop_base = asc_dvc->iop_base;
6490
6491 sg_head = scsiq->sg_head;
6492
6493 saved_data_addr = scsiq->q1.data_addr;
6494 saved_data_cnt = scsiq->q1.data_cnt;
6495 scsiq->q1.data_addr = sg_head->sg_list[0].addr;
6496 scsiq->q1.data_cnt = sg_head->sg_list[0].bytes;
6497 sg_entry_cnt = sg_head->entry_cnt - 1;
6498 if (sg_entry_cnt != 0) {
6499 scsiq->q1.cntl |= QC_SG_HEAD;
6500 q_addr = ASC_QNO_TO_QADDR(q_no);
6501 sg_index = 1;
6502 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
6503 scsi_sg_q.sg_head_qp = q_no;
6504 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
6505 for (i = 0; i < sg_head->queue_cnt; i++) {
6506 scsi_sg_q.seq_no = i + 1;
6507 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
6508 sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
6509 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
6510 if (i == 0) {
6511 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q;
6512 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q;
6513 } else {
6514 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
6515 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
6516 }
6517 } else {
6518
6519 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
6520 sg_list_dwords = sg_entry_cnt << 1;
6521 if (i == 0) {
6522 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
6523 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt;
6524 } else {
6525 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
6526 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
6527 }
6528 sg_entry_cnt = 0;
6529 }
6530 next_qp = AscReadLramByte(iop_base,
6531 (ushort) (q_addr + ASC_SCSIQ_B_FWD));
6532 scsi_sg_q.q_no = next_qp;
6533 q_addr = ASC_QNO_TO_QADDR(next_qp);
6534
6535 AscMemWordCopyToLram(iop_base,
6536 (ushort) (q_addr + ASC_SCSIQ_SGHD_CPY_BEG),
6537 (ushort dosfar *) & scsi_sg_q,
6538 (ushort) (sizeof (ASC_SG_LIST_Q) >> 1));
6539
6540 AscMemDWordCopyToLram(iop_base,
6541 (ushort) (q_addr + ASC_SGQ_LIST_BEG),
6542 (ulong dosfar *) & sg_head->sg_list[sg_index],
6543 (ushort) sg_list_dwords);
6544
6545 sg_index += ASC_SG_LIST_PER_Q;
6546 }
6547 } else {
6548
6549 scsiq->q1.cntl &= ~QC_SG_HEAD;
6550 }
6551 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
6552
6553 scsiq->q1.data_addr = saved_data_addr;
6554 scsiq->q1.data_cnt = saved_data_cnt;
6555 return (sta);
6556 }
6557
6558 int
6559 AscAbortSRB(
6560 ASC_DVC_VAR asc_ptr_type * asc_dvc,
6561 ulong srb_ptr
6562 )
6563 {
6564 int sta;
6565 ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
6566 PortAddr iop_base;
6567
6568 iop_base = asc_dvc->iop_base;
6569 sta = ERR;
6570 saved_unit_not_ready = asc_dvc->unit_not_ready;
6571 asc_dvc->unit_not_ready = 0xFF;
6572 AscWaitISRDone(asc_dvc);
6573 if (AscStopQueueExe(iop_base) == 1) {
6574 if (AscRiscHaltedAbortSRB(asc_dvc, srb_ptr) == 1) {
6575 sta = 1;
6576 AscCleanUpBusyQueue(iop_base);
6577 AscStartQueueExe(iop_base);
6578
6579 } else {
6580 sta = 0;
6581 AscStartQueueExe(iop_base);
6582 }
6583 }
6584 asc_dvc->unit_not_ready = saved_unit_not_ready;
6585 return (sta);
6586 }
6587
6588 int
6589 AscResetDevice(
6590 ASC_DVC_VAR asc_ptr_type * asc_dvc,
6591 uchar target_ix
6592 )
6593 {
6594 PortAddr iop_base;
6595 int sta;
6596 uchar tid_no;
6597 ASC_SCSI_BIT_ID_TYPE target_id;
6598 int i;
6599 ASC_SCSI_REQ_Q scsiq_buf;
6600 ASC_SCSI_REQ_Q dosfar *scsiq;
6601 uchar dosfar *buf;
6602 ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
6603
6604 iop_base = asc_dvc->iop_base;
6605 tid_no = ASC_TIX_TO_TID(target_ix);
6606 target_id = ASC_TID_TO_TARGET_ID(tid_no);
6607 saved_unit_not_ready = asc_dvc->unit_not_ready;
6608 asc_dvc->unit_not_ready = target_id;
6609 sta = ERR;
6610 AscWaitTixISRDone(asc_dvc, target_ix);
6611 if (AscStopQueueExe(iop_base) == 1) {
6612 if (AscRiscHaltedAbortTIX(asc_dvc, target_ix) == 1) {
6613
6614 AscCleanUpBusyQueue(iop_base);
6615 AscStartQueueExe(iop_base);
6616
6617 AscWaitTixISRDone(asc_dvc, target_ix);
6618
6619 sta = TRUE;
6620 scsiq = (ASC_SCSI_REQ_Q dosfar *) & scsiq_buf;
6621 buf = (uchar dosfar *) & scsiq_buf;
6622 for (i = 0; i < sizeof (ASC_SCSI_REQ_Q); i++) {
6623 *buf++ = 0x00;
6624 }
6625
6626 scsiq->r1.status = (uchar) QS_READY;
6627 scsiq->r2.cdb_len = 6;
6628 scsiq->r2.tag_code = M2_QTAG_MSG_SIMPLE;
6629 scsiq->r1.target_id = target_id;
6630
6631 scsiq->r2.target_ix = ASC_TIDLUN_TO_IX(tid_no, 0);
6632 scsiq->cdbptr = (uchar dosfar *) scsiq->cdb;
6633
6634 scsiq->r1.cntl = QC_NO_CALLBACK | QC_MSG_OUT | QC_URGENT;
6635 AscWriteLramByte(asc_dvc->iop_base, ASCV_MSGOUT_BEG,
6636 M1_BUS_DVC_RESET);
6637
6638 asc_dvc->unit_not_ready &= ~target_id;
6639
6640 asc_dvc->sdtr_done |= target_id;
6641
6642 if (AscExeScsiQueue(asc_dvc, (ASC_SCSI_Q dosfar *) scsiq)
6643 == 1) {
6644 asc_dvc->unit_not_ready = target_id;
6645 DvcSleepMilliSecond(1000);
6646 _AscWaitQDone(iop_base, (ASC_SCSI_Q dosfar *) scsiq);
6647 if (AscStopQueueExe(iop_base) == 1) {
6648
6649 AscCleanUpDiscQueue(iop_base);
6650 AscStartQueueExe(iop_base);
6651 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
6652
6653 AscSetRunChipSynRegAtID(iop_base, tid_no,
6654 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
6655 }
6656 AscWaitTixISRDone(asc_dvc, target_ix);
6657 }
6658 } else {
6659
6660 sta = 0;
6661 }
6662
6663 asc_dvc->sdtr_done &= ~target_id;
6664 } else {
6665 sta = ERR;
6666 AscStartQueueExe(iop_base);
6667 }
6668 }
6669 asc_dvc->unit_not_ready = saved_unit_not_ready;
6670 return (sta);
6671 }
6672
6673 int
6674 AscResetSB(
6675 ASC_DVC_VAR asc_ptr_type * asc_dvc
6676 )
6677 {
6678 int sta;
6679 int i;
6680 PortAddr iop_base;
6681
6682 iop_base = asc_dvc->iop_base;
6683 asc_dvc->unit_not_ready = 0xFF;
6684 sta = TRUE;
6685 AscWaitISRDone(asc_dvc);
6686 AscStopQueueExe(iop_base);
6687
6688 asc_dvc->sdtr_done = 0;
6689 AscResetChipAndScsiBus(iop_base);
6690
6691 DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
6692
6693 #if CC_SCAM
6694 if (!(asc_dvc->dvc_cntl & ASC_CNTL_NO_SCAM)) {
6695 AscSCAM(asc_dvc);
6696 }
6697 #endif
6698 AscReInitLram(asc_dvc);
6699
6700 for (i = 0; i <= ASC_MAX_TID; i++) {
6701 asc_dvc->cur_dvc_qng[i] = 0;
6702 if (asc_dvc->pci_fix_asyn_xfer & (0x01 << i)) {
6703
6704 AscSetChipSynRegAtID(iop_base, i, ASYN_SDTR_DATA_FIX_PCI_REV_AB);
6705 }
6706 }
6707
6708 asc_dvc->err_code = 0;
6709
6710 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
6711 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
6712 sta = ERR;
6713 }
6714 if (AscStartChip(iop_base) == 0) {
6715 sta = ERR;
6716 }
6717 AscStartQueueExe(iop_base);
6718 asc_dvc->unit_not_ready = 0;
6719 asc_dvc->queue_full_or_busy = 0;
6720 return (sta);
6721 }
6722
6723 int
6724 AscSetRunChipSynRegAtID(
6725 PortAddr iop_base,
6726 uchar tid_no,
6727 uchar sdtr_data
6728 )
6729 {
6730 int sta = FALSE;
6731
6732 if (AscHostReqRiscHalt(iop_base)) {
6733 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
6734
6735 AscStartChip(iop_base);
6736 return (sta);
6737 }
6738 return (sta);
6739 }
6740
6741 int
6742 AscSetChipSynRegAtID(
6743 PortAddr iop_base,
6744 uchar id,
6745 uchar sdtr_data
6746 )
6747 {
6748 AscSetBank(iop_base, 1);
6749 AscWriteChipScsiID(iop_base, id);
6750 if (AscReadChipScsiID(iop_base) != (0x01 << id)) {
6751 return (FALSE);
6752 }
6753 AscSetBank(iop_base, 0);
6754 AscWriteChipSyn(iop_base, sdtr_data);
6755 if (AscReadChipSyn(iop_base) != sdtr_data) {
6756 return (FALSE);
6757 }
6758 return (TRUE);
6759 }
6760
6761 int
6762 AscReInitLram(
6763 ASC_DVC_VAR asc_ptr_type * asc_dvc
6764 )
6765 {
6766 AscInitLram(asc_dvc);
6767 AscInitQLinkVar(asc_dvc);
6768 return (0);
6769 }
6770
6771 ushort
6772 AscInitLram(
6773 ASC_DVC_VAR asc_ptr_type * asc_dvc)
6774 {
6775 uchar i;
6776 ushort s_addr;
6777 PortAddr iop_base;
6778 ushort warn_code;
6779
6780 iop_base = asc_dvc->iop_base;
6781 warn_code = 0;
6782
6783 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
6784 (ushort) (((int) (asc_dvc->max_total_qng + 2 + 1) * 64) >> 1)
6785 );
6786
6787 i = ASC_MIN_ACTIVE_QNO;
6788 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
6789
6790 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
6791 (uchar) (i + 1));
6792 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
6793 (uchar) (asc_dvc->max_total_qng));
6794 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
6795 (uchar) i);
6796 i++;
6797 s_addr += ASC_QBLK_SIZE;
6798 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
6799 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
6800 (uchar) (i + 1));
6801 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
6802 (uchar) (i - 1));
6803 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
6804 (uchar) i);
6805 }
6806
6807 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
6808 (uchar) ASC_QLINK_END);
6809 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
6810 (uchar) (asc_dvc->max_total_qng - 1));
6811 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
6812 (uchar) asc_dvc->max_total_qng);
6813 i++;
6814 s_addr += ASC_QBLK_SIZE;
6815
6816 for (; i <= (uchar) (asc_dvc->max_total_qng + 3);
6817 i++, s_addr += ASC_QBLK_SIZE) {
6818
6819 AscWriteLramByte(iop_base,
6820 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_FWD), i);
6821 AscWriteLramByte(iop_base,
6822 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_BWD), i);
6823 AscWriteLramByte(iop_base,
6824 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_QNO), i);
6825 }
6826
6827 return (warn_code);
6828 }
6829
6830 ushort
6831 AscInitQLinkVar(
6832 ASC_DVC_VAR asc_ptr_type * asc_dvc
6833 )
6834 {
6835 PortAddr iop_base;
6836 int i;
6837 ushort lram_addr;
6838
6839 iop_base = asc_dvc->iop_base;
6840 AscPutRiscVarFreeQHead(iop_base, 1);
6841 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
6842
6843 AscPutVarFreeQHead(iop_base, 1);
6844 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
6845
6846 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
6847 (uchar) ((int) asc_dvc->max_total_qng + 1));
6848 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
6849 (uchar) ((int) asc_dvc->max_total_qng + 2));
6850
6851 AscWriteLramByte(iop_base, (ushort) ASCV_TOTAL_READY_Q_B,
6852 asc_dvc->max_total_qng);
6853
6854 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
6855 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6856 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
6857 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
6858 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
6859
6860 AscWriteLramByte(iop_base, (ushort) ASCV_CDBCNT_B, 0);
6861
6862 lram_addr = ASC_QADR_BEG;
6863 for (i = 0; i < 32; i++, lram_addr += 2) {
6864 AscWriteLramWord(iop_base, lram_addr, 0);
6865 }
6866
6867 return (0);
6868 }
6869
6870 int
6871 AscSetLibErrorCode(
6872 ASC_DVC_VAR asc_ptr_type * asc_dvc,
6873 ushort err_code
6874 )
6875 {
6876 if (asc_dvc->err_code == 0) {
6877
6878 asc_dvc->err_code = err_code;
6879 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
6880 err_code);
6881 }
6882 return (err_code);
6883 }
6884
6885 int
6886 _AscWaitQDone(
6887 PortAddr iop_base,
6888 ASC_SCSI_Q dosfar * scsiq
6889 )
6890 {
6891 ushort q_addr;
6892 uchar q_status;
6893 int count = 0;
6894
6895 while (scsiq->q1.q_no == 0) ;
6896 q_addr = ASC_QNO_TO_QADDR(scsiq->q1.q_no);
6897
6898 do {
6899 q_status = AscReadLramByte(iop_base, q_addr + ASC_SCSIQ_B_STATUS);
6900 DvcSleepMilliSecond(100L);
6901 if (count++ > 30) {
6902 return (0);
6903 }
6904 } while ((q_status & QS_READY) != 0);
6905 return (1);
6906 }
6907
6908 uchar _sdtr_period_tbl_[ASC_SYN_XFER_NO] =
6909 {
6910 SYN_XFER_NS_0,
6911 SYN_XFER_NS_1,
6912 SYN_XFER_NS_2,
6913 SYN_XFER_NS_3,
6914 SYN_XFER_NS_4,
6915 SYN_XFER_NS_5,
6916 SYN_XFER_NS_6,
6917 SYN_XFER_NS_7};
6918
6919 uchar
6920 AscMsgOutSDTR(
6921 PortAddr iop_base,
6922 uchar sdtr_period,
6923 uchar sdtr_offset
6924 )
6925 {
6926 SDTR_XMSG sdtr_buf;
6927 uchar sdtr_period_index;
6928
6929 sdtr_buf.msg_type = MS_EXTEND;
6930 sdtr_buf.msg_len = MS_SDTR_LEN;
6931 sdtr_buf.msg_req = MS_SDTR_CODE;
6932 sdtr_buf.xfer_period = sdtr_period;
6933 sdtr_offset &= ASC_SYN_MAX_OFFSET;
6934 sdtr_buf.req_ack_offset = sdtr_offset;
6935 AscMemWordCopyToLram(iop_base, ASCV_MSGOUT_BEG,
6936 (ushort dosfar *) & sdtr_buf, SYN_XMSG_WLEN);
6937 if ((sdtr_period_index = AscGetSynPeriodIndex(sdtr_period)) <=
6938 ASC_MAX_SDTR_PERIOD_INDEX) {
6939 return ((sdtr_period_index << 4) | sdtr_offset);
6940 } else {
6941
6942 return (0);
6943 }
6944 }
6945
6946 uchar
6947 AscCalSDTRData(
6948 uchar sdtr_period,
6949 uchar syn_offset
6950 )
6951 {
6952 uchar byte;
6953 uchar sdtr_period_ix;
6954
6955 sdtr_period_ix = AscGetSynPeriodIndex(sdtr_period);
6956 if ((sdtr_period_ix > ASC_MAX_SDTR_PERIOD_INDEX) ||
6957 (sdtr_period_ix > ASC_SDTR_PERIOD_IX_MIN)) {
6958 return (0xFF);
6959 }
6960 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
6961 return (byte);
6962 }
6963
6964 void
6965 AscSetChipSDTR(
6966 PortAddr iop_base,
6967 uchar sdtr_data,
6968 uchar tid_no
6969 )
6970 {
6971
6972 AscWriteChipSyn(iop_base, sdtr_data);
6973 AscWriteLramByte(iop_base,
6974 (ushort) ((ushort) ASCV_SDTR_DONE_BEG + (ushort) tid_no),
6975 sdtr_data);
6976 return;
6977 }
6978
6979 uchar
6980 AscGetSynPeriodIndex(
6981 uchar syn_time
6982 )
6983 {
6984 if ((syn_time >= SYN_XFER_NS_0) && (syn_time <= SYN_XFER_NS_7)) {
6985 if (syn_time <= SYN_XFER_NS_6) {
6986 if (syn_time <= SYN_XFER_NS_5) {
6987 if (syn_time <= SYN_XFER_NS_4) {
6988 if (syn_time <= SYN_XFER_NS_3) {
6989 if (syn_time <= SYN_XFER_NS_2) {
6990 if (syn_time <= SYN_XFER_NS_1) {
6991 if (syn_time <= SYN_XFER_NS_0) {
6992 return (0);
6993 } else
6994 return (1);
6995 } else {
6996 return (2);
6997 }
6998 } else {
6999 return (3);
7000 }
7001 } else {
7002 return (4);
7003 }
7004 } else {
7005 return (5);
7006 }
7007 } else {
7008 return (6);
7009 }
7010 } else {
7011 return (7);
7012 }
7013 } else {
7014
7015 return (8);
7016 }
7017 }
7018
7019 uchar
7020 AscAllocFreeQueue(
7021 PortAddr iop_base,
7022 uchar free_q_head
7023 )
7024 {
7025 ushort q_addr;
7026 uchar next_qp;
7027 uchar q_status;
7028
7029 q_addr = ASC_QNO_TO_QADDR(free_q_head);
7030 q_status = (uchar) AscReadLramByte(iop_base,
7031 (ushort) (q_addr + ASC_SCSIQ_B_STATUS));
7032 next_qp = AscReadLramByte(iop_base,
7033 (ushort) (q_addr + ASC_SCSIQ_B_FWD));
7034 if (((q_status & QS_READY) == 0) &&
7035 (next_qp != ASC_QLINK_END)) {
7036 return (next_qp);
7037 }
7038 return (ASC_QLINK_END);
7039 }
7040
7041 uchar
7042 AscAllocMultipleFreeQueue(
7043 PortAddr iop_base,
7044 uchar free_q_head,
7045 uchar n_free_q
7046 )
7047 {
7048 uchar i;
7049
7050 for (i = 0; i < n_free_q; i++) {
7051 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
7052 == ASC_QLINK_END) {
7053 return (ASC_QLINK_END);
7054 }
7055 }
7056 return (free_q_head);
7057 }
7058
7059 int
7060 AscRiscHaltedAbortSRB(
7061 ASC_DVC_VAR asc_ptr_type * asc_dvc,
7062 ulong srb_ptr
7063 )
7064 {
7065 PortAddr iop_base;
7066 ushort q_addr;
7067 uchar q_no;
7068 ASC_QDONE_INFO scsiq_buf;
7069 ASC_QDONE_INFO dosfar *scsiq;
7070 ASC_ISR_CALLBACK asc_isr_callback;
7071 int last_int_level;
7072
7073 iop_base = asc_dvc->iop_base;
7074 asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
7075 last_int_level = DvcEnterCritical();
7076 scsiq = (ASC_QDONE_INFO dosfar *) & scsiq_buf;
7077
7078 #if CC_LINK_BUSY_Q
7079 _AscAbortSrbBusyQueue(asc_dvc, scsiq, srb_ptr);
7080 #endif
7081
7082 for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= asc_dvc->max_total_qng;
7083 q_no++) {
7084 q_addr = ASC_QNO_TO_QADDR(q_no);
7085 scsiq->d2.srb_ptr = AscReadLramDWord(iop_base,
7086 (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR));
7087 if (scsiq->d2.srb_ptr == srb_ptr) {
7088 _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
7089 if (((scsiq->q_status & QS_READY) != 0) &&
7090 ((scsiq->q_status & QS_ABORTED) == 0) &&
7091 ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0)) {
7092
7093 scsiq->q_status |= QS_ABORTED;
7094 scsiq->d3.done_stat = QD_ABORTED_BY_HOST;
7095 AscWriteLramDWord(iop_base,
7096 (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR),
7097 0L);
7098 AscWriteLramByte(iop_base,
7099 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
7100 scsiq->q_status);
7101 (*asc_isr_callback) (asc_dvc, scsiq);
7102 return (1);
7103 }
7104 }
7105 }
7106 DvcLeaveCritical(last_int_level);
7107 return (0);
7108 }
7109
7110 int
7111 AscRiscHaltedAbortTIX(
7112 ASC_DVC_VAR asc_ptr_type * asc_dvc,
7113 uchar target_ix
7114 )
7115 {
7116 PortAddr iop_base;
7117 ushort q_addr;
7118 uchar q_no;
7119 ASC_QDONE_INFO scsiq_buf;
7120 ASC_QDONE_INFO dosfar *scsiq;
7121 ASC_ISR_CALLBACK asc_isr_callback;
7122 int last_int_level;
7123
7124 #if CC_LINK_BUSY_Q
7125 uchar tid_no;
7126
7127 #endif
7128
7129 iop_base = asc_dvc->iop_base;
7130 asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
7131 last_int_level = DvcEnterCritical();
7132 scsiq = (ASC_QDONE_INFO dosfar *) & scsiq_buf;
7133
7134 #if CC_LINK_BUSY_Q
7135
7136 tid_no = ASC_TIX_TO_TID(target_ix);
7137 _AscAbortTidBusyQueue(asc_dvc, scsiq, tid_no);
7138
7139 #endif
7140
7141 for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= asc_dvc->max_total_qng;
7142 q_no++) {
7143 q_addr = ASC_QNO_TO_QADDR(q_no);
7144 _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
7145 if (((scsiq->q_status & QS_READY) != 0) &&
7146 ((scsiq->q_status & QS_ABORTED) == 0) &&
7147 ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0)) {
7148 if (scsiq->d2.target_ix == target_ix) {
7149 scsiq->q_status |= QS_ABORTED;
7150 scsiq->d3.done_stat = QD_ABORTED_BY_HOST;
7151
7152 AscWriteLramDWord(iop_base,
7153 (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR),
7154 0L);
7155
7156 AscWriteLramByte(iop_base,
7157 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
7158 scsiq->q_status);
7159 (*asc_isr_callback) (asc_dvc, scsiq);
7160 }
7161 }
7162 }
7163 DvcLeaveCritical(last_int_level);
7164 return (1);
7165 }
7166
7167 #if CC_LINK_BUSY_Q
7168
7169 #endif
7170
7171 int
7172 AscHostReqRiscHalt(
7173 PortAddr iop_base
7174 )
7175 {
7176 int count = 0;
7177 int sta = 0;
7178 uchar saved_stop_code;
7179
7180 if (AscIsChipHalted(iop_base))
7181 return (1);
7182 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
7183
7184 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
7185 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP
7186 );
7187 do {
7188 if (AscIsChipHalted(iop_base)) {
7189 sta = 1;
7190 break;
7191 }
7192 DvcSleepMilliSecond(100);
7193 } while (count++ < 20);
7194
7195 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
7196 return (sta);
7197 }
7198
7199 int
7200 AscStopQueueExe(
7201 PortAddr iop_base
7202 )
7203 {
7204 int count;
7205
7206 count = 0;
7207 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
7208 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
7209 ASC_STOP_REQ_RISC_STOP);
7210 do {
7211 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
7212 ASC_STOP_ACK_RISC_STOP) {
7213 return (1);
7214 }
7215 DvcSleepMilliSecond(100);
7216 } while (count++ < 20);
7217 }
7218 return (0);
7219 }
7220
7221 int
7222 AscStartQueueExe(
7223 PortAddr iop_base
7224 )
7225 {
7226 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
7227 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
7228 }
7229 return (1);
7230 }
7231
7232 int
7233 AscCleanUpBusyQueue(
7234 PortAddr iop_base
7235 )
7236 {
7237 int count;
7238 uchar stop_code;
7239
7240 count = 0;
7241 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
7242 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
7243 ASC_STOP_CLEAN_UP_BUSY_Q);
7244 do {
7245 stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
7246 if ((stop_code & ASC_STOP_CLEAN_UP_BUSY_Q) == 0)
7247 break;
7248 DvcSleepMilliSecond(100);
7249 } while (count++ < 20);
7250 }
7251 return (1);
7252 }
7253
7254 int
7255 AscCleanUpDiscQueue(
7256 PortAddr iop_base
7257 )
7258 {
7259 int count;
7260 uchar stop_code;
7261
7262 count = 0;
7263 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
7264 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
7265 ASC_STOP_CLEAN_UP_DISC_Q);
7266 do {
7267 stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
7268 if ((stop_code & ASC_STOP_CLEAN_UP_DISC_Q) == 0)
7269 break;
7270 DvcSleepMilliSecond(100);
7271 } while (count++ < 20);
7272 }
7273 return (1);
7274 }
7275
7276 int
7277 AscWaitTixISRDone(
7278 ASC_DVC_VAR asc_ptr_type * asc_dvc,
7279 uchar target_ix
7280 )
7281 {
7282 uchar cur_req;
7283 uchar tid_no;
7284
7285 tid_no = ASC_TIX_TO_TID(target_ix);
7286 while (TRUE) {
7287 if ((cur_req = asc_dvc->cur_dvc_qng[tid_no]) == 0) {
7288 break;
7289 }
7290 DvcSleepMilliSecond(1000L);
7291 if (asc_dvc->cur_dvc_qng[tid_no] == cur_req) {
7292 break;
7293 }
7294 }
7295 return (1);
7296 }
7297
7298 int
7299 AscWaitISRDone(
7300 ASC_DVC_VAR asc_ptr_type * asc_dvc
7301 )
7302 {
7303 int tid;
7304
7305 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
7306 AscWaitTixISRDone(asc_dvc, ASC_TID_TO_TIX(tid));
7307 }
7308 return (1);
7309 }
7310
7311 ulong
7312 AscGetOnePhyAddr(
7313 ASC_DVC_VAR asc_ptr_type * asc_dvc,
7314 uchar dosfar * buf_addr,
7315 ulong buf_size
7316 )
7317 {
7318 ASC_MIN_SG_HEAD sg_head;
7319
7320 sg_head.entry_cnt = ASC_MIN_SG_LIST;
7321 if (DvcGetSGList(asc_dvc, (uchar dosfar *) buf_addr,
7322 buf_size, (ASC_SG_HEAD dosfar *) & sg_head) != buf_size) {
7323 return (0L);
7324 }
7325 if (sg_head.entry_cnt > 1) {
7326 return (0L);
7327 }
7328 return (sg_head.sg_list[0].addr);
7329 }
7330
7331 ulong
7332 AscGetEisaProductID(
7333 PortAddr iop_base
7334 )
7335 {
7336 PortAddr eisa_iop;
7337 ushort product_id_high, product_id_low;
7338 ulong product_id;
7339
7340 eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK;
7341 product_id_low = inpw(eisa_iop);
7342 product_id_high = inpw(eisa_iop + 2);
7343 product_id = ((ulong) product_id_high << 16) | (ulong) product_id_low;
7344 return (product_id);
7345 }
7346
7347 PortAddr
7348 AscSearchIOPortAddrEISA(
7349 PortAddr iop_base
7350 )
7351 {
7352 ulong eisa_product_id;
7353
7354 if (iop_base == 0) {
7355 iop_base = ASC_EISA_MIN_IOP_ADDR;
7356 } else {
7357 if (iop_base == ASC_EISA_MAX_IOP_ADDR)
7358 return (0);
7359 if ((iop_base & 0x0050) == 0x0050) {
7360 iop_base += ASC_EISA_BIG_IOP_GAP;
7361 } else {
7362 iop_base += ASC_EISA_SMALL_IOP_GAP;
7363 }
7364 }
7365 while (iop_base <= ASC_EISA_MAX_IOP_ADDR) {
7366
7367 eisa_product_id = AscGetEisaProductID(iop_base);
7368 if ((eisa_product_id == ASC_EISA_ID_740) ||
7369 (eisa_product_id == ASC_EISA_ID_750)) {
7370 if (AscFindSignature(iop_base)) {
7371
7372 inpw(iop_base + 4);
7373 return (iop_base);
7374 }
7375 }
7376 if (iop_base == ASC_EISA_MAX_IOP_ADDR)
7377 return (0);
7378 if ((iop_base & 0x0050) == 0x0050) {
7379 iop_base += ASC_EISA_BIG_IOP_GAP;
7380 } else {
7381 iop_base += ASC_EISA_SMALL_IOP_GAP;
7382 }
7383 }
7384 return (0);
7385 }
7386
7387 int
7388 AscStartChip(
7389 PortAddr iop_base
7390 )
7391 {
7392 AscSetChipControl(iop_base, 0);
7393 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
7394 return (0);
7395 }
7396 return (1);
7397 }
7398
7399 int
7400 AscStopChip(
7401 PortAddr iop_base
7402 )
7403 {
7404 uchar cc_val;
7405
7406 cc_val = AscGetChipControl(iop_base) & (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
7407 AscSetChipControl(iop_base, (uchar) (cc_val | CC_HALT));
7408 AscSetChipIH(iop_base, INS_HALT);
7409 AscSetChipIH(iop_base, INS_RFLAG_WTM);
7410 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
7411 return (0);
7412 }
7413 return (1);
7414 }
7415
7416 int
7417 AscIsChipHalted(
7418 PortAddr iop_base
7419 )
7420 {
7421
7422 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
7423 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
7424 return (1);
7425 }
7426 }
7427 return (0);
7428 }
7429
7430 void
7431 AscSetChipIH(
7432 PortAddr iop_base,
7433 ushort ins_code
7434 )
7435 {
7436 AscSetBank(iop_base, 1);
7437 AscWriteChipIH(iop_base, ins_code);
7438 AscSetBank(iop_base, 0);
7439 return;
7440 }
7441
7442 void
7443 AscAckInterrupt(
7444 PortAddr iop_base
7445 )
7446 {
7447
7448 uchar host_flag;
7449 uchar risc_flag;
7450 ushort loop;
7451
7452 loop = 0;
7453 do {
7454 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
7455 if (loop++ > 0x7FFF) {
7456 break;
7457 }
7458 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
7459
7460 host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B);
7461 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
7462 (uchar) (host_flag | ASC_HOST_FLAG_ACK_INT));
7463
7464 AscSetChipStatus(iop_base, CIW_INT_ACK);
7465 loop = 0;
7466 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
7467
7468 AscSetChipStatus(iop_base, CIW_INT_ACK);
7469 if (loop++ > 3) {
7470 break;
7471 }
7472 }
7473
7474 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
7475 return;
7476 }
7477
7478 void
7479 AscDisableInterrupt(
7480 PortAddr iop_base
7481 )
7482 {
7483 ushort cfg;
7484
7485 cfg = AscGetChipCfgLsw(iop_base);
7486 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
7487 return;
7488 }
7489
7490 void
7491 AscEnableInterrupt(
7492 PortAddr iop_base
7493 )
7494 {
7495 ushort cfg;
7496
7497 cfg = AscGetChipCfgLsw(iop_base);
7498 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
7499 return;
7500 }
7501
7502 void
7503 AscSetBank(
7504 PortAddr iop_base,
7505 uchar bank
7506 )
7507 {
7508 uchar val;
7509
7510 val = AscGetChipControl(iop_base) &
7511 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | CC_CHIP_RESET));
7512 if (bank == 1) {
7513 val |= CC_BANK_ONE;
7514 } else if (bank == 2) {
7515 val |= CC_DIAG | CC_BANK_ONE;
7516 } else {
7517 val &= ~CC_BANK_ONE;
7518 }
7519 AscSetChipControl(iop_base, val);
7520 return;
7521 }
7522
7523 int
7524 AscResetChipAndScsiBus(
7525 PortAddr iop_base
7526 )
7527 {
7528 AscStopChip(iop_base);
7529 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
7530 DvcSleepMilliSecond(200);
7531
7532 AscSetChipIH(iop_base, INS_RFLAG_WTM);
7533 AscSetChipIH(iop_base, INS_HALT);
7534
7535 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
7536 AscSetChipControl(iop_base, CC_HALT);
7537 DvcSleepMilliSecond(200);
7538 return (AscIsChipHalted(iop_base));
7539 }
7540
7541 ushort
7542 AscGetIsaDmaChannel(
7543 PortAddr iop_base
7544 )
7545 {
7546 ushort channel;
7547
7548 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
7549 if (channel == 0x03)
7550 return (0);
7551 else if (channel == 0x00)
7552 return (7);
7553 return (channel + 4);
7554 }
7555
7556 ushort
7557 AscSetIsaDmaChannel(
7558 PortAddr iop_base,
7559 ushort dma_channel
7560 )
7561 {
7562 ushort cfg_lsw;
7563 uchar value;
7564
7565 if ((dma_channel >= 5) && (dma_channel <= 7)) {
7566
7567 if (dma_channel == 7)
7568 value = 0x00;
7569 else
7570 value = dma_channel - 4;
7571 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
7572 cfg_lsw |= value;
7573 AscSetChipCfgLsw(iop_base, cfg_lsw);
7574 return (AscGetIsaDmaChannel(iop_base));
7575 }
7576 return (0);
7577 }
7578
7579 uchar
7580 AscSetIsaDmaSpeed(
7581 PortAddr iop_base,
7582 uchar speed_value
7583 )
7584 {
7585 speed_value &= 0x07;
7586 AscSetBank(iop_base, 1);
7587 AscSetChipDmaSpeed(iop_base, speed_value);
7588 AscSetBank(iop_base, 0);
7589 return (AscGetIsaDmaSpeed(iop_base));
7590 }
7591
7592 uchar
7593 AscGetIsaDmaSpeed(
7594 PortAddr iop_base
7595 )
7596 {
7597 uchar speed_value;
7598
7599 AscSetBank(iop_base, 1);
7600 speed_value = AscGetChipDmaSpeed(iop_base);
7601 speed_value &= 0x07;
7602 AscSetBank(iop_base, 0);
7603 return (speed_value);
7604 }
7605
7606 ulong
7607 AscGetMaxDmaCount(
7608 ushort bus_type
7609 )
7610 {
7611 if (bus_type & ASC_IS_ISA)
7612 return (ASC_MAX_ISA_DMA_COUNT);
7613 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
7614 return (ASC_MAX_VL_DMA_COUNT);
7615 return (ASC_MAX_PCI_DMA_COUNT);
7616 }
7617
7618 ushort
7619 AscInitGetConfig(
7620 ASC_DVC_VAR asc_ptr_type * asc_dvc
7621 )
7622 {
7623 ushort warn_code;
7624
7625 warn_code = 0;
7626 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
7627 if (asc_dvc->err_code != 0)
7628 return (UW_ERR);
7629 if (AscFindSignature(asc_dvc->iop_base)) {
7630 warn_code |= AscInitAscDvcVar(asc_dvc);
7631 warn_code |= AscInitFromEEP(asc_dvc);
7632 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
7633
7634 if (asc_dvc->scsi_reset_wait > 10)
7635 asc_dvc->scsi_reset_wait = 10;
7636
7637 } else {
7638 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
7639 }
7640 return (warn_code);
7641 }
7642
7643 ushort
7644 AscInitSetConfig(
7645 ASC_DVC_VAR asc_ptr_type * asc_dvc
7646 )
7647 {
7648 ushort warn_code;
7649
7650 warn_code = 0;
7651 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
7652 if (asc_dvc->err_code != 0)
7653 return (UW_ERR);
7654 if (AscFindSignature(asc_dvc->iop_base)) {
7655 warn_code |= AscInitFromAscDvcVar(asc_dvc);
7656 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
7657 } else {
7658 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
7659 }
7660 return (warn_code);
7661 }
7662
7663 ushort
7664 AscInitAsc1000Driver(
7665 ASC_DVC_VAR asc_ptr_type * asc_dvc
7666 )
7667 {
7668 ushort warn_code;
7669 PortAddr iop_base;
7670
7671 extern ushort _mcode_size;
7672 extern ulong _mcode_chksum;
7673 extern uchar _mcode_buf[];
7674
7675 ASC_DBG(3, "AscInitAsc1000Driver: begin\n");
7676 iop_base = asc_dvc->iop_base;
7677 warn_code = 0;
7678
7679 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
7680 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
7681
7682 ASC_DBG(3, "AscInitAsc1000Driver: AscResetChipAndScsiBus()\n");
7683 AscResetChipAndScsiBus(iop_base);
7684 DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
7685 }
7686 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
7687 if (asc_dvc->err_code != 0)
7688 return (UW_ERR);
7689 ASC_DBG(3, "AscInitAsc1000Driver: AscFindSignature()\n");
7690 if (!AscFindSignature(asc_dvc->iop_base)) {
7691 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
7692 return (warn_code);
7693 }
7694 ASC_DBG(3, "AscInitAsc1000Driver: AscDisableInterrupt()\n");
7695 AscDisableInterrupt(iop_base);
7696
7697 ASC_DBG(3, "AscInitAsc1000Driver: AscInitLram()\n");
7698 warn_code |= AscInitLram(asc_dvc);
7699 if (asc_dvc->err_code != 0)
7700 return (UW_ERR);
7701 ASC_DBG(3, "AscInitAsc1000Driver: AscLoadMicroCode()\n");
7702 if (AscLoadMicroCode(iop_base, 0, (ushort dosfar *) _mcode_buf,
7703 _mcode_size) != _mcode_chksum) {
7704 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
7705 return (warn_code);
7706 }
7707 ASC_DBG(3, "AscInitAsc1000Driver: AscInitMicroCodeVar()\n");
7708 warn_code |= AscInitMicroCodeVar(asc_dvc);
7709 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
7710 ASC_DBG(3, "AscInitAsc1000Driver: AscEnableInterrupt()\n");
7711 AscEnableInterrupt(iop_base);
7712 return (warn_code);
7713 }
7714
7715 ushort
7716 AscInitAscDvcVar(
7717 ASC_DVC_VAR asc_ptr_type * asc_dvc
7718 )
7719 {
7720 int i;
7721 PortAddr iop_base;
7722 ushort warn_code;
7723
7724 iop_base = asc_dvc->iop_base;
7725 warn_code = 0;
7726 asc_dvc->err_code = 0;
7727
7728 if ((asc_dvc->bus_type &
7729 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
7730 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
7731 }
7732 #if CC_LINK_BUSY_Q
7733 for (i = 0; i <= ASC_MAX_TID; i++) {
7734 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q dosfar *) 0L;
7735 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q dosfar *) 0L;
7736 }
7737 #endif
7738
7739 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
7740 asc_dvc->bug_fix_cntl = 0;
7741 asc_dvc->pci_fix_asyn_xfer = 0;
7742 asc_dvc->init_sdtr = 0;
7743 asc_dvc->sdtr_done = 0;
7744 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
7745 asc_dvc->cur_total_qng = 0;
7746 asc_dvc->is_in_int = 0;
7747 asc_dvc->scsi_reset_wait = 3;
7748 asc_dvc->in_critical_cnt = 0;
7749
7750 asc_dvc->last_q_shortage = 0;
7751 asc_dvc->use_tagged_qng = 0;
7752 asc_dvc->cfg->can_tagged_qng = 0;
7753 asc_dvc->no_scam = 0;
7754 asc_dvc->irq_no = 10;
7755 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
7756 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
7757 asc_dvc->cfg->cmd_qng_enabled = ASC_SCSI_WIDTH_BIT_SET;
7758 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
7759 asc_dvc->cfg->chip_version = AscGetChipVersion(iop_base,
7760 asc_dvc->bus_type);
7761 if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
7762
7763 AscPutChipIFC(iop_base, IFC_INIT_DEFAULT);
7764 asc_dvc->bus_type = ASC_IS_ISAPNP;
7765 }
7766 asc_dvc->unit_not_ready = 0;
7767 asc_dvc->queue_full_or_busy = 0;
7768
7769 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
7770 asc_dvc->cfg->isa_dma_channel = (uchar) AscGetIsaDmaChannel(iop_base);
7771 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
7772 }
7773 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
7774 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
7775 ASC_LIB_VERSION_MINOR;
7776 asc_dvc->int_count = 0L;
7777 asc_dvc->req_count = 0L;
7778 asc_dvc->busy_count = 0L;
7779 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
7780
7781 for (i = 0; i <= ASC_MAX_TID; i++) {
7782 asc_dvc->cfg->sdtr_data[i] =
7783 (uchar) (ASC_DEF_SDTR_OFFSET | (ASC_DEF_SDTR_INDEX << 4));
7784 asc_dvc->cur_dvc_qng[i] = 0;
7785 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
7786 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q dosfar *) 0L;
7787 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q dosfar *) 0L;
7788 }
7789 return (warn_code);
7790 }
7791
7792 ushort
7793 AscInitFromAscDvcVar(
7794 ASC_DVC_VAR asc_ptr_type * asc_dvc
7795 )
7796 {
7797 PortAddr iop_base;
7798 ushort cfg_msw;
7799 ushort warn_code;
7800
7801 iop_base = asc_dvc->iop_base;
7802 warn_code = 0;
7803
7804 cfg_msw = AscGetChipCfgMsw(iop_base);
7805
7806 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
7807 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
7808 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
7809 AscSetChipCfgMsw(iop_base, cfg_msw);
7810 }
7811 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
7812 warn_code |= ASC_WARN_AUTO_CONFIG;
7813
7814 }
7815 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
7816 asc_dvc->cfg->cmd_qng_enabled) {
7817 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
7818 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
7819 }
7820 if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
7821
7822 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
7823 != asc_dvc->irq_no) {
7824 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
7825 }
7826 }
7827 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
7828 asc_dvc->cfg->chip_scsi_id) {
7829 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
7830 }
7831 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
7832 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
7833 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
7834 }
7835 return (warn_code);
7836 }
7837
7838 ushort
7839 AscInitFromEEP(
7840 ASC_DVC_VAR asc_ptr_type * asc_dvc
7841 )
7842 {
7843 ASCEEP_CONFIG eep_config_buf;
7844 ASCEEP_CONFIG dosfar *eep_config;
7845 PortAddr iop_base;
7846 ushort chksum;
7847 ushort warn_code;
7848 ushort cfg_msw, cfg_lsw;
7849 uchar i;
7850
7851 iop_base = asc_dvc->iop_base;
7852 warn_code = 0;
7853
7854 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
7855
7856 AscStopQueueExe(iop_base);
7857 if ((AscStopChip(iop_base) == FALSE) ||
7858 (AscGetChipScsiCtrl(iop_base) != 0)) {
7859 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
7860 AscResetChipAndScsiBus(iop_base);
7861 DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
7862 }
7863 if (AscIsChipHalted(iop_base) == FALSE) {
7864 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
7865 return (warn_code);
7866 }
7867 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
7868 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
7869 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
7870 return (warn_code);
7871 }
7872 eep_config = (ASCEEP_CONFIG dosfar *) & eep_config_buf;
7873
7874 cfg_msw = AscGetChipCfgMsw(iop_base);
7875 cfg_lsw = AscGetChipCfgLsw(iop_base);
7876
7877 if (asc_dvc->bus_type & ASC_IS_PCI) {
7878 #if CC_DISABLE_PCI_PARITY_INT
7879 cfg_msw &= 0xFFC0;
7880 AscSetChipCfgMsw(iop_base, cfg_msw);
7881 #endif
7882 if (asc_dvc->cfg->pci_device_id == ASC_PCI_DEVICE_ID_REV_A) {
7883 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ADD_ONE_BYTE;
7884 }
7885 }
7886 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
7887 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
7888 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
7889 AscSetChipCfgMsw(iop_base, cfg_msw);
7890 }
7891 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
7892
7893 eep_config->cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
7894
7895 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
7896 warn_code |= ASC_WARN_AUTO_CONFIG;
7897
7898 if (asc_dvc->cfg->chip_version == 3) {
7899
7900 if (eep_config->cfg_lsw != cfg_lsw) {
7901 warn_code |= ASC_WARN_EEPROM_RECOVER;
7902 eep_config->cfg_lsw = AscGetChipCfgLsw(iop_base);
7903 }
7904 if (eep_config->cfg_msw != cfg_msw) {
7905 warn_code |= ASC_WARN_EEPROM_RECOVER;
7906 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
7907 }
7908 }
7909 }
7910 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
7911 if (chksum != eep_config->chksum) {
7912 warn_code |= ASC_WARN_EEPROM_CHKSUM;
7913 }
7914 asc_dvc->init_sdtr = eep_config->init_sdtr;
7915 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
7916
7917 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
7918 asc_dvc->cfg->isa_dma_speed = eep_config->isa_dma_speed;
7919 asc_dvc->start_motor = eep_config->start_motor;
7920 asc_dvc->dvc_cntl = eep_config->cntl;
7921 asc_dvc->no_scam = eep_config->no_scam;
7922
7923 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
7924 !(asc_dvc->dvc_cntl & ASC_CNTL_NO_PCI_FIX_ASYN_XFER)) {
7925 if ((asc_dvc->cfg->pci_device_id == ASC_PCI_DEVICE_ID_REV_A) ||
7926 (asc_dvc->cfg->pci_device_id == ASC_PCI_DEVICE_ID_REV_B)) {
7927 asc_dvc->pci_fix_asyn_xfer = ASC_ALL_DEVICE_BIT_SET;
7928 }
7929 } else if (asc_dvc->bus_type & ASC_IS_ISAPNP) {
7930
7931 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
7932 == ASC_CHIP_VER_ASYN_BUG) {
7933 asc_dvc->pci_fix_asyn_xfer = ASC_ALL_DEVICE_BIT_SET;
7934 }
7935 }
7936 if (!AscTestExternalLram(asc_dvc)) {
7937 if (asc_dvc->bus_type & ASC_IS_PCI) {
7938 eep_config->cfg_msw |= 0x0800;
7939 cfg_msw |= 0x0800;
7940 AscSetChipCfgMsw(iop_base, cfg_msw);
7941 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
7942 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
7943 }
7944 } else {
7945 #if CC_TEST_RW_LRAM
7946 asc_dvc->err_code |= AscTestLramEndian(iop_base);
7947 #endif
7948 }
7949 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
7950 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
7951 }
7952 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
7953 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
7954 }
7955 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
7956 eep_config->max_tag_qng = eep_config->max_total_qng;
7957 }
7958 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
7959 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
7960 }
7961 asc_dvc->max_total_qng = eep_config->max_total_qng;
7962
7963 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
7964 eep_config->use_cmd_qng) {
7965 eep_config->disc_enable = eep_config->use_cmd_qng;
7966 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
7967 }
7968 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
7969 eep_config->chip_scsi_id &= ASC_MAX_TID;
7970 asc_dvc->cfg->chip_scsi_id = eep_config->chip_scsi_id;
7971
7972 for (i = 0; i <= ASC_MAX_TID; i++) {
7973 asc_dvc->cfg->sdtr_data[i] = eep_config->sdtr_data[i];
7974 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
7975 }
7976
7977 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
7978 if (AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type) != 0) {
7979 asc_dvc->err_code |= ASC_IERR_WRITE_EEPROM;
7980 }
7981 return (warn_code);
7982 }
7983
7984 ushort
7985 AscInitMicroCodeVar(
7986 ASC_DVC_VAR asc_ptr_type * asc_dvc
7987 )
7988 {
7989 int i;
7990 ushort warn_code;
7991 PortAddr iop_base;
7992 ulong phy_addr;
7993
7994 iop_base = asc_dvc->iop_base;
7995 warn_code = 0;
7996 for (i = 0; i <= ASC_MAX_TID; i++) {
7997 AscWriteLramByte(iop_base, (ushort) (ASCV_SDTR_DATA_BEG + i),
7998 asc_dvc->cfg->sdtr_data[i]);
7999 }
8000
8001 AscInitQLinkVar(asc_dvc);
8002
8003 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
8004 asc_dvc->cfg->disc_enable);
8005 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
8006 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
8007 if ((phy_addr = AscGetOnePhyAddr(asc_dvc,
8008 (uchar dosfar *) asc_dvc->cfg->overrun_buf,
8009 ASC_OVERRUN_BSIZE)) == 0L) {
8010 asc_dvc->err_code |= ASC_IERR_GET_PHY_ADDR;
8011 } else {
8012
8013 phy_addr = (phy_addr & 0xFFFFFFF8UL) + 8;
8014 AscWriteLramDWord(iop_base, ASCV_OVERRUN_PADDR_D, phy_addr);
8015 AscWriteLramDWord(iop_base, ASCV_OVERRUN_BSIZE_D,
8016 ASC_OVERRUN_BSIZE - 8);
8017 }
8018
8019 asc_dvc->cfg->mcode_date = AscReadLramWord(iop_base,
8020 (ushort) ASCV_MC_DATE_W);
8021 asc_dvc->cfg->mcode_version = AscReadLramWord(iop_base,
8022 (ushort) ASCV_MC_VER_W);
8023 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
8024 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
8025 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
8026 return (warn_code);
8027 }
8028 if (AscStartChip(iop_base) != 1) {
8029 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
8030 return (warn_code);
8031 }
8032 return (warn_code);
8033 }
8034
8035 void dosfar
8036 AscInitPollIsrCallBack(
8037 ASC_DVC_VAR asc_ptr_type * asc_dvc,
8038 ASC_QDONE_INFO dosfar * scsi_done_q
8039 )
8040 {
8041 ASC_SCSI_REQ_Q dosfar *scsiq_req;
8042 ASC_ISR_CALLBACK asc_isr_callback;
8043 uchar cp_sen_len;
8044 uchar i;
8045
8046 if ((scsi_done_q->d2.flag & ASC_FLAG_SCSIQ_REQ) != 0) {
8047 scsiq_req = (ASC_SCSI_REQ_Q dosfar *) scsi_done_q->d2.srb_ptr;
8048 ASC_DBG2(3, "AscInitPollIsrCallBack: done_stat %x, host_stat %x\n",
8049 scsiq_req->r3.done_stat, scsiq_req->r3.host_stat);
8050 scsiq_req->r3.done_stat = scsi_done_q->d3.done_stat;
8051 scsiq_req->r3.host_stat = scsi_done_q->d3.host_stat;
8052 scsiq_req->r3.scsi_stat = scsi_done_q->d3.scsi_stat;
8053 scsiq_req->r3.scsi_msg = scsi_done_q->d3.scsi_msg;
8054 if ((scsi_done_q->d3.scsi_stat == SS_CHK_CONDITION) &&
8055 (scsi_done_q->d3.host_stat == 0)) {
8056 cp_sen_len = (uchar) ASC_MIN_SENSE_LEN;
8057 if (scsiq_req->r1.sense_len < ASC_MIN_SENSE_LEN) {
8058 cp_sen_len = (uchar) scsiq_req->r1.sense_len;
8059 }
8060 for (i = 0; i < cp_sen_len; i++) {
8061 scsiq_req->sense[i] = scsiq_req->sense_ptr[i];
8062 }
8063 }
8064 } else {
8065 ASC_DBG1(3, "AscInitPollIsrCallBack: isr_callback %x\n",
8066 (unsigned) asc_dvc->isr_callback);
8067 if (asc_dvc->isr_callback != 0) {
8068 asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
8069 (*asc_isr_callback) (asc_dvc, scsi_done_q);
8070 }
8071 }
8072 return;
8073 }
8074
8075 int
8076 AscTestExternalLram(
8077 ASC_DVC_VAR asc_ptr_type * asc_dvc
8078 )
8079 {
8080 PortAddr iop_base;
8081 ushort q_addr;
8082 ushort saved_word;
8083 int sta;
8084
8085 iop_base = asc_dvc->iop_base;
8086 sta = 0;
8087
8088 q_addr = ASC_QNO_TO_QADDR(241);
8089 saved_word = AscReadLramWord(iop_base, q_addr);
8090 if (AscVerWriteLramWord(iop_base, q_addr, 0x55AA) == 0) {
8091 sta = 1;
8092 AscWriteLramWord(iop_base, q_addr, saved_word);
8093 }
8094 return (sta);
8095 }
8096
8097 #if CC_TEST_LRAM_ENDIAN
8098
8099 #endif
8100
8101 int
8102 AscWriteEEPCmdReg(
8103 PortAddr iop_base,
8104 uchar cmd_reg
8105 )
8106 {
8107 uchar read_back;
8108 int retry;
8109
8110 retry = 0;
8111 while (TRUE) {
8112 AscSetChipEEPCmd(iop_base, cmd_reg);
8113 DvcSleepMilliSecond(1);
8114 read_back = AscGetChipEEPCmd(iop_base);
8115 if (read_back == cmd_reg) {
8116 return (1);
8117 }
8118 if (retry++ > ASC_EEP_MAX_RETRY) {
8119 return (0);
8120 }
8121 }
8122 }
8123
8124 int
8125 AscWriteEEPDataReg(
8126 PortAddr iop_base,
8127 ushort data_reg
8128 )
8129 {
8130 ushort read_back;
8131 int retry;
8132
8133 retry = 0;
8134 while (TRUE) {
8135 AscSetChipEEPData(iop_base, data_reg);
8136 DvcSleepMilliSecond(1);
8137 read_back = AscGetChipEEPData(iop_base);
8138 if (read_back == data_reg) {
8139 return (1);
8140 }
8141 if (retry++ > ASC_EEP_MAX_RETRY) {
8142 return (0);
8143 }
8144 }
8145 }
8146
8147 void
8148 AscWaitEEPRead(
8149 void
8150 )
8151 {
8152 DvcSleepMilliSecond(1);
8153 return;
8154 }
8155
8156 void
8157 AscWaitEEPWrite(
8158 void
8159 )
8160 {
8161 DvcSleepMilliSecond(20);
8162 return;
8163 }
8164
8165 ushort
8166 AscReadEEPWord(
8167 PortAddr iop_base,
8168 uchar addr
8169 )
8170 {
8171 ushort read_wval;
8172 uchar cmd_reg;
8173
8174 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
8175 AscWaitEEPRead();
8176 cmd_reg = addr | ASC_EEP_CMD_READ;
8177 AscWriteEEPCmdReg(iop_base, cmd_reg);
8178 AscWaitEEPRead();
8179 read_wval = AscGetChipEEPData(iop_base);
8180 AscWaitEEPRead();
8181 return (read_wval);
8182 }
8183
8184 ushort
8185 AscWriteEEPWord(
8186 PortAddr iop_base,
8187 uchar addr,
8188 ushort word_val
8189 )
8190 {
8191 ushort read_wval;
8192
8193 read_wval = AscReadEEPWord(iop_base, addr);
8194 if (read_wval != word_val) {
8195 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
8196 AscWaitEEPRead();
8197
8198 AscWriteEEPDataReg(iop_base, word_val);
8199 AscWaitEEPRead();
8200
8201 AscWriteEEPCmdReg(iop_base,
8202 (uchar) ((uchar) ASC_EEP_CMD_WRITE | addr));
8203 AscWaitEEPWrite();
8204
8205 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
8206 AscWaitEEPRead();
8207 return (AscReadEEPWord(iop_base, addr));
8208 }
8209 return (read_wval);
8210 }
8211
8212 ushort
8213 AscGetEEPConfig(
8214 PortAddr iop_base,
8215 ASCEEP_CONFIG dosfar * cfg_buf, ushort bus_type
8216 )
8217 {
8218 ushort wval;
8219 ushort sum;
8220 ushort dosfar *wbuf;
8221 int cfg_beg;
8222 int cfg_end;
8223 int s_addr;
8224 int isa_pnp_wsize;
8225
8226 wbuf = (ushort dosfar *) cfg_buf;
8227 sum = 0;
8228
8229 isa_pnp_wsize = 0;
8230 for (s_addr = 0; s_addr < (2 + isa_pnp_wsize); s_addr++, wbuf++) {
8231 wval = AscReadEEPWord(iop_base, (uchar) s_addr);
8232 sum += wval;
8233 *wbuf = wval;
8234 }
8235
8236 if (bus_type & ASC_IS_VL) {
8237 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
8238 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
8239 } else {
8240 cfg_beg = ASC_EEP_DVC_CFG_BEG;
8241 cfg_end = ASC_EEP_MAX_DVC_ADDR;
8242 }
8243
8244 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1);
8245 s_addr++, wbuf++) {
8246 wval = AscReadEEPWord(iop_base, (uchar) s_addr);
8247 sum += wval;
8248 *wbuf = wval;
8249 }
8250 *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
8251 return (sum);
8252 }
8253
8254 int
8255 AscSetEEPConfigOnce(
8256 PortAddr iop_base,
8257 ASCEEP_CONFIG dosfar * cfg_buf, ushort bus_type
8258 )
8259 {
8260 int n_error;
8261 ushort dosfar *wbuf;
8262 ushort sum;
8263 int s_addr;
8264 int cfg_beg;
8265 int cfg_end;
8266
8267 wbuf = (ushort dosfar *) cfg_buf;
8268 n_error = 0;
8269 sum = 0;
8270 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
8271 sum += *wbuf;
8272 if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
8273 n_error++;
8274 }
8275 }
8276 if (bus_type & ASC_IS_VL) {
8277 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
8278 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
8279 } else {
8280 cfg_beg = ASC_EEP_DVC_CFG_BEG;
8281 cfg_end = ASC_EEP_MAX_DVC_ADDR;
8282 }
8283 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1);
8284 s_addr++, wbuf++) {
8285 sum += *wbuf;
8286 if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
8287 n_error++;
8288 }
8289 }
8290 *wbuf = sum;
8291 if (sum != AscWriteEEPWord(iop_base, (uchar) s_addr, sum)) {
8292 n_error++;
8293 }
8294 wbuf = (ushort dosfar *) cfg_buf;
8295 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
8296 if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
8297 n_error++;
8298 }
8299 }
8300 for (s_addr = cfg_beg; s_addr <= cfg_end;
8301 s_addr++, wbuf++) {
8302 if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
8303 n_error++;
8304 }
8305 }
8306 return (n_error);
8307 }
8308
8309 int
8310 AscSetEEPConfig(
8311 PortAddr iop_base,
8312 ASCEEP_CONFIG dosfar * cfg_buf, ushort bus_type
8313 )
8314 {
8315 int retry;
8316 int n_error;
8317
8318 retry = 0;
8319 while (TRUE) {
8320 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
8321 bus_type)) == 0) {
8322 break;
8323 }
8324 if (++retry > ASC_EEP_MAX_RETRY) {
8325 break;
8326 }
8327 }
8328 return (n_error);
8329 }
8330
8331 int
8332 AscInitPollBegin(
8333 ASC_DVC_VAR asc_ptr_type * asc_dvc
8334 )
8335 {
8336 PortAddr iop_base;
8337
8338 iop_base = asc_dvc->iop_base;
8339
8340 #if CC_INIT_INQ_DISPLAY
8341 DvcDisplayString((uchar dosfar *) "\r\n");
8342 #endif
8343
8344 AscDisableInterrupt(iop_base);
8345
8346 asc_dvc->init_state |= ASC_INIT_STATE_BEG_INQUIRY;
8347
8348 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B, 0x00);
8349 asc_dvc->use_tagged_qng = 0;
8350 asc_dvc->cfg->can_tagged_qng = 0;
8351 asc_dvc->saved_ptr2func = (ulong) asc_dvc->isr_callback;
8352 asc_dvc->isr_callback = ASC_GET_PTR2FUNC(AscInitPollIsrCallBack);
8353 return (0);
8354 }
8355
8356 int
8357 AscInitPollEnd(
8358 ASC_DVC_VAR asc_ptr_type * asc_dvc
8359 )
8360 {
8361 PortAddr iop_base;
8362 int i;
8363
8364 iop_base = asc_dvc->iop_base;
8365 asc_dvc->isr_callback = (Ptr2Func) asc_dvc->saved_ptr2func;
8366 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
8367 asc_dvc->cfg->disc_enable);
8368 AscWriteLramByte(iop_base, ASCV_USE_TAGGED_QNG_B,
8369 asc_dvc->use_tagged_qng);
8370 AscWriteLramByte(iop_base, ASCV_CAN_TAGGED_QNG_B,
8371 asc_dvc->cfg->can_tagged_qng);
8372
8373 for (i = 0; i <= ASC_MAX_TID; i++) {
8374 AscWriteLramByte(iop_base,
8375 (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG + (ushort) i),
8376 asc_dvc->max_dvc_qng[i]);
8377 }
8378
8379 AscEnableInterrupt(iop_base);
8380
8381 #if CC_INIT_INQ_DISPLAY
8382 DvcDisplayString((uchar dosfar *) "\r\n");
8383 #endif
8384 asc_dvc->init_state |= ASC_INIT_STATE_END_INQUIRY;
8385
8386 return (0);
8387 }
8388
8389 int _asc_wait_slow_device_ = FALSE;
8390
8391 int
8392 AscInitPollTarget(
8393 ASC_DVC_VAR asc_ptr_type * asc_dvc,
8394 ASC_SCSI_REQ_Q dosfar * scsiq,
8395 ASC_SCSI_INQUIRY dosfar * inq,
8396 ASC_CAP_INFO dosfar * cap_info
8397 )
8398 {
8399 uchar tid_no, lun;
8400 uchar dvc_type;
8401 ASC_SCSI_BIT_ID_TYPE tid_bits;
8402 int dvc_found;
8403 int support_read_cap;
8404 int tmp_disable_init_sdtr;
8405 ulong phy_addr;
8406
8407 dvc_found = 0;
8408 tmp_disable_init_sdtr = FALSE;
8409 tid_bits = scsiq->r1.target_id;
8410 lun = scsiq->r1.target_lun;
8411 tid_no = ASC_TIX_TO_TID(scsiq->r2.target_ix);
8412 if ((phy_addr = AscGetOnePhyAddr(asc_dvc,
8413 (uchar dosfar *) scsiq->sense_ptr,
8414 (ulong) scsiq->r1.sense_len)) == 0L) {
8415 return (ERR);
8416 }
8417 scsiq->r1.sense_addr = phy_addr;
8418 if (((asc_dvc->init_sdtr & tid_bits) != 0) &&
8419 ((asc_dvc->sdtr_done & tid_bits) == 0)) {
8420
8421 asc_dvc->init_sdtr &= ~tid_bits;
8422 tmp_disable_init_sdtr = TRUE;
8423 }
8424 ASC_DBG(3, "AscInitPollTarget: PollScsiInquiry()\n");
8425 if (PollScsiInquiry(asc_dvc, scsiq, (uchar dosfar *) inq,
8426 sizeof (ASC_SCSI_INQUIRY)) == 1) {
8427 dvc_found = 1;
8428 support_read_cap = TRUE;
8429 dvc_type = inq->byte0.peri_dvc_type;
8430 if (dvc_type != SCSI_TYPE_UNKNOWN) {
8431 if ((dvc_type != SCSI_TYPE_DASD) &&
8432 (dvc_type != SCSI_TYPE_WORM) &&
8433 (dvc_type != SCSI_TYPE_CDROM) &&
8434 (dvc_type != SCSI_TYPE_OPTMEM)) {
8435 asc_dvc->start_motor &= ~tid_bits;
8436 support_read_cap = FALSE;
8437 }
8438 if ((dvc_type != SCSI_TYPE_DASD) ||
8439 inq->byte1.rmb) {
8440
8441 if (!_asc_wait_slow_device_) {
8442 DvcSleepMilliSecond(3000 - ((int) tid_no * 250));
8443 _asc_wait_slow_device_ = TRUE;
8444 }
8445 }
8446 #if CC_INIT_INQ_DISPLAY
8447 AscDispInquiry(tid_no, lun, inq);
8448 #endif
8449
8450 if (lun == 0) {
8451
8452 if ((inq->byte3.rsp_data_fmt >= 2) ||
8453 (inq->byte2.ansi_apr_ver >= 2)) {
8454
8455 if (inq->byte7.CmdQue) {
8456 asc_dvc->cfg->can_tagged_qng |= tid_bits;
8457 if (asc_dvc->cfg->cmd_qng_enabled & tid_bits) {
8458 asc_dvc->use_tagged_qng |= tid_bits;
8459 asc_dvc->max_dvc_qng[tid_no] =
8460 asc_dvc->cfg->max_tag_qng[tid_no];
8461 }
8462 }
8463 if (!inq->byte7.Sync) {
8464
8465 asc_dvc->init_sdtr &= ~tid_bits;
8466 asc_dvc->sdtr_done &= ~tid_bits;
8467 } else if (tmp_disable_init_sdtr) {
8468
8469 asc_dvc->init_sdtr |= tid_bits;
8470 }
8471 } else {
8472
8473 asc_dvc->init_sdtr &= ~tid_bits;
8474 asc_dvc->sdtr_done &= ~tid_bits;
8475 asc_dvc->use_tagged_qng &= ~tid_bits;
8476 }
8477 }
8478 if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
8479 if (!(asc_dvc->init_sdtr & tid_bits)) {
8480
8481 AscSetRunChipSynRegAtID(asc_dvc->iop_base, tid_no,
8482 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
8483 }
8484 }
8485 ASC_DBG(3, "AscInitPollTarget: InitTestUnitReady()\n");
8486 if (InitTestUnitReady(asc_dvc, scsiq) != 1) {
8487
8488 } else {
8489 if ((cap_info != 0L) && support_read_cap) {
8490 ASC_DBG(3, "AscInitPollTarget: PollScsiReadCapacity()\n");
8491 if (PollScsiReadCapacity(asc_dvc, scsiq,
8492 cap_info) != 1) {
8493 cap_info->lba = 0L;
8494 cap_info->blk_size = 0x0000;
8495 } else {
8496
8497 }
8498 }
8499 }
8500 } else {
8501 asc_dvc->start_motor &= ~tid_bits;
8502 }
8503 } else {
8504
8505 }
8506 return (dvc_found);
8507 }
8508
8509 int
8510 PollQueueDone(
8511 ASC_DVC_VAR asc_ptr_type * asc_dvc,
8512 ASC_SCSI_REQ_Q dosfar * scsiq,
8513 int timeout_sec
8514 )
8515 {
8516 int status;
8517 int retry;
8518
8519 retry = 0;
8520 do {
8521 ASC_DBG(3, "PollQueueDone: AscExeScsiQueue()\n");
8522 if ((status = AscExeScsiQueue(asc_dvc,
8523 (ASC_SCSI_Q dosfar *) scsiq)) == 1) {
8524 ASC_DBG(3, "PollQueueDone: AscPollQDone()\n");
8525 if ((status = AscPollQDone(asc_dvc, scsiq,
8526 timeout_sec)) != 1) {
8527 ASC_DBG1(3, "PollQueueDone: AscPollQDone() status %x\n", status);
8528 if (status == 0x80) {
8529 if (retry++ > ASC_MAX_INIT_BUSY_RETRY) {
8530 break;
8531 }
8532 scsiq->r3.done_stat = 0;
8533 scsiq->r3.host_stat = 0;
8534 scsiq->r3.scsi_stat = 0;
8535 scsiq->r3.scsi_msg = 0;
8536 DvcSleepMilliSecond(100);
8537 continue;
8538 }
8539 scsiq->r3.done_stat = 0;
8540 scsiq->r3.host_stat = 0;
8541 scsiq->r3.scsi_stat = 0;
8542 scsiq->r3.scsi_msg = 0;
8543 ASC_DBG1(3, "PollQueueDone: AscAbortSRB() scsiq %x\n",
8544 (unsigned) scsiq);
8545
8546 AscAbortSRB(asc_dvc, (ulong) scsiq);
8547 }
8548 ASC_DBG1(3, "PollQueueDone: done_stat %x\n", scsiq->r3.done_stat);
8549 return (scsiq->r3.done_stat);
8550 }
8551 } while ((status == 0) || (status == 0x80));
8552 ASC_DBG(3, "PollQueueDone: done_stat QD_WITH_ERROR\n");
8553 return (scsiq->r3.done_stat = QD_WITH_ERROR);
8554 }
8555
8556 int
8557 PollScsiInquiry(
8558 ASC_DVC_VAR asc_ptr_type * asc_dvc,
8559 ASC_SCSI_REQ_Q dosfar * scsiq,
8560 uchar dosfar * buf,
8561 int buf_len
8562 )
8563 {
8564 if (AscScsiInquiry(asc_dvc, scsiq, buf, buf_len) == ERR) {
8565 return (scsiq->r3.done_stat = QD_WITH_ERROR);
8566 }
8567 return (PollQueueDone(asc_dvc, (ASC_SCSI_REQ_Q dosfar *) scsiq, 4));
8568 }
8569
8570 int
8571 PollScsiReadCapacity(
8572 ASC_DVC_VAR asc_ptr_type * asc_dvc,
8573 ASC_SCSI_REQ_Q dosfar * scsiq,
8574 ASC_CAP_INFO dosfar * cap_info
8575 )
8576 {
8577 ASC_CAP_INFO scsi_cap_info;
8578 int status;
8579
8580 if (AscScsiReadCapacity(asc_dvc, scsiq,
8581 (uchar dosfar *) & scsi_cap_info) == ERR) {
8582 return (scsiq->r3.done_stat = QD_WITH_ERROR);
8583 }
8584 status = PollQueueDone(asc_dvc, (ASC_SCSI_REQ_Q dosfar *) scsiq, 8);
8585 if (status == 1) {
8586 #if CC_LITTLE_ENDIAN_HOST
8587 cap_info->lba = (ulong) * swapfarbuf4((uchar dosfar *) & scsi_cap_info.lba);
8588 cap_info->blk_size = (ulong) * swapfarbuf4((uchar dosfar *) & scsi_cap_info.blk_size);
8589 #else
8590 cap_info->lba = scsi_cap_info.lba;
8591 cap_info->blk_size = scsi_cap_info.blk_size;
8592 #endif
8593 return (scsiq->r3.done_stat);
8594 }
8595 return (scsiq->r3.done_stat = QD_WITH_ERROR);
8596 }
8597
8598 ulong dosfar *
8599 swapfarbuf4(
8600 uchar dosfar * buf
8601 )
8602 {
8603 uchar tmp;
8604
8605 tmp = buf[3];
8606 buf[3] = buf[0];
8607 buf[0] = tmp;
8608
8609 tmp = buf[1];
8610 buf[1] = buf[2];
8611 buf[2] = tmp;
8612
8613 return ((ulong dosfar *) buf);
8614 }
8615
8616 int
8617 PollScsiTestUnitReady(
8618 ASC_DVC_VAR asc_ptr_type * asc_dvc,
8619 ASC_SCSI_REQ_Q dosfar * scsiq
8620 )
8621 {
8622 if (AscScsiTestUnitReady(asc_dvc, scsiq) == ERR) {
8623 return (scsiq->r3.done_stat = QD_WITH_ERROR);
8624 }
8625 return (PollQueueDone(asc_dvc, (ASC_SCSI_REQ_Q dosfar *) scsiq, 12));
8626 }
8627
8628 int
8629 PollScsiStartUnit(
8630 ASC_DVC_VAR asc_ptr_type * asc_dvc,
8631 ASC_SCSI_REQ_Q dosfar * scsiq
8632 )
8633 {
8634 if (AscScsiStartStopUnit(asc_dvc, scsiq, 1) == ERR) {
8635 return (scsiq->r3.done_stat = QD_WITH_ERROR);
8636 }
8637 return (PollQueueDone(asc_dvc, (ASC_SCSI_REQ_Q dosfar *) scsiq, 40));
8638 }
8639
8640 int
8641 InitTestUnitReady(
8642 ASC_DVC_VAR asc_ptr_type * asc_dvc,
8643 ASC_SCSI_REQ_Q dosfar * scsiq
8644 )
8645 {
8646 ASC_SCSI_BIT_ID_TYPE tid_bits;
8647 int retry;
8648 ASC_REQ_SENSE dosfar *sen;
8649
8650 retry = 0;
8651 tid_bits = scsiq->r1.target_id;
8652 while (retry++ < 2) {
8653 ASC_DBG(3, "InitTestUnitReady: PollScsiTestUnitReady()\n");
8654 PollScsiTestUnitReady(asc_dvc, scsiq);
8655 ASC_DBG1(3, "InitTestUnitReady: done_stat %x\n", scsiq->r3.done_stat);
8656 if (scsiq->r3.done_stat == 0x01) {
8657 return (1);
8658 } else if (scsiq->r3.done_stat == QD_WITH_ERROR) {
8659 DvcSleepMilliSecond(100);
8660
8661 sen = (ASC_REQ_SENSE dosfar *) scsiq->sense_ptr;
8662
8663 if ((scsiq->r3.scsi_stat == SS_CHK_CONDITION) &&
8664 ((sen->err_code & 0x70) != 0)) {
8665
8666 if (sen->sense_key == SCSI_SENKEY_NOT_READY) {
8667
8668 if (asc_dvc->start_motor & tid_bits) {
8669 if (PollScsiStartUnit(asc_dvc, scsiq) == 1) {
8670 retry = 0;
8671 continue;
8672 } else {
8673 asc_dvc->start_motor &= ~tid_bits;
8674 break;
8675 }
8676 } else {
8677 DvcSleepMilliSecond(100);
8678 }
8679 } else if (sen->sense_key == SCSI_SENKEY_ATTENSION) {
8680 DvcSleepMilliSecond(100);
8681 } else {
8682 break;
8683 }
8684 } else {
8685 break;
8686 }
8687 } else if (scsiq->r3.done_stat == QD_ABORTED_BY_HOST) {
8688 break;
8689 } else {
8690 break;
8691 }
8692 }
8693 return (0);
8694 }
8695
8696 #if CC_INIT_INQ_DISPLAY
8697
8698 #endif
8699
8700 int
8701 AscPollQDone(
8702 ASC_DVC_VAR asc_ptr_type * asc_dvc,
8703 ASC_SCSI_REQ_Q dosfar * scsiq,
8704 int timeout_sec
8705 )
8706 {
8707 int loop, loop_end;
8708 int sta;
8709 PortAddr iop_base;
8710
8711 iop_base = asc_dvc->iop_base;
8712 loop = 0;
8713 loop_end = timeout_sec * 100;
8714 sta = 1;
8715
8716 while (TRUE) {
8717 ASC_DBG4(3,
8718 "AscPollQDone: loop %d, err_code %x, done_stat %x, scsi_stat %x\n",
8719 loop, asc_dvc->err_code, scsiq->r3.done_stat, scsiq->r3.scsi_stat);
8720 if (asc_dvc->err_code != 0) {
8721 scsiq->r3.done_stat = QD_WITH_ERROR;
8722 sta = ERR;
8723 break;
8724 }
8725 if (scsiq->r3.done_stat != QD_IN_PROGRESS) {
8726 if ((scsiq->r3.done_stat == QD_WITH_ERROR) &&
8727 (scsiq->r3.scsi_stat == SS_TARGET_BUSY)) {
8728 sta = 0x80;
8729 break;
8730 }
8731 break;
8732 }
8733 DvcSleepMilliSecond(10);
8734 if (loop++ > loop_end) {
8735 sta = 0;
8736 break;
8737 }
8738 if (AscIsChipHalted(iop_base)) {
8739 AscISR(asc_dvc);
8740 loop = 0;
8741 } else {
8742 ASC_DBG(3, "AscPollQDone: AscIsIntPending()\n");
8743 if (AscIsIntPending(iop_base)) {
8744 ASC_DBG(3, "AscPollQDone: AscISR()\n");
8745 AscISR(asc_dvc);
8746 }
8747 }
8748 }
8749 ASC_DBG1(3, "AscPollQDone: sta %x\n", sta);
8750 return (sta);
8751 }
8752
8753 uchar
8754 AscReadLramByte(
8755 PortAddr iop_base,
8756 ushort addr
8757 )
8758 {
8759 uchar byte_data;
8760 ushort word_data;
8761
8762 if (isodd_word(addr)) {
8763 AscSetChipLramAddr(iop_base, addr - 1);
8764 word_data = AscGetChipLramData(iop_base);
8765
8766 #if CC_LITTLE_ENDIAN_HOST
8767 byte_data = (uchar) ((word_data >> 8) & 0xFF);
8768 #else
8769 byte_data = (uchar) (word_data & 0xFF);
8770 #endif
8771
8772 } else {
8773 AscSetChipLramAddr(iop_base, addr);
8774 word_data = AscGetChipLramData(iop_base);
8775
8776 #if CC_LITTLE_ENDIAN_HOST
8777 byte_data = (uchar) (word_data & 0xFF);
8778 #else
8779 byte_data = (uchar) ((word_data >> 8) & 0xFF);
8780 #endif
8781
8782 }
8783 return (byte_data);
8784 }
8785
8786 ushort
8787 AscReadLramWord(
8788 PortAddr iop_base,
8789 ushort addr
8790 )
8791 {
8792 ushort word_data;
8793
8794 AscSetChipLramAddr(iop_base, addr);
8795 word_data = AscGetChipLramData(iop_base);
8796 return (word_data);
8797 }
8798
8799 ulong
8800 AscReadLramDWord(
8801 PortAddr iop_base,
8802 ushort addr
8803 )
8804 {
8805 ushort val_low, val_high;
8806 ulong dword_data;
8807
8808 AscSetChipLramAddr(iop_base, addr);
8809
8810 #if CC_LITTLE_ENDIAN_HOST
8811 val_low = AscGetChipLramData(iop_base);
8812
8813 val_high = AscGetChipLramData(iop_base);
8814 #else
8815 val_high = AscGetChipLramData(iop_base);
8816 val_low = AscGetChipLramData(iop_base);
8817 #endif
8818
8819 dword_data = ((ulong) val_high << 16) | (ulong) val_low;
8820 return (dword_data);
8821 }
8822
8823 void
8824 AscWriteLramWord(
8825 PortAddr iop_base,
8826 ushort addr,
8827 ushort word_val
8828 )
8829 {
8830 AscSetChipLramAddr(iop_base, addr);
8831 AscPutChipLramData(iop_base, word_val);
8832 return;
8833 }
8834
8835 void
8836 AscWriteLramDWord(
8837 PortAddr iop_base,
8838 ushort addr,
8839 ulong dword_val
8840 )
8841 {
8842 ushort word_val;
8843
8844 AscSetChipLramAddr(iop_base, addr);
8845
8846 #if CC_LITTLE_ENDIAN_HOST
8847 word_val = (ushort) dword_val;
8848 AscPutChipLramData(iop_base, word_val);
8849 word_val = (ushort) (dword_val >> 16);
8850 AscPutChipLramData(iop_base, word_val);
8851 #else
8852 word_val = (ushort) (dword_val >> 16);
8853 AscPutChipLramData(iop_base, word_val);
8854 word_val = (ushort) dword_val;
8855 AscPutChipLramData(iop_base, word_val);
8856 #endif
8857 return;
8858 }
8859
8860 void
8861 AscWriteLramByte(
8862 PortAddr iop_base,
8863 ushort addr,
8864 uchar byte_val
8865 )
8866 {
8867 ushort word_data;
8868
8869 if (isodd_word(addr)) {
8870 addr--;
8871 word_data = AscReadLramWord(iop_base, addr);
8872 word_data &= 0x00FF;
8873 word_data |= (((ushort) byte_val << 8) & 0xFF00);
8874 } else {
8875 word_data = AscReadLramWord(iop_base, addr);
8876 word_data &= 0xFF00;
8877 word_data |= ((ushort) byte_val & 0x00FF);
8878 }
8879 AscWriteLramWord(iop_base, addr, word_data);
8880 return;
8881 }
8882
8883 int
8884 AscVerWriteLramWord(
8885 PortAddr iop_base,
8886 ushort addr,
8887 ushort word_val
8888 )
8889 {
8890 int sta;
8891
8892 sta = 0;
8893 AscSetChipLramAddr(iop_base, addr);
8894 AscPutChipLramData(iop_base, word_val);
8895 AscSetChipLramAddr(iop_base, addr);
8896 if (word_val != AscGetChipLramData(iop_base)) {
8897 sta = ERR;
8898 }
8899 return (sta);
8900 }
8901
8902 void
8903 AscMemWordCopyToLram(
8904 PortAddr iop_base,
8905 ushort s_addr,
8906 ushort dosfar * s_buffer,
8907 int words
8908 )
8909 {
8910 AscSetChipLramAddr(iop_base, s_addr);
8911 DvcOutPortWords(iop_base + IOP_RAM_DATA, s_buffer, words);
8912 return;
8913 }
8914
8915 void
8916 AscMemDWordCopyToLram(
8917 PortAddr iop_base,
8918 ushort s_addr,
8919 ulong dosfar * s_buffer,
8920 int dwords
8921 )
8922 {
8923 AscSetChipLramAddr(iop_base, s_addr);
8924 DvcOutPortDWords(iop_base + IOP_RAM_DATA, s_buffer, dwords);
8925 return;
8926 }
8927
8928 void
8929 AscMemWordCopyFromLram(
8930 PortAddr iop_base,
8931 ushort s_addr,
8932 ushort dosfar * d_buffer,
8933 int words
8934 )
8935 {
8936 AscSetChipLramAddr(iop_base, s_addr);
8937 DvcInPortWords(iop_base + IOP_RAM_DATA, d_buffer, words);
8938 return;
8939 }
8940
8941 ulong
8942 AscMemSumLramWord(
8943 PortAddr iop_base,
8944 ushort s_addr,
8945 rint words
8946 )
8947 {
8948 ulong sum;
8949 int i;
8950
8951 sum = 0L;
8952 for (i = 0; i < words; i++, s_addr += 2) {
8953 sum += AscReadLramWord(iop_base, s_addr);
8954 }
8955 return (sum);
8956 }
8957
8958 void
8959 AscMemWordSetLram(
8960 PortAddr iop_base,
8961 ushort s_addr,
8962 ushort set_wval,
8963 rint words
8964 )
8965 {
8966 rint i;
8967
8968 AscSetChipLramAddr(iop_base, s_addr);
8969 for (i = 0; i < words; i++) {
8970 AscPutChipLramData(iop_base, set_wval);
8971 }
8972 return;
8973 }
8974
8975 int
8976 AscScsiInquiry(
8977 ASC_DVC_VAR asc_ptr_type * asc_dvc,
8978 ASC_SCSI_REQ_Q dosfar * scsiq,
8979 uchar dosfar * buf, int buf_len
8980 )
8981 {
8982 if (AscScsiSetupCmdQ(asc_dvc, scsiq, buf,
8983 (ulong) buf_len) == ERR) {
8984 return (scsiq->r3.done_stat = QD_WITH_ERROR);
8985 }
8986 scsiq->cdb[0] = (uchar) SCSICMD_Inquiry;
8987 scsiq->cdb[1] = scsiq->r1.target_lun << 5;
8988 scsiq->cdb[2] = 0;
8989 scsiq->cdb[3] = 0;
8990 scsiq->cdb[4] = buf_len;
8991 scsiq->cdb[5] = 0;
8992 scsiq->r2.cdb_len = 6;
8993 return (0);
8994 }
8995
8996 int
8997 AscScsiReadCapacity(
8998 ASC_DVC_VAR asc_ptr_type * asc_dvc,
8999 ASC_SCSI_REQ_Q dosfar * scsiq,
9000 uchar dosfar * info
9001 )
9002 {
9003 if (AscScsiSetupCmdQ(asc_dvc, scsiq, info, 8L) == ERR) {
9004 return (scsiq->r3.done_stat = QD_WITH_ERROR);
9005 }
9006 scsiq->cdb[0] = (uchar) SCSICMD_ReadCapacity;
9007 scsiq->cdb[1] = scsiq->r1.target_lun << 5;
9008 scsiq->cdb[2] = 0;
9009 scsiq->cdb[3] = 0;
9010 scsiq->cdb[4] = 0;
9011 scsiq->cdb[5] = 0;
9012 scsiq->cdb[6] = 0;
9013 scsiq->cdb[7] = 0;
9014 scsiq->cdb[8] = 0;
9015 scsiq->cdb[9] = 0;
9016 scsiq->r2.cdb_len = 10;
9017 return (0);
9018 }
9019
9020 int
9021 AscScsiTestUnitReady(
9022 ASC_DVC_VAR asc_ptr_type * asc_dvc,
9023 ASC_SCSI_REQ_Q dosfar * scsiq
9024 )
9025 {
9026 if (AscScsiSetupCmdQ(asc_dvc, scsiq, FNULLPTR,
9027 (ulong) 0L) == ERR) {
9028 return (scsiq->r3.done_stat = QD_WITH_ERROR);
9029 }
9030 scsiq->r1.cntl = (uchar) ASC_SCSIDIR_NODATA;
9031 scsiq->cdb[0] = (uchar) SCSICMD_TestUnitReady;
9032 scsiq->cdb[1] = scsiq->r1.target_lun << 5;
9033 scsiq->cdb[2] = 0;
9034 scsiq->cdb[3] = 0;
9035 scsiq->cdb[4] = 0;
9036 scsiq->cdb[5] = 0;
9037 scsiq->r2.cdb_len = 6;
9038 return (0);
9039 }
9040
9041 int
9042 AscScsiStartStopUnit(
9043 ASC_DVC_VAR asc_ptr_type * asc_dvc,
9044 ASC_SCSI_REQ_Q dosfar * scsiq,
9045 uchar op_mode
9046 )
9047 {
9048 if (AscScsiSetupCmdQ(asc_dvc, scsiq, FNULLPTR, (ulong) 0L) == ERR) {
9049 return (scsiq->r3.done_stat = QD_WITH_ERROR);
9050 }
9051 scsiq->r1.cntl = (uchar) ASC_SCSIDIR_NODATA;
9052 scsiq->cdb[0] = (uchar) SCSICMD_StartStopUnit;
9053 scsiq->cdb[1] = scsiq->r1.target_lun << 5;
9054 scsiq->cdb[2] = 0;
9055 scsiq->cdb[3] = 0;
9056 scsiq->cdb[4] = op_mode;
9057
9058 scsiq->cdb[5] = 0;
9059 scsiq->r2.cdb_len = 6;
9060 return (0);
9061 }