Linux Audio

Check our new training course

Linux kernel drivers training

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