2 * Copyright (C) 1997 Wu Ching Chen
3 * 2.1.x update (C) 1998 Krzysztof G. Baranowski
4 * 2.5.x update (C) 2002 Red Hat <alan@redhat.com>
5 * 2.6.x update (C) 2004 Red Hat <alan@redhat.com>
7 * Marcelo Tosatti <marcelo@conectiva.com.br> : SMP fixes
9 * Wu Ching Chen : NULL pointer fixes 2000/06/02
11 * enable 32 bit fifo transfer
12 * support cdrom & remove device run ultra speed
13 * fix disconnect bug 2000/12/21
14 * support atp880 chip lvd u160 2001/05/15
15 * fix prd table bug 2001/09/12 (7.1)
18 #include <linux/module.h>
19 #include <linux/init.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 <asm/system.h>
33 #include <scsi/scsi.h>
34 #include <scsi/scsi_cmnd.h>
35 #include <scsi/scsi_device.h>
36 #include <scsi/scsi_host.h>
40 static struct scsi_host_template atp870u_template;
41 static void send_s870(struct Scsi_Host *host);
44 static irqreturn_t atp870u_intr_handle(int irq, void *dev_id,
48 unsigned short int tmpcip, id;
49 unsigned char i, j, target_id, lun;
51 struct scsi_cmnd *workrequ;
52 unsigned int workportu, tmport;
53 unsigned long adrcntu, k;
55 struct Scsi_Host *host = dev_id;
56 struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
59 workportu = dev->ioport;
62 if (dev->working != 0) {
65 if ((j & 0x80) == 0) {
70 tmpcip = dev->pciport;
71 if ((inb(tmpcip) & 0x08) != 0) {
73 for (k = 0; k < 1000; k++) {
74 if ((inb(tmpcip) & 0x08) == 0) {
77 if ((inb(tmpcip) & 0x01) == 0) {
83 tmpcip = dev->pciport;
90 target_id = inb(tmport);
94 * Remap wide devices onto id numbers
97 if ((target_id & 0x40) != 0) {
98 target_id = (target_id & 0x07) | 0x08;
103 if ((j & 0x40) != 0) {
104 if (dev->last_cmd == 0xff) {
105 dev->last_cmd = target_id;
107 dev->last_cmd |= 0x40;
111 if ((dev->last_cmd & 0xf0) != 0x40) {
112 dev->last_cmd = 0xff;
117 if (dev->wide_idu != 0) {
118 tmport = workportu + 0x1b;
120 while ((inb(tmport) & 0x01) != 0x01) {
125 * Issue more commands
127 spin_lock_irqsave(dev->host->host_lock, flags);
128 if (((dev->quhdu != dev->quendu) || (dev->last_cmd != 0xff)) && (dev->in_snd == 0)) {
131 spin_unlock_irqrestore(dev->host->host_lock, flags);
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
348 if (workrequ->use_sg) {
349 pci_unmap_sg(dev->pdev,
350 (struct scatterlist *)workrequ->buffer,
352 workrequ->sc_data_direction);
353 } else if (workrequ->request_bufflen &&
354 workrequ->sc_data_direction != DMA_NONE) {
355 pci_unmap_single(dev->pdev,
356 workrequ->SCp.dma_handle,
357 workrequ->request_bufflen,
358 workrequ->sc_data_direction);
360 spin_lock_irqsave(dev->host->host_lock, flags);
361 (*workrequ->scsi_done) (workrequ);
364 * Clear it off the queue
366 dev->id[target_id].curr_req = NULL;
368 spin_unlock_irqrestore(dev->host->host_lock, flags);
372 if (dev->wide_idu != 0) {
373 tmport = workportu + 0x1b;
375 while ((inb(tmport) & 0x01) != 0x01) {
380 * If there is stuff to send and nothing going then send it
382 spin_lock_irqsave(dev->host->host_lock, flags);
383 if (((dev->last_cmd != 0xff) || (dev->quhdu != dev->quendu)) && (dev->in_snd == 0)) {
386 spin_unlock_irqrestore(dev->host->host_lock, flags);
390 if ((dev->last_cmd & 0xf0) != 0x40) {
391 dev->last_cmd = 0xff;
399 outl(dev->id[target_id].prdaddru, tmpcip);
404 tmport = workportu + 0x10;
406 dev->id[target_id].dirctu = 0x00;
415 outl(dev->id[target_id].prdaddru, tmpcip);
420 tmport = workportu + 0x10;
423 outb((unsigned char) (inb(tmport) | 0x20), tmport);
424 dev->id[target_id].dirctu = 0x20;
437 dev->id[target_id].dirctu = 0x00;
439 outb(0x00, tmport++);
440 outb(0x00, tmport++);
441 outb(0x00, tmport++);
447 // tmport = workportu + 0x17;
457 * atp870u_queuecommand - Queue SCSI command
458 * @req_p: request block
459 * @done: completion function
461 * Queue a command to the ATP queue. Called with the host lock held.
464 static int atp870u_queuecommand(struct scsi_cmnd *req_p,
465 void (*done) (struct scsi_cmnd *))
467 unsigned short int m;
469 struct Scsi_Host *host;
470 struct atp_unit *dev;
472 if (req_p->device->channel != 0) {
473 req_p->result = 0x00040000;
478 host = req_p->device->host;
479 dev = (struct atp_unit *)&host->hostdata;
482 m = m << req_p->device->id;
485 * Fake a timeout for missing targets
488 if ((m & dev->active_idu) == 0) {
489 req_p->result = 0x00040000;
494 req_p->scsi_done = done;
496 printk(KERN_WARNING "atp870u_queuecommand: done can't be NULL\n");
506 if (dev->quendu >= qcnt) {
512 if (dev->quhdu == dev->quendu) {
513 if (dev->quendu == 0) {
517 req_p->result = 0x00020000;
521 dev->querequ[dev->quendu] = req_p;
522 tmport = dev->ioport + 0x1c;
523 if ((inb(tmport) == 0) && (dev->in_int == 0) && (dev->in_snd == 0)) {
530 * send_s870 - send a command to the controller
533 * On entry there is work queued to be done. We move some of that work to the
536 * Caller holds the host lock.
539 static void send_s870(struct Scsi_Host *host)
542 struct scsi_cmnd *workrequ;
544 unsigned char j, target_id;
546 unsigned short int tmpcip, w;
549 unsigned int workportu;
550 struct scatterlist *sgpnt;
551 struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
554 if (dev->in_snd != 0) {
558 if ((dev->last_cmd != 0xff) && ((dev->last_cmd & 0x40) != 0)) {
559 dev->last_cmd &= 0x0f;
560 workrequ = dev->id[dev->last_cmd].curr_req;
561 if (workrequ != NULL) { /* check NULL pointer */
564 dev->last_cmd = 0xff;
565 if (dev->quhdu == dev->quendu) {
570 if ((dev->last_cmd != 0xff) && (dev->working != 0)) {
577 if (dev->quhdu >= qcnt) {
580 workrequ = dev->querequ[dev->quhdu];
581 if (dev->id[workrequ->device->id].curr_req == 0) {
582 dev->id[workrequ->device->id].curr_req = workrequ;
583 dev->last_cmd = workrequ->device->id;
591 workportu = dev->ioport;
592 tmport = workportu + 0x1f;
593 if ((inb(tmport) & 0xb0) != 0) {
596 tmport = workportu + 0x1c;
597 if (inb(tmport) == 0) {
601 dev->last_cmd |= 0x40;
605 memcpy(&dev->ata_cdbu[0], &workrequ->cmnd[0], workrequ->cmd_len);
606 if (dev->ata_cdbu[0] == READ_CAPACITY) {
607 if (workrequ->request_bufflen > 8) {
608 workrequ->request_bufflen = 0x08;
611 if (dev->ata_cdbu[0] == 0x00) {
612 workrequ->request_bufflen = 0;
615 tmport = workportu + 0x1b;
617 target_id = workrequ->device->id;
624 if ((w & dev->wide_idu) != 0) {
628 while ((inb(tmport) & 0x01) != j) {
637 outb(workrequ->cmd_len, tmport++);
638 outb(0x2c, tmport++);
639 outb(0xcf, tmport++);
640 for (i = 0; i < workrequ->cmd_len; i++) {
641 outb(dev->ata_cdbu[i], tmport++);
643 tmport = workportu + 0x0f;
644 outb(workrequ->device->lun, tmport);
649 outb(dev->id[target_id].devspu, tmport++);
652 * Figure out the transfer size
654 if (workrequ->use_sg) {
656 sgpnt = (struct scatterlist *) workrequ->request_buffer;
657 sg_count = pci_map_sg(dev->pdev, sgpnt, workrequ->use_sg,
658 workrequ->sc_data_direction);
659 for (i = 0; i < workrequ->use_sg; i++) {
660 if (sgpnt[i].length == 0 || workrequ->use_sg > ATP870U_SCATTER) {
661 panic("Foooooooood fight!");
663 l += sgpnt[i].length;
665 } else if(workrequ->request_bufflen && workrequ->sc_data_direction != PCI_DMA_NONE) {
666 workrequ->SCp.dma_handle = pci_map_single(dev->pdev,
667 workrequ->request_buffer,
668 workrequ->request_bufflen,
669 workrequ->sc_data_direction);
670 l = workrequ->request_bufflen;
674 * Write transfer size
676 outb((unsigned char) (((unsigned char *) (&l))[2]), tmport++);
677 outb((unsigned char) (((unsigned char *) (&l))[1]), tmport++);
678 outb((unsigned char) (((unsigned char *) (&l))[0]), tmport++);
680 dev->id[j].last_lenu = l;
681 dev->id[j].tran_lenu = 0;
685 if ((j & 0x08) != 0) {
686 j = (j & 0x07) | 0x40;
689 * Check transfer direction
691 if (workrequ->sc_data_direction == DMA_TO_DEVICE) {
692 outb((unsigned char) (j | 0x20), tmport++);
696 outb((unsigned char) (inb(tmport) | 0x80), tmport);
698 tmport = workportu + 0x1c;
699 dev->id[target_id].dirctu = 0;
701 if (inb(tmport) == 0) {
702 tmport = workportu + 0x18;
705 dev->last_cmd |= 0x40;
710 tmpcip = dev->pciport;
711 prd = dev->id[target_id].prd_tableu;
712 dev->id[target_id].prd_posu = prd;
715 * Now write the request list. Either as scatter/gather or as
719 if (workrequ->use_sg) {
720 sgpnt = (struct scatterlist *) workrequ->request_buffer;
722 for (j = 0; j < workrequ->use_sg; j++) {
723 bttl = sg_dma_address(&sgpnt[j]);
724 l = sg_dma_len(&sgpnt[j]);
725 while (l > 0x10000) {
726 (((u16 *) (prd))[i + 3]) = 0x0000;
727 (((u16 *) (prd))[i + 2]) = 0x0000;
728 (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl);
733 (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl);
734 (((u16 *) (prd))[i + 2]) = cpu_to_le16(l);
735 (((u16 *) (prd))[i + 3]) = 0;
738 (((u16 *) (prd))[i - 1]) = cpu_to_le16(0x8000);
741 * For a linear request write a chain of blocks
743 bttl = workrequ->SCp.dma_handle;
744 l = workrequ->request_bufflen;
746 while (l > 0x10000) {
747 (((u16 *) (prd))[i + 3]) = 0x0000;
748 (((u16 *) (prd))[i + 2]) = 0x0000;
749 (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl);
754 (((u16 *) (prd))[i + 3]) = cpu_to_le16(0x8000);
755 (((u16 *) (prd))[i + 2]) = cpu_to_le16(l);
756 (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl);
759 dev->id[target_id].prdaddru = dev->id[target_id].prd_phys;
760 outl(dev->id[target_id].prd_phys, tmpcip);
766 if (dev->deviceid != 0x8081) {
767 tmport = workportu + 0x3a;
768 if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) || (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a)) {
769 outb((inb(tmport) & 0xf3) | 0x08, tmport);
771 outb(inb(tmport) & 0xf3, tmport);
774 tmport = workportu - 0x05;
775 if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) || (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a)) {
776 outb((unsigned char) ((inb(tmport) & 0x3f) | 0xc0), tmport);
778 outb((unsigned char) (inb(tmport) & 0x3f), tmport);
781 tmport = workportu + 0x1c;
783 if (workrequ->sc_data_direction == DMA_TO_DEVICE) {
784 dev->id[target_id].dirctu = 0x20;
785 if (inb(tmport) == 0) {
786 tmport = workportu + 0x18;
790 dev->last_cmd |= 0x40;
795 if (inb(tmport) == 0) {
796 tmport = workportu + 0x18;
800 dev->last_cmd |= 0x40;
805 static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val)
808 unsigned short int i, k;
811 tmport = dev->ioport + 0x1c;
814 for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */
816 j = (unsigned char) (k >> 8);
817 if ((k & 0x8000) != 0) { /* DB7 all release? */
821 *val |= 0x4000; /* assert DB6 */
823 *val &= 0xdfff; /* assert DB5 */
826 for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */
827 if ((inw(tmport) & 0x2000) != 0) { /* DB5 all release? */
831 *val |= 0x8000; /* no DB4-0, assert DB7 */
834 *val &= 0xbfff; /* release DB6 */
837 for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */
838 if ((inw(tmport) & 0x4000) != 0) { /* DB6 all release? */
846 static void tscam(struct Scsi_Host *host)
850 unsigned char i, j, k;
852 unsigned short int m, assignid_map, val;
853 unsigned char mbuf[33], quintet[2];
854 struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
855 static unsigned char g2q_tab[8] = {
856 0x38, 0x31, 0x32, 0x2b, 0x34, 0x2d, 0x2e, 0x27
859 /* I can't believe we need this before we've even done anything. Remove it
860 * and see if anyone bitches.
861 for (i = 0; i < 0x10; i++) {
866 tmport = dev->ioport + 1;
867 outb(0x08, tmport++);
869 tmport = dev->ioport + 0x11;
872 if ((dev->scam_on & 0x40) == 0) {
878 if (dev->chip_veru < 4) {
883 tmport = dev->ioport + 0x02;
884 outb(0x02, tmport++); /* 2*2=4ms,3EH 2/32*3E=3.9ms */
892 for (i = 0; i < j; i++) {
895 if ((m & assignid_map) != 0) {
898 tmport = dev->ioport + 0x0f;
905 k = (i & 0x07) | 0x40;
910 tmport = dev->ioport + 0x1b;
911 if (dev->chip_veru == 4) {
917 tmport = dev->ioport + 0x18;
921 while ((inb(tmport) & 0x80) == 0x00);
925 if ((k == 0x85) || (k == 0x42)) {
928 tmport = dev->ioport + 0x10;
935 tmport = dev->ioport + 0x02;
937 tmport = dev->ioport + 0x1b;
942 val = 0x0080; /* bsy */
943 tmport = dev->ioport + 0x1c;
945 val |= 0x0040; /* sel */
947 val |= 0x0004; /* msg */
949 inb(0x80); /* 2 deskew delay(45ns*2=90ns) */
950 val &= 0x007f; /* no bsy */
953 val &= 0x00fb; /* after 1ms no msg */
956 if ((inb(tmport) & 0x04) != 0) {
961 for (n = 0; n < 0x30000; n++) {
962 if ((inb(tmport) & 0x80) != 0) { /* bsy ? */
968 for (n = 0; n < 0x30000; n++) {
969 if ((inb(tmport) & 0x81) == 0x0081) {
976 val |= 0x8003; /* io,cd,db7 */
979 val &= 0x00bf; /* no sel */
984 if ((inb(tmport) & 0x80) == 0x00) { /* bsy ? */
987 tmport = dev->ioport + 0x15;
992 while ((inb(tmport) & 0x80) == 0);
997 val &= 0x00ff; /* synchronization */
1001 val &= 0x00ff; /* isolation */
1003 fun_scam(dev, &val);
1008 if ((inw(tmport) & 0x2000) == 0) {
1012 val &= 0x00ff; /* get ID_STRING */
1014 k = fun_scam(dev, &val);
1015 if ((k & 0x03) == 0) {
1020 if ((k & 0x02) != 0) {
1031 TCM_5: /* isolation complete.. */
1033 printk(" \n%x %x %x %s\n ",assignid_map,mbuf[0],mbuf[1],&mbuf[2]); */
1036 if ((j & 0x20) != 0) { /* bit5=1:ID upto 7 */
1039 if ((j & 0x06) == 0) { /* IDvalid? */
1046 if ((m & assignid_map) == 0) {
1053 G2Q5: /* srch from max acceptable ID# */
1054 k = i; /* max acceptable ID# */
1058 if ((m & assignid_map) == 0) {
1065 G2Q_QUIN: /* k=binID#, */
1068 quintet[0] = 0x38; /* 1st dft ID<8 */
1070 quintet[0] = 0x31; /* 1st ID>=8 */
1073 quintet[1] = g2q_tab[k];
1075 val &= 0x00ff; /* AssignID 1stQuintet,AH=001xxxxx */
1076 m = quintet[0] << 8;
1078 fun_scam(dev, &val);
1079 val &= 0x00ff; /* AssignID 2ndQuintet,AH=001xxxxx */
1080 m = quintet[1] << 8;
1082 fun_scam(dev, &val);
1088 void is870(struct Scsi_Host *host, unsigned int wkport)
1090 unsigned int tmport;
1091 unsigned char i, j, k, rmb, n;
1092 unsigned short int m;
1093 static unsigned char mbuf[512];
1094 static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 };
1095 static unsigned char inqd[9] = { 0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6 };
1096 static unsigned char synn[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
1097 static unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0c, 0x0e };
1098 static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 };
1099 static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 };
1100 struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
1102 tmport = wkport + 0x3a;
1103 outb((unsigned char) (inb(tmport) | 0x10), tmport);
1105 for (i = 0; i < 16; i++) {
1106 if ((dev->chip_veru != 4) && (i > 7)) {
1111 if ((m & dev->active_idu) != 0) {
1114 if (i == dev->host_idu) {
1115 printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_idu);
1118 tmport = wkport + 0x1b;
1119 if (dev->chip_veru == 4) {
1124 tmport = wkport + 1;
1125 outb(0x08, tmport++);
1126 outb(0x7f, tmport++);
1127 outb(satn[0], tmport++);
1128 outb(satn[1], tmport++);
1129 outb(satn[2], tmport++);
1130 outb(satn[3], tmport++);
1131 outb(satn[4], tmport++);
1132 outb(satn[5], tmport++);
1136 outb(dev->id[i].devspu, tmport++);
1138 outb(satn[6], tmport++);
1139 outb(satn[7], tmport++);
1141 if ((j & 0x08) != 0) {
1142 j = (j & 0x07) | 0x40;
1146 outb(satn[8], tmport);
1149 while ((inb(tmport) & 0x80) == 0x00);
1151 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1154 while (inb(tmport) != 0x8e);
1155 dev->active_idu |= m;
1157 tmport = wkport + 0x10;
1159 tmport = wkport + 0x04;
1163 tmport = wkport + 0x18;
1166 while ((inb(tmport) & 0x80) == 0x00);
1170 tmport = wkport + 0x10;
1175 tmport = wkport + 3;
1176 outb(inqd[0], tmport++);
1177 outb(inqd[1], tmport++);
1178 outb(inqd[2], tmport++);
1179 outb(inqd[3], tmport++);
1180 outb(inqd[4], tmport++);
1181 outb(inqd[5], tmport);
1185 outb(dev->id[i].devspu, tmport++);
1187 outb(inqd[6], tmport++);
1188 outb(inqd[7], tmport++);
1190 outb(inqd[8], tmport);
1192 while ((inb(tmport) & 0x80) == 0x00);
1194 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1197 while (inb(tmport) != 0x8e);
1198 tmport = wkport + 0x1b;
1199 if (dev->chip_veru == 4) {
1202 tmport = wkport + 0x18;
1208 if ((k & 0x01) != 0) {
1210 mbuf[j++] = inb(tmport);
1214 if ((k & 0x80) == 0) {
1222 tmport = wkport + 0x10;
1231 while ((inb(tmport) & 0x80) == 0x00);
1233 if (inb(tmport) != 0x16) {
1238 printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]);
1239 dev->id[i].devtypeu = mbuf[0];
1242 if (dev->chip_veru != 4) {
1245 if ((mbuf[7] & 0x60) == 0) {
1248 if ((dev->global_map & 0x20) == 0) {
1251 tmport = wkport + 0x1b;
1253 tmport = wkport + 3;
1254 outb(satn[0], tmport++);
1255 outb(satn[1], tmport++);
1256 outb(satn[2], tmport++);
1257 outb(satn[3], tmport++);
1258 outb(satn[4], tmport++);
1259 outb(satn[5], tmport++);
1263 outb(dev->id[i].devspu, tmport++);
1265 outb(satn[6], tmport++);
1266 outb(satn[7], tmport++);
1268 outb(satn[8], tmport);
1271 while ((inb(tmport) & 0x80) == 0x00);
1273 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1276 while (inb(tmport) != 0x8e);
1279 tmport = wkport + 0x14;
1285 while ((inb(tmport) & 0x80) == 0) {
1286 if ((inb(tmport) & 0x01) != 0) {
1288 outb(wide[j++], tmport);
1293 while ((inb(tmport) & 0x80) == 0x00);
1294 j = inb(tmport) & 0x0f;
1306 tmport = wkport + 0x18;
1309 while ((inb(tmport) & 0x80) == 0) {
1310 if ((inb(tmport) & 0x01) != 0) {
1317 j = inb(tmport) & 0x0f;
1329 tmport = wkport + 0x14;
1337 if ((j & 0x01) != 0) {
1339 mbuf[k++] = inb(tmport);
1343 if ((j & 0x80) == 0x00) {
1347 j = inb(tmport) & 0x0f;
1359 tmport = wkport + 0x10;
1361 tmport = wkport + 0x14;
1366 while ((inb(tmport) & 0x80) == 0x00);
1375 if (mbuf[0] != 0x01) {
1378 if (mbuf[1] != 0x02) {
1381 if (mbuf[2] != 0x03) {
1384 if (mbuf[3] != 0x01) {
1391 if ((dev->id[i].devtypeu == 0x00) || (dev->id[i].devtypeu == 0x07) || ((dev->id[i].devtypeu == 0x05) && ((n & 0x10) != 0))) {
1396 tmport = wkport + 0x1b;
1398 if ((m & dev->wide_idu) != 0) {
1402 tmport = wkport + 3;
1403 outb(satn[0], tmport++);
1404 outb(satn[1], tmport++);
1405 outb(satn[2], tmport++);
1406 outb(satn[3], tmport++);
1407 outb(satn[4], tmport++);
1408 outb(satn[5], tmport++);
1412 outb(dev->id[i].devspu, tmport++);
1414 outb(satn[6], tmport++);
1415 outb(satn[7], tmport++);
1417 outb(satn[8], tmport);
1420 while ((inb(tmport) & 0x80) == 0x00);
1422 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1425 while (inb(tmport) != 0x8e);
1428 tmport = wkport + 0x14;
1434 while ((inb(tmport) & 0x80) == 0) {
1435 if ((inb(tmport) & 0x01) != 0) {
1437 if ((m & dev->wide_idu) != 0) {
1438 outb(synw[j++], tmport);
1440 if ((m & dev->ultra_map) != 0) {
1441 outb(synu[j++], tmport);
1443 outb(synn[j++], tmport);
1450 while ((inb(tmport) & 0x80) == 0x00);
1451 j = inb(tmport) & 0x0f;
1463 tmport = wkport + 0x18;
1466 while ((inb(tmport) & 0x80) == 0x00) {
1467 if ((inb(tmport) & 0x01) != 0x00) {
1490 tmport = wkport + 0x14;
1498 if ((j & 0x01) != 0x00) {
1500 mbuf[k++] = inb(tmport);
1504 if ((j & 0x80) == 0x00) {
1508 while ((inb(tmport) & 0x80) == 0x00);
1525 tmport = wkport + 0x10;
1528 tmport = wkport + 0x14;
1533 while ((inb(tmport) & 0x80) == 0x00);
1539 if (mbuf[0] != 0x01) {
1542 if (mbuf[1] != 0x03) {
1545 if (mbuf[4] == 0x00) {
1548 if (mbuf[3] > 0x64) {
1551 if (mbuf[4] > 0x0c) {
1554 dev->id[i].devspu = mbuf[4];
1555 if ((mbuf[3] < 0x0d) && (rmb == 0)) {
1559 if (mbuf[3] < 0x1a) {
1563 if (mbuf[3] < 0x33) {
1567 if (mbuf[3] < 0x4c) {
1573 dev->id[i].devspu = (dev->id[i].devspu & 0x0f) | j;
1575 tmport = wkport + 0x3a;
1576 outb((unsigned char) (inb(tmport) & 0xef), tmport);
1579 static void is880(struct Scsi_Host *host, unsigned int wkport)
1581 unsigned int tmport;
1582 unsigned char i, j, k, rmb, n, lvdmode;
1583 unsigned short int m;
1584 static unsigned char mbuf[512];
1585 static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 };
1586 static unsigned char inqd[9] = { 0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6 };
1587 static unsigned char synn[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
1588 unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e };
1589 static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
1590 unsigned char synuw[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e };
1591 static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 };
1592 static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 };
1593 struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
1595 lvdmode = inb(wkport + 0x3f) & 0x40;
1597 for (i = 0; i < 16; i++) {
1600 if ((m & dev->active_idu) != 0) {
1603 if (i == dev->host_idu) {
1604 printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_idu);
1607 tmport = wkport + 0x5b;
1609 tmport = wkport + 0x41;
1610 outb(0x08, tmport++);
1611 outb(0x7f, tmport++);
1612 outb(satn[0], tmport++);
1613 outb(satn[1], tmport++);
1614 outb(satn[2], tmport++);
1615 outb(satn[3], tmport++);
1616 outb(satn[4], tmport++);
1617 outb(satn[5], tmport++);
1621 outb(dev->id[i].devspu, tmport++);
1623 outb(satn[6], tmport++);
1624 outb(satn[7], tmport++);
1626 if ((j & 0x08) != 0) {
1627 j = (j & 0x07) | 0x40;
1631 outb(satn[8], tmport);
1634 while ((inb(tmport) & 0x80) == 0x00);
1636 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1639 while (inb(tmport) != 0x8e);
1640 dev->active_idu |= m;
1642 tmport = wkport + 0x50;
1644 tmport = wkport + 0x54;
1648 tmport = wkport + 0x58;
1651 while ((inb(tmport) & 0x80) == 0x00);
1655 tmport = wkport + 0x50;
1660 tmport = wkport + 0x43;
1661 outb(inqd[0], tmport++);
1662 outb(inqd[1], tmport++);
1663 outb(inqd[2], tmport++);
1664 outb(inqd[3], tmport++);
1665 outb(inqd[4], tmport++);
1666 outb(inqd[5], tmport);
1670 outb(dev->id[i].devspu, tmport++);
1672 outb(inqd[6], tmport++);
1673 outb(inqd[7], tmport++);
1675 outb(inqd[8], tmport);
1677 while ((inb(tmport) & 0x80) == 0x00);
1679 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1682 while (inb(tmport) != 0x8e);
1683 tmport = wkport + 0x5b;
1685 tmport = wkport + 0x58;
1691 if ((k & 0x01) != 0) {
1693 mbuf[j++] = inb(tmport);
1697 if ((k & 0x80) == 0) {
1705 tmport = wkport + 0x50;
1714 while ((inb(tmport) & 0x80) == 0x00);
1716 if (inb(tmport) != 0x16) {
1721 printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]);
1722 dev->id[i].devtypeu = mbuf[0];
1725 if ((mbuf[7] & 0x60) == 0) {
1728 if ((i < 8) && ((dev->global_map & 0x20) == 0)) {
1734 if (dev->sp[i] != 0x04) // force u2
1739 tmport = wkport + 0x5b;
1741 tmport = wkport + 0x43;
1742 outb(satn[0], tmport++);
1743 outb(satn[1], tmport++);
1744 outb(satn[2], tmport++);
1745 outb(satn[3], tmport++);
1746 outb(satn[4], tmport++);
1747 outb(satn[5], tmport++);
1751 outb(dev->id[i].devspu, tmport++);
1753 outb(satn[6], tmport++);
1754 outb(satn[7], tmport++);
1756 outb(satn[8], tmport);
1759 while ((inb(tmport) & 0x80) == 0x00);
1761 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1764 while (inb(tmport) != 0x8e);
1767 tmport = wkport + 0x54;
1773 while ((inb(tmport) & 0x80) == 0) {
1774 if ((inb(tmport) & 0x01) != 0) {
1776 outb(u3[j++], tmport);
1781 while ((inb(tmport) & 0x80) == 0x00);
1782 j = inb(tmport) & 0x0f;
1794 tmport = wkport + 0x58;
1797 while ((inb(tmport) & 0x80) == 0) {
1798 if ((inb(tmport) & 0x01) != 0) {
1805 j = inb(tmport) & 0x0f;
1817 tmport = wkport + 0x54;
1825 if ((j & 0x01) != 0) {
1827 mbuf[k++] = inb(tmport);
1831 if ((j & 0x80) == 0x00) {
1835 j = inb(tmport) & 0x0f;
1847 tmport = wkport + 0x50;
1849 tmport = wkport + 0x54;
1854 while ((inb(tmport) & 0x80) == 0x00);
1863 if (mbuf[0] != 0x01) {
1866 if (mbuf[1] != 0x06) {
1869 if (mbuf[2] != 0x04) {
1872 if (mbuf[3] == 0x09) {
1876 dev->id[i].devspu = 0xce;
1880 tmport = wkport + 0x5b;
1882 tmport = wkport + 0x43;
1883 outb(satn[0], tmport++);
1884 outb(satn[1], tmport++);
1885 outb(satn[2], tmport++);
1886 outb(satn[3], tmport++);
1887 outb(satn[4], tmport++);
1888 outb(satn[5], tmport++);
1892 outb(dev->id[i].devspu, tmport++);
1894 outb(satn[6], tmport++);
1895 outb(satn[7], tmport++);
1897 outb(satn[8], tmport);
1900 while ((inb(tmport) & 0x80) == 0x00);
1902 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1905 while (inb(tmport) != 0x8e);
1908 tmport = wkport + 0x54;
1914 while ((inb(tmport) & 0x80) == 0) {
1915 if ((inb(tmport) & 0x01) != 0) {
1917 outb(wide[j++], tmport);
1922 while ((inb(tmport) & 0x80) == 0x00);
1923 j = inb(tmport) & 0x0f;
1935 tmport = wkport + 0x58;
1938 while ((inb(tmport) & 0x80) == 0) {
1939 if ((inb(tmport) & 0x01) != 0) {
1946 j = inb(tmport) & 0x0f;
1958 tmport = wkport + 0x54;
1966 if ((j & 0x01) != 0) {
1968 mbuf[k++] = inb(tmport);
1972 if ((j & 0x80) == 0x00) {
1976 j = inb(tmport) & 0x0f;
1988 tmport = wkport + 0x50;
1990 tmport = wkport + 0x54;
1995 while ((inb(tmport) & 0x80) == 0x00);
2004 if (mbuf[0] != 0x01) {
2007 if (mbuf[1] != 0x02) {
2010 if (mbuf[2] != 0x03) {
2013 if (mbuf[3] != 0x01) {
2020 if ((dev->id[i].devtypeu == 0x00) || (dev->id[i].devtypeu == 0x07) || ((dev->id[i].devtypeu == 0x05) && ((n & 0x10) != 0))) {
2023 if ((dev->async & m) != 0) {
2029 if (dev->sp[i] == 0x02) {
2033 if (dev->sp[i] >= 0x03) {
2038 tmport = wkport + 0x5b;
2040 if ((m & dev->wide_idu) != 0) {
2044 tmport = wkport + 0x43;
2045 outb(satn[0], tmport++);
2046 outb(satn[1], tmport++);
2047 outb(satn[2], tmport++);
2048 outb(satn[3], tmport++);
2049 outb(satn[4], tmport++);
2050 outb(satn[5], tmport++);
2054 outb(dev->id[i].devspu, tmport++);
2056 outb(satn[6], tmport++);
2057 outb(satn[7], tmport++);
2059 outb(satn[8], tmport);
2062 while ((inb(tmport) & 0x80) == 0x00);
2064 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
2067 while (inb(tmport) != 0x8e);
2070 tmport = wkport + 0x54;
2076 while ((inb(tmport) & 0x80) == 0) {
2077 if ((inb(tmport) & 0x01) != 0) {
2079 if ((m & dev->wide_idu) != 0) {
2080 if ((m & dev->ultra_map) != 0) {
2081 outb(synuw[j++], tmport);
2083 outb(synw[j++], tmport);
2086 if ((m & dev->ultra_map) != 0) {
2087 outb(synu[j++], tmport);
2089 outb(synn[j++], tmport);
2096 while ((inb(tmport) & 0x80) == 0x00);
2097 j = inb(tmport) & 0x0f;
2109 tmport = wkport + 0x58;
2112 while ((inb(tmport) & 0x80) == 0x00) {
2113 if ((inb(tmport) & 0x01) != 0x00) {
2136 tmport = wkport + 0x54;
2144 if ((j & 0x01) != 0x00) {
2146 mbuf[k++] = inb(tmport);
2150 if ((j & 0x80) == 0x00) {
2154 while ((inb(tmport) & 0x80) == 0x00);
2171 tmport = wkport + 0x50;
2174 tmport = wkport + 0x54;
2179 while ((inb(tmport) & 0x80) == 0x00);
2185 if (mbuf[0] != 0x01) {
2188 if (mbuf[1] != 0x03) {
2191 if (mbuf[4] == 0x00) {
2194 if (mbuf[3] > 0x64) {
2197 if (mbuf[4] > 0x0e) {
2200 dev->id[i].devspu = mbuf[4];
2201 if (mbuf[3] < 0x0c) {
2205 if ((mbuf[3] < 0x0d) && (rmb == 0)) {
2209 if (mbuf[3] < 0x1a) {
2213 if (mbuf[3] < 0x33) {
2217 if (mbuf[3] < 0x4c) {
2223 dev->id[i].devspu = (dev->id[i].devspu & 0x0f) | j;
2227 static void atp870u_free_tables(struct Scsi_Host *host)
2229 struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata;
2232 for (k = 0; k < 16; k++) {
2233 if (!atp_dev->id[k].prd_tableu)
2235 pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[k].prd_tableu,
2236 atp_dev->id[k].prd_phys);
2237 atp_dev->id[k].prd_tableu = NULL;
2241 static int atp870u_init_tables(struct Scsi_Host *host)
2243 struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
2246 for (i = k = 0; k < 16; k++) {
2247 dev->id[k].prd_tableu = pci_alloc_consistent(dev->pdev, 1024, &dev->id[k].prd_phys);
2248 if (!dev->id[k].prd_tableu) {
2249 atp870u_free_tables(host);
2252 dev->id[k].devspu = 0x20;
2253 dev->id[k].devtypeu = 0;
2254 dev->id[k].curr_req = NULL;
2256 dev->active_idu = 0;
2258 dev->host_idu = 0x07;
2262 dev->last_cmd = 0xff;
2265 for (k = 0; k < qcnt; k++) {
2266 dev->querequ[k] = NULL;
2268 for (k = 0; k < 16; k++) {
2269 dev->id[k].curr_req = NULL;
2275 /* return non-zero on detection */
2276 static int atp870u_probe(struct pci_dev *dev, const struct pci_device_id *ent)
2279 unsigned long flags;
2280 unsigned int base_io, error, tmport;
2281 unsigned char host_id;
2283 struct Scsi_Host *shpnt;
2284 struct atp_unit atp_dev, *p;
2287 if (pci_enable_device(dev))
2290 if (pci_set_dma_mask(dev, 0xFFFFFFFFUL)) {
2291 printk(KERN_ERR "atp870u: 32bit DMA mask required but not available.\n");
2295 memset(&atp_dev, 0, sizeof atp_dev);
2298 * It's probably easier to weed out some revisions like
2299 * this than via the PCI device table
2301 if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) {
2302 error = pci_read_config_byte(dev, PCI_CLASS_REVISION, &atp_dev.chip_veru);
2303 if (atp_dev.chip_veru < 2)
2307 switch (ent->device) {
2309 case PCI_DEVICE_ID_ARTOP_AEC7612UW:
2310 case PCI_DEVICE_ID_ARTOP_AEC7612SUW:
2311 atp_dev.chip_veru = 0x04;
2316 base_io = pci_resource_start(dev, 0);
2318 if (ent->device != 0x8081) {
2319 error = pci_read_config_byte(dev, 0x49, &host_id);
2320 base_io &= 0xfffffff8;
2322 printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-3 Host Adapter: %d "
2323 "IO:%x, IRQ:%d.\n", count, base_io, dev->irq);
2325 atp_dev.unit = count;
2326 atp_dev.ioport = base_io;
2327 atp_dev.pciport = base_io + 0x20;
2328 atp_dev.deviceid = ent->device;
2330 atp_dev.host_idu = host_id;
2331 tmport = base_io + 0x22;
2332 atp_dev.scam_on = inb(tmport);
2334 atp_dev.global_map = inb(tmport++);
2335 atp_dev.ultra_map = inw(tmport);
2337 if (atp_dev.ultra_map == 0) {
2338 atp_dev.scam_on = 0x00;
2339 atp_dev.global_map = 0x20;
2340 atp_dev.ultra_map = 0xffff;
2343 shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
2347 p = (struct atp_unit *)&shpnt->hostdata;
2349 atp_dev.host = shpnt;
2351 pci_set_drvdata(dev, p);
2352 memcpy(p, &atp_dev, sizeof atp_dev);
2353 if (atp870u_init_tables(shpnt) < 0)
2356 if (request_irq(dev->irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", shpnt)) {
2357 printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", dev->irq);
2361 spin_lock_irqsave(shpnt->host_lock, flags);
2362 if (atp_dev.chip_veru > 0x07) { /* check if atp876 chip then enable terminator */
2363 tmport = base_io + 0x3e;
2367 tmport = base_io + 0x3a;
2368 k = (inb(tmport) & 0xf3) | 0x10;
2370 outb((k & 0xdf), tmport);
2375 outb((host_id | 0x08), tmport);
2379 while ((inb(tmport) & 0x80) == 0)
2384 tmport = base_io + 1;
2387 tmport = base_io + 0x11;
2391 is870(shpnt, base_io);
2392 tmport = base_io + 0x3a;
2393 outb((inb(tmport) & 0xef), tmport);
2395 outb((inb(tmport) | 0x20), tmport);
2397 base_io &= 0xfffffff8;
2398 host_id = inb(base_io + 0x39);
2401 printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d"
2402 " IO:%x, IRQ:%d.\n", count, base_io, dev->irq);
2403 atp_dev.ioport = base_io + 0x40;
2404 atp_dev.pciport = base_io + 0x28;
2405 atp_dev.deviceid = ent->device;
2406 atp_dev.host_idu = host_id;
2408 tmport = base_io + 0x22;
2409 atp_dev.scam_on = inb(tmport);
2411 atp_dev.global_map = inb(tmport);
2413 atp_dev.ultra_map = inw(tmport);
2421 outw(n, base_io + 0x34);
2423 if (inb(base_io + 0x30) == 0xff)
2426 atp_dev.sp[m++] = inb(base_io + 0x30);
2427 atp_dev.sp[m++] = inb(base_io + 0x31);
2428 atp_dev.sp[m++] = inb(base_io + 0x32);
2429 atp_dev.sp[m++] = inb(base_io + 0x33);
2430 outw(n, base_io + 0x34);
2432 atp_dev.sp[m++] = inb(base_io + 0x30);
2433 atp_dev.sp[m++] = inb(base_io + 0x31);
2434 atp_dev.sp[m++] = inb(base_io + 0x32);
2435 atp_dev.sp[m++] = inb(base_io + 0x33);
2436 outw(n, base_io + 0x34);
2438 atp_dev.sp[m++] = inb(base_io + 0x30);
2439 atp_dev.sp[m++] = inb(base_io + 0x31);
2440 atp_dev.sp[m++] = inb(base_io + 0x32);
2441 atp_dev.sp[m++] = inb(base_io + 0x33);
2442 outw(n, base_io + 0x34);
2444 atp_dev.sp[m++] = inb(base_io + 0x30);
2445 atp_dev.sp[m++] = inb(base_io + 0x31);
2446 atp_dev.sp[m++] = inb(base_io + 0x32);
2447 atp_dev.sp[m++] = inb(base_io + 0x33);
2451 outw(0, base_io + 0x34);
2452 atp_dev.ultra_map = 0;
2454 for (k = 0; k < 16; k++) {
2457 if (atp_dev.sp[k] > 1) {
2458 atp_dev.ultra_map |= n;
2460 if (atp_dev.sp[k] == 0)
2464 atp_dev.async = ~(atp_dev.async);
2465 outb(atp_dev.global_map, base_io + 0x35);
2467 shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
2471 p = (struct atp_unit *)&shpnt->hostdata;
2473 atp_dev.host = shpnt;
2475 pci_set_drvdata(dev, p);
2476 memcpy(p, &atp_dev, sizeof atp_dev);
2477 if (atp870u_init_tables(shpnt) < 0) {
2478 printk(KERN_ERR "Unable to allocate tables for Acard controller\n");
2482 if (request_irq(dev->irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", shpnt)) {
2483 printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", dev->irq);
2487 spin_lock_irqsave(shpnt->host_lock, flags);
2488 tmport = base_io + 0x38;
2489 k = inb(tmport) & 0x80;
2496 tmport = base_io + 0x5b;
2500 tmport = base_io + 0x40;
2501 outb((host_id | 0x08), tmport);
2505 while ((inb(tmport) & 0x80) == 0)
2509 tmport = base_io + 0x41;
2512 tmport = base_io + 0x51;
2516 is880(shpnt, base_io);
2517 tmport = base_io + 0x38;
2521 if (p->chip_veru == 4)
2524 shpnt->this_id = host_id;
2525 shpnt->unique_id = base_io;
2526 shpnt->io_port = base_io;
2527 if (ent->device == 0x8081) {
2528 shpnt->n_io_port = 0x60; /* Number of bytes of I/O space used */
2530 shpnt->n_io_port = 0x40; /* Number of bytes of I/O space used */
2532 shpnt->irq = dev->irq;
2533 spin_unlock_irqrestore(shpnt->host_lock, flags);
2534 if (ent->device == 0x8081) {
2535 if (!request_region(base_io, 0x60, "atp870u"))
2536 goto request_io_fail;
2538 if (!request_region(base_io, 0x40, "atp870u"))
2539 goto request_io_fail;
2543 if (scsi_add_host(shpnt, &dev->dev))
2545 scsi_scan_host(shpnt);
2549 if (ent->device == 0x8081)
2550 release_region(base_io, 0x60);
2552 release_region(base_io, 0x40);
2554 free_irq(dev->irq, shpnt);
2556 atp870u_free_tables(shpnt);
2558 scsi_host_put(shpnt);
2562 /* The abort command does not leave the device in a clean state where
2563 it is available to be used again. Until this gets worked out, we will
2564 leave it commented out. */
2566 static int atp870u_abort(struct scsi_cmnd * SCpnt)
2569 struct scsi_cmnd *workrequ;
2570 unsigned int tmport;
2571 struct atp_unit *dev = (struct atp_unit *)&SCpnt->device->host->hostdata;
2573 printk(KERN_DEBUG "working=%x last_cmd=%x ", dev->working, dev->last_cmd);
2574 printk(" quhdu=%x quendu=%x ", dev->quhdu, dev->quendu);
2575 tmport = dev->ioport;
2576 for (j = 0; j < 0x17; j++) {
2577 printk(" r%2x=%2x", j, inb(tmport++));
2580 printk(" r1c=%2x", inb(tmport));
2582 printk(" r1f=%2x in_snd=%2x ", inb(tmport), dev->in_snd);
2583 tmport = dev->pciport;
2584 printk(" r20=%2x", inb(tmport));
2586 printk(" r22=%2x", inb(tmport));
2587 tmport = dev->ioport + 0x3a;
2588 printk(" r3a=%2x \n", inb(tmport));
2589 tmport = dev->ioport + 0x3b;
2590 printk(" r3b=%2x \n", inb(tmport));
2591 for (j = 0; j < 16; j++) {
2592 if (dev->id[j].curr_req != NULL) {
2593 workrequ = dev->id[j].curr_req;
2594 printk("\n que cdb= ");
2595 for (k = 0; k < workrequ->cmd_len; k++) {
2596 printk(" %2x ", workrequ->cmnd[k]);
2598 printk(" last_lenu= %lx ", dev->id[j].last_lenu);
2601 /* Sort of - the thing handles itself */
2605 static const char *atp870u_info(struct Scsi_Host *notused)
2607 static char buffer[128];
2609 strcpy(buffer, "ACARD AEC-6710/6712/67160 PCI Ultra/W/LVD SCSI-3 Adapter Driver V2.6+ac ");
2614 #define BLS buffer + len + size
2615 static int atp870u_proc_info(struct Scsi_Host *HBAptr, char *buffer,
2616 char **start, off_t offset, int length, int inout)
2618 static u8 buff[512];
2627 memset(buff, 0, sizeof(buff));
2629 size += sprintf(BLS, "ACARD AEC-671X Driver Version: 2.6+ac\n");
2634 size += sprintf(BLS, "\n");
2635 size += sprintf(BLS, "Adapter Configuration:\n");
2636 size += sprintf(BLS, " Base IO: %#.4lx\n", HBAptr->io_port);
2637 size += sprintf(BLS, " IRQ: %d\n", HBAptr->irq);
2641 *start = buffer + (offset - begin); /* Start of wanted data */
2642 len -= (offset - begin); /* Start slop */
2644 len = length; /* Ending slop */
2649 static int atp870u_biosparam(struct scsi_device *sdev,
2650 struct block_device *dev, sector_t capacity, int *ip)
2652 int heads, sectors, cylinders;
2656 cylinders = (unsigned long)capacity / (heads * sectors);
2658 if (cylinders > 1024) {
2661 cylinders = (unsigned long)capacity / (heads * sectors);
2670 static void atp870u_remove(struct pci_dev *pdev)
2672 struct atp_unit *atp_dev = pci_get_drvdata(pdev);
2673 struct Scsi_Host *pshost = atp_dev->host;
2675 scsi_remove_host(pshost);
2676 free_irq(pshost->irq, pshost);
2677 release_region(pshost->io_port, pshost->n_io_port);
2678 atp870u_free_tables(pshost);
2679 scsi_host_put(pshost);
2680 pci_set_drvdata(pdev, NULL);
2683 MODULE_LICENSE("GPL");
2685 static struct scsi_host_template atp870u_template = {
2686 .module = THIS_MODULE,
2688 .proc_name = "atp870u",
2689 .proc_info = atp870u_proc_info,
2690 .info = atp870u_info,
2691 .queuecommand = atp870u_queuecommand,
2692 .eh_abort_handler = atp870u_abort,
2693 .bios_param = atp870u_biosparam,
2696 .sg_tablesize = ATP870U_SCATTER,
2697 .cmd_per_lun = ATP870U_CMDLUN,
2698 .use_clustering = ENABLE_CLUSTERING,
2701 static struct pci_device_id atp870u_id_table[] = {
2702 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, 0x8081) },
2703 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7610) },
2704 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612UW) },
2705 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612U) },
2706 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612S) },
2707 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612D) },
2708 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612SUW) },
2709 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_8060) },
2713 MODULE_DEVICE_TABLE(pci, atp870u_id_table);
2715 static struct pci_driver atp870u_driver = {
2716 .id_table = atp870u_id_table,
2718 .probe = atp870u_probe,
2719 .remove = __devexit_p(atp870u_remove),
2722 static int __init atp870u_init(void)
2724 return pci_module_init(&atp870u_driver);
2727 static void __exit atp870u_exit(void)
2729 pci_unregister_driver(&atp870u_driver);
2732 module_init(atp870u_init);
2733 module_exit(atp870u_exit);