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