File: /usr/src/linux/drivers/scsi/atp870u.c

1     /* $Id: atp870u.c,v 1.0 1997/05/07 15:22:00 root Exp root $
2      *  linux/kernel/atp870u.c
3      *
4      *  Copyright (C) 1997	Wu Ching Chen
5      *  2.1.x update (C) 1998  Krzysztof G. Baranowski
6      *
7      * Marcelo Tosatti <marcelo@conectiva.com.br> : SMP fixes
8      *
9      * Wu Ching Chen : NULL pointer fixes  2000/06/02
10      *		   support atp876 chip
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 (7.1)
15      */
16     
17     #include <linux/module.h>
18     
19     #include <linux/kernel.h>
20     #include <linux/types.h>
21     #include <linux/string.h>
22     #include <linux/ioport.h>
23     #include <linux/delay.h>
24     #include <linux/sched.h>
25     #include <linux/proc_fs.h>
26     #include <linux/spinlock.h>
27     #include <asm/system.h>
28     #include <asm/io.h>
29     #include <linux/pci.h>
30     #include <linux/blk.h>
31     #include "scsi.h"
32     #include "hosts.h"
33     
34     
35     #include "atp870u.h"
36     
37     #include<linux/stat.h>
38     
39     void mydlyu(unsigned int);
40     
41     /*
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 $";
43      */
44     
45     static unsigned char admaxu = 1;
46     static unsigned short int sync_idu;
47     
48     static unsigned int irqnumu[2] = {0, 0};
49     
50     struct atp_unit
51     {
52     	unsigned long ioport;
53     	unsigned long irq;
54     	unsigned long pciport;
55     	unsigned char last_cmd;
56     	unsigned char in_snd;
57     	unsigned char in_int;
58     	unsigned char quhdu;
59     	unsigned char quendu;
60     	unsigned char scam_on;
61     	unsigned char global_map;
62     	unsigned char chip_veru;
63     	unsigned char host_idu;
64     	int working;
65     	unsigned short wide_idu;
66     	unsigned short active_idu;
67     	unsigned short ultra_map;
68     	unsigned short async;
69     	unsigned short deviceid;
70     	unsigned char ata_cdbu[16];
71     	unsigned char sp[16];
72     	Scsi_Cmnd *querequ[qcnt];
73     	struct atp_id
74     	{
75     		unsigned char dirctu;
76     		unsigned char devspu;
77     		unsigned char devtypeu;
78     		unsigned long prdaddru;
79     		unsigned long tran_lenu;
80     		unsigned long last_lenu;
81     		unsigned char *prd_posu;
82     		unsigned char *prd_tableu;
83     		Scsi_Cmnd *curr_req;
84     	} id[16];
85     };
86     
87     static struct Scsi_Host *atp_host[2] = {NULL, NULL};
88     static struct atp_unit atp_unit[2];
89     
90     static void atp870u_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
91     {
92     	unsigned long flags;
93     	unsigned short int tmpcip, id;
94     	unsigned char i, j, h, target_id, lun;
95     	unsigned char *prd;
96     	Scsi_Cmnd *workrequ;
97     	unsigned int workportu, tmport;
98     	unsigned long adrcntu, k;
99     	int errstus;
100     	struct atp_unit *dev = dev_id;
101     
102     	for (h = 0; h < 2; h++) {
103     		if (irq == irqnumu[h]) {
104     			goto irq_numok;
105     		}
106     	}
107     	return;
108     irq_numok:
109     	dev->in_int = 1;
110     	workportu = dev->ioport;
111     	tmport = workportu;
112     
113     	if (dev->working != 0)
114     	{
115     		tmport += 0x1f;
116     		j = inb(tmport);
117     		if ((j & 0x80) == 0)
118     		{
119     			dev->in_int = 0;
120     			return;
121     		}
122     
123     		tmpcip = dev->pciport;
124     		if ((inb(tmpcip) & 0x08) != 0)
125     		{
126     			tmpcip += 0x2;
127     			for (k=0; k < 1000; k++)
128     			{
129     				if ((inb(tmpcip) & 0x08) == 0)
130     				{
131     					goto stop_dma;
132     				}
133     				if ((inb(tmpcip) & 0x01) == 0)
134     				{
135     					goto stop_dma;
136     				}
137     			}
138     		}
139     stop_dma:
140     		tmpcip = dev->pciport;
141     		outb(0x00, tmpcip);
142     		tmport -= 0x08;
143     
144     		i = inb(tmport);
145     
146     		tmport -= 0x02;
147     		target_id = inb(tmport);
148     		tmport += 0x02;
149     
150     		/*
151     		 *	Remap wide devices onto id numbers
152     		 */
153     
154     		if ((target_id & 0x40) != 0) {
155     			target_id = (target_id & 0x07) | 0x08;
156     		} else {
157     			target_id &= 0x07;
158     		}
159     
160     		if ((j & 0x40) != 0)
161     		{
162     		     if (dev->last_cmd == 0xff)
163     		     {
164     			dev->last_cmd = target_id;
165     		     }
166     		     dev->last_cmd |= 0x40;
167     		}
168     
169     		if (i == 0x85)
170     		{
171     			if ((dev->last_cmd & 0xf0) != 0x40)
172     			{
173     			   dev->last_cmd = 0xff;
174     			}
175     			/*
176     			 *	Flip wide
177     			 */
178     			if (dev->wide_idu != 0)
179     			{
180     				tmport = workportu + 0x1b;
181     				outb(0x01,tmport);
182     				while ((inb(tmport) & 0x01) != 0x01)
183     				{
184     				   outb(0x01,tmport);
185     				}
186     			}
187     			/*
188     			 *	Issue more commands
189     			 */
190     			if (((dev->quhdu != dev->quendu) || (dev->last_cmd != 0xff)) &&
191     			    (dev->in_snd == 0))
192     			{
193     				send_s870(h);
194     			}
195     			/*
196     			 *	Done
197     			 */
198     			dev->in_int = 0;
199     			return;
200     		}
201     
202     		if (i == 0x40)
203     		{
204     		     dev->last_cmd |= 0x40;
205     		     dev->in_int = 0;
206     		     return;
207     		}
208     
209     		if (i == 0x21)
210     		{
211     			if ((dev->last_cmd & 0xf0) != 0x40)
212     			{
213     			   dev->last_cmd = 0xff;
214     			}
215     			tmport -= 0x05;
216     			adrcntu = 0;
217     			((unsigned char *) &adrcntu)[2] = inb(tmport++);
218     			((unsigned char *) &adrcntu)[1] = inb(tmport++);
219     			((unsigned char *) &adrcntu)[0] = inb(tmport);
220     			k = dev->id[target_id].last_lenu;
221     			k -= adrcntu;
222     			dev->id[target_id].tran_lenu = k;
223     			dev->id[target_id].last_lenu = adrcntu;
224     			tmport -= 0x04;
225     			outb(0x41, tmport);
226     			tmport += 0x08;
227     			outb(0x08, tmport);
228     			dev->in_int = 0;
229     			return;
230     		}
231     		if ((i == 0x80) || (i == 0x8f))
232     		{
233     			lun = 0;
234     			tmport -= 0x07;
235     			j = inb(tmport);
236     			if (j == 0x44 || i==0x80) {
237     				tmport += 0x0d;
238     				lun = inb(tmport) & 0x07;
239     			} else {
240     				if ((dev->last_cmd & 0xf0) != 0x40)
241     				{
242     				   dev->last_cmd = 0xff;
243     				}
244     				if (j == 0x41)
245     				{
246     					tmport += 0x02;
247     					adrcntu = 0;
248     					((unsigned char *) &adrcntu)[2] = inb(tmport++);
249     					((unsigned char *) &adrcntu)[1] = inb(tmport++);
250     					((unsigned char *) &adrcntu)[0] = inb(tmport);
251     					k = dev->id[target_id].last_lenu;
252     					k -= adrcntu;
253     					dev->id[target_id].tran_lenu = k;
254     					dev->id[target_id].last_lenu = adrcntu;
255     					tmport += 0x04;
256     					outb(0x08, tmport);
257     					dev->in_int = 0;
258     					return;
259     				}
260     				else
261     				{
262     					outb(0x46, tmport);
263     					dev->id[target_id].dirctu = 0x00;
264     					tmport += 0x02;
265     					outb(0x00, tmport++);
266     					outb(0x00, tmport++);
267     					outb(0x00, tmport++);
268     					tmport += 0x03;
269     					outb(0x08, tmport);
270     					dev->in_int = 0;
271     					return;
272     				}
273     			}
274     			if (dev->last_cmd != 0xff)
275     			{
276     			   dev->last_cmd |= 0x40;
277     			}
278     			tmport = workportu + 0x10;
279     			outb(0x45, tmport);
280     			tmport += 0x06;
281     			target_id = inb(tmport);
282     			/*
283     			 *	Remap wide identifiers
284     			 */
285     			if ((target_id & 0x10) != 0)
286     			{
287     				target_id = (target_id & 0x07) | 0x08;
288     			} else {
289     				target_id &= 0x07;
290     			}
291     			workrequ = dev->id[target_id].curr_req;
292     			tmport = workportu + 0x0f;
293     			outb(lun, tmport);
294     			tmport += 0x02;
295     			outb(dev->id[target_id].devspu, tmport++);
296     			adrcntu = dev->id[target_id].tran_lenu;
297     			k = dev->id[target_id].last_lenu;
298     			outb(((unsigned char *) &k)[2], tmport++);
299     			outb(((unsigned char *) &k)[1], tmport++);
300     			outb(((unsigned char *) &k)[0], tmport++);
301     			/* Remap wide */
302     			j = target_id;
303     			if (target_id > 7) {
304     				j = (j & 0x07) | 0x40;
305     			}
306     			/* Add direction */
307     			j |= dev->id[target_id].dirctu;
308     			outb(j, tmport++);
309     			outb(0x80, tmport);
310     
311     			/* enable 32 bit fifo transfer */
312     			if (dev->deviceid != 0x8081)
313     			{
314     			   tmport = workportu + 0x3a;
315     			   if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) ||
316     			       (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a))
317     			   {
318     			      outb((unsigned char)((inb(tmport) & 0xf3) | 0x08),tmport);
319     			   }
320     			   else
321     			   {
322     			      outb((unsigned char)(inb(tmport) & 0xf3),tmport);
323     			   }
324     			}
325     			else
326     			{
327     			   tmport = workportu - 0x05;
328     			   if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) ||
329     			       (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a))
330     			   {
331     			      outb((unsigned char)((inb(tmport) & 0x3f) | 0xc0),tmport);
332     			   }
333     			   else
334     			   {
335     			      outb((unsigned char)(inb(tmport) & 0x3f),tmport);
336     			   }
337     			}
338     
339     			tmport = workportu + 0x1b;
340     			j = 0;
341     			id = 1;
342     			id = id << target_id;
343     			/*
344     			 *	Is this a wide device
345     			 */
346     			if ((id & dev->wide_idu) != 0) {
347     				j |= 0x01;
348     			}
349     			outb(j, tmport);
350     			while ((inb(tmport) & 0x01) != j)
351     			{
352     			   outb(j,tmport);
353     			}
354     
355     			if (dev->id[target_id].last_lenu == 0) {
356     				tmport = workportu + 0x18;
357     				outb(0x08, tmport);
358     				dev->in_int = 0;
359     				return;
360     			}
361     			prd = dev->id[target_id].prd_posu;
362     			while (adrcntu != 0)
363     			{
364     				id = ((unsigned short int *) (prd))[2];
365     				if (id == 0) {
366     					k = 0x10000;
367     				} else {
368     					k = id;
369     				}
370     				if (k > adrcntu) {
371     					((unsigned short int *) (prd))[2] = (unsigned short int)
372     					    (k - adrcntu);
373     					((unsigned long *) (prd))[0] += adrcntu;
374     					adrcntu = 0;
375     					dev->id[target_id].prd_posu = prd;
376     				} else {
377     					adrcntu -= k;
378     					dev->id[target_id].prdaddru += 0x08;
379     					prd += 0x08;
380     					if (adrcntu == 0) {
381     						dev->id[target_id].prd_posu = prd;
382     					}
383     				}
384     			}
385     			tmpcip = dev->pciport + 0x04;
386     			outl(dev->id[target_id].prdaddru, tmpcip);
387     			tmpcip -= 0x02;
388     			outb(0x06, tmpcip);
389     			outb(0x00, tmpcip);
390     			tmpcip -= 0x02;
391     			tmport = workportu + 0x18;
392     			/*
393     			 *	Check transfer direction
394     			 */
395     			if (dev->id[target_id].dirctu != 0) {
396     				outb(0x08, tmport);
397     				outb(0x01, tmpcip);
398     				dev->in_int = 0;
399     				return;
400     			}
401     			outb(0x08, tmport);
402     			outb(0x09, tmpcip);
403     			dev->in_int = 0;
404     			return;
405     		}
406     
407     		/*
408     		 *	Current scsi request on this target
409     		 */
410     
411     		workrequ = dev->id[target_id].curr_req;
412     
413     		if (i == 0x42) {
414     			if ((dev->last_cmd & 0xf0) != 0x40)
415     			{
416     			   dev->last_cmd = 0xff;
417     			}
418     			errstus = 0x02;
419     			workrequ->result = errstus;
420     			goto go_42;
421     		}
422     		if (i == 0x16)
423     		{
424     			if ((dev->last_cmd & 0xf0) != 0x40)
425     			{
426     			   dev->last_cmd = 0xff;
427     			}
428     			errstus = 0;
429     			tmport -= 0x08;
430     			errstus = inb(tmport);
431     			workrequ->result = errstus;
432     go_42:
433     			/*
434     			 *	Complete the command
435     			 */
436     			spin_lock_irqsave(&io_request_lock, flags);
437     			(*workrequ->scsi_done) (workrequ);
438     
439     			/*
440     			 *	Clear it off the queue
441     			 */
442     			dev->id[target_id].curr_req = 0;
443     			dev->working--;
444     			spin_unlock_irqrestore(&io_request_lock, flags);
445     			/*
446     			 *	Take it back wide
447     			 */
448     			if (dev->wide_idu != 0) {
449     				tmport = workportu + 0x1b;
450     				outb(0x01,tmport);
451     				while ((inb(tmport) & 0x01) != 0x01)
452     				{
453     				   outb(0x01,tmport);
454     				}
455     			}
456     			/*
457     			 *	If there is stuff to send and nothing going then send it
458     			 */
459     			if (((dev->last_cmd != 0xff) || (dev->quhdu != dev->quendu)) &&
460     			    (dev->in_snd == 0))
461     			{
462     			   send_s870(h);
463     			}
464     			dev->in_int = 0;
465     			return;
466     		}
467     		if ((dev->last_cmd & 0xf0) != 0x40)
468     		{
469     		   dev->last_cmd = 0xff;
470     		}
471     		if (i == 0x4f) {
472     			i = 0x89;
473     		}
474     		i &= 0x0f;
475     		if (i == 0x09) {
476     			tmpcip = tmpcip + 4;
477     			outl(dev->id[target_id].prdaddru, tmpcip);
478     			tmpcip = tmpcip - 2;
479     			outb(0x06, tmpcip);
480     			outb(0x00, tmpcip);
481     			tmpcip = tmpcip - 2;
482     			tmport = workportu + 0x10;
483     			outb(0x41, tmport);
484     			dev->id[target_id].dirctu = 0x00;
485     			tmport += 0x08;
486     			outb(0x08, tmport);
487     			outb(0x09, tmpcip);
488     			dev->in_int = 0;
489     			return;
490     		}
491     		if (i == 0x08) {
492     			tmpcip = tmpcip + 4;
493     			outl(dev->id[target_id].prdaddru, tmpcip);
494     			tmpcip = tmpcip - 2;
495     			outb(0x06, tmpcip);
496     			outb(0x00, tmpcip);
497     			tmpcip = tmpcip - 2;
498     			tmport = workportu + 0x10;
499     			outb(0x41, tmport);
500     			tmport += 0x05;
501     			outb((unsigned char) (inb(tmport) | 0x20), tmport);
502     			dev->id[target_id].dirctu = 0x20;
503     			tmport += 0x03;
504     			outb(0x08, tmport);
505     			outb(0x01, tmpcip);
506     			dev->in_int = 0;
507     			return;
508     		}
509     		tmport -= 0x07;
510     		if (i == 0x0a) {
511     			outb(0x30, tmport);
512     		} else {
513     			outb(0x46, tmport);
514     		}
515     		dev->id[target_id].dirctu = 0x00;
516     		tmport += 0x02;
517     		outb(0x00, tmport++);
518     		outb(0x00, tmport++);
519     		outb(0x00, tmport++);
520     		tmport += 0x03;
521     		outb(0x08, tmport);
522     		dev->in_int = 0;
523     		return;
524     	} else {
525     //		tmport = workportu + 0x17;
526     //		inb(tmport);
527     //		dev->working = 0;
528     		dev->in_int = 0;
529     		return;
530     	}
531     }
532     
533     int atp870u_queuecommand(Scsi_Cmnd * req_p, void (*done) (Scsi_Cmnd *))
534     {
535     	unsigned char h;
536     	unsigned long flags;
537     	unsigned short int m;
538     	unsigned int tmport;
539     	struct atp_unit *dev;
540     
541     	for (h = 0; h <= admaxu; h++) {
542     		if (req_p->host == atp_host[h]) {
543     			goto host_ok;
544     		}
545     	}
546     	return 0;
547     host_ok:
548     	if (req_p->channel != 0) {
549     		req_p->result = 0x00040000;
550     		done(req_p);
551     		return 0;
552     	}
553     	dev = &atp_unit[h];
554     	m = 1;
555     	m = m << req_p->target;
556     
557     	/*
558     	 *	Fake a timeout for missing targets
559     	 */
560     
561     	if ((m & dev->active_idu) == 0) {
562     		req_p->result = 0x00040000;
563     		done(req_p);
564     		return 0;
565     	}
566     	if (done) {
567     		req_p->scsi_done = done;
568     	} else {
569     		printk(KERN_WARNING "atp870u_queuecommand: done can't be NULL\n");
570     		req_p->result = 0;
571     		done(req_p);
572     		return 0;
573     	}
574     	/*
575     	 *	Count new command
576     	 */
577     	save_flags(flags);
578     	cli();
579     	dev->quendu++;
580     	if (dev->quendu >= qcnt) {
581     		dev->quendu = 0;
582     	}
583     	/*
584     	 *	Check queue state
585     	 */
586     	if (dev->quhdu == dev->quendu) {
587     		if (dev->quendu == 0) {
588     			dev->quendu = qcnt;
589     		}
590     		dev->quendu--;
591     		req_p->result = 0x00020000;
592     		done(req_p);
593     		restore_flags(flags);
594     		return 0;
595     	}
596     	dev->querequ[dev->quendu] = req_p;
597     	tmport = dev->ioport + 0x1c;
598     	restore_flags(flags);
599     	if ((inb(tmport) == 0) && (dev->in_int == 0) && (dev->in_snd == 0)) {
600     		send_s870(h);
601     	}
602     	return 0;
603     }
604     
605     void mydlyu(unsigned int dlycnt)
606     {
607     	unsigned int i;
608     	for (i = 0; i < dlycnt; i++) {
609     		inb(0x80);
610     	}
611     }
612     
613     void send_s870(unsigned char h)
614     {
615     	unsigned int tmport;
616     	Scsi_Cmnd *workrequ;
617     	unsigned long flags;
618     	unsigned int i;
619     	unsigned char j, target_id;
620     	unsigned char *prd;
621     	unsigned short int tmpcip, w;
622     	unsigned long l, bttl;
623     	unsigned int workportu;
624     	struct scatterlist *sgpnt;
625     	struct atp_unit *dev = &atp_unit[h];
626     
627     	save_flags(flags);
628     	cli();
629     	if (dev->in_snd != 0) {
630     		restore_flags(flags);
631     		return;
632     	}
633     	dev->in_snd = 1;
634     	if ((dev->last_cmd != 0xff) && ((dev->last_cmd & 0x40) != 0)) {
635     		dev->last_cmd &= 0x0f;
636     		workrequ = dev->id[dev->last_cmd].curr_req;
637     		if (workrequ != NULL)	     /* check NULL pointer */
638     		{
639     		   goto cmd_subp;
640     		}
641     		dev->last_cmd = 0xff;
642     		if (dev->quhdu == dev->quendu)
643     		{
644     		   dev->in_snd = 0;
645     		   restore_flags(flags);
646     		   return ;
647     		}
648     	}
649     	if ((dev->last_cmd != 0xff) && (dev->working != 0))
650     	{
651     	     dev->in_snd = 0;
652     	     restore_flags(flags);
653     	     return ;
654     	}
655     	dev->working++;
656     	j = dev->quhdu;
657     	dev->quhdu++;
658     	if (dev->quhdu >= qcnt) {
659     		dev->quhdu = 0;
660     	}
661     	workrequ = dev->querequ[dev->quhdu];
662     	if (dev->id[workrequ->target].curr_req == 0) {
663     		dev->id[workrequ->target].curr_req = workrequ;
664     		dev->last_cmd = workrequ->target;
665     		goto cmd_subp;
666     	}
667     	dev->quhdu = j;
668     	dev->working--;
669     	dev->in_snd = 0;
670     	restore_flags(flags);
671     	return;
672     cmd_subp:
673     	workportu = dev->ioport;
674     	tmport = workportu + 0x1f;
675     	if ((inb(tmport) & 0xb0) != 0) {
676     		goto abortsnd;
677     	}
678     	tmport = workportu + 0x1c;
679     	if (inb(tmport) == 0) {
680     		goto oktosend;
681     	}
682     abortsnd:
683     	dev->last_cmd |= 0x40;
684     	dev->in_snd = 0;
685     	restore_flags(flags);
686     	return;
687     oktosend:
688     	memcpy(&dev->ata_cdbu[0], &workrequ->cmnd[0], workrequ->cmd_len);
689     	if (dev->ata_cdbu[0] == READ_CAPACITY) {
690     		if (workrequ->request_bufflen > 8) {
691     			workrequ->request_bufflen = 0x08;
692     		}
693     	}
694     	if (dev->ata_cdbu[0] == 0x00) {
695     		workrequ->request_bufflen = 0;
696     	}
697     
698     	tmport = workportu + 0x1b;
699     	j = 0;
700     	target_id = workrequ->target;
701     
702     	/*
703     	 *	Wide ?
704     	 */
705     	w = 1;
706     	w = w << target_id;
707     	if ((w & dev->wide_idu) != 0) {
708     		j |= 0x01;
709     	}
710     	outb(j, tmport);
711     	while ((inb(tmport) & 0x01) != j)
712     	{
713     	   outb(j,tmport);
714     	}
715     
716     	/*
717     	 *	Write the command
718     	 */
719     
720     	tmport = workportu;
721     	outb(workrequ->cmd_len, tmport++);
722     	outb(0x2c, tmport++);
723     	outb(0xcf, tmport++);
724     	for (i = 0; i < workrequ->cmd_len; i++) {
725     		outb(dev->ata_cdbu[i], tmport++);
726     	}
727     	tmport = workportu + 0x0f;
728     	outb(workrequ->lun, tmport);
729     	tmport += 0x02;
730     	/*
731     	 *	Write the target
732     	 */
733     	outb(dev->id[target_id].devspu, tmport++);
734     
735     	/*
736     	 *	Figure out the transfer size
737     	 */
738     	if (workrequ->use_sg)
739     	{
740     		l = 0;
741     		sgpnt = (struct scatterlist *) workrequ->request_buffer;
742     		for (i = 0; i < workrequ->use_sg; i++)
743     		{
744     			if (sgpnt[i].length == 0 || workrequ->use_sg > ATP870U_SCATTER)
745     			{
746     				panic("Foooooooood fight!");
747     			}
748     			l += sgpnt[i].length;
749     		}
750     	} else {
751     		l = workrequ->request_bufflen;
752     	}
753     	/*
754     	 *	Write transfer size
755     	 */
756     	outb((unsigned char) (((unsigned char *) (&l))[2]), tmport++);
757     	outb((unsigned char) (((unsigned char *) (&l))[1]), tmport++);
758     	outb((unsigned char) (((unsigned char *) (&l))[0]), tmport++);
759     	j = target_id;
760     	dev->id[j].last_lenu = l;
761     	dev->id[j].tran_lenu = 0;
762     	/*
763     	 *	Flip the wide bits
764     	 */
765     	if ((j & 0x08) != 0) {
766     		j = (j & 0x07) | 0x40;
767     	}
768     	/*
769     	 *	Check transfer direction
770     	 */
771     	if ((dev->ata_cdbu[0] == WRITE_6) || (dev->ata_cdbu[0] == WRITE_10) ||
772     	    (dev->ata_cdbu[0] == WRITE_12) || (dev->ata_cdbu[0] == MODE_SELECT)) {
773     		outb((unsigned char) (j | 0x20), tmport++);
774     	} else {
775     		outb(j, tmport++);
776     	}
777     	outb((unsigned char)(inb(tmport) | 0x80),tmport);
778     	outb(0x80, tmport);
779     	tmport = workportu + 0x1c;
780     	dev->id[target_id].dirctu = 0;
781     	if (l == 0) {
782     		if (inb(tmport) == 0) {
783     			tmport = workportu + 0x18;
784     			outb(0x08, tmport);
785     		} else {
786     			dev->last_cmd |= 0x40;
787     		}
788     		dev->in_snd = 0;
789     		restore_flags(flags);
790     		return;
791     	}
792     	tmpcip = dev->pciport;
793     	prd = dev->id[target_id].prd_tableu;
794     	dev->id[target_id].prd_posu = prd;
795     
796     	/*
797     	 *	Now write the request list. Either as scatter/gather or as
798     	 *	a linear chain.
799     	 */
800     
801     	if (workrequ->use_sg)
802     	{
803     		sgpnt = (struct scatterlist *) workrequ->request_buffer;
804     		i = 0;
805     		for (j = 0; j < workrequ->use_sg; j++) {
806     			(unsigned long) (((unsigned long *) (prd))[i >> 1]) = virt_to_bus(sgpnt[j].address);
807     			(unsigned short int) (((unsigned short int *) (prd))[i + 2]) = sgpnt[j].length;
808     			(unsigned short int) (((unsigned short int *) (prd))[i + 3]) = 0;
809     			i += 0x04;
810     		}
811     		(unsigned short int) (((unsigned short int *) (prd))[i - 1]) = 0x8000;
812     	} else {
813     		/*
814     		 *	For a linear request write a chain of blocks
815     		 */
816     		bttl = virt_to_bus(workrequ->request_buffer);
817     		l = workrequ->request_bufflen;
818     		i = 0;
819     		while (l > 0x10000) {
820     			(unsigned short int) (((unsigned short int *) (prd))[i + 3]) = 0x0000;
821     			(unsigned short int) (((unsigned short int *) (prd))[i + 2]) = 0x0000;
822     			(unsigned long) (((unsigned long *) (prd))[i >> 1]) = bttl;
823     			l -= 0x10000;
824     			bttl += 0x10000;
825     			i += 0x04;
826     		}
827     		(unsigned short int) (((unsigned short int *) (prd))[i + 3]) = 0x8000;
828     		(unsigned short int) (((unsigned short int *) (prd))[i + 2]) = l;
829     		(unsigned long) (((unsigned long *) (prd))[i >> 1]) = bttl;
830     	}
831     	tmpcip = tmpcip + 4;
832     	dev->id[target_id].prdaddru = virt_to_bus(dev->id[target_id].prd_tableu);
833     	outl(dev->id[target_id].prdaddru, tmpcip);
834     	tmpcip = tmpcip - 2;
835     	outb(0x06, tmpcip);
836     	outb(0x00, tmpcip);
837     	tmpcip = tmpcip - 2;
838     
839     	if (dev->deviceid != 0x8081)
840     	{
841     	   tmport = workportu + 0x3a;
842     	   if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) ||
843     	       (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a))
844     	   {
845     	      outb((unsigned char)((inb(tmport) & 0xf3) | 0x08),tmport);
846     	   }
847     	   else
848     	   {
849     	      outb((unsigned char)(inb(tmport) & 0xf3),tmport);
850     	   }
851     	}
852     	else
853     	{
854     	   tmport = workportu - 0x05;
855     	   if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) ||
856     	       (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a))
857     	   {
858     	      outb((unsigned char)((inb(tmport) & 0x3f) | 0xc0),tmport);
859     	   }
860     	   else
861     	   {
862     	      outb((unsigned char)(inb(tmport) & 0x3f),tmport);
863     	   }
864     	}
865     	tmport = workportu + 0x1c;
866     
867     	if ((dev->ata_cdbu[0] == WRITE_6) || (dev->ata_cdbu[0] == WRITE_10) ||
868     	    (dev->ata_cdbu[0] == WRITE_12) || (dev->ata_cdbu[0] == MODE_SELECT))
869     	{
870     		dev->id[target_id].dirctu = 0x20;
871     		if (inb(tmport) == 0) {
872     			tmport = workportu + 0x18;
873     			outb(0x08, tmport);
874     			outb(0x01, tmpcip);
875     		} else {
876     			dev->last_cmd |= 0x40;
877     		}
878     		dev->in_snd = 0;
879     		restore_flags(flags);
880     		return;
881     	}
882     	if (inb(tmport) == 0)
883     	{
884     		tmport = workportu + 0x18;
885     		outb(0x08, tmport);
886     		outb(0x09, tmpcip);
887     	} else {
888     		dev->last_cmd |= 0x40;
889     	}
890     	dev->in_snd = 0;
891     	restore_flags(flags);
892     	return;
893     
894     }
895     
896     static void internal_done(Scsi_Cmnd * SCpnt)
897     {
898     	SCpnt->SCp.Status++;
899     }
900     
901     int atp870u_command(Scsi_Cmnd * SCpnt)
902     {
903     
904     	atp870u_queuecommand(SCpnt, internal_done);
905     
906     	SCpnt->SCp.Status = 0;
907     	while (!SCpnt->SCp.Status)
908     		barrier();
909     	return SCpnt->result;
910     }
911     
912     unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val)
913     {
914     	unsigned int tmport;
915     	unsigned short int i, k;
916     	unsigned char j;
917     
918     	tmport = dev->ioport + 0x1c;
919     	outw(*val, tmport);
920     FUN_D7:
921     	for (i = 0; i < 10; i++) {	/* stable >= bus settle delay(400 ns)  */
922     		k = inw(tmport);
923     		j = (unsigned char) (k >> 8);
924     		if ((k & 0x8000) != 0) {	/* DB7 all release?    */
925     			goto FUN_D7;
926     		}
927     	}
928     	*val |= 0x4000; 	/* assert DB6		*/
929     	outw(*val, tmport);
930     	*val &= 0xdfff; 	/* assert DB5		*/
931     	outw(*val, tmport);
932     FUN_D5:
933     	for (i = 0; i < 10; i++) {	/* stable >= bus settle delay(400 ns) */
934     		if ((inw(tmport) & 0x2000) != 0) {	/* DB5 all release?	  */
935     			goto FUN_D5;
936     		}
937     	}
938     	*val |= 0x8000; 	/* no DB4-0, assert DB7    */
939     	*val &= 0xe0ff;
940     	outw(*val, tmport);
941     	*val &= 0xbfff; 	/* release DB6		   */
942     	outw(*val, tmport);
943           FUN_D6:
944     	for (i = 0; i < 10; i++) {	/* stable >= bus settle delay(400 ns)  */
945     		if ((inw(tmport) & 0x4000) != 0) {	/* DB6 all release?  */
946     			goto FUN_D6;
947     		}
948     	}
949     
950     	return j;
951     }
952     
953     void tscam(unsigned char host)
954     {
955     
956     	unsigned int tmport;
957     	unsigned char i, j, k;
958     	unsigned long n;
959     	unsigned short int m, assignid_map, val;
960     	unsigned char mbuf[33], quintet[2];
961     	struct atp_unit *dev = &atp_unit[host];
962     	static unsigned char g2q_tab[8] = {
963     		0x38, 0x31, 0x32, 0x2b, 0x34, 0x2d, 0x2e, 0x27
964     	};
965     
966     
967     	for (i = 0; i < 0x10; i++) {
968     		mydlyu(0xffff);
969     	}
970     
971     	tmport = dev->ioport + 1;
972     	outb(0x08, tmport++);
973     	outb(0x7f, tmport);
974     	tmport = dev->ioport + 0x11;
975     	outb(0x20, tmport);
976     
977     	if ((dev->scam_on & 0x40) == 0) {
978     		return;
979     	}
980     	m = 1;
981     	m <<= dev->host_idu;
982     	j = 16;
983     	if (dev->chip_veru < 4) {
984     		m |= 0xff00;
985     		j = 8;
986     	}
987     	assignid_map = m;
988     	tmport = dev->ioport + 0x02;
989     	outb(0x02, tmport++);	/* 2*2=4ms,3EH 2/32*3E=3.9ms */
990     	outb(0, tmport++);
991     	outb(0, tmport++);
992     	outb(0, tmport++);
993     	outb(0, tmport++);
994     	outb(0, tmport++);
995     	outb(0, tmport++);
996     
997     	for (i = 0; i < j; i++) {
998     		m = 1;
999     		m = m << i;
1000     		if ((m & assignid_map) != 0) {
1001     			continue;
1002     		}
1003     		tmport = dev->ioport + 0x0f;
1004     		outb(0, tmport++);
1005     		tmport += 0x02;
1006     		outb(0, tmport++);
1007     		outb(0, tmport++);
1008     		outb(0, tmport++);
1009     		if (i > 7) {
1010     			k = (i & 0x07) | 0x40;
1011     		} else {
1012     			k = i;
1013     		}
1014     		outb(k, tmport++);
1015     		tmport = dev->ioport + 0x1b;
1016     		if (dev->chip_veru == 4) {
1017     			outb(0x01, tmport);
1018     		} else {
1019     			outb(0x00, tmport);
1020     		}
1021     wait_rdyok:
1022     		tmport = dev->ioport + 0x18;
1023     		outb(0x09, tmport);
1024     		tmport += 0x07;
1025     
1026     		while ((inb(tmport) & 0x80) == 0x00);
1027     		tmport -= 0x08;
1028     		k = inb(tmport);
1029     		if (k != 0x16) {
1030     			if ((k == 0x85) || (k == 0x42)) {
1031     				continue;
1032     			}
1033     			tmport = dev->ioport + 0x10;
1034     			outb(0x41, tmport);
1035     			goto wait_rdyok;
1036     		}
1037     		assignid_map |= m;
1038     
1039     	}
1040     	tmport = dev->ioport + 0x02;
1041     	outb(0x7f, tmport);
1042     	tmport = dev->ioport + 0x1b;
1043     	outb(0x02, tmport);
1044     
1045     	outb(0, 0x80);
1046     
1047     	val = 0x0080;		/* bsy	*/
1048     	tmport = dev->ioport + 0x1c;
1049     	outw(val, tmport);
1050     	val |= 0x0040;		/* sel	*/
1051     	outw(val, tmport);
1052     	val |= 0x0004;		/* msg	*/
1053     	outw(val, tmport);
1054     	inb(0x80);		/* 2 deskew delay(45ns*2=90ns) */
1055     	val &= 0x007f;		/* no bsy  */
1056     	outw(val, tmport);
1057     	mydlyu(0xffff); 	/* recommanded SCAM selection response time */
1058     	mydlyu(0xffff);
1059     	val &= 0x00fb;		/* after 1ms no msg */
1060     	outw(val, tmport);
1061     wait_nomsg:
1062     	if ((inb(tmport) & 0x04) != 0) {
1063     		goto wait_nomsg;
1064     	}
1065     	outb(1, 0x80);
1066     	mydlyu(100);
1067     	for (n = 0; n < 0x30000; n++) {
1068     		if ((inb(tmport) & 0x80) != 0) {	/* bsy ? */
1069     			goto wait_io;
1070     		}
1071     	}
1072     	goto TCM_SYNC;
1073     wait_io:
1074     	for (n = 0; n < 0x30000; n++) {
1075     		if ((inb(tmport) & 0x81) == 0x0081) {
1076     			goto wait_io1;
1077     		}
1078     	}
1079     	goto TCM_SYNC;
1080     wait_io1:
1081     	inb(0x80);
1082     	val |= 0x8003;		/* io,cd,db7  */
1083     	outw(val, tmport);
1084     	inb(0x80);
1085     	val &= 0x00bf;		/* no sel     */
1086     	outw(val, tmport);
1087     	outb(2, 0x80);
1088     TCM_SYNC:
1089     	mydlyu(0x800);
1090     	if ((inb(tmport) & 0x80) == 0x00) {	/* bsy ? */
1091     		outw(0, tmport--);
1092     		outb(0, tmport);
1093     		tmport = dev->ioport + 0x15;
1094     		outb(0, tmport);
1095     		tmport += 0x03;
1096     		outb(0x09, tmport);
1097     		tmport += 0x07;
1098     		while ((inb(tmport) & 0x80) == 0);
1099     		tmport -= 0x08;
1100     		inb(tmport);
1101     		return;
1102     	}
1103     	val &= 0x00ff;		/* synchronization  */
1104     	val |= 0x3f00;
1105     	fun_scam(dev, &val);
1106     	outb(3, 0x80);
1107     	val &= 0x00ff;		/* isolation	    */
1108     	val |= 0x2000;
1109     	fun_scam(dev, &val);
1110     	outb(4, 0x80);
1111     	i = 8;
1112     	j = 0;
1113     TCM_ID:
1114     	if ((inw(tmport) & 0x2000) == 0) {
1115     		goto TCM_ID;
1116     	}
1117     	outb(5, 0x80);
1118     	val &= 0x00ff;		/* get ID_STRING */
1119     	val |= 0x2000;
1120     	k = fun_scam(dev, &val);
1121     	if ((k & 0x03) == 0) {
1122     		goto TCM_5;
1123     	}
1124     	mbuf[j] <<= 0x01;
1125     	mbuf[j] &= 0xfe;
1126     	if ((k & 0x02) != 0) {
1127     		mbuf[j] |= 0x01;
1128     	}
1129     	i--;
1130     	if (i > 0) {
1131     		goto TCM_ID;
1132     	}
1133     	j++;
1134     	i = 8;
1135     	goto TCM_ID;
1136     
1137     TCM_5:			/* isolation complete..  */
1138     /*    mbuf[32]=0;
1139     	printk(" \n%x %x %x %s\n ",assignid_map,mbuf[0],mbuf[1],&mbuf[2]); */
1140     	i = 15;
1141     	j = mbuf[0];
1142     	if ((j & 0x20) != 0) {	/* bit5=1:ID upto 7	 */
1143     		i = 7;
1144     	}
1145     	if ((j & 0x06) == 0) {	/* IDvalid?		*/
1146     		goto G2Q5;
1147     	}
1148     	k = mbuf[1];
1149     small_id:
1150     	m = 1;
1151     	m <<= k;
1152     	if ((m & assignid_map) == 0) {
1153     		goto G2Q_QUIN;
1154     	}
1155     	if (k > 0) {
1156     		k--;
1157     		goto small_id;
1158     	}
1159     G2Q5:				/* srch from max acceptable ID#  */
1160     	k = i;			/* max acceptable ID#		 */
1161     G2Q_LP:
1162     	m = 1;
1163     	m <<= k;
1164     	if ((m & assignid_map) == 0) {
1165     		goto G2Q_QUIN;
1166     	}
1167     	if (k > 0) {
1168     		k--;
1169     		goto G2Q_LP;
1170     	}
1171     G2Q_QUIN:		/* k=binID#,	   */
1172     	assignid_map |= m;
1173     	if (k < 8) {
1174     		quintet[0] = 0x38;	/* 1st dft ID<8    */
1175     	} else {
1176     		quintet[0] = 0x31;	/* 1st	ID>=8	   */
1177     	}
1178     	k &= 0x07;
1179     	quintet[1] = g2q_tab[k];
1180     
1181     	val &= 0x00ff;		/* AssignID 1stQuintet,AH=001xxxxx  */
1182     	m = quintet[0] << 8;
1183     	val |= m;
1184     	fun_scam(dev, &val);
1185     	val &= 0x00ff;		/* AssignID 2ndQuintet,AH=001xxxxx */
1186     	m = quintet[1] << 8;
1187     	val |= m;
1188     	fun_scam(dev, &val);
1189     
1190     	goto TCM_SYNC;
1191     
1192     }
1193     
1194     void is870(unsigned long host, unsigned int wkport)
1195     {
1196     	unsigned int tmport;
1197     	unsigned char i, j, k, rmb, n;
1198     	unsigned short int m;
1199     	static unsigned char mbuf[512];
1200     	static unsigned char satn[9] =	{0, 0, 0, 0, 0, 0, 0, 6, 6};
1201     	static unsigned char inqd[9] =	{0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6};
1202     	static unsigned char synn[6] =	{0x80, 1, 3, 1, 0x19, 0x0e};
1203     	static unsigned char synu[6] =	{0x80, 1, 3, 1, 0x0c, 0x0e};
1204     	static unsigned char synw[6] =	{0x80, 1, 3, 1, 0x0c, 0x07};
1205     	static unsigned char wide[6] =	{0x80, 1, 2, 3, 1, 0};
1206     	struct atp_unit *dev = &atp_unit[host];
1207     
1208     	sync_idu = 0;
1209     	tmport = wkport + 0x3a;
1210     	outb((unsigned char) (inb(tmport) | 0x10), tmport);
1211     
1212     	for (i = 0; i < 16; i++) {
1213     		if ((dev->chip_veru != 4) && (i > 7)) {
1214     			break;
1215     		}
1216     		m = 1;
1217     		m = m << i;
1218     		if ((m & dev->active_idu) != 0) {
1219     			continue;
1220     		}
1221     		if (i == dev->host_idu) {
1222     			printk(KERN_INFO "         ID: %2d  Host Adapter\n", dev->host_idu);
1223     			continue;
1224     		}
1225     		tmport = wkport + 0x1b;
1226     		if (dev->chip_veru == 4) {
1227     		   outb(0x01, tmport);
1228     		}
1229     		else
1230     		{
1231     		   outb(0x00, tmport);
1232     		}
1233     		tmport = wkport + 1;
1234     		outb(0x08, tmport++);
1235     		outb(0x7f, tmport++);
1236     		outb(satn[0], tmport++);
1237     		outb(satn[1], tmport++);
1238     		outb(satn[2], tmport++);
1239     		outb(satn[3], tmport++);
1240     		outb(satn[4], tmport++);
1241     		outb(satn[5], tmport++);
1242     		tmport += 0x06;
1243     		outb(0, tmport);
1244     		tmport += 0x02;
1245     		outb(dev->id[i].devspu, tmport++);
1246     		outb(0, tmport++);
1247     		outb(satn[6], tmport++);
1248     		outb(satn[7], tmport++);
1249     		j = i;
1250     		if ((j & 0x08) != 0) {
1251     			j = (j & 0x07) | 0x40;
1252     		}
1253     		outb(j, tmport);
1254     		tmport += 0x03;
1255     		outb(satn[8], tmport);
1256     		tmport += 0x07;
1257     
1258     		while ((inb(tmport) & 0x80) == 0x00);
1259     		tmport -= 0x08;
1260     		if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1261     			continue;
1262     		}
1263     		while (inb(tmport) != 0x8e);
1264     		dev->active_idu |= m;
1265     
1266     		tmport = wkport + 0x10;
1267     		outb(0x30, tmport);
1268     		tmport = wkport + 0x04;
1269     		outb(0x00, tmport);
1270     
1271     phase_cmd:
1272     		tmport = wkport + 0x18;
1273     		outb(0x08, tmport);
1274     		tmport += 0x07;
1275     		while ((inb(tmport) & 0x80) == 0x00);
1276     		tmport -= 0x08;
1277     		j = inb(tmport);
1278     		if (j != 0x16) {
1279     			tmport = wkport + 0x10;
1280     			outb(0x41, tmport);
1281     			goto phase_cmd;
1282     		}
1283     sel_ok:
1284     		tmport = wkport + 3;
1285     		outb(inqd[0], tmport++);
1286     		outb(inqd[1], tmport++);
1287     		outb(inqd[2], tmport++);
1288     		outb(inqd[3], tmport++);
1289     		outb(inqd[4], tmport++);
1290     		outb(inqd[5], tmport);
1291     		tmport += 0x07;
1292     		outb(0, tmport);
1293     		tmport += 0x02;
1294     		outb(dev->id[i].devspu, tmport++);
1295     		outb(0, tmport++);
1296     		outb(inqd[6], tmport++);
1297     		outb(inqd[7], tmport++);
1298     		tmport += 0x03;
1299     		outb(inqd[8], tmport);
1300     		tmport += 0x07;
1301     		while ((inb(tmport) & 0x80) == 0x00);
1302     		tmport -= 0x08;
1303     		if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1304     			continue;
1305     		}
1306     		while (inb(tmport) != 0x8e);
1307     		tmport = wkport + 0x1b;
1308     		if (dev->chip_veru == 4) {
1309     			outb(0x00, tmport);
1310     		}
1311     		tmport = wkport + 0x18;
1312     		outb(0x08, tmport);
1313     		tmport += 0x07;
1314     		j = 0;
1315     rd_inq_data:
1316     		k = inb(tmport);
1317     		if ((k & 0x01) != 0) {
1318     			tmport -= 0x06;
1319     			mbuf[j++] = inb(tmport);
1320     			tmport += 0x06;
1321     			goto rd_inq_data;
1322     		}
1323     		if ((k & 0x80) == 0) {
1324     			goto rd_inq_data;
1325     		}
1326     		tmport -= 0x08;
1327     		j = inb(tmport);
1328     		if (j == 0x16) {
1329     			goto inq_ok;
1330     		}
1331     		tmport = wkport + 0x10;
1332     		outb(0x46, tmport);
1333     		tmport += 0x02;
1334     		outb(0, tmport++);
1335     		outb(0, tmport++);
1336     		outb(0, tmport++);
1337     		tmport += 0x03;
1338     		outb(0x08, tmport);
1339     		tmport += 0x07;
1340     		while ((inb(tmport) & 0x80) == 0x00);
1341     		tmport -= 0x08;
1342     		if (inb(tmport) != 0x16) {
1343     			goto sel_ok;
1344     		}
1345     inq_ok:
1346     		mbuf[36] = 0;
1347     		printk(KERN_INFO "         ID: %2d  %s\n", i, &mbuf[8]);
1348     		dev->id[i].devtypeu = mbuf[0];
1349     		rmb = mbuf[1];
1350     		n = mbuf[7];
1351     		if (dev->chip_veru != 4) {
1352     			goto not_wide;
1353     		}
1354     		if ((mbuf[7] & 0x60) == 0) {
1355     			goto not_wide;
1356     		}
1357     		if ((dev->global_map & 0x20) == 0) {
1358     			goto not_wide;
1359     		}
1360     		tmport = wkport + 0x1b;
1361     		outb(0x01, tmport);
1362     		tmport = wkport + 3;
1363     		outb(satn[0], tmport++);
1364     		outb(satn[1], tmport++);
1365     		outb(satn[2], tmport++);
1366     		outb(satn[3], tmport++);
1367     		outb(satn[4], tmport++);
1368     		outb(satn[5], tmport++);
1369     		tmport += 0x06;
1370     		outb(0, tmport);
1371     		tmport += 0x02;
1372     		outb(dev->id[i].devspu, tmport++);
1373     		outb(0, tmport++);
1374     		outb(satn[6], tmport++);
1375     		outb(satn[7], tmport++);
1376     		tmport += 0x03;
1377     		outb(satn[8], tmport);
1378     		tmport += 0x07;
1379     
1380     		while ((inb(tmport) & 0x80) == 0x00);
1381     		tmport -= 0x08;
1382     		if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1383     			continue;
1384     		}
1385     		while (inb(tmport) != 0x8e);
1386     try_wide:
1387     		j = 0;
1388     		tmport = wkport + 0x14;
1389     		outb(0x05, tmport);
1390     		tmport += 0x04;
1391     		outb(0x20, tmport);
1392     		tmport += 0x07;
1393     
1394     		while ((inb(tmport) & 0x80) == 0) {
1395     			if ((inb(tmport) & 0x01) != 0) {
1396     				tmport -= 0x06;
1397     				outb(wide[j++], tmport);
1398     				tmport += 0x06;
1399     			}
1400     		}
1401     		tmport -= 0x08;
1402     		while ((inb(tmport) & 0x80) == 0x00);
1403     		j = inb(tmport) & 0x0f;
1404     		if (j == 0x0f) {
1405     			goto widep_in;
1406     		}
1407     		if (j == 0x0a) {
1408     			goto widep_cmd;
1409     		}
1410     		if (j == 0x0e) {
1411     			goto try_wide;
1412     		}
1413     		continue;
1414     widep_out:
1415     		tmport = wkport + 0x18;
1416     		outb(0x20, tmport);
1417     		tmport += 0x07;
1418     		while ((inb(tmport) & 0x80) == 0) {
1419     			if ((inb(tmport) & 0x01) != 0) {
1420     				tmport -= 0x06;
1421     				outb(0, tmport);
1422     				tmport += 0x06;
1423     			}
1424     		}
1425     		tmport -= 0x08;
1426     		j = inb(tmport) & 0x0f;
1427     		if (j == 0x0f) {
1428     			goto widep_in;
1429     		}
1430     		if (j == 0x0a) {
1431     			goto widep_cmd;
1432     		}
1433     		if (j == 0x0e) {
1434     			goto widep_out;
1435     		}
1436     		continue;
1437     widep_in:
1438     		tmport = wkport + 0x14;
1439     		outb(0xff, tmport);
1440     		tmport += 0x04;
1441     		outb(0x20, tmport);
1442     		tmport += 0x07;
1443     		k = 0;
1444     widep_in1:
1445     		j = inb(tmport);
1446     		if ((j & 0x01) != 0) {
1447     			tmport -= 0x06;
1448     			mbuf[k++] = inb(tmport);
1449     			tmport += 0x06;
1450     			goto widep_in1;
1451     		}
1452     		if ((j & 0x80) == 0x00) {
1453     			goto widep_in1;
1454     		}
1455     		tmport -= 0x08;
1456     		j = inb(tmport) & 0x0f;
1457     		if (j == 0x0f) {
1458     			goto widep_in;
1459     		}
1460     		if (j == 0x0a) {
1461     			goto widep_cmd;
1462     		}
1463     		if (j == 0x0e) {
1464     			goto widep_out;
1465     		}
1466     		continue;
1467     widep_cmd:
1468     		tmport = wkport + 0x10;
1469     		outb(0x30, tmport);
1470     		tmport = wkport + 0x14;
1471     		outb(0x00, tmport);
1472     		tmport += 0x04;
1473     		outb(0x08, tmport);
1474     		tmport += 0x07;
1475     		while ((inb(tmport) & 0x80) == 0x00);
1476     		tmport -= 0x08;
1477     		j = inb(tmport);
1478     		if (j != 0x16) {
1479     			if (j == 0x4e) {
1480     				goto widep_out;
1481     			}
1482     			continue;
1483     		}
1484     		if (mbuf[0] != 0x01) {
1485     			goto not_wide;
1486     		}
1487     		if (mbuf[1] != 0x02) {
1488     			goto not_wide;
1489     		}
1490     		if (mbuf[2] != 0x03) {
1491     			goto not_wide;
1492     		}
1493     		if (mbuf[3] != 0x01) {
1494     			goto not_wide;
1495     		}
1496     		m = 1;
1497     		m = m << i;
1498     		dev->wide_idu |= m;
1499     not_wide:
1500     		if ((dev->id[i].devtypeu == 0x00) || (dev->id[i].devtypeu == 0x07) ||
1501     		    ((dev->id[i].devtypeu == 0x05) && ((n & 0x10) != 0)))
1502     		{
1503     			goto set_sync;
1504     		}
1505     		continue;
1506     set_sync:
1507     		tmport = wkport + 0x1b;
1508     		j = 0;
1509     		if ((m & dev->wide_idu) != 0) {
1510     			j |= 0x01;
1511     		}
1512     		outb(j, tmport);
1513     		tmport = wkport + 3;
1514     		outb(satn[0], tmport++);
1515     		outb(satn[1], tmport++);
1516     		outb(satn[2], tmport++);
1517     		outb(satn[3], tmport++);
1518     		outb(satn[4], tmport++);
1519     		outb(satn[5], tmport++);
1520     		tmport += 0x06;
1521     		outb(0, tmport);
1522     		tmport += 0x02;
1523     		outb(dev->id[i].devspu, tmport++);
1524     		outb(0, tmport++);
1525     		outb(satn[6], tmport++);
1526     		outb(satn[7], tmport++);
1527     		tmport += 0x03;
1528     		outb(satn[8], tmport);
1529     		tmport += 0x07;
1530     
1531     		while ((inb(tmport) & 0x80) == 0x00);
1532     		tmport -= 0x08;
1533     		if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1534     			continue;
1535     		}
1536     		while (inb(tmport) != 0x8e);
1537     try_sync:
1538     		j = 0;
1539     		tmport = wkport + 0x14;
1540     		outb(0x06, tmport);
1541     		tmport += 0x04;
1542     		outb(0x20, tmport);
1543     		tmport += 0x07;
1544     
1545     		while ((inb(tmport) & 0x80) == 0) {
1546     			if ((inb(tmport) & 0x01) != 0) {
1547     				tmport -= 0x06;
1548     				if ((m & dev->wide_idu) != 0) {
1549     					outb(synw[j++], tmport);
1550     				} else {
1551     					if ((m & dev->ultra_map) != 0) {
1552     						outb(synu[j++], tmport);
1553     					} else {
1554     						outb(synn[j++], tmport);
1555     					}
1556     				}
1557     				tmport += 0x06;
1558     			}
1559     		}
1560     		tmport -= 0x08;
1561     		while ((inb(tmport) & 0x80) == 0x00);
1562     		j = inb(tmport) & 0x0f;
1563     		if (j == 0x0f) {
1564     			goto phase_ins;
1565     		}
1566     		if (j == 0x0a) {
1567     			goto phase_cmds;
1568     		}
1569     		if (j == 0x0e) {
1570     			goto try_sync;
1571     		}
1572     		continue;
1573     phase_outs:
1574     		tmport = wkport + 0x18;
1575     		outb(0x20, tmport);
1576     		tmport += 0x07;
1577     		while ((inb(tmport) & 0x80) == 0x00) {
1578     			if ((inb(tmport) & 0x01) != 0x00) {
1579     				tmport -= 0x06;
1580     				outb(0x00, tmport);
1581     				tmport += 0x06;
1582     			}
1583     		}
1584     		tmport -= 0x08;
1585     		j = inb(tmport);
1586     		if (j == 0x85) {
1587     			goto tar_dcons;
1588     		}
1589     		j &= 0x0f;
1590     		if (j == 0x0f) {
1591     			goto phase_ins;
1592     		}
1593     		if (j == 0x0a) {
1594     			goto phase_cmds;
1595     		}
1596     		if (j == 0x0e) {
1597     			goto phase_outs;
1598     		}
1599     		continue;
1600     phase_ins:
1601     		tmport = wkport + 0x14;
1602     		outb(0xff, tmport);
1603     		tmport += 0x04;
1604     		outb(0x20, tmport);
1605     		tmport += 0x07;
1606     		k = 0;
1607     phase_ins1:
1608     		j = inb(tmport);
1609     		if ((j & 0x01) != 0x00) {
1610     			tmport -= 0x06;
1611     			mbuf[k++] = inb(tmport);
1612     			tmport += 0x06;
1613     			goto phase_ins1;
1614     		}
1615     		if ((j & 0x80) == 0x00) {
1616     			goto phase_ins1;
1617     		}
1618     		tmport -= 0x08;
1619     		while ((inb(tmport) & 0x80) == 0x00);
1620     		j = inb(tmport);
1621     		if (j == 0x85) {
1622     			goto tar_dcons;
1623     		}
1624     		j &= 0x0f;
1625     		if (j == 0x0f) {
1626     			goto phase_ins;
1627     		}
1628     		if (j == 0x0a) {
1629     			goto phase_cmds;
1630     		}
1631     		if (j == 0x0e) {
1632     			goto phase_outs;
1633     		}
1634     		continue;
1635     phase_cmds:
1636     		tmport = wkport + 0x10;
1637     		outb(0x30, tmport);
1638     tar_dcons:
1639     		tmport = wkport + 0x14;
1640     		outb(0x00, tmport);
1641     		tmport += 0x04;
1642     		outb(0x08, tmport);
1643     		tmport += 0x07;
1644     		while ((inb(tmport) & 0x80) == 0x00);
1645     		tmport -= 0x08;
1646     		j = inb(tmport);
1647     		if (j != 0x16) {
1648     			continue;
1649     		}
1650     		if (mbuf[0] != 0x01) {
1651     			continue;
1652     		}
1653     		if (mbuf[1] != 0x03) {
1654     			continue;
1655     		}
1656     		if (mbuf[4] == 0x00) {
1657     			continue;
1658     		}
1659     		if (mbuf[3] > 0x64) {
1660     			continue;
1661     		}
1662     		if (mbuf[4] > 0x0c) {
1663     			mbuf[4] = 0x0c;
1664     		}
1665     		dev->id[i].devspu = mbuf[4];
1666     		if ((mbuf[3] < 0x0d) && (rmb == 0)) {
1667     			j = 0xa0;
1668     			goto set_syn_ok;
1669     		}
1670     		if (mbuf[3] < 0x1a) {
1671     			j = 0x20;
1672     			goto set_syn_ok;
1673     		}
1674     		if (mbuf[3] < 0x33) {
1675     			j = 0x40;
1676     			goto set_syn_ok;
1677     		}
1678     		if (mbuf[3] < 0x4c) {
1679     			j = 0x50;
1680     			goto set_syn_ok;
1681     		}
1682     		j = 0x60;
1683     	      set_syn_ok:
1684     		dev->id[i].devspu = (dev->id[i].devspu & 0x0f) | j;
1685     	}
1686     	tmport = wkport + 0x3a;
1687     	outb((unsigned char) (inb(tmport) & 0xef), tmport);
1688     }
1689     
1690     void is880(unsigned long host, unsigned int wkport)
1691     {
1692     	unsigned int tmport;
1693     	unsigned char i, j, k, rmb, n, lvdmode;
1694     	unsigned short int m;
1695     	static unsigned char mbuf[512];
1696     	static unsigned char satn[9] =	{0, 0, 0, 0, 0, 0, 0, 6, 6};
1697     	static unsigned char inqd[9] =	{0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6};
1698     	static unsigned char synn[6] =	{0x80, 1, 3, 1, 0x19, 0x0e};
1699     	unsigned char synu[6] =  {0x80, 1, 3, 1, 0x0a, 0x0e};
1700     	static unsigned char synw[6] =	{0x80, 1, 3, 1, 0x19, 0x0e};
1701     	unsigned char synuw[6] =  {0x80, 1, 3, 1, 0x0a, 0x0e};
1702     	static unsigned char wide[6] =	{0x80, 1, 2, 3, 1, 0};
1703     	static unsigned char u3[9] = { 0x80,1,6,4,0x09,00,0x0e,0x01,0x02 };
1704     	struct atp_unit *dev = &atp_unit[host];
1705     
1706     	sync_idu = 0;
1707     	lvdmode=inb(wkport + 0x3f) & 0x40;
1708     
1709     	for (i = 0; i < 16; i++) {
1710     		m = 1;
1711     		m = m << i;
1712     		if ((m & dev->active_idu) != 0) {
1713     			continue;
1714     		}
1715     		if (i == dev->host_idu) {
1716     			printk(KERN_INFO "         ID: %2d  Host Adapter\n", dev->host_idu);
1717     			continue;
1718     		}
1719     		tmport = wkport + 0x5b;
1720     		outb(0x01, tmport);
1721     		tmport = wkport + 0x41;
1722     		outb(0x08, tmport++);
1723     		outb(0x7f, tmport++);
1724     		outb(satn[0], tmport++);
1725     		outb(satn[1], tmport++);
1726     		outb(satn[2], tmport++);
1727     		outb(satn[3], tmport++);
1728     		outb(satn[4], tmport++);
1729     		outb(satn[5], tmport++);
1730     		tmport += 0x06;
1731     		outb(0, tmport);
1732     		tmport += 0x02;
1733     		outb(dev->id[i].devspu, tmport++);
1734     		outb(0, tmport++);
1735     		outb(satn[6], tmport++);
1736     		outb(satn[7], tmport++);
1737     		j = i;
1738     		if ((j & 0x08) != 0) {
1739     			j = (j & 0x07) | 0x40;
1740     		}
1741     		outb(j, tmport);
1742     		tmport += 0x03;
1743     		outb(satn[8], tmport);
1744     		tmport += 0x07;
1745     
1746     		while ((inb(tmport) & 0x80) == 0x00);
1747     		tmport -= 0x08;
1748     		if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1749     			continue;
1750     		}
1751     		while (inb(tmport) != 0x8e);
1752     		dev->active_idu |= m;
1753     
1754     		tmport = wkport + 0x50;
1755     		outb(0x30, tmport);
1756     		tmport = wkport + 0x54;
1757     		outb(0x00, tmport);
1758     
1759     phase_cmd:
1760     		tmport = wkport + 0x58;
1761     		outb(0x08, tmport);
1762     		tmport += 0x07;
1763     		while ((inb(tmport) & 0x80) == 0x00);
1764     		tmport -= 0x08;
1765     		j = inb(tmport);
1766     		if (j != 0x16) {
1767     			tmport = wkport + 0x50;
1768     			outb(0x41, tmport);
1769     			goto phase_cmd;
1770     		}
1771     sel_ok:
1772     		tmport = wkport + 0x43;
1773     		outb(inqd[0], tmport++);
1774     		outb(inqd[1], tmport++);
1775     		outb(inqd[2], tmport++);
1776     		outb(inqd[3], tmport++);
1777     		outb(inqd[4], tmport++);
1778     		outb(inqd[5], tmport);
1779     		tmport += 0x07;
1780     		outb(0, tmport);
1781     		tmport += 0x02;
1782     		outb(dev->id[i].devspu, tmport++);
1783     		outb(0, tmport++);
1784     		outb(inqd[6], tmport++);
1785     		outb(inqd[7], tmport++);
1786     		tmport += 0x03;
1787     		outb(inqd[8], tmport);
1788     		tmport += 0x07;
1789     		while ((inb(tmport) & 0x80) == 0x00);
1790     		tmport -= 0x08;
1791     		if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1792     			continue;
1793     		}
1794     		while (inb(tmport) != 0x8e);
1795     		tmport = wkport + 0x5b;
1796     		outb(0x00, tmport);
1797     		tmport = wkport + 0x58;
1798     		outb(0x08, tmport);
1799     		tmport += 0x07;
1800     		j = 0;
1801     rd_inq_data:
1802     		k = inb(tmport);
1803     		if ((k & 0x01) != 0) {
1804     			tmport -= 0x06;
1805     			mbuf[j++] = inb(tmport);
1806     			tmport += 0x06;
1807     			goto rd_inq_data;
1808     		}
1809     		if ((k & 0x80) == 0) {
1810     			goto rd_inq_data;
1811     		}
1812     		tmport -= 0x08;
1813     		j = inb(tmport);
1814     		if (j == 0x16) {
1815     			goto inq_ok;
1816     		}
1817     		tmport = wkport + 0x50;
1818     		outb(0x46, tmport);
1819     		tmport += 0x02;
1820     		outb(0, tmport++);
1821     		outb(0, tmport++);
1822     		outb(0, tmport++);
1823     		tmport += 0x03;
1824     		outb(0x08, tmport);
1825     		tmport += 0x07;
1826     		while ((inb(tmport) & 0x80) == 0x00);
1827     		tmport -= 0x08;
1828     		if (inb(tmport) != 0x16) {
1829     			goto sel_ok;
1830     		}
1831     inq_ok:
1832     		mbuf[36] = 0;
1833     		printk(KERN_INFO "         ID: %2d  %s\n", i, &mbuf[8]);
1834     		dev->id[i].devtypeu = mbuf[0];
1835     		rmb = mbuf[1];
1836     		n = mbuf[7];
1837     		if ((mbuf[7] & 0x60) == 0) {
1838     			goto not_wide;
1839     		}
1840     		if ((i < 8) && ((dev->global_map & 0x20) == 0)) {
1841     			goto not_wide;
1842     		}
1843     		if (lvdmode == 0)
1844     		{
1845     		   goto chg_wide;
1846     		}
1847     		if (dev->sp[i] != 0x04) 	 // force u2
1848     		{
1849     		   goto chg_wide;
1850     		}
1851     
1852     		tmport = wkport + 0x5b;
1853     		outb(0x01, tmport);
1854     		tmport = wkport + 0x43;
1855     		outb(satn[0], tmport++);
1856     		outb(satn[1], tmport++);
1857     		outb(satn[2], tmport++);
1858     		outb(satn[3], tmport++);
1859     		outb(satn[4], tmport++);
1860     		outb(satn[5], tmport++);
1861     		tmport += 0x06;
1862     		outb(0, tmport);
1863     		tmport += 0x02;
1864     		outb(dev->id[i].devspu, tmport++);
1865     		outb(0, tmport++);
1866     		outb(satn[6], tmport++);
1867     		outb(satn[7], tmport++);
1868     		tmport += 0x03;
1869     		outb(satn[8], tmport);
1870     		tmport += 0x07;
1871     
1872     		while ((inb(tmport) & 0x80) == 0x00);
1873     		tmport -= 0x08;
1874     		if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1875     			continue;
1876     		}
1877     		while (inb(tmport) != 0x8e);
1878     try_u3:
1879     		j = 0;
1880     		tmport = wkport + 0x54;
1881     		outb(0x09, tmport);
1882     		tmport += 0x04;
1883     		outb(0x20, tmport);
1884     		tmport += 0x07;
1885     
1886     		while ((inb(tmport) & 0x80) == 0) {
1887     			if ((inb(tmport) & 0x01) != 0) {
1888     				tmport -= 0x06;
1889     				outb(u3[j++], tmport);
1890     				tmport += 0x06;
1891     			}
1892     		}
1893     		tmport -= 0x08;
1894     		while ((inb(tmport) & 0x80) == 0x00);
1895     		j = inb(tmport) & 0x0f;
1896     		if (j == 0x0f) {
1897     			goto u3p_in;
1898     		}
1899     		if (j == 0x0a) {
1900     			goto u3p_cmd;
1901     		}
1902     		if (j == 0x0e) {
1903     			goto try_u3;
1904     		}
1905     		continue;
1906     u3p_out:
1907     		tmport = wkport + 0x58;
1908     		outb(0x20, tmport);
1909     		tmport += 0x07;
1910     		while ((inb(tmport) & 0x80) == 0) {
1911     			if ((inb(tmport) & 0x01) != 0) {
1912     				tmport -= 0x06;
1913     				outb(0, tmport);
1914     				tmport += 0x06;
1915     			}
1916     		}
1917     		tmport -= 0x08;
1918     		j = inb(tmport) & 0x0f;
1919     		if (j == 0x0f) {
1920     			goto u3p_in;
1921     		}
1922     		if (j == 0x0a) {
1923     			goto u3p_cmd;
1924     		}
1925     		if (j == 0x0e) {
1926     			goto u3p_out;
1927     		}
1928     		continue;
1929     u3p_in:
1930     		tmport = wkport + 0x54;
1931     		outb(0x09, tmport);
1932     		tmport += 0x04;
1933     		outb(0x20, tmport);
1934     		tmport += 0x07;
1935     		k = 0;
1936     u3p_in1:
1937     		j = inb(tmport);
1938     		if ((j & 0x01) != 0) {
1939     			tmport -= 0x06;
1940     			mbuf[k++] = inb(tmport);
1941     			tmport += 0x06;
1942     			goto u3p_in1;
1943     		}
1944     		if ((j & 0x80) == 0x00) {
1945     			goto u3p_in1;
1946     		}
1947     		tmport -= 0x08;
1948     		j = inb(tmport) & 0x0f;
1949     		if (j == 0x0f) {
1950     			goto u3p_in;
1951     		}
1952     		if (j == 0x0a) {
1953     			goto u3p_cmd;
1954     		}
1955     		if (j == 0x0e) {
1956     			goto u3p_out;
1957     		}
1958     		continue;
1959     u3p_cmd:
1960     		tmport = wkport + 0x50;
1961     		outb(0x30, tmport);
1962     		tmport = wkport + 0x54;
1963     		outb(0x00, tmport);
1964     		tmport += 0x04;
1965     		outb(0x08, tmport);
1966     		tmport += 0x07;
1967     		while ((inb(tmport) & 0x80) == 0x00);
1968     		tmport -= 0x08;
1969     		j = inb(tmport);
1970     		if (j != 0x16) {
1971     			if (j == 0x4e) {
1972     				goto u3p_out;
1973     			}
1974     			continue;
1975     		}
1976     		if (mbuf[0] != 0x01) {
1977     			goto chg_wide;
1978     		}
1979     		if (mbuf[1] != 0x06) {
1980     			goto chg_wide;
1981     		}
1982     		if (mbuf[2] != 0x04) {
1983     			goto chg_wide;
1984     		}
1985     		if (mbuf[3] == 0x09) {
1986     		   m = 1;
1987     		   m = m << i;
1988     		   dev->wide_idu |= m;
1989     		   dev->id[i].devspu = 0xce;
1990     		   continue;
1991     		}
1992     chg_wide:
1993     		tmport = wkport + 0x5b;
1994     		outb(0x01, tmport);
1995     		tmport = wkport + 0x43;
1996     		outb(satn[0], tmport++);
1997     		outb(satn[1], tmport++);
1998     		outb(satn[2], tmport++);
1999     		outb(satn[3], tmport++);
2000     		outb(satn[4], tmport++);
2001     		outb(satn[5], tmport++);
2002     		tmport += 0x06;
2003     		outb(0, tmport);
2004     		tmport += 0x02;
2005     		outb(dev->id[i].devspu, tmport++);
2006     		outb(0, tmport++);
2007     		outb(satn[6], tmport++);
2008     		outb(satn[7], tmport++);
2009     		tmport += 0x03;
2010     		outb(satn[8], tmport);
2011     		tmport += 0x07;
2012     
2013     		while ((inb(tmport) & 0x80) == 0x00);
2014     		tmport -= 0x08;
2015     		if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
2016     			continue;
2017     		}
2018     		while (inb(tmport) != 0x8e);
2019     try_wide:
2020     		j = 0;
2021     		tmport = wkport + 0x54;
2022     		outb(0x05, tmport);
2023     		tmport += 0x04;
2024     		outb(0x20, tmport);
2025     		tmport += 0x07;
2026     
2027     		while ((inb(tmport) & 0x80) == 0) {
2028     			if ((inb(tmport) & 0x01) != 0) {
2029     				tmport -= 0x06;
2030     				outb(wide[j++], tmport);
2031     				tmport += 0x06;
2032     			}
2033     		}
2034     		tmport -= 0x08;
2035     		while ((inb(tmport) & 0x80) == 0x00);
2036     		j = inb(tmport) & 0x0f;
2037     		if (j == 0x0f) {
2038     			goto widep_in;
2039     		}
2040     		if (j == 0x0a) {
2041     			goto widep_cmd;
2042     		}
2043     		if (j == 0x0e) {
2044     			goto try_wide;
2045     		}
2046     		continue;
2047     widep_out:
2048     		tmport = wkport + 0x58;
2049     		outb(0x20, tmport);
2050     		tmport += 0x07;
2051     		while ((inb(tmport) & 0x80) == 0) {
2052     			if ((inb(tmport) & 0x01) != 0) {
2053     				tmport -= 0x06;
2054     				outb(0, tmport);
2055     				tmport += 0x06;
2056     			}
2057     		}
2058     		tmport -= 0x08;
2059     		j = inb(tmport) & 0x0f;
2060     		if (j == 0x0f) {
2061     			goto widep_in;
2062     		}
2063     		if (j == 0x0a) {
2064     			goto widep_cmd;
2065     		}
2066     		if (j == 0x0e) {
2067     			goto widep_out;
2068     		}
2069     		continue;
2070     widep_in:
2071     		tmport = wkport + 0x54;
2072     		outb(0xff, tmport);
2073     		tmport += 0x04;
2074     		outb(0x20, tmport);
2075     		tmport += 0x07;
2076     		k = 0;
2077     widep_in1:
2078     		j = inb(tmport);
2079     		if ((j & 0x01) != 0) {
2080     			tmport -= 0x06;
2081     			mbuf[k++] = inb(tmport);
2082     			tmport += 0x06;
2083     			goto widep_in1;
2084     		}
2085     		if ((j & 0x80) == 0x00) {
2086     			goto widep_in1;
2087     		}
2088     		tmport -= 0x08;
2089     		j = inb(tmport) & 0x0f;
2090     		if (j == 0x0f) {
2091     			goto widep_in;
2092     		}
2093     		if (j == 0x0a) {
2094     			goto widep_cmd;
2095     		}
2096     		if (j == 0x0e) {
2097     			goto widep_out;
2098     		}
2099     		continue;
2100     widep_cmd:
2101     		tmport = wkport + 0x50;
2102     		outb(0x30, tmport);
2103     		tmport = wkport + 0x54;
2104     		outb(0x00, tmport);
2105     		tmport += 0x04;
2106     		outb(0x08, tmport);
2107     		tmport += 0x07;
2108     		while ((inb(tmport) & 0x80) == 0x00);
2109     		tmport -= 0x08;
2110     		j = inb(tmport);
2111     		if (j != 0x16) {
2112     			if (j == 0x4e) {
2113     				goto widep_out;
2114     			}
2115     			continue;
2116     		}
2117     		if (mbuf[0] != 0x01) {
2118     			goto not_wide;
2119     		}
2120     		if (mbuf[1] != 0x02) {
2121     			goto not_wide;
2122     		}
2123     		if (mbuf[2] != 0x03) {
2124     			goto not_wide;
2125     		}
2126     		if (mbuf[3] != 0x01) {
2127     			goto not_wide;
2128     		}
2129     		m = 1;
2130     		m = m << i;
2131     		dev->wide_idu |= m;
2132     not_wide:
2133     		if ((dev->id[i].devtypeu == 0x00) || (dev->id[i].devtypeu == 0x07) ||
2134     		    ((dev->id[i].devtypeu == 0x05) && ((n & 0x10) != 0)))
2135     		{
2136     			m = 1;
2137     			m = m << i;
2138     			if ((dev->async & m) != 0)
2139     			{
2140     			   goto set_sync;
2141     			}
2142     		}
2143     		continue;
2144     set_sync:
2145     		if (dev->sp[i] == 0x02)
2146     		{
2147     		   synu[4]=0x0c;
2148     		   synuw[4]=0x0c;
2149     		}
2150     		else
2151     		{
2152     		   if (dev->sp[i] >= 0x03)
2153     		   {
2154     		      synu[4]=0x0a;
2155     		      synuw[4]=0x0a;
2156     		   }
2157     		}
2158     		tmport = wkport + 0x5b;
2159     		j = 0;
2160     		if ((m & dev->wide_idu) != 0) {
2161     			j |= 0x01;
2162     		}
2163     		outb(j, tmport);
2164     		tmport = wkport + 0x43;
2165     		outb(satn[0], tmport++);
2166     		outb(satn[1], tmport++);
2167     		outb(satn[2], tmport++);
2168     		outb(satn[3], tmport++);
2169     		outb(satn[4], tmport++);
2170     		outb(satn[5], tmport++);
2171     		tmport += 0x06;
2172     		outb(0, tmport);
2173     		tmport += 0x02;
2174     		outb(dev->id[i].devspu, tmport++);
2175     		outb(0, tmport++);
2176     		outb(satn[6], tmport++);
2177     		outb(satn[7], tmport++);
2178     		tmport += 0x03;
2179     		outb(satn[8], tmport);
2180     		tmport += 0x07;
2181     
2182     		while ((inb(tmport) & 0x80) == 0x00);
2183     		tmport -= 0x08;
2184     		if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
2185     			continue;
2186     		}
2187     		while (inb(tmport) != 0x8e);
2188     try_sync:
2189     		j = 0;
2190     		tmport = wkport + 0x54;
2191     		outb(0x06, tmport);
2192     		tmport += 0x04;
2193     		outb(0x20, tmport);
2194     		tmport += 0x07;
2195     
2196     		while ((inb(tmport) & 0x80) == 0) {
2197     			if ((inb(tmport) & 0x01) != 0) {
2198     				tmport -= 0x06;
2199     				if ((m & dev->wide_idu) != 0) {
2200     					if ((m & dev->ultra_map) != 0) {
2201     						outb(synuw[j++], tmport);
2202     					} else {
2203     						outb(synw[j++], tmport);
2204     					}
2205     				} else {
2206     					if ((m & dev->ultra_map) != 0) {
2207     						outb(synu[j++], tmport);
2208     					} else {
2209     						outb(synn[j++], tmport);
2210     					}
2211     				}
2212     				tmport += 0x06;
2213     			}
2214     		}
2215     		tmport -= 0x08;
2216     		while ((inb(tmport) & 0x80) == 0x00);
2217     		j = inb(tmport) & 0x0f;
2218     		if (j == 0x0f) {
2219     			goto phase_ins;
2220     		}
2221     		if (j == 0x0a) {
2222     			goto phase_cmds;
2223     		}
2224     		if (j == 0x0e) {
2225     			goto try_sync;
2226     		}
2227     		continue;
2228     phase_outs:
2229     		tmport = wkport + 0x58;
2230     		outb(0x20, tmport);
2231     		tmport += 0x07;
2232     		while ((inb(tmport) & 0x80) == 0x00) {
2233     			if ((inb(tmport) & 0x01) != 0x00) {
2234     				tmport -= 0x06;
2235     				outb(0x00, tmport);
2236     				tmport += 0x06;
2237     			}
2238     		}
2239     		tmport -= 0x08;
2240     		j = inb(tmport);
2241     		if (j == 0x85) {
2242     			goto tar_dcons;
2243     		}
2244     		j &= 0x0f;
2245     		if (j == 0x0f) {
2246     			goto phase_ins;
2247     		}
2248     		if (j == 0x0a) {
2249     			goto phase_cmds;
2250     		}
2251     		if (j == 0x0e) {
2252     			goto phase_outs;
2253     		}
2254     		continue;
2255     phase_ins:
2256     		tmport = wkport + 0x54;
2257     		outb(0x06, tmport);
2258     		tmport += 0x04;
2259     		outb(0x20, tmport);
2260     		tmport += 0x07;
2261     		k = 0;
2262     phase_ins1:
2263     		j = inb(tmport);
2264     		if ((j & 0x01) != 0x00) {
2265     			tmport -= 0x06;
2266     			mbuf[k++] = inb(tmport);
2267     			tmport += 0x06;
2268     			goto phase_ins1;
2269     		}
2270     		if ((j & 0x80) == 0x00) {
2271     			goto phase_ins1;
2272     		}
2273     		tmport -= 0x08;
2274     		while ((inb(tmport) & 0x80) == 0x00);
2275     		j = inb(tmport);
2276     		if (j == 0x85) {
2277     			goto tar_dcons;
2278     		}
2279     		j &= 0x0f;
2280     		if (j == 0x0f) {
2281     			goto phase_ins;
2282     		}
2283     		if (j == 0x0a) {
2284     			goto phase_cmds;
2285     		}
2286     		if (j == 0x0e) {
2287     			goto phase_outs;
2288     		}
2289     		continue;
2290     phase_cmds:
2291     		tmport = wkport + 0x50;
2292     		outb(0x30, tmport);
2293     tar_dcons:
2294     		tmport = wkport + 0x54;
2295     		outb(0x00, tmport);
2296     		tmport += 0x04;
2297     		outb(0x08, tmport);
2298     		tmport += 0x07;
2299     		while ((inb(tmport) & 0x80) == 0x00);
2300     		tmport -= 0x08;
2301     		j = inb(tmport);
2302     		if (j != 0x16) {
2303     			continue;
2304     		}
2305     		if (mbuf[0] != 0x01) {
2306     			continue;
2307     		}
2308     		if (mbuf[1] != 0x03) {
2309     			continue;
2310     		}
2311     		if (mbuf[4] == 0x00) {
2312     			continue;
2313     		}
2314     		if (mbuf[3] > 0x64) {
2315     			continue;
2316     		}
2317     		if (mbuf[4] > 0x0e) {
2318     			mbuf[4] = 0x0e;
2319     		}
2320     		dev->id[i].devspu = mbuf[4];
2321     		if (mbuf[3] < 0x0c){
2322     			j = 0xb0;
2323     			goto set_syn_ok;
2324     		}
2325     		if ((mbuf[3] < 0x0d) && (rmb == 0)) {
2326     			j = 0xa0;
2327     			goto set_syn_ok;
2328     		}
2329     		if (mbuf[3] < 0x1a) {
2330     			j = 0x20;
2331     			goto set_syn_ok;
2332     		}
2333     		if (mbuf[3] < 0x33) {
2334     			j = 0x40;
2335     			goto set_syn_ok;
2336     		}
2337     		if (mbuf[3] < 0x4c) {
2338     			j = 0x50;
2339     			goto set_syn_ok;
2340     		}
2341     		j = 0x60;
2342     	      set_syn_ok:
2343     		dev->id[i].devspu = (dev->id[i].devspu & 0x0f) | j;
2344     	}
2345     }
2346     
2347     /* return non-zero on detection */
2348     int atp870u_detect(Scsi_Host_Template * tpnt)
2349     {
2350     	unsigned char irq, h, k, m;
2351     	unsigned long flags;
2352     	unsigned int base_io, error, tmport;
2353     	unsigned short index = 0;
2354     	struct pci_dev *pdev[3];
2355     	unsigned char chip_ver[3], host_id;
2356     	unsigned short dev_id[3], n;
2357     	struct Scsi_Host *shpnt = NULL;
2358     	int tmpcnt = 0;
2359     	int count = 0;
2360     
2361     	static unsigned short devid[9] = {
2362     	  0x8081, 0x8002, 0x8010, 0x8020, 0x8030, 0x8040, 0x8050, 0x8060, 0
2363     	};
2364     
2365     	printk(KERN_INFO "aec671x_detect: \n");
2366     	if (!pci_present()) {
2367     		printk(KERN_INFO"   NO PCI SUPPORT.\n");
2368     		return count;
2369     	}
2370     	tpnt->proc_name = "atp870u";
2371     
2372     	for (h = 0; h < 2; h++) {
2373     		struct atp_unit *dev = &atp_unit[h];
2374     		for(k=0;k<16;k++)
2375     		{
2376     			dev->id[k].prd_tableu = kmalloc(1024, GFP_KERNEL);
2377     			dev->id[k].devspu=0x20;
2378     			dev->id[k].devtypeu = 0;
2379     			dev->id[k].curr_req = NULL;
2380     		}
2381     		dev->active_idu = 0;
2382     		dev->wide_idu = 0;
2383     		dev->host_idu = 0x07;
2384     		dev->quhdu = 0;
2385     		dev->quendu = 0;
2386     		pdev[h]=NULL;
2387     		pdev[2]=NULL;
2388     		dev->chip_veru = 0;
2389     		dev->last_cmd = 0xff;
2390     		dev->in_snd = 0;
2391     		dev->in_int = 0;
2392     		for (k = 0; k < qcnt; k++) {
2393     			dev->querequ[k] = 0;
2394     		}
2395     		for (k = 0; k < 16; k++) {
2396     			dev->id[k].curr_req = 0;
2397     			dev->sp[k] = 0x04;
2398     		}
2399     	}
2400     	h = 0;
2401     	while (devid[h] != 0) {
2402     		pdev[2] = pci_find_device(0x1191, devid[h], pdev[2]);
2403     		if (pdev[2] == NULL || pci_enable_device(pdev[2])) {
2404     			h++;
2405     			index = 0;
2406     			continue;
2407     		}
2408     		chip_ver[2] = 0;
2409     		dev_id[2] = devid[h];
2410     
2411     		if (devid[h] == 0x8002) {
2412     			error = pci_read_config_byte(pdev[2], 0x08, &chip_ver[2]);
2413     			if (chip_ver[2] < 2) {
2414     				goto nxt_devfn;
2415     			}
2416     		}
2417     		if (devid[h] == 0x8010 || devid[h] == 0x8081 || devid[h] == 0x8050)
2418     		{
2419     			chip_ver[2] = 0x04;
2420     		}
2421     		pdev[tmpcnt] = pdev[2];
2422     		chip_ver[tmpcnt] = chip_ver[2];
2423     		dev_id[tmpcnt] = dev_id[2];
2424     		tmpcnt++;
2425     	      nxt_devfn:
2426     		index++;
2427     		if (index > 3) {
2428     			index = 0;
2429     			h++;
2430     		}
2431     		if(tmpcnt>1)
2432     			break;
2433     	}
2434     	for (h = 0; h < 2; h++) {
2435     		struct atp_unit *dev=&atp_unit[h];
2436     		if (pdev[h]==NULL) {
2437     			return count;
2438     		}
2439     
2440     		/* Found an atp870u/w. */
2441     		base_io = pci_resource_start(pdev[h], 0);
2442     		irq = pdev[h]->irq;
2443     
2444     		if (dev_id[h] != 0x8081)
2445     		{
2446     		   error = pci_read_config_byte(pdev[h],0x49,&host_id);
2447     
2448     		   base_io &= 0xfffffff8;
2449     
2450     		   if (check_region(base_io,0x40) != 0)
2451     		   {
2452     			   return 0;
2453     		   }
2454     		   printk(KERN_INFO "   ACARD AEC-671X PCI Ultra/W SCSI-3 Host Adapter: %d    IO:%x, IRQ:%d.\n"
2455     			  ,h, base_io, irq);
2456     		   dev->ioport = base_io;
2457     		   dev->pciport = base_io + 0x20;
2458     		   dev->deviceid = dev_id[h];
2459     		   irqnumu[h] = irq;
2460     		   host_id &= 0x07;
2461     		   dev->host_idu = host_id;
2462     		   dev->chip_veru = chip_ver[h];
2463     
2464     		   tmport = base_io + 0x22;
2465     		   dev->scam_on = inb(tmport);
2466     		   tmport += 0x0b;
2467     		   dev->global_map = inb(tmport++);
2468     		   dev->ultra_map = inw(tmport);
2469     		   if (dev->ultra_map == 0) {
2470     			   dev->scam_on = 0x00;
2471     			   dev->global_map = 0x20;
2472     			   dev->ultra_map = 0xffff;
2473     		   }
2474     		   shpnt = scsi_register(tpnt, 4);
2475     		   if(shpnt==NULL)
2476     			   return count;
2477     
2478     		   save_flags(flags);
2479     		   cli();
2480     		   if (request_irq(irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", dev)) {
2481     			   printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n");
2482     			   goto unregister;
2483     		   }
2484     
2485     		   if (chip_ver[h] > 0x07)	     /* check if atp876 chip   */
2486     		   {				     /* then enable terminator */
2487     		      tmport = base_io + 0x3e;
2488     		      outb(0x00, tmport);
2489     		   }
2490     
2491     		   tmport = base_io + 0x3a;
2492     		   k = (inb(tmport) & 0xf3) | 0x10;
2493     		   outb(k, tmport);
2494     		   outb((k & 0xdf), tmport);
2495     		   mydlyu(0x8000);
2496     		   outb(k, tmport);
2497     		   mydlyu(0x8000);
2498     		   tmport = base_io;
2499     		   outb((host_id | 0x08), tmport);
2500     		   tmport += 0x18;
2501     		   outb(0, tmport);
2502     		   tmport += 0x07;
2503     		   while ((inb(tmport) & 0x80) == 0);
2504     		   tmport -= 0x08;
2505     		   inb(tmport);
2506     		   tmport = base_io + 1;
2507     		   outb(8, tmport++);
2508     		   outb(0x7f, tmport);
2509     		   tmport = base_io + 0x11;
2510     		   outb(0x20, tmport);
2511     
2512     		   tscam(h);
2513     		   is870(h, base_io);
2514     		   tmport = base_io + 0x3a;
2515     		   outb((inb(tmport) & 0xef), tmport);
2516     		   tmport++;
2517     		   outb((inb(tmport) | 0x20),tmport);
2518     		}
2519     		else
2520     		{
2521     		   base_io &= 0xfffffff8;
2522     
2523     		   if (check_region(base_io,0x60) != 0)
2524     		   {
2525     			   return 0;
2526     		   }
2527     		   host_id = inb(base_io + 0x39);
2528     		   host_id >>= 0x04;
2529     
2530     		   printk(KERN_INFO "   ACARD AEC-67160 PCI Ultra160 LVD/SE SCSI Adapter: %d    IO:%x, IRQ:%d.\n"
2531     			  ,h, base_io, irq);
2532     		   dev->ioport = base_io + 0x40;
2533     		   dev->pciport = base_io + 0x28;
2534     		   dev->deviceid = dev_id[h];
2535     		   irqnumu[h] = irq;
2536     		   dev->host_idu = host_id;
2537     		   dev->chip_veru = chip_ver[h];
2538     
2539     		   tmport = base_io + 0x22;
2540     		   dev->scam_on = inb(tmport);
2541     		   tmport += 0x13;
2542     		   dev->global_map = inb(tmport);
2543     		   tmport += 0x07;
2544     		   dev->ultra_map = inw(tmport);
2545     
2546     		   n=0x3f09;
2547     next_fblk:
2548     		   if (n >= 0x4000)
2549     		   {
2550     		      goto flash_ok;
2551     		   }
2552     		   m=0;
2553     		   outw(n,base_io + 0x34);
2554     		   n += 0x0002;
2555     		   if (inb(base_io + 0x30) == 0xff)
2556     		   {
2557     		      goto flash_ok;
2558     		   }
2559     		   dev->sp[m++]=inb(base_io + 0x30);
2560     		   dev->sp[m++]=inb(base_io + 0x31);
2561     		   dev->sp[m++]=inb(base_io + 0x32);
2562     		   dev->sp[m++]=inb(base_io + 0x33);
2563     		   outw(n,base_io + 0x34);
2564     		   n += 0x0002;
2565     		   dev->sp[m++]=inb(base_io + 0x30);
2566     		   dev->sp[m++]=inb(base_io + 0x31);
2567     		   dev->sp[m++]=inb(base_io + 0x32);
2568     		   dev->sp[m++]=inb(base_io + 0x33);
2569     		   outw(n,base_io + 0x34);
2570     		   n += 0x0002;
2571     		   dev->sp[m++]=inb(base_io + 0x30);
2572     		   dev->sp[m++]=inb(base_io + 0x31);
2573     		   dev->sp[m++]=inb(base_io + 0x32);
2574     		   dev->sp[m++]=inb(base_io + 0x33);
2575     		   outw(n,base_io + 0x34);
2576     		   n += 0x0002;
2577     		   dev->sp[m++]=inb(base_io + 0x30);
2578     		   dev->sp[m++]=inb(base_io + 0x31);
2579     		   dev->sp[m++]=inb(base_io + 0x32);
2580     		   dev->sp[m++]=inb(base_io + 0x33);
2581     		   n += 0x0018;
2582     		   goto next_fblk;
2583     flash_ok:
2584     		   outw(0,base_io + 0x34);
2585     		   dev->ultra_map=0;
2586     		   dev->async = 0;
2587     		   for (k=0; k < 16; k++)
2588     		   {
2589     		       n=1;
2590     		       n = n << k;
2591     		       if (dev->sp[k] > 1)
2592     		       {
2593     			  dev->ultra_map |= n;
2594     		       }
2595     		       else
2596     		       {
2597     			  if (dev->sp[k] == 0)
2598     			  {
2599     			     dev->async |= n;
2600     			  }
2601     		       }
2602     		   }
2603     		   dev->async = ~(dev->async);
2604     		   outb(dev->global_map,base_io + 0x35);
2605     
2606     		   shpnt = scsi_register(tpnt, 4);
2607     		   if(shpnt==NULL)
2608     			   return count;
2609     
2610     		   save_flags(flags);
2611     		   cli();
2612     		   if (request_irq(irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", dev)) {
2613     			   printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n");
2614     			   goto unregister;
2615     		   }
2616     
2617     		   tmport = base_io + 0x38;
2618     		   k = inb(tmport) & 0x80;
2619     		   outb(k, tmport);
2620     		   tmport += 0x03;
2621     		   outb(0x20, tmport);
2622     		   mydlyu(0x8000);
2623     		   outb(0, tmport);
2624     		   mydlyu(0x8000);
2625     		   tmport = base_io + 0x5b;
2626     		   inb(tmport);
2627     		   tmport -= 0x04;
2628     		   inb(tmport);
2629     		   tmport = base_io + 0x40;
2630     		   outb((host_id | 0x08), tmport);
2631     		   tmport += 0x18;
2632     		   outb(0, tmport);
2633     		   tmport += 0x07;
2634     		   while ((inb(tmport) & 0x80) == 0);
2635     		   tmport -= 0x08;
2636     		   inb(tmport);
2637     		   tmport = base_io + 0x41;
2638     		   outb(8, tmport++);
2639     		   outb(0x7f, tmport);
2640     		   tmport = base_io + 0x51;
2641     		   outb(0x20, tmport);
2642     
2643     		   tscam(h);
2644     		   is880(h, base_io);
2645     		   tmport = base_io + 0x38;
2646     		   outb(0xb0, tmport);
2647     		}
2648     
2649     		atp_host[h] = shpnt;
2650     		if (dev->chip_veru == 4) {
2651     			shpnt->max_id = 16;
2652     		}
2653     		shpnt->this_id = host_id;
2654     		shpnt->unique_id = base_io;
2655     		shpnt->io_port = base_io;
2656     		if (dev_id[h] == 0x8081)
2657     		{
2658     		   shpnt->n_io_port = 0x60;	   /* Number of bytes of I/O space used */
2659     		}
2660     		else
2661     		{
2662     		   shpnt->n_io_port = 0x40;	   /* Number of bytes of I/O space used */
2663     		}
2664     		shpnt->irq = irq;
2665     		restore_flags(flags);
2666     		if (dev_id[h] == 0x8081)
2667     		{
2668     		   request_region(base_io, 0x60, "atp870u");       /* Register the IO ports that we use */
2669     		}
2670     		else
2671     		{
2672     		   request_region(base_io, 0x40, "atp870u");       /* Register the IO ports that we use */
2673     		}
2674     		count++;
2675     		index++;
2676     		continue;
2677     unregister:
2678     		scsi_unregister(shpnt);
2679     		restore_flags(flags);
2680     		index++;
2681     		continue;
2682     	}
2683     
2684     	return count;
2685     }
2686     
2687     /* The abort command does not leave the device in a clean state where
2688        it is available to be used again.  Until this gets worked out, we will
2689        leave it commented out.  */
2690     
2691     int atp870u_abort(Scsi_Cmnd * SCpnt)
2692     {
2693     	unsigned char h, j, k;
2694     	Scsi_Cmnd *workrequ;
2695     	unsigned int tmport;
2696     	struct atp_unit *dev;
2697     	for (h = 0; h <= admaxu; h++) {
2698     		if (SCpnt->host == atp_host[h]) {
2699     			goto find_adp;
2700     		}
2701     	}
2702     	panic("Abort host not found !");
2703     find_adp:
2704     	dev=&atp_unit[h];
2705     	printk(KERN_DEBUG "working=%x last_cmd=%x ", dev->working, dev->last_cmd);
2706     	printk(" quhdu=%x quendu=%x ", dev->quhdu, dev->quendu);
2707     	tmport = dev->ioport;
2708     	for (j = 0; j < 0x17; j++) {
2709     		printk(" r%2x=%2x", j, inb(tmport++));
2710     	}
2711     	tmport += 0x05;
2712     	printk(" r1c=%2x", inb(tmport));
2713     	tmport += 0x03;
2714     	printk(" r1f=%2x in_snd=%2x ", inb(tmport), dev->in_snd);
2715     	tmport= dev->pciport;
2716     	printk(" r20=%2x", inb(tmport));
2717     	tmport += 0x02;
2718     	printk(" r22=%2x", inb(tmport));
2719     	tmport = dev->ioport + 0x3a;
2720     	printk(" r3a=%2x \n",inb(tmport));
2721     	tmport = dev->ioport + 0x3b;
2722     	printk(" r3b=%2x \n",inb(tmport));
2723     	for(j=0;j<16;j++)
2724     	{
2725     	   if (dev->id[j].curr_req != NULL)
2726     	   {
2727     		workrequ = dev->id[j].curr_req;
2728     		printk("\n que cdb= ");
2729     		for (k=0; k < workrequ->cmd_len; k++)
2730     		{
2731     		    printk(" %2x ",workrequ->cmnd[k]);
2732     		}
2733     		printk(" last_lenu= %lx ",dev->id[j].last_lenu);
2734     	   }
2735     	}
2736     	return (SCSI_ABORT_SNOOZE);
2737     }
2738     
2739     int atp870u_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
2740     {
2741     	unsigned char h;
2742     	struct atp_unit *dev;
2743     	/*
2744     	 * See if a bus reset was suggested.
2745     	 */
2746     	for (h = 0; h <= admaxu; h++) {
2747     		if (SCpnt->host == atp_host[h]) {
2748     			goto find_host;
2749     		}
2750     	}
2751     	panic("Reset bus host not found !");
2752     find_host:
2753     	dev=&atp_unit[h];
2754     /*	SCpnt->result = 0x00080000;
2755     	SCpnt->scsi_done(SCpnt);
2756     	dev->working=0;
2757     	dev->quhdu=0;
2758     	dev->quendu=0;
2759     	return (SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET);  */
2760     	return (SCSI_RESET_SNOOZE);
2761     }
2762     
2763     const char *atp870u_info(struct Scsi_Host *notused)
2764     {
2765     	static char buffer[128];
2766     
2767     	strcpy(buffer, "ACARD AEC-6710/6712/67160 PCI Ultra/W/LVD SCSI-3 Adapter Driver V2.5+ac ");
2768     
2769     	return buffer;
2770     }
2771     
2772     int atp870u_set_info(char *buffer, int length, struct Scsi_Host *HBAptr)
2773     {
2774     	return -ENOSYS; 	/* Currently this is a no-op */
2775     }
2776     
2777     #define BLS buffer + len + size
2778     int atp870u_proc_info(char *buffer, char **start, off_t offset, int length,
2779     		      int hostno, int inout)
2780     {
2781     	struct Scsi_Host *HBAptr;
2782     	static u8 buff[512];
2783     	int i;
2784     	int size = 0;
2785     	int len = 0;
2786     	off_t begin = 0;
2787     	off_t pos = 0;
2788     
2789     	HBAptr = NULL;
2790     	for (i = 0; i < 2; i++) {
2791     		if ((HBAptr = atp_host[i]) != NULL) {
2792     			if (HBAptr->host_no == hostno) {
2793     				break;
2794     			}
2795     			HBAptr = NULL;
2796     		}
2797     	}
2798     
2799     	if (HBAptr == NULL) {
2800     		size += sprintf(BLS, "Can't find adapter for host number %d\n", hostno);
2801     		len += size;
2802     		pos = begin + len;
2803     		size = 0;
2804     		goto stop_output;
2805     	}
2806     	if (inout == TRUE) {	/* Has data been written to the file? */
2807     		return (atp870u_set_info(buffer, length, HBAptr));
2808     	}
2809     	if (offset == 0) {
2810     		memset(buff, 0, sizeof(buff));
2811     	}
2812     	size += sprintf(BLS, "ACARD AEC-671X Driver Version: 2.5+ac\n");
2813     	len += size;
2814     	pos = begin + len;
2815     	size = 0;
2816     
2817     	size += sprintf(BLS, "\n");
2818     	size += sprintf(BLS, "Adapter Configuration:\n");
2819     	size += sprintf(BLS, "               Base IO: %#.4lx\n", HBAptr->io_port);
2820     	size += sprintf(BLS, "                   IRQ: %d\n", HBAptr->irq);
2821     	len += size;
2822     	pos = begin + len;
2823     	size = 0;
2824     
2825     stop_output:
2826     	*start = buffer + (offset - begin);	/* Start of wanted data */
2827     	len -= (offset - begin);	/* Start slop */
2828     	if (len > length) {
2829     		len = length;	/* Ending slop */
2830     	}
2831     	return (len);
2832     }
2833     
2834     #include "sd.h"
2835     
2836     int atp870u_biosparam(Scsi_Disk * disk, kdev_t dev, int *ip)
2837     {
2838     	int heads, sectors, cylinders;
2839     
2840     	heads = 64;
2841     	sectors = 32;
2842     	cylinders = disk->capacity / (heads * sectors);
2843     
2844     	if (cylinders > 1024) {
2845     		heads = 255;
2846     		sectors = 63;
2847     		cylinders = disk->capacity / (heads * sectors);
2848     	}
2849     	ip[0] = heads;
2850     	ip[1] = sectors;
2851     	ip[2] = cylinders;
2852     
2853     	return 0;
2854     }
2855     
2856     
2857     int atp870u_release (struct Scsi_Host *pshost)
2858     {
2859     	int h;
2860     	for (h = 0; h <= admaxu; h++)
2861     	{
2862     		if (pshost == atp_host[h]) {
2863     			int k;
2864     			free_irq (pshost->irq, &atp_unit[h]);
2865     			release_region (pshost->io_port, pshost->n_io_port);
2866     			scsi_unregister(pshost);
2867     			for(k=0;k<16;k++)
2868     				kfree(atp_unit[h].id[k].prd_tableu);
2869     			return 0;
2870     		}
2871     	}
2872     	panic("atp870u: bad scsi host passed.\n");
2873     
2874     }
2875     
2876     static Scsi_Host_Template driver_template = ATP870U;
2877     #include "scsi_module.c"
2878