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