Linux Audio

Check our new training course

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