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/init.h>
21 #include <linux/interrupt.h>
22 #include <linux/kernel.h>
23 #include <linux/types.h>
24 #include <linux/string.h>
25 #include <linux/ioport.h>
26 #include <linux/delay.h>
27 #include <linux/proc_fs.h>
28 #include <linux/spinlock.h>
29 #include <linux/pci.h>
30 #include <linux/blkdev.h>
31 #include <linux/stat.h>
33 #include <asm/system.h>
41 * 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 $";
44 static unsigned short int sync_idu;
46 static irqreturn_t atp870u_intr_handle(int irq, void *dev_id,
50 unsigned short int tmpcip, id;
51 unsigned char i, j, target_id, lun;
54 unsigned int workportu, tmport;
55 unsigned long adrcntu, k;
57 struct Scsi_Host *host = dev_id;
58 struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
61 workportu = dev->ioport;
64 if (dev->working != 0) {
67 if ((j & 0x80) == 0) {
72 tmpcip = dev->pciport;
73 if ((inb(tmpcip) & 0x08) != 0) {
75 for (k = 0; k < 1000; k++) {
76 if ((inb(tmpcip) & 0x08) == 0) {
79 if ((inb(tmpcip) & 0x01) == 0) {
85 tmpcip = dev->pciport;
92 target_id = inb(tmport);
96 * Remap wide devices onto id numbers
99 if ((target_id & 0x40) != 0) {
100 target_id = (target_id & 0x07) | 0x08;
105 if ((j & 0x40) != 0) {
106 if (dev->last_cmd == 0xff) {
107 dev->last_cmd = target_id;
109 dev->last_cmd |= 0x40;
113 if ((dev->last_cmd & 0xf0) != 0x40) {
114 dev->last_cmd = 0xff;
119 if (dev->wide_idu != 0) {
120 tmport = workportu + 0x1b;
122 while ((inb(tmport) & 0x01) != 0x01) {
127 * Issue more commands
129 if (((dev->quhdu != dev->quendu) || (dev->last_cmd != 0xff)) && (dev->in_snd == 0)) {
140 dev->last_cmd |= 0x40;
146 if ((dev->last_cmd & 0xf0) != 0x40) {
147 dev->last_cmd = 0xff;
151 ((unsigned char *) &adrcntu)[2] = inb(tmport++);
152 ((unsigned char *) &adrcntu)[1] = inb(tmport++);
153 ((unsigned char *) &adrcntu)[0] = inb(tmport);
154 k = dev->id[target_id].last_lenu;
156 dev->id[target_id].tran_lenu = k;
157 dev->id[target_id].last_lenu = adrcntu;
165 if ((i == 0x80) || (i == 0x8f)) {
169 if (j == 0x44 || i == 0x80) {
171 lun = inb(tmport) & 0x07;
173 if ((dev->last_cmd & 0xf0) != 0x40) {
174 dev->last_cmd = 0xff;
179 ((unsigned char *) &adrcntu)[2] = inb(tmport++);
180 ((unsigned char *) &adrcntu)[1] = inb(tmport++);
181 ((unsigned char *) &adrcntu)[0] = inb(tmport);
182 k = dev->id[target_id].last_lenu;
184 dev->id[target_id].tran_lenu = k;
185 dev->id[target_id].last_lenu = adrcntu;
192 dev->id[target_id].dirctu = 0x00;
194 outb(0x00, tmport++);
195 outb(0x00, tmport++);
196 outb(0x00, tmport++);
203 if (dev->last_cmd != 0xff) {
204 dev->last_cmd |= 0x40;
206 tmport = workportu + 0x10;
209 target_id = inb(tmport);
211 * Remap wide identifiers
213 if ((target_id & 0x10) != 0) {
214 target_id = (target_id & 0x07) | 0x08;
218 workrequ = dev->id[target_id].curr_req;
219 tmport = workportu + 0x0f;
222 outb(dev->id[target_id].devspu, tmport++);
223 adrcntu = dev->id[target_id].tran_lenu;
224 k = dev->id[target_id].last_lenu;
225 outb(((unsigned char *) &k)[2], tmport++);
226 outb(((unsigned char *) &k)[1], tmport++);
227 outb(((unsigned char *) &k)[0], tmport++);
231 j = (j & 0x07) | 0x40;
234 j |= dev->id[target_id].dirctu;
238 /* enable 32 bit fifo transfer */
239 if (dev->deviceid != 0x8081) {
240 tmport = workportu + 0x3a;
241 if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) || (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a)) {
242 outb((unsigned char) ((inb(tmport) & 0xf3) | 0x08), tmport);
244 outb((unsigned char) (inb(tmport) & 0xf3), tmport);
247 tmport = workportu - 0x05;
248 if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) || (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a)) {
249 outb((unsigned char) ((inb(tmport) & 0x3f) | 0xc0), tmport);
251 outb((unsigned char) (inb(tmport) & 0x3f), tmport);
255 tmport = workportu + 0x1b;
258 id = id << target_id;
260 * Is this a wide device
262 if ((id & dev->wide_idu) != 0) {
266 while ((inb(tmport) & 0x01) != j) {
270 if (dev->id[target_id].last_lenu == 0) {
271 tmport = workportu + 0x18;
276 prd = dev->id[target_id].prd_posu;
277 while (adrcntu != 0) {
278 id = ((unsigned short int *) (prd))[2];
285 ((unsigned short int *) (prd))[2] = (unsigned short int)
287 ((unsigned long *) (prd))[0] += adrcntu;
289 dev->id[target_id].prd_posu = prd;
292 dev->id[target_id].prdaddru += 0x08;
295 dev->id[target_id].prd_posu = prd;
299 tmpcip = dev->pciport + 0x04;
300 outl(dev->id[target_id].prdaddru, tmpcip);
305 tmport = workportu + 0x18;
307 * Check transfer direction
309 if (dev->id[target_id].dirctu != 0) {
322 * Current scsi request on this target
325 workrequ = dev->id[target_id].curr_req;
328 if ((dev->last_cmd & 0xf0) != 0x40) {
329 dev->last_cmd = 0xff;
332 workrequ->result = errstus;
336 if ((dev->last_cmd & 0xf0) != 0x40) {
337 dev->last_cmd = 0xff;
341 errstus = inb(tmport);
342 workrequ->result = errstus;
345 * Complete the command
349 pci_unmap_sg(dev->pdev, (struct scatterlist *)workrequ->buffer, workrequ->use_sg, scsi_to_pci_dma_dir(workrequ->sc_data_direction));
350 else if(workrequ->request_bufflen && workrequ->sc_data_direction != SCSI_DATA_NONE)
351 pci_unmap_single(dev->pdev, workrequ->SCp.dma_handle, workrequ->request_bufflen, scsi_to_pci_dma_dir(workrequ->sc_data_direction));
352 spin_lock_irqsave(dev->host->host_lock, flags);
353 (*workrequ->scsi_done) (workrequ);
356 * Clear it off the queue
358 dev->id[target_id].curr_req = 0;
360 spin_unlock_irqrestore(dev->host->host_lock, flags);
364 if (dev->wide_idu != 0) {
365 tmport = workportu + 0x1b;
367 while ((inb(tmport) & 0x01) != 0x01) {
372 * If there is stuff to send and nothing going then send it
374 if (((dev->last_cmd != 0xff) || (dev->quhdu != dev->quendu)) && (dev->in_snd == 0)) {
380 if ((dev->last_cmd & 0xf0) != 0x40) {
381 dev->last_cmd = 0xff;
389 outl(dev->id[target_id].prdaddru, tmpcip);
394 tmport = workportu + 0x10;
396 dev->id[target_id].dirctu = 0x00;
405 outl(dev->id[target_id].prdaddru, tmpcip);
410 tmport = workportu + 0x10;
413 outb((unsigned char) (inb(tmport) | 0x20), tmport);
414 dev->id[target_id].dirctu = 0x20;
427 dev->id[target_id].dirctu = 0x00;
429 outb(0x00, tmport++);
430 outb(0x00, tmport++);
431 outb(0x00, tmport++);
437 // tmport = workportu + 0x17;
446 static int atp870u_queuecommand(Scsi_Cmnd * req_p, void (*done) (Scsi_Cmnd *))
449 unsigned short int m;
451 struct Scsi_Host *host;
452 struct atp_unit *dev;
454 if (req_p->device->channel != 0) {
455 req_p->result = 0x00040000;
460 host = req_p->device->host;
461 dev = (struct atp_unit *)&host->hostdata;
464 m = m << req_p->device->id;
467 * Fake a timeout for missing targets
470 if ((m & dev->active_idu) == 0) {
471 req_p->result = 0x00040000;
476 req_p->scsi_done = done;
478 printk(KERN_WARNING "atp870u_queuecommand: done can't be NULL\n");
487 spin_lock_irqsave(host->host_lock, flags);
489 if (dev->quendu >= qcnt) {
495 if (dev->quhdu == dev->quendu) {
496 if (dev->quendu == 0) {
500 req_p->result = 0x00020000;
501 spin_unlock_irqrestore(host->host_lock, flags);
505 dev->querequ[dev->quendu] = req_p;
506 tmport = dev->ioport + 0x1c;
507 spin_unlock_irqrestore(host->host_lock, flags);
508 if ((inb(tmport) == 0) && (dev->in_int == 0) && (dev->in_snd == 0)) {
514 static void send_s870(struct Scsi_Host *host)
520 unsigned char j, target_id;
522 unsigned short int tmpcip, w;
525 unsigned int workportu;
526 struct scatterlist *sgpnt;
527 struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
530 spin_lock_irqsave(host->host_lock, flags);
532 if (dev->in_snd != 0) {
533 spin_unlock_irqrestore(host->host_lock, flags);
537 if ((dev->last_cmd != 0xff) && ((dev->last_cmd & 0x40) != 0)) {
538 dev->last_cmd &= 0x0f;
539 workrequ = dev->id[dev->last_cmd].curr_req;
540 if (workrequ != NULL) { /* check NULL pointer */
543 dev->last_cmd = 0xff;
544 if (dev->quhdu == dev->quendu) {
546 spin_unlock_irqrestore(dev->host->host_lock, flags);
550 if ((dev->last_cmd != 0xff) && (dev->working != 0)) {
552 spin_unlock_irqrestore(dev->host->host_lock, flags);
558 if (dev->quhdu >= qcnt) {
561 workrequ = dev->querequ[dev->quhdu];
562 if (dev->id[workrequ->device->id].curr_req == 0) {
563 dev->id[workrequ->device->id].curr_req = workrequ;
564 dev->last_cmd = workrequ->device->id;
570 spin_unlock_irqrestore(host->host_lock, flags);
573 workportu = dev->ioport;
574 tmport = workportu + 0x1f;
575 if ((inb(tmport) & 0xb0) != 0) {
578 tmport = workportu + 0x1c;
579 if (inb(tmport) == 0) {
583 dev->last_cmd |= 0x40;
585 spin_unlock_irqrestore(dev->host->host_lock, flags);
588 memcpy(&dev->ata_cdbu[0], &workrequ->cmnd[0], workrequ->cmd_len);
589 if (dev->ata_cdbu[0] == READ_CAPACITY) {
590 if (workrequ->request_bufflen > 8) {
591 workrequ->request_bufflen = 0x08;
594 if (dev->ata_cdbu[0] == 0x00) {
595 workrequ->request_bufflen = 0;
598 tmport = workportu + 0x1b;
600 target_id = workrequ->device->id;
607 if ((w & dev->wide_idu) != 0) {
611 while ((inb(tmport) & 0x01) != j) {
620 outb(workrequ->cmd_len, tmport++);
621 outb(0x2c, tmport++);
622 outb(0xcf, tmport++);
623 for (i = 0; i < workrequ->cmd_len; i++) {
624 outb(dev->ata_cdbu[i], tmport++);
626 tmport = workportu + 0x0f;
627 outb(workrequ->device->lun, tmport);
632 outb(dev->id[target_id].devspu, tmport++);
635 * Figure out the transfer size
637 if (workrequ->use_sg) {
639 sgpnt = (struct scatterlist *) workrequ->request_buffer;
640 sg_count = pci_map_sg(dev->pdev, sgpnt, workrequ->use_sg, scsi_to_pci_dma_dir(workrequ->sc_data_direction));
641 for (i = 0; i < workrequ->use_sg; i++) {
642 if (sgpnt[i].length == 0 || workrequ->use_sg > ATP870U_SCATTER) {
643 panic("Foooooooood fight!");
645 l += sgpnt[i].length;
647 } else if(workrequ->request_bufflen && workrequ->sc_data_direction != PCI_DMA_NONE) {
648 workrequ->SCp.dma_handle = pci_map_single(dev->pdev, workrequ->request_buffer, workrequ->request_bufflen, scsi_to_pci_dma_dir(workrequ->sc_data_direction));
649 l = workrequ->request_bufflen;
653 * Write transfer size
655 outb((unsigned char) (((unsigned char *) (&l))[2]), tmport++);
656 outb((unsigned char) (((unsigned char *) (&l))[1]), tmport++);
657 outb((unsigned char) (((unsigned char *) (&l))[0]), tmport++);
659 dev->id[j].last_lenu = l;
660 dev->id[j].tran_lenu = 0;
664 if ((j & 0x08) != 0) {
665 j = (j & 0x07) | 0x40;
668 * Check transfer direction
670 if (workrequ->sc_data_direction == SCSI_DATA_WRITE) {
671 outb((unsigned char) (j | 0x20), tmport++);
675 outb((unsigned char) (inb(tmport) | 0x80), tmport);
677 tmport = workportu + 0x1c;
678 dev->id[target_id].dirctu = 0;
680 if (inb(tmport) == 0) {
681 tmport = workportu + 0x18;
684 dev->last_cmd |= 0x40;
687 spin_unlock_irqrestore(host->host_lock, flags);
690 tmpcip = dev->pciport;
691 prd = dev->id[target_id].prd_tableu;
692 dev->id[target_id].prd_posu = prd;
695 * Now write the request list. Either as scatter/gather or as
699 if (workrequ->use_sg) {
700 sgpnt = (struct scatterlist *) workrequ->request_buffer;
702 for (j = 0; j < workrequ->use_sg; j++) {
703 bttl = sg_dma_address(&sgpnt[j]);
704 l = sg_dma_len(&sgpnt[j]);
705 while (l > 0x10000) {
706 (((u16 *) (prd))[i + 3]) = 0x0000;
707 (((u16 *) (prd))[i + 2]) = 0x0000;
708 (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl);
713 (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl);
714 (((u16 *) (prd))[i + 2]) = cpu_to_le16(l);
715 (((u16 *) (prd))[i + 3]) = 0;
718 (((u16 *) (prd))[i - 1]) = cpu_to_le16(0x8000);
721 * For a linear request write a chain of blocks
723 bttl = workrequ->SCp.dma_handle;
724 l = workrequ->request_bufflen;
726 while (l > 0x10000) {
727 (((u16 *) (prd))[i + 3]) = 0x0000;
728 (((u16 *) (prd))[i + 2]) = 0x0000;
729 (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl);
734 (((u16 *) (prd))[i + 3]) = cpu_to_le16(0x8000);
735 (((u16 *) (prd))[i + 2]) = cpu_to_le16(l);
736 (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl);
739 dev->id[target_id].prdaddru = dev->id[target_id].prd_phys;
740 outl(dev->id[target_id].prd_phys, tmpcip);
746 if (dev->deviceid != 0x8081) {
747 tmport = workportu + 0x3a;
748 if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) || (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a)) {
749 outb((inb(tmport) & 0xf3) | 0x08, tmport);
751 outb(inb(tmport) & 0xf3, tmport);
754 tmport = workportu - 0x05;
755 if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) || (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a)) {
756 outb((unsigned char) ((inb(tmport) & 0x3f) | 0xc0), tmport);
758 outb((unsigned char) (inb(tmport) & 0x3f), tmport);
761 tmport = workportu + 0x1c;
763 if (workrequ->sc_data_direction == SCSI_DATA_WRITE) {
764 dev->id[target_id].dirctu = 0x20;
765 if (inb(tmport) == 0) {
766 tmport = workportu + 0x18;
770 dev->last_cmd |= 0x40;
773 spin_unlock_irqrestore(host->host_lock, flags);
776 if (inb(tmport) == 0) {
777 tmport = workportu + 0x18;
781 dev->last_cmd |= 0x40;
784 spin_unlock_irqrestore(host->host_lock, flags);
789 static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val)
792 unsigned short int i, k;
795 tmport = dev->ioport + 0x1c;
798 for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */
800 j = (unsigned char) (k >> 8);
801 if ((k & 0x8000) != 0) { /* DB7 all release? */
805 *val |= 0x4000; /* assert DB6 */
807 *val &= 0xdfff; /* assert DB5 */
810 for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */
811 if ((inw(tmport) & 0x2000) != 0) { /* DB5 all release? */
815 *val |= 0x8000; /* no DB4-0, assert DB7 */
818 *val &= 0xbfff; /* release DB6 */
821 for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */
822 if ((inw(tmport) & 0x4000) != 0) { /* DB6 all release? */
830 static void tscam(struct Scsi_Host *host)
834 unsigned char i, j, k;
836 unsigned short int m, assignid_map, val;
837 unsigned char mbuf[33], quintet[2];
838 struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
839 static unsigned char g2q_tab[8] = {
840 0x38, 0x31, 0x32, 0x2b, 0x34, 0x2d, 0x2e, 0x27
843 /* I can't believe we need this before we've even done anything. Remove it
844 * and see if anyone bitches.
845 for (i = 0; i < 0x10; i++) {
850 tmport = dev->ioport + 1;
851 outb(0x08, tmport++);
853 tmport = dev->ioport + 0x11;
856 if ((dev->scam_on & 0x40) == 0) {
862 if (dev->chip_veru < 4) {
867 tmport = dev->ioport + 0x02;
868 outb(0x02, tmport++); /* 2*2=4ms,3EH 2/32*3E=3.9ms */
876 for (i = 0; i < j; i++) {
879 if ((m & assignid_map) != 0) {
882 tmport = dev->ioport + 0x0f;
889 k = (i & 0x07) | 0x40;
894 tmport = dev->ioport + 0x1b;
895 if (dev->chip_veru == 4) {
901 tmport = dev->ioport + 0x18;
905 while ((inb(tmport) & 0x80) == 0x00);
909 if ((k == 0x85) || (k == 0x42)) {
912 tmport = dev->ioport + 0x10;
919 tmport = dev->ioport + 0x02;
921 tmport = dev->ioport + 0x1b;
926 val = 0x0080; /* bsy */
927 tmport = dev->ioport + 0x1c;
929 val |= 0x0040; /* sel */
931 val |= 0x0004; /* msg */
933 inb(0x80); /* 2 deskew delay(45ns*2=90ns) */
934 val &= 0x007f; /* no bsy */
937 val &= 0x00fb; /* after 1ms no msg */
940 if ((inb(tmport) & 0x04) != 0) {
945 for (n = 0; n < 0x30000; n++) {
946 if ((inb(tmport) & 0x80) != 0) { /* bsy ? */
952 for (n = 0; n < 0x30000; n++) {
953 if ((inb(tmport) & 0x81) == 0x0081) {
960 val |= 0x8003; /* io,cd,db7 */
963 val &= 0x00bf; /* no sel */
968 if ((inb(tmport) & 0x80) == 0x00) { /* bsy ? */
971 tmport = dev->ioport + 0x15;
976 while ((inb(tmport) & 0x80) == 0);
981 val &= 0x00ff; /* synchronization */
985 val &= 0x00ff; /* isolation */
992 if ((inw(tmport) & 0x2000) == 0) {
996 val &= 0x00ff; /* get ID_STRING */
998 k = fun_scam(dev, &val);
999 if ((k & 0x03) == 0) {
1004 if ((k & 0x02) != 0) {
1015 TCM_5: /* isolation complete.. */
1017 printk(" \n%x %x %x %s\n ",assignid_map,mbuf[0],mbuf[1],&mbuf[2]); */
1020 if ((j & 0x20) != 0) { /* bit5=1:ID upto 7 */
1023 if ((j & 0x06) == 0) { /* IDvalid? */
1030 if ((m & assignid_map) == 0) {
1037 G2Q5: /* srch from max acceptable ID# */
1038 k = i; /* max acceptable ID# */
1042 if ((m & assignid_map) == 0) {
1049 G2Q_QUIN: /* k=binID#, */
1052 quintet[0] = 0x38; /* 1st dft ID<8 */
1054 quintet[0] = 0x31; /* 1st ID>=8 */
1057 quintet[1] = g2q_tab[k];
1059 val &= 0x00ff; /* AssignID 1stQuintet,AH=001xxxxx */
1060 m = quintet[0] << 8;
1062 fun_scam(dev, &val);
1063 val &= 0x00ff; /* AssignID 2ndQuintet,AH=001xxxxx */
1064 m = quintet[1] << 8;
1066 fun_scam(dev, &val);
1072 void is870(struct Scsi_Host *host, unsigned int wkport)
1074 unsigned int tmport;
1075 unsigned char i, j, k, rmb, n;
1076 unsigned short int m;
1077 static unsigned char mbuf[512];
1078 static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 };
1079 static unsigned char inqd[9] = { 0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6 };
1080 static unsigned char synn[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
1081 static unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0c, 0x0e };
1082 static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 };
1083 static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 };
1084 struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
1087 tmport = wkport + 0x3a;
1088 outb((unsigned char) (inb(tmport) | 0x10), tmport);
1090 for (i = 0; i < 16; i++) {
1091 if ((dev->chip_veru != 4) && (i > 7)) {
1096 if ((m & dev->active_idu) != 0) {
1099 if (i == dev->host_idu) {
1100 printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_idu);
1103 tmport = wkport + 0x1b;
1104 if (dev->chip_veru == 4) {
1109 tmport = wkport + 1;
1110 outb(0x08, tmport++);
1111 outb(0x7f, tmport++);
1112 outb(satn[0], tmport++);
1113 outb(satn[1], tmport++);
1114 outb(satn[2], tmport++);
1115 outb(satn[3], tmport++);
1116 outb(satn[4], tmport++);
1117 outb(satn[5], tmport++);
1121 outb(dev->id[i].devspu, tmport++);
1123 outb(satn[6], tmport++);
1124 outb(satn[7], tmport++);
1126 if ((j & 0x08) != 0) {
1127 j = (j & 0x07) | 0x40;
1131 outb(satn[8], tmport);
1134 while ((inb(tmport) & 0x80) == 0x00);
1136 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1139 while (inb(tmport) != 0x8e);
1140 dev->active_idu |= m;
1142 tmport = wkport + 0x10;
1144 tmport = wkport + 0x04;
1148 tmport = wkport + 0x18;
1151 while ((inb(tmport) & 0x80) == 0x00);
1155 tmport = wkport + 0x10;
1160 tmport = wkport + 3;
1161 outb(inqd[0], tmport++);
1162 outb(inqd[1], tmport++);
1163 outb(inqd[2], tmport++);
1164 outb(inqd[3], tmport++);
1165 outb(inqd[4], tmport++);
1166 outb(inqd[5], tmport);
1170 outb(dev->id[i].devspu, tmport++);
1172 outb(inqd[6], tmport++);
1173 outb(inqd[7], tmport++);
1175 outb(inqd[8], tmport);
1177 while ((inb(tmport) & 0x80) == 0x00);
1179 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1182 while (inb(tmport) != 0x8e);
1183 tmport = wkport + 0x1b;
1184 if (dev->chip_veru == 4) {
1187 tmport = wkport + 0x18;
1193 if ((k & 0x01) != 0) {
1195 mbuf[j++] = inb(tmport);
1199 if ((k & 0x80) == 0) {
1207 tmport = wkport + 0x10;
1216 while ((inb(tmport) & 0x80) == 0x00);
1218 if (inb(tmport) != 0x16) {
1223 printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]);
1224 dev->id[i].devtypeu = mbuf[0];
1227 if (dev->chip_veru != 4) {
1230 if ((mbuf[7] & 0x60) == 0) {
1233 if ((dev->global_map & 0x20) == 0) {
1236 tmport = wkport + 0x1b;
1238 tmport = wkport + 3;
1239 outb(satn[0], tmport++);
1240 outb(satn[1], tmport++);
1241 outb(satn[2], tmport++);
1242 outb(satn[3], tmport++);
1243 outb(satn[4], tmport++);
1244 outb(satn[5], tmport++);
1248 outb(dev->id[i].devspu, tmport++);
1250 outb(satn[6], tmport++);
1251 outb(satn[7], tmport++);
1253 outb(satn[8], tmport);
1256 while ((inb(tmport) & 0x80) == 0x00);
1258 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1261 while (inb(tmport) != 0x8e);
1264 tmport = wkport + 0x14;
1270 while ((inb(tmport) & 0x80) == 0) {
1271 if ((inb(tmport) & 0x01) != 0) {
1273 outb(wide[j++], tmport);
1278 while ((inb(tmport) & 0x80) == 0x00);
1279 j = inb(tmport) & 0x0f;
1291 tmport = wkport + 0x18;
1294 while ((inb(tmport) & 0x80) == 0) {
1295 if ((inb(tmport) & 0x01) != 0) {
1302 j = inb(tmport) & 0x0f;
1314 tmport = wkport + 0x14;
1322 if ((j & 0x01) != 0) {
1324 mbuf[k++] = inb(tmport);
1328 if ((j & 0x80) == 0x00) {
1332 j = inb(tmport) & 0x0f;
1344 tmport = wkport + 0x10;
1346 tmport = wkport + 0x14;
1351 while ((inb(tmport) & 0x80) == 0x00);
1360 if (mbuf[0] != 0x01) {
1363 if (mbuf[1] != 0x02) {
1366 if (mbuf[2] != 0x03) {
1369 if (mbuf[3] != 0x01) {
1376 if ((dev->id[i].devtypeu == 0x00) || (dev->id[i].devtypeu == 0x07) || ((dev->id[i].devtypeu == 0x05) && ((n & 0x10) != 0))) {
1381 tmport = wkport + 0x1b;
1383 if ((m & dev->wide_idu) != 0) {
1387 tmport = wkport + 3;
1388 outb(satn[0], tmport++);
1389 outb(satn[1], tmport++);
1390 outb(satn[2], tmport++);
1391 outb(satn[3], tmport++);
1392 outb(satn[4], tmport++);
1393 outb(satn[5], tmport++);
1397 outb(dev->id[i].devspu, tmport++);
1399 outb(satn[6], tmport++);
1400 outb(satn[7], tmport++);
1402 outb(satn[8], tmport);
1405 while ((inb(tmport) & 0x80) == 0x00);
1407 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1410 while (inb(tmport) != 0x8e);
1413 tmport = wkport + 0x14;
1419 while ((inb(tmport) & 0x80) == 0) {
1420 if ((inb(tmport) & 0x01) != 0) {
1422 if ((m & dev->wide_idu) != 0) {
1423 outb(synw[j++], tmport);
1425 if ((m & dev->ultra_map) != 0) {
1426 outb(synu[j++], tmport);
1428 outb(synn[j++], tmport);
1435 while ((inb(tmport) & 0x80) == 0x00);
1436 j = inb(tmport) & 0x0f;
1448 tmport = wkport + 0x18;
1451 while ((inb(tmport) & 0x80) == 0x00) {
1452 if ((inb(tmport) & 0x01) != 0x00) {
1475 tmport = wkport + 0x14;
1483 if ((j & 0x01) != 0x00) {
1485 mbuf[k++] = inb(tmport);
1489 if ((j & 0x80) == 0x00) {
1493 while ((inb(tmport) & 0x80) == 0x00);
1510 tmport = wkport + 0x10;
1513 tmport = wkport + 0x14;
1518 while ((inb(tmport) & 0x80) == 0x00);
1524 if (mbuf[0] != 0x01) {
1527 if (mbuf[1] != 0x03) {
1530 if (mbuf[4] == 0x00) {
1533 if (mbuf[3] > 0x64) {
1536 if (mbuf[4] > 0x0c) {
1539 dev->id[i].devspu = mbuf[4];
1540 if ((mbuf[3] < 0x0d) && (rmb == 0)) {
1544 if (mbuf[3] < 0x1a) {
1548 if (mbuf[3] < 0x33) {
1552 if (mbuf[3] < 0x4c) {
1558 dev->id[i].devspu = (dev->id[i].devspu & 0x0f) | j;
1560 tmport = wkport + 0x3a;
1561 outb((unsigned char) (inb(tmport) & 0xef), tmport);
1564 static void is880(struct Scsi_Host *host, unsigned int wkport)
1566 unsigned int tmport;
1567 unsigned char i, j, k, rmb, n, lvdmode;
1568 unsigned short int m;
1569 static unsigned char mbuf[512];
1570 static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 };
1571 static unsigned char inqd[9] = { 0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6 };
1572 static unsigned char synn[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
1573 unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e };
1574 static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
1575 unsigned char synuw[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e };
1576 static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 };
1577 static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 };
1578 struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
1581 lvdmode = inb(wkport + 0x3f) & 0x40;
1583 for (i = 0; i < 16; i++) {
1586 if ((m & dev->active_idu) != 0) {
1589 if (i == dev->host_idu) {
1590 printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_idu);
1593 tmport = wkport + 0x5b;
1595 tmport = wkport + 0x41;
1596 outb(0x08, tmport++);
1597 outb(0x7f, tmport++);
1598 outb(satn[0], tmport++);
1599 outb(satn[1], tmport++);
1600 outb(satn[2], tmport++);
1601 outb(satn[3], tmport++);
1602 outb(satn[4], tmport++);
1603 outb(satn[5], tmport++);
1607 outb(dev->id[i].devspu, tmport++);
1609 outb(satn[6], tmport++);
1610 outb(satn[7], tmport++);
1612 if ((j & 0x08) != 0) {
1613 j = (j & 0x07) | 0x40;
1617 outb(satn[8], tmport);
1620 while ((inb(tmport) & 0x80) == 0x00);
1622 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1625 while (inb(tmport) != 0x8e);
1626 dev->active_idu |= m;
1628 tmport = wkport + 0x50;
1630 tmport = wkport + 0x54;
1634 tmport = wkport + 0x58;
1637 while ((inb(tmport) & 0x80) == 0x00);
1641 tmport = wkport + 0x50;
1646 tmport = wkport + 0x43;
1647 outb(inqd[0], tmport++);
1648 outb(inqd[1], tmport++);
1649 outb(inqd[2], tmport++);
1650 outb(inqd[3], tmport++);
1651 outb(inqd[4], tmport++);
1652 outb(inqd[5], tmport);
1656 outb(dev->id[i].devspu, tmport++);
1658 outb(inqd[6], tmport++);
1659 outb(inqd[7], tmport++);
1661 outb(inqd[8], tmport);
1663 while ((inb(tmport) & 0x80) == 0x00);
1665 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1668 while (inb(tmport) != 0x8e);
1669 tmport = wkport + 0x5b;
1671 tmport = wkport + 0x58;
1677 if ((k & 0x01) != 0) {
1679 mbuf[j++] = inb(tmport);
1683 if ((k & 0x80) == 0) {
1691 tmport = wkport + 0x50;
1700 while ((inb(tmport) & 0x80) == 0x00);
1702 if (inb(tmport) != 0x16) {
1707 printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]);
1708 dev->id[i].devtypeu = mbuf[0];
1711 if ((mbuf[7] & 0x60) == 0) {
1714 if ((i < 8) && ((dev->global_map & 0x20) == 0)) {
1720 if (dev->sp[i] != 0x04) // force u2
1725 tmport = wkport + 0x5b;
1727 tmport = wkport + 0x43;
1728 outb(satn[0], tmport++);
1729 outb(satn[1], tmport++);
1730 outb(satn[2], tmport++);
1731 outb(satn[3], tmport++);
1732 outb(satn[4], tmport++);
1733 outb(satn[5], tmport++);
1737 outb(dev->id[i].devspu, tmport++);
1739 outb(satn[6], tmport++);
1740 outb(satn[7], tmport++);
1742 outb(satn[8], tmport);
1745 while ((inb(tmport) & 0x80) == 0x00);
1747 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1750 while (inb(tmport) != 0x8e);
1753 tmport = wkport + 0x54;
1759 while ((inb(tmport) & 0x80) == 0) {
1760 if ((inb(tmport) & 0x01) != 0) {
1762 outb(u3[j++], tmport);
1767 while ((inb(tmport) & 0x80) == 0x00);
1768 j = inb(tmport) & 0x0f;
1780 tmport = wkport + 0x58;
1783 while ((inb(tmport) & 0x80) == 0) {
1784 if ((inb(tmport) & 0x01) != 0) {
1791 j = inb(tmport) & 0x0f;
1803 tmport = wkport + 0x54;
1811 if ((j & 0x01) != 0) {
1813 mbuf[k++] = inb(tmport);
1817 if ((j & 0x80) == 0x00) {
1821 j = inb(tmport) & 0x0f;
1833 tmport = wkport + 0x50;
1835 tmport = wkport + 0x54;
1840 while ((inb(tmport) & 0x80) == 0x00);
1849 if (mbuf[0] != 0x01) {
1852 if (mbuf[1] != 0x06) {
1855 if (mbuf[2] != 0x04) {
1858 if (mbuf[3] == 0x09) {
1862 dev->id[i].devspu = 0xce;
1866 tmport = wkport + 0x5b;
1868 tmport = wkport + 0x43;
1869 outb(satn[0], tmport++);
1870 outb(satn[1], tmport++);
1871 outb(satn[2], tmport++);
1872 outb(satn[3], tmport++);
1873 outb(satn[4], tmport++);
1874 outb(satn[5], tmport++);
1878 outb(dev->id[i].devspu, tmport++);
1880 outb(satn[6], tmport++);
1881 outb(satn[7], tmport++);
1883 outb(satn[8], tmport);
1886 while ((inb(tmport) & 0x80) == 0x00);
1888 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1891 while (inb(tmport) != 0x8e);
1894 tmport = wkport + 0x54;
1900 while ((inb(tmport) & 0x80) == 0) {
1901 if ((inb(tmport) & 0x01) != 0) {
1903 outb(wide[j++], tmport);
1908 while ((inb(tmport) & 0x80) == 0x00);
1909 j = inb(tmport) & 0x0f;
1921 tmport = wkport + 0x58;
1924 while ((inb(tmport) & 0x80) == 0) {
1925 if ((inb(tmport) & 0x01) != 0) {
1932 j = inb(tmport) & 0x0f;
1944 tmport = wkport + 0x54;
1952 if ((j & 0x01) != 0) {
1954 mbuf[k++] = inb(tmport);
1958 if ((j & 0x80) == 0x00) {
1962 j = inb(tmport) & 0x0f;
1974 tmport = wkport + 0x50;
1976 tmport = wkport + 0x54;
1981 while ((inb(tmport) & 0x80) == 0x00);
1990 if (mbuf[0] != 0x01) {
1993 if (mbuf[1] != 0x02) {
1996 if (mbuf[2] != 0x03) {
1999 if (mbuf[3] != 0x01) {
2006 if ((dev->id[i].devtypeu == 0x00) || (dev->id[i].devtypeu == 0x07) || ((dev->id[i].devtypeu == 0x05) && ((n & 0x10) != 0))) {
2009 if ((dev->async & m) != 0) {
2015 if (dev->sp[i] == 0x02) {
2019 if (dev->sp[i] >= 0x03) {
2024 tmport = wkport + 0x5b;
2026 if ((m & dev->wide_idu) != 0) {
2030 tmport = wkport + 0x43;
2031 outb(satn[0], tmport++);
2032 outb(satn[1], tmport++);
2033 outb(satn[2], tmport++);
2034 outb(satn[3], tmport++);
2035 outb(satn[4], tmport++);
2036 outb(satn[5], tmport++);
2040 outb(dev->id[i].devspu, tmport++);
2042 outb(satn[6], tmport++);
2043 outb(satn[7], tmport++);
2045 outb(satn[8], tmport);
2048 while ((inb(tmport) & 0x80) == 0x00);
2050 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
2053 while (inb(tmport) != 0x8e);
2056 tmport = wkport + 0x54;
2062 while ((inb(tmport) & 0x80) == 0) {
2063 if ((inb(tmport) & 0x01) != 0) {
2065 if ((m & dev->wide_idu) != 0) {
2066 if ((m & dev->ultra_map) != 0) {
2067 outb(synuw[j++], tmport);
2069 outb(synw[j++], tmport);
2072 if ((m & dev->ultra_map) != 0) {
2073 outb(synu[j++], tmport);
2075 outb(synn[j++], tmport);
2082 while ((inb(tmport) & 0x80) == 0x00);
2083 j = inb(tmport) & 0x0f;
2095 tmport = wkport + 0x58;
2098 while ((inb(tmport) & 0x80) == 0x00) {
2099 if ((inb(tmport) & 0x01) != 0x00) {
2122 tmport = wkport + 0x54;
2130 if ((j & 0x01) != 0x00) {
2132 mbuf[k++] = inb(tmport);
2136 if ((j & 0x80) == 0x00) {
2140 while ((inb(tmport) & 0x80) == 0x00);
2157 tmport = wkport + 0x50;
2160 tmport = wkport + 0x54;
2165 while ((inb(tmport) & 0x80) == 0x00);
2171 if (mbuf[0] != 0x01) {
2174 if (mbuf[1] != 0x03) {
2177 if (mbuf[4] == 0x00) {
2180 if (mbuf[3] > 0x64) {
2183 if (mbuf[4] > 0x0e) {
2186 dev->id[i].devspu = mbuf[4];
2187 if (mbuf[3] < 0x0c) {
2191 if ((mbuf[3] < 0x0d) && (rmb == 0)) {
2195 if (mbuf[3] < 0x1a) {
2199 if (mbuf[3] < 0x33) {
2203 if (mbuf[3] < 0x4c) {
2209 dev->id[i].devspu = (dev->id[i].devspu & 0x0f) | j;
2213 static void atp870u_free_tables(struct Scsi_Host *host)
2215 struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata;
2218 for (k = 0; k < 16; k++) {
2219 if (!atp_dev->id[k].prd_tableu)
2221 pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[k].prd_tableu,
2222 atp_dev->id[k].prd_phys);
2223 atp_dev->id[k].prd_tableu = NULL;
2227 static int atp870u_init_tables(struct Scsi_Host *host)
2229 struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
2232 for (i = k = 0; k < 16; k++) {
2233 dev->id[k].prd_tableu = pci_alloc_consistent(dev->pdev, 1024, &dev->id[k].prd_phys);
2234 if (!dev->id[k].prd_tableu) {
2235 atp870u_free_tables(host);
2238 dev->id[k].devspu = 0x20;
2239 dev->id[k].devtypeu = 0;
2240 dev->id[k].curr_req = NULL;
2242 dev->active_idu = 0;
2244 dev->host_idu = 0x07;
2248 dev->last_cmd = 0xff;
2251 for (k = 0; k < qcnt; k++) {
2252 dev->querequ[k] = 0;
2254 for (k = 0; k < 16; k++) {
2255 dev->id[k].curr_req = 0;
2261 /* return non-zero on detection */
2262 static int atp870u_probe(struct pci_dev *dev, const struct pci_device_id *ent)
2265 unsigned long flags;
2266 unsigned int base_io, error, tmport;
2267 unsigned char host_id;
2269 struct Scsi_Host *shpnt;
2270 struct atp_unit atp_dev, *p;
2273 if (pci_enable_device(dev))
2276 if (pci_set_dma_mask(dev, 0xFFFFFFFFUL)) {
2277 printk(KERN_ERR "atp870u: 32bit DMA mask required but not available.\n");
2281 memset(&atp_dev, 0, sizeof atp_dev);
2284 * It's probably easier to weed out some revisions like
2285 * this than via the PCI device table
2287 if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) {
2288 error = pci_read_config_byte(dev, PCI_CLASS_REVISION, &atp_dev.chip_veru);
2289 if (atp_dev.chip_veru < 2)
2293 switch (ent->device) {
2295 case PCI_DEVICE_ID_ARTOP_AEC7612UW:
2296 case PCI_DEVICE_ID_ARTOP_AEC7612SUW:
2297 atp_dev.chip_veru = 0x04;
2302 base_io = pci_resource_start(dev, 0);
2304 if (ent->device != 0x8081) {
2305 error = pci_read_config_byte(dev, 0x49, &host_id);
2306 base_io &= 0xfffffff8;
2308 printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-3 Host Adapter: %d "
2309 "IO:%x, IRQ:%d.\n", count, base_io, dev->irq);
2311 atp_dev.unit = count;
2312 atp_dev.ioport = base_io;
2313 atp_dev.pciport = base_io + 0x20;
2314 atp_dev.deviceid = ent->device;
2316 atp_dev.host_idu = host_id;
2317 tmport = base_io + 0x22;
2318 atp_dev.scam_on = inb(tmport);
2320 atp_dev.global_map = inb(tmport++);
2321 atp_dev.ultra_map = inw(tmport);
2323 if (atp_dev.ultra_map == 0) {
2324 atp_dev.scam_on = 0x00;
2325 atp_dev.global_map = 0x20;
2326 atp_dev.ultra_map = 0xffff;
2329 shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
2333 p = (struct atp_unit *)&shpnt->hostdata;
2335 atp_dev.host = shpnt;
2337 pci_set_drvdata(dev, p);
2338 memcpy(p, &atp_dev, sizeof atp_dev);
2339 if (atp870u_init_tables(shpnt) < 0)
2342 if (request_irq(dev->irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", shpnt)) {
2343 printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", dev->irq);
2347 spin_lock_irqsave(shpnt->host_lock, flags);
2348 if (atp_dev.chip_veru > 0x07) { /* check if atp876 chip then enable terminator */
2349 tmport = base_io + 0x3e;
2353 tmport = base_io + 0x3a;
2354 k = (inb(tmport) & 0xf3) | 0x10;
2356 outb((k & 0xdf), tmport);
2361 outb((host_id | 0x08), tmport);
2365 while ((inb(tmport) & 0x80) == 0)
2370 tmport = base_io + 1;
2373 tmport = base_io + 0x11;
2377 is870(shpnt, base_io);
2378 tmport = base_io + 0x3a;
2379 outb((inb(tmport) & 0xef), tmport);
2381 outb((inb(tmport) | 0x20), tmport);
2383 base_io &= 0xfffffff8;
2384 host_id = inb(base_io + 0x39);
2387 printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d"
2388 " IO:%x, IRQ:%d.\n", count, base_io, dev->irq);
2389 atp_dev.ioport = base_io + 0x40;
2390 atp_dev.pciport = base_io + 0x28;
2391 atp_dev.deviceid = ent->device;
2392 atp_dev.host_idu = host_id;
2394 tmport = base_io + 0x22;
2395 atp_dev.scam_on = inb(tmport);
2397 atp_dev.global_map = inb(tmport);
2399 atp_dev.ultra_map = inw(tmport);
2407 outw(n, base_io + 0x34);
2409 if (inb(base_io + 0x30) == 0xff)
2412 atp_dev.sp[m++] = inb(base_io + 0x30);
2413 atp_dev.sp[m++] = inb(base_io + 0x31);
2414 atp_dev.sp[m++] = inb(base_io + 0x32);
2415 atp_dev.sp[m++] = inb(base_io + 0x33);
2416 outw(n, base_io + 0x34);
2418 atp_dev.sp[m++] = inb(base_io + 0x30);
2419 atp_dev.sp[m++] = inb(base_io + 0x31);
2420 atp_dev.sp[m++] = inb(base_io + 0x32);
2421 atp_dev.sp[m++] = inb(base_io + 0x33);
2422 outw(n, base_io + 0x34);
2424 atp_dev.sp[m++] = inb(base_io + 0x30);
2425 atp_dev.sp[m++] = inb(base_io + 0x31);
2426 atp_dev.sp[m++] = inb(base_io + 0x32);
2427 atp_dev.sp[m++] = inb(base_io + 0x33);
2428 outw(n, base_io + 0x34);
2430 atp_dev.sp[m++] = inb(base_io + 0x30);
2431 atp_dev.sp[m++] = inb(base_io + 0x31);
2432 atp_dev.sp[m++] = inb(base_io + 0x32);
2433 atp_dev.sp[m++] = inb(base_io + 0x33);
2437 outw(0, base_io + 0x34);
2438 atp_dev.ultra_map = 0;
2440 for (k = 0; k < 16; k++) {
2443 if (atp_dev.sp[k] > 1) {
2444 atp_dev.ultra_map |= n;
2446 if (atp_dev.sp[k] == 0)
2450 atp_dev.async = ~(atp_dev.async);
2451 outb(atp_dev.global_map, base_io + 0x35);
2453 shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
2457 p = (struct atp_unit *)&shpnt->hostdata;
2459 atp_dev.host = shpnt;
2461 pci_set_drvdata(dev, p);
2462 memcpy(p, &atp_dev, sizeof atp_dev);
2463 if (atp870u_init_tables(shpnt) < 0) {
2464 printk(KERN_ERR "Unable to allocate tables for Acard controller\n");
2468 if (request_irq(dev->irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", shpnt)) {
2469 printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", dev->irq);
2473 spin_lock_irqsave(shpnt->host_lock, flags);
2474 tmport = base_io + 0x38;
2475 k = inb(tmport) & 0x80;
2482 tmport = base_io + 0x5b;
2486 tmport = base_io + 0x40;
2487 outb((host_id | 0x08), tmport);
2491 while ((inb(tmport) & 0x80) == 0)
2495 tmport = base_io + 0x41;
2498 tmport = base_io + 0x51;
2502 is880(shpnt, base_io);
2503 tmport = base_io + 0x38;
2507 if (p->chip_veru == 4)
2510 shpnt->this_id = host_id;
2511 shpnt->unique_id = base_io;
2512 shpnt->io_port = base_io;
2513 if (ent->device == 0x8081) {
2514 shpnt->n_io_port = 0x60; /* Number of bytes of I/O space used */
2516 shpnt->n_io_port = 0x40; /* Number of bytes of I/O space used */
2518 shpnt->irq = dev->irq;
2519 spin_unlock_irqrestore(shpnt->host_lock, flags);
2520 if (ent->device == 0x8081) {
2521 if (!request_region(base_io, 0x60, "atp870u"))
2522 goto request_io_fail;
2524 if (!request_region(base_io, 0x40, "atp870u"))
2525 goto request_io_fail;
2529 if (scsi_add_host(shpnt, &dev->dev))
2531 scsi_scan_host(shpnt);
2535 if (ent->device == 0x8081)
2536 release_region(base_io, 0x60);
2538 release_region(base_io, 0x40);
2540 free_irq(dev->irq, shpnt);
2542 atp870u_free_tables(shpnt);
2544 scsi_host_put(shpnt);
2548 /* The abort command does not leave the device in a clean state where
2549 it is available to be used again. Until this gets worked out, we will
2550 leave it commented out. */
2552 int atp870u_abort(Scsi_Cmnd * SCpnt)
2555 Scsi_Cmnd *workrequ;
2556 unsigned int tmport;
2557 struct atp_unit *dev = (struct atp_unit *)&SCpnt->device->host->hostdata;
2559 printk(KERN_DEBUG "working=%x last_cmd=%x ", dev->working, dev->last_cmd);
2560 printk(" quhdu=%x quendu=%x ", dev->quhdu, dev->quendu);
2561 tmport = dev->ioport;
2562 for (j = 0; j < 0x17; j++) {
2563 printk(" r%2x=%2x", j, inb(tmport++));
2566 printk(" r1c=%2x", inb(tmport));
2568 printk(" r1f=%2x in_snd=%2x ", inb(tmport), dev->in_snd);
2569 tmport = dev->pciport;
2570 printk(" r20=%2x", inb(tmport));
2572 printk(" r22=%2x", inb(tmport));
2573 tmport = dev->ioport + 0x3a;
2574 printk(" r3a=%2x \n", inb(tmport));
2575 tmport = dev->ioport + 0x3b;
2576 printk(" r3b=%2x \n", inb(tmport));
2577 for (j = 0; j < 16; j++) {
2578 if (dev->id[j].curr_req != NULL) {
2579 workrequ = dev->id[j].curr_req;
2580 printk("\n que cdb= ");
2581 for (k = 0; k < workrequ->cmd_len; k++) {
2582 printk(" %2x ", workrequ->cmnd[k]);
2584 printk(" last_lenu= %lx ", dev->id[j].last_lenu);
2587 /* Sort of - the thing handles itself */
2591 const char *atp870u_info(struct Scsi_Host *notused)
2593 static char buffer[128];
2595 strcpy(buffer, "ACARD AEC-6710/6712/67160 PCI Ultra/W/LVD SCSI-3 Adapter Driver V2.6+ac ");
2600 int atp870u_set_info(char *buffer, int length, struct Scsi_Host *HBAptr)
2602 return -ENOSYS; /* Currently this is a no-op */
2605 #define BLS buffer + len + size
2606 int atp870u_proc_info(struct Scsi_Host *HBAptr, char *buffer, char **start, off_t offset, int length, int inout)
2608 static u8 buff[512];
2614 if (inout == TRUE) { /* Has data been written to the file? */
2615 return (atp870u_set_info(buffer, length, HBAptr));
2618 memset(buff, 0, sizeof(buff));
2620 size += sprintf(BLS, "ACARD AEC-671X Driver Version: 2.6+ac\n");
2625 size += sprintf(BLS, "\n");
2626 size += sprintf(BLS, "Adapter Configuration:\n");
2627 size += sprintf(BLS, " Base IO: %#.4lx\n", HBAptr->io_port);
2628 size += sprintf(BLS, " IRQ: %d\n", HBAptr->irq);
2632 *start = buffer + (offset - begin); /* Start of wanted data */
2633 len -= (offset - begin); /* Start slop */
2635 len = length; /* Ending slop */
2640 static int atp870u_biosparam(struct scsi_device *sdev,
2641 struct block_device *dev, sector_t capacity, int *ip)
2643 int heads, sectors, cylinders;
2647 cylinders = (unsigned long)capacity / (heads * sectors);
2649 if (cylinders > 1024) {
2652 cylinders = (unsigned long)capacity / (heads * sectors);
2661 static void atp870u_remove(struct pci_dev *pdev)
2663 struct atp_unit *atp_dev = pci_get_drvdata(pdev);
2664 struct Scsi_Host *pshost = atp_dev->host;
2666 scsi_remove_host(pshost);
2667 free_irq(pshost->irq, pshost);
2668 release_region(pshost->io_port, pshost->n_io_port);
2669 atp870u_free_tables(pshost);
2670 scsi_host_put(pshost);
2671 pci_set_drvdata(pdev, NULL);
2674 MODULE_LICENSE("GPL");
2676 static Scsi_Host_Template atp870u_template = {
2677 .module = THIS_MODULE,
2679 .proc_name = "atp870u",
2680 .proc_info = atp870u_proc_info,
2681 .info = atp870u_info,
2682 .queuecommand = atp870u_queuecommand,
2683 .eh_abort_handler = atp870u_abort,
2684 .bios_param = atp870u_biosparam,
2687 .sg_tablesize = ATP870U_SCATTER,
2688 .cmd_per_lun = ATP870U_CMDLUN,
2689 .use_clustering = ENABLE_CLUSTERING,
2692 static struct pci_device_id atp870u_id_table[] = {
2693 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, 0x8081) },
2694 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7610) },
2695 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612UW) },
2696 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612U) },
2697 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612S) },
2698 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612D) },
2699 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612SUW) },
2700 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_8060) },
2704 MODULE_DEVICE_TABLE(pci, atp870u_id_table);
2706 static struct pci_driver atp870u_driver = {
2707 .id_table = atp870u_id_table,
2709 .probe = atp870u_probe,
2710 .remove = __devexit_p(atp870u_remove),
2713 static int __init atp870u_init(void)
2715 pci_register_driver(&atp870u_driver);
2719 static void __exit atp870u_exit(void)
2721 pci_unregister_driver(&atp870u_driver);
2724 module_init(atp870u_init);
2725 module_exit(atp870u_exit);