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