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