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
6 * 2.5.x update (C) 2002 Red Hat <alan@redhat.com>
8 * Marcelo Tosatti <marcelo@conectiva.com.br> : SMP fixes
10 * Wu Ching Chen : NULL pointer fixes 2000/06/02
12 * enable 32 bit fifo transfer
13 * support cdrom & remove device run ultra speed
14 * fix disconnect bug 2000/12/21
15 * support atp880 chip lvd u160 2001/05/15
16 * fix prd table bug 2001/09/12 (7.1)
19 #include <linux/module.h>
20 #include <linux/interrupt.h>
21 #include <linux/kernel.h>
22 #include <linux/types.h>
23 #include <linux/string.h>
24 #include <linux/ioport.h>
25 #include <linux/delay.h>
26 #include <linux/proc_fs.h>
27 #include <linux/spinlock.h>
28 #include <linux/pci.h>
29 #include <linux/blkdev.h>
30 #include <linux/stat.h>
32 #include <asm/system.h>
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 short int sync_idu
;
50 unsigned long pciport
;
51 unsigned char last_cmd
;
56 unsigned char scam_on
;
57 unsigned char global_map
;
58 unsigned char chip_veru
;
59 unsigned char host_idu
;
61 unsigned short wide_idu
;
62 unsigned short active_idu
;
63 unsigned short ultra_map
;
65 unsigned short deviceid
;
66 unsigned char ata_cdbu
[16];
68 Scsi_Cmnd
*querequ
[qcnt
];
72 unsigned char devtypeu
;
73 unsigned long prdaddru
;
74 unsigned long tran_lenu
;
75 unsigned long last_lenu
;
76 unsigned char *prd_posu
;
77 unsigned char *prd_tableu
;
81 struct Scsi_Host
*host
;
85 static struct Scsi_Host
*atp_host
[MAX_ATP
];
87 static void send_s870(struct Scsi_Host
*);
89 static irqreturn_t
atp870u_intr_handle(int irq
, void *dev_id
,
93 unsigned short int tmpcip
, id
;
94 unsigned char i
, j
, target_id
, lun
;
97 unsigned int workportu
, tmport
;
98 unsigned long adrcntu
, k
;
100 struct Scsi_Host
*host
= dev_id
;
101 struct atp_unit
*dev
= (struct atp_unit
*)&host
->hostdata
;
104 workportu
= dev
->ioport
;
107 if (dev
->working
!= 0) {
110 if ((j
& 0x80) == 0) {
115 tmpcip
= dev
->pciport
;
116 if ((inb(tmpcip
) & 0x08) != 0) {
118 for (k
= 0; k
< 1000; k
++) {
119 if ((inb(tmpcip
) & 0x08) == 0) {
122 if ((inb(tmpcip
) & 0x01) == 0) {
128 tmpcip
= dev
->pciport
;
135 target_id
= inb(tmport
);
139 * Remap wide devices onto id numbers
142 if ((target_id
& 0x40) != 0) {
143 target_id
= (target_id
& 0x07) | 0x08;
148 if ((j
& 0x40) != 0) {
149 if (dev
->last_cmd
== 0xff) {
150 dev
->last_cmd
= target_id
;
152 dev
->last_cmd
|= 0x40;
156 if ((dev
->last_cmd
& 0xf0) != 0x40) {
157 dev
->last_cmd
= 0xff;
162 if (dev
->wide_idu
!= 0) {
163 tmport
= workportu
+ 0x1b;
165 while ((inb(tmport
) & 0x01) != 0x01) {
170 * Issue more commands
172 if (((dev
->quhdu
!= dev
->quendu
) || (dev
->last_cmd
!= 0xff)) && (dev
->in_snd
== 0)) {
183 dev
->last_cmd
|= 0x40;
189 if ((dev
->last_cmd
& 0xf0) != 0x40) {
190 dev
->last_cmd
= 0xff;
194 ((unsigned char *) &adrcntu
)[2] = inb(tmport
++);
195 ((unsigned char *) &adrcntu
)[1] = inb(tmport
++);
196 ((unsigned char *) &adrcntu
)[0] = inb(tmport
);
197 k
= dev
->id
[target_id
].last_lenu
;
199 dev
->id
[target_id
].tran_lenu
= k
;
200 dev
->id
[target_id
].last_lenu
= adrcntu
;
208 if ((i
== 0x80) || (i
== 0x8f)) {
212 if (j
== 0x44 || i
== 0x80) {
214 lun
= inb(tmport
) & 0x07;
216 if ((dev
->last_cmd
& 0xf0) != 0x40) {
217 dev
->last_cmd
= 0xff;
222 ((unsigned char *) &adrcntu
)[2] = inb(tmport
++);
223 ((unsigned char *) &adrcntu
)[1] = inb(tmport
++);
224 ((unsigned char *) &adrcntu
)[0] = inb(tmport
);
225 k
= dev
->id
[target_id
].last_lenu
;
227 dev
->id
[target_id
].tran_lenu
= k
;
228 dev
->id
[target_id
].last_lenu
= adrcntu
;
235 dev
->id
[target_id
].dirctu
= 0x00;
237 outb(0x00, tmport
++);
238 outb(0x00, tmport
++);
239 outb(0x00, tmport
++);
246 if (dev
->last_cmd
!= 0xff) {
247 dev
->last_cmd
|= 0x40;
249 tmport
= workportu
+ 0x10;
252 target_id
= inb(tmport
);
254 * Remap wide identifiers
256 if ((target_id
& 0x10) != 0) {
257 target_id
= (target_id
& 0x07) | 0x08;
261 workrequ
= dev
->id
[target_id
].curr_req
;
262 tmport
= workportu
+ 0x0f;
265 outb(dev
->id
[target_id
].devspu
, tmport
++);
266 adrcntu
= dev
->id
[target_id
].tran_lenu
;
267 k
= dev
->id
[target_id
].last_lenu
;
268 outb(((unsigned char *) &k
)[2], tmport
++);
269 outb(((unsigned char *) &k
)[1], tmport
++);
270 outb(((unsigned char *) &k
)[0], tmport
++);
274 j
= (j
& 0x07) | 0x40;
277 j
|= dev
->id
[target_id
].dirctu
;
281 /* enable 32 bit fifo transfer */
282 if (dev
->deviceid
!= 0x8081) {
283 tmport
= workportu
+ 0x3a;
284 if ((dev
->ata_cdbu
[0] == 0x08) || (dev
->ata_cdbu
[0] == 0x28) || (dev
->ata_cdbu
[0] == 0x0a) || (dev
->ata_cdbu
[0] == 0x2a)) {
285 outb((unsigned char) ((inb(tmport
) & 0xf3) | 0x08), tmport
);
287 outb((unsigned char) (inb(tmport
) & 0xf3), tmport
);
290 tmport
= workportu
- 0x05;
291 if ((dev
->ata_cdbu
[0] == 0x08) || (dev
->ata_cdbu
[0] == 0x28) || (dev
->ata_cdbu
[0] == 0x0a) || (dev
->ata_cdbu
[0] == 0x2a)) {
292 outb((unsigned char) ((inb(tmport
) & 0x3f) | 0xc0), tmport
);
294 outb((unsigned char) (inb(tmport
) & 0x3f), tmport
);
298 tmport
= workportu
+ 0x1b;
301 id
= id
<< target_id
;
303 * Is this a wide device
305 if ((id
& dev
->wide_idu
) != 0) {
309 while ((inb(tmport
) & 0x01) != j
) {
313 if (dev
->id
[target_id
].last_lenu
== 0) {
314 tmport
= workportu
+ 0x18;
319 prd
= dev
->id
[target_id
].prd_posu
;
320 while (adrcntu
!= 0) {
321 id
= ((unsigned short int *) (prd
))[2];
328 ((unsigned short int *) (prd
))[2] = (unsigned short int)
330 ((unsigned long *) (prd
))[0] += adrcntu
;
332 dev
->id
[target_id
].prd_posu
= prd
;
335 dev
->id
[target_id
].prdaddru
+= 0x08;
338 dev
->id
[target_id
].prd_posu
= prd
;
342 tmpcip
= dev
->pciport
+ 0x04;
343 outl(dev
->id
[target_id
].prdaddru
, tmpcip
);
348 tmport
= workportu
+ 0x18;
350 * Check transfer direction
352 if (dev
->id
[target_id
].dirctu
!= 0) {
365 * Current scsi request on this target
368 workrequ
= dev
->id
[target_id
].curr_req
;
371 if ((dev
->last_cmd
& 0xf0) != 0x40) {
372 dev
->last_cmd
= 0xff;
375 workrequ
->result
= errstus
;
379 if ((dev
->last_cmd
& 0xf0) != 0x40) {
380 dev
->last_cmd
= 0xff;
384 errstus
= inb(tmport
);
385 workrequ
->result
= errstus
;
388 * Complete the command
392 pci_unmap_sg(dev
->pdev
, (struct scatterlist
*)workrequ
->buffer
, workrequ
->use_sg
, scsi_to_pci_dma_dir(workrequ
->sc_data_direction
));
393 else if(workrequ
->request_bufflen
&& workrequ
->sc_data_direction
!= SCSI_DATA_NONE
)
394 pci_unmap_single(dev
->pdev
, workrequ
->SCp
.dma_handle
, workrequ
->request_bufflen
, scsi_to_pci_dma_dir(workrequ
->sc_data_direction
));
395 spin_lock_irqsave(dev
->host
->host_lock
, flags
);
396 (*workrequ
->scsi_done
) (workrequ
);
399 * Clear it off the queue
401 dev
->id
[target_id
].curr_req
= 0;
403 spin_unlock_irqrestore(dev
->host
->host_lock
, flags
);
407 if (dev
->wide_idu
!= 0) {
408 tmport
= workportu
+ 0x1b;
410 while ((inb(tmport
) & 0x01) != 0x01) {
415 * If there is stuff to send and nothing going then send it
417 if (((dev
->last_cmd
!= 0xff) || (dev
->quhdu
!= dev
->quendu
)) && (dev
->in_snd
== 0)) {
423 if ((dev
->last_cmd
& 0xf0) != 0x40) {
424 dev
->last_cmd
= 0xff;
432 outl(dev
->id
[target_id
].prdaddru
, tmpcip
);
437 tmport
= workportu
+ 0x10;
439 dev
->id
[target_id
].dirctu
= 0x00;
448 outl(dev
->id
[target_id
].prdaddru
, tmpcip
);
453 tmport
= workportu
+ 0x10;
456 outb((unsigned char) (inb(tmport
) | 0x20), tmport
);
457 dev
->id
[target_id
].dirctu
= 0x20;
470 dev
->id
[target_id
].dirctu
= 0x00;
472 outb(0x00, tmport
++);
473 outb(0x00, tmport
++);
474 outb(0x00, tmport
++);
480 // tmport = workportu + 0x17;
489 static int atp870u_queuecommand(Scsi_Cmnd
* req_p
, void (*done
) (Scsi_Cmnd
*))
492 unsigned short int m
;
494 struct Scsi_Host
*host
;
495 struct atp_unit
*dev
;
497 if (req_p
->device
->channel
!= 0) {
498 req_p
->result
= 0x00040000;
503 host
= req_p
->device
->host
;
504 dev
= (struct atp_unit
*)&host
->hostdata
;
507 m
= m
<< req_p
->device
->id
;
510 * Fake a timeout for missing targets
513 if ((m
& dev
->active_idu
) == 0) {
514 req_p
->result
= 0x00040000;
519 req_p
->scsi_done
= done
;
521 printk(KERN_WARNING
"atp870u_queuecommand: done can't be NULL\n");
530 spin_lock_irqsave(host
->host_lock
, flags
);
532 if (dev
->quendu
>= qcnt
) {
538 if (dev
->quhdu
== dev
->quendu
) {
539 if (dev
->quendu
== 0) {
543 req_p
->result
= 0x00020000;
544 spin_unlock_irqrestore(host
->host_lock
, flags
);
548 dev
->querequ
[dev
->quendu
] = req_p
;
549 tmport
= dev
->ioport
+ 0x1c;
550 spin_unlock_irqrestore(host
->host_lock
, flags
);
551 if ((inb(tmport
) == 0) && (dev
->in_int
== 0) && (dev
->in_snd
== 0)) {
557 static void send_s870(struct Scsi_Host
*host
)
563 unsigned char j
, target_id
;
565 unsigned short int tmpcip
, w
;
568 unsigned int workportu
;
569 struct scatterlist
*sgpnt
;
570 struct atp_unit
*dev
= (struct atp_unit
*)&host
->hostdata
;
573 spin_lock_irqsave(host
->host_lock
, flags
);
575 if (dev
->in_snd
!= 0) {
576 spin_unlock_irqrestore(host
->host_lock
, flags
);
580 if ((dev
->last_cmd
!= 0xff) && ((dev
->last_cmd
& 0x40) != 0)) {
581 dev
->last_cmd
&= 0x0f;
582 workrequ
= dev
->id
[dev
->last_cmd
].curr_req
;
583 if (workrequ
!= NULL
) { /* check NULL pointer */
586 dev
->last_cmd
= 0xff;
587 if (dev
->quhdu
== dev
->quendu
) {
589 spin_unlock_irqrestore(dev
->host
->host_lock
, flags
);
593 if ((dev
->last_cmd
!= 0xff) && (dev
->working
!= 0)) {
595 spin_unlock_irqrestore(dev
->host
->host_lock
, flags
);
601 if (dev
->quhdu
>= qcnt
) {
604 workrequ
= dev
->querequ
[dev
->quhdu
];
605 if (dev
->id
[workrequ
->device
->id
].curr_req
== 0) {
606 dev
->id
[workrequ
->device
->id
].curr_req
= workrequ
;
607 dev
->last_cmd
= workrequ
->device
->id
;
613 spin_unlock_irqrestore(host
->host_lock
, flags
);
616 workportu
= dev
->ioport
;
617 tmport
= workportu
+ 0x1f;
618 if ((inb(tmport
) & 0xb0) != 0) {
621 tmport
= workportu
+ 0x1c;
622 if (inb(tmport
) == 0) {
626 dev
->last_cmd
|= 0x40;
628 spin_unlock_irqrestore(dev
->host
->host_lock
, flags
);
631 memcpy(&dev
->ata_cdbu
[0], &workrequ
->cmnd
[0], workrequ
->cmd_len
);
632 if (dev
->ata_cdbu
[0] == READ_CAPACITY
) {
633 if (workrequ
->request_bufflen
> 8) {
634 workrequ
->request_bufflen
= 0x08;
637 if (dev
->ata_cdbu
[0] == 0x00) {
638 workrequ
->request_bufflen
= 0;
641 tmport
= workportu
+ 0x1b;
643 target_id
= workrequ
->device
->id
;
650 if ((w
& dev
->wide_idu
) != 0) {
654 while ((inb(tmport
) & 0x01) != j
) {
663 outb(workrequ
->cmd_len
, tmport
++);
664 outb(0x2c, tmport
++);
665 outb(0xcf, tmport
++);
666 for (i
= 0; i
< workrequ
->cmd_len
; i
++) {
667 outb(dev
->ata_cdbu
[i
], tmport
++);
669 tmport
= workportu
+ 0x0f;
670 outb(workrequ
->device
->lun
, tmport
);
675 outb(dev
->id
[target_id
].devspu
, tmport
++);
678 * Figure out the transfer size
680 if (workrequ
->use_sg
) {
682 sgpnt
= (struct scatterlist
*) workrequ
->request_buffer
;
683 sg_count
= pci_map_sg(dev
->pdev
, sgpnt
, workrequ
->use_sg
, scsi_to_pci_dma_dir(workrequ
->sc_data_direction
));
684 for (i
= 0; i
< workrequ
->use_sg
; i
++) {
685 if (sgpnt
[i
].length
== 0 || workrequ
->use_sg
> ATP870U_SCATTER
) {
686 panic("Foooooooood fight!");
688 l
+= sgpnt
[i
].length
;
690 } else if(workrequ
->request_bufflen
&& workrequ
->sc_data_direction
!= PCI_DMA_NONE
) {
691 workrequ
->SCp
.dma_handle
= pci_map_single(dev
->pdev
, workrequ
->request_buffer
, workrequ
->request_bufflen
, scsi_to_pci_dma_dir(workrequ
->sc_data_direction
));
692 l
= workrequ
->request_bufflen
;
696 * Write transfer size
698 outb((unsigned char) (((unsigned char *) (&l
))[2]), tmport
++);
699 outb((unsigned char) (((unsigned char *) (&l
))[1]), tmport
++);
700 outb((unsigned char) (((unsigned char *) (&l
))[0]), tmport
++);
702 dev
->id
[j
].last_lenu
= l
;
703 dev
->id
[j
].tran_lenu
= 0;
707 if ((j
& 0x08) != 0) {
708 j
= (j
& 0x07) | 0x40;
711 * Check transfer direction
713 if (workrequ
->sc_data_direction
== SCSI_DATA_WRITE
) {
714 outb((unsigned char) (j
| 0x20), tmport
++);
718 outb((unsigned char) (inb(tmport
) | 0x80), tmport
);
720 tmport
= workportu
+ 0x1c;
721 dev
->id
[target_id
].dirctu
= 0;
723 if (inb(tmport
) == 0) {
724 tmport
= workportu
+ 0x18;
727 dev
->last_cmd
|= 0x40;
730 spin_unlock_irqrestore(host
->host_lock
, flags
);
733 tmpcip
= dev
->pciport
;
734 prd
= dev
->id
[target_id
].prd_tableu
;
735 dev
->id
[target_id
].prd_posu
= prd
;
738 * Now write the request list. Either as scatter/gather or as
742 if (workrequ
->use_sg
) {
743 sgpnt
= (struct scatterlist
*) workrequ
->request_buffer
;
745 for (j
= 0; j
< workrequ
->use_sg
; j
++) {
746 bttl
= sg_dma_address(&sgpnt
[j
]);
747 l
= sg_dma_len(&sgpnt
[j
]);
748 while (l
> 0x10000) {
749 (u16
) (((u16
*) (prd
))[i
+ 3]) = 0x0000;
750 (u16
) (((u16
*) (prd
))[i
+ 2]) = 0x0000;
751 (u32
) (((u32
*) (prd
))[i
>> 1]) = cpu_to_le32(bttl
);
756 (u32
) (((u32
*) (prd
))[i
>> 1]) = cpu_to_le32(bttl
);
757 (u16
) (((u16
*) (prd
))[i
+ 2]) = cpu_to_le16(l
);
758 (u16
) (((u16
*) (prd
))[i
+ 3]) = 0;
761 (u16
) (((u16
*) (prd
))[i
- 1]) = cpu_to_le16(0x8000);
764 * For a linear request write a chain of blocks
766 bttl
= workrequ
->SCp
.dma_handle
;
767 l
= workrequ
->request_bufflen
;
769 while (l
> 0x10000) {
770 (u16
) (((u16
*) (prd
))[i
+ 3]) = 0x0000;
771 (u16
) (((u16
*) (prd
))[i
+ 2]) = 0x0000;
772 (u32
) (((u32
*) (prd
))[i
>> 1]) = cpu_to_le32(bttl
);
777 (u16
) (((u16
*) (prd
))[i
+ 3]) = cpu_to_le16(0x8000);
778 (u16
) (((u16
*) (prd
))[i
+ 2]) = cpu_to_le16(l
);
779 (u32
) (((u32
*) (prd
))[i
>> 1]) = cpu_to_le32(bttl
);
782 dev
->id
[target_id
].prdaddru
= dev
->id
[target_id
].prd_phys
;
783 outl(dev
->id
[target_id
].prd_phys
, tmpcip
);
789 if (dev
->deviceid
!= 0x8081) {
790 tmport
= workportu
+ 0x3a;
791 if ((dev
->ata_cdbu
[0] == 0x08) || (dev
->ata_cdbu
[0] == 0x28) || (dev
->ata_cdbu
[0] == 0x0a) || (dev
->ata_cdbu
[0] == 0x2a)) {
792 outb((inb(tmport
) & 0xf3) | 0x08, tmport
);
794 outb(inb(tmport
) & 0xf3, tmport
);
797 tmport
= workportu
- 0x05;
798 if ((dev
->ata_cdbu
[0] == 0x08) || (dev
->ata_cdbu
[0] == 0x28) || (dev
->ata_cdbu
[0] == 0x0a) || (dev
->ata_cdbu
[0] == 0x2a)) {
799 outb((unsigned char) ((inb(tmport
) & 0x3f) | 0xc0), tmport
);
801 outb((unsigned char) (inb(tmport
) & 0x3f), tmport
);
804 tmport
= workportu
+ 0x1c;
806 if (workrequ
->sc_data_direction
== SCSI_DATA_WRITE
) {
807 dev
->id
[target_id
].dirctu
= 0x20;
808 if (inb(tmport
) == 0) {
809 tmport
= workportu
+ 0x18;
813 dev
->last_cmd
|= 0x40;
816 spin_unlock_irqrestore(host
->host_lock
, flags
);
819 if (inb(tmport
) == 0) {
820 tmport
= workportu
+ 0x18;
824 dev
->last_cmd
|= 0x40;
827 spin_unlock_irqrestore(host
->host_lock
, flags
);
832 static unsigned char fun_scam(struct atp_unit
*dev
, unsigned short int *val
)
835 unsigned short int i
, k
;
838 tmport
= dev
->ioport
+ 0x1c;
841 for (i
= 0; i
< 10; i
++) { /* stable >= bus settle delay(400 ns) */
843 j
= (unsigned char) (k
>> 8);
844 if ((k
& 0x8000) != 0) { /* DB7 all release? */
848 *val
|= 0x4000; /* assert DB6 */
850 *val
&= 0xdfff; /* assert DB5 */
853 for (i
= 0; i
< 10; i
++) { /* stable >= bus settle delay(400 ns) */
854 if ((inw(tmport
) & 0x2000) != 0) { /* DB5 all release? */
858 *val
|= 0x8000; /* no DB4-0, assert DB7 */
861 *val
&= 0xbfff; /* release DB6 */
864 for (i
= 0; i
< 10; i
++) { /* stable >= bus settle delay(400 ns) */
865 if ((inw(tmport
) & 0x4000) != 0) { /* DB6 all release? */
873 static void tscam(struct Scsi_Host
*host
)
877 unsigned char i
, j
, k
;
879 unsigned short int m
, assignid_map
, val
;
880 unsigned char mbuf
[33], quintet
[2];
881 struct atp_unit
*dev
= (struct atp_unit
*)host
->hostdata
;
882 static unsigned char g2q_tab
[8] = {
883 0x38, 0x31, 0x32, 0x2b, 0x34, 0x2d, 0x2e, 0x27
886 /* I can't believe we need this before we've even done anything. Remove it
887 * and see if anyone bitches.
888 for (i = 0; i < 0x10; i++) {
893 tmport
= dev
->ioport
+ 1;
894 outb(0x08, tmport
++);
896 tmport
= dev
->ioport
+ 0x11;
899 if ((dev
->scam_on
& 0x40) == 0) {
905 if (dev
->chip_veru
< 4) {
910 tmport
= dev
->ioport
+ 0x02;
911 outb(0x02, tmport
++); /* 2*2=4ms,3EH 2/32*3E=3.9ms */
919 for (i
= 0; i
< j
; i
++) {
922 if ((m
& assignid_map
) != 0) {
925 tmport
= dev
->ioport
+ 0x0f;
932 k
= (i
& 0x07) | 0x40;
937 tmport
= dev
->ioport
+ 0x1b;
938 if (dev
->chip_veru
== 4) {
944 tmport
= dev
->ioport
+ 0x18;
948 while ((inb(tmport
) & 0x80) == 0x00);
952 if ((k
== 0x85) || (k
== 0x42)) {
955 tmport
= dev
->ioport
+ 0x10;
962 tmport
= dev
->ioport
+ 0x02;
964 tmport
= dev
->ioport
+ 0x1b;
969 val
= 0x0080; /* bsy */
970 tmport
= dev
->ioport
+ 0x1c;
972 val
|= 0x0040; /* sel */
974 val
|= 0x0004; /* msg */
976 inb(0x80); /* 2 deskew delay(45ns*2=90ns) */
977 val
&= 0x007f; /* no bsy */
980 val
&= 0x00fb; /* after 1ms no msg */
983 if ((inb(tmport
) & 0x04) != 0) {
988 for (n
= 0; n
< 0x30000; n
++) {
989 if ((inb(tmport
) & 0x80) != 0) { /* bsy ? */
995 for (n
= 0; n
< 0x30000; n
++) {
996 if ((inb(tmport
) & 0x81) == 0x0081) {
1003 val
|= 0x8003; /* io,cd,db7 */
1006 val
&= 0x00bf; /* no sel */
1011 if ((inb(tmport
) & 0x80) == 0x00) { /* bsy ? */
1014 tmport
= dev
->ioport
+ 0x15;
1019 while ((inb(tmport
) & 0x80) == 0);
1024 val
&= 0x00ff; /* synchronization */
1026 fun_scam(dev
, &val
);
1028 val
&= 0x00ff; /* isolation */
1030 fun_scam(dev
, &val
);
1035 if ((inw(tmport
) & 0x2000) == 0) {
1039 val
&= 0x00ff; /* get ID_STRING */
1041 k
= fun_scam(dev
, &val
);
1042 if ((k
& 0x03) == 0) {
1047 if ((k
& 0x02) != 0) {
1058 TCM_5
: /* isolation complete.. */
1060 printk(" \n%x %x %x %s\n ",assignid_map,mbuf[0],mbuf[1],&mbuf[2]); */
1063 if ((j
& 0x20) != 0) { /* bit5=1:ID upto 7 */
1066 if ((j
& 0x06) == 0) { /* IDvalid? */
1073 if ((m
& assignid_map
) == 0) {
1080 G2Q5
: /* srch from max acceptable ID# */
1081 k
= i
; /* max acceptable ID# */
1085 if ((m
& assignid_map
) == 0) {
1092 G2Q_QUIN
: /* k=binID#, */
1095 quintet
[0] = 0x38; /* 1st dft ID<8 */
1097 quintet
[0] = 0x31; /* 1st ID>=8 */
1100 quintet
[1] = g2q_tab
[k
];
1102 val
&= 0x00ff; /* AssignID 1stQuintet,AH=001xxxxx */
1103 m
= quintet
[0] << 8;
1105 fun_scam(dev
, &val
);
1106 val
&= 0x00ff; /* AssignID 2ndQuintet,AH=001xxxxx */
1107 m
= quintet
[1] << 8;
1109 fun_scam(dev
, &val
);
1115 void is870(struct Scsi_Host
*host
, unsigned int wkport
)
1117 unsigned int tmport
;
1118 unsigned char i
, j
, k
, rmb
, n
;
1119 unsigned short int m
;
1120 static unsigned char mbuf
[512];
1121 static unsigned char satn
[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 };
1122 static unsigned char inqd
[9] = { 0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6 };
1123 static unsigned char synn
[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
1124 static unsigned char synu
[6] = { 0x80, 1, 3, 1, 0x0c, 0x0e };
1125 static unsigned char synw
[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 };
1126 static unsigned char wide
[6] = { 0x80, 1, 2, 3, 1, 0 };
1127 struct atp_unit
*dev
= (struct atp_unit
*)&host
->hostdata
;
1130 tmport
= wkport
+ 0x3a;
1131 outb((unsigned char) (inb(tmport
) | 0x10), tmport
);
1133 for (i
= 0; i
< 16; i
++) {
1134 if ((dev
->chip_veru
!= 4) && (i
> 7)) {
1139 if ((m
& dev
->active_idu
) != 0) {
1142 if (i
== dev
->host_idu
) {
1143 printk(KERN_INFO
" ID: %2d Host Adapter\n", dev
->host_idu
);
1146 tmport
= wkport
+ 0x1b;
1147 if (dev
->chip_veru
== 4) {
1152 tmport
= wkport
+ 1;
1153 outb(0x08, tmport
++);
1154 outb(0x7f, tmport
++);
1155 outb(satn
[0], tmport
++);
1156 outb(satn
[1], tmport
++);
1157 outb(satn
[2], tmport
++);
1158 outb(satn
[3], tmport
++);
1159 outb(satn
[4], tmport
++);
1160 outb(satn
[5], tmport
++);
1164 outb(dev
->id
[i
].devspu
, tmport
++);
1166 outb(satn
[6], tmport
++);
1167 outb(satn
[7], tmport
++);
1169 if ((j
& 0x08) != 0) {
1170 j
= (j
& 0x07) | 0x40;
1174 outb(satn
[8], tmport
);
1177 while ((inb(tmport
) & 0x80) == 0x00);
1179 if ((inb(tmport
) != 0x11) && (inb(tmport
) != 0x8e)) {
1182 while (inb(tmport
) != 0x8e);
1183 dev
->active_idu
|= m
;
1185 tmport
= wkport
+ 0x10;
1187 tmport
= wkport
+ 0x04;
1191 tmport
= wkport
+ 0x18;
1194 while ((inb(tmport
) & 0x80) == 0x00);
1198 tmport
= wkport
+ 0x10;
1203 tmport
= wkport
+ 3;
1204 outb(inqd
[0], tmport
++);
1205 outb(inqd
[1], tmport
++);
1206 outb(inqd
[2], tmport
++);
1207 outb(inqd
[3], tmport
++);
1208 outb(inqd
[4], tmport
++);
1209 outb(inqd
[5], tmport
);
1213 outb(dev
->id
[i
].devspu
, tmport
++);
1215 outb(inqd
[6], tmport
++);
1216 outb(inqd
[7], tmport
++);
1218 outb(inqd
[8], tmport
);
1220 while ((inb(tmport
) & 0x80) == 0x00);
1222 if ((inb(tmport
) != 0x11) && (inb(tmport
) != 0x8e)) {
1225 while (inb(tmport
) != 0x8e);
1226 tmport
= wkport
+ 0x1b;
1227 if (dev
->chip_veru
== 4) {
1230 tmport
= wkport
+ 0x18;
1236 if ((k
& 0x01) != 0) {
1238 mbuf
[j
++] = inb(tmport
);
1242 if ((k
& 0x80) == 0) {
1250 tmport
= wkport
+ 0x10;
1259 while ((inb(tmport
) & 0x80) == 0x00);
1261 if (inb(tmport
) != 0x16) {
1266 printk(KERN_INFO
" ID: %2d %s\n", i
, &mbuf
[8]);
1267 dev
->id
[i
].devtypeu
= mbuf
[0];
1270 if (dev
->chip_veru
!= 4) {
1273 if ((mbuf
[7] & 0x60) == 0) {
1276 if ((dev
->global_map
& 0x20) == 0) {
1279 tmport
= wkport
+ 0x1b;
1281 tmport
= wkport
+ 3;
1282 outb(satn
[0], tmport
++);
1283 outb(satn
[1], tmport
++);
1284 outb(satn
[2], tmport
++);
1285 outb(satn
[3], tmport
++);
1286 outb(satn
[4], tmport
++);
1287 outb(satn
[5], tmport
++);
1291 outb(dev
->id
[i
].devspu
, tmport
++);
1293 outb(satn
[6], tmport
++);
1294 outb(satn
[7], tmport
++);
1296 outb(satn
[8], tmport
);
1299 while ((inb(tmport
) & 0x80) == 0x00);
1301 if ((inb(tmport
) != 0x11) && (inb(tmport
) != 0x8e)) {
1304 while (inb(tmport
) != 0x8e);
1307 tmport
= wkport
+ 0x14;
1313 while ((inb(tmport
) & 0x80) == 0) {
1314 if ((inb(tmport
) & 0x01) != 0) {
1316 outb(wide
[j
++], tmport
);
1321 while ((inb(tmport
) & 0x80) == 0x00);
1322 j
= inb(tmport
) & 0x0f;
1334 tmport
= wkport
+ 0x18;
1337 while ((inb(tmport
) & 0x80) == 0) {
1338 if ((inb(tmport
) & 0x01) != 0) {
1345 j
= inb(tmport
) & 0x0f;
1357 tmport
= wkport
+ 0x14;
1365 if ((j
& 0x01) != 0) {
1367 mbuf
[k
++] = inb(tmport
);
1371 if ((j
& 0x80) == 0x00) {
1375 j
= inb(tmport
) & 0x0f;
1387 tmport
= wkport
+ 0x10;
1389 tmport
= wkport
+ 0x14;
1394 while ((inb(tmport
) & 0x80) == 0x00);
1403 if (mbuf
[0] != 0x01) {
1406 if (mbuf
[1] != 0x02) {
1409 if (mbuf
[2] != 0x03) {
1412 if (mbuf
[3] != 0x01) {
1419 if ((dev
->id
[i
].devtypeu
== 0x00) || (dev
->id
[i
].devtypeu
== 0x07) || ((dev
->id
[i
].devtypeu
== 0x05) && ((n
& 0x10) != 0))) {
1424 tmport
= wkport
+ 0x1b;
1426 if ((m
& dev
->wide_idu
) != 0) {
1430 tmport
= wkport
+ 3;
1431 outb(satn
[0], tmport
++);
1432 outb(satn
[1], tmport
++);
1433 outb(satn
[2], tmport
++);
1434 outb(satn
[3], tmport
++);
1435 outb(satn
[4], tmport
++);
1436 outb(satn
[5], tmport
++);
1440 outb(dev
->id
[i
].devspu
, tmport
++);
1442 outb(satn
[6], tmport
++);
1443 outb(satn
[7], tmport
++);
1445 outb(satn
[8], tmport
);
1448 while ((inb(tmport
) & 0x80) == 0x00);
1450 if ((inb(tmport
) != 0x11) && (inb(tmport
) != 0x8e)) {
1453 while (inb(tmport
) != 0x8e);
1456 tmport
= wkport
+ 0x14;
1462 while ((inb(tmport
) & 0x80) == 0) {
1463 if ((inb(tmport
) & 0x01) != 0) {
1465 if ((m
& dev
->wide_idu
) != 0) {
1466 outb(synw
[j
++], tmport
);
1468 if ((m
& dev
->ultra_map
) != 0) {
1469 outb(synu
[j
++], tmport
);
1471 outb(synn
[j
++], tmport
);
1478 while ((inb(tmport
) & 0x80) == 0x00);
1479 j
= inb(tmport
) & 0x0f;
1491 tmport
= wkport
+ 0x18;
1494 while ((inb(tmport
) & 0x80) == 0x00) {
1495 if ((inb(tmport
) & 0x01) != 0x00) {
1518 tmport
= wkport
+ 0x14;
1526 if ((j
& 0x01) != 0x00) {
1528 mbuf
[k
++] = inb(tmport
);
1532 if ((j
& 0x80) == 0x00) {
1536 while ((inb(tmport
) & 0x80) == 0x00);
1553 tmport
= wkport
+ 0x10;
1556 tmport
= wkport
+ 0x14;
1561 while ((inb(tmport
) & 0x80) == 0x00);
1567 if (mbuf
[0] != 0x01) {
1570 if (mbuf
[1] != 0x03) {
1573 if (mbuf
[4] == 0x00) {
1576 if (mbuf
[3] > 0x64) {
1579 if (mbuf
[4] > 0x0c) {
1582 dev
->id
[i
].devspu
= mbuf
[4];
1583 if ((mbuf
[3] < 0x0d) && (rmb
== 0)) {
1587 if (mbuf
[3] < 0x1a) {
1591 if (mbuf
[3] < 0x33) {
1595 if (mbuf
[3] < 0x4c) {
1601 dev
->id
[i
].devspu
= (dev
->id
[i
].devspu
& 0x0f) | j
;
1603 tmport
= wkport
+ 0x3a;
1604 outb((unsigned char) (inb(tmport
) & 0xef), tmport
);
1607 static void is880(struct Scsi_Host
*host
, unsigned int wkport
)
1609 unsigned int tmport
;
1610 unsigned char i
, j
, k
, rmb
, n
, lvdmode
;
1611 unsigned short int m
;
1612 static unsigned char mbuf
[512];
1613 static unsigned char satn
[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 };
1614 static unsigned char inqd
[9] = { 0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6 };
1615 static unsigned char synn
[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
1616 unsigned char synu
[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e };
1617 static unsigned char synw
[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
1618 unsigned char synuw
[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e };
1619 static unsigned char wide
[6] = { 0x80, 1, 2, 3, 1, 0 };
1620 static unsigned char u3
[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 };
1621 struct atp_unit
*dev
= (struct atp_unit
*)&host
->hostdata
;
1624 lvdmode
= inb(wkport
+ 0x3f) & 0x40;
1626 for (i
= 0; i
< 16; i
++) {
1629 if ((m
& dev
->active_idu
) != 0) {
1632 if (i
== dev
->host_idu
) {
1633 printk(KERN_INFO
" ID: %2d Host Adapter\n", dev
->host_idu
);
1636 tmport
= wkport
+ 0x5b;
1638 tmport
= wkport
+ 0x41;
1639 outb(0x08, tmport
++);
1640 outb(0x7f, tmport
++);
1641 outb(satn
[0], tmport
++);
1642 outb(satn
[1], tmport
++);
1643 outb(satn
[2], tmport
++);
1644 outb(satn
[3], tmport
++);
1645 outb(satn
[4], tmport
++);
1646 outb(satn
[5], tmport
++);
1650 outb(dev
->id
[i
].devspu
, tmport
++);
1652 outb(satn
[6], tmport
++);
1653 outb(satn
[7], tmport
++);
1655 if ((j
& 0x08) != 0) {
1656 j
= (j
& 0x07) | 0x40;
1660 outb(satn
[8], tmport
);
1663 while ((inb(tmport
) & 0x80) == 0x00);
1665 if ((inb(tmport
) != 0x11) && (inb(tmport
) != 0x8e)) {
1668 while (inb(tmport
) != 0x8e);
1669 dev
->active_idu
|= m
;
1671 tmport
= wkport
+ 0x50;
1673 tmport
= wkport
+ 0x54;
1677 tmport
= wkport
+ 0x58;
1680 while ((inb(tmport
) & 0x80) == 0x00);
1684 tmport
= wkport
+ 0x50;
1689 tmport
= wkport
+ 0x43;
1690 outb(inqd
[0], tmport
++);
1691 outb(inqd
[1], tmport
++);
1692 outb(inqd
[2], tmport
++);
1693 outb(inqd
[3], tmport
++);
1694 outb(inqd
[4], tmport
++);
1695 outb(inqd
[5], tmport
);
1699 outb(dev
->id
[i
].devspu
, tmport
++);
1701 outb(inqd
[6], tmport
++);
1702 outb(inqd
[7], tmport
++);
1704 outb(inqd
[8], tmport
);
1706 while ((inb(tmport
) & 0x80) == 0x00);
1708 if ((inb(tmport
) != 0x11) && (inb(tmport
) != 0x8e)) {
1711 while (inb(tmport
) != 0x8e);
1712 tmport
= wkport
+ 0x5b;
1714 tmport
= wkport
+ 0x58;
1720 if ((k
& 0x01) != 0) {
1722 mbuf
[j
++] = inb(tmport
);
1726 if ((k
& 0x80) == 0) {
1734 tmport
= wkport
+ 0x50;
1743 while ((inb(tmport
) & 0x80) == 0x00);
1745 if (inb(tmport
) != 0x16) {
1750 printk(KERN_INFO
" ID: %2d %s\n", i
, &mbuf
[8]);
1751 dev
->id
[i
].devtypeu
= mbuf
[0];
1754 if ((mbuf
[7] & 0x60) == 0) {
1757 if ((i
< 8) && ((dev
->global_map
& 0x20) == 0)) {
1763 if (dev
->sp
[i
] != 0x04) // force u2
1768 tmport
= wkport
+ 0x5b;
1770 tmport
= wkport
+ 0x43;
1771 outb(satn
[0], tmport
++);
1772 outb(satn
[1], tmport
++);
1773 outb(satn
[2], tmport
++);
1774 outb(satn
[3], tmport
++);
1775 outb(satn
[4], tmport
++);
1776 outb(satn
[5], tmport
++);
1780 outb(dev
->id
[i
].devspu
, tmport
++);
1782 outb(satn
[6], tmport
++);
1783 outb(satn
[7], tmport
++);
1785 outb(satn
[8], tmport
);
1788 while ((inb(tmport
) & 0x80) == 0x00);
1790 if ((inb(tmport
) != 0x11) && (inb(tmport
) != 0x8e)) {
1793 while (inb(tmport
) != 0x8e);
1796 tmport
= wkport
+ 0x54;
1802 while ((inb(tmport
) & 0x80) == 0) {
1803 if ((inb(tmport
) & 0x01) != 0) {
1805 outb(u3
[j
++], tmport
);
1810 while ((inb(tmport
) & 0x80) == 0x00);
1811 j
= inb(tmport
) & 0x0f;
1823 tmport
= wkport
+ 0x58;
1826 while ((inb(tmport
) & 0x80) == 0) {
1827 if ((inb(tmport
) & 0x01) != 0) {
1834 j
= inb(tmport
) & 0x0f;
1846 tmport
= wkport
+ 0x54;
1854 if ((j
& 0x01) != 0) {
1856 mbuf
[k
++] = inb(tmport
);
1860 if ((j
& 0x80) == 0x00) {
1864 j
= inb(tmport
) & 0x0f;
1876 tmport
= wkport
+ 0x50;
1878 tmport
= wkport
+ 0x54;
1883 while ((inb(tmport
) & 0x80) == 0x00);
1892 if (mbuf
[0] != 0x01) {
1895 if (mbuf
[1] != 0x06) {
1898 if (mbuf
[2] != 0x04) {
1901 if (mbuf
[3] == 0x09) {
1905 dev
->id
[i
].devspu
= 0xce;
1909 tmport
= wkport
+ 0x5b;
1911 tmport
= wkport
+ 0x43;
1912 outb(satn
[0], tmport
++);
1913 outb(satn
[1], tmport
++);
1914 outb(satn
[2], tmport
++);
1915 outb(satn
[3], tmport
++);
1916 outb(satn
[4], tmport
++);
1917 outb(satn
[5], tmport
++);
1921 outb(dev
->id
[i
].devspu
, tmport
++);
1923 outb(satn
[6], tmport
++);
1924 outb(satn
[7], tmport
++);
1926 outb(satn
[8], tmport
);
1929 while ((inb(tmport
) & 0x80) == 0x00);
1931 if ((inb(tmport
) != 0x11) && (inb(tmport
) != 0x8e)) {
1934 while (inb(tmport
) != 0x8e);
1937 tmport
= wkport
+ 0x54;
1943 while ((inb(tmport
) & 0x80) == 0) {
1944 if ((inb(tmport
) & 0x01) != 0) {
1946 outb(wide
[j
++], tmport
);
1951 while ((inb(tmport
) & 0x80) == 0x00);
1952 j
= inb(tmport
) & 0x0f;
1964 tmport
= wkport
+ 0x58;
1967 while ((inb(tmport
) & 0x80) == 0) {
1968 if ((inb(tmport
) & 0x01) != 0) {
1975 j
= inb(tmport
) & 0x0f;
1987 tmport
= wkport
+ 0x54;
1995 if ((j
& 0x01) != 0) {
1997 mbuf
[k
++] = inb(tmport
);
2001 if ((j
& 0x80) == 0x00) {
2005 j
= inb(tmport
) & 0x0f;
2017 tmport
= wkport
+ 0x50;
2019 tmport
= wkport
+ 0x54;
2024 while ((inb(tmport
) & 0x80) == 0x00);
2033 if (mbuf
[0] != 0x01) {
2036 if (mbuf
[1] != 0x02) {
2039 if (mbuf
[2] != 0x03) {
2042 if (mbuf
[3] != 0x01) {
2049 if ((dev
->id
[i
].devtypeu
== 0x00) || (dev
->id
[i
].devtypeu
== 0x07) || ((dev
->id
[i
].devtypeu
== 0x05) && ((n
& 0x10) != 0))) {
2052 if ((dev
->async
& m
) != 0) {
2058 if (dev
->sp
[i
] == 0x02) {
2062 if (dev
->sp
[i
] >= 0x03) {
2067 tmport
= wkport
+ 0x5b;
2069 if ((m
& dev
->wide_idu
) != 0) {
2073 tmport
= wkport
+ 0x43;
2074 outb(satn
[0], tmport
++);
2075 outb(satn
[1], tmport
++);
2076 outb(satn
[2], tmport
++);
2077 outb(satn
[3], tmport
++);
2078 outb(satn
[4], tmport
++);
2079 outb(satn
[5], tmport
++);
2083 outb(dev
->id
[i
].devspu
, tmport
++);
2085 outb(satn
[6], tmport
++);
2086 outb(satn
[7], tmport
++);
2088 outb(satn
[8], tmport
);
2091 while ((inb(tmport
) & 0x80) == 0x00);
2093 if ((inb(tmport
) != 0x11) && (inb(tmport
) != 0x8e)) {
2096 while (inb(tmport
) != 0x8e);
2099 tmport
= wkport
+ 0x54;
2105 while ((inb(tmport
) & 0x80) == 0) {
2106 if ((inb(tmport
) & 0x01) != 0) {
2108 if ((m
& dev
->wide_idu
) != 0) {
2109 if ((m
& dev
->ultra_map
) != 0) {
2110 outb(synuw
[j
++], tmport
);
2112 outb(synw
[j
++], tmport
);
2115 if ((m
& dev
->ultra_map
) != 0) {
2116 outb(synu
[j
++], tmport
);
2118 outb(synn
[j
++], tmport
);
2125 while ((inb(tmport
) & 0x80) == 0x00);
2126 j
= inb(tmport
) & 0x0f;
2138 tmport
= wkport
+ 0x58;
2141 while ((inb(tmport
) & 0x80) == 0x00) {
2142 if ((inb(tmport
) & 0x01) != 0x00) {
2165 tmport
= wkport
+ 0x54;
2173 if ((j
& 0x01) != 0x00) {
2175 mbuf
[k
++] = inb(tmport
);
2179 if ((j
& 0x80) == 0x00) {
2183 while ((inb(tmport
) & 0x80) == 0x00);
2200 tmport
= wkport
+ 0x50;
2203 tmport
= wkport
+ 0x54;
2208 while ((inb(tmport
) & 0x80) == 0x00);
2214 if (mbuf
[0] != 0x01) {
2217 if (mbuf
[1] != 0x03) {
2220 if (mbuf
[4] == 0x00) {
2223 if (mbuf
[3] > 0x64) {
2226 if (mbuf
[4] > 0x0e) {
2229 dev
->id
[i
].devspu
= mbuf
[4];
2230 if (mbuf
[3] < 0x0c) {
2234 if ((mbuf
[3] < 0x0d) && (rmb
== 0)) {
2238 if (mbuf
[3] < 0x1a) {
2242 if (mbuf
[3] < 0x33) {
2246 if (mbuf
[3] < 0x4c) {
2252 dev
->id
[i
].devspu
= (dev
->id
[i
].devspu
& 0x0f) | j
;
2257 static void atp870u_init_tables(struct Scsi_Host
*host
)
2259 struct atp_unit
*dev
= (struct atp_unit
*)&host
->hostdata
;
2262 for (k
= 0; k
< 16; k
++) {
2264 dev
->id
[k
].prd_tableu
= pci_alloc_consistent(dev
->pdev
, 1024, &dev
->id
[k
].prd_phys
);
2265 dev
->id
[k
].devspu
= 0x20;
2266 dev
->id
[k
].devtypeu
= 0;
2267 dev
->id
[k
].curr_req
= NULL
;
2269 dev
->active_idu
= 0;
2271 dev
->host_idu
= 0x07;
2275 dev
->last_cmd
= 0xff;
2278 for (k
= 0; k
< qcnt
; k
++) {
2279 dev
->querequ
[k
] = 0;
2281 for (k
= 0; k
< 16; k
++) {
2282 dev
->id
[k
].curr_req
= 0;
2287 /* return non-zero on detection */
2288 static int atp870u_detect(Scsi_Host_Template
* tpnt
)
2290 unsigned char irq
, h
, k
, m
;
2291 unsigned long flags
;
2292 unsigned int base_io
, error
, tmport
;
2293 struct pci_dev
*pdev
[MAX_ATP
];
2294 unsigned char chip_ver
[MAX_ATP
], host_id
;
2295 unsigned short dev_id
[MAX_ATP
], n
;
2296 struct Scsi_Host
*shpnt
= NULL
;
2300 static unsigned short devid
[9] = {
2301 0x8081, 0x8002, 0x8010, 0x8020, 0x8030, 0x8040, 0x8050, 0x8060, 0
2304 printk(KERN_INFO
"aec671x_detect: \n");
2305 tpnt
->proc_name
= "atp870u";
2307 for (h
= 0; devid
[h
]; h
++) {
2308 struct pci_dev
*dev
= NULL
;
2310 while((dev
= pci_find_device(0x1191, devid
[h
], dev
))!=NULL
)
2312 if(pci_enable_device(dev
))
2315 if(pci_set_dma_mask(dev
, 0xFFFFFFFFUL
))
2317 printk(KERN_ERR
"atp870u: 32bit DMA mask required but not available.\n");
2321 dev_id
[card
] = devid
[h
];
2323 if (devid
[h
] == 0x8002) {
2324 error
= pci_read_config_byte(dev
, 0x08, &chip_ver
[card
]);
2325 if (chip_ver
[card
] < 2) {
2329 if (devid
[h
] == 0x8010 || devid
[h
] == 0x8081 || devid
[h
] == 0x8050) {
2330 chip_ver
[card
] = 0x04;
2334 if (card
== MAX_ATP
)
2338 for (h
= 0; h
< MAX_ATP
; h
++) {
2339 struct atp_unit tmp
, *dev
;
2340 if (pdev
[h
] == NULL
) {
2344 /* Found an atp870u/w. */
2345 base_io
= pci_resource_start(pdev
[h
], 0);
2348 if (dev_id
[h
] != 0x8081) {
2349 error
= pci_read_config_byte(pdev
[h
], 0x49, &host_id
);
2351 base_io
&= 0xfffffff8;
2353 if (check_region(base_io
, 0x40) != 0) {
2356 printk(KERN_INFO
" ACARD AEC-671X PCI Ultra/W SCSI-3 Host Adapter: %d IO:%x, IRQ:%d.\n", h
, base_io
, irq
);
2358 tmp
.ioport
= base_io
;
2359 tmp
.pciport
= base_io
+ 0x20;
2360 tmp
.deviceid
= dev_id
[h
];
2362 tmp
.host_idu
= host_id
;
2363 tmp
.chip_veru
= chip_ver
[h
];
2365 tmport
= base_io
+ 0x22;
2366 tmp
.scam_on
= inb(tmport
);
2368 tmp
.global_map
= inb(tmport
++);
2369 tmp
.ultra_map
= inw(tmport
);
2370 if (tmp
.ultra_map
== 0) {
2372 tmp
.global_map
= 0x20;
2373 tmp
.ultra_map
= 0xffff;
2375 shpnt
= scsi_register(tpnt
, sizeof(struct atp_unit
));
2380 /* Save the atp_unit data */
2381 memcpy(&shpnt
->hostdata
, &tmp
, sizeof(tmp
));
2383 atp870u_init_tables(shpnt
);
2384 spin_lock_irqsave(shpnt
->host_lock
, flags
);
2385 if (request_irq(irq
, atp870u_intr_handle
, SA_SHIRQ
, "atp870u", shpnt
)) {
2386 printk(KERN_ERR
"Unable to allocate IRQ for Acard controller.\n");
2390 if (chip_ver
[h
] > 0x07) { /* check if atp876 chip *//* then enable terminator */
2391 tmport
= base_io
+ 0x3e;
2395 tmport
= base_io
+ 0x3a;
2396 k
= (inb(tmport
) & 0xf3) | 0x10;
2398 outb((k
& 0xdf), tmport
);
2403 outb((host_id
| 0x08), tmport
);
2407 while ((inb(tmport
) & 0x80) == 0);
2410 tmport
= base_io
+ 1;
2413 tmport
= base_io
+ 0x11;
2417 is870(shpnt
, base_io
);
2418 tmport
= base_io
+ 0x3a;
2419 outb((inb(tmport
) & 0xef), tmport
);
2421 outb((inb(tmport
) | 0x20), tmport
);
2423 base_io
&= 0xfffffff8;
2425 if (check_region(base_io
, 0x60) != 0) {
2428 host_id
= inb(base_io
+ 0x39);
2431 printk(KERN_INFO
" ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d IO:%x, IRQ:%d.\n", h
, base_io
, irq
);
2432 tmp
.ioport
= base_io
+ 0x40;
2433 tmp
.pciport
= base_io
+ 0x28;
2434 tmp
.deviceid
= dev_id
[h
];
2435 tmp
.host_idu
= host_id
;
2436 tmp
.chip_veru
= chip_ver
[h
];
2438 tmport
= base_io
+ 0x22;
2439 tmp
.scam_on
= inb(tmport
);
2441 tmp
.global_map
= inb(tmport
);
2443 tmp
.ultra_map
= inw(tmport
);
2451 outw(n
, base_io
+ 0x34);
2453 if (inb(base_io
+ 0x30) == 0xff) {
2456 tmp
.sp
[m
++] = inb(base_io
+ 0x30);
2457 tmp
.sp
[m
++] = inb(base_io
+ 0x31);
2458 tmp
.sp
[m
++] = inb(base_io
+ 0x32);
2459 tmp
.sp
[m
++] = inb(base_io
+ 0x33);
2460 outw(n
, base_io
+ 0x34);
2462 tmp
.sp
[m
++] = inb(base_io
+ 0x30);
2463 tmp
.sp
[m
++] = inb(base_io
+ 0x31);
2464 tmp
.sp
[m
++] = inb(base_io
+ 0x32);
2465 tmp
.sp
[m
++] = inb(base_io
+ 0x33);
2466 outw(n
, base_io
+ 0x34);
2468 tmp
.sp
[m
++] = inb(base_io
+ 0x30);
2469 tmp
.sp
[m
++] = inb(base_io
+ 0x31);
2470 tmp
.sp
[m
++] = inb(base_io
+ 0x32);
2471 tmp
.sp
[m
++] = inb(base_io
+ 0x33);
2472 outw(n
, base_io
+ 0x34);
2474 tmp
.sp
[m
++] = inb(base_io
+ 0x30);
2475 tmp
.sp
[m
++] = inb(base_io
+ 0x31);
2476 tmp
.sp
[m
++] = inb(base_io
+ 0x32);
2477 tmp
.sp
[m
++] = inb(base_io
+ 0x33);
2481 outw(0, base_io
+ 0x34);
2484 for (k
= 0; k
< 16; k
++) {
2487 if (tmp
.sp
[k
] > 1) {
2490 if (tmp
.sp
[k
] == 0) {
2495 tmp
.async
= ~(tmp
.async
);
2496 outb(tmp
.global_map
, base_io
+ 0x35);
2498 shpnt
= scsi_register(tpnt
, sizeof(struct atp_unit
));
2503 memcpy(&shpnt
->hostdata
, &tmp
, sizeof(tmp
));
2505 atp870u_init_tables(shpnt
);
2507 spin_lock_irqsave(shpnt
->host_lock
, flags
);
2508 if (request_irq(irq
, atp870u_intr_handle
, SA_SHIRQ
, "atp870u", shpnt
)) {
2509 printk(KERN_ERR
"Unable to allocate IRQ for Acard controller.\n");
2513 tmport
= base_io
+ 0x38;
2514 k
= inb(tmport
) & 0x80;
2521 tmport
= base_io
+ 0x5b;
2525 tmport
= base_io
+ 0x40;
2526 outb((host_id
| 0x08), tmport
);
2530 while ((inb(tmport
) & 0x80) == 0);
2533 tmport
= base_io
+ 0x41;
2536 tmport
= base_io
+ 0x51;
2540 is880(shpnt
, base_io
);
2541 tmport
= base_io
+ 0x38;
2545 dev
= (struct atp_unit
*)&shpnt
->hostdata
;
2547 atp_host
[h
] = shpnt
;
2548 if (dev
->chip_veru
== 4) {
2551 shpnt
->this_id
= host_id
;
2552 shpnt
->unique_id
= base_io
;
2553 shpnt
->io_port
= base_io
;
2554 if (dev_id
[h
] == 0x8081) {
2555 shpnt
->n_io_port
= 0x60; /* Number of bytes of I/O space used */
2557 shpnt
->n_io_port
= 0x40; /* Number of bytes of I/O space used */
2560 spin_unlock_irqrestore(shpnt
->host_lock
, flags
);
2561 if (dev_id
[h
] == 0x8081) {
2562 request_region(base_io
, 0x60, "atp870u"); /* Register the IO ports that we use */
2564 request_region(base_io
, 0x40, "atp870u"); /* Register the IO ports that we use */
2569 scsi_unregister(shpnt
);
2570 spin_unlock_irqrestore(shpnt
->host_lock
, flags
);
2577 /* The abort command does not leave the device in a clean state where
2578 it is available to be used again. Until this gets worked out, we will
2579 leave it commented out. */
2581 int atp870u_abort(Scsi_Cmnd
* SCpnt
)
2584 Scsi_Cmnd
*workrequ
;
2585 unsigned int tmport
;
2586 struct atp_unit
*dev
= (struct atp_unit
*)&SCpnt
->device
->host
->hostdata
;
2588 printk(KERN_DEBUG
"working=%x last_cmd=%x ", dev
->working
, dev
->last_cmd
);
2589 printk(" quhdu=%x quendu=%x ", dev
->quhdu
, dev
->quendu
);
2590 tmport
= dev
->ioport
;
2591 for (j
= 0; j
< 0x17; j
++) {
2592 printk(" r%2x=%2x", j
, inb(tmport
++));
2595 printk(" r1c=%2x", inb(tmport
));
2597 printk(" r1f=%2x in_snd=%2x ", inb(tmport
), dev
->in_snd
);
2598 tmport
= dev
->pciport
;
2599 printk(" r20=%2x", inb(tmport
));
2601 printk(" r22=%2x", inb(tmport
));
2602 tmport
= dev
->ioport
+ 0x3a;
2603 printk(" r3a=%2x \n", inb(tmport
));
2604 tmport
= dev
->ioport
+ 0x3b;
2605 printk(" r3b=%2x \n", inb(tmport
));
2606 for (j
= 0; j
< 16; j
++) {
2607 if (dev
->id
[j
].curr_req
!= NULL
) {
2608 workrequ
= dev
->id
[j
].curr_req
;
2609 printk("\n que cdb= ");
2610 for (k
= 0; k
< workrequ
->cmd_len
; k
++) {
2611 printk(" %2x ", workrequ
->cmnd
[k
]);
2613 printk(" last_lenu= %lx ", dev
->id
[j
].last_lenu
);
2616 /* Sort of - the thing handles itself */
2620 const char *atp870u_info(struct Scsi_Host
*notused
)
2622 static char buffer
[128];
2624 strcpy(buffer
, "ACARD AEC-6710/6712/67160 PCI Ultra/W/LVD SCSI-3 Adapter Driver V2.6+ac ");
2629 int atp870u_set_info(char *buffer
, int length
, struct Scsi_Host
*HBAptr
)
2631 return -ENOSYS
; /* Currently this is a no-op */
2634 #define BLS buffer + len + size
2635 int atp870u_proc_info(struct Scsi_Host
*HBAptr
, char *buffer
, char **start
, off_t offset
, int length
, int inout
)
2637 static u8 buff
[512];
2643 if (inout
== TRUE
) { /* Has data been written to the file? */
2644 return (atp870u_set_info(buffer
, length
, HBAptr
));
2647 memset(buff
, 0, sizeof(buff
));
2649 size
+= sprintf(BLS
, "ACARD AEC-671X Driver Version: 2.6+ac\n");
2654 size
+= sprintf(BLS
, "\n");
2655 size
+= sprintf(BLS
, "Adapter Configuration:\n");
2656 size
+= sprintf(BLS
, " Base IO: %#.4lx\n", HBAptr
->io_port
);
2657 size
+= sprintf(BLS
, " IRQ: %d\n", HBAptr
->irq
);
2661 *start
= buffer
+ (offset
- begin
); /* Start of wanted data */
2662 len
-= (offset
- begin
); /* Start slop */
2664 len
= length
; /* Ending slop */
2669 static int atp870u_biosparam(struct scsi_device
*sdev
,
2670 struct block_device
*dev
, sector_t capacity
, int *ip
)
2672 int heads
, sectors
, cylinders
;
2676 cylinders
= (unsigned long)capacity
/ (heads
* sectors
);
2678 if (cylinders
> 1024) {
2681 cylinders
= (unsigned long)capacity
/ (heads
* sectors
);
2691 static int atp870u_release(struct Scsi_Host
*pshost
)
2693 struct atp_unit
*dev
= (struct atp_unit
*)&pshost
->hostdata
;
2695 free_irq(pshost
->irq
, pshost
);
2696 release_region(pshost
->io_port
, pshost
->n_io_port
);
2697 scsi_unregister(pshost
);
2698 for (k
= 0; k
< 16; k
++)
2699 pci_free_consistent(dev
->pdev
, 1024, dev
->id
[k
].prd_tableu
, dev
->id
[k
].prd_phys
);
2703 MODULE_LICENSE("GPL");
2705 static Scsi_Host_Template driver_template
= {
2706 .proc_info
= atp870u_proc_info
,
2707 .detect
= atp870u_detect
,
2708 .release
= atp870u_release
,
2709 .info
= atp870u_info
,
2710 .queuecommand
= atp870u_queuecommand
,
2711 .eh_abort_handler
= atp870u_abort
,
2712 .bios_param
= atp870u_biosparam
,
2715 .sg_tablesize
= ATP870U_SCATTER
,
2716 .cmd_per_lun
= ATP870U_CMDLUN
,
2717 .use_clustering
= ENABLE_CLUSTERING
,
2719 #include "scsi_module.c"