1 /* $Id: atp870u.c,v 1.0 1997/05/07 15:22:00 root Exp root $
2 * linux/kernel/atp870u.c
4 * Copyright (C) 1997 Wu Ching Chen
5 * 2.1.x update (C) 1998 Krzysztof G. Baranowski
7 * Marcelo Tosatti <marcelo@conectiva.com.br> : SMP fixes
11 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/types.h>
15 #include <linux/string.h>
16 #include <linux/ioport.h>
17 #include <linux/delay.h>
18 #include <linux/sched.h>
19 #include <linux/proc_fs.h>
20 #include <linux/spinlock.h>
21 #include <asm/system.h>
23 #include <linux/pci.h>
24 #include <linux/blk.h>
31 #include<linux/stat.h>
33 struct proc_dir_entry proc_scsi_atp870u
= {
34 PROC_SCSI_ATP870U
, 7, "atp870u",
35 S_IFDIR
| S_IRUGO
| S_IXUGO
, 2
38 void mydlyu(unsigned int);
40 static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/atp870u.c,v 1.0 1997/05/07 15:22:00 root Exp root $";
43 static unsigned char admaxu
=1,host_idu
[2],chip_veru
[2],scam_on
[2],global_map
[2];
44 static unsigned short int active_idu
[2],wide_idu
[2],sync_idu
,ultra_map
[2];
45 static int workingu
[2]={0,0};
46 static Scsi_Cmnd
*querequ
[2][qcnt
],*curr_req
[2][16];
47 static unsigned char devspu
[2][16] = {{0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
48 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20},
49 {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
50 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20}};
51 static unsigned char dirctu
[2][16],last_cmd
[2],in_snd
[2],in_int
[2];
52 static unsigned char ata_cdbu
[2][16];
53 static unsigned int ioportu
[2]={0,0};
54 static unsigned int irqnumu
[2]={0,0};
55 static unsigned short int pciportu
[2];
56 static unsigned long prdaddru
[2][16],tran_lenu
[2][16],last_lenu
[2][16];
57 static unsigned char prd_tableu
[2][16][1024];
58 static unsigned char *prd_posu
[2][16];
59 static unsigned char quhdu
[2],quendu
[2];
60 static unsigned char devtypeu
[2][16] = {{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
61 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
62 static struct Scsi_Host
* atp_host
[2]={NULL
,NULL
};
64 static void atp870u_intr_handle(int irq
, void *dev_id
, struct pt_regs
*regs
)
67 unsigned short int tmpcip
,id
;
68 unsigned char i
,j
,h
,tarid
,lun
;
71 unsigned int workportu
,tmport
;
72 unsigned long adrcntu
,k
;
75 for ( h
=0; h
< 2; h
++ )
77 if ( ( irq
& 0x0f ) == irqnumu
[h
] )
88 if ( workingu
[h
] != 0 )
93 if ((inb(tmpcip
) & 0x08) != 0)
96 while((inb(tmpcip
) & 0x08) != 0);
104 if ((last_cmd
[h
] & 0x40) == 0)
116 if ((tarid
& 0x40) != 0)
118 tarid
=(tarid
& 0x07) | 0x08;
126 if (wide_idu
[h
] != 0)
128 tmport
=workportu
+0x1b;
129 j
=inb(tmport
) & 0x0e;
133 if (((quhdu
[h
] != quendu
[h
]) || (last_cmd
[h
] != 0xff)) &&
145 ((unsigned char *)&adrcntu
)[2]=inb(tmport
++);
146 ((unsigned char *)&adrcntu
)[1]=inb(tmport
++);
147 ((unsigned char *)&adrcntu
)[0]=inb(tmport
);
148 k
=last_lenu
[h
][tarid
];
150 tran_lenu
[h
][tarid
]= k
;
151 last_lenu
[h
][tarid
]=adrcntu
;
160 if ((i
== 0x80) || (i
== 0x8f))
168 lun
=inb(tmport
) & 0x07;
176 ((unsigned char *)&adrcntu
)[2]=inb(tmport
++);
177 ((unsigned char *)&adrcntu
)[1]=inb(tmport
++);
178 ((unsigned char *)&adrcntu
)[0]=inb(tmport
);
179 k
=last_lenu
[h
][tarid
];
181 tran_lenu
[h
][tarid
]= k
;
182 last_lenu
[h
][tarid
]=adrcntu
;
191 dirctu
[h
][tarid
]=0x00;
202 tmport
=workportu
+ 0x10;
206 if ((tarid
& 0x10) != 0)
208 tarid
=(tarid
& 0x07) | 0x08;
214 workrequ
=curr_req
[h
][tarid
];
215 tmport
=workportu
+ 0x0f;
218 outb(devspu
[h
][tarid
],tmport
++);
219 adrcntu
=tran_lenu
[h
][tarid
];
220 k
=last_lenu
[h
][tarid
];
221 outb(((unsigned char *)&k
)[2],tmport
++);
222 outb(((unsigned char *)&k
)[1],tmport
++);
223 outb(((unsigned char *)&k
)[0],tmport
++);
227 j
= (j
& 0x07) | 0x40;
229 j
|= dirctu
[h
][tarid
];
232 tmport
=workportu
+ 0x1b;
233 j
=inb(tmport
) & 0x0e;
236 if ((id
& wide_idu
[h
]) != 0)
241 if ( last_lenu
[h
][tarid
] == 0 )
243 tmport
=workportu
+ 0x18;
248 prd
=prd_posu
[h
][tarid
];
249 while ( adrcntu
!= 0 )
251 id
=((unsigned short int *)(prd
))[2];
262 ((unsigned short int *)(prd
))[2] =(unsigned short int)
264 ((unsigned long *)(prd
))[0] += adrcntu
;
266 prd_posu
[h
][tarid
]=prd
;
271 prdaddru
[h
][tarid
] += 0x08;
275 prd_posu
[h
][tarid
]=prd
;
279 tmpcip
=pciportu
[h
] + 0x04;
280 outl(prdaddru
[h
][tarid
],tmpcip
);
285 tmport
=workportu
+ 0x18;
286 if ( dirctu
[h
][tarid
] != 0 )
299 workrequ
=curr_req
[h
][tarid
];
303 workrequ
->result
=errstus
;
311 workrequ
->result
=errstus
;
312 /* if ( errstus == 0x02 )
315 if ((inb(tmport) & 0x80) != 0)
317 printk(" autosense ");
321 tmport=workportu+0x3a;
322 outb((unsigned char)(inb(tmport) | 0x10),tmport);
336 outb(devspu[h][workrequ->target],tmport++);
344 adrcntu=(unsigned long)(&workrequ->sense_buffer[0]);
350 (unsigned char)(((caddr_t) adrcntu)[i++])=inb(tmport);
363 tmport=workportu+0x3a;
364 outb((unsigned char)(inb(tmport) & 0xef),tmport);
365 tmport=workportu+0x01;
371 spin_lock_irqsave(&io_request_lock
, flags
);
372 (*workrequ
->scsi_done
)(workrequ
);
373 spin_unlock_irqrestore(&io_request_lock
, flags
);
375 curr_req
[h
][tarid
]=0;
377 if (wide_idu
[h
] != 0)
379 tmport
=workportu
+0x1b;
380 j
=inb(tmport
) & 0x0e;
384 if (((last_cmd
[h
] != 0xff) || (quhdu
[h
] != quendu
[h
])) &&
400 outl(prdaddru
[h
][tarid
],tmpcip
);
405 tmport
=workportu
+0x10;
407 dirctu
[h
][tarid
]=0x00;
417 outl(prdaddru
[h
][tarid
],tmpcip
);
422 tmport
=workportu
+0x10;
425 outb((unsigned char)(inb(tmport
) | 0x20),tmport
);
426 dirctu
[h
][tarid
]=0x20;
442 dirctu
[h
][tarid
]=0x00;
454 tmport
=workportu
+0x17;
462 int atp870u_queuecommand(Scsi_Cmnd
* req_p
, void (*done
)(Scsi_Cmnd
*))
466 unsigned short int m
;
469 for( h
=0; h
<= admaxu
; h
++ )
471 if ( req_p
->host
== atp_host
[h
] )
478 if ( req_p
->channel
!= 0 )
480 req_p
->result
= 0x00040000;
485 m
= m
<< req_p
->target
;
486 if ( ( m
& active_idu
[h
] ) == 0 )
488 req_p
->result
= 0x00040000;
494 req_p
->scsi_done
= done
;
498 printk("atp870u_queuecommand: done can't be NULL\n");
504 if ( quendu
[h
] >= qcnt
)
509 if ( quhdu
[h
] == quendu
[h
] )
515 querequ
[h
][quendu
[h
]]=req_p
;
516 if ( quendu
[h
] == 0 )
524 tmport
= ioportu
[h
]+0x1c;
525 restore_flags(flags
);
526 if ((inb(tmport
) == 0) && (in_int
[h
] == 0) && (in_snd
[h
] == 0))
533 void mydlyu(unsigned int dlycnt
)
536 for ( i
= 0 ; i
< dlycnt
; i
++ )
542 void send_s870(unsigned char h
)
548 unsigned char j
,tarid
;
550 unsigned short int tmpcip
,w
;
551 unsigned long l
,bttl
;
552 unsigned int workportu
;
553 struct scatterlist
* sgpnt
;
557 if ( in_snd
[h
] != 0 )
559 restore_flags(flags
);
563 if ((last_cmd
[h
] != 0xff) && ((last_cmd
[h
] & 0x40) != 0))
566 workrequ
=curr_req
[h
][last_cmd
[h
]];
572 if ( quhdu
[h
] >= qcnt
)
576 workrequ
=querequ
[h
][quhdu
[h
]];
577 if ( curr_req
[h
][workrequ
->target
] == 0 )
579 curr_req
[h
][workrequ
->target
]=workrequ
;
580 last_cmd
[h
]=workrequ
->target
;
586 restore_flags(flags
);
589 workportu
=ioportu
[h
];
590 tmport
=workportu
+0x1f;
591 if ((inb(tmport
) & 0xb0) != 0)
595 tmport
=workportu
+0x1c;
596 if ( inb(tmport
) == 0 )
603 restore_flags(flags
);
606 memcpy(&ata_cdbu
[h
][0], &workrequ
->cmnd
[0], workrequ
->cmd_len
);
607 if ( ata_cdbu
[h
][0] == 0x25 )
609 if ( workrequ
->request_bufflen
> 8 )
611 workrequ
->request_bufflen
=0x08;
614 if ( ata_cdbu
[h
][0] == 0x12 )
616 if ( workrequ
->request_bufflen
> 0x24 )
618 workrequ
->request_bufflen
= 0x24;
623 tmport
=workportu
+0x1b;
624 j
=inb(tmport
) & 0x0e;
625 tarid
=workrequ
->target
;
628 if ((w
& wide_idu
[h
]) != 0)
634 outb(workrequ
->cmd_len
,tmport
++);
637 for ( i
=0 ; i
< workrequ
->cmd_len
; i
++ )
639 outb(ata_cdbu
[h
][i
],tmport
++);
641 tmport
=workportu
+0x0f;
644 outb(devspu
[h
][tarid
],tmport
++);
645 if (workrequ
->use_sg
)
649 sgpnt
= (struct scatterlist
*) workrequ
->request_buffer
;
650 for(i
=0; i
<workrequ
->use_sg
; i
++)
652 if(sgpnt
[i
].length
== 0 || workrequ
->use_sg
> ATP870U_SCATTER
)
654 panic("Foooooooood fight!");
656 l
+= sgpnt
[i
].length
;
661 l
=workrequ
->request_bufflen
;
663 outb((unsigned char)(((unsigned char *)(&l
))[2]),tmport
++);
664 outb((unsigned char)(((unsigned char *)(&l
))[1]),tmport
++);
665 outb((unsigned char)(((unsigned char *)(&l
))[0]),tmport
++);
673 if ((ata_cdbu
[h
][0] == 0x0a) || (ata_cdbu
[h
][0] == 0x2a) ||
674 (ata_cdbu
[h
][0] == 0xaa) || (ata_cdbu
[h
][0] == 0x15))
676 outb((unsigned char)(j
| 0x20),tmport
++);
683 tmport
=workportu
+ 0x1c;
687 if ( inb(tmport
) == 0 )
689 tmport
=workportu
+0x18;
697 restore_flags(flags
);
701 prd
=&prd_tableu
[h
][tarid
][0];
702 prd_posu
[h
][tarid
]=prd
;
703 if (workrequ
->use_sg
)
705 sgpnt
= (struct scatterlist
*) workrequ
->request_buffer
;
707 for(j
=0; j
<workrequ
->use_sg
; j
++)
709 (unsigned long)(((unsigned long *)(prd
))[i
>> 1])=(unsigned long)sgpnt
[j
].address
;
710 (unsigned short int)(((unsigned short int *)(prd
))[i
+2])=sgpnt
[j
].length
;
711 (unsigned short int)(((unsigned short int *)(prd
))[i
+3])=0;
714 (unsigned short int)(((unsigned short int *)(prd
))[i
-1])=0x8000;
718 bttl
=(unsigned long)workrequ
->request_buffer
;
719 l
=workrequ
->request_bufflen
;
721 while ( l
> 0x10000 )
723 (unsigned short int)(((unsigned short int *)(prd
))[i
+3])=0x0000;
724 (unsigned short int)(((unsigned short int *)(prd
))[i
+2])=0x0000;
725 (unsigned long)(((unsigned long *)(prd
))[i
>> 1])=bttl
;
730 (unsigned short int)(((unsigned short int *)(prd
))[i
+3])=0x8000;
731 (unsigned short int)(((unsigned short int *)(prd
))[i
+2])=l
;
732 (unsigned long)(((unsigned long *)(prd
))[i
>> 1])=bttl
;
735 prdaddru
[h
][tarid
]=(unsigned long)&prd_tableu
[h
][tarid
][0];
736 outl(prdaddru
[h
][tarid
],tmpcip
);
741 if ((ata_cdbu
[h
][0] == 0x0a) || (ata_cdbu
[h
][0] == 0x2a) ||
742 (ata_cdbu
[h
][0] == 0xaa) || (ata_cdbu
[h
][0] == 0x15))
744 dirctu
[h
][tarid
]=0x20;
745 if ( inb(tmport
) == 0 )
747 tmport
=workportu
+0x18;
756 restore_flags(flags
);
759 if ( inb(tmport
) == 0 )
761 tmport
=workportu
+0x18;
770 restore_flags(flags
);
775 static void internal_done(Scsi_Cmnd
* SCpnt
)
780 int atp870u_command(Scsi_Cmnd
* SCpnt
)
783 atp870u_queuecommand(SCpnt
, internal_done
);
785 SCpnt
->SCp
.Status
= 0;
786 while (!SCpnt
->SCp
.Status
)
788 return SCpnt
->result
;
791 unsigned char fun_scam ( unsigned char host
,unsigned short int * val
)
793 unsigned int tmport
;
794 unsigned short int i
,k
;
797 tmport
= ioportu
[host
]+0x1c;
800 for ( i
=0; i
< 10; i
++ ) /* stable >= bus settle delay(400 ns) */
803 j
= (unsigned char)(k
>> 8);
804 if ((k
& 0x8000) != 0) /* DB7 all release? */
809 *val
|= 0x4000; /* assert DB6 */
811 *val
&= 0xdfff; /* assert DB5 */
814 for ( i
=0; i
< 10; i
++ ) /* stable >= bus settle delay(400 ns) */
816 if ((inw(tmport
) & 0x2000) != 0) /* DB5 all release? */
821 *val
|= 0x8000; /* no DB4-0, assert DB7 */
824 *val
&= 0xbfff; /* release DB6 */
827 for ( i
=0; i
< 10; i
++ ) /* stable >= bus settle delay(400 ns) */
829 if ((inw(tmport
) & 0x4000) != 0) /* DB6 all release? */
838 void tscam( unsigned char host
)
841 unsigned int tmport
;
844 unsigned short int m
,assignid_map
,val
;
845 unsigned char mbuf
[33],quintet
[2];
846 static unsigned char g2q_tab
[8]={ 0x38,0x31,0x32,0x2b,0x34,0x2d,0x2e,0x27 };
849 for ( i
=0; i
< 0x10; i
++ )
854 tmport
= ioportu
[host
]+1;
857 tmport
= ioportu
[host
]+0x11;
860 if ((scam_on
[host
] & 0x40) == 0)
866 m
<<= host_idu
[host
];
868 if ( chip_veru
[host
] < 4 )
874 tmport
= ioportu
[host
]+0x02;
875 outb(0x02,tmport
++); /* 2*2=4ms,3EH 2/32*3E=3.9ms */
883 for ( i
= 0 ; i
< j
; i
++ )
887 if ( ( m
& assignid_map
) != 0 )
891 tmport
= ioportu
[host
]+0x0f;
906 tmport
= ioportu
[host
]+0x1b;
907 if ( chip_veru
[host
] == 4 )
909 outb((unsigned char)((inb(tmport
) & 0x0e) | 0x01),tmport
);
913 outb((unsigned char)(inb(tmport
) & 0x0e),tmport
);
916 tmport
= ioportu
[host
]+0x18;
920 while ((inb(tmport
) & 0x80) == 0x00);
925 if ((k
== 0x85) || (k
== 0x42))
929 tmport
= ioportu
[host
]+0x10;
936 tmport
= ioportu
[host
]+0x02;
938 tmport
= ioportu
[host
]+0x1b;
943 val
=0x0080; /* bsy */
944 tmport
= ioportu
[host
]+0x1c;
946 val
|=0x0040; /* sel */
948 val
|=0x0004; /* msg */
950 inb(0x80); /* 2 deskew delay(45ns*2=90ns) */
951 val
&=0x007f; /* no bsy */
953 mydlyu(0xffff); /* recommanded SCAM selection response time */
955 val
&=0x00fb; /* after 1ms no msg */
958 if ((inb(tmport
) & 0x04) != 0)
964 for ( n
=0; n
< 0x30000; n
++ )
966 if ((inb(tmport
) & 0x80) != 0) /* bsy ? */
973 for ( n
=0; n
< 0x30000; n
++ )
975 if ((inb(tmport
) & 0x81) == 0x0081)
983 val
|=0x8003; /* io,cd,db7 */
986 val
&=0x00bf; /* no sel */
991 if ((inb(tmport
) & 0x80) == 0x00) /* bsy ? */
995 tmport
=ioportu
[host
] + 0x15;
1000 while ((inb(tmport
) & 0x80) == 0);
1006 val
&= 0x00ff; /* synchronization */
1008 fun_scam(host
,&val
);
1010 val
&= 0x00ff; /* isolation */
1012 fun_scam(host
,&val
);
1017 if ((inw(tmport
) & 0x2000) == 0)
1022 val
&= 0x00ff; /* get ID_STRING */
1024 k
=fun_scam(host
,&val
);
1025 if ((k
& 0x03) == 0)
1031 if ((k
& 0x02) != 0)
1044 TCM_5
: /* isolation complete.. */
1046 printk(" \n%x %x %x %s\n ",assignid_map,mbuf[0],mbuf[1],&mbuf[2]); */
1049 if ((j
& 0x20) != 0) /* bit5=1:ID upto 7 */
1053 if ((j
& 0x06) == 0) /* IDvalid? */
1061 if ((m
& assignid_map
) == 0)
1070 G2Q5
: /* srch from max acceptable ID# */
1071 k
=i
; /* max acceptable ID# */
1075 if ((m
& assignid_map
) == 0)
1084 G2Q_QUIN
: /* k=binID#, */
1088 quintet
[0]=0x38; /* 1st dft ID<8 */
1092 quintet
[0]=0x31; /* 1st ID>=8 */
1095 quintet
[1]=g2q_tab
[k
];
1097 val
&= 0x00ff; /* AssignID 1stQuintet,AH=001xxxxx */
1100 fun_scam(host
,&val
);
1101 val
&= 0x00ff; /* AssignID 2ndQuintet,AH=001xxxxx */
1104 fun_scam(host
,&val
);
1110 void is870(unsigned long host
,unsigned int wkport
)
1112 unsigned int tmport
;
1113 unsigned char i
,j
,k
,rmb
;
1114 unsigned short int m
;
1115 static unsigned char mbuf
[512];
1116 static unsigned char satn
[9] = { 0,0,0,0,0,0,0,6,6 };
1117 static unsigned char inqd
[9] = { 0x12,0,0,0,0x24,0,0,0x24,6 };
1118 static unsigned char synn
[6] = { 0x80,1,3,1,0x19,0x0e };
1119 static unsigned char synu
[6] = { 0x80,1,3,1,0x0c,0x0e };
1120 static unsigned char synw
[6] = { 0x80,1,3,1,0x0c,0x07 };
1121 static unsigned char wide
[6] = { 0x80,1,2,3,1,0 };
1125 outb((unsigned char)(inb(tmport
) | 0x10),tmport
);
1127 for ( i
= 0 ; i
< 16 ; i
++ )
1129 if ((chip_veru
[host
] != 4) && (i
> 7))
1135 if ( ( m
& active_idu
[host
] ) != 0 )
1139 if ( i
== host_idu
[host
] )
1141 printk(" ID: %2d Host Adapter\n",host_idu
[host
]);
1144 if ( chip_veru
[host
] == 4 )
1147 j
=(inb(tmport
) & 0x0e) | 0x01;
1151 outb(0x08,tmport
++);
1152 outb(0x7f,tmport
++);
1153 outb(satn
[0],tmport
++);
1154 outb(satn
[1],tmport
++);
1155 outb(satn
[2],tmport
++);
1156 outb(satn
[3],tmport
++);
1157 outb(satn
[4],tmport
++);
1158 outb(satn
[5],tmport
++);
1162 outb(devspu
[host
][i
],tmport
++);
1164 outb(satn
[6],tmport
++);
1165 outb(satn
[7],tmport
++);
1167 if ((j
& 0x08) != 0)
1169 j
=(j
& 0x07) | 0x40;
1173 outb(satn
[8],tmport
);
1176 while ((inb(tmport
) & 0x80) == 0x00);
1178 if ((inb(tmport
) != 0x11) && (inb(tmport
) != 0x8e))
1182 while ( inb(tmport
) != 0x8e );
1183 active_idu
[host
] |= m
;
1194 while ((inb(tmport
) & 0x80) == 0x00);
1205 outb(inqd
[0],tmport
++);
1206 outb(inqd
[1],tmport
++);
1207 outb(inqd
[2],tmport
++);
1208 outb(inqd
[3],tmport
++);
1209 outb(inqd
[4],tmport
++);
1210 outb(inqd
[5],tmport
);
1214 outb(devspu
[host
][i
],tmport
++);
1216 outb(inqd
[6],tmport
++);
1217 outb(inqd
[7],tmport
++);
1219 outb(inqd
[8],tmport
);
1221 while ((inb(tmport
) & 0x80) == 0x00);
1223 if ((inb(tmport
) != 0x11) && (inb(tmport
) != 0x8e))
1227 while ( inb(tmport
) != 0x8e );
1228 if ( chip_veru
[host
] == 4 )
1231 j
=inb(tmport
) & 0x0e;
1240 if ((k
& 0x01) != 0 )
1243 mbuf
[j
++]=inb(tmport
);
1247 if ((k
& 0x80) == 0 )
1266 while ((inb(tmport
) & 0x80) == 0x00);
1268 if (inb(tmport
) != 0x16)
1274 printk(" ID: %2d %s\n",i
,&mbuf
[8]);
1275 devtypeu
[host
][i
]=mbuf
[0];
1277 if ( chip_veru
[host
] != 4 )
1281 if ((mbuf
[7] & 0x60) == 0)
1285 if ((global_map
[host
] & 0x20) == 0)
1290 j
=(inb(tmport
) & 0x0e) | 0x01;
1293 outb(satn
[0],tmport
++);
1294 outb(satn
[1],tmport
++);
1295 outb(satn
[2],tmport
++);
1296 outb(satn
[3],tmport
++);
1297 outb(satn
[4],tmport
++);
1298 outb(satn
[5],tmport
++);
1302 outb(devspu
[host
][i
],tmport
++);
1304 outb(satn
[6],tmport
++);
1305 outb(satn
[7],tmport
++);
1307 outb(satn
[8],tmport
);
1310 while ((inb(tmport
) & 0x80) == 0x00);
1312 if ((inb(tmport
) != 0x11) && (inb(tmport
) != 0x8e))
1316 while ( inb(tmport
) != 0x8e );
1325 while ((inb(tmport
) & 0x80) == 0 )
1327 if ((inb(tmport
) & 0x01) != 0 )
1330 outb(wide
[j
++],tmport
);
1335 while ((inb(tmport
) & 0x80) == 0x00);
1336 j
=inb(tmport
) & 0x0f;
1354 while ((inb(tmport
) & 0x80) == 0 )
1356 if ((inb(tmport
) & 0x01) != 0 )
1364 j
=inb(tmport
) & 0x0f;
1387 if ((j
& 0x01) != 0)
1390 mbuf
[k
++]=inb(tmport
);
1394 if ((j
& 0x80) == 0x00)
1399 j
=inb(tmport
) & 0x0f;
1421 while ((inb(tmport
) & 0x80) == 0x00);
1432 if ( mbuf
[0] != 0x01 )
1436 if ( mbuf
[1] != 0x02 )
1440 if ( mbuf
[2] != 0x03 )
1444 if ( mbuf
[3] != 0x01 )
1450 wide_idu
[host
] |= m
;
1452 if ((devtypeu
[host
][i
] == 0x00) || (devtypeu
[host
][i
] == 0x07))
1459 j
=inb(tmport
) & 0x0e;
1460 if ((m
& wide_idu
[host
]) != 0 )
1466 outb(satn
[0],tmport
++);
1467 outb(satn
[1],tmport
++);
1468 outb(satn
[2],tmport
++);
1469 outb(satn
[3],tmport
++);
1470 outb(satn
[4],tmport
++);
1471 outb(satn
[5],tmport
++);
1475 outb(devspu
[host
][i
],tmport
++);
1477 outb(satn
[6],tmport
++);
1478 outb(satn
[7],tmport
++);
1480 outb(satn
[8],tmport
);
1483 while ((inb(tmport
) & 0x80) == 0x00);
1485 if ((inb(tmport
) != 0x11) && (inb(tmport
) != 0x8e))
1489 while ( inb(tmport
) != 0x8e);
1498 while ((inb(tmport
) & 0x80) == 0 )
1500 if ((inb(tmport
) & 0x01) != 0 )
1505 outb(synn
[j
++],tmport
);
1509 if ((m
& wide_idu
[host
]) != 0)
1511 outb(synw
[j
++],tmport
);
1515 if ((m
& ultra_map
[host
]) != 0)
1517 outb(synu
[j
++],tmport
);
1521 outb(synn
[j
++],tmport
);
1529 while ((inb(tmport
) & 0x80) == 0x00);
1530 j
=inb(tmport
) & 0x0f;
1548 while ((inb(tmport
) & 0x80) == 0x00)
1550 if ((inb(tmport
) & 0x01) != 0x00)
1586 if ((j
& 0x01) != 0x00)
1589 mbuf
[k
++]=inb(tmport
);
1593 if ((j
& 0x80) == 0x00)
1598 while ((inb(tmport
) & 0x80) == 0x00);
1627 while ((inb(tmport
) & 0x80) == 0x00);
1634 if ( mbuf
[0] != 0x01 )
1638 if ( mbuf
[1] != 0x03 )
1642 if ( mbuf
[4] == 0x00 )
1646 if ( mbuf
[3] > 0x64 )
1650 if ( mbuf
[4] > 0x0c )
1654 devspu
[host
][i
] = mbuf
[4];
1655 if ((mbuf
[3] < 0x0d) && (rmb
== 0))
1660 if ( mbuf
[3] < 0x1a )
1665 if ( mbuf
[3] < 0x33 )
1670 if ( mbuf
[3] < 0x4c )
1677 devspu
[host
][i
] = (devspu
[host
][i
] & 0x0f) | j
;
1680 outb((unsigned char)(inb(tmport
) & 0xef),tmport
);
1683 /* return non-zero on detection */
1684 int atp870u_detect(Scsi_Host_Template
* tpnt
)
1686 unsigned char irq
,h
,k
;
1687 unsigned long flags
;
1688 unsigned int base_io
,error
,tmport
;
1689 unsigned short index
= 0;
1690 unsigned char pci_bus
[3], pci_device_fn
[3], chip_ver
[3],host_id
;
1691 struct Scsi_Host
* shpnt
= NULL
;
1693 static unsigned short devid
[7]={0x8002,0x8010,0x8020,0x8030,0x8040,0x8050,0};
1694 static struct pci_dev
*pdev
= NULL
, *acard_pdev
[3];
1696 printk("aec671x_detect: \n");
1699 printk(" NO BIOS32 SUPPORT.\n");
1703 tpnt
->proc_dir
= &proc_scsi_atp870u
;
1705 for ( h
= 0 ; h
< 2 ; h
++ )
1713 pci_device_fn
[h
]=0xff;
1718 for ( k
= 0 ; k
< qcnt
; k
++ )
1722 for ( k
= 0 ; k
< 16 ; k
++ )
1728 while ( devid
[h
] != 0 )
1730 pdev
= pci_find_device(0x1191,devid
[h
],pdev
);
1738 /* To avoid messing with the things below... */
1739 acard_pdev
[2] = pdev
;
1740 pci_device_fn
[2] = pdev
->devfn
;
1741 pci_bus
[2] = pdev
->bus
->number
;
1743 if ( devid
[h
] == 0x8002 )
1745 error
= pci_read_config_byte(pdev
,0x08,&chip_ver
[2]);
1746 if ( chip_ver
[2] < 2 )
1751 if ( devid
[h
] == 0x8010 )
1755 if ( pci_device_fn
[2] < pci_device_fn
[0] )
1757 acard_pdev
[1]=acard_pdev
[0];
1758 pci_bus
[1]=pci_bus
[0];
1759 pci_device_fn
[1]=pci_device_fn
[0];
1760 chip_ver
[1]=chip_ver
[0];
1761 acard_pdev
[0]=acard_pdev
[2];
1762 pci_bus
[0]=pci_bus
[2];
1763 pci_device_fn
[0]=pci_device_fn
[2];
1764 chip_ver
[0]=chip_ver
[2];
1766 else if ( pci_device_fn
[2] < pci_device_fn
[1] )
1768 acard_pdev
[1]=acard_pdev
[2];
1769 pci_bus
[1]=pci_bus
[2];
1770 pci_device_fn
[1]=pci_device_fn
[2];
1771 chip_ver
[1]=chip_ver
[2];
1781 for ( h
=0; h
< 2; h
++ )
1783 if ( pci_device_fn
[h
] == 0xff )
1788 pdev
= acard_pdev
[h
];
1789 pdev
->devfn
= pci_device_fn
[h
];
1790 pdev
->bus
->number
= pci_bus
[h
];
1792 /* Found an atp870u/w. */
1793 error
= pci_read_config_dword(pdev
,0x10,&base_io
);
1794 error
+= pci_read_config_byte(pdev
,0x3c,&irq
);
1795 error
+= pci_read_config_byte(pdev
,0x49,&host_id
);
1797 base_io
&= 0xfffffff8;
1798 printk(" ACARD AEC-671X PCI Ultra/W SCSI-3 Host Adapter: %d IO:%x, IRQ:%d.\n"
1801 pciportu
[h
]=base_io
+ 0x20;
1804 host_idu
[h
]=host_id
;
1805 chip_veru
[h
]=chip_ver
[h
];
1807 tmport
=base_io
+0x22;
1808 scam_on
[h
]=inb(tmport
);
1810 global_map
[h
]=inb(tmport
++);
1811 ultra_map
[h
]=inw(tmport
);
1812 if ( ultra_map
[h
] == 0 )
1816 ultra_map
[h
]=0xffff;
1819 shpnt
= scsi_register(tpnt
,4);
1823 if (request_irq(irq
,atp870u_intr_handle
, 0, "atp870u", NULL
))
1825 printk("Unable to allocate IRQ for Acard controller.\n");
1829 tmport
=base_io
+0x3a;
1830 k
=(inb(tmport
) & 0xf3) | 0x10;
1832 outb((k
& 0xdf),tmport
);
1837 outb((host_id
| 0x08),tmport
);
1841 while ((inb(tmport
) & 0x80) == 0);
1844 tmport
= base_io
+1;
1847 tmport
= base_io
+ 0x11;
1852 tmport
=base_io
+0x3a;
1853 outb((inb(tmport
) & 0xef),tmport
);
1855 atp_host
[h
] = shpnt
;
1856 if ( chip_ver
[h
] == 4 )
1860 shpnt
->this_id
= host_id
;
1861 shpnt
->unique_id
= base_io
;
1862 shpnt
->io_port
= base_io
;
1863 shpnt
->n_io_port
= 0x40; /* Number of bytes of I/O space used */
1865 restore_flags(flags
);
1866 request_region(base_io
, 0x40,"atp870u"); /* Register the IO ports that we use */
1871 scsi_unregister(shpnt
);
1872 restore_flags(flags
);
1880 /* The abort command does not leave the device in a clean state where
1881 it is available to be used again. Until this gets worked out, we will
1882 leave it commented out. */
1884 int atp870u_abort(Scsi_Cmnd
* SCpnt
)
1887 unsigned int tmport
;
1888 /* printk(" atp870u_abort: \n"); */
1889 for ( h
=0; h
<= admaxu
; h
++ )
1891 if ( SCpnt
->host
== atp_host
[h
] )
1896 panic("Abort host not found !");
1898 printk(" workingu=%x last_cmd=%x ",workingu
[h
],last_cmd
[h
]);
1899 printk(" quhdu=%x quendu=%x ",quhdu
[h
],quendu
[h
]);
1901 for ( j
=0; j
< 0x17; j
++)
1903 printk(" r%2x=%2x",j
,inb(tmport
++));
1906 printk(" r1c=%2x",inb(tmport
));
1908 printk(" r1f=%2x in_snd=%2x ",inb(tmport
),in_snd
[h
]);
1910 printk(" r20=%2x",inb(tmport
));
1912 printk(" r22=%2x \n",inb(tmport
));
1913 return (SCSI_ABORT_SNOOZE
);
1916 int atp870u_reset(Scsi_Cmnd
* SCpnt
, unsigned int reset_flags
)
1920 * See if a bus reset was suggested.
1922 /* printk("atp870u_reset: \n"); */
1923 for( h
=0; h
<= admaxu
; h
++ )
1925 if ( SCpnt
->host
== atp_host
[h
] )
1930 panic("Reset bus host not found !");
1932 /* SCpnt->result = 0x00080000;
1933 SCpnt->scsi_done(SCpnt);
1937 return (SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET); */
1938 return (SCSI_RESET_SNOOZE
);
1942 atp870u_info(struct Scsi_Host
*notused
)
1944 static char buffer
[128];
1946 strcpy(buffer
, "ACARD AEC-6710/6712 PCI Ultra/W SCSI-3 Adapter Driver V1.0 ");
1952 atp870u_set_info(char *buffer
, int length
, struct Scsi_Host
*HBAptr
)
1954 return (-ENOSYS
); /* Currently this is a no-op */
1957 #define BLS buffer + len + size
1959 atp870u_proc_info(char *buffer
, char **start
, off_t offset
, int length
,
1960 int hostno
, int inout
)
1962 struct Scsi_Host
*HBAptr
;
1963 static u8 buff
[512];
1971 for (i
= 0; i
< 2; i
++)
1973 if ((HBAptr
= atp_host
[i
]) != NULL
)
1975 if (HBAptr
->host_no
== hostno
)
1985 size
+= sprintf(BLS
, "Can't find adapter for host number %d\n", hostno
);
1986 len
+= size
; pos
= begin
+ len
; size
= 0;
1990 if (inout
== TRUE
) /* Has data been written to the file? */
1992 return (atp870u_set_info(buffer
, length
, HBAptr
));
1997 memset(buff
, 0, sizeof(buff
));
2000 size
+= sprintf(BLS
, "ACARD AEC-671X Driver Version: 1.0\n");
2001 len
+= size
; pos
= begin
+ len
; size
= 0;
2003 size
+= sprintf(BLS
, "\n");
2004 size
+= sprintf(BLS
, "Adapter Configuration:\n");
2005 size
+= sprintf(BLS
, " Base IO: %#.4lx\n", HBAptr
->io_port
);
2006 size
+= sprintf(BLS
, " IRQ: %d\n", HBAptr
->irq
);
2007 len
+= size
; pos
= begin
+ len
; size
= 0;
2010 *start
= buffer
+ (offset
- begin
); /* Start of wanted data */
2011 len
-= (offset
- begin
); /* Start slop */
2014 len
= length
; /* Ending slop */
2022 int atp870u_biosparam(Scsi_Disk
* disk
, kdev_t dev
, int * ip
)
2024 int heads
, sectors
, cylinders
;
2028 cylinders
= disk
->capacity
/ (heads
* sectors
);
2030 if ( cylinders
> 1024 )
2034 cylinders
= disk
->capacity
/ (heads
* sectors
);
2045 Scsi_Host_Template driver_template
= ATP870U
;
2047 #include "scsi_module.c"