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>
7 * 2.6.x update (C) 2004 Red Hat <alan@redhat.com>
9 * Marcelo Tosatti <marcelo@conectiva.com.br> : SMP fixes
11 * Wu Ching Chen : NULL pointer fixes 2000/06/02
13 * enable 32 bit fifo transfer
14 * support cdrom & remove device run ultra speed
15 * fix disconnect bug 2000/12/21
16 * support atp880 chip lvd u160 2001/05/15
17 * fix prd table bug 2001/09/12 (7.1)
20 #include <linux/module.h>
21 #include <linux/init.h>
22 #include <linux/interrupt.h>
23 #include <linux/kernel.h>
24 #include <linux/types.h>
25 #include <linux/string.h>
26 #include <linux/ioport.h>
27 #include <linux/delay.h>
28 #include <linux/proc_fs.h>
29 #include <linux/spinlock.h>
30 #include <linux/pci.h>
31 #include <linux/blkdev.h>
32 #include <linux/stat.h>
34 #include <asm/system.h>
38 #include <scsi/scsi_host.h>
42 * 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 $";
45 static unsigned short int sync_idu;
47 static irqreturn_t atp870u_intr_handle(int irq, void *dev_id,
51 unsigned short int tmpcip, id;
52 unsigned char i, j, target_id, lun;
55 unsigned int workportu, tmport;
56 unsigned long adrcntu, k;
58 struct Scsi_Host *host = dev_id;
59 struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
62 workportu = dev->ioport;
65 if (dev->working != 0) {
68 if ((j & 0x80) == 0) {
73 tmpcip = dev->pciport;
74 if ((inb(tmpcip) & 0x08) != 0) {
76 for (k = 0; k < 1000; k++) {
77 if ((inb(tmpcip) & 0x08) == 0) {
80 if ((inb(tmpcip) & 0x01) == 0) {
86 tmpcip = dev->pciport;
93 target_id = inb(tmport);
97 * Remap wide devices onto id numbers
100 if ((target_id & 0x40) != 0) {
101 target_id = (target_id & 0x07) | 0x08;
106 if ((j & 0x40) != 0) {
107 if (dev->last_cmd == 0xff) {
108 dev->last_cmd = target_id;
110 dev->last_cmd |= 0x40;
114 if ((dev->last_cmd & 0xf0) != 0x40) {
115 dev->last_cmd = 0xff;
120 if (dev->wide_idu != 0) {
121 tmport = workportu + 0x1b;
123 while ((inb(tmport) & 0x01) != 0x01) {
128 * Issue more commands
130 spin_lock_irqsave(dev->host->host_lock, flags);
131 if (((dev->quhdu != dev->quendu) || (dev->last_cmd != 0xff)) && (dev->in_snd == 0)) {
134 spin_unlock_irqrestore(dev->host->host_lock, flags);
143 dev->last_cmd |= 0x40;
149 if ((dev->last_cmd & 0xf0) != 0x40) {
150 dev->last_cmd = 0xff;
154 ((unsigned char *) &adrcntu)[2] = inb(tmport++);
155 ((unsigned char *) &adrcntu)[1] = inb(tmport++);
156 ((unsigned char *) &adrcntu)[0] = inb(tmport);
157 k = dev->id[target_id].last_lenu;
159 dev->id[target_id].tran_lenu = k;
160 dev->id[target_id].last_lenu = adrcntu;
168 if ((i == 0x80) || (i == 0x8f)) {
172 if (j == 0x44 || i == 0x80) {
174 lun = inb(tmport) & 0x07;
176 if ((dev->last_cmd & 0xf0) != 0x40) {
177 dev->last_cmd = 0xff;
182 ((unsigned char *) &adrcntu)[2] = inb(tmport++);
183 ((unsigned char *) &adrcntu)[1] = inb(tmport++);
184 ((unsigned char *) &adrcntu)[0] = inb(tmport);
185 k = dev->id[target_id].last_lenu;
187 dev->id[target_id].tran_lenu = k;
188 dev->id[target_id].last_lenu = adrcntu;
195 dev->id[target_id].dirctu = 0x00;
197 outb(0x00, tmport++);
198 outb(0x00, tmport++);
199 outb(0x00, tmport++);
206 if (dev->last_cmd != 0xff) {
207 dev->last_cmd |= 0x40;
209 tmport = workportu + 0x10;
212 target_id = inb(tmport);
214 * Remap wide identifiers
216 if ((target_id & 0x10) != 0) {
217 target_id = (target_id & 0x07) | 0x08;
221 workrequ = dev->id[target_id].curr_req;
222 tmport = workportu + 0x0f;
225 outb(dev->id[target_id].devspu, tmport++);
226 adrcntu = dev->id[target_id].tran_lenu;
227 k = dev->id[target_id].last_lenu;
228 outb(((unsigned char *) &k)[2], tmport++);
229 outb(((unsigned char *) &k)[1], tmport++);
230 outb(((unsigned char *) &k)[0], tmport++);
234 j = (j & 0x07) | 0x40;
237 j |= dev->id[target_id].dirctu;
241 /* enable 32 bit fifo transfer */
242 if (dev->deviceid != 0x8081) {
243 tmport = workportu + 0x3a;
244 if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) || (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a)) {
245 outb((unsigned char) ((inb(tmport) & 0xf3) | 0x08), tmport);
247 outb((unsigned char) (inb(tmport) & 0xf3), tmport);
250 tmport = workportu - 0x05;
251 if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) || (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a)) {
252 outb((unsigned char) ((inb(tmport) & 0x3f) | 0xc0), tmport);
254 outb((unsigned char) (inb(tmport) & 0x3f), tmport);
258 tmport = workportu + 0x1b;
261 id = id << target_id;
263 * Is this a wide device
265 if ((id & dev->wide_idu) != 0) {
269 while ((inb(tmport) & 0x01) != j) {
273 if (dev->id[target_id].last_lenu == 0) {
274 tmport = workportu + 0x18;
279 prd = dev->id[target_id].prd_posu;
280 while (adrcntu != 0) {
281 id = ((unsigned short int *) (prd))[2];
288 ((unsigned short int *) (prd))[2] = (unsigned short int)
290 ((unsigned long *) (prd))[0] += adrcntu;
292 dev->id[target_id].prd_posu = prd;
295 dev->id[target_id].prdaddru += 0x08;
298 dev->id[target_id].prd_posu = prd;
302 tmpcip = dev->pciport + 0x04;
303 outl(dev->id[target_id].prdaddru, tmpcip);
308 tmport = workportu + 0x18;
310 * Check transfer direction
312 if (dev->id[target_id].dirctu != 0) {
325 * Current scsi request on this target
328 workrequ = dev->id[target_id].curr_req;
331 if ((dev->last_cmd & 0xf0) != 0x40) {
332 dev->last_cmd = 0xff;
335 workrequ->result = errstus;
339 if ((dev->last_cmd & 0xf0) != 0x40) {
340 dev->last_cmd = 0xff;
344 errstus = inb(tmport);
345 workrequ->result = errstus;
348 * Complete the command
352 pci_unmap_sg(dev->pdev, (struct scatterlist *)workrequ->buffer, workrequ->use_sg, scsi_to_pci_dma_dir(workrequ->sc_data_direction));
353 else if(workrequ->request_bufflen && workrequ->sc_data_direction != SCSI_DATA_NONE)
354 pci_unmap_single(dev->pdev, workrequ->SCp.dma_handle, workrequ->request_bufflen, scsi_to_pci_dma_dir(workrequ->sc_data_direction));
355 spin_lock_irqsave(dev->host->host_lock, flags);
356 (*workrequ->scsi_done) (workrequ);
359 * Clear it off the queue
361 dev->id[target_id].curr_req = 0;
363 spin_unlock_irqrestore(dev->host->host_lock, flags);
367 if (dev->wide_idu != 0) {
368 tmport = workportu + 0x1b;
370 while ((inb(tmport) & 0x01) != 0x01) {
375 * If there is stuff to send and nothing going then send it
377 spin_lock_irqsave(dev->host->host_lock, flags);
378 if (((dev->last_cmd != 0xff) || (dev->quhdu != dev->quendu)) && (dev->in_snd == 0)) {
381 spin_unlock_irqrestore(dev->host->host_lock, flags);
385 if ((dev->last_cmd & 0xf0) != 0x40) {
386 dev->last_cmd = 0xff;
394 outl(dev->id[target_id].prdaddru, tmpcip);
399 tmport = workportu + 0x10;
401 dev->id[target_id].dirctu = 0x00;
410 outl(dev->id[target_id].prdaddru, tmpcip);
415 tmport = workportu + 0x10;
418 outb((unsigned char) (inb(tmport) | 0x20), tmport);
419 dev->id[target_id].dirctu = 0x20;
432 dev->id[target_id].dirctu = 0x00;
434 outb(0x00, tmport++);
435 outb(0x00, tmport++);
436 outb(0x00, tmport++);
442 // tmport = workportu + 0x17;
452 * atp870u_queuecommand - Queue SCSI command
453 * @req_p: request block
454 * @done: completion function
456 * Queue a command to the ATP queue. Called with the host lock held.
459 static int atp870u_queuecommand(Scsi_Cmnd * req_p, void (*done) (Scsi_Cmnd *))
461 unsigned short int m;
463 struct Scsi_Host *host;
464 struct atp_unit *dev;
466 if (req_p->device->channel != 0) {
467 req_p->result = 0x00040000;
472 host = req_p->device->host;
473 dev = (struct atp_unit *)&host->hostdata;
476 m = m << req_p->device->id;
479 * Fake a timeout for missing targets
482 if ((m & dev->active_idu) == 0) {
483 req_p->result = 0x00040000;
488 req_p->scsi_done = done;
490 printk(KERN_WARNING "atp870u_queuecommand: done can't be NULL\n");
500 if (dev->quendu >= qcnt) {
506 if (dev->quhdu == dev->quendu) {
507 if (dev->quendu == 0) {
511 req_p->result = 0x00020000;
515 dev->querequ[dev->quendu] = req_p;
516 tmport = dev->ioport + 0x1c;
517 if ((inb(tmport) == 0) && (dev->in_int == 0) && (dev->in_snd == 0)) {
524 * send_s870 - send a command to the controller
527 * On entry there is work queued to be done. We move some of that work to the
530 * Caller holds the host lock.
533 static void send_s870(struct Scsi_Host *host)
538 unsigned char j, target_id;
540 unsigned short int tmpcip, w;
543 unsigned int workportu;
544 struct scatterlist *sgpnt;
545 struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
548 if (dev->in_snd != 0) {
552 if ((dev->last_cmd != 0xff) && ((dev->last_cmd & 0x40) != 0)) {
553 dev->last_cmd &= 0x0f;
554 workrequ = dev->id[dev->last_cmd].curr_req;
555 if (workrequ != NULL) { /* check NULL pointer */
558 dev->last_cmd = 0xff;
559 if (dev->quhdu == dev->quendu) {
564 if ((dev->last_cmd != 0xff) && (dev->working != 0)) {
571 if (dev->quhdu >= qcnt) {
574 workrequ = dev->querequ[dev->quhdu];
575 if (dev->id[workrequ->device->id].curr_req == 0) {
576 dev->id[workrequ->device->id].curr_req = workrequ;
577 dev->last_cmd = workrequ->device->id;
585 workportu = dev->ioport;
586 tmport = workportu + 0x1f;
587 if ((inb(tmport) & 0xb0) != 0) {
590 tmport = workportu + 0x1c;
591 if (inb(tmport) == 0) {
595 dev->last_cmd |= 0x40;
599 memcpy(&dev->ata_cdbu[0], &workrequ->cmnd[0], workrequ->cmd_len);
600 if (dev->ata_cdbu[0] == READ_CAPACITY) {
601 if (workrequ->request_bufflen > 8) {
602 workrequ->request_bufflen = 0x08;
605 if (dev->ata_cdbu[0] == 0x00) {
606 workrequ->request_bufflen = 0;
609 tmport = workportu + 0x1b;
611 target_id = workrequ->device->id;
618 if ((w & dev->wide_idu) != 0) {
622 while ((inb(tmport) & 0x01) != j) {
631 outb(workrequ->cmd_len, tmport++);
632 outb(0x2c, tmport++);
633 outb(0xcf, tmport++);
634 for (i = 0; i < workrequ->cmd_len; i++) {
635 outb(dev->ata_cdbu[i], tmport++);
637 tmport = workportu + 0x0f;
638 outb(workrequ->device->lun, tmport);
643 outb(dev->id[target_id].devspu, tmport++);
646 * Figure out the transfer size
648 if (workrequ->use_sg) {
650 sgpnt = (struct scatterlist *) workrequ->request_buffer;
651 sg_count = pci_map_sg(dev->pdev, sgpnt, workrequ->use_sg, scsi_to_pci_dma_dir(workrequ->sc_data_direction));
652 for (i = 0; i < workrequ->use_sg; i++) {
653 if (sgpnt[i].length == 0 || workrequ->use_sg > ATP870U_SCATTER) {
654 panic("Foooooooood fight!");
656 l += sgpnt[i].length;
658 } else if(workrequ->request_bufflen && workrequ->sc_data_direction != PCI_DMA_NONE) {
659 workrequ->SCp.dma_handle = pci_map_single(dev->pdev, workrequ->request_buffer, workrequ->request_bufflen, scsi_to_pci_dma_dir(workrequ->sc_data_direction));
660 l = workrequ->request_bufflen;
664 * Write transfer size
666 outb((unsigned char) (((unsigned char *) (&l))[2]), tmport++);
667 outb((unsigned char) (((unsigned char *) (&l))[1]), tmport++);
668 outb((unsigned char) (((unsigned char *) (&l))[0]), tmport++);
670 dev->id[j].last_lenu = l;
671 dev->id[j].tran_lenu = 0;
675 if ((j & 0x08) != 0) {
676 j = (j & 0x07) | 0x40;
679 * Check transfer direction
681 if (workrequ->sc_data_direction == SCSI_DATA_WRITE) {
682 outb((unsigned char) (j | 0x20), tmport++);
686 outb((unsigned char) (inb(tmport) | 0x80), tmport);
688 tmport = workportu + 0x1c;
689 dev->id[target_id].dirctu = 0;
691 if (inb(tmport) == 0) {
692 tmport = workportu + 0x18;
695 dev->last_cmd |= 0x40;
700 tmpcip = dev->pciport;
701 prd = dev->id[target_id].prd_tableu;
702 dev->id[target_id].prd_posu = prd;
705 * Now write the request list. Either as scatter/gather or as
709 if (workrequ->use_sg) {
710 sgpnt = (struct scatterlist *) workrequ->request_buffer;
712 for (j = 0; j < workrequ->use_sg; j++) {
713 bttl = sg_dma_address(&sgpnt[j]);
714 l = sg_dma_len(&sgpnt[j]);
715 while (l > 0x10000) {
716 (((u16 *) (prd))[i + 3]) = 0x0000;
717 (((u16 *) (prd))[i + 2]) = 0x0000;
718 (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl);
723 (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl);
724 (((u16 *) (prd))[i + 2]) = cpu_to_le16(l);
725 (((u16 *) (prd))[i + 3]) = 0;
728 (((u16 *) (prd))[i - 1]) = cpu_to_le16(0x8000);
731 * For a linear request write a chain of blocks
733 bttl = workrequ->SCp.dma_handle;
734 l = workrequ->request_bufflen;
736 while (l > 0x10000) {
737 (((u16 *) (prd))[i + 3]) = 0x0000;
738 (((u16 *) (prd))[i + 2]) = 0x0000;
739 (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl);
744 (((u16 *) (prd))[i + 3]) = cpu_to_le16(0x8000);
745 (((u16 *) (prd))[i + 2]) = cpu_to_le16(l);
746 (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl);
749 dev->id[target_id].prdaddru = dev->id[target_id].prd_phys;
750 outl(dev->id[target_id].prd_phys, tmpcip);
756 if (dev->deviceid != 0x8081) {
757 tmport = workportu + 0x3a;
758 if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) || (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a)) {
759 outb((inb(tmport) & 0xf3) | 0x08, tmport);
761 outb(inb(tmport) & 0xf3, tmport);
764 tmport = workportu - 0x05;
765 if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) || (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a)) {
766 outb((unsigned char) ((inb(tmport) & 0x3f) | 0xc0), tmport);
768 outb((unsigned char) (inb(tmport) & 0x3f), tmport);
771 tmport = workportu + 0x1c;
773 if (workrequ->sc_data_direction == SCSI_DATA_WRITE) {
774 dev->id[target_id].dirctu = 0x20;
775 if (inb(tmport) == 0) {
776 tmport = workportu + 0x18;
780 dev->last_cmd |= 0x40;
785 if (inb(tmport) == 0) {
786 tmport = workportu + 0x18;
790 dev->last_cmd |= 0x40;
795 static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val)
798 unsigned short int i, k;
801 tmport = dev->ioport + 0x1c;
804 for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */
806 j = (unsigned char) (k >> 8);
807 if ((k & 0x8000) != 0) { /* DB7 all release? */
811 *val |= 0x4000; /* assert DB6 */
813 *val &= 0xdfff; /* assert DB5 */
816 for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */
817 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) */
828 if ((inw(tmport) & 0x4000) != 0) { /* DB6 all release? */
836 static void tscam(struct Scsi_Host *host)
840 unsigned char i, j, k;
842 unsigned short int m, assignid_map, val;
843 unsigned char mbuf[33], quintet[2];
844 struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
845 static unsigned char g2q_tab[8] = {
846 0x38, 0x31, 0x32, 0x2b, 0x34, 0x2d, 0x2e, 0x27
849 /* I can't believe we need this before we've even done anything. Remove it
850 * and see if anyone bitches.
851 for (i = 0; i < 0x10; i++) {
856 tmport = dev->ioport + 1;
857 outb(0x08, tmport++);
859 tmport = dev->ioport + 0x11;
862 if ((dev->scam_on & 0x40) == 0) {
868 if (dev->chip_veru < 4) {
873 tmport = dev->ioport + 0x02;
874 outb(0x02, tmport++); /* 2*2=4ms,3EH 2/32*3E=3.9ms */
882 for (i = 0; i < j; i++) {
885 if ((m & assignid_map) != 0) {
888 tmport = dev->ioport + 0x0f;
895 k = (i & 0x07) | 0x40;
900 tmport = dev->ioport + 0x1b;
901 if (dev->chip_veru == 4) {
907 tmport = dev->ioport + 0x18;
911 while ((inb(tmport) & 0x80) == 0x00);
915 if ((k == 0x85) || (k == 0x42)) {
918 tmport = dev->ioport + 0x10;
925 tmport = dev->ioport + 0x02;
927 tmport = dev->ioport + 0x1b;
932 val = 0x0080; /* bsy */
933 tmport = dev->ioport + 0x1c;
935 val |= 0x0040; /* sel */
937 val |= 0x0004; /* msg */
939 inb(0x80); /* 2 deskew delay(45ns*2=90ns) */
940 val &= 0x007f; /* no bsy */
943 val &= 0x00fb; /* after 1ms no msg */
946 if ((inb(tmport) & 0x04) != 0) {
951 for (n = 0; n < 0x30000; n++) {
952 if ((inb(tmport) & 0x80) != 0) { /* bsy ? */
958 for (n = 0; n < 0x30000; n++) {
959 if ((inb(tmport) & 0x81) == 0x0081) {
966 val |= 0x8003; /* io,cd,db7 */
969 val &= 0x00bf; /* no sel */
974 if ((inb(tmport) & 0x80) == 0x00) { /* bsy ? */
977 tmport = dev->ioport + 0x15;
982 while ((inb(tmport) & 0x80) == 0);
987 val &= 0x00ff; /* synchronization */
991 val &= 0x00ff; /* isolation */
998 if ((inw(tmport) & 0x2000) == 0) {
1002 val &= 0x00ff; /* get ID_STRING */
1004 k = fun_scam(dev, &val);
1005 if ((k & 0x03) == 0) {
1010 if ((k & 0x02) != 0) {
1021 TCM_5: /* isolation complete.. */
1023 printk(" \n%x %x %x %s\n ",assignid_map,mbuf[0],mbuf[1],&mbuf[2]); */
1026 if ((j & 0x20) != 0) { /* bit5=1:ID upto 7 */
1029 if ((j & 0x06) == 0) { /* IDvalid? */
1036 if ((m & assignid_map) == 0) {
1043 G2Q5: /* srch from max acceptable ID# */
1044 k = i; /* max acceptable ID# */
1048 if ((m & assignid_map) == 0) {
1055 G2Q_QUIN: /* k=binID#, */
1058 quintet[0] = 0x38; /* 1st dft ID<8 */
1060 quintet[0] = 0x31; /* 1st ID>=8 */
1063 quintet[1] = g2q_tab[k];
1065 val &= 0x00ff; /* AssignID 1stQuintet,AH=001xxxxx */
1066 m = quintet[0] << 8;
1068 fun_scam(dev, &val);
1069 val &= 0x00ff; /* AssignID 2ndQuintet,AH=001xxxxx */
1070 m = quintet[1] << 8;
1072 fun_scam(dev, &val);
1078 void is870(struct Scsi_Host *host, unsigned int wkport)
1080 unsigned int tmport;
1081 unsigned char i, j, k, rmb, n;
1082 unsigned short int m;
1083 static unsigned char mbuf[512];
1084 static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 };
1085 static unsigned char inqd[9] = { 0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6 };
1086 static unsigned char synn[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
1087 static unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0c, 0x0e };
1088 static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 };
1089 static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 };
1090 struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
1093 tmport = wkport + 0x3a;
1094 outb((unsigned char) (inb(tmport) | 0x10), tmport);
1096 for (i = 0; i < 16; i++) {
1097 if ((dev->chip_veru != 4) && (i > 7)) {
1102 if ((m & dev->active_idu) != 0) {
1105 if (i == dev->host_idu) {
1106 printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_idu);
1109 tmport = wkport + 0x1b;
1110 if (dev->chip_veru == 4) {
1115 tmport = wkport + 1;
1116 outb(0x08, tmport++);
1117 outb(0x7f, tmport++);
1118 outb(satn[0], tmport++);
1119 outb(satn[1], tmport++);
1120 outb(satn[2], tmport++);
1121 outb(satn[3], tmport++);
1122 outb(satn[4], tmport++);
1123 outb(satn[5], tmport++);
1127 outb(dev->id[i].devspu, tmport++);
1129 outb(satn[6], tmport++);
1130 outb(satn[7], tmport++);
1132 if ((j & 0x08) != 0) {
1133 j = (j & 0x07) | 0x40;
1137 outb(satn[8], tmport);
1140 while ((inb(tmport) & 0x80) == 0x00);
1142 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1145 while (inb(tmport) != 0x8e);
1146 dev->active_idu |= m;
1148 tmport = wkport + 0x10;
1150 tmport = wkport + 0x04;
1154 tmport = wkport + 0x18;
1157 while ((inb(tmport) & 0x80) == 0x00);
1161 tmport = wkport + 0x10;
1166 tmport = wkport + 3;
1167 outb(inqd[0], tmport++);
1168 outb(inqd[1], tmport++);
1169 outb(inqd[2], tmport++);
1170 outb(inqd[3], tmport++);
1171 outb(inqd[4], tmport++);
1172 outb(inqd[5], tmport);
1176 outb(dev->id[i].devspu, tmport++);
1178 outb(inqd[6], tmport++);
1179 outb(inqd[7], tmport++);
1181 outb(inqd[8], tmport);
1183 while ((inb(tmport) & 0x80) == 0x00);
1185 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1188 while (inb(tmport) != 0x8e);
1189 tmport = wkport + 0x1b;
1190 if (dev->chip_veru == 4) {
1193 tmport = wkport + 0x18;
1199 if ((k & 0x01) != 0) {
1201 mbuf[j++] = inb(tmport);
1205 if ((k & 0x80) == 0) {
1213 tmport = wkport + 0x10;
1222 while ((inb(tmport) & 0x80) == 0x00);
1224 if (inb(tmport) != 0x16) {
1229 printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]);
1230 dev->id[i].devtypeu = mbuf[0];
1233 if (dev->chip_veru != 4) {
1236 if ((mbuf[7] & 0x60) == 0) {
1239 if ((dev->global_map & 0x20) == 0) {
1242 tmport = wkport + 0x1b;
1244 tmport = wkport + 3;
1245 outb(satn[0], tmport++);
1246 outb(satn[1], tmport++);
1247 outb(satn[2], tmport++);
1248 outb(satn[3], tmport++);
1249 outb(satn[4], tmport++);
1250 outb(satn[5], tmport++);
1254 outb(dev->id[i].devspu, tmport++);
1256 outb(satn[6], tmport++);
1257 outb(satn[7], tmport++);
1259 outb(satn[8], tmport);
1262 while ((inb(tmport) & 0x80) == 0x00);
1264 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1267 while (inb(tmport) != 0x8e);
1270 tmport = wkport + 0x14;
1276 while ((inb(tmport) & 0x80) == 0) {
1277 if ((inb(tmport) & 0x01) != 0) {
1279 outb(wide[j++], tmport);
1284 while ((inb(tmport) & 0x80) == 0x00);
1285 j = inb(tmport) & 0x0f;
1297 tmport = wkport + 0x18;
1300 while ((inb(tmport) & 0x80) == 0) {
1301 if ((inb(tmport) & 0x01) != 0) {
1308 j = inb(tmport) & 0x0f;
1320 tmport = wkport + 0x14;
1328 if ((j & 0x01) != 0) {
1330 mbuf[k++] = inb(tmport);
1334 if ((j & 0x80) == 0x00) {
1338 j = inb(tmport) & 0x0f;
1350 tmport = wkport + 0x10;
1352 tmport = wkport + 0x14;
1357 while ((inb(tmport) & 0x80) == 0x00);
1366 if (mbuf[0] != 0x01) {
1369 if (mbuf[1] != 0x02) {
1372 if (mbuf[2] != 0x03) {
1375 if (mbuf[3] != 0x01) {
1382 if ((dev->id[i].devtypeu == 0x00) || (dev->id[i].devtypeu == 0x07) || ((dev->id[i].devtypeu == 0x05) && ((n & 0x10) != 0))) {
1387 tmport = wkport + 0x1b;
1389 if ((m & dev->wide_idu) != 0) {
1393 tmport = wkport + 3;
1394 outb(satn[0], tmport++);
1395 outb(satn[1], tmport++);
1396 outb(satn[2], tmport++);
1397 outb(satn[3], tmport++);
1398 outb(satn[4], tmport++);
1399 outb(satn[5], tmport++);
1403 outb(dev->id[i].devspu, tmport++);
1405 outb(satn[6], tmport++);
1406 outb(satn[7], tmport++);
1408 outb(satn[8], tmport);
1411 while ((inb(tmport) & 0x80) == 0x00);
1413 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1416 while (inb(tmport) != 0x8e);
1419 tmport = wkport + 0x14;
1425 while ((inb(tmport) & 0x80) == 0) {
1426 if ((inb(tmport) & 0x01) != 0) {
1428 if ((m & dev->wide_idu) != 0) {
1429 outb(synw[j++], tmport);
1431 if ((m & dev->ultra_map) != 0) {
1432 outb(synu[j++], tmport);
1434 outb(synn[j++], tmport);
1441 while ((inb(tmport) & 0x80) == 0x00);
1442 j = inb(tmport) & 0x0f;
1454 tmport = wkport + 0x18;
1457 while ((inb(tmport) & 0x80) == 0x00) {
1458 if ((inb(tmport) & 0x01) != 0x00) {
1481 tmport = wkport + 0x14;
1489 if ((j & 0x01) != 0x00) {
1491 mbuf[k++] = inb(tmport);
1495 if ((j & 0x80) == 0x00) {
1499 while ((inb(tmport) & 0x80) == 0x00);
1516 tmport = wkport + 0x10;
1519 tmport = wkport + 0x14;
1524 while ((inb(tmport) & 0x80) == 0x00);
1530 if (mbuf[0] != 0x01) {
1533 if (mbuf[1] != 0x03) {
1536 if (mbuf[4] == 0x00) {
1539 if (mbuf[3] > 0x64) {
1542 if (mbuf[4] > 0x0c) {
1545 dev->id[i].devspu = mbuf[4];
1546 if ((mbuf[3] < 0x0d) && (rmb == 0)) {
1550 if (mbuf[3] < 0x1a) {
1554 if (mbuf[3] < 0x33) {
1558 if (mbuf[3] < 0x4c) {
1564 dev->id[i].devspu = (dev->id[i].devspu & 0x0f) | j;
1566 tmport = wkport + 0x3a;
1567 outb((unsigned char) (inb(tmport) & 0xef), tmport);
1570 static void is880(struct Scsi_Host *host, unsigned int wkport)
1572 unsigned int tmport;
1573 unsigned char i, j, k, rmb, n, lvdmode;
1574 unsigned short int m;
1575 static unsigned char mbuf[512];
1576 static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 };
1577 static unsigned char inqd[9] = { 0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6 };
1578 static unsigned char synn[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
1579 unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e };
1580 static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
1581 unsigned char synuw[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e };
1582 static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 };
1583 static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 };
1584 struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
1587 lvdmode = inb(wkport + 0x3f) & 0x40;
1589 for (i = 0; i < 16; i++) {
1592 if ((m & dev->active_idu) != 0) {
1595 if (i == dev->host_idu) {
1596 printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_idu);
1599 tmport = wkport + 0x5b;
1601 tmport = wkport + 0x41;
1602 outb(0x08, tmport++);
1603 outb(0x7f, tmport++);
1604 outb(satn[0], tmport++);
1605 outb(satn[1], tmport++);
1606 outb(satn[2], tmport++);
1607 outb(satn[3], tmport++);
1608 outb(satn[4], tmport++);
1609 outb(satn[5], tmport++);
1613 outb(dev->id[i].devspu, tmport++);
1615 outb(satn[6], tmport++);
1616 outb(satn[7], tmport++);
1618 if ((j & 0x08) != 0) {
1619 j = (j & 0x07) | 0x40;
1623 outb(satn[8], tmport);
1626 while ((inb(tmport) & 0x80) == 0x00);
1628 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1631 while (inb(tmport) != 0x8e);
1632 dev->active_idu |= m;
1634 tmport = wkport + 0x50;
1636 tmport = wkport + 0x54;
1640 tmport = wkport + 0x58;
1643 while ((inb(tmport) & 0x80) == 0x00);
1647 tmport = wkport + 0x50;
1652 tmport = wkport + 0x43;
1653 outb(inqd[0], tmport++);
1654 outb(inqd[1], tmport++);
1655 outb(inqd[2], tmport++);
1656 outb(inqd[3], tmport++);
1657 outb(inqd[4], tmport++);
1658 outb(inqd[5], tmport);
1662 outb(dev->id[i].devspu, tmport++);
1664 outb(inqd[6], tmport++);
1665 outb(inqd[7], tmport++);
1667 outb(inqd[8], tmport);
1669 while ((inb(tmport) & 0x80) == 0x00);
1671 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1674 while (inb(tmport) != 0x8e);
1675 tmport = wkport + 0x5b;
1677 tmport = wkport + 0x58;
1683 if ((k & 0x01) != 0) {
1685 mbuf[j++] = inb(tmport);
1689 if ((k & 0x80) == 0) {
1697 tmport = wkport + 0x50;
1706 while ((inb(tmport) & 0x80) == 0x00);
1708 if (inb(tmport) != 0x16) {
1713 printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]);
1714 dev->id[i].devtypeu = mbuf[0];
1717 if ((mbuf[7] & 0x60) == 0) {
1720 if ((i < 8) && ((dev->global_map & 0x20) == 0)) {
1726 if (dev->sp[i] != 0x04) // force u2
1731 tmport = wkport + 0x5b;
1733 tmport = wkport + 0x43;
1734 outb(satn[0], tmport++);
1735 outb(satn[1], tmport++);
1736 outb(satn[2], tmport++);
1737 outb(satn[3], tmport++);
1738 outb(satn[4], tmport++);
1739 outb(satn[5], tmport++);
1743 outb(dev->id[i].devspu, tmport++);
1745 outb(satn[6], tmport++);
1746 outb(satn[7], tmport++);
1748 outb(satn[8], tmport);
1751 while ((inb(tmport) & 0x80) == 0x00);
1753 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1756 while (inb(tmport) != 0x8e);
1759 tmport = wkport + 0x54;
1765 while ((inb(tmport) & 0x80) == 0) {
1766 if ((inb(tmport) & 0x01) != 0) {
1768 outb(u3[j++], tmport);
1773 while ((inb(tmport) & 0x80) == 0x00);
1774 j = inb(tmport) & 0x0f;
1786 tmport = wkport + 0x58;
1789 while ((inb(tmport) & 0x80) == 0) {
1790 if ((inb(tmport) & 0x01) != 0) {
1797 j = inb(tmport) & 0x0f;
1809 tmport = wkport + 0x54;
1817 if ((j & 0x01) != 0) {
1819 mbuf[k++] = inb(tmport);
1823 if ((j & 0x80) == 0x00) {
1827 j = inb(tmport) & 0x0f;
1839 tmport = wkport + 0x50;
1841 tmport = wkport + 0x54;
1846 while ((inb(tmport) & 0x80) == 0x00);
1855 if (mbuf[0] != 0x01) {
1858 if (mbuf[1] != 0x06) {
1861 if (mbuf[2] != 0x04) {
1864 if (mbuf[3] == 0x09) {
1868 dev->id[i].devspu = 0xce;
1872 tmport = wkport + 0x5b;
1874 tmport = wkport + 0x43;
1875 outb(satn[0], tmport++);
1876 outb(satn[1], tmport++);
1877 outb(satn[2], tmport++);
1878 outb(satn[3], tmport++);
1879 outb(satn[4], tmport++);
1880 outb(satn[5], tmport++);
1884 outb(dev->id[i].devspu, tmport++);
1886 outb(satn[6], tmport++);
1887 outb(satn[7], tmport++);
1889 outb(satn[8], tmport);
1892 while ((inb(tmport) & 0x80) == 0x00);
1894 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1897 while (inb(tmport) != 0x8e);
1900 tmport = wkport + 0x54;
1906 while ((inb(tmport) & 0x80) == 0) {
1907 if ((inb(tmport) & 0x01) != 0) {
1909 outb(wide[j++], tmport);
1914 while ((inb(tmport) & 0x80) == 0x00);
1915 j = inb(tmport) & 0x0f;
1927 tmport = wkport + 0x58;
1930 while ((inb(tmport) & 0x80) == 0) {
1931 if ((inb(tmport) & 0x01) != 0) {
1938 j = inb(tmport) & 0x0f;
1950 tmport = wkport + 0x54;
1958 if ((j & 0x01) != 0) {
1960 mbuf[k++] = inb(tmport);
1964 if ((j & 0x80) == 0x00) {
1968 j = inb(tmport) & 0x0f;
1980 tmport = wkport + 0x50;
1982 tmport = wkport + 0x54;
1987 while ((inb(tmport) & 0x80) == 0x00);
1996 if (mbuf[0] != 0x01) {
1999 if (mbuf[1] != 0x02) {
2002 if (mbuf[2] != 0x03) {
2005 if (mbuf[3] != 0x01) {
2012 if ((dev->id[i].devtypeu == 0x00) || (dev->id[i].devtypeu == 0x07) || ((dev->id[i].devtypeu == 0x05) && ((n & 0x10) != 0))) {
2015 if ((dev->async & m) != 0) {
2021 if (dev->sp[i] == 0x02) {
2025 if (dev->sp[i] >= 0x03) {
2030 tmport = wkport + 0x5b;
2032 if ((m & dev->wide_idu) != 0) {
2036 tmport = wkport + 0x43;
2037 outb(satn[0], tmport++);
2038 outb(satn[1], tmport++);
2039 outb(satn[2], tmport++);
2040 outb(satn[3], tmport++);
2041 outb(satn[4], tmport++);
2042 outb(satn[5], tmport++);
2046 outb(dev->id[i].devspu, tmport++);
2048 outb(satn[6], tmport++);
2049 outb(satn[7], tmport++);
2051 outb(satn[8], tmport);
2054 while ((inb(tmport) & 0x80) == 0x00);
2056 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
2059 while (inb(tmport) != 0x8e);
2062 tmport = wkport + 0x54;
2068 while ((inb(tmport) & 0x80) == 0) {
2069 if ((inb(tmport) & 0x01) != 0) {
2071 if ((m & dev->wide_idu) != 0) {
2072 if ((m & dev->ultra_map) != 0) {
2073 outb(synuw[j++], tmport);
2075 outb(synw[j++], tmport);
2078 if ((m & dev->ultra_map) != 0) {
2079 outb(synu[j++], tmport);
2081 outb(synn[j++], tmport);
2088 while ((inb(tmport) & 0x80) == 0x00);
2089 j = inb(tmport) & 0x0f;
2101 tmport = wkport + 0x58;
2104 while ((inb(tmport) & 0x80) == 0x00) {
2105 if ((inb(tmport) & 0x01) != 0x00) {
2128 tmport = wkport + 0x54;
2136 if ((j & 0x01) != 0x00) {
2138 mbuf[k++] = inb(tmport);
2142 if ((j & 0x80) == 0x00) {
2146 while ((inb(tmport) & 0x80) == 0x00);
2163 tmport = wkport + 0x50;
2166 tmport = wkport + 0x54;
2171 while ((inb(tmport) & 0x80) == 0x00);
2177 if (mbuf[0] != 0x01) {
2180 if (mbuf[1] != 0x03) {
2183 if (mbuf[4] == 0x00) {
2186 if (mbuf[3] > 0x64) {
2189 if (mbuf[4] > 0x0e) {
2192 dev->id[i].devspu = mbuf[4];
2193 if (mbuf[3] < 0x0c) {
2197 if ((mbuf[3] < 0x0d) && (rmb == 0)) {
2201 if (mbuf[3] < 0x1a) {
2205 if (mbuf[3] < 0x33) {
2209 if (mbuf[3] < 0x4c) {
2215 dev->id[i].devspu = (dev->id[i].devspu & 0x0f) | j;
2219 static void atp870u_free_tables(struct Scsi_Host *host)
2221 struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata;
2224 for (k = 0; k < 16; k++) {
2225 if (!atp_dev->id[k].prd_tableu)
2227 pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[k].prd_tableu,
2228 atp_dev->id[k].prd_phys);
2229 atp_dev->id[k].prd_tableu = NULL;
2233 static int atp870u_init_tables(struct Scsi_Host *host)
2235 struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
2238 for (i = k = 0; k < 16; k++) {
2239 dev->id[k].prd_tableu = pci_alloc_consistent(dev->pdev, 1024, &dev->id[k].prd_phys);
2240 if (!dev->id[k].prd_tableu) {
2241 atp870u_free_tables(host);
2244 dev->id[k].devspu = 0x20;
2245 dev->id[k].devtypeu = 0;
2246 dev->id[k].curr_req = NULL;
2248 dev->active_idu = 0;
2250 dev->host_idu = 0x07;
2254 dev->last_cmd = 0xff;
2257 for (k = 0; k < qcnt; k++) {
2258 dev->querequ[k] = 0;
2260 for (k = 0; k < 16; k++) {
2261 dev->id[k].curr_req = 0;
2267 /* return non-zero on detection */
2268 static int atp870u_probe(struct pci_dev *dev, const struct pci_device_id *ent)
2271 unsigned long flags;
2272 unsigned int base_io, error, tmport;
2273 unsigned char host_id;
2275 struct Scsi_Host *shpnt;
2276 struct atp_unit atp_dev, *p;
2279 if (pci_enable_device(dev))
2282 if (pci_set_dma_mask(dev, 0xFFFFFFFFUL)) {
2283 printk(KERN_ERR "atp870u: 32bit DMA mask required but not available.\n");
2287 memset(&atp_dev, 0, sizeof atp_dev);
2290 * It's probably easier to weed out some revisions like
2291 * this than via the PCI device table
2293 if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) {
2294 error = pci_read_config_byte(dev, PCI_CLASS_REVISION, &atp_dev.chip_veru);
2295 if (atp_dev.chip_veru < 2)
2299 switch (ent->device) {
2301 case PCI_DEVICE_ID_ARTOP_AEC7612UW:
2302 case PCI_DEVICE_ID_ARTOP_AEC7612SUW:
2303 atp_dev.chip_veru = 0x04;
2308 base_io = pci_resource_start(dev, 0);
2310 if (ent->device != 0x8081) {
2311 error = pci_read_config_byte(dev, 0x49, &host_id);
2312 base_io &= 0xfffffff8;
2314 printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-3 Host Adapter: %d "
2315 "IO:%x, IRQ:%d.\n", count, base_io, dev->irq);
2317 atp_dev.unit = count;
2318 atp_dev.ioport = base_io;
2319 atp_dev.pciport = base_io + 0x20;
2320 atp_dev.deviceid = ent->device;
2322 atp_dev.host_idu = host_id;
2323 tmport = base_io + 0x22;
2324 atp_dev.scam_on = inb(tmport);
2326 atp_dev.global_map = inb(tmport++);
2327 atp_dev.ultra_map = inw(tmport);
2329 if (atp_dev.ultra_map == 0) {
2330 atp_dev.scam_on = 0x00;
2331 atp_dev.global_map = 0x20;
2332 atp_dev.ultra_map = 0xffff;
2335 shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
2339 p = (struct atp_unit *)&shpnt->hostdata;
2341 atp_dev.host = shpnt;
2343 pci_set_drvdata(dev, p);
2344 memcpy(p, &atp_dev, sizeof atp_dev);
2345 if (atp870u_init_tables(shpnt) < 0)
2348 if (request_irq(dev->irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", shpnt)) {
2349 printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", dev->irq);
2353 spin_lock_irqsave(shpnt->host_lock, flags);
2354 if (atp_dev.chip_veru > 0x07) { /* check if atp876 chip then enable terminator */
2355 tmport = base_io + 0x3e;
2359 tmport = base_io + 0x3a;
2360 k = (inb(tmport) & 0xf3) | 0x10;
2362 outb((k & 0xdf), tmport);
2367 outb((host_id | 0x08), tmport);
2371 while ((inb(tmport) & 0x80) == 0)
2376 tmport = base_io + 1;
2379 tmport = base_io + 0x11;
2383 is870(shpnt, base_io);
2384 tmport = base_io + 0x3a;
2385 outb((inb(tmport) & 0xef), tmport);
2387 outb((inb(tmport) | 0x20), tmport);
2389 base_io &= 0xfffffff8;
2390 host_id = inb(base_io + 0x39);
2393 printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d"
2394 " IO:%x, IRQ:%d.\n", count, base_io, dev->irq);
2395 atp_dev.ioport = base_io + 0x40;
2396 atp_dev.pciport = base_io + 0x28;
2397 atp_dev.deviceid = ent->device;
2398 atp_dev.host_idu = host_id;
2400 tmport = base_io + 0x22;
2401 atp_dev.scam_on = inb(tmport);
2403 atp_dev.global_map = inb(tmport);
2405 atp_dev.ultra_map = inw(tmport);
2413 outw(n, base_io + 0x34);
2415 if (inb(base_io + 0x30) == 0xff)
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);
2434 outw(n, base_io + 0x34);
2436 atp_dev.sp[m++] = inb(base_io + 0x30);
2437 atp_dev.sp[m++] = inb(base_io + 0x31);
2438 atp_dev.sp[m++] = inb(base_io + 0x32);
2439 atp_dev.sp[m++] = inb(base_io + 0x33);
2443 outw(0, base_io + 0x34);
2444 atp_dev.ultra_map = 0;
2446 for (k = 0; k < 16; k++) {
2449 if (atp_dev.sp[k] > 1) {
2450 atp_dev.ultra_map |= n;
2452 if (atp_dev.sp[k] == 0)
2456 atp_dev.async = ~(atp_dev.async);
2457 outb(atp_dev.global_map, base_io + 0x35);
2459 shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
2463 p = (struct atp_unit *)&shpnt->hostdata;
2465 atp_dev.host = shpnt;
2467 pci_set_drvdata(dev, p);
2468 memcpy(p, &atp_dev, sizeof atp_dev);
2469 if (atp870u_init_tables(shpnt) < 0) {
2470 printk(KERN_ERR "Unable to allocate tables for Acard controller\n");
2474 if (request_irq(dev->irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", shpnt)) {
2475 printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", dev->irq);
2479 spin_lock_irqsave(shpnt->host_lock, flags);
2480 tmport = base_io + 0x38;
2481 k = inb(tmport) & 0x80;
2488 tmport = base_io + 0x5b;
2492 tmport = base_io + 0x40;
2493 outb((host_id | 0x08), tmport);
2497 while ((inb(tmport) & 0x80) == 0)
2501 tmport = base_io + 0x41;
2504 tmport = base_io + 0x51;
2508 is880(shpnt, base_io);
2509 tmport = base_io + 0x38;
2513 if (p->chip_veru == 4)
2516 shpnt->this_id = host_id;
2517 shpnt->unique_id = base_io;
2518 shpnt->io_port = base_io;
2519 if (ent->device == 0x8081) {
2520 shpnt->n_io_port = 0x60; /* Number of bytes of I/O space used */
2522 shpnt->n_io_port = 0x40; /* Number of bytes of I/O space used */
2524 shpnt->irq = dev->irq;
2525 spin_unlock_irqrestore(shpnt->host_lock, flags);
2526 if (ent->device == 0x8081) {
2527 if (!request_region(base_io, 0x60, "atp870u"))
2528 goto request_io_fail;
2530 if (!request_region(base_io, 0x40, "atp870u"))
2531 goto request_io_fail;
2535 if (scsi_add_host(shpnt, &dev->dev))
2537 scsi_scan_host(shpnt);
2541 if (ent->device == 0x8081)
2542 release_region(base_io, 0x60);
2544 release_region(base_io, 0x40);
2546 free_irq(dev->irq, shpnt);
2548 atp870u_free_tables(shpnt);
2550 scsi_host_put(shpnt);
2554 /* The abort command does not leave the device in a clean state where
2555 it is available to be used again. Until this gets worked out, we will
2556 leave it commented out. */
2558 int atp870u_abort(Scsi_Cmnd * SCpnt)
2561 Scsi_Cmnd *workrequ;
2562 unsigned int tmport;
2563 struct atp_unit *dev = (struct atp_unit *)&SCpnt->device->host->hostdata;
2565 printk(KERN_DEBUG "working=%x last_cmd=%x ", dev->working, dev->last_cmd);
2566 printk(" quhdu=%x quendu=%x ", dev->quhdu, dev->quendu);
2567 tmport = dev->ioport;
2568 for (j = 0; j < 0x17; j++) {
2569 printk(" r%2x=%2x", j, inb(tmport++));
2572 printk(" r1c=%2x", inb(tmport));
2574 printk(" r1f=%2x in_snd=%2x ", inb(tmport), dev->in_snd);
2575 tmport = dev->pciport;
2576 printk(" r20=%2x", inb(tmport));
2578 printk(" r22=%2x", inb(tmport));
2579 tmport = dev->ioport + 0x3a;
2580 printk(" r3a=%2x \n", inb(tmport));
2581 tmport = dev->ioport + 0x3b;
2582 printk(" r3b=%2x \n", inb(tmport));
2583 for (j = 0; j < 16; j++) {
2584 if (dev->id[j].curr_req != NULL) {
2585 workrequ = dev->id[j].curr_req;
2586 printk("\n que cdb= ");
2587 for (k = 0; k < workrequ->cmd_len; k++) {
2588 printk(" %2x ", workrequ->cmnd[k]);
2590 printk(" last_lenu= %lx ", dev->id[j].last_lenu);
2593 /* Sort of - the thing handles itself */
2597 const char *atp870u_info(struct Scsi_Host *notused)
2599 static char buffer[128];
2601 strcpy(buffer, "ACARD AEC-6710/6712/67160 PCI Ultra/W/LVD SCSI-3 Adapter Driver V2.6+ac ");
2606 int atp870u_set_info(char *buffer, int length, struct Scsi_Host *HBAptr)
2608 return -ENOSYS; /* Currently this is a no-op */
2611 #define BLS buffer + len + size
2612 int atp870u_proc_info(struct Scsi_Host *HBAptr, char *buffer, char **start, off_t offset, int length, int inout)
2614 static u8 buff[512];
2620 if (inout == TRUE) { /* Has data been written to the file? */
2621 return (atp870u_set_info(buffer, length, HBAptr));
2624 memset(buff, 0, sizeof(buff));
2626 size += sprintf(BLS, "ACARD AEC-671X Driver Version: 2.6+ac\n");
2631 size += sprintf(BLS, "\n");
2632 size += sprintf(BLS, "Adapter Configuration:\n");
2633 size += sprintf(BLS, " Base IO: %#.4lx\n", HBAptr->io_port);
2634 size += sprintf(BLS, " IRQ: %d\n", HBAptr->irq);
2638 *start = buffer + (offset - begin); /* Start of wanted data */
2639 len -= (offset - begin); /* Start slop */
2641 len = length; /* Ending slop */
2646 static int atp870u_biosparam(struct scsi_device *sdev,
2647 struct block_device *dev, sector_t capacity, int *ip)
2649 int heads, sectors, cylinders;
2653 cylinders = (unsigned long)capacity / (heads * sectors);
2655 if (cylinders > 1024) {
2658 cylinders = (unsigned long)capacity / (heads * sectors);
2667 static void atp870u_remove(struct pci_dev *pdev)
2669 struct atp_unit *atp_dev = pci_get_drvdata(pdev);
2670 struct Scsi_Host *pshost = atp_dev->host;
2672 scsi_remove_host(pshost);
2673 free_irq(pshost->irq, pshost);
2674 release_region(pshost->io_port, pshost->n_io_port);
2675 atp870u_free_tables(pshost);
2676 scsi_host_put(pshost);
2677 pci_set_drvdata(pdev, NULL);
2680 MODULE_LICENSE("GPL");
2682 static Scsi_Host_Template atp870u_template = {
2683 .module = THIS_MODULE,
2685 .proc_name = "atp870u",
2686 .proc_info = atp870u_proc_info,
2687 .info = atp870u_info,
2688 .queuecommand = atp870u_queuecommand,
2689 .eh_abort_handler = atp870u_abort,
2690 .bios_param = atp870u_biosparam,
2693 .sg_tablesize = ATP870U_SCATTER,
2694 .cmd_per_lun = ATP870U_CMDLUN,
2695 .use_clustering = ENABLE_CLUSTERING,
2698 static struct pci_device_id atp870u_id_table[] = {
2699 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, 0x8081) },
2700 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7610) },
2701 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612UW) },
2702 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612U) },
2703 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612S) },
2704 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612D) },
2705 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612SUW) },
2706 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_8060) },
2710 MODULE_DEVICE_TABLE(pci, atp870u_id_table);
2712 static struct pci_driver atp870u_driver = {
2713 .id_table = atp870u_id_table,
2715 .probe = atp870u_probe,
2716 .remove = __devexit_p(atp870u_remove),
2719 static int __init atp870u_init(void)
2721 pci_register_driver(&atp870u_driver);
2725 static void __exit atp870u_exit(void)
2727 pci_unregister_driver(&atp870u_driver);
2730 module_init(atp870u_init);
2731 module_exit(atp870u_exit);