1 /* $Id: atp870u.c,v 1.0 1997/05/07 15:22:00 root Exp root $
2 * linux/kernel/atp870u.c
4 * Copyright (C) 1997 Wu Ching Chen
5 * 2.1.x update (C) 1998 Krzysztof G. Baranowski
7 * Marcelo Tosatti <marcelo@conectiva.com.br> : SMP fixes
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>
20 #include <linux/kernel.h>
21 #include <linux/types.h>
22 #include <linux/string.h>
23 #include <linux/ioport.h>
24 #include <linux/delay.h>
25 #include <linux/sched.h>
26 #include <linux/proc_fs.h>
27 #include <linux/spinlock.h>
28 #include <asm/system.h>
30 #include <linux/pci.h>
31 #include <linux/blk.h>
38 #include<linux/stat.h>
40 void mydlyu(unsigned int);
43 * 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 $";
46 static unsigned char admaxu = 1;
47 static unsigned short int sync_idu;
49 static unsigned int irqnumu[2] = {0, 0};
55 unsigned long pciport;
56 unsigned char last_cmd;
61 unsigned char scam_on;
62 unsigned char global_map;
63 unsigned char chip_veru;
64 unsigned char host_idu;
66 unsigned short wide_idu;
67 unsigned short active_idu;
68 unsigned short ultra_map;
70 unsigned short deviceid;
71 unsigned char ata_cdbu[16];
73 Scsi_Cmnd *querequ[qcnt];
78 unsigned char devtypeu;
79 unsigned long prdaddru;
80 unsigned long tran_lenu;
81 unsigned long last_lenu;
82 unsigned char *prd_posu;
83 unsigned char *prd_tableu;
88 static struct Scsi_Host *atp_host[2] = {NULL, NULL};
89 static struct atp_unit atp_unit[2];
91 static void atp870u_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
94 unsigned short int tmpcip, id;
95 unsigned char i, j, h, target_id, lun;
98 unsigned int workportu, tmport;
99 unsigned long adrcntu, k;
101 struct atp_unit *dev = dev_id;
103 for (h = 0; h < 2; h++) {
104 if (irq == irqnumu[h]) {
111 workportu = dev->ioport;
114 if (dev->working != 0)
124 tmpcip = dev->pciport;
125 if ((inb(tmpcip) & 0x08) != 0)
128 for (k=0; k < 1000; k++)
130 if ((inb(tmpcip) & 0x08) == 0)
134 if ((inb(tmpcip) & 0x01) == 0)
141 tmpcip = dev->pciport;
148 target_id = inb(tmport);
152 * Remap wide devices onto id numbers
155 if ((target_id & 0x40) != 0) {
156 target_id = (target_id & 0x07) | 0x08;
163 if (dev->last_cmd == 0xff)
165 dev->last_cmd = target_id;
167 dev->last_cmd |= 0x40;
172 if ((dev->last_cmd & 0xf0) != 0x40)
174 dev->last_cmd = 0xff;
179 if (dev->wide_idu != 0)
181 tmport = workportu + 0x1b;
183 while ((inb(tmport) & 0x01) != 0x01)
189 * Issue more commands
191 if (((dev->quhdu != dev->quendu) || (dev->last_cmd != 0xff)) &&
205 dev->last_cmd |= 0x40;
212 if ((dev->last_cmd & 0xf0) != 0x40)
214 dev->last_cmd = 0xff;
218 ((unsigned char *) &adrcntu)[2] = inb(tmport++);
219 ((unsigned char *) &adrcntu)[1] = inb(tmport++);
220 ((unsigned char *) &adrcntu)[0] = inb(tmport);
221 k = dev->id[target_id].last_lenu;
223 dev->id[target_id].tran_lenu = k;
224 dev->id[target_id].last_lenu = adrcntu;
232 if ((i == 0x80) || (i == 0x8f))
237 if (j == 0x44 || i==0x80) {
239 lun = inb(tmport) & 0x07;
241 if ((dev->last_cmd & 0xf0) != 0x40)
243 dev->last_cmd = 0xff;
249 ((unsigned char *) &adrcntu)[2] = inb(tmport++);
250 ((unsigned char *) &adrcntu)[1] = inb(tmport++);
251 ((unsigned char *) &adrcntu)[0] = inb(tmport);
252 k = dev->id[target_id].last_lenu;
254 dev->id[target_id].tran_lenu = k;
255 dev->id[target_id].last_lenu = adrcntu;
264 dev->id[target_id].dirctu = 0x00;
266 outb(0x00, tmport++);
267 outb(0x00, tmport++);
268 outb(0x00, tmport++);
275 if (dev->last_cmd != 0xff)
277 dev->last_cmd |= 0x40;
279 tmport = workportu + 0x10;
282 target_id = inb(tmport);
284 * Remap wide identifiers
286 if ((target_id & 0x10) != 0)
288 target_id = (target_id & 0x07) | 0x08;
292 workrequ = dev->id[target_id].curr_req;
293 tmport = workportu + 0x0f;
296 outb(dev->id[target_id].devspu, tmport++);
297 adrcntu = dev->id[target_id].tran_lenu;
298 k = dev->id[target_id].last_lenu;
299 outb(((unsigned char *) &k)[2], tmport++);
300 outb(((unsigned char *) &k)[1], tmport++);
301 outb(((unsigned char *) &k)[0], tmport++);
305 j = (j & 0x07) | 0x40;
308 j |= dev->id[target_id].dirctu;
312 /* enable 32 bit fifo transfer */
313 if (dev->deviceid != 0x8081)
315 tmport = workportu + 0x3a;
316 if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) ||
317 (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a))
319 outb((unsigned char)((inb(tmport) & 0xf3) | 0x08),tmport);
323 outb((unsigned char)(inb(tmport) & 0xf3),tmport);
328 tmport = workportu - 0x05;
329 if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) ||
330 (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a))
332 outb((unsigned char)((inb(tmport) & 0x3f) | 0xc0),tmport);
336 outb((unsigned char)(inb(tmport) & 0x3f),tmport);
340 tmport = workportu + 0x1b;
343 id = id << target_id;
345 * Is this a wide device
347 if ((id & dev->wide_idu) != 0) {
351 while ((inb(tmport) & 0x01) != j)
356 if (dev->id[target_id].last_lenu == 0) {
357 tmport = workportu + 0x18;
362 prd = dev->id[target_id].prd_posu;
365 id = ((unsigned short int *) (prd))[2];
372 ((unsigned short int *) (prd))[2] = (unsigned short int)
374 ((unsigned long *) (prd))[0] += adrcntu;
376 dev->id[target_id].prd_posu = prd;
379 dev->id[target_id].prdaddru += 0x08;
382 dev->id[target_id].prd_posu = prd;
386 tmpcip = dev->pciport + 0x04;
387 outl(dev->id[target_id].prdaddru, tmpcip);
392 tmport = workportu + 0x18;
394 * Check transfer direction
396 if (dev->id[target_id].dirctu != 0) {
409 * Current scsi request on this target
412 workrequ = dev->id[target_id].curr_req;
415 if ((dev->last_cmd & 0xf0) != 0x40)
417 dev->last_cmd = 0xff;
420 workrequ->result = errstus;
425 if ((dev->last_cmd & 0xf0) != 0x40)
427 dev->last_cmd = 0xff;
431 errstus = inb(tmport);
432 workrequ->result = errstus;
435 * Complete the command
437 spin_lock_irqsave(&io_request_lock, flags);
438 (*workrequ->scsi_done) (workrequ);
441 * Clear it off the queue
443 dev->id[target_id].curr_req = 0;
445 spin_unlock_irqrestore(&io_request_lock, flags);
449 if (dev->wide_idu != 0) {
450 tmport = workportu + 0x1b;
452 while ((inb(tmport) & 0x01) != 0x01)
458 * If there is stuff to send and nothing going then send it
460 if (((dev->last_cmd != 0xff) || (dev->quhdu != dev->quendu)) &&
468 if ((dev->last_cmd & 0xf0) != 0x40)
470 dev->last_cmd = 0xff;
478 outl(dev->id[target_id].prdaddru, tmpcip);
483 tmport = workportu + 0x10;
485 dev->id[target_id].dirctu = 0x00;
494 outl(dev->id[target_id].prdaddru, tmpcip);
499 tmport = workportu + 0x10;
502 outb((unsigned char) (inb(tmport) | 0x20), tmport);
503 dev->id[target_id].dirctu = 0x20;
516 dev->id[target_id].dirctu = 0x00;
518 outb(0x00, tmport++);
519 outb(0x00, tmport++);
520 outb(0x00, tmport++);
526 // tmport = workportu + 0x17;
534 int atp870u_queuecommand(Scsi_Cmnd * req_p, void (*done) (Scsi_Cmnd *))
538 unsigned short int m;
540 struct atp_unit *dev;
542 for (h = 0; h <= admaxu; h++) {
543 if (req_p->host == atp_host[h]) {
549 if (req_p->channel != 0) {
550 req_p->result = 0x00040000;
556 m = m << req_p->target;
559 * Fake a timeout for missing targets
562 if ((m & dev->active_idu) == 0) {
563 req_p->result = 0x00040000;
568 req_p->scsi_done = done;
570 printk(KERN_WARNING "atp870u_queuecommand: done can't be NULL\n");
581 if (dev->quendu >= qcnt) {
587 if (dev->quhdu == dev->quendu) {
588 if (dev->quendu == 0) {
592 req_p->result = 0x00020000;
594 restore_flags(flags);
597 dev->querequ[dev->quendu] = req_p;
598 tmport = dev->ioport + 0x1c;
599 restore_flags(flags);
600 if ((inb(tmport) == 0) && (dev->in_int == 0) && (dev->in_snd == 0)) {
606 void mydlyu(unsigned int dlycnt)
609 for (i = 0; i < dlycnt; i++) {
614 void send_s870(unsigned char h)
620 unsigned char j, target_id;
622 unsigned short int tmpcip, w;
623 unsigned long l, bttl;
624 unsigned int workportu;
625 struct scatterlist *sgpnt;
626 struct atp_unit *dev = &atp_unit[h];
630 if (dev->in_snd != 0) {
631 restore_flags(flags);
635 if ((dev->last_cmd != 0xff) && ((dev->last_cmd & 0x40) != 0)) {
636 dev->last_cmd &= 0x0f;
637 workrequ = dev->id[dev->last_cmd].curr_req;
638 if (workrequ != NULL) /* check NULL pointer */
642 dev->last_cmd = 0xff;
643 if (dev->quhdu == dev->quendu)
646 restore_flags(flags);
650 if ((dev->last_cmd != 0xff) && (dev->working != 0))
653 restore_flags(flags);
659 if (dev->quhdu >= qcnt) {
662 workrequ = dev->querequ[dev->quhdu];
663 if (dev->id[workrequ->target].curr_req == 0) {
664 dev->id[workrequ->target].curr_req = workrequ;
665 dev->last_cmd = workrequ->target;
671 restore_flags(flags);
674 workportu = dev->ioport;
675 tmport = workportu + 0x1f;
676 if ((inb(tmport) & 0xb0) != 0) {
679 tmport = workportu + 0x1c;
680 if (inb(tmport) == 0) {
684 dev->last_cmd |= 0x40;
686 restore_flags(flags);
689 memcpy(&dev->ata_cdbu[0], &workrequ->cmnd[0], workrequ->cmd_len);
690 if (dev->ata_cdbu[0] == READ_CAPACITY) {
691 if (workrequ->request_bufflen > 8) {
692 workrequ->request_bufflen = 0x08;
695 if (dev->ata_cdbu[0] == 0x00) {
696 workrequ->request_bufflen = 0;
699 tmport = workportu + 0x1b;
701 target_id = workrequ->target;
708 if ((w & dev->wide_idu) != 0) {
712 while ((inb(tmport) & 0x01) != j)
722 outb(workrequ->cmd_len, tmport++);
723 outb(0x2c, tmport++);
724 outb(0xcf, tmport++);
725 for (i = 0; i < workrequ->cmd_len; i++) {
726 outb(dev->ata_cdbu[i], tmport++);
728 tmport = workportu + 0x0f;
729 outb(workrequ->lun, tmport);
734 outb(dev->id[target_id].devspu, tmport++);
737 * Figure out the transfer size
739 if (workrequ->use_sg)
742 sgpnt = (struct scatterlist *) workrequ->request_buffer;
743 for (i = 0; i < workrequ->use_sg; i++)
745 if (sgpnt[i].length == 0 || workrequ->use_sg > ATP870U_SCATTER)
747 panic("Foooooooood fight!");
749 l += sgpnt[i].length;
752 l = workrequ->request_bufflen;
755 * Write transfer size
757 outb((unsigned char) (((unsigned char *) (&l))[2]), tmport++);
758 outb((unsigned char) (((unsigned char *) (&l))[1]), tmport++);
759 outb((unsigned char) (((unsigned char *) (&l))[0]), tmport++);
761 dev->id[j].last_lenu = l;
762 dev->id[j].tran_lenu = 0;
766 if ((j & 0x08) != 0) {
767 j = (j & 0x07) | 0x40;
770 * Check transfer direction
772 if ((dev->ata_cdbu[0] == WRITE_6) || (dev->ata_cdbu[0] == WRITE_10) ||
773 (dev->ata_cdbu[0] == WRITE_12) || (dev->ata_cdbu[0] == MODE_SELECT)) {
774 outb((unsigned char) (j | 0x20), tmport++);
778 outb((unsigned char)(inb(tmport) | 0x80),tmport);
780 tmport = workportu + 0x1c;
781 dev->id[target_id].dirctu = 0;
783 if (inb(tmport) == 0) {
784 tmport = workportu + 0x18;
787 dev->last_cmd |= 0x40;
790 restore_flags(flags);
793 tmpcip = dev->pciport;
794 prd = dev->id[target_id].prd_tableu;
795 dev->id[target_id].prd_posu = prd;
798 * Now write the request list. Either as scatter/gather or as
802 if (workrequ->use_sg)
804 sgpnt = (struct scatterlist *) workrequ->request_buffer;
806 for (j = 0; j < workrequ->use_sg; j++) {
807 bttl = virt_to_bus(sgpnt[j].address);
809 while (l > 0x10000) {
810 (((unsigned short int *) (prd))[i + 3]) = 0x0000;
811 (((unsigned short int *) (prd))[i + 2]) = 0x0000;
812 (((unsigned long *) (prd))[i >> 1]) = bttl;
817 (((unsigned long *) (prd))[i >> 1]) = bttl;
818 (((unsigned short int *) (prd))[i + 2]) = l;
819 (((unsigned short int *) (prd))[i + 3]) = 0;
822 (((unsigned short int *) (prd))[i - 1]) = 0x8000;
825 * For a linear request write a chain of blocks
827 bttl = virt_to_bus(workrequ->request_buffer);
828 l = workrequ->request_bufflen;
830 while (l > 0x10000) {
831 (((unsigned short int *) (prd))[i + 3]) = 0x0000;
832 (((unsigned short int *) (prd))[i + 2]) = 0x0000;
833 (((unsigned long *) (prd))[i >> 1]) = bttl;
838 (((unsigned short int *) (prd))[i + 3]) = 0x8000;
839 (((unsigned short int *) (prd))[i + 2]) = l;
840 (((unsigned long *) (prd))[i >> 1]) = bttl;
843 dev->id[target_id].prdaddru = virt_to_bus(dev->id[target_id].prd_tableu);
844 outl(dev->id[target_id].prdaddru, tmpcip);
850 if (dev->deviceid != 0x8081)
852 tmport = workportu + 0x3a;
853 if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) ||
854 (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a))
856 outb((unsigned char)((inb(tmport) & 0xf3) | 0x08),tmport);
860 outb((unsigned char)(inb(tmport) & 0xf3),tmport);
865 tmport = workportu - 0x05;
866 if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) ||
867 (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a))
869 outb((unsigned char)((inb(tmport) & 0x3f) | 0xc0),tmport);
873 outb((unsigned char)(inb(tmport) & 0x3f),tmport);
876 tmport = workportu + 0x1c;
878 if ((dev->ata_cdbu[0] == WRITE_6) || (dev->ata_cdbu[0] == WRITE_10) ||
879 (dev->ata_cdbu[0] == WRITE_12) || (dev->ata_cdbu[0] == MODE_SELECT))
881 dev->id[target_id].dirctu = 0x20;
882 if (inb(tmport) == 0) {
883 tmport = workportu + 0x18;
887 dev->last_cmd |= 0x40;
890 restore_flags(flags);
893 if (inb(tmport) == 0)
895 tmport = workportu + 0x18;
899 dev->last_cmd |= 0x40;
902 restore_flags(flags);
907 static void internal_done(Scsi_Cmnd * SCpnt)
912 int atp870u_command(Scsi_Cmnd * SCpnt)
915 atp870u_queuecommand(SCpnt, internal_done);
917 SCpnt->SCp.Status = 0;
918 while (!SCpnt->SCp.Status)
920 return SCpnt->result;
923 unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val)
926 unsigned short int i, k;
929 tmport = dev->ioport + 0x1c;
932 for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */
934 j = (unsigned char) (k >> 8);
935 if ((k & 0x8000) != 0) { /* DB7 all release? */
939 *val |= 0x4000; /* assert DB6 */
941 *val &= 0xdfff; /* assert DB5 */
944 for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */
945 if ((inw(tmport) & 0x2000) != 0) { /* DB5 all release? */
949 *val |= 0x8000; /* no DB4-0, assert DB7 */
952 *val &= 0xbfff; /* release DB6 */
955 for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */
956 if ((inw(tmport) & 0x4000) != 0) { /* DB6 all release? */
964 void tscam(unsigned char host)
968 unsigned char i, j, k;
970 unsigned short int m, assignid_map, val;
971 unsigned char mbuf[33], quintet[2];
972 struct atp_unit *dev = &atp_unit[host];
973 static unsigned char g2q_tab[8] = {
974 0x38, 0x31, 0x32, 0x2b, 0x34, 0x2d, 0x2e, 0x27
978 for (i = 0; i < 0x10; i++) {
982 tmport = dev->ioport + 1;
983 outb(0x08, tmport++);
985 tmport = dev->ioport + 0x11;
988 if ((dev->scam_on & 0x40) == 0) {
994 if (dev->chip_veru < 4) {
999 tmport = dev->ioport + 0x02;
1000 outb(0x02, tmport++); /* 2*2=4ms,3EH 2/32*3E=3.9ms */
1008 for (i = 0; i < j; i++) {
1011 if ((m & assignid_map) != 0) {
1014 tmport = dev->ioport + 0x0f;
1021 k = (i & 0x07) | 0x40;
1026 tmport = dev->ioport + 0x1b;
1027 if (dev->chip_veru == 4) {
1033 tmport = dev->ioport + 0x18;
1037 while ((inb(tmport) & 0x80) == 0x00);
1041 if ((k == 0x85) || (k == 0x42)) {
1044 tmport = dev->ioport + 0x10;
1051 tmport = dev->ioport + 0x02;
1053 tmport = dev->ioport + 0x1b;
1058 val = 0x0080; /* bsy */
1059 tmport = dev->ioport + 0x1c;
1061 val |= 0x0040; /* sel */
1063 val |= 0x0004; /* msg */
1065 inb(0x80); /* 2 deskew delay(45ns*2=90ns) */
1066 val &= 0x007f; /* no bsy */
1068 mydlyu(0xffff); /* recommanded SCAM selection response time */
1070 val &= 0x00fb; /* after 1ms no msg */
1073 if ((inb(tmport) & 0x04) != 0) {
1078 for (n = 0; n < 0x30000; n++) {
1079 if ((inb(tmport) & 0x80) != 0) { /* bsy ? */
1085 for (n = 0; n < 0x30000; n++) {
1086 if ((inb(tmport) & 0x81) == 0x0081) {
1093 val |= 0x8003; /* io,cd,db7 */
1096 val &= 0x00bf; /* no sel */
1101 if ((inb(tmport) & 0x80) == 0x00) { /* bsy ? */
1104 tmport = dev->ioport + 0x15;
1109 while ((inb(tmport) & 0x80) == 0);
1114 val &= 0x00ff; /* synchronization */
1116 fun_scam(dev, &val);
1118 val &= 0x00ff; /* isolation */
1120 fun_scam(dev, &val);
1125 if ((inw(tmport) & 0x2000) == 0) {
1129 val &= 0x00ff; /* get ID_STRING */
1131 k = fun_scam(dev, &val);
1132 if ((k & 0x03) == 0) {
1137 if ((k & 0x02) != 0) {
1148 TCM_5: /* isolation complete.. */
1150 printk(" \n%x %x %x %s\n ",assignid_map,mbuf[0],mbuf[1],&mbuf[2]); */
1153 if ((j & 0x20) != 0) { /* bit5=1:ID upto 7 */
1156 if ((j & 0x06) == 0) { /* IDvalid? */
1163 if ((m & assignid_map) == 0) {
1170 G2Q5: /* srch from max acceptable ID# */
1171 k = i; /* max acceptable ID# */
1175 if ((m & assignid_map) == 0) {
1182 G2Q_QUIN: /* k=binID#, */
1185 quintet[0] = 0x38; /* 1st dft ID<8 */
1187 quintet[0] = 0x31; /* 1st ID>=8 */
1190 quintet[1] = g2q_tab[k];
1192 val &= 0x00ff; /* AssignID 1stQuintet,AH=001xxxxx */
1193 m = quintet[0] << 8;
1195 fun_scam(dev, &val);
1196 val &= 0x00ff; /* AssignID 2ndQuintet,AH=001xxxxx */
1197 m = quintet[1] << 8;
1199 fun_scam(dev, &val);
1205 void is870(unsigned long host, unsigned int wkport)
1207 unsigned int tmport;
1208 unsigned char i, j, k, rmb, n;
1209 unsigned short int m;
1210 static unsigned char mbuf[512];
1211 static unsigned char satn[9] = {0, 0, 0, 0, 0, 0, 0, 6, 6};
1212 static unsigned char inqd[9] = {0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6};
1213 static unsigned char synn[6] = {0x80, 1, 3, 1, 0x19, 0x0e};
1214 static unsigned char synu[6] = {0x80, 1, 3, 1, 0x0c, 0x0e};
1215 static unsigned char synw[6] = {0x80, 1, 3, 1, 0x0c, 0x07};
1216 static unsigned char wide[6] = {0x80, 1, 2, 3, 1, 0};
1217 struct atp_unit *dev = &atp_unit[host];
1220 tmport = wkport + 0x3a;
1221 outb((unsigned char) (inb(tmport) | 0x10), tmport);
1223 for (i = 0; i < 16; i++) {
1224 if ((dev->chip_veru != 4) && (i > 7)) {
1229 if ((m & dev->active_idu) != 0) {
1232 if (i == dev->host_idu) {
1233 printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_idu);
1236 tmport = wkport + 0x1b;
1237 if (dev->chip_veru == 4) {
1244 tmport = wkport + 1;
1245 outb(0x08, tmport++);
1246 outb(0x7f, tmport++);
1247 outb(satn[0], tmport++);
1248 outb(satn[1], tmport++);
1249 outb(satn[2], tmport++);
1250 outb(satn[3], tmport++);
1251 outb(satn[4], tmport++);
1252 outb(satn[5], tmport++);
1256 outb(dev->id[i].devspu, tmport++);
1258 outb(satn[6], tmport++);
1259 outb(satn[7], tmport++);
1261 if ((j & 0x08) != 0) {
1262 j = (j & 0x07) | 0x40;
1266 outb(satn[8], tmport);
1269 while ((inb(tmport) & 0x80) == 0x00);
1271 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1274 while (inb(tmport) != 0x8e);
1275 dev->active_idu |= m;
1277 tmport = wkport + 0x10;
1279 tmport = wkport + 0x04;
1283 tmport = wkport + 0x18;
1286 while ((inb(tmport) & 0x80) == 0x00);
1290 tmport = wkport + 0x10;
1295 tmport = wkport + 3;
1296 outb(inqd[0], tmport++);
1297 outb(inqd[1], tmport++);
1298 outb(inqd[2], tmport++);
1299 outb(inqd[3], tmport++);
1300 outb(inqd[4], tmport++);
1301 outb(inqd[5], tmport);
1305 outb(dev->id[i].devspu, tmport++);
1307 outb(inqd[6], tmport++);
1308 outb(inqd[7], tmport++);
1310 outb(inqd[8], tmport);
1312 while ((inb(tmport) & 0x80) == 0x00);
1314 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1317 while (inb(tmport) != 0x8e);
1318 tmport = wkport + 0x1b;
1319 if (dev->chip_veru == 4) {
1322 tmport = wkport + 0x18;
1328 if ((k & 0x01) != 0) {
1330 mbuf[j++] = inb(tmport);
1334 if ((k & 0x80) == 0) {
1342 tmport = wkport + 0x10;
1351 while ((inb(tmport) & 0x80) == 0x00);
1353 if (inb(tmport) != 0x16) {
1358 printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]);
1359 dev->id[i].devtypeu = mbuf[0];
1362 if (dev->chip_veru != 4) {
1365 if ((mbuf[7] & 0x60) == 0) {
1368 if ((dev->global_map & 0x20) == 0) {
1371 tmport = wkport + 0x1b;
1373 tmport = wkport + 3;
1374 outb(satn[0], tmport++);
1375 outb(satn[1], tmport++);
1376 outb(satn[2], tmport++);
1377 outb(satn[3], tmport++);
1378 outb(satn[4], tmport++);
1379 outb(satn[5], tmport++);
1383 outb(dev->id[i].devspu, tmport++);
1385 outb(satn[6], tmport++);
1386 outb(satn[7], tmport++);
1388 outb(satn[8], tmport);
1391 while ((inb(tmport) & 0x80) == 0x00);
1393 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1396 while (inb(tmport) != 0x8e);
1399 tmport = wkport + 0x14;
1405 while ((inb(tmport) & 0x80) == 0) {
1406 if ((inb(tmport) & 0x01) != 0) {
1408 outb(wide[j++], tmport);
1413 while ((inb(tmport) & 0x80) == 0x00);
1414 j = inb(tmport) & 0x0f;
1426 tmport = wkport + 0x18;
1429 while ((inb(tmport) & 0x80) == 0) {
1430 if ((inb(tmport) & 0x01) != 0) {
1437 j = inb(tmport) & 0x0f;
1449 tmport = wkport + 0x14;
1457 if ((j & 0x01) != 0) {
1459 mbuf[k++] = inb(tmport);
1463 if ((j & 0x80) == 0x00) {
1467 j = inb(tmport) & 0x0f;
1479 tmport = wkport + 0x10;
1481 tmport = wkport + 0x14;
1486 while ((inb(tmport) & 0x80) == 0x00);
1495 if (mbuf[0] != 0x01) {
1498 if (mbuf[1] != 0x02) {
1501 if (mbuf[2] != 0x03) {
1504 if (mbuf[3] != 0x01) {
1511 if ((dev->id[i].devtypeu == 0x00) || (dev->id[i].devtypeu == 0x07) ||
1512 ((dev->id[i].devtypeu == 0x05) && ((n & 0x10) != 0)))
1518 tmport = wkport + 0x1b;
1520 if ((m & dev->wide_idu) != 0) {
1524 tmport = wkport + 3;
1525 outb(satn[0], tmport++);
1526 outb(satn[1], tmport++);
1527 outb(satn[2], tmport++);
1528 outb(satn[3], tmport++);
1529 outb(satn[4], tmport++);
1530 outb(satn[5], tmport++);
1534 outb(dev->id[i].devspu, tmport++);
1536 outb(satn[6], tmport++);
1537 outb(satn[7], tmport++);
1539 outb(satn[8], tmport);
1542 while ((inb(tmport) & 0x80) == 0x00);
1544 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1547 while (inb(tmport) != 0x8e);
1550 tmport = wkport + 0x14;
1556 while ((inb(tmport) & 0x80) == 0) {
1557 if ((inb(tmport) & 0x01) != 0) {
1559 if ((m & dev->wide_idu) != 0) {
1560 outb(synw[j++], tmport);
1562 if ((m & dev->ultra_map) != 0) {
1563 outb(synu[j++], tmport);
1565 outb(synn[j++], tmport);
1572 while ((inb(tmport) & 0x80) == 0x00);
1573 j = inb(tmport) & 0x0f;
1585 tmport = wkport + 0x18;
1588 while ((inb(tmport) & 0x80) == 0x00) {
1589 if ((inb(tmport) & 0x01) != 0x00) {
1612 tmport = wkport + 0x14;
1620 if ((j & 0x01) != 0x00) {
1622 mbuf[k++] = inb(tmport);
1626 if ((j & 0x80) == 0x00) {
1630 while ((inb(tmport) & 0x80) == 0x00);
1647 tmport = wkport + 0x10;
1650 tmport = wkport + 0x14;
1655 while ((inb(tmport) & 0x80) == 0x00);
1661 if (mbuf[0] != 0x01) {
1664 if (mbuf[1] != 0x03) {
1667 if (mbuf[4] == 0x00) {
1670 if (mbuf[3] > 0x64) {
1673 if (mbuf[4] > 0x0c) {
1676 dev->id[i].devspu = mbuf[4];
1677 if ((mbuf[3] < 0x0d) && (rmb == 0)) {
1681 if (mbuf[3] < 0x1a) {
1685 if (mbuf[3] < 0x33) {
1689 if (mbuf[3] < 0x4c) {
1695 dev->id[i].devspu = (dev->id[i].devspu & 0x0f) | j;
1697 tmport = wkport + 0x3a;
1698 outb((unsigned char) (inb(tmport) & 0xef), tmport);
1701 void is880(unsigned long host, unsigned int wkport)
1703 unsigned int tmport;
1704 unsigned char i, j, k, rmb, n, lvdmode;
1705 unsigned short int m;
1706 static unsigned char mbuf[512];
1707 static unsigned char satn[9] = {0, 0, 0, 0, 0, 0, 0, 6, 6};
1708 static unsigned char inqd[9] = {0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6};
1709 static unsigned char synn[6] = {0x80, 1, 3, 1, 0x19, 0x0e};
1710 unsigned char synu[6] = {0x80, 1, 3, 1, 0x0a, 0x0e};
1711 static unsigned char synw[6] = {0x80, 1, 3, 1, 0x19, 0x0e};
1712 unsigned char synuw[6] = {0x80, 1, 3, 1, 0x0a, 0x0e};
1713 static unsigned char wide[6] = {0x80, 1, 2, 3, 1, 0};
1714 static unsigned char u3[9] = { 0x80,1,6,4,0x09,00,0x0e,0x01,0x02 };
1715 struct atp_unit *dev = &atp_unit[host];
1718 lvdmode=inb(wkport + 0x3f) & 0x40;
1720 for (i = 0; i < 16; i++) {
1723 if ((m & dev->active_idu) != 0) {
1726 if (i == dev->host_idu) {
1727 printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_idu);
1730 tmport = wkport + 0x5b;
1732 tmport = wkport + 0x41;
1733 outb(0x08, tmport++);
1734 outb(0x7f, tmport++);
1735 outb(satn[0], tmport++);
1736 outb(satn[1], tmport++);
1737 outb(satn[2], tmport++);
1738 outb(satn[3], tmport++);
1739 outb(satn[4], tmport++);
1740 outb(satn[5], tmport++);
1744 outb(dev->id[i].devspu, tmport++);
1746 outb(satn[6], tmport++);
1747 outb(satn[7], tmport++);
1749 if ((j & 0x08) != 0) {
1750 j = (j & 0x07) | 0x40;
1754 outb(satn[8], tmport);
1757 while ((inb(tmport) & 0x80) == 0x00);
1759 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1762 while (inb(tmport) != 0x8e);
1763 dev->active_idu |= m;
1765 tmport = wkport + 0x50;
1767 tmport = wkport + 0x54;
1771 tmport = wkport + 0x58;
1774 while ((inb(tmport) & 0x80) == 0x00);
1778 tmport = wkport + 0x50;
1783 tmport = wkport + 0x43;
1784 outb(inqd[0], tmport++);
1785 outb(inqd[1], tmport++);
1786 outb(inqd[2], tmport++);
1787 outb(inqd[3], tmport++);
1788 outb(inqd[4], tmport++);
1789 outb(inqd[5], tmport);
1793 outb(dev->id[i].devspu, tmport++);
1795 outb(inqd[6], tmport++);
1796 outb(inqd[7], tmport++);
1798 outb(inqd[8], tmport);
1800 while ((inb(tmport) & 0x80) == 0x00);
1802 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1805 while (inb(tmport) != 0x8e);
1806 tmport = wkport + 0x5b;
1808 tmport = wkport + 0x58;
1814 if ((k & 0x01) != 0) {
1816 mbuf[j++] = inb(tmport);
1820 if ((k & 0x80) == 0) {
1828 tmport = wkport + 0x50;
1837 while ((inb(tmport) & 0x80) == 0x00);
1839 if (inb(tmport) != 0x16) {
1844 printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]);
1845 dev->id[i].devtypeu = mbuf[0];
1848 if ((mbuf[7] & 0x60) == 0) {
1851 if ((i < 8) && ((dev->global_map & 0x20) == 0)) {
1858 if (dev->sp[i] != 0x04) // force u2
1863 tmport = wkport + 0x5b;
1865 tmport = wkport + 0x43;
1866 outb(satn[0], tmport++);
1867 outb(satn[1], tmport++);
1868 outb(satn[2], tmport++);
1869 outb(satn[3], tmport++);
1870 outb(satn[4], tmport++);
1871 outb(satn[5], tmport++);
1875 outb(dev->id[i].devspu, tmport++);
1877 outb(satn[6], tmport++);
1878 outb(satn[7], tmport++);
1880 outb(satn[8], tmport);
1883 while ((inb(tmport) & 0x80) == 0x00);
1885 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1888 while (inb(tmport) != 0x8e);
1891 tmport = wkport + 0x54;
1897 while ((inb(tmport) & 0x80) == 0) {
1898 if ((inb(tmport) & 0x01) != 0) {
1900 outb(u3[j++], tmport);
1905 while ((inb(tmport) & 0x80) == 0x00);
1906 j = inb(tmport) & 0x0f;
1918 tmport = wkport + 0x58;
1921 while ((inb(tmport) & 0x80) == 0) {
1922 if ((inb(tmport) & 0x01) != 0) {
1929 j = inb(tmport) & 0x0f;
1941 tmport = wkport + 0x54;
1949 if ((j & 0x01) != 0) {
1951 mbuf[k++] = inb(tmport);
1955 if ((j & 0x80) == 0x00) {
1959 j = inb(tmport) & 0x0f;
1971 tmport = wkport + 0x50;
1973 tmport = wkport + 0x54;
1978 while ((inb(tmport) & 0x80) == 0x00);
1987 if (mbuf[0] != 0x01) {
1990 if (mbuf[1] != 0x06) {
1993 if (mbuf[2] != 0x04) {
1996 if (mbuf[3] == 0x09) {
2000 dev->id[i].devspu = 0xce;
2004 tmport = wkport + 0x5b;
2006 tmport = wkport + 0x43;
2007 outb(satn[0], tmport++);
2008 outb(satn[1], tmport++);
2009 outb(satn[2], tmport++);
2010 outb(satn[3], tmport++);
2011 outb(satn[4], tmport++);
2012 outb(satn[5], tmport++);
2016 outb(dev->id[i].devspu, tmport++);
2018 outb(satn[6], tmport++);
2019 outb(satn[7], tmport++);
2021 outb(satn[8], tmport);
2024 while ((inb(tmport) & 0x80) == 0x00);
2026 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
2029 while (inb(tmport) != 0x8e);
2032 tmport = wkport + 0x54;
2038 while ((inb(tmport) & 0x80) == 0) {
2039 if ((inb(tmport) & 0x01) != 0) {
2041 outb(wide[j++], tmport);
2046 while ((inb(tmport) & 0x80) == 0x00);
2047 j = inb(tmport) & 0x0f;
2059 tmport = wkport + 0x58;
2062 while ((inb(tmport) & 0x80) == 0) {
2063 if ((inb(tmport) & 0x01) != 0) {
2070 j = inb(tmport) & 0x0f;
2082 tmport = wkport + 0x54;
2090 if ((j & 0x01) != 0) {
2092 mbuf[k++] = inb(tmport);
2096 if ((j & 0x80) == 0x00) {
2100 j = inb(tmport) & 0x0f;
2112 tmport = wkport + 0x50;
2114 tmport = wkport + 0x54;
2119 while ((inb(tmport) & 0x80) == 0x00);
2128 if (mbuf[0] != 0x01) {
2131 if (mbuf[1] != 0x02) {
2134 if (mbuf[2] != 0x03) {
2137 if (mbuf[3] != 0x01) {
2144 if ((dev->id[i].devtypeu == 0x00) || (dev->id[i].devtypeu == 0x07) ||
2145 ((dev->id[i].devtypeu == 0x05) && ((n & 0x10) != 0)))
2149 if ((dev->async & m) != 0)
2156 if (dev->sp[i] == 0x02)
2163 if (dev->sp[i] >= 0x03)
2169 tmport = wkport + 0x5b;
2171 if ((m & dev->wide_idu) != 0) {
2175 tmport = wkport + 0x43;
2176 outb(satn[0], tmport++);
2177 outb(satn[1], tmport++);
2178 outb(satn[2], tmport++);
2179 outb(satn[3], tmport++);
2180 outb(satn[4], tmport++);
2181 outb(satn[5], tmport++);
2185 outb(dev->id[i].devspu, tmport++);
2187 outb(satn[6], tmport++);
2188 outb(satn[7], tmport++);
2190 outb(satn[8], tmport);
2193 while ((inb(tmport) & 0x80) == 0x00);
2195 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
2198 while (inb(tmport) != 0x8e);
2201 tmport = wkport + 0x54;
2207 while ((inb(tmport) & 0x80) == 0) {
2208 if ((inb(tmport) & 0x01) != 0) {
2210 if ((m & dev->wide_idu) != 0) {
2211 if ((m & dev->ultra_map) != 0) {
2212 outb(synuw[j++], tmport);
2214 outb(synw[j++], tmport);
2217 if ((m & dev->ultra_map) != 0) {
2218 outb(synu[j++], tmport);
2220 outb(synn[j++], tmport);
2227 while ((inb(tmport) & 0x80) == 0x00);
2228 j = inb(tmport) & 0x0f;
2240 tmport = wkport + 0x58;
2243 while ((inb(tmport) & 0x80) == 0x00) {
2244 if ((inb(tmport) & 0x01) != 0x00) {
2267 tmport = wkport + 0x54;
2275 if ((j & 0x01) != 0x00) {
2277 mbuf[k++] = inb(tmport);
2281 if ((j & 0x80) == 0x00) {
2285 while ((inb(tmport) & 0x80) == 0x00);
2302 tmport = wkport + 0x50;
2305 tmport = wkport + 0x54;
2310 while ((inb(tmport) & 0x80) == 0x00);
2316 if (mbuf[0] != 0x01) {
2319 if (mbuf[1] != 0x03) {
2322 if (mbuf[4] == 0x00) {
2325 if (mbuf[3] > 0x64) {
2328 if (mbuf[4] > 0x0e) {
2331 dev->id[i].devspu = mbuf[4];
2332 if (mbuf[3] < 0x0c){
2336 if ((mbuf[3] < 0x0d) && (rmb == 0)) {
2340 if (mbuf[3] < 0x1a) {
2344 if (mbuf[3] < 0x33) {
2348 if (mbuf[3] < 0x4c) {
2354 dev->id[i].devspu = (dev->id[i].devspu & 0x0f) | j;
2358 /* return non-zero on detection */
2359 int atp870u_detect(Scsi_Host_Template * tpnt)
2361 unsigned char irq, h, k, m;
2362 unsigned long flags;
2363 unsigned int base_io, error, tmport;
2364 unsigned short index = 0;
2365 struct pci_dev *pdev[3];
2366 unsigned char chip_ver[3], host_id;
2367 unsigned short dev_id[3], n;
2368 struct Scsi_Host *shpnt = NULL;
2372 static unsigned short devid[9] = {
2373 0x8081, 0x8002, 0x8010, 0x8020, 0x8030, 0x8040, 0x8050, 0x8060, 0
2376 printk(KERN_INFO "aec671x_detect: \n");
2377 if (!pci_present()) {
2378 printk(KERN_INFO" NO PCI SUPPORT.\n");
2381 tpnt->proc_name = "atp870u";
2383 for (h = 0; h < 2; h++) {
2384 struct atp_unit *dev = &atp_unit[h];
2387 dev->id[k].prd_tableu = kmalloc(1024, GFP_KERNEL);
2388 dev->id[k].devspu=0x20;
2389 dev->id[k].devtypeu = 0;
2390 dev->id[k].curr_req = NULL;
2392 dev->active_idu = 0;
2394 dev->host_idu = 0x07;
2400 dev->last_cmd = 0xff;
2403 for (k = 0; k < qcnt; k++) {
2404 dev->querequ[k] = 0;
2406 for (k = 0; k < 16; k++) {
2407 dev->id[k].curr_req = 0;
2412 while (devid[h] != 0) {
2413 pdev[2] = pci_find_device(0x1191, devid[h], pdev[2]);
2414 if (pdev[2] == NULL || pci_enable_device(pdev[2])) {
2420 dev_id[2] = devid[h];
2422 if (devid[h] == 0x8002) {
2423 error = pci_read_config_byte(pdev[2], 0x08, &chip_ver[2]);
2424 if (chip_ver[2] < 2) {
2428 if (devid[h] == 0x8010 || devid[h] == 0x8081 || devid[h] == 0x8050)
2432 pdev[tmpcnt] = pdev[2];
2433 chip_ver[tmpcnt] = chip_ver[2];
2434 dev_id[tmpcnt] = dev_id[2];
2445 for (h = 0; h < 2; h++) {
2446 struct atp_unit *dev=&atp_unit[h];
2447 if (pdev[h]==NULL) {
2451 /* Found an atp870u/w. */
2452 base_io = pci_resource_start(pdev[h], 0);
2455 if (dev_id[h] != 0x8081)
2457 error = pci_read_config_byte(pdev[h],0x49,&host_id);
2459 base_io &= 0xfffffff8;
2461 if (check_region(base_io,0x40) != 0)
2465 printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-3 Host Adapter: %d IO:%x, IRQ:%d.\n"
2467 dev->ioport = base_io;
2468 dev->pciport = base_io + 0x20;
2469 dev->deviceid = dev_id[h];
2472 dev->host_idu = host_id;
2473 dev->chip_veru = chip_ver[h];
2475 tmport = base_io + 0x22;
2476 dev->scam_on = inb(tmport);
2478 dev->global_map = inb(tmport++);
2479 dev->ultra_map = inw(tmport);
2480 if (dev->ultra_map == 0) {
2481 dev->scam_on = 0x00;
2482 dev->global_map = 0x20;
2483 dev->ultra_map = 0xffff;
2485 shpnt = scsi_register(tpnt, 4);
2491 if (request_irq(irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", dev)) {
2492 printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n");
2496 if (chip_ver[h] > 0x07) /* check if atp876 chip */
2497 { /* then enable terminator */
2498 tmport = base_io + 0x3e;
2502 tmport = base_io + 0x3a;
2503 k = (inb(tmport) & 0xf3) | 0x10;
2505 outb((k & 0xdf), tmport);
2510 outb((host_id | 0x08), tmport);
2514 while ((inb(tmport) & 0x80) == 0);
2517 tmport = base_io + 1;
2520 tmport = base_io + 0x11;
2525 tmport = base_io + 0x3a;
2526 outb((inb(tmport) & 0xef), tmport);
2528 outb((inb(tmport) | 0x20),tmport);
2532 base_io &= 0xfffffff8;
2534 if (check_region(base_io,0x60) != 0)
2538 host_id = inb(base_io + 0x39);
2541 printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d IO:%x, IRQ:%d.\n"
2543 dev->ioport = base_io + 0x40;
2544 dev->pciport = base_io + 0x28;
2545 dev->deviceid = dev_id[h];
2547 dev->host_idu = host_id;
2548 dev->chip_veru = chip_ver[h];
2550 tmport = base_io + 0x22;
2551 dev->scam_on = inb(tmport);
2553 dev->global_map = inb(tmport);
2555 dev->ultra_map = inw(tmport);
2564 outw(n,base_io + 0x34);
2566 if (inb(base_io + 0x30) == 0xff)
2570 dev->sp[m++]=inb(base_io + 0x30);
2571 dev->sp[m++]=inb(base_io + 0x31);
2572 dev->sp[m++]=inb(base_io + 0x32);
2573 dev->sp[m++]=inb(base_io + 0x33);
2574 outw(n,base_io + 0x34);
2576 dev->sp[m++]=inb(base_io + 0x30);
2577 dev->sp[m++]=inb(base_io + 0x31);
2578 dev->sp[m++]=inb(base_io + 0x32);
2579 dev->sp[m++]=inb(base_io + 0x33);
2580 outw(n,base_io + 0x34);
2582 dev->sp[m++]=inb(base_io + 0x30);
2583 dev->sp[m++]=inb(base_io + 0x31);
2584 dev->sp[m++]=inb(base_io + 0x32);
2585 dev->sp[m++]=inb(base_io + 0x33);
2586 outw(n,base_io + 0x34);
2588 dev->sp[m++]=inb(base_io + 0x30);
2589 dev->sp[m++]=inb(base_io + 0x31);
2590 dev->sp[m++]=inb(base_io + 0x32);
2591 dev->sp[m++]=inb(base_io + 0x33);
2595 outw(0,base_io + 0x34);
2598 for (k=0; k < 16; k++)
2604 dev->ultra_map |= n;
2608 if (dev->sp[k] == 0)
2614 dev->async = ~(dev->async);
2615 outb(dev->global_map,base_io + 0x35);
2617 shpnt = scsi_register(tpnt, 4);
2623 if (request_irq(irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", dev)) {
2624 printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n");
2628 tmport = base_io + 0x38;
2629 k = inb(tmport) & 0x80;
2636 tmport = base_io + 0x5b;
2640 tmport = base_io + 0x40;
2641 outb((host_id | 0x08), tmport);
2645 while ((inb(tmport) & 0x80) == 0);
2648 tmport = base_io + 0x41;
2651 tmport = base_io + 0x51;
2656 tmport = base_io + 0x38;
2660 atp_host[h] = shpnt;
2661 if (dev->chip_veru == 4) {
2664 shpnt->this_id = host_id;
2665 shpnt->unique_id = base_io;
2666 shpnt->io_port = base_io;
2667 if (dev_id[h] == 0x8081)
2669 shpnt->n_io_port = 0x60; /* Number of bytes of I/O space used */
2673 shpnt->n_io_port = 0x40; /* Number of bytes of I/O space used */
2676 restore_flags(flags);
2677 if (dev_id[h] == 0x8081)
2679 request_region(base_io, 0x60, "atp870u"); /* Register the IO ports that we use */
2683 request_region(base_io, 0x40, "atp870u"); /* Register the IO ports that we use */
2689 scsi_unregister(shpnt);
2690 restore_flags(flags);
2698 /* The abort command does not leave the device in a clean state where
2699 it is available to be used again. Until this gets worked out, we will
2700 leave it commented out. */
2702 int atp870u_abort(Scsi_Cmnd * SCpnt)
2704 unsigned char h, j, k;
2705 Scsi_Cmnd *workrequ;
2706 unsigned int tmport;
2707 struct atp_unit *dev;
2708 for (h = 0; h <= admaxu; h++) {
2709 if (SCpnt->host == atp_host[h]) {
2713 panic("Abort host not found !");
2716 printk(KERN_DEBUG "working=%x last_cmd=%x ", dev->working, dev->last_cmd);
2717 printk(" quhdu=%x quendu=%x ", dev->quhdu, dev->quendu);
2718 tmport = dev->ioport;
2719 for (j = 0; j < 0x17; j++) {
2720 printk(" r%2x=%2x", j, inb(tmport++));
2723 printk(" r1c=%2x", inb(tmport));
2725 printk(" r1f=%2x in_snd=%2x ", inb(tmport), dev->in_snd);
2726 tmport= dev->pciport;
2727 printk(" r20=%2x", inb(tmport));
2729 printk(" r22=%2x", inb(tmport));
2730 tmport = dev->ioport + 0x3a;
2731 printk(" r3a=%2x \n",inb(tmport));
2732 tmport = dev->ioport + 0x3b;
2733 printk(" r3b=%2x \n",inb(tmport));
2736 if (dev->id[j].curr_req != NULL)
2738 workrequ = dev->id[j].curr_req;
2739 printk("\n que cdb= ");
2740 for (k=0; k < workrequ->cmd_len; k++)
2742 printk(" %2x ",workrequ->cmnd[k]);
2744 printk(" last_lenu= %lx ",dev->id[j].last_lenu);
2747 return (SCSI_ABORT_SNOOZE);
2750 int atp870u_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
2753 struct atp_unit *dev;
2755 * See if a bus reset was suggested.
2757 for (h = 0; h <= admaxu; h++) {
2758 if (SCpnt->host == atp_host[h]) {
2762 panic("Reset bus host not found !");
2765 /* SCpnt->result = 0x00080000;
2766 SCpnt->scsi_done(SCpnt);
2770 return (SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET); */
2771 return (SCSI_RESET_SNOOZE);
2774 const char *atp870u_info(struct Scsi_Host *notused)
2776 static char buffer[128];
2778 strcpy(buffer, "ACARD AEC-6710/6712/67160 PCI Ultra/W/LVD SCSI-3 Adapter Driver V2.6+ac ");
2783 int atp870u_set_info(char *buffer, int length, struct Scsi_Host *HBAptr)
2785 return -ENOSYS; /* Currently this is a no-op */
2788 #define BLS buffer + len + size
2789 int atp870u_proc_info(char *buffer, char **start, off_t offset, int length,
2790 int hostno, int inout)
2792 struct Scsi_Host *HBAptr;
2793 static u8 buff[512];
2801 for (i = 0; i < 2; i++) {
2802 if ((HBAptr = atp_host[i]) != NULL) {
2803 if (HBAptr->host_no == hostno) {
2810 if (HBAptr == NULL) {
2811 size += sprintf(BLS, "Can't find adapter for host number %d\n", hostno);
2817 if (inout == TRUE) { /* Has data been written to the file? */
2818 return (atp870u_set_info(buffer, length, HBAptr));
2821 memset(buff, 0, sizeof(buff));
2823 size += sprintf(BLS, "ACARD AEC-671X Driver Version: 2.6+ac\n");
2828 size += sprintf(BLS, "\n");
2829 size += sprintf(BLS, "Adapter Configuration:\n");
2830 size += sprintf(BLS, " Base IO: %#.4lx\n", HBAptr->io_port);
2831 size += sprintf(BLS, " IRQ: %d\n", HBAptr->irq);
2837 *start = buffer + (offset - begin); /* Start of wanted data */
2838 len -= (offset - begin); /* Start slop */
2840 len = length; /* Ending slop */
2847 int atp870u_biosparam(Scsi_Disk * disk, kdev_t dev, int *ip)
2849 int heads, sectors, cylinders;
2853 cylinders = disk->capacity / (heads * sectors);
2855 if (cylinders > 1024) {
2858 cylinders = disk->capacity / (heads * sectors);
2868 int atp870u_release (struct Scsi_Host *pshost)
2871 for (h = 0; h <= admaxu; h++)
2873 if (pshost == atp_host[h]) {
2875 free_irq (pshost->irq, &atp_unit[h]);
2876 release_region (pshost->io_port, pshost->n_io_port);
2877 scsi_unregister(pshost);
2879 kfree(atp_unit[h].id[k].prd_tableu);
2883 panic("atp870u: bad scsi host passed.\n");
2886 MODULE_LICENSE("GPL");
2888 static Scsi_Host_Template driver_template = ATP870U;
2889 #include "scsi_module.c"