xref: /openbmc/linux/drivers/scsi/atp870u.c (revision 8569c914)
1 /*
2  *  Copyright (C) 1997	Wu Ching Chen
3  *  2.1.x update (C) 1998  Krzysztof G. Baranowski
4  *  2.5.x update (C) 2002  Red Hat <alan@redhat.com>
5  *  2.6.x update (C) 2004  Red Hat <alan@redhat.com>
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  * atp885 support add by ACARD Hao Ping Lian 2005/01/05
18  */
19 #include <linux/module.h>
20 #include <linux/init.h>
21 #include <linux/interrupt.h>
22 #include <linux/kernel.h>
23 #include <linux/types.h>
24 #include <linux/string.h>
25 #include <linux/ioport.h>
26 #include <linux/delay.h>
27 #include <linux/proc_fs.h>
28 #include <linux/spinlock.h>
29 #include <linux/pci.h>
30 #include <linux/blkdev.h>
31 #include <linux/dma-mapping.h>
32 #include <asm/system.h>
33 #include <asm/io.h>
34 
35 #include <scsi/scsi.h>
36 #include <scsi/scsi_cmnd.h>
37 #include <scsi/scsi_device.h>
38 #include <scsi/scsi_host.h>
39 
40 #include "atp870u.h"
41 
42 static struct scsi_host_template atp870u_template;
43 static void send_s870(struct atp_unit *dev,unsigned char c);
44 static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c);
45 static void tscam_885(void);
46 
47 static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
48 {
49 	unsigned long flags;
50 	unsigned short int tmpcip, id;
51 	unsigned char i, j, c, target_id, lun,cmdp;
52 	unsigned char *prd;
53 	struct scsi_cmnd *workreq;
54 	unsigned int workport, tmport, tmport1;
55 	unsigned long adrcnt, k;
56 #ifdef ED_DBGP
57 	unsigned long l;
58 #endif
59 	int errstus;
60 	struct Scsi_Host *host = dev_id;
61 	struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
62 
63 	for (c = 0; c < 2; c++) {
64 		tmport = dev->ioport[c] + 0x1f;
65 		j = inb(tmport);
66 		if ((j & 0x80) != 0)
67 		{
68 	   		goto ch_sel;
69 		}
70 		dev->in_int[c] = 0;
71 	}
72 	return IRQ_NONE;
73 ch_sel:
74 #ifdef ED_DBGP
75 	printk("atp870u_intr_handle enter\n");
76 #endif
77 	dev->in_int[c] = 1;
78 	cmdp = inb(dev->ioport[c] + 0x10);
79 	workport = dev->ioport[c];
80 	if (dev->working[c] != 0) {
81 		if (dev->dev_id == ATP885_DEVID) {
82 			tmport1 = workport + 0x16;
83 			if ((inb(tmport1) & 0x80) == 0)
84 				outb((inb(tmport1) | 0x80), tmport1);
85 		}
86 		tmpcip = dev->pciport[c];
87 		if ((inb(tmpcip) & 0x08) != 0)
88 		{
89 			tmpcip += 0x2;
90 			for (k=0; k < 1000; k++) {
91 				if ((inb(tmpcip) & 0x08) == 0) {
92 					goto stop_dma;
93 				}
94 				if ((inb(tmpcip) & 0x01) == 0) {
95 					goto stop_dma;
96 				}
97 			}
98 		}
99 stop_dma:
100 		tmpcip = dev->pciport[c];
101 		outb(0x00, tmpcip);
102 		tmport -= 0x08;
103 
104 		i = inb(tmport);
105 
106 		if (dev->dev_id == ATP885_DEVID) {
107 			tmpcip += 2;
108 			outb(0x06, tmpcip);
109 			tmpcip -= 2;
110 		}
111 
112 		tmport -= 0x02;
113 		target_id = inb(tmport);
114 		tmport += 0x02;
115 
116 		/*
117 		 *	Remap wide devices onto id numbers
118 		 */
119 
120 		if ((target_id & 0x40) != 0) {
121 			target_id = (target_id & 0x07) | 0x08;
122 		} else {
123 			target_id &= 0x07;
124 		}
125 
126 		if ((j & 0x40) != 0) {
127 		     if (dev->last_cmd[c] == 0xff) {
128 			dev->last_cmd[c] = target_id;
129 		     }
130 		     dev->last_cmd[c] |= 0x40;
131 		}
132 		if (dev->dev_id == ATP885_DEVID)
133 			dev->r1f[c][target_id] |= j;
134 #ifdef ED_DBGP
135 		printk("atp870u_intr_handle status = %x\n",i);
136 #endif
137 		if (i == 0x85) {
138 			if ((dev->last_cmd[c] & 0xf0) != 0x40) {
139 			   dev->last_cmd[c] = 0xff;
140 			}
141 			if (dev->dev_id == ATP885_DEVID) {
142 				tmport -= 0x05;
143 				adrcnt = 0;
144 				((unsigned char *) &adrcnt)[2] = inb(tmport++);
145 				((unsigned char *) &adrcnt)[1] = inb(tmport++);
146 				((unsigned char *) &adrcnt)[0] = inb(tmport);
147 				if (dev->id[c][target_id].last_len != adrcnt)
148 				{
149 			   		k = dev->id[c][target_id].last_len;
150 			   		k -= adrcnt;
151 			   		dev->id[c][target_id].tran_len = k;
152 			   	dev->id[c][target_id].last_len = adrcnt;
153 				}
154 #ifdef ED_DBGP
155 				printk("tmport = %x dev->id[c][target_id].last_len = %d dev->id[c][target_id].tran_len = %d\n",tmport,dev->id[c][target_id].last_len,dev->id[c][target_id].tran_len);
156 #endif
157 			}
158 
159 			/*
160 			 *      Flip wide
161 			 */
162 			if (dev->wide_id[c] != 0) {
163 				tmport = workport + 0x1b;
164 				outb(0x01, tmport);
165 				while ((inb(tmport) & 0x01) != 0x01) {
166 					outb(0x01, tmport);
167 				}
168 			}
169 			/*
170 			 *	Issue more commands
171 			 */
172 			spin_lock_irqsave(dev->host->host_lock, flags);
173 			if (((dev->quhd[c] != dev->quend[c]) || (dev->last_cmd[c] != 0xff)) &&
174 			    (dev->in_snd[c] == 0)) {
175 #ifdef ED_DBGP
176 				printk("Call sent_s870\n");
177 #endif
178 				send_s870(dev,c);
179 			}
180 			spin_unlock_irqrestore(dev->host->host_lock, flags);
181 			/*
182 			 *	Done
183 			 */
184 			dev->in_int[c] = 0;
185 #ifdef ED_DBGP
186 				printk("Status 0x85 return\n");
187 #endif
188 			goto handled;
189 		}
190 
191 		if (i == 0x40) {
192 		     dev->last_cmd[c] |= 0x40;
193 		     dev->in_int[c] = 0;
194 		     goto handled;
195 		}
196 
197 		if (i == 0x21) {
198 			if ((dev->last_cmd[c] & 0xf0) != 0x40) {
199 			   dev->last_cmd[c] = 0xff;
200 			}
201 			tmport -= 0x05;
202 			adrcnt = 0;
203 			((unsigned char *) &adrcnt)[2] = inb(tmport++);
204 			((unsigned char *) &adrcnt)[1] = inb(tmport++);
205 			((unsigned char *) &adrcnt)[0] = inb(tmport);
206 			k = dev->id[c][target_id].last_len;
207 			k -= adrcnt;
208 			dev->id[c][target_id].tran_len = k;
209 			dev->id[c][target_id].last_len = adrcnt;
210 			tmport -= 0x04;
211 			outb(0x41, tmport);
212 			tmport += 0x08;
213 			outb(0x08, tmport);
214 			dev->in_int[c] = 0;
215 			goto handled;
216 		}
217 
218 		if (dev->dev_id == ATP885_DEVID) {
219 			if ((i == 0x4c) || (i == 0x4d) || (i == 0x8c) || (i == 0x8d)) {
220 		   		if ((i == 0x4c) || (i == 0x8c))
221 		      			i=0x48;
222 		   		else
223 		      			i=0x49;
224 		   	}
225 
226 		}
227 		if ((i == 0x80) || (i == 0x8f)) {
228 #ifdef ED_DBGP
229 			printk(KERN_DEBUG "Device reselect\n");
230 #endif
231 			lun = 0;
232 			tmport -= 0x07;
233 			if (cmdp == 0x44 || i==0x80) {
234 				tmport += 0x0d;
235 				lun = inb(tmport) & 0x07;
236 			} else {
237 				if ((dev->last_cmd[c] & 0xf0) != 0x40) {
238 				   dev->last_cmd[c] = 0xff;
239 				}
240 				if (cmdp == 0x41) {
241 #ifdef ED_DBGP
242 					printk("cmdp = 0x41\n");
243 #endif
244 					tmport += 0x02;
245 					adrcnt = 0;
246 					((unsigned char *) &adrcnt)[2] = inb(tmport++);
247 					((unsigned char *) &adrcnt)[1] = inb(tmport++);
248 					((unsigned char *) &adrcnt)[0] = inb(tmport);
249 					k = dev->id[c][target_id].last_len;
250 					k -= adrcnt;
251 					dev->id[c][target_id].tran_len = k;
252 					dev->id[c][target_id].last_len = adrcnt;
253 					tmport += 0x04;
254 					outb(0x08, tmport);
255 					dev->in_int[c] = 0;
256 					goto handled;
257 				} else {
258 #ifdef ED_DBGP
259 					printk("cmdp != 0x41\n");
260 #endif
261 					outb(0x46, tmport);
262 					dev->id[c][target_id].dirct = 0x00;
263 					tmport += 0x02;
264 					outb(0x00, tmport++);
265 					outb(0x00, tmport++);
266 					outb(0x00, tmport++);
267 					tmport += 0x03;
268 					outb(0x08, tmport);
269 					dev->in_int[c] = 0;
270 					goto handled;
271 				}
272 			}
273 			if (dev->last_cmd[c] != 0xff) {
274 			   dev->last_cmd[c] |= 0x40;
275 			}
276 			if (dev->dev_id == ATP885_DEVID) {
277 				j = inb(dev->baseport + 0x29) & 0xfe;
278 				outb(j, dev->baseport + 0x29);
279 				tmport = workport + 0x16;
280 			} else {
281 				tmport = workport + 0x10;
282 				outb(0x45, tmport);
283 				tmport += 0x06;
284 			}
285 
286 			target_id = inb(tmport);
287 			/*
288 			 *	Remap wide identifiers
289 			 */
290 			if ((target_id & 0x10) != 0) {
291 				target_id = (target_id & 0x07) | 0x08;
292 			} else {
293 				target_id &= 0x07;
294 			}
295 			if (dev->dev_id == ATP885_DEVID) {
296 				tmport = workport + 0x10;
297 				outb(0x45, tmport);
298 			}
299 			workreq = dev->id[c][target_id].curr_req;
300 #ifdef ED_DBGP
301 			scmd_printk(KERN_DEBUG, workreq, "CDB");
302 			for (l = 0; l < workreq->cmd_len; l++)
303 				printk(KERN_DEBUG " %x",workreq->cmnd[l]);
304 			printk("\n");
305 #endif
306 
307 			tmport = workport + 0x0f;
308 			outb(lun, tmport);
309 			tmport += 0x02;
310 			outb(dev->id[c][target_id].devsp, tmport++);
311 			adrcnt = dev->id[c][target_id].tran_len;
312 			k = dev->id[c][target_id].last_len;
313 
314 			outb(((unsigned char *) &k)[2], tmport++);
315 			outb(((unsigned char *) &k)[1], tmport++);
316 			outb(((unsigned char *) &k)[0], tmport++);
317 #ifdef ED_DBGP
318 			printk("k %x, k[0] 0x%x k[1] 0x%x k[2] 0x%x\n", k, inb(tmport-1), inb(tmport-2), inb(tmport-3));
319 #endif
320 			/* Remap wide */
321 			j = target_id;
322 			if (target_id > 7) {
323 				j = (j & 0x07) | 0x40;
324 			}
325 			/* Add direction */
326 			j |= dev->id[c][target_id].dirct;
327 			outb(j, tmport++);
328 			outb(0x80,tmport);
329 
330 			/* enable 32 bit fifo transfer */
331 			if (dev->dev_id == ATP885_DEVID) {
332 				tmpcip = dev->pciport[c] + 1;
333 				i=inb(tmpcip) & 0xf3;
334 				//j=workreq->cmnd[0];
335 				if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) {
336 				   i |= 0x0c;
337 				}
338 				outb(i,tmpcip);
339 			} else if ((dev->dev_id == ATP880_DEVID1) ||
340 	    		    	   (dev->dev_id == ATP880_DEVID2) ) {
341 				tmport = workport - 0x05;
342 				if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) {
343 					outb((unsigned char) ((inb(tmport) & 0x3f) | 0xc0), tmport);
344 				} else {
345 					outb((unsigned char) (inb(tmport) & 0x3f), tmport);
346 				}
347 			} else {
348 				tmport = workport + 0x3a;
349 				if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) {
350 					outb((unsigned char) ((inb(tmport) & 0xf3) | 0x08), tmport);
351 				} else {
352 					outb((unsigned char) (inb(tmport) & 0xf3), tmport);
353 				}
354 			}
355 			tmport = workport + 0x1b;
356 			j = 0;
357 			id = 1;
358 			id = id << target_id;
359 			/*
360 			 *	Is this a wide device
361 			 */
362 			if ((id & dev->wide_id[c]) != 0) {
363 				j |= 0x01;
364 			}
365 			outb(j, tmport);
366 			while ((inb(tmport) & 0x01) != j) {
367 				outb(j,tmport);
368 			}
369 			if (dev->id[c][target_id].last_len == 0) {
370 				tmport = workport + 0x18;
371 				outb(0x08, tmport);
372 				dev->in_int[c] = 0;
373 #ifdef ED_DBGP
374 				printk("dev->id[c][target_id].last_len = 0\n");
375 #endif
376 				goto handled;
377 			}
378 #ifdef ED_DBGP
379 			printk("target_id = %d adrcnt = %d\n",target_id,adrcnt);
380 #endif
381 			prd = dev->id[c][target_id].prd_pos;
382 			while (adrcnt != 0) {
383 				id = ((unsigned short int *)prd)[2];
384 				if (id == 0) {
385 					k = 0x10000;
386 				} else {
387 					k = id;
388 				}
389 				if (k > adrcnt) {
390 					((unsigned short int *)prd)[2] = (unsigned short int)
391 					    (k - adrcnt);
392 					((unsigned long *)prd)[0] += adrcnt;
393 					adrcnt = 0;
394 					dev->id[c][target_id].prd_pos = prd;
395 				} else {
396 					adrcnt -= k;
397 					dev->id[c][target_id].prdaddr += 0x08;
398 					prd += 0x08;
399 					if (adrcnt == 0) {
400 						dev->id[c][target_id].prd_pos = prd;
401 					}
402 				}
403 			}
404 			tmpcip = dev->pciport[c] + 0x04;
405 			outl(dev->id[c][target_id].prdaddr, tmpcip);
406 #ifdef ED_DBGP
407 			printk("dev->id[%d][%d].prdaddr 0x%8x\n", c, target_id, dev->id[c][target_id].prdaddr);
408 #endif
409 			if (dev->dev_id == ATP885_DEVID) {
410 				tmpcip -= 0x04;
411 			} else {
412 				tmpcip -= 0x02;
413 				outb(0x06, tmpcip);
414 				outb(0x00, tmpcip);
415 				tmpcip -= 0x02;
416 			}
417 			tmport = workport + 0x18;
418 			/*
419 			 *	Check transfer direction
420 			 */
421 			if (dev->id[c][target_id].dirct != 0) {
422 				outb(0x08, tmport);
423 				outb(0x01, tmpcip);
424 				dev->in_int[c] = 0;
425 #ifdef ED_DBGP
426 				printk("status 0x80 return dirct != 0\n");
427 #endif
428 				goto handled;
429 			}
430 			outb(0x08, tmport);
431 			outb(0x09, tmpcip);
432 			dev->in_int[c] = 0;
433 #ifdef ED_DBGP
434 			printk("status 0x80 return dirct = 0\n");
435 #endif
436 			goto handled;
437 		}
438 
439 		/*
440 		 *	Current scsi request on this target
441 		 */
442 
443 		workreq = dev->id[c][target_id].curr_req;
444 
445 		if (i == 0x42) {
446 			if ((dev->last_cmd[c] & 0xf0) != 0x40)
447 			{
448 			   dev->last_cmd[c] = 0xff;
449 			}
450 			errstus = 0x02;
451 			workreq->result = errstus;
452 			goto go_42;
453 		}
454 		if (i == 0x16) {
455 			if ((dev->last_cmd[c] & 0xf0) != 0x40) {
456 			   dev->last_cmd[c] = 0xff;
457 			}
458 			errstus = 0;
459 			tmport -= 0x08;
460 			errstus = inb(tmport);
461 			if (((dev->r1f[c][target_id] & 0x10) != 0)&&(dev->dev_id==ATP885_DEVID)) {
462 			   printk(KERN_WARNING "AEC67162 CRC ERROR !\n");
463 			   errstus = 0x02;
464 			}
465 			workreq->result = errstus;
466 go_42:
467 			if (dev->dev_id == ATP885_DEVID) {
468 				j = inb(dev->baseport + 0x29) | 0x01;
469 				outb(j, dev->baseport + 0x29);
470 			}
471 			/*
472 			 *	Complete the command
473 			 */
474 			scsi_dma_unmap(workreq);
475 
476 			spin_lock_irqsave(dev->host->host_lock, flags);
477 			(*workreq->scsi_done) (workreq);
478 #ifdef ED_DBGP
479 			   printk("workreq->scsi_done\n");
480 #endif
481 			/*
482 			 *	Clear it off the queue
483 			 */
484 			dev->id[c][target_id].curr_req = NULL;
485 			dev->working[c]--;
486 			spin_unlock_irqrestore(dev->host->host_lock, flags);
487 			/*
488 			 *      Take it back wide
489 			 */
490 			if (dev->wide_id[c] != 0) {
491 				tmport = workport + 0x1b;
492 				outb(0x01, tmport);
493 				while ((inb(tmport) & 0x01) != 0x01) {
494 					outb(0x01, tmport);
495 				}
496 			}
497 			/*
498 			 *	If there is stuff to send and nothing going then send it
499 			 */
500 			spin_lock_irqsave(dev->host->host_lock, flags);
501 			if (((dev->last_cmd[c] != 0xff) || (dev->quhd[c] != dev->quend[c])) &&
502 			    (dev->in_snd[c] == 0)) {
503 #ifdef ED_DBGP
504 			   printk("Call sent_s870(scsi_done)\n");
505 #endif
506 			   send_s870(dev,c);
507 			}
508 			spin_unlock_irqrestore(dev->host->host_lock, flags);
509 			dev->in_int[c] = 0;
510 			goto handled;
511 		}
512 		if ((dev->last_cmd[c] & 0xf0) != 0x40) {
513 		   dev->last_cmd[c] = 0xff;
514 		}
515 		if (i == 0x4f) {
516 			i = 0x89;
517 		}
518 		i &= 0x0f;
519 		if (i == 0x09) {
520 			tmpcip += 4;
521 			outl(dev->id[c][target_id].prdaddr, tmpcip);
522 			tmpcip = tmpcip - 2;
523 			outb(0x06, tmpcip);
524 			outb(0x00, tmpcip);
525 			tmpcip = tmpcip - 2;
526 			tmport = workport + 0x10;
527 			outb(0x41, tmport);
528 			if (dev->dev_id == ATP885_DEVID) {
529 				tmport += 2;
530 				k = dev->id[c][target_id].last_len;
531 				outb((unsigned char) (((unsigned char *) (&k))[2]), tmport++);
532 				outb((unsigned char) (((unsigned char *) (&k))[1]), tmport++);
533 				outb((unsigned char) (((unsigned char *) (&k))[0]), tmport);
534 				dev->id[c][target_id].dirct = 0x00;
535 				tmport += 0x04;
536 			} else {
537 				dev->id[c][target_id].dirct = 0x00;
538 				tmport += 0x08;
539 			}
540 			outb(0x08, tmport);
541 			outb(0x09, tmpcip);
542 			dev->in_int[c] = 0;
543 			goto handled;
544 		}
545 		if (i == 0x08) {
546 			tmpcip += 4;
547 			outl(dev->id[c][target_id].prdaddr, tmpcip);
548 			tmpcip = tmpcip - 2;
549 			outb(0x06, tmpcip);
550 			outb(0x00, tmpcip);
551 			tmpcip = tmpcip - 2;
552 			tmport = workport + 0x10;
553 			outb(0x41, tmport);
554 			if (dev->dev_id == ATP885_DEVID) {
555 				tmport += 2;
556 				k = dev->id[c][target_id].last_len;
557 				outb((unsigned char) (((unsigned char *) (&k))[2]), tmport++);
558 				outb((unsigned char) (((unsigned char *) (&k))[1]), tmport++);
559 				outb((unsigned char) (((unsigned char *) (&k))[0]), tmport++);
560 			} else {
561 				tmport += 5;
562 			}
563 			outb((unsigned char) (inb(tmport) | 0x20), tmport);
564 			dev->id[c][target_id].dirct = 0x20;
565 			tmport += 0x03;
566 			outb(0x08, tmport);
567 			outb(0x01, tmpcip);
568 			dev->in_int[c] = 0;
569 			goto handled;
570 		}
571 		tmport -= 0x07;
572 		if (i == 0x0a) {
573 			outb(0x30, tmport);
574 		} else {
575 			outb(0x46, tmport);
576 		}
577 		dev->id[c][target_id].dirct = 0x00;
578 		tmport += 0x02;
579 		outb(0x00, tmport++);
580 		outb(0x00, tmport++);
581 		outb(0x00, tmport++);
582 		tmport += 0x03;
583 		outb(0x08, tmport);
584 		dev->in_int[c] = 0;
585 		goto handled;
586 	} else {
587 //		tmport = workport + 0x17;
588 //		inb(tmport);
589 //		dev->working[c] = 0;
590 		dev->in_int[c] = 0;
591 		goto handled;
592 	}
593 
594 handled:
595 #ifdef ED_DBGP
596 	printk("atp870u_intr_handle exit\n");
597 #endif
598 	return IRQ_HANDLED;
599 }
600 /**
601  *	atp870u_queuecommand	-	Queue SCSI command
602  *	@req_p: request block
603  *	@done: completion function
604  *
605  *	Queue a command to the ATP queue. Called with the host lock held.
606  */
607 static int atp870u_queuecommand(struct scsi_cmnd * req_p,
608 			 void (*done) (struct scsi_cmnd *))
609 {
610 	unsigned char c;
611 	unsigned int tmport,m;
612 	struct atp_unit *dev;
613 	struct Scsi_Host *host;
614 
615 	c = scmd_channel(req_p);
616 	req_p->sense_buffer[0]=0;
617 	scsi_set_resid(req_p, 0);
618 	if (scmd_channel(req_p) > 1) {
619 		req_p->result = 0x00040000;
620 		done(req_p);
621 #ifdef ED_DBGP
622 		printk("atp870u_queuecommand : req_p->device->channel > 1\n");
623 #endif
624 		return 0;
625 	}
626 
627 	host = req_p->device->host;
628 	dev = (struct atp_unit *)&host->hostdata;
629 
630 
631 
632 	m = 1;
633 	m = m << scmd_id(req_p);
634 
635 	/*
636 	 *      Fake a timeout for missing targets
637 	 */
638 
639 	if ((m & dev->active_id[c]) == 0) {
640 		req_p->result = 0x00040000;
641 		done(req_p);
642 		return 0;
643 	}
644 
645 	if (done) {
646 		req_p->scsi_done = done;
647 	} else {
648 #ifdef ED_DBGP
649 		printk( "atp870u_queuecommand: done can't be NULL\n");
650 #endif
651 		req_p->result = 0;
652 		done(req_p);
653 		return 0;
654 	}
655 
656 	/*
657 	 *	Count new command
658 	 */
659 	dev->quend[c]++;
660 	if (dev->quend[c] >= qcnt) {
661 		dev->quend[c] = 0;
662 	}
663 
664 	/*
665 	 *	Check queue state
666 	 */
667 	if (dev->quhd[c] == dev->quend[c]) {
668 		if (dev->quend[c] == 0) {
669 			dev->quend[c] = qcnt;
670 		}
671 #ifdef ED_DBGP
672 		printk("atp870u_queuecommand : dev->quhd[c] == dev->quend[c]\n");
673 #endif
674 		dev->quend[c]--;
675 		req_p->result = 0x00020000;
676 		done(req_p);
677 		return 0;
678 	}
679 	dev->quereq[c][dev->quend[c]] = req_p;
680 	tmport = dev->ioport[c] + 0x1c;
681 #ifdef ED_DBGP
682 	printk("dev->ioport[c] = %x inb(tmport) = %x dev->in_int[%d] = %d dev->in_snd[%d] = %d\n",dev->ioport[c],inb(tmport),c,dev->in_int[c],c,dev->in_snd[c]);
683 #endif
684 	if ((inb(tmport) == 0) && (dev->in_int[c] == 0) && (dev->in_snd[c] == 0)) {
685 #ifdef ED_DBGP
686 		printk("Call sent_s870(atp870u_queuecommand)\n");
687 #endif
688 		send_s870(dev,c);
689 	}
690 #ifdef ED_DBGP
691 	printk("atp870u_queuecommand : exit\n");
692 #endif
693 	return 0;
694 }
695 
696 /**
697  *	send_s870	-	send a command to the controller
698  *	@host: host
699  *
700  *	On entry there is work queued to be done. We move some of that work to the
701  *	controller itself.
702  *
703  *	Caller holds the host lock.
704  */
705 static void send_s870(struct atp_unit *dev,unsigned char c)
706 {
707 	unsigned int tmport;
708 	struct scsi_cmnd *workreq;
709 	unsigned int i;//,k;
710 	unsigned char  j, target_id;
711 	unsigned char *prd;
712 	unsigned short int tmpcip, w;
713 	unsigned long l, bttl = 0;
714 	unsigned int workport;
715 	unsigned long  sg_count;
716 
717 	if (dev->in_snd[c] != 0) {
718 #ifdef ED_DBGP
719 		printk("cmnd in_snd\n");
720 #endif
721 		return;
722 	}
723 #ifdef ED_DBGP
724 	printk("Sent_s870 enter\n");
725 #endif
726 	dev->in_snd[c] = 1;
727 	if ((dev->last_cmd[c] != 0xff) && ((dev->last_cmd[c] & 0x40) != 0)) {
728 		dev->last_cmd[c] &= 0x0f;
729 		workreq = dev->id[c][dev->last_cmd[c]].curr_req;
730 		if (workreq != NULL) {	/* check NULL pointer */
731 		   goto cmd_subp;
732 		}
733 		dev->last_cmd[c] = 0xff;
734 		if (dev->quhd[c] == dev->quend[c]) {
735 		   	dev->in_snd[c] = 0;
736 		   	return ;
737 		}
738 	}
739 	if ((dev->last_cmd[c] != 0xff) && (dev->working[c] != 0)) {
740 	     	dev->in_snd[c] = 0;
741 	     	return ;
742 	}
743 	dev->working[c]++;
744 	j = dev->quhd[c];
745 	dev->quhd[c]++;
746 	if (dev->quhd[c] >= qcnt) {
747 		dev->quhd[c] = 0;
748 	}
749 	workreq = dev->quereq[c][dev->quhd[c]];
750 	if (dev->id[c][scmd_id(workreq)].curr_req == NULL) {
751 		dev->id[c][scmd_id(workreq)].curr_req = workreq;
752 		dev->last_cmd[c] = scmd_id(workreq);
753 		goto cmd_subp;
754 	}
755 	dev->quhd[c] = j;
756 	dev->working[c]--;
757 	dev->in_snd[c] = 0;
758 	return;
759 cmd_subp:
760 	workport = dev->ioport[c];
761 	tmport = workport + 0x1f;
762 	if ((inb(tmport) & 0xb0) != 0) {
763 		goto abortsnd;
764 	}
765 	tmport = workport + 0x1c;
766 	if (inb(tmport) == 0) {
767 		goto oktosend;
768 	}
769 abortsnd:
770 #ifdef ED_DBGP
771 	printk("Abort to Send\n");
772 #endif
773 	dev->last_cmd[c] |= 0x40;
774 	dev->in_snd[c] = 0;
775 	return;
776 oktosend:
777 #ifdef ED_DBGP
778 	printk("OK to Send\n");
779 	scmd_printk(KERN_DEBUG, workreq, "CDB");
780 	for(i=0;i<workreq->cmd_len;i++) {
781 		printk(" %x",workreq->cmnd[i]);
782 	}
783 	printk("\n");
784 #endif
785 	l = scsi_bufflen(workreq);
786 
787 	if (dev->dev_id == ATP885_DEVID) {
788 		j = inb(dev->baseport + 0x29) & 0xfe;
789 		outb(j, dev->baseport + 0x29);
790 		dev->r1f[c][scmd_id(workreq)] = 0;
791 	}
792 
793 	if (workreq->cmnd[0] == READ_CAPACITY) {
794 		if (l > 8)
795 			l = 8;
796 	}
797 	if (workreq->cmnd[0] == 0x00) {
798 		l = 0;
799 	}
800 
801 	tmport = workport + 0x1b;
802 	j = 0;
803 	target_id = scmd_id(workreq);
804 
805 	/*
806 	 *	Wide ?
807 	 */
808 	w = 1;
809 	w = w << target_id;
810 	if ((w & dev->wide_id[c]) != 0) {
811 		j |= 0x01;
812 	}
813 	outb(j, tmport);
814 	while ((inb(tmport) & 0x01) != j) {
815 		outb(j,tmport);
816 #ifdef ED_DBGP
817 		printk("send_s870 while loop 1\n");
818 #endif
819 	}
820 	/*
821 	 *	Write the command
822 	 */
823 
824 	tmport = workport;
825 	outb(workreq->cmd_len, tmport++);
826 	outb(0x2c, tmport++);
827 	if (dev->dev_id == ATP885_DEVID) {
828 		outb(0x7f, tmport++);
829 	} else {
830 		outb(0xcf, tmport++);
831 	}
832 	for (i = 0; i < workreq->cmd_len; i++) {
833 		outb(workreq->cmnd[i], tmport++);
834 	}
835 	tmport = workport + 0x0f;
836 	outb(workreq->device->lun, tmport);
837 	tmport += 0x02;
838 	/*
839 	 *	Write the target
840 	 */
841 	outb(dev->id[c][target_id].devsp, tmport++);
842 #ifdef ED_DBGP
843 	printk("dev->id[%d][%d].devsp = %2x\n",c,target_id,dev->id[c][target_id].devsp);
844 #endif
845 
846 	sg_count = scsi_dma_map(workreq);
847 	/*
848 	 *	Write transfer size
849 	 */
850 	outb((unsigned char) (((unsigned char *) (&l))[2]), tmport++);
851 	outb((unsigned char) (((unsigned char *) (&l))[1]), tmport++);
852 	outb((unsigned char) (((unsigned char *) (&l))[0]), tmport++);
853 	j = target_id;
854 	dev->id[c][j].last_len = l;
855 	dev->id[c][j].tran_len = 0;
856 #ifdef ED_DBGP
857 	printk("dev->id[%2d][%2d].last_len = %d\n",c,j,dev->id[c][j].last_len);
858 #endif
859 	/*
860 	 *	Flip the wide bits
861 	 */
862 	if ((j & 0x08) != 0) {
863 		j = (j & 0x07) | 0x40;
864 	}
865 	/*
866 	 *	Check transfer direction
867 	 */
868 	if (workreq->sc_data_direction == DMA_TO_DEVICE) {
869 		outb((unsigned char) (j | 0x20), tmport++);
870 	} else {
871 		outb(j, tmport++);
872 	}
873 	outb((unsigned char) (inb(tmport) | 0x80), tmport);
874 	outb(0x80, tmport);
875 	tmport = workport + 0x1c;
876 	dev->id[c][target_id].dirct = 0;
877 	if (l == 0) {
878 		if (inb(tmport) == 0) {
879 			tmport = workport + 0x18;
880 #ifdef ED_DBGP
881 			printk("change SCSI_CMD_REG 0x08\n");
882 #endif
883 			outb(0x08, tmport);
884 		} else {
885 			dev->last_cmd[c] |= 0x40;
886 		}
887 		dev->in_snd[c] = 0;
888 		return;
889 	}
890 	tmpcip = dev->pciport[c];
891 	prd = dev->id[c][target_id].prd_table;
892 	dev->id[c][target_id].prd_pos = prd;
893 
894 	/*
895 	 *	Now write the request list. Either as scatter/gather or as
896 	 *	a linear chain.
897 	 */
898 
899 	if (l) {
900 		struct scatterlist *sgpnt;
901 		i = 0;
902 		scsi_for_each_sg(workreq, sgpnt, sg_count, j) {
903 			bttl = sg_dma_address(sgpnt);
904 			l=sg_dma_len(sgpnt);
905 #ifdef ED_DBGP
906 			printk("1. bttl %x, l %x\n",bttl, l);
907 #endif
908 			while (l > 0x10000) {
909 				(((u16 *) (prd))[i + 3]) = 0x0000;
910 				(((u16 *) (prd))[i + 2]) = 0x0000;
911 				(((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl);
912 				l -= 0x10000;
913 				bttl += 0x10000;
914 				i += 0x04;
915 			}
916 			(((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl);
917 			(((u16 *) (prd))[i + 2]) = cpu_to_le16(l);
918 			(((u16 *) (prd))[i + 3]) = 0;
919 			i += 0x04;
920 		}
921 		(((u16 *) (prd))[i - 1]) = cpu_to_le16(0x8000);
922 #ifdef ED_DBGP
923 		printk("prd %4x %4x %4x %4x\n",(((unsigned short int *)prd)[0]),(((unsigned short int *)prd)[1]),(((unsigned short int *)prd)[2]),(((unsigned short int *)prd)[3]));
924 		printk("2. bttl %x, l %x\n",bttl, l);
925 #endif
926 	}
927 	tmpcip += 4;
928 #ifdef ED_DBGP
929 	printk("send_s870: prdaddr_2 0x%8x tmpcip %x target_id %d\n", dev->id[c][target_id].prdaddr,tmpcip,target_id);
930 #endif
931 	dev->id[c][target_id].prdaddr = dev->id[c][target_id].prd_bus;
932 	outl(dev->id[c][target_id].prdaddr, tmpcip);
933 	tmpcip = tmpcip - 2;
934 	outb(0x06, tmpcip);
935 	outb(0x00, tmpcip);
936 	if (dev->dev_id == ATP885_DEVID) {
937 		tmpcip--;
938 		j=inb(tmpcip) & 0xf3;
939 		if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) ||
940 	    	(workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) {
941 	   		j |= 0x0c;
942 		}
943 		outb(j,tmpcip);
944 		tmpcip--;
945 	} else if ((dev->dev_id == ATP880_DEVID1) ||
946 	    	   (dev->dev_id == ATP880_DEVID2)) {
947 		tmpcip =tmpcip -2;
948 		tmport = workport - 0x05;
949 		if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) {
950 			outb((unsigned char) ((inb(tmport) & 0x3f) | 0xc0), tmport);
951 		} else {
952 			outb((unsigned char) (inb(tmport) & 0x3f), tmport);
953 		}
954 	} else {
955 		tmpcip =tmpcip -2;
956 		tmport = workport + 0x3a;
957 		if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) {
958 			outb((inb(tmport) & 0xf3) | 0x08, tmport);
959 		} else {
960 			outb(inb(tmport) & 0xf3, tmport);
961 		}
962 	}
963 	tmport = workport + 0x1c;
964 
965 	if(workreq->sc_data_direction == DMA_TO_DEVICE) {
966 		dev->id[c][target_id].dirct = 0x20;
967 		if (inb(tmport) == 0) {
968 			tmport = workport + 0x18;
969 			outb(0x08, tmport);
970 			outb(0x01, tmpcip);
971 #ifdef ED_DBGP
972 		printk( "start DMA(to target)\n");
973 #endif
974 		} else {
975 			dev->last_cmd[c] |= 0x40;
976 		}
977 		dev->in_snd[c] = 0;
978 		return;
979 	}
980 	if (inb(tmport) == 0) {
981 		tmport = workport + 0x18;
982 		outb(0x08, tmport);
983 		outb(0x09, tmpcip);
984 #ifdef ED_DBGP
985 		printk( "start DMA(to host)\n");
986 #endif
987 	} else {
988 		dev->last_cmd[c] |= 0x40;
989 	}
990 	dev->in_snd[c] = 0;
991 	return;
992 
993 }
994 
995 static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val)
996 {
997 	unsigned int tmport;
998 	unsigned short int i, k;
999 	unsigned char j;
1000 
1001 	tmport = dev->ioport[0] + 0x1c;
1002 	outw(*val, tmport);
1003 FUN_D7:
1004 	for (i = 0; i < 10; i++) {	/* stable >= bus settle delay(400 ns)  */
1005 		k = inw(tmport);
1006 		j = (unsigned char) (k >> 8);
1007 		if ((k & 0x8000) != 0) {	/* DB7 all release?    */
1008 			goto FUN_D7;
1009 		}
1010 	}
1011 	*val |= 0x4000;		/* assert DB6           */
1012 	outw(*val, tmport);
1013 	*val &= 0xdfff;		/* assert DB5           */
1014 	outw(*val, tmport);
1015 FUN_D5:
1016 	for (i = 0; i < 10; i++) {	/* stable >= bus settle delay(400 ns) */
1017 		if ((inw(tmport) & 0x2000) != 0) {	/* DB5 all release?       */
1018 			goto FUN_D5;
1019 		}
1020 	}
1021 	*val |= 0x8000;		/* no DB4-0, assert DB7    */
1022 	*val &= 0xe0ff;
1023 	outw(*val, tmport);
1024 	*val &= 0xbfff;		/* release DB6             */
1025 	outw(*val, tmport);
1026 FUN_D6:
1027 	for (i = 0; i < 10; i++) {	/* stable >= bus settle delay(400 ns)  */
1028 		if ((inw(tmport) & 0x4000) != 0) {	/* DB6 all release?  */
1029 			goto FUN_D6;
1030 		}
1031 	}
1032 
1033 	return j;
1034 }
1035 
1036 static void tscam(struct Scsi_Host *host)
1037 {
1038 
1039 	unsigned int tmport;
1040 	unsigned char i, j, k;
1041 	unsigned long n;
1042 	unsigned short int m, assignid_map, val;
1043 	unsigned char mbuf[33], quintet[2];
1044 	struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
1045 	static unsigned char g2q_tab[8] = {
1046 		0x38, 0x31, 0x32, 0x2b, 0x34, 0x2d, 0x2e, 0x27
1047 	};
1048 
1049 /*  I can't believe we need this before we've even done anything.  Remove it
1050  *  and see if anyone bitches.
1051 	for (i = 0; i < 0x10; i++) {
1052 		udelay(0xffff);
1053 	}
1054  */
1055 
1056 	tmport = dev->ioport[0] + 1;
1057 	outb(0x08, tmport++);
1058 	outb(0x7f, tmport);
1059 	tmport = dev->ioport[0] + 0x11;
1060 	outb(0x20, tmport);
1061 
1062 	if ((dev->scam_on & 0x40) == 0) {
1063 		return;
1064 	}
1065 	m = 1;
1066 	m <<= dev->host_id[0];
1067 	j = 16;
1068 	if (dev->chip_ver < 4) {
1069 		m |= 0xff00;
1070 		j = 8;
1071 	}
1072 	assignid_map = m;
1073 	tmport = dev->ioport[0] + 0x02;
1074 	outb(0x02, tmport++);	/* 2*2=4ms,3EH 2/32*3E=3.9ms */
1075 	outb(0, tmport++);
1076 	outb(0, tmport++);
1077 	outb(0, tmport++);
1078 	outb(0, tmport++);
1079 	outb(0, tmport++);
1080 	outb(0, tmport++);
1081 
1082 	for (i = 0; i < j; i++) {
1083 		m = 1;
1084 		m = m << i;
1085 		if ((m & assignid_map) != 0) {
1086 			continue;
1087 		}
1088 		tmport = dev->ioport[0] + 0x0f;
1089 		outb(0, tmport++);
1090 		tmport += 0x02;
1091 		outb(0, tmport++);
1092 		outb(0, tmport++);
1093 		outb(0, tmport++);
1094 		if (i > 7) {
1095 			k = (i & 0x07) | 0x40;
1096 		} else {
1097 			k = i;
1098 		}
1099 		outb(k, tmport++);
1100 		tmport = dev->ioport[0] + 0x1b;
1101 		if (dev->chip_ver == 4) {
1102 			outb(0x01, tmport);
1103 		} else {
1104 			outb(0x00, tmport);
1105 		}
1106 wait_rdyok:
1107 		tmport = dev->ioport[0] + 0x18;
1108 		outb(0x09, tmport);
1109 		tmport += 0x07;
1110 
1111 		while ((inb(tmport) & 0x80) == 0x00)
1112 			cpu_relax();
1113 		tmport -= 0x08;
1114 		k = inb(tmport);
1115 		if (k != 0x16) {
1116 			if ((k == 0x85) || (k == 0x42)) {
1117 				continue;
1118 			}
1119 			tmport = dev->ioport[0] + 0x10;
1120 			outb(0x41, tmport);
1121 			goto wait_rdyok;
1122 		}
1123 		assignid_map |= m;
1124 
1125 	}
1126 	tmport = dev->ioport[0] + 0x02;
1127 	outb(0x7f, tmport);
1128 	tmport = dev->ioport[0] + 0x1b;
1129 	outb(0x02, tmport);
1130 
1131 	outb(0, 0x80);
1132 
1133 	val = 0x0080;		/* bsy  */
1134 	tmport = dev->ioport[0] + 0x1c;
1135 	outw(val, tmport);
1136 	val |= 0x0040;		/* sel  */
1137 	outw(val, tmport);
1138 	val |= 0x0004;		/* msg  */
1139 	outw(val, tmport);
1140 	inb(0x80);		/* 2 deskew delay(45ns*2=90ns) */
1141 	val &= 0x007f;		/* no bsy  */
1142 	outw(val, tmport);
1143 	mdelay(128);
1144 	val &= 0x00fb;		/* after 1ms no msg */
1145 	outw(val, tmport);
1146 wait_nomsg:
1147 	if ((inb(tmport) & 0x04) != 0) {
1148 		goto wait_nomsg;
1149 	}
1150 	outb(1, 0x80);
1151 	udelay(100);
1152 	for (n = 0; n < 0x30000; n++) {
1153 		if ((inb(tmport) & 0x80) != 0) {	/* bsy ? */
1154 			goto wait_io;
1155 		}
1156 	}
1157 	goto TCM_SYNC;
1158 wait_io:
1159 	for (n = 0; n < 0x30000; n++) {
1160 		if ((inb(tmport) & 0x81) == 0x0081) {
1161 			goto wait_io1;
1162 		}
1163 	}
1164 	goto TCM_SYNC;
1165 wait_io1:
1166 	inb(0x80);
1167 	val |= 0x8003;		/* io,cd,db7  */
1168 	outw(val, tmport);
1169 	inb(0x80);
1170 	val &= 0x00bf;		/* no sel     */
1171 	outw(val, tmport);
1172 	outb(2, 0x80);
1173 TCM_SYNC:
1174 	udelay(0x800);
1175 	if ((inb(tmport) & 0x80) == 0x00) {	/* bsy ? */
1176 		outw(0, tmport--);
1177 		outb(0, tmport);
1178 		tmport = dev->ioport[0] + 0x15;
1179 		outb(0, tmport);
1180 		tmport += 0x03;
1181 		outb(0x09, tmport);
1182 		tmport += 0x07;
1183 		while ((inb(tmport) & 0x80) == 0)
1184 			cpu_relax();
1185 		tmport -= 0x08;
1186 		inb(tmport);
1187 		return;
1188 	}
1189 	val &= 0x00ff;		/* synchronization  */
1190 	val |= 0x3f00;
1191 	fun_scam(dev, &val);
1192 	outb(3, 0x80);
1193 	val &= 0x00ff;		/* isolation        */
1194 	val |= 0x2000;
1195 	fun_scam(dev, &val);
1196 	outb(4, 0x80);
1197 	i = 8;
1198 	j = 0;
1199 TCM_ID:
1200 	if ((inw(tmport) & 0x2000) == 0) {
1201 		goto TCM_ID;
1202 	}
1203 	outb(5, 0x80);
1204 	val &= 0x00ff;		/* get ID_STRING */
1205 	val |= 0x2000;
1206 	k = fun_scam(dev, &val);
1207 	if ((k & 0x03) == 0) {
1208 		goto TCM_5;
1209 	}
1210 	mbuf[j] <<= 0x01;
1211 	mbuf[j] &= 0xfe;
1212 	if ((k & 0x02) != 0) {
1213 		mbuf[j] |= 0x01;
1214 	}
1215 	i--;
1216 	if (i > 0) {
1217 		goto TCM_ID;
1218 	}
1219 	j++;
1220 	i = 8;
1221 	goto TCM_ID;
1222 
1223 TCM_5:			/* isolation complete..  */
1224 /*    mbuf[32]=0;
1225 	printk(" \n%x %x %x %s\n ",assignid_map,mbuf[0],mbuf[1],&mbuf[2]); */
1226 	i = 15;
1227 	j = mbuf[0];
1228 	if ((j & 0x20) != 0) {	/* bit5=1:ID upto 7      */
1229 		i = 7;
1230 	}
1231 	if ((j & 0x06) == 0) {	/* IDvalid?             */
1232 		goto G2Q5;
1233 	}
1234 	k = mbuf[1];
1235 small_id:
1236 	m = 1;
1237 	m <<= k;
1238 	if ((m & assignid_map) == 0) {
1239 		goto G2Q_QUIN;
1240 	}
1241 	if (k > 0) {
1242 		k--;
1243 		goto small_id;
1244 	}
1245 G2Q5:			/* srch from max acceptable ID#  */
1246 	k = i;			/* max acceptable ID#            */
1247 G2Q_LP:
1248 	m = 1;
1249 	m <<= k;
1250 	if ((m & assignid_map) == 0) {
1251 		goto G2Q_QUIN;
1252 	}
1253 	if (k > 0) {
1254 		k--;
1255 		goto G2Q_LP;
1256 	}
1257 G2Q_QUIN:		/* k=binID#,       */
1258 	assignid_map |= m;
1259 	if (k < 8) {
1260 		quintet[0] = 0x38;	/* 1st dft ID<8    */
1261 	} else {
1262 		quintet[0] = 0x31;	/* 1st  ID>=8      */
1263 	}
1264 	k &= 0x07;
1265 	quintet[1] = g2q_tab[k];
1266 
1267 	val &= 0x00ff;		/* AssignID 1stQuintet,AH=001xxxxx  */
1268 	m = quintet[0] << 8;
1269 	val |= m;
1270 	fun_scam(dev, &val);
1271 	val &= 0x00ff;		/* AssignID 2ndQuintet,AH=001xxxxx */
1272 	m = quintet[1] << 8;
1273 	val |= m;
1274 	fun_scam(dev, &val);
1275 
1276 	goto TCM_SYNC;
1277 
1278 }
1279 
1280 static void is870(struct atp_unit *dev, unsigned int wkport)
1281 {
1282 	unsigned int tmport;
1283 	unsigned char i, j, k, rmb, n;
1284 	unsigned short int m;
1285 	static unsigned char mbuf[512];
1286 	static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 };
1287 	static unsigned char inqd[9] = { 0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6 };
1288 	static unsigned char synn[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
1289 	static unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0c, 0x0e };
1290 	static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 };
1291 	static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 };
1292 
1293 	tmport = wkport + 0x3a;
1294 	outb((unsigned char) (inb(tmport) | 0x10), tmport);
1295 
1296 	for (i = 0; i < 16; i++) {
1297 		if ((dev->chip_ver != 4) && (i > 7)) {
1298 			break;
1299 		}
1300 		m = 1;
1301 		m = m << i;
1302 		if ((m & dev->active_id[0]) != 0) {
1303 			continue;
1304 		}
1305 		if (i == dev->host_id[0]) {
1306 			printk(KERN_INFO "         ID: %2d  Host Adapter\n", dev->host_id[0]);
1307 			continue;
1308 		}
1309 		tmport = wkport + 0x1b;
1310 		if (dev->chip_ver == 4) {
1311 			outb(0x01, tmport);
1312 		} else {
1313 			outb(0x00, tmport);
1314 		}
1315 		tmport = wkport + 1;
1316 		outb(0x08, tmport++);
1317 		outb(0x7f, tmport++);
1318 		outb(satn[0], tmport++);
1319 		outb(satn[1], tmport++);
1320 		outb(satn[2], tmport++);
1321 		outb(satn[3], tmport++);
1322 		outb(satn[4], tmport++);
1323 		outb(satn[5], tmport++);
1324 		tmport += 0x06;
1325 		outb(0, tmport);
1326 		tmport += 0x02;
1327 		outb(dev->id[0][i].devsp, tmport++);
1328 		outb(0, tmport++);
1329 		outb(satn[6], tmport++);
1330 		outb(satn[7], tmport++);
1331 		j = i;
1332 		if ((j & 0x08) != 0) {
1333 			j = (j & 0x07) | 0x40;
1334 		}
1335 		outb(j, tmport);
1336 		tmport += 0x03;
1337 		outb(satn[8], tmport);
1338 		tmport += 0x07;
1339 
1340 		while ((inb(tmport) & 0x80) == 0x00)
1341 			cpu_relax();
1342 
1343 		tmport -= 0x08;
1344 		if (inb(tmport) != 0x11 && inb(tmport) != 0x8e)
1345 			continue;
1346 
1347 		while (inb(tmport) != 0x8e)
1348 			cpu_relax();
1349 
1350 		dev->active_id[0] |= m;
1351 
1352 		tmport = wkport + 0x10;
1353 		outb(0x30, tmport);
1354 		tmport = wkport + 0x04;
1355 		outb(0x00, tmport);
1356 
1357 phase_cmd:
1358 		tmport = wkport + 0x18;
1359 		outb(0x08, tmport);
1360 		tmport += 0x07;
1361 		while ((inb(tmport) & 0x80) == 0x00)
1362 			cpu_relax();
1363 		tmport -= 0x08;
1364 		j = inb(tmport);
1365 		if (j != 0x16) {
1366 			tmport = wkport + 0x10;
1367 			outb(0x41, tmport);
1368 			goto phase_cmd;
1369 		}
1370 sel_ok:
1371 		tmport = wkport + 3;
1372 		outb(inqd[0], tmport++);
1373 		outb(inqd[1], tmport++);
1374 		outb(inqd[2], tmport++);
1375 		outb(inqd[3], tmport++);
1376 		outb(inqd[4], tmport++);
1377 		outb(inqd[5], tmport);
1378 		tmport += 0x07;
1379 		outb(0, tmport);
1380 		tmport += 0x02;
1381 		outb(dev->id[0][i].devsp, tmport++);
1382 		outb(0, tmport++);
1383 		outb(inqd[6], tmport++);
1384 		outb(inqd[7], tmport++);
1385 		tmport += 0x03;
1386 		outb(inqd[8], tmport);
1387 		tmport += 0x07;
1388 
1389 		while ((inb(tmport) & 0x80) == 0x00)
1390 			cpu_relax();
1391 
1392 		tmport -= 0x08;
1393 		if (inb(tmport) != 0x11 && inb(tmport) != 0x8e)
1394 			continue;
1395 
1396 		while (inb(tmport) != 0x8e)
1397 			cpu_relax();
1398 
1399 		tmport = wkport + 0x1b;
1400 		if (dev->chip_ver == 4)
1401 			outb(0x00, tmport);
1402 
1403 		tmport = wkport + 0x18;
1404 		outb(0x08, tmport);
1405 		tmport += 0x07;
1406 		j = 0;
1407 rd_inq_data:
1408 		k = inb(tmport);
1409 		if ((k & 0x01) != 0) {
1410 			tmport -= 0x06;
1411 			mbuf[j++] = inb(tmport);
1412 			tmport += 0x06;
1413 			goto rd_inq_data;
1414 		}
1415 		if ((k & 0x80) == 0) {
1416 			goto rd_inq_data;
1417 		}
1418 		tmport -= 0x08;
1419 		j = inb(tmport);
1420 		if (j == 0x16) {
1421 			goto inq_ok;
1422 		}
1423 		tmport = wkport + 0x10;
1424 		outb(0x46, tmport);
1425 		tmport += 0x02;
1426 		outb(0, tmport++);
1427 		outb(0, tmport++);
1428 		outb(0, tmport++);
1429 		tmport += 0x03;
1430 		outb(0x08, tmport);
1431 		tmport += 0x07;
1432 
1433 		while ((inb(tmport) & 0x80) == 0x00)
1434 			cpu_relax();
1435 
1436 		tmport -= 0x08;
1437 		if (inb(tmport) != 0x16) {
1438 			goto sel_ok;
1439 		}
1440 inq_ok:
1441 		mbuf[36] = 0;
1442 		printk(KERN_INFO "         ID: %2d  %s\n", i, &mbuf[8]);
1443 		dev->id[0][i].devtype = mbuf[0];
1444 		rmb = mbuf[1];
1445 		n = mbuf[7];
1446 		if (dev->chip_ver != 4) {
1447 			goto not_wide;
1448 		}
1449 		if ((mbuf[7] & 0x60) == 0) {
1450 			goto not_wide;
1451 		}
1452 		if ((dev->global_map[0] & 0x20) == 0) {
1453 			goto not_wide;
1454 		}
1455 		tmport = wkport + 0x1b;
1456 		outb(0x01, tmport);
1457 		tmport = wkport + 3;
1458 		outb(satn[0], tmport++);
1459 		outb(satn[1], tmport++);
1460 		outb(satn[2], tmport++);
1461 		outb(satn[3], tmport++);
1462 		outb(satn[4], tmport++);
1463 		outb(satn[5], tmport++);
1464 		tmport += 0x06;
1465 		outb(0, tmport);
1466 		tmport += 0x02;
1467 		outb(dev->id[0][i].devsp, tmport++);
1468 		outb(0, tmport++);
1469 		outb(satn[6], tmport++);
1470 		outb(satn[7], tmport++);
1471 		tmport += 0x03;
1472 		outb(satn[8], tmport);
1473 		tmport += 0x07;
1474 
1475 		while ((inb(tmport) & 0x80) == 0x00)
1476 			cpu_relax();
1477 
1478 		tmport -= 0x08;
1479 		if (inb(tmport) != 0x11 && inb(tmport) != 0x8e)
1480 			continue;
1481 
1482 		while (inb(tmport) != 0x8e)
1483 			cpu_relax();
1484 
1485 try_wide:
1486 		j = 0;
1487 		tmport = wkport + 0x14;
1488 		outb(0x05, tmport);
1489 		tmport += 0x04;
1490 		outb(0x20, tmport);
1491 		tmport += 0x07;
1492 
1493 		while ((inb(tmport) & 0x80) == 0) {
1494 			if ((inb(tmport) & 0x01) != 0) {
1495 				tmport -= 0x06;
1496 				outb(wide[j++], tmport);
1497 				tmport += 0x06;
1498 			}
1499 		}
1500 		tmport -= 0x08;
1501 
1502 		while ((inb(tmport) & 0x80) == 0x00)
1503 			cpu_relax();
1504 
1505 		j = inb(tmport) & 0x0f;
1506 		if (j == 0x0f) {
1507 			goto widep_in;
1508 		}
1509 		if (j == 0x0a) {
1510 			goto widep_cmd;
1511 		}
1512 		if (j == 0x0e) {
1513 			goto try_wide;
1514 		}
1515 		continue;
1516 widep_out:
1517 		tmport = wkport + 0x18;
1518 		outb(0x20, tmport);
1519 		tmport += 0x07;
1520 		while ((inb(tmport) & 0x80) == 0) {
1521 			if ((inb(tmport) & 0x01) != 0) {
1522 				tmport -= 0x06;
1523 				outb(0, tmport);
1524 				tmport += 0x06;
1525 			}
1526 		}
1527 		tmport -= 0x08;
1528 		j = inb(tmport) & 0x0f;
1529 		if (j == 0x0f) {
1530 			goto widep_in;
1531 		}
1532 		if (j == 0x0a) {
1533 			goto widep_cmd;
1534 		}
1535 		if (j == 0x0e) {
1536 			goto widep_out;
1537 		}
1538 		continue;
1539 widep_in:
1540 		tmport = wkport + 0x14;
1541 		outb(0xff, tmport);
1542 		tmport += 0x04;
1543 		outb(0x20, tmport);
1544 		tmport += 0x07;
1545 		k = 0;
1546 widep_in1:
1547 		j = inb(tmport);
1548 		if ((j & 0x01) != 0) {
1549 			tmport -= 0x06;
1550 			mbuf[k++] = inb(tmport);
1551 			tmport += 0x06;
1552 			goto widep_in1;
1553 		}
1554 		if ((j & 0x80) == 0x00) {
1555 			goto widep_in1;
1556 		}
1557 		tmport -= 0x08;
1558 		j = inb(tmport) & 0x0f;
1559 		if (j == 0x0f) {
1560 			goto widep_in;
1561 		}
1562 		if (j == 0x0a) {
1563 			goto widep_cmd;
1564 		}
1565 		if (j == 0x0e) {
1566 			goto widep_out;
1567 		}
1568 		continue;
1569 widep_cmd:
1570 		tmport = wkport + 0x10;
1571 		outb(0x30, tmport);
1572 		tmport = wkport + 0x14;
1573 		outb(0x00, tmport);
1574 		tmport += 0x04;
1575 		outb(0x08, tmport);
1576 		tmport += 0x07;
1577 
1578 		while ((inb(tmport) & 0x80) == 0x00)
1579 			cpu_relax();
1580 
1581 		tmport -= 0x08;
1582 		j = inb(tmport);
1583 		if (j != 0x16) {
1584 			if (j == 0x4e) {
1585 				goto widep_out;
1586 			}
1587 			continue;
1588 		}
1589 		if (mbuf[0] != 0x01) {
1590 			goto not_wide;
1591 		}
1592 		if (mbuf[1] != 0x02) {
1593 			goto not_wide;
1594 		}
1595 		if (mbuf[2] != 0x03) {
1596 			goto not_wide;
1597 		}
1598 		if (mbuf[3] != 0x01) {
1599 			goto not_wide;
1600 		}
1601 		m = 1;
1602 		m = m << i;
1603 		dev->wide_id[0] |= m;
1604 not_wide:
1605 		if ((dev->id[0][i].devtype == 0x00) || (dev->id[0][i].devtype == 0x07) || ((dev->id[0][i].devtype == 0x05) && ((n & 0x10) != 0))) {
1606 			goto set_sync;
1607 		}
1608 		continue;
1609 set_sync:
1610 		tmport = wkport + 0x1b;
1611 		j = 0;
1612 		if ((m & dev->wide_id[0]) != 0) {
1613 			j |= 0x01;
1614 		}
1615 		outb(j, tmport);
1616 		tmport = wkport + 3;
1617 		outb(satn[0], tmport++);
1618 		outb(satn[1], tmport++);
1619 		outb(satn[2], tmport++);
1620 		outb(satn[3], tmport++);
1621 		outb(satn[4], tmport++);
1622 		outb(satn[5], tmport++);
1623 		tmport += 0x06;
1624 		outb(0, tmport);
1625 		tmport += 0x02;
1626 		outb(dev->id[0][i].devsp, tmport++);
1627 		outb(0, tmport++);
1628 		outb(satn[6], tmport++);
1629 		outb(satn[7], tmport++);
1630 		tmport += 0x03;
1631 		outb(satn[8], tmport);
1632 		tmport += 0x07;
1633 
1634 		while ((inb(tmport) & 0x80) == 0x00)
1635 			cpu_relax();
1636 
1637 		tmport -= 0x08;
1638 		if (inb(tmport) != 0x11 && inb(tmport) != 0x8e)
1639 			continue;
1640 
1641 		while (inb(tmport) != 0x8e)
1642 			cpu_relax();
1643 
1644 try_sync:
1645 		j = 0;
1646 		tmport = wkport + 0x14;
1647 		outb(0x06, tmport);
1648 		tmport += 0x04;
1649 		outb(0x20, tmport);
1650 		tmport += 0x07;
1651 
1652 		while ((inb(tmport) & 0x80) == 0) {
1653 			if ((inb(tmport) & 0x01) != 0) {
1654 				tmport -= 0x06;
1655 				if ((m & dev->wide_id[0]) != 0) {
1656 					outb(synw[j++], tmport);
1657 				} else {
1658 					if ((m & dev->ultra_map[0]) != 0) {
1659 						outb(synu[j++], tmport);
1660 					} else {
1661 						outb(synn[j++], tmport);
1662 					}
1663 				}
1664 				tmport += 0x06;
1665 			}
1666 		}
1667 		tmport -= 0x08;
1668 
1669 		while ((inb(tmport) & 0x80) == 0x00)
1670 			cpu_relax();
1671 
1672 		j = inb(tmport) & 0x0f;
1673 		if (j == 0x0f) {
1674 			goto phase_ins;
1675 		}
1676 		if (j == 0x0a) {
1677 			goto phase_cmds;
1678 		}
1679 		if (j == 0x0e) {
1680 			goto try_sync;
1681 		}
1682 		continue;
1683 phase_outs:
1684 		tmport = wkport + 0x18;
1685 		outb(0x20, tmport);
1686 		tmport += 0x07;
1687 		while ((inb(tmport) & 0x80) == 0x00) {
1688 			if ((inb(tmport) & 0x01) != 0x00) {
1689 				tmport -= 0x06;
1690 				outb(0x00, tmport);
1691 				tmport += 0x06;
1692 			}
1693 		}
1694 		tmport -= 0x08;
1695 		j = inb(tmport);
1696 		if (j == 0x85) {
1697 			goto tar_dcons;
1698 		}
1699 		j &= 0x0f;
1700 		if (j == 0x0f) {
1701 			goto phase_ins;
1702 		}
1703 		if (j == 0x0a) {
1704 			goto phase_cmds;
1705 		}
1706 		if (j == 0x0e) {
1707 			goto phase_outs;
1708 		}
1709 		continue;
1710 phase_ins:
1711 		tmport = wkport + 0x14;
1712 		outb(0xff, tmport);
1713 		tmport += 0x04;
1714 		outb(0x20, tmport);
1715 		tmport += 0x07;
1716 		k = 0;
1717 phase_ins1:
1718 		j = inb(tmport);
1719 		if ((j & 0x01) != 0x00) {
1720 			tmport -= 0x06;
1721 			mbuf[k++] = inb(tmport);
1722 			tmport += 0x06;
1723 			goto phase_ins1;
1724 		}
1725 		if ((j & 0x80) == 0x00) {
1726 			goto phase_ins1;
1727 		}
1728 		tmport -= 0x08;
1729 
1730 		while ((inb(tmport) & 0x80) == 0x00)
1731 			cpu_relax();
1732 
1733 		j = inb(tmport);
1734 		if (j == 0x85) {
1735 			goto tar_dcons;
1736 		}
1737 		j &= 0x0f;
1738 		if (j == 0x0f) {
1739 			goto phase_ins;
1740 		}
1741 		if (j == 0x0a) {
1742 			goto phase_cmds;
1743 		}
1744 		if (j == 0x0e) {
1745 			goto phase_outs;
1746 		}
1747 		continue;
1748 phase_cmds:
1749 		tmport = wkport + 0x10;
1750 		outb(0x30, tmport);
1751 tar_dcons:
1752 		tmport = wkport + 0x14;
1753 		outb(0x00, tmport);
1754 		tmport += 0x04;
1755 		outb(0x08, tmport);
1756 		tmport += 0x07;
1757 
1758 		while ((inb(tmport) & 0x80) == 0x00)
1759 			cpu_relax();
1760 
1761 		tmport -= 0x08;
1762 		j = inb(tmport);
1763 		if (j != 0x16) {
1764 			continue;
1765 		}
1766 		if (mbuf[0] != 0x01) {
1767 			continue;
1768 		}
1769 		if (mbuf[1] != 0x03) {
1770 			continue;
1771 		}
1772 		if (mbuf[4] == 0x00) {
1773 			continue;
1774 		}
1775 		if (mbuf[3] > 0x64) {
1776 			continue;
1777 		}
1778 		if (mbuf[4] > 0x0c) {
1779 			mbuf[4] = 0x0c;
1780 		}
1781 		dev->id[0][i].devsp = mbuf[4];
1782 		if ((mbuf[3] < 0x0d) && (rmb == 0)) {
1783 			j = 0xa0;
1784 			goto set_syn_ok;
1785 		}
1786 		if (mbuf[3] < 0x1a) {
1787 			j = 0x20;
1788 			goto set_syn_ok;
1789 		}
1790 		if (mbuf[3] < 0x33) {
1791 			j = 0x40;
1792 			goto set_syn_ok;
1793 		}
1794 		if (mbuf[3] < 0x4c) {
1795 			j = 0x50;
1796 			goto set_syn_ok;
1797 		}
1798 		j = 0x60;
1799 set_syn_ok:
1800 		dev->id[0][i].devsp = (dev->id[0][i].devsp & 0x0f) | j;
1801 	}
1802 	tmport = wkport + 0x3a;
1803 	outb((unsigned char) (inb(tmport) & 0xef), tmport);
1804 }
1805 
1806 static void is880(struct atp_unit *dev, unsigned int wkport)
1807 {
1808 	unsigned int tmport;
1809 	unsigned char i, j, k, rmb, n, lvdmode;
1810 	unsigned short int m;
1811 	static unsigned char mbuf[512];
1812 	static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 };
1813 	static unsigned char inqd[9] = { 0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6 };
1814 	static unsigned char synn[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
1815 	unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e };
1816 	static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
1817 	unsigned char synuw[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e };
1818 	static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 };
1819 	static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 };
1820 
1821 	lvdmode = inb(wkport + 0x3f) & 0x40;
1822 
1823 	for (i = 0; i < 16; i++) {
1824 		m = 1;
1825 		m = m << i;
1826 		if ((m & dev->active_id[0]) != 0) {
1827 			continue;
1828 		}
1829 		if (i == dev->host_id[0]) {
1830 			printk(KERN_INFO "         ID: %2d  Host Adapter\n", dev->host_id[0]);
1831 			continue;
1832 		}
1833 		tmport = wkport + 0x5b;
1834 		outb(0x01, tmport);
1835 		tmport = wkport + 0x41;
1836 		outb(0x08, tmport++);
1837 		outb(0x7f, tmport++);
1838 		outb(satn[0], tmport++);
1839 		outb(satn[1], tmport++);
1840 		outb(satn[2], tmport++);
1841 		outb(satn[3], tmport++);
1842 		outb(satn[4], tmport++);
1843 		outb(satn[5], tmport++);
1844 		tmport += 0x06;
1845 		outb(0, tmport);
1846 		tmport += 0x02;
1847 		outb(dev->id[0][i].devsp, tmport++);
1848 		outb(0, tmport++);
1849 		outb(satn[6], tmport++);
1850 		outb(satn[7], tmport++);
1851 		j = i;
1852 		if ((j & 0x08) != 0) {
1853 			j = (j & 0x07) | 0x40;
1854 		}
1855 		outb(j, tmport);
1856 		tmport += 0x03;
1857 		outb(satn[8], tmport);
1858 		tmport += 0x07;
1859 
1860 		while ((inb(tmport) & 0x80) == 0x00)
1861 			cpu_relax();
1862 
1863 		tmport -= 0x08;
1864 		if (inb(tmport) != 0x11 && inb(tmport) != 0x8e)
1865 			continue;
1866 
1867 		while (inb(tmport) != 0x8e)
1868 			cpu_relax();
1869 
1870 		dev->active_id[0] |= m;
1871 
1872 		tmport = wkport + 0x50;
1873 		outb(0x30, tmport);
1874 		tmport = wkport + 0x54;
1875 		outb(0x00, tmport);
1876 
1877 phase_cmd:
1878 		tmport = wkport + 0x58;
1879 		outb(0x08, tmport);
1880 		tmport += 0x07;
1881 
1882 		while ((inb(tmport) & 0x80) == 0x00)
1883 			cpu_relax();
1884 
1885 		tmport -= 0x08;
1886 		j = inb(tmport);
1887 		if (j != 0x16) {
1888 			tmport = wkport + 0x50;
1889 			outb(0x41, tmport);
1890 			goto phase_cmd;
1891 		}
1892 sel_ok:
1893 		tmport = wkport + 0x43;
1894 		outb(inqd[0], tmport++);
1895 		outb(inqd[1], tmport++);
1896 		outb(inqd[2], tmport++);
1897 		outb(inqd[3], tmport++);
1898 		outb(inqd[4], tmport++);
1899 		outb(inqd[5], tmport);
1900 		tmport += 0x07;
1901 		outb(0, tmport);
1902 		tmport += 0x02;
1903 		outb(dev->id[0][i].devsp, tmport++);
1904 		outb(0, tmport++);
1905 		outb(inqd[6], tmport++);
1906 		outb(inqd[7], tmport++);
1907 		tmport += 0x03;
1908 		outb(inqd[8], tmport);
1909 		tmport += 0x07;
1910 
1911 		while ((inb(tmport) & 0x80) == 0x00)
1912 			cpu_relax();
1913 
1914 		tmport -= 0x08;
1915 		if (inb(tmport) != 0x11 && inb(tmport) != 0x8e)
1916 			continue;
1917 
1918 		while (inb(tmport) != 0x8e)
1919 			cpu_relax();
1920 
1921 		tmport = wkport + 0x5b;
1922 		outb(0x00, tmport);
1923 		tmport = wkport + 0x58;
1924 		outb(0x08, tmport);
1925 		tmport += 0x07;
1926 		j = 0;
1927 rd_inq_data:
1928 		k = inb(tmport);
1929 		if ((k & 0x01) != 0) {
1930 			tmport -= 0x06;
1931 			mbuf[j++] = inb(tmport);
1932 			tmport += 0x06;
1933 			goto rd_inq_data;
1934 		}
1935 		if ((k & 0x80) == 0) {
1936 			goto rd_inq_data;
1937 		}
1938 		tmport -= 0x08;
1939 		j = inb(tmport);
1940 		if (j == 0x16) {
1941 			goto inq_ok;
1942 		}
1943 		tmport = wkport + 0x50;
1944 		outb(0x46, tmport);
1945 		tmport += 0x02;
1946 		outb(0, tmport++);
1947 		outb(0, tmport++);
1948 		outb(0, tmport++);
1949 		tmport += 0x03;
1950 		outb(0x08, tmport);
1951 		tmport += 0x07;
1952 		while ((inb(tmport) & 0x80) == 0x00)
1953 			cpu_relax();
1954 
1955 		tmport -= 0x08;
1956 		if (inb(tmport) != 0x16)
1957 			goto sel_ok;
1958 
1959 inq_ok:
1960 		mbuf[36] = 0;
1961 		printk(KERN_INFO "         ID: %2d  %s\n", i, &mbuf[8]);
1962 		dev->id[0][i].devtype = mbuf[0];
1963 		rmb = mbuf[1];
1964 		n = mbuf[7];
1965 		if ((mbuf[7] & 0x60) == 0) {
1966 			goto not_wide;
1967 		}
1968 		if ((i < 8) && ((dev->global_map[0] & 0x20) == 0)) {
1969 			goto not_wide;
1970 		}
1971 		if (lvdmode == 0) {
1972 			goto chg_wide;
1973 		}
1974 		if (dev->sp[0][i] != 0x04)	// force u2
1975 		{
1976 			goto chg_wide;
1977 		}
1978 
1979 		tmport = wkport + 0x5b;
1980 		outb(0x01, tmport);
1981 		tmport = wkport + 0x43;
1982 		outb(satn[0], tmport++);
1983 		outb(satn[1], tmport++);
1984 		outb(satn[2], tmport++);
1985 		outb(satn[3], tmport++);
1986 		outb(satn[4], tmport++);
1987 		outb(satn[5], tmport++);
1988 		tmport += 0x06;
1989 		outb(0, tmport);
1990 		tmport += 0x02;
1991 		outb(dev->id[0][i].devsp, tmport++);
1992 		outb(0, tmport++);
1993 		outb(satn[6], tmport++);
1994 		outb(satn[7], tmport++);
1995 		tmport += 0x03;
1996 		outb(satn[8], tmport);
1997 		tmport += 0x07;
1998 
1999 		while ((inb(tmport) & 0x80) == 0x00)
2000 			cpu_relax();
2001 
2002 		tmport -= 0x08;
2003 
2004 		if (inb(tmport) != 0x11 && inb(tmport) != 0x8e)
2005 			continue;
2006 
2007 		while (inb(tmport) != 0x8e)
2008 			cpu_relax();
2009 
2010 try_u3:
2011 		j = 0;
2012 		tmport = wkport + 0x54;
2013 		outb(0x09, tmport);
2014 		tmport += 0x04;
2015 		outb(0x20, tmport);
2016 		tmport += 0x07;
2017 
2018 		while ((inb(tmport) & 0x80) == 0) {
2019 			if ((inb(tmport) & 0x01) != 0) {
2020 				tmport -= 0x06;
2021 				outb(u3[j++], tmport);
2022 				tmport += 0x06;
2023 			}
2024 		}
2025 		tmport -= 0x08;
2026 
2027 		while ((inb(tmport) & 0x80) == 0x00)
2028 			cpu_relax();
2029 
2030 		j = inb(tmport) & 0x0f;
2031 		if (j == 0x0f) {
2032 			goto u3p_in;
2033 		}
2034 		if (j == 0x0a) {
2035 			goto u3p_cmd;
2036 		}
2037 		if (j == 0x0e) {
2038 			goto try_u3;
2039 		}
2040 		continue;
2041 u3p_out:
2042 		tmport = wkport + 0x58;
2043 		outb(0x20, tmport);
2044 		tmport += 0x07;
2045 		while ((inb(tmport) & 0x80) == 0) {
2046 			if ((inb(tmport) & 0x01) != 0) {
2047 				tmport -= 0x06;
2048 				outb(0, tmport);
2049 				tmport += 0x06;
2050 			}
2051 		}
2052 		tmport -= 0x08;
2053 		j = inb(tmport) & 0x0f;
2054 		if (j == 0x0f) {
2055 			goto u3p_in;
2056 		}
2057 		if (j == 0x0a) {
2058 			goto u3p_cmd;
2059 		}
2060 		if (j == 0x0e) {
2061 			goto u3p_out;
2062 		}
2063 		continue;
2064 u3p_in:
2065 		tmport = wkport + 0x54;
2066 		outb(0x09, tmport);
2067 		tmport += 0x04;
2068 		outb(0x20, tmport);
2069 		tmport += 0x07;
2070 		k = 0;
2071 u3p_in1:
2072 		j = inb(tmport);
2073 		if ((j & 0x01) != 0) {
2074 			tmport -= 0x06;
2075 			mbuf[k++] = inb(tmport);
2076 			tmport += 0x06;
2077 			goto u3p_in1;
2078 		}
2079 		if ((j & 0x80) == 0x00) {
2080 			goto u3p_in1;
2081 		}
2082 		tmport -= 0x08;
2083 		j = inb(tmport) & 0x0f;
2084 		if (j == 0x0f) {
2085 			goto u3p_in;
2086 		}
2087 		if (j == 0x0a) {
2088 			goto u3p_cmd;
2089 		}
2090 		if (j == 0x0e) {
2091 			goto u3p_out;
2092 		}
2093 		continue;
2094 u3p_cmd:
2095 		tmport = wkport + 0x50;
2096 		outb(0x30, tmport);
2097 		tmport = wkport + 0x54;
2098 		outb(0x00, tmport);
2099 		tmport += 0x04;
2100 		outb(0x08, tmport);
2101 		tmport += 0x07;
2102 
2103 		while ((inb(tmport) & 0x80) == 0x00)
2104 			cpu_relax();
2105 
2106 		tmport -= 0x08;
2107 		j = inb(tmport);
2108 		if (j != 0x16) {
2109 			if (j == 0x4e) {
2110 				goto u3p_out;
2111 			}
2112 			continue;
2113 		}
2114 		if (mbuf[0] != 0x01) {
2115 			goto chg_wide;
2116 		}
2117 		if (mbuf[1] != 0x06) {
2118 			goto chg_wide;
2119 		}
2120 		if (mbuf[2] != 0x04) {
2121 			goto chg_wide;
2122 		}
2123 		if (mbuf[3] == 0x09) {
2124 			m = 1;
2125 			m = m << i;
2126 			dev->wide_id[0] |= m;
2127 			dev->id[0][i].devsp = 0xce;
2128 			continue;
2129 		}
2130 chg_wide:
2131 		tmport = wkport + 0x5b;
2132 		outb(0x01, tmport);
2133 		tmport = wkport + 0x43;
2134 		outb(satn[0], tmport++);
2135 		outb(satn[1], tmport++);
2136 		outb(satn[2], tmport++);
2137 		outb(satn[3], tmport++);
2138 		outb(satn[4], tmport++);
2139 		outb(satn[5], tmport++);
2140 		tmport += 0x06;
2141 		outb(0, tmport);
2142 		tmport += 0x02;
2143 		outb(dev->id[0][i].devsp, tmport++);
2144 		outb(0, tmport++);
2145 		outb(satn[6], tmport++);
2146 		outb(satn[7], tmport++);
2147 		tmport += 0x03;
2148 		outb(satn[8], tmport);
2149 		tmport += 0x07;
2150 
2151 		while ((inb(tmport) & 0x80) == 0x00)
2152 			cpu_relax();
2153 
2154 		tmport -= 0x08;
2155 		if (inb(tmport) != 0x11 && inb(tmport) != 0x8e)
2156 			continue;
2157 
2158 		while (inb(tmport) != 0x8e)
2159 			cpu_relax();
2160 
2161 try_wide:
2162 		j = 0;
2163 		tmport = wkport + 0x54;
2164 		outb(0x05, tmport);
2165 		tmport += 0x04;
2166 		outb(0x20, tmport);
2167 		tmport += 0x07;
2168 
2169 		while ((inb(tmport) & 0x80) == 0) {
2170 			if ((inb(tmport) & 0x01) != 0) {
2171 				tmport -= 0x06;
2172 				outb(wide[j++], tmport);
2173 				tmport += 0x06;
2174 			}
2175 		}
2176 		tmport -= 0x08;
2177 		while ((inb(tmport) & 0x80) == 0x00)
2178 			cpu_relax();
2179 
2180 		j = inb(tmport) & 0x0f;
2181 		if (j == 0x0f) {
2182 			goto widep_in;
2183 		}
2184 		if (j == 0x0a) {
2185 			goto widep_cmd;
2186 		}
2187 		if (j == 0x0e) {
2188 			goto try_wide;
2189 		}
2190 		continue;
2191 widep_out:
2192 		tmport = wkport + 0x58;
2193 		outb(0x20, tmport);
2194 		tmport += 0x07;
2195 		while ((inb(tmport) & 0x80) == 0) {
2196 			if ((inb(tmport) & 0x01) != 0) {
2197 				tmport -= 0x06;
2198 				outb(0, tmport);
2199 				tmport += 0x06;
2200 			}
2201 		}
2202 		tmport -= 0x08;
2203 		j = inb(tmport) & 0x0f;
2204 		if (j == 0x0f) {
2205 			goto widep_in;
2206 		}
2207 		if (j == 0x0a) {
2208 			goto widep_cmd;
2209 		}
2210 		if (j == 0x0e) {
2211 			goto widep_out;
2212 		}
2213 		continue;
2214 widep_in:
2215 		tmport = wkport + 0x54;
2216 		outb(0xff, tmport);
2217 		tmport += 0x04;
2218 		outb(0x20, tmport);
2219 		tmport += 0x07;
2220 		k = 0;
2221 widep_in1:
2222 		j = inb(tmport);
2223 		if ((j & 0x01) != 0) {
2224 			tmport -= 0x06;
2225 			mbuf[k++] = inb(tmport);
2226 			tmport += 0x06;
2227 			goto widep_in1;
2228 		}
2229 		if ((j & 0x80) == 0x00) {
2230 			goto widep_in1;
2231 		}
2232 		tmport -= 0x08;
2233 		j = inb(tmport) & 0x0f;
2234 		if (j == 0x0f) {
2235 			goto widep_in;
2236 		}
2237 		if (j == 0x0a) {
2238 			goto widep_cmd;
2239 		}
2240 		if (j == 0x0e) {
2241 			goto widep_out;
2242 		}
2243 		continue;
2244 widep_cmd:
2245 		tmport = wkport + 0x50;
2246 		outb(0x30, tmport);
2247 		tmport = wkport + 0x54;
2248 		outb(0x00, tmport);
2249 		tmport += 0x04;
2250 		outb(0x08, tmport);
2251 		tmport += 0x07;
2252 
2253 		while ((inb(tmport) & 0x80) == 0x00)
2254 			cpu_relax();
2255 
2256 		tmport -= 0x08;
2257 		j = inb(tmport);
2258 		if (j != 0x16) {
2259 			if (j == 0x4e) {
2260 				goto widep_out;
2261 			}
2262 			continue;
2263 		}
2264 		if (mbuf[0] != 0x01) {
2265 			goto not_wide;
2266 		}
2267 		if (mbuf[1] != 0x02) {
2268 			goto not_wide;
2269 		}
2270 		if (mbuf[2] != 0x03) {
2271 			goto not_wide;
2272 		}
2273 		if (mbuf[3] != 0x01) {
2274 			goto not_wide;
2275 		}
2276 		m = 1;
2277 		m = m << i;
2278 		dev->wide_id[0] |= m;
2279 not_wide:
2280 		if ((dev->id[0][i].devtype == 0x00) || (dev->id[0][i].devtype == 0x07) || ((dev->id[0][i].devtype == 0x05) && ((n & 0x10) != 0))) {
2281 			m = 1;
2282 			m = m << i;
2283 			if ((dev->async[0] & m) != 0) {
2284 				goto set_sync;
2285 			}
2286 		}
2287 		continue;
2288 set_sync:
2289 		if (dev->sp[0][i] == 0x02) {
2290 			synu[4] = 0x0c;
2291 			synuw[4] = 0x0c;
2292 		} else {
2293 			if (dev->sp[0][i] >= 0x03) {
2294 				synu[4] = 0x0a;
2295 				synuw[4] = 0x0a;
2296 			}
2297 		}
2298 		tmport = wkport + 0x5b;
2299 		j = 0;
2300 		if ((m & dev->wide_id[0]) != 0) {
2301 			j |= 0x01;
2302 		}
2303 		outb(j, tmport);
2304 		tmport = wkport + 0x43;
2305 		outb(satn[0], tmport++);
2306 		outb(satn[1], tmport++);
2307 		outb(satn[2], tmport++);
2308 		outb(satn[3], tmport++);
2309 		outb(satn[4], tmport++);
2310 		outb(satn[5], tmport++);
2311 		tmport += 0x06;
2312 		outb(0, tmport);
2313 		tmport += 0x02;
2314 		outb(dev->id[0][i].devsp, tmport++);
2315 		outb(0, tmport++);
2316 		outb(satn[6], tmport++);
2317 		outb(satn[7], tmport++);
2318 		tmport += 0x03;
2319 		outb(satn[8], tmport);
2320 		tmport += 0x07;
2321 
2322 		while ((inb(tmport) & 0x80) == 0x00)
2323 			cpu_relax();
2324 
2325 		tmport -= 0x08;
2326 		if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
2327 			continue;
2328 		}
2329 		while (inb(tmport) != 0x8e)
2330 			cpu_relax();
2331 
2332 try_sync:
2333 		j = 0;
2334 		tmport = wkport + 0x54;
2335 		outb(0x06, tmport);
2336 		tmport += 0x04;
2337 		outb(0x20, tmport);
2338 		tmport += 0x07;
2339 
2340 		while ((inb(tmport) & 0x80) == 0) {
2341 			if ((inb(tmport) & 0x01) != 0) {
2342 				tmport -= 0x06;
2343 				if ((m & dev->wide_id[0]) != 0) {
2344 					if ((m & dev->ultra_map[0]) != 0) {
2345 						outb(synuw[j++], tmport);
2346 					} else {
2347 						outb(synw[j++], tmport);
2348 					}
2349 				} else {
2350 					if ((m & dev->ultra_map[0]) != 0) {
2351 						outb(synu[j++], tmport);
2352 					} else {
2353 						outb(synn[j++], tmport);
2354 					}
2355 				}
2356 				tmport += 0x06;
2357 			}
2358 		}
2359 		tmport -= 0x08;
2360 
2361 		while ((inb(tmport) & 0x80) == 0x00)
2362 			cpu_relax();
2363 
2364 		j = inb(tmport) & 0x0f;
2365 		if (j == 0x0f) {
2366 			goto phase_ins;
2367 		}
2368 		if (j == 0x0a) {
2369 			goto phase_cmds;
2370 		}
2371 		if (j == 0x0e) {
2372 			goto try_sync;
2373 		}
2374 		continue;
2375 phase_outs:
2376 		tmport = wkport + 0x58;
2377 		outb(0x20, tmport);
2378 		tmport += 0x07;
2379 		while ((inb(tmport) & 0x80) == 0x00) {
2380 			if ((inb(tmport) & 0x01) != 0x00) {
2381 				tmport -= 0x06;
2382 				outb(0x00, tmport);
2383 				tmport += 0x06;
2384 			}
2385 		}
2386 		tmport -= 0x08;
2387 		j = inb(tmport);
2388 		if (j == 0x85) {
2389 			goto tar_dcons;
2390 		}
2391 		j &= 0x0f;
2392 		if (j == 0x0f) {
2393 			goto phase_ins;
2394 		}
2395 		if (j == 0x0a) {
2396 			goto phase_cmds;
2397 		}
2398 		if (j == 0x0e) {
2399 			goto phase_outs;
2400 		}
2401 		continue;
2402 phase_ins:
2403 		tmport = wkport + 0x54;
2404 		outb(0x06, tmport);
2405 		tmport += 0x04;
2406 		outb(0x20, tmport);
2407 		tmport += 0x07;
2408 		k = 0;
2409 phase_ins1:
2410 		j = inb(tmport);
2411 		if ((j & 0x01) != 0x00) {
2412 			tmport -= 0x06;
2413 			mbuf[k++] = inb(tmport);
2414 			tmport += 0x06;
2415 			goto phase_ins1;
2416 		}
2417 		if ((j & 0x80) == 0x00) {
2418 			goto phase_ins1;
2419 		}
2420 		tmport -= 0x08;
2421 
2422 		while ((inb(tmport) & 0x80) == 0x00)
2423 			cpu_relax();
2424 
2425 		j = inb(tmport);
2426 		if (j == 0x85) {
2427 			goto tar_dcons;
2428 		}
2429 		j &= 0x0f;
2430 		if (j == 0x0f) {
2431 			goto phase_ins;
2432 		}
2433 		if (j == 0x0a) {
2434 			goto phase_cmds;
2435 		}
2436 		if (j == 0x0e) {
2437 			goto phase_outs;
2438 		}
2439 		continue;
2440 phase_cmds:
2441 		tmport = wkport + 0x50;
2442 		outb(0x30, tmport);
2443 tar_dcons:
2444 		tmport = wkport + 0x54;
2445 		outb(0x00, tmport);
2446 		tmport += 0x04;
2447 		outb(0x08, tmport);
2448 		tmport += 0x07;
2449 
2450 		while ((inb(tmport) & 0x80) == 0x00)
2451 			cpu_relax();
2452 
2453 		tmport -= 0x08;
2454 		j = inb(tmport);
2455 		if (j != 0x16) {
2456 			continue;
2457 		}
2458 		if (mbuf[0] != 0x01) {
2459 			continue;
2460 		}
2461 		if (mbuf[1] != 0x03) {
2462 			continue;
2463 		}
2464 		if (mbuf[4] == 0x00) {
2465 			continue;
2466 		}
2467 		if (mbuf[3] > 0x64) {
2468 			continue;
2469 		}
2470 		if (mbuf[4] > 0x0e) {
2471 			mbuf[4] = 0x0e;
2472 		}
2473 		dev->id[0][i].devsp = mbuf[4];
2474 		if (mbuf[3] < 0x0c) {
2475 			j = 0xb0;
2476 			goto set_syn_ok;
2477 		}
2478 		if ((mbuf[3] < 0x0d) && (rmb == 0)) {
2479 			j = 0xa0;
2480 			goto set_syn_ok;
2481 		}
2482 		if (mbuf[3] < 0x1a) {
2483 			j = 0x20;
2484 			goto set_syn_ok;
2485 		}
2486 		if (mbuf[3] < 0x33) {
2487 			j = 0x40;
2488 			goto set_syn_ok;
2489 		}
2490 		if (mbuf[3] < 0x4c) {
2491 			j = 0x50;
2492 			goto set_syn_ok;
2493 		}
2494 		j = 0x60;
2495 set_syn_ok:
2496 		dev->id[0][i].devsp = (dev->id[0][i].devsp & 0x0f) | j;
2497 	}
2498 }
2499 
2500 static void atp870u_free_tables(struct Scsi_Host *host)
2501 {
2502 	struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata;
2503 	int j, k;
2504 	for (j=0; j < 2; j++) {
2505 		for (k = 0; k < 16; k++) {
2506 			if (!atp_dev->id[j][k].prd_table)
2507 				continue;
2508 			pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[j][k].prd_table, atp_dev->id[j][k].prd_bus);
2509 			atp_dev->id[j][k].prd_table = NULL;
2510 		}
2511 	}
2512 }
2513 
2514 static int atp870u_init_tables(struct Scsi_Host *host)
2515 {
2516 	struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata;
2517 	int c,k;
2518 	for(c=0;c < 2;c++) {
2519 	   	for(k=0;k<16;k++) {
2520 	   			atp_dev->id[c][k].prd_table = pci_alloc_consistent(atp_dev->pdev, 1024, &(atp_dev->id[c][k].prd_bus));
2521 	   			if (!atp_dev->id[c][k].prd_table) {
2522 	   				printk("atp870u_init_tables fail\n");
2523 				atp870u_free_tables(host);
2524 				return -ENOMEM;
2525 			}
2526 			atp_dev->id[c][k].prdaddr = atp_dev->id[c][k].prd_bus;
2527 			atp_dev->id[c][k].devsp=0x20;
2528 			atp_dev->id[c][k].devtype = 0x7f;
2529 			atp_dev->id[c][k].curr_req = NULL;
2530 	   	}
2531 
2532 	   	atp_dev->active_id[c] = 0;
2533 	   	atp_dev->wide_id[c] = 0;
2534 	   	atp_dev->host_id[c] = 0x07;
2535 	   	atp_dev->quhd[c] = 0;
2536 	   	atp_dev->quend[c] = 0;
2537 	   	atp_dev->last_cmd[c] = 0xff;
2538 	   	atp_dev->in_snd[c] = 0;
2539 	   	atp_dev->in_int[c] = 0;
2540 
2541 	   	for (k = 0; k < qcnt; k++) {
2542 	   		  atp_dev->quereq[c][k] = NULL;
2543 	   	}
2544 	   	for (k = 0; k < 16; k++) {
2545 			   atp_dev->id[c][k].curr_req = NULL;
2546 			   atp_dev->sp[c][k] = 0x04;
2547 	   	}
2548 	}
2549 	return 0;
2550 }
2551 
2552 /* return non-zero on detection */
2553 static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2554 {
2555 	unsigned char k, m, c;
2556 	unsigned long flags;
2557 	unsigned int base_io, tmport, error,n;
2558 	unsigned char host_id;
2559 	struct Scsi_Host *shpnt = NULL;
2560 	struct atp_unit *atpdev, *p;
2561 	unsigned char setupdata[2][16];
2562 	int count = 0;
2563 
2564 	atpdev = kzalloc(sizeof(*atpdev), GFP_KERNEL);
2565 	if (!atpdev)
2566 		return -ENOMEM;
2567 
2568 	if (pci_enable_device(pdev))
2569 		goto err_eio;
2570 
2571         if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
2572                 printk(KERN_INFO "atp870u: use 32bit DMA mask.\n");
2573         } else {
2574                 printk(KERN_ERR "atp870u: DMA mask required but not available.\n");
2575 		goto err_eio;
2576         }
2577 
2578 	/*
2579 	 * It's probably easier to weed out some revisions like
2580 	 * this than via the PCI device table
2581 	 */
2582 	if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) {
2583 		error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atpdev->chip_ver);
2584 		if (atpdev->chip_ver < 2)
2585 			goto err_eio;
2586 	}
2587 
2588 	switch (ent->device) {
2589 	case PCI_DEVICE_ID_ARTOP_AEC7612UW:
2590 	case PCI_DEVICE_ID_ARTOP_AEC7612SUW:
2591 	case ATP880_DEVID1:
2592 	case ATP880_DEVID2:
2593 	case ATP885_DEVID:
2594 		atpdev->chip_ver = 0x04;
2595 	default:
2596 		break;
2597 	}
2598 	base_io = pci_resource_start(pdev, 0);
2599 	base_io &= 0xfffffff8;
2600 
2601 	if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) {
2602 		error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atpdev->chip_ver);
2603 		pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803
2604 
2605 		host_id = inb(base_io + 0x39);
2606 		host_id >>= 0x04;
2607 
2608 		printk(KERN_INFO "   ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d"
2609 			"    IO:%x, IRQ:%d.\n", count, base_io, pdev->irq);
2610 		atpdev->ioport[0] = base_io + 0x40;
2611 		atpdev->pciport[0] = base_io + 0x28;
2612 		atpdev->dev_id = ent->device;
2613 		atpdev->host_id[0] = host_id;
2614 
2615 		tmport = base_io + 0x22;
2616 		atpdev->scam_on = inb(tmport);
2617 		tmport += 0x13;
2618 		atpdev->global_map[0] = inb(tmport);
2619 		tmport += 0x07;
2620 		atpdev->ultra_map[0] = inw(tmport);
2621 
2622 		n = 0x3f09;
2623 next_fblk_880:
2624 		if (n >= 0x4000)
2625 			goto flash_ok_880;
2626 
2627 		m = 0;
2628 		outw(n, base_io + 0x34);
2629 		n += 0x0002;
2630 		if (inb(base_io + 0x30) == 0xff)
2631 			goto flash_ok_880;
2632 
2633 		atpdev->sp[0][m++] = inb(base_io + 0x30);
2634 		atpdev->sp[0][m++] = inb(base_io + 0x31);
2635 		atpdev->sp[0][m++] = inb(base_io + 0x32);
2636 		atpdev->sp[0][m++] = inb(base_io + 0x33);
2637 		outw(n, base_io + 0x34);
2638 		n += 0x0002;
2639 		atpdev->sp[0][m++] = inb(base_io + 0x30);
2640 		atpdev->sp[0][m++] = inb(base_io + 0x31);
2641 		atpdev->sp[0][m++] = inb(base_io + 0x32);
2642 		atpdev->sp[0][m++] = inb(base_io + 0x33);
2643 		outw(n, base_io + 0x34);
2644 		n += 0x0002;
2645 		atpdev->sp[0][m++] = inb(base_io + 0x30);
2646 		atpdev->sp[0][m++] = inb(base_io + 0x31);
2647 		atpdev->sp[0][m++] = inb(base_io + 0x32);
2648 		atpdev->sp[0][m++] = inb(base_io + 0x33);
2649 		outw(n, base_io + 0x34);
2650 		n += 0x0002;
2651 		atpdev->sp[0][m++] = inb(base_io + 0x30);
2652 		atpdev->sp[0][m++] = inb(base_io + 0x31);
2653 		atpdev->sp[0][m++] = inb(base_io + 0x32);
2654 		atpdev->sp[0][m++] = inb(base_io + 0x33);
2655 		n += 0x0018;
2656 		goto next_fblk_880;
2657 flash_ok_880:
2658 		outw(0, base_io + 0x34);
2659 		atpdev->ultra_map[0] = 0;
2660 		atpdev->async[0] = 0;
2661 		for (k = 0; k < 16; k++) {
2662 			n = 1;
2663 			n = n << k;
2664 			if (atpdev->sp[0][k] > 1) {
2665 				atpdev->ultra_map[0] |= n;
2666 			} else {
2667 				if (atpdev->sp[0][k] == 0)
2668 					atpdev->async[0] |= n;
2669  			}
2670 	 	}
2671 		atpdev->async[0] = ~(atpdev->async[0]);
2672 		outb(atpdev->global_map[0], base_io + 0x35);
2673 
2674 		shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
2675 		if (!shpnt)
2676 			goto err_nomem;
2677 
2678 		p = (struct atp_unit *)&shpnt->hostdata;
2679 
2680 		atpdev->host = shpnt;
2681 		atpdev->pdev = pdev;
2682 		pci_set_drvdata(pdev, p);
2683 		memcpy(p, atpdev, sizeof(*atpdev));
2684 		if (atp870u_init_tables(shpnt) < 0) {
2685 			printk(KERN_ERR "Unable to allocate tables for Acard controller\n");
2686 			goto unregister;
2687 		}
2688 
2689 		if (request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp880i", shpnt)) {
2690  			printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", pdev->irq);
2691 			goto free_tables;
2692 		}
2693 
2694 		spin_lock_irqsave(shpnt->host_lock, flags);
2695 		tmport = base_io + 0x38;
2696 		k = inb(tmport) & 0x80;
2697 		outb(k, tmport);
2698 		tmport += 0x03;
2699 		outb(0x20, tmport);
2700 		mdelay(32);
2701 		outb(0, tmport);
2702 		mdelay(32);
2703 		tmport = base_io + 0x5b;
2704 		inb(tmport);
2705 		tmport -= 0x04;
2706 		inb(tmport);
2707 		tmport = base_io + 0x40;
2708 		outb((host_id | 0x08), tmport);
2709 		tmport += 0x18;
2710 		outb(0, tmport);
2711 		tmport += 0x07;
2712 		while ((inb(tmport) & 0x80) == 0)
2713 			mdelay(1);
2714 		tmport -= 0x08;
2715 		inb(tmport);
2716 		tmport = base_io + 0x41;
2717 		outb(8, tmport++);
2718 		outb(0x7f, tmport);
2719 		tmport = base_io + 0x51;
2720 		outb(0x20, tmport);
2721 
2722 		tscam(shpnt);
2723 		is880(p, base_io);
2724 		tmport = base_io + 0x38;
2725 		outb(0xb0, tmport);
2726 		shpnt->max_id = 16;
2727 		shpnt->this_id = host_id;
2728 		shpnt->unique_id = base_io;
2729 		shpnt->io_port = base_io;
2730 		shpnt->n_io_port = 0x60;	/* Number of bytes of I/O space used */
2731 		shpnt->irq = pdev->irq;
2732 	} else if (ent->device == ATP885_DEVID) {
2733 			printk(KERN_INFO "   ACARD AEC-67162 PCI Ultra3 LVD Host Adapter:  IO:%x, IRQ:%d.\n"
2734 			       , base_io, pdev->irq);
2735 
2736 		atpdev->pdev = pdev;
2737 		atpdev->dev_id  = ent->device;
2738 		atpdev->baseport = base_io;
2739 		atpdev->ioport[0] = base_io + 0x80;
2740 		atpdev->ioport[1] = base_io + 0xc0;
2741 		atpdev->pciport[0] = base_io + 0x40;
2742 		atpdev->pciport[1] = base_io + 0x50;
2743 
2744 		shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
2745 		if (!shpnt)
2746 			goto err_nomem;
2747 
2748 		p = (struct atp_unit *)&shpnt->hostdata;
2749 
2750 		atpdev->host = shpnt;
2751 		atpdev->pdev = pdev;
2752 		pci_set_drvdata(pdev, p);
2753 		memcpy(p, atpdev, sizeof(struct atp_unit));
2754 		if (atp870u_init_tables(shpnt) < 0)
2755 			goto unregister;
2756 
2757 #ifdef ED_DBGP
2758 	printk("request_irq() shpnt %p hostdata %p\n", shpnt, p);
2759 #endif
2760 		if (request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp870u", shpnt)) {
2761 				printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n");
2762 			goto free_tables;
2763 		}
2764 
2765 		spin_lock_irqsave(shpnt->host_lock, flags);
2766 
2767 		c=inb(base_io + 0x29);
2768 		outb((c | 0x04),base_io + 0x29);
2769 
2770 		n=0x1f80;
2771 next_fblk_885:
2772 		if (n >= 0x2000) {
2773 		   goto flash_ok_885;
2774 		}
2775 		outw(n,base_io + 0x3c);
2776 		if (inl(base_io + 0x38) == 0xffffffff) {
2777 		   goto flash_ok_885;
2778 		}
2779 		for (m=0; m < 2; m++) {
2780 		    p->global_map[m]= 0;
2781 		    for (k=0; k < 4; k++) {
2782 			outw(n++,base_io + 0x3c);
2783 			((unsigned long *)&setupdata[m][0])[k]=inl(base_io + 0x38);
2784 		    }
2785 		    for (k=0; k < 4; k++) {
2786 			outw(n++,base_io + 0x3c);
2787 			((unsigned long *)&p->sp[m][0])[k]=inl(base_io + 0x38);
2788 		    }
2789 		    n += 8;
2790 		}
2791 		goto next_fblk_885;
2792 flash_ok_885:
2793 #ifdef ED_DBGP
2794 		printk( "Flash Read OK\n");
2795 #endif
2796 		c=inb(base_io + 0x29);
2797 		outb((c & 0xfb),base_io + 0x29);
2798 		for (c=0;c < 2;c++) {
2799 		    p->ultra_map[c]=0;
2800 		    p->async[c] = 0;
2801 		    for (k=0; k < 16; k++) {
2802 			n=1;
2803 			n = n << k;
2804 			if (p->sp[c][k] > 1) {
2805 			   p->ultra_map[c] |= n;
2806 			} else {
2807 			   if (p->sp[c][k] == 0) {
2808 			      p->async[c] |= n;
2809 			   }
2810 			}
2811 		    }
2812 		    p->async[c] = ~(p->async[c]);
2813 
2814 		    if (p->global_map[c] == 0) {
2815 		       k=setupdata[c][1];
2816 		       if ((k & 0x40) != 0)
2817 			  p->global_map[c] |= 0x20;
2818 		       k &= 0x07;
2819 		       p->global_map[c] |= k;
2820 		       if ((setupdata[c][2] & 0x04) != 0)
2821 			  p->global_map[c] |= 0x08;
2822 		       p->host_id[c] = setupdata[c][0] & 0x07;
2823 		    }
2824 		}
2825 
2826 		k = inb(base_io + 0x28) & 0x8f;
2827 		k |= 0x10;
2828 		outb(k, base_io + 0x28);
2829 		outb(0x80, base_io + 0x41);
2830 		outb(0x80, base_io + 0x51);
2831 		mdelay(100);
2832 		outb(0, base_io + 0x41);
2833 		outb(0, base_io + 0x51);
2834 		mdelay(1000);
2835 		inb(base_io + 0x9b);
2836 		inb(base_io + 0x97);
2837 		inb(base_io + 0xdb);
2838 		inb(base_io + 0xd7);
2839 		tmport = base_io + 0x80;
2840 		k=p->host_id[0];
2841 		if (k > 7)
2842 		   k = (k & 0x07) | 0x40;
2843 		k |= 0x08;
2844 		outb(k, tmport);
2845 		tmport += 0x18;
2846 		outb(0, tmport);
2847 		tmport += 0x07;
2848 
2849 		while ((inb(tmport) & 0x80) == 0)
2850 			cpu_relax();
2851 
2852 		tmport -= 0x08;
2853 		inb(tmport);
2854 		tmport = base_io + 0x81;
2855 		outb(8, tmport++);
2856 		outb(0x7f, tmport);
2857 		tmport = base_io + 0x91;
2858 		outb(0x20, tmport);
2859 
2860 		tmport = base_io + 0xc0;
2861 		k=p->host_id[1];
2862 		if (k > 7)
2863 		   k = (k & 0x07) | 0x40;
2864 		k |= 0x08;
2865 		outb(k, tmport);
2866 		tmport += 0x18;
2867 		outb(0, tmport);
2868 		tmport += 0x07;
2869 
2870 		while ((inb(tmport) & 0x80) == 0)
2871 			cpu_relax();
2872 
2873 		tmport -= 0x08;
2874 		inb(tmport);
2875 		tmport = base_io + 0xc1;
2876 		outb(8, tmport++);
2877 		outb(0x7f, tmport);
2878 		tmport = base_io + 0xd1;
2879 		outb(0x20, tmport);
2880 
2881 		tscam_885();
2882 		printk(KERN_INFO "   Scanning Channel A SCSI Device ...\n");
2883 		is885(p, base_io + 0x80, 0);
2884 		printk(KERN_INFO "   Scanning Channel B SCSI Device ...\n");
2885 		is885(p, base_io + 0xc0, 1);
2886 
2887 		k = inb(base_io + 0x28) & 0xcf;
2888 		k |= 0xc0;
2889 		outb(k, base_io + 0x28);
2890 		k = inb(base_io + 0x1f) | 0x80;
2891 		outb(k, base_io + 0x1f);
2892 		k = inb(base_io + 0x29) | 0x01;
2893 		outb(k, base_io + 0x29);
2894 #ifdef ED_DBGP
2895 		//printk("atp885: atp_host[0] 0x%p\n", atp_host[0]);
2896 #endif
2897 		shpnt->max_id = 16;
2898 		shpnt->max_lun = (p->global_map[0] & 0x07) + 1;
2899 		shpnt->max_channel = 1;
2900 		shpnt->this_id = p->host_id[0];
2901 		shpnt->unique_id = base_io;
2902 		shpnt->io_port = base_io;
2903 		shpnt->n_io_port = 0xff;	/* Number of bytes of I/O space used */
2904 		shpnt->irq = pdev->irq;
2905 
2906 	} else {
2907 		error = pci_read_config_byte(pdev, 0x49, &host_id);
2908 
2909 		printk(KERN_INFO "   ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: %d "
2910 			"IO:%x, IRQ:%d.\n", count, base_io, pdev->irq);
2911 
2912 		atpdev->ioport[0] = base_io;
2913 		atpdev->pciport[0] = base_io + 0x20;
2914 		atpdev->dev_id = ent->device;
2915 		host_id &= 0x07;
2916 		atpdev->host_id[0] = host_id;
2917 		tmport = base_io + 0x22;
2918 		atpdev->scam_on = inb(tmport);
2919 		tmport += 0x0b;
2920 		atpdev->global_map[0] = inb(tmport++);
2921 		atpdev->ultra_map[0] = inw(tmport);
2922 
2923 		if (atpdev->ultra_map[0] == 0) {
2924 			atpdev->scam_on = 0x00;
2925 			atpdev->global_map[0] = 0x20;
2926 			atpdev->ultra_map[0] = 0xffff;
2927 		}
2928 
2929 		shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
2930 		if (!shpnt)
2931 			goto err_nomem;
2932 
2933 		p = (struct atp_unit *)&shpnt->hostdata;
2934 
2935 		atpdev->host = shpnt;
2936 		atpdev->pdev = pdev;
2937 		pci_set_drvdata(pdev, p);
2938 		memcpy(p, atpdev, sizeof(*atpdev));
2939 		if (atp870u_init_tables(shpnt) < 0)
2940 			goto unregister;
2941 
2942 		if (request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp870i", shpnt)) {
2943 			printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", pdev->irq);
2944 			goto free_tables;
2945 		}
2946 
2947 		spin_lock_irqsave(shpnt->host_lock, flags);
2948 		if (atpdev->chip_ver > 0x07) {	/* check if atp876 chip then enable terminator */
2949 			tmport = base_io + 0x3e;
2950 			outb(0x00, tmport);
2951 		}
2952 
2953 		tmport = base_io + 0x3a;
2954 		k = (inb(tmport) & 0xf3) | 0x10;
2955 		outb(k, tmport);
2956 		outb((k & 0xdf), tmport);
2957 		mdelay(32);
2958 		outb(k, tmport);
2959 		mdelay(32);
2960 		tmport = base_io;
2961 		outb((host_id | 0x08), tmport);
2962 		tmport += 0x18;
2963 		outb(0, tmport);
2964 		tmport += 0x07;
2965 		while ((inb(tmport) & 0x80) == 0)
2966 			mdelay(1);
2967 
2968 		tmport -= 0x08;
2969 		inb(tmport);
2970 		tmport = base_io + 1;
2971 		outb(8, tmport++);
2972 		outb(0x7f, tmport);
2973 		tmport = base_io + 0x11;
2974 		outb(0x20, tmport);
2975 
2976 		tscam(shpnt);
2977 		is870(p, base_io);
2978 		tmport = base_io + 0x3a;
2979 		outb((inb(tmport) & 0xef), tmport);
2980 		tmport++;
2981 		outb((inb(tmport) | 0x20), tmport);
2982 		if (atpdev->chip_ver == 4)
2983 			shpnt->max_id = 16;
2984 		else
2985 			shpnt->max_id = 8;
2986 		shpnt->this_id = host_id;
2987 		shpnt->unique_id = base_io;
2988 		shpnt->io_port = base_io;
2989 		shpnt->n_io_port = 0x40;	/* Number of bytes of I/O space used */
2990 		shpnt->irq = pdev->irq;
2991 	}
2992 		spin_unlock_irqrestore(shpnt->host_lock, flags);
2993 		if(ent->device==ATP885_DEVID) {
2994 			if(!request_region(base_io, 0xff, "atp870u")) /* Register the IO ports that we use */
2995 				goto request_io_fail;
2996 		} else if((ent->device==ATP880_DEVID1)||(ent->device==ATP880_DEVID2)) {
2997 			if(!request_region(base_io, 0x60, "atp870u")) /* Register the IO ports that we use */
2998 				goto request_io_fail;
2999 		} else {
3000 			if(!request_region(base_io, 0x40, "atp870u")) /* Register the IO ports that we use */
3001 				goto request_io_fail;
3002 		}
3003 		count++;
3004 		if (scsi_add_host(shpnt, &pdev->dev))
3005 			goto scsi_add_fail;
3006 		scsi_scan_host(shpnt);
3007 #ifdef ED_DBGP
3008 		printk("atp870u_prob : exit\n");
3009 #endif
3010 		return 0;
3011 
3012 scsi_add_fail:
3013 	printk("atp870u_prob:scsi_add_fail\n");
3014 	if(ent->device==ATP885_DEVID) {
3015 		release_region(base_io, 0xff);
3016 	} else if((ent->device==ATP880_DEVID1)||(ent->device==ATP880_DEVID2)) {
3017 		release_region(base_io, 0x60);
3018 	} else {
3019 		release_region(base_io, 0x40);
3020 	}
3021 request_io_fail:
3022 	printk("atp870u_prob:request_io_fail\n");
3023 	free_irq(pdev->irq, shpnt);
3024 free_tables:
3025 	printk("atp870u_prob:free_table\n");
3026 	atp870u_free_tables(shpnt);
3027 unregister:
3028 	printk("atp870u_prob:unregister\n");
3029 	scsi_host_put(shpnt);
3030 	return -1;
3031 err_eio:
3032 	kfree(atpdev);
3033 	return -EIO;
3034 err_nomem:
3035 	kfree(atpdev);
3036 	return -ENOMEM;
3037 }
3038 
3039 /* The abort command does not leave the device in a clean state where
3040    it is available to be used again.  Until this gets worked out, we will
3041    leave it commented out.  */
3042 
3043 static int atp870u_abort(struct scsi_cmnd * SCpnt)
3044 {
3045 	unsigned char  j, k, c;
3046 	struct scsi_cmnd *workrequ;
3047 	unsigned int tmport;
3048 	struct atp_unit *dev;
3049 	struct Scsi_Host *host;
3050 	host = SCpnt->device->host;
3051 
3052 	dev = (struct atp_unit *)&host->hostdata;
3053 	c = scmd_channel(SCpnt);
3054 	printk(" atp870u: abort Channel = %x \n", c);
3055 	printk("working=%x last_cmd=%x ", dev->working[c], dev->last_cmd[c]);
3056 	printk(" quhdu=%x quendu=%x ", dev->quhd[c], dev->quend[c]);
3057 	tmport = dev->ioport[c];
3058 	for (j = 0; j < 0x18; j++) {
3059 		printk(" r%2x=%2x", j, inb(tmport++));
3060 	}
3061 	tmport += 0x04;
3062 	printk(" r1c=%2x", inb(tmport));
3063 	tmport += 0x03;
3064 	printk(" r1f=%2x in_snd=%2x ", inb(tmport), dev->in_snd[c]);
3065 	tmport= dev->pciport[c];
3066 	printk(" d00=%2x", inb(tmport));
3067 	tmport += 0x02;
3068 	printk(" d02=%2x", inb(tmport));
3069 	for(j=0;j<16;j++) {
3070 	   if (dev->id[c][j].curr_req != NULL) {
3071 		workrequ = dev->id[c][j].curr_req;
3072 		printk("\n que cdb= ");
3073 		for (k=0; k < workrequ->cmd_len; k++) {
3074 		    printk(" %2x ",workrequ->cmnd[k]);
3075 		}
3076 		printk(" last_lenu= %x ",(unsigned int)dev->id[c][j].last_len);
3077 	   }
3078 	}
3079 	return SUCCESS;
3080 }
3081 
3082 static const char *atp870u_info(struct Scsi_Host *notused)
3083 {
3084 	static char buffer[128];
3085 
3086 	strcpy(buffer, "ACARD AEC-6710/6712/67160 PCI Ultra/W/LVD SCSI-3 Adapter Driver V2.6+ac ");
3087 
3088 	return buffer;
3089 }
3090 
3091 #define BLS buffer + len + size
3092 static int atp870u_proc_info(struct Scsi_Host *HBAptr, char *buffer,
3093 			     char **start, off_t offset, int length, int inout)
3094 {
3095 	static u8 buff[512];
3096 	int size = 0;
3097 	int len = 0;
3098 	off_t begin = 0;
3099 	off_t pos = 0;
3100 
3101 	if (inout)
3102 		return -EINVAL;
3103 	if (offset == 0)
3104 		memset(buff, 0, sizeof(buff));
3105 	size += sprintf(BLS, "ACARD AEC-671X Driver Version: 2.6+ac\n");
3106 	len += size;
3107 	pos = begin + len;
3108 	size = 0;
3109 
3110 	size += sprintf(BLS, "\n");
3111 	size += sprintf(BLS, "Adapter Configuration:\n");
3112 	size += sprintf(BLS, "               Base IO: %#.4lx\n", HBAptr->io_port);
3113 	size += sprintf(BLS, "                   IRQ: %d\n", HBAptr->irq);
3114 	len += size;
3115 	pos = begin + len;
3116 
3117 	*start = buffer + (offset - begin);	/* Start of wanted data */
3118 	len -= (offset - begin);	/* Start slop */
3119 	if (len > length) {
3120 		len = length;	/* Ending slop */
3121 	}
3122 	return (len);
3123 }
3124 
3125 
3126 static int atp870u_biosparam(struct scsi_device *disk, struct block_device *dev,
3127 			sector_t capacity, int *ip)
3128 {
3129 	int heads, sectors, cylinders;
3130 
3131 	heads = 64;
3132 	sectors = 32;
3133 	cylinders = (unsigned long)capacity / (heads * sectors);
3134 	if (cylinders > 1024) {
3135 		heads = 255;
3136 		sectors = 63;
3137 		cylinders = (unsigned long)capacity / (heads * sectors);
3138 	}
3139 	ip[0] = heads;
3140 	ip[1] = sectors;
3141 	ip[2] = cylinders;
3142 
3143 	return 0;
3144 }
3145 
3146 static void atp870u_remove (struct pci_dev *pdev)
3147 {
3148 	struct atp_unit *devext = pci_get_drvdata(pdev);
3149 	struct Scsi_Host *pshost = devext->host;
3150 
3151 
3152 	scsi_remove_host(pshost);
3153 	printk(KERN_INFO "free_irq : %d\n",pshost->irq);
3154 	free_irq(pshost->irq, pshost);
3155 	release_region(pshost->io_port, pshost->n_io_port);
3156 	printk(KERN_INFO "atp870u_free_tables : %p\n",pshost);
3157 	atp870u_free_tables(pshost);
3158 	printk(KERN_INFO "scsi_host_put : %p\n",pshost);
3159 	scsi_host_put(pshost);
3160 	printk(KERN_INFO "pci_set_drvdata : %p\n",pdev);
3161 	pci_set_drvdata(pdev, NULL);
3162 }
3163 MODULE_LICENSE("GPL");
3164 
3165 static struct scsi_host_template atp870u_template = {
3166      .module			= THIS_MODULE,
3167      .name              	= "atp870u"		/* name */,
3168      .proc_name			= "atp870u",
3169      .proc_info			= atp870u_proc_info,
3170      .info              	= atp870u_info		/* info */,
3171      .queuecommand      	= atp870u_queuecommand	/* queuecommand */,
3172      .eh_abort_handler  	= atp870u_abort		/* abort */,
3173      .bios_param        	= atp870u_biosparam	/* biosparm */,
3174      .can_queue         	= qcnt			/* can_queue */,
3175      .this_id           	= 7			/* SCSI ID */,
3176      .sg_tablesize      	= ATP870U_SCATTER	/*SG_ALL*/ /*SG_NONE*/,
3177      .cmd_per_lun       	= ATP870U_CMDLUN		/* commands per lun */,
3178      .use_clustering    	= ENABLE_CLUSTERING,
3179      .max_sectors		= ATP870U_MAX_SECTORS,
3180 };
3181 
3182 static struct pci_device_id atp870u_id_table[] = {
3183 	{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, ATP885_DEVID)			  },
3184 	{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, ATP880_DEVID1)			  },
3185 	{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, ATP880_DEVID2)			  },
3186 	{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7610)    },
3187 	{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612UW)  },
3188 	{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612U)   },
3189 	{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612S)   },
3190 	{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612D)	  },
3191 	{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612SUW) },
3192 	{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_8060)	  },
3193 	{ 0, },
3194 };
3195 
3196 MODULE_DEVICE_TABLE(pci, atp870u_id_table);
3197 
3198 static struct pci_driver atp870u_driver = {
3199 	.id_table	= atp870u_id_table,
3200 	.name		= "atp870u",
3201 	.probe		= atp870u_probe,
3202 	.remove		= __devexit_p(atp870u_remove),
3203 };
3204 
3205 static int __init atp870u_init(void)
3206 {
3207 #ifdef ED_DBGP
3208 	printk("atp870u_init: Entry\n");
3209 #endif
3210 	return pci_register_driver(&atp870u_driver);
3211 }
3212 
3213 static void __exit atp870u_exit(void)
3214 {
3215 #ifdef ED_DBGP
3216 	printk("atp870u_exit: Entry\n");
3217 #endif
3218 	pci_unregister_driver(&atp870u_driver);
3219 }
3220 
3221 static void tscam_885(void)
3222 {
3223 	unsigned char i;
3224 
3225 	for (i = 0; i < 0x2; i++) {
3226 		mdelay(300);
3227 	}
3228 	return;
3229 }
3230 
3231 
3232 
3233 static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c)
3234 {
3235 	unsigned int tmport;
3236 	unsigned char i, j, k, rmb, n, lvdmode;
3237 	unsigned short int m;
3238 	static unsigned char mbuf[512];
3239 	static unsigned char satn[9] =	{0, 0, 0, 0, 0, 0, 0, 6, 6};
3240 	static unsigned char inqd[9] =	{0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6};
3241 	static unsigned char synn[6] =	{0x80, 1, 3, 1, 0x19, 0x0e};
3242 	unsigned char synu[6] =  {0x80, 1, 3, 1, 0x0a, 0x0e};
3243 	static unsigned char synw[6] =	{0x80, 1, 3, 1, 0x19, 0x0e};
3244 	unsigned char synuw[6] =  {0x80, 1, 3, 1, 0x0a, 0x0e};
3245 	static unsigned char wide[6] =	{0x80, 1, 2, 3, 1, 0};
3246 	static unsigned char u3[9] = { 0x80,1,6,4,0x09,00,0x0e,0x01,0x02 };
3247 
3248 	lvdmode=inb(wkport + 0x1b) >> 7;
3249 
3250 	for (i = 0; i < 16; i++) {
3251 		m = 1;
3252 		m = m << i;
3253 		if ((m & dev->active_id[c]) != 0) {
3254 			continue;
3255 		}
3256 		if (i == dev->host_id[c]) {
3257 			printk(KERN_INFO "         ID: %2d  Host Adapter\n", dev->host_id[c]);
3258 			continue;
3259 		}
3260 		tmport = wkport + 0x1b;
3261 		outb(0x01, tmport);
3262 		tmport = wkport + 0x01;
3263 		outb(0x08, tmport++);
3264 		outb(0x7f, tmport++);
3265 		outb(satn[0], tmport++);
3266 		outb(satn[1], tmport++);
3267 		outb(satn[2], tmport++);
3268 		outb(satn[3], tmport++);
3269 		outb(satn[4], tmport++);
3270 		outb(satn[5], tmport++);
3271 		tmport += 0x06;
3272 		outb(0, tmport);
3273 		tmport += 0x02;
3274 		outb(dev->id[c][i].devsp, tmport++);
3275 
3276 		outb(0, tmport++);
3277 		outb(satn[6], tmport++);
3278 		outb(satn[7], tmport++);
3279 		j = i;
3280 		if ((j & 0x08) != 0) {
3281 			j = (j & 0x07) | 0x40;
3282 		}
3283 		outb(j, tmport);
3284 		tmport += 0x03;
3285 		outb(satn[8], tmport);
3286 		tmport += 0x07;
3287 
3288 		while ((inb(tmport) & 0x80) == 0x00)
3289 			cpu_relax();
3290 		tmport -= 0x08;
3291 		if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
3292 			continue;
3293 		}
3294 		while (inb(tmport) != 0x8e)
3295 			cpu_relax();
3296 		dev->active_id[c] |= m;
3297 
3298 		tmport = wkport + 0x10;
3299 		outb(0x30, tmport);
3300 		tmport = wkport + 0x14;
3301 		outb(0x00, tmport);
3302 
3303 phase_cmd:
3304 		tmport = wkport + 0x18;
3305 		outb(0x08, tmport);
3306 		tmport += 0x07;
3307 		while ((inb(tmport) & 0x80) == 0x00)
3308 			cpu_relax();
3309 		tmport -= 0x08;
3310 		j = inb(tmport);
3311 		if (j != 0x16) {
3312 			tmport = wkport + 0x10;
3313 			outb(0x41, tmport);
3314 			goto phase_cmd;
3315 		}
3316 sel_ok:
3317 		tmport = wkport + 0x03;
3318 		outb(inqd[0], tmport++);
3319 		outb(inqd[1], tmport++);
3320 		outb(inqd[2], tmport++);
3321 		outb(inqd[3], tmport++);
3322 		outb(inqd[4], tmport++);
3323 		outb(inqd[5], tmport);
3324 		tmport += 0x07;
3325 		outb(0, tmport);
3326 		tmport += 0x02;
3327 		outb(dev->id[c][i].devsp, tmport++);
3328 		outb(0, tmport++);
3329 		outb(inqd[6], tmport++);
3330 		outb(inqd[7], tmport++);
3331 		tmport += 0x03;
3332 		outb(inqd[8], tmport);
3333 		tmport += 0x07;
3334 		while ((inb(tmport) & 0x80) == 0x00)
3335 			cpu_relax();
3336 		tmport -= 0x08;
3337 		if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
3338 			continue;
3339 		}
3340 		while (inb(tmport) != 0x8e)
3341 			cpu_relax();
3342 		tmport = wkport + 0x1b;
3343 		outb(0x00, tmport);
3344 		tmport = wkport + 0x18;
3345 		outb(0x08, tmport);
3346 		tmport += 0x07;
3347 		j = 0;
3348 rd_inq_data:
3349 		k = inb(tmport);
3350 		if ((k & 0x01) != 0) {
3351 			tmport -= 0x06;
3352 			mbuf[j++] = inb(tmport);
3353 			tmport += 0x06;
3354 			goto rd_inq_data;
3355 		}
3356 		if ((k & 0x80) == 0) {
3357 			goto rd_inq_data;
3358 		}
3359 		tmport -= 0x08;
3360 		j = inb(tmport);
3361 		if (j == 0x16) {
3362 			goto inq_ok;
3363 		}
3364 		tmport = wkport + 0x10;
3365 		outb(0x46, tmport);
3366 		tmport += 0x02;
3367 		outb(0, tmport++);
3368 		outb(0, tmport++);
3369 		outb(0, tmport++);
3370 		tmport += 0x03;
3371 		outb(0x08, tmport);
3372 		tmport += 0x07;
3373 		while ((inb(tmport) & 0x80) == 0x00)
3374 			cpu_relax();
3375 		tmport -= 0x08;
3376 		if (inb(tmport) != 0x16) {
3377 			goto sel_ok;
3378 		}
3379 inq_ok:
3380 		mbuf[36] = 0;
3381 		printk( KERN_INFO"         ID: %2d  %s\n", i, &mbuf[8]);
3382 		dev->id[c][i].devtype = mbuf[0];
3383 		rmb = mbuf[1];
3384 		n = mbuf[7];
3385 		if ((mbuf[7] & 0x60) == 0) {
3386 			goto not_wide;
3387 		}
3388 		if ((i < 8) && ((dev->global_map[c] & 0x20) == 0)) {
3389 			goto not_wide;
3390 		}
3391 		if (lvdmode == 0) {
3392 		   goto chg_wide;
3393 		}
3394 		if (dev->sp[c][i] != 0x04) {	// force u2
3395 		   goto chg_wide;
3396 		}
3397 
3398 		tmport = wkport + 0x1b;
3399 		outb(0x01, tmport);
3400 		tmport = wkport + 0x03;
3401 		outb(satn[0], tmport++);
3402 		outb(satn[1], tmport++);
3403 		outb(satn[2], tmport++);
3404 		outb(satn[3], tmport++);
3405 		outb(satn[4], tmport++);
3406 		outb(satn[5], tmport++);
3407 		tmport += 0x06;
3408 		outb(0, tmport);
3409 		tmport += 0x02;
3410 		outb(dev->id[c][i].devsp, tmport++);
3411 		outb(0, tmport++);
3412 		outb(satn[6], tmport++);
3413 		outb(satn[7], tmport++);
3414 		tmport += 0x03;
3415 		outb(satn[8], tmport);
3416 		tmport += 0x07;
3417 
3418 		while ((inb(tmport) & 0x80) == 0x00)
3419 			cpu_relax();
3420 		tmport -= 0x08;
3421 		if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
3422 			continue;
3423 		}
3424 		while (inb(tmport) != 0x8e)
3425 			cpu_relax();
3426 try_u3:
3427 		j = 0;
3428 		tmport = wkport + 0x14;
3429 		outb(0x09, tmport);
3430 		tmport += 0x04;
3431 		outb(0x20, tmport);
3432 		tmport += 0x07;
3433 
3434 		while ((inb(tmport) & 0x80) == 0) {
3435 			if ((inb(tmport) & 0x01) != 0) {
3436 				tmport -= 0x06;
3437 				outb(u3[j++], tmport);
3438 				tmport += 0x06;
3439 			}
3440 			cpu_relax();
3441 		}
3442 		tmport -= 0x08;
3443 		while ((inb(tmport) & 0x80) == 0x00)
3444 			cpu_relax();
3445 		j = inb(tmport) & 0x0f;
3446 		if (j == 0x0f) {
3447 			goto u3p_in;
3448 		}
3449 		if (j == 0x0a) {
3450 			goto u3p_cmd;
3451 		}
3452 		if (j == 0x0e) {
3453 			goto try_u3;
3454 		}
3455 		continue;
3456 u3p_out:
3457 		tmport = wkport + 0x18;
3458 		outb(0x20, tmport);
3459 		tmport += 0x07;
3460 		while ((inb(tmport) & 0x80) == 0) {
3461 			if ((inb(tmport) & 0x01) != 0) {
3462 				tmport -= 0x06;
3463 				outb(0, tmport);
3464 				tmport += 0x06;
3465 			}
3466 			cpu_relax();
3467 		}
3468 		tmport -= 0x08;
3469 		j = inb(tmport) & 0x0f;
3470 		if (j == 0x0f) {
3471 			goto u3p_in;
3472 		}
3473 		if (j == 0x0a) {
3474 			goto u3p_cmd;
3475 		}
3476 		if (j == 0x0e) {
3477 			goto u3p_out;
3478 		}
3479 		continue;
3480 u3p_in:
3481 		tmport = wkport + 0x14;
3482 		outb(0x09, tmport);
3483 		tmport += 0x04;
3484 		outb(0x20, tmport);
3485 		tmport += 0x07;
3486 		k = 0;
3487 u3p_in1:
3488 		j = inb(tmport);
3489 		if ((j & 0x01) != 0) {
3490 			tmport -= 0x06;
3491 			mbuf[k++] = inb(tmport);
3492 			tmport += 0x06;
3493 			goto u3p_in1;
3494 		}
3495 		if ((j & 0x80) == 0x00) {
3496 			goto u3p_in1;
3497 		}
3498 		tmport -= 0x08;
3499 		j = inb(tmport) & 0x0f;
3500 		if (j == 0x0f) {
3501 			goto u3p_in;
3502 		}
3503 		if (j == 0x0a) {
3504 			goto u3p_cmd;
3505 		}
3506 		if (j == 0x0e) {
3507 			goto u3p_out;
3508 		}
3509 		continue;
3510 u3p_cmd:
3511 		tmport = wkport + 0x10;
3512 		outb(0x30, tmport);
3513 		tmport = wkport + 0x14;
3514 		outb(0x00, tmport);
3515 		tmport += 0x04;
3516 		outb(0x08, tmport);
3517 		tmport += 0x07;
3518 		while ((inb(tmport) & 0x80) == 0x00);
3519 		tmport -= 0x08;
3520 		j = inb(tmport);
3521 		if (j != 0x16) {
3522 			if (j == 0x4e) {
3523 				goto u3p_out;
3524 			}
3525 			continue;
3526 		}
3527 		if (mbuf[0] != 0x01) {
3528 			goto chg_wide;
3529 		}
3530 		if (mbuf[1] != 0x06) {
3531 			goto chg_wide;
3532 		}
3533 		if (mbuf[2] != 0x04) {
3534 			goto chg_wide;
3535 		}
3536 		if (mbuf[3] == 0x09) {
3537 			m = 1;
3538 			m = m << i;
3539 			dev->wide_id[c] |= m;
3540 			dev->id[c][i].devsp = 0xce;
3541 #ifdef ED_DBGP
3542 			printk("dev->id[%2d][%2d].devsp = %2x\n",c,i,dev->id[c][i].devsp);
3543 #endif
3544 			continue;
3545 		}
3546 chg_wide:
3547 		tmport = wkport + 0x1b;
3548 		outb(0x01, tmport);
3549 		tmport = wkport + 0x03;
3550 		outb(satn[0], tmport++);
3551 		outb(satn[1], tmport++);
3552 		outb(satn[2], tmport++);
3553 		outb(satn[3], tmport++);
3554 		outb(satn[4], tmport++);
3555 		outb(satn[5], tmport++);
3556 		tmport += 0x06;
3557 		outb(0, tmport);
3558 		tmport += 0x02;
3559 		outb(dev->id[c][i].devsp, tmport++);
3560 		outb(0, tmport++);
3561 		outb(satn[6], tmport++);
3562 		outb(satn[7], tmport++);
3563 		tmport += 0x03;
3564 		outb(satn[8], tmport);
3565 		tmport += 0x07;
3566 
3567 		while ((inb(tmport) & 0x80) == 0x00)
3568 			cpu_relax();
3569 		tmport -= 0x08;
3570 		if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
3571 			continue;
3572 		}
3573 		while (inb(tmport) != 0x8e)
3574 			cpu_relax();
3575 try_wide:
3576 		j = 0;
3577 		tmport = wkport + 0x14;
3578 		outb(0x05, tmport);
3579 		tmport += 0x04;
3580 		outb(0x20, tmport);
3581 		tmport += 0x07;
3582 
3583 		while ((inb(tmport) & 0x80) == 0) {
3584 			if ((inb(tmport) & 0x01) != 0) {
3585 				tmport -= 0x06;
3586 				outb(wide[j++], tmport);
3587 				tmport += 0x06;
3588 			}
3589 			cpu_relax();
3590 		}
3591 		tmport -= 0x08;
3592 		while ((inb(tmport) & 0x80) == 0x00)
3593 			cpu_relax();
3594 		j = inb(tmport) & 0x0f;
3595 		if (j == 0x0f) {
3596 			goto widep_in;
3597 		}
3598 		if (j == 0x0a) {
3599 			goto widep_cmd;
3600 		}
3601 		if (j == 0x0e) {
3602 			goto try_wide;
3603 		}
3604 		continue;
3605 widep_out:
3606 		tmport = wkport + 0x18;
3607 		outb(0x20, tmport);
3608 		tmport += 0x07;
3609 		while ((inb(tmport) & 0x80) == 0) {
3610 			if ((inb(tmport) & 0x01) != 0) {
3611 				tmport -= 0x06;
3612 				outb(0, tmport);
3613 				tmport += 0x06;
3614 			}
3615 			cpu_relax();
3616 		}
3617 		tmport -= 0x08;
3618 		j = inb(tmport) & 0x0f;
3619 		if (j == 0x0f) {
3620 			goto widep_in;
3621 		}
3622 		if (j == 0x0a) {
3623 			goto widep_cmd;
3624 		}
3625 		if (j == 0x0e) {
3626 			goto widep_out;
3627 		}
3628 		continue;
3629 widep_in:
3630 		tmport = wkport + 0x14;
3631 		outb(0xff, tmport);
3632 		tmport += 0x04;
3633 		outb(0x20, tmport);
3634 		tmport += 0x07;
3635 		k = 0;
3636 widep_in1:
3637 		j = inb(tmport);
3638 		if ((j & 0x01) != 0) {
3639 			tmport -= 0x06;
3640 			mbuf[k++] = inb(tmport);
3641 			tmport += 0x06;
3642 			goto widep_in1;
3643 		}
3644 		if ((j & 0x80) == 0x00) {
3645 			goto widep_in1;
3646 		}
3647 		tmport -= 0x08;
3648 		j = inb(tmport) & 0x0f;
3649 		if (j == 0x0f) {
3650 			goto widep_in;
3651 		}
3652 		if (j == 0x0a) {
3653 			goto widep_cmd;
3654 		}
3655 		if (j == 0x0e) {
3656 			goto widep_out;
3657 		}
3658 		continue;
3659 widep_cmd:
3660 		tmport = wkport + 0x10;
3661 		outb(0x30, tmport);
3662 		tmport = wkport + 0x14;
3663 		outb(0x00, tmport);
3664 		tmport += 0x04;
3665 		outb(0x08, tmport);
3666 		tmport += 0x07;
3667 		while ((inb(tmport) & 0x80) == 0x00)
3668 			cpu_relax();
3669 		tmport -= 0x08;
3670 		j = inb(tmport);
3671 		if (j != 0x16) {
3672 			if (j == 0x4e) {
3673 				goto widep_out;
3674 			}
3675 			continue;
3676 		}
3677 		if (mbuf[0] != 0x01) {
3678 			goto not_wide;
3679 		}
3680 		if (mbuf[1] != 0x02) {
3681 			goto not_wide;
3682 		}
3683 		if (mbuf[2] != 0x03) {
3684 			goto not_wide;
3685 		}
3686 		if (mbuf[3] != 0x01) {
3687 			goto not_wide;
3688 		}
3689 		m = 1;
3690 		m = m << i;
3691 		dev->wide_id[c] |= m;
3692 not_wide:
3693 		if ((dev->id[c][i].devtype == 0x00) || (dev->id[c][i].devtype == 0x07) ||
3694 		    ((dev->id[c][i].devtype == 0x05) && ((n & 0x10) != 0))) {
3695 			m = 1;
3696 			m = m << i;
3697 			if ((dev->async[c] & m) != 0) {
3698 			   goto set_sync;
3699 			}
3700 		}
3701 		continue;
3702 set_sync:
3703 		if (dev->sp[c][i] == 0x02) {
3704 		   synu[4]=0x0c;
3705 		   synuw[4]=0x0c;
3706 		} else {
3707 		   if (dev->sp[c][i] >= 0x03) {
3708 		      synu[4]=0x0a;
3709 		      synuw[4]=0x0a;
3710 		   }
3711 		}
3712 		tmport = wkport + 0x1b;
3713 		j = 0;
3714 		if ((m & dev->wide_id[c]) != 0) {
3715 			j |= 0x01;
3716 		}
3717 		outb(j, tmport);
3718 		tmport = wkport + 0x03;
3719 		outb(satn[0], tmport++);
3720 		outb(satn[1], tmport++);
3721 		outb(satn[2], tmport++);
3722 		outb(satn[3], tmport++);
3723 		outb(satn[4], tmport++);
3724 		outb(satn[5], tmport++);
3725 		tmport += 0x06;
3726 		outb(0, tmport);
3727 		tmport += 0x02;
3728 		outb(dev->id[c][i].devsp, tmport++);
3729 		outb(0, tmport++);
3730 		outb(satn[6], tmport++);
3731 		outb(satn[7], tmport++);
3732 		tmport += 0x03;
3733 		outb(satn[8], tmport);
3734 		tmport += 0x07;
3735 
3736 		while ((inb(tmport) & 0x80) == 0x00)
3737 			cpu_relax();
3738 		tmport -= 0x08;
3739 		if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
3740 			continue;
3741 		}
3742 		while (inb(tmport) != 0x8e)
3743 			cpu_relax();
3744 try_sync:
3745 		j = 0;
3746 		tmport = wkport + 0x14;
3747 		outb(0x06, tmport);
3748 		tmport += 0x04;
3749 		outb(0x20, tmport);
3750 		tmport += 0x07;
3751 
3752 		while ((inb(tmport) & 0x80) == 0) {
3753 			if ((inb(tmport) & 0x01) != 0) {
3754 				tmport -= 0x06;
3755 				if ((m & dev->wide_id[c]) != 0) {
3756 					if ((m & dev->ultra_map[c]) != 0) {
3757 						outb(synuw[j++], tmport);
3758 					} else {
3759 						outb(synw[j++], tmport);
3760 					}
3761 				} else {
3762 					if ((m & dev->ultra_map[c]) != 0) {
3763 						outb(synu[j++], tmport);
3764 					} else {
3765 						outb(synn[j++], tmport);
3766 					}
3767 				}
3768 				tmport += 0x06;
3769 			}
3770 		}
3771 		tmport -= 0x08;
3772 		while ((inb(tmport) & 0x80) == 0x00)
3773 			cpu_relax();
3774 		j = inb(tmport) & 0x0f;
3775 		if (j == 0x0f) {
3776 			goto phase_ins;
3777 		}
3778 		if (j == 0x0a) {
3779 			goto phase_cmds;
3780 		}
3781 		if (j == 0x0e) {
3782 			goto try_sync;
3783 		}
3784 		continue;
3785 phase_outs:
3786 		tmport = wkport + 0x18;
3787 		outb(0x20, tmport);
3788 		tmport += 0x07;
3789 		while ((inb(tmport) & 0x80) == 0x00) {
3790 			if ((inb(tmport) & 0x01) != 0x00) {
3791 				tmport -= 0x06;
3792 				outb(0x00, tmport);
3793 				tmport += 0x06;
3794 			}
3795 			cpu_relax();
3796 		}
3797 		tmport -= 0x08;
3798 		j = inb(tmport);
3799 		if (j == 0x85) {
3800 			goto tar_dcons;
3801 		}
3802 		j &= 0x0f;
3803 		if (j == 0x0f) {
3804 			goto phase_ins;
3805 		}
3806 		if (j == 0x0a) {
3807 			goto phase_cmds;
3808 		}
3809 		if (j == 0x0e) {
3810 			goto phase_outs;
3811 		}
3812 		continue;
3813 phase_ins:
3814 		tmport = wkport + 0x14;
3815 		outb(0x06, tmport);
3816 		tmport += 0x04;
3817 		outb(0x20, tmport);
3818 		tmport += 0x07;
3819 		k = 0;
3820 phase_ins1:
3821 		j = inb(tmport);
3822 		if ((j & 0x01) != 0x00) {
3823 			tmport -= 0x06;
3824 			mbuf[k++] = inb(tmport);
3825 			tmport += 0x06;
3826 			goto phase_ins1;
3827 		}
3828 		if ((j & 0x80) == 0x00) {
3829 			goto phase_ins1;
3830 		}
3831 		tmport -= 0x08;
3832 		while ((inb(tmport) & 0x80) == 0x00);
3833 		j = inb(tmport);
3834 		if (j == 0x85) {
3835 			goto tar_dcons;
3836 		}
3837 		j &= 0x0f;
3838 		if (j == 0x0f) {
3839 			goto phase_ins;
3840 		}
3841 		if (j == 0x0a) {
3842 			goto phase_cmds;
3843 		}
3844 		if (j == 0x0e) {
3845 			goto phase_outs;
3846 		}
3847 		continue;
3848 phase_cmds:
3849 		tmport = wkport + 0x10;
3850 		outb(0x30, tmport);
3851 tar_dcons:
3852 		tmport = wkport + 0x14;
3853 		outb(0x00, tmport);
3854 		tmport += 0x04;
3855 		outb(0x08, tmport);
3856 		tmport += 0x07;
3857 		while ((inb(tmport) & 0x80) == 0x00)
3858 			cpu_relax();
3859 		tmport -= 0x08;
3860 		j = inb(tmport);
3861 		if (j != 0x16) {
3862 			continue;
3863 		}
3864 		if (mbuf[0] != 0x01) {
3865 			continue;
3866 		}
3867 		if (mbuf[1] != 0x03) {
3868 			continue;
3869 		}
3870 		if (mbuf[4] == 0x00) {
3871 			continue;
3872 		}
3873 		if (mbuf[3] > 0x64) {
3874 			continue;
3875 		}
3876 		if (mbuf[4] > 0x0e) {
3877 			mbuf[4] = 0x0e;
3878 		}
3879 		dev->id[c][i].devsp = mbuf[4];
3880 		if (mbuf[3] < 0x0c){
3881 			j = 0xb0;
3882 			goto set_syn_ok;
3883 		}
3884 		if ((mbuf[3] < 0x0d) && (rmb == 0)) {
3885 			j = 0xa0;
3886 			goto set_syn_ok;
3887 		}
3888 		if (mbuf[3] < 0x1a) {
3889 			j = 0x20;
3890 			goto set_syn_ok;
3891 		}
3892 		if (mbuf[3] < 0x33) {
3893 			j = 0x40;
3894 			goto set_syn_ok;
3895 		}
3896 		if (mbuf[3] < 0x4c) {
3897 			j = 0x50;
3898 			goto set_syn_ok;
3899 		}
3900 		j = 0x60;
3901 	      set_syn_ok:
3902 		dev->id[c][i].devsp = (dev->id[c][i].devsp & 0x0f) | j;
3903 #ifdef ED_DBGP
3904 		printk("dev->id[%2d][%2d].devsp = %2x\n",c,i,dev->id[c][i].devsp);
3905 #endif
3906 	}
3907 	tmport = wkport + 0x16;
3908 	outb(0x80, tmport);
3909 }
3910 
3911 module_init(atp870u_init);
3912 module_exit(atp870u_exit);
3913 
3914