patch-2.4.7 linux/drivers/scsi/atp870u.c

Next file: linux/drivers/scsi/cpqfcTSinit.c
Previous file: linux/drivers/scsi/aic7xxx_old.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.6/linux/drivers/scsi/atp870u.c linux/drivers/scsi/atp870u.c
@@ -10,6 +10,8 @@
  *		   support atp876 chip
  *		   enable 32 bit fifo transfer
  *		   support cdrom & remove device run ultra speed
+ *		   fix disconnect bug  2000/12/21
+ *		   support atp880 chip lvd u160 2001/05/15
  */
 
 #include <linux/module.h>
@@ -63,6 +65,7 @@
 	unsigned short wide_idu;
 	unsigned short active_idu;
 	unsigned short ultra_map;
+	unsigned short deviceid;
 	unsigned char ata_cdbu[16];
 	Scsi_Cmnd *querequ[qcnt];
 	struct atp_id
@@ -137,14 +140,6 @@
 		tmport -= 0x08;
 
 		i = inb(tmport);
-		if ((j & 0x40) == 0)
-		{
-			if ((dev->last_cmd & 0x40) == 0)
-			{
-				dev->last_cmd = 0xff;
-			}
-		}
-		else dev->last_cmd |= 0x40;
 
 		tmport -= 0x02;
 		target_id = inb(tmport);
@@ -160,8 +155,21 @@
 			target_id &= 0x07;
 		}
 
+		if ((j & 0x40) != 0)
+		{
+		     if (dev->last_cmd == 0xff)
+		     {
+			dev->last_cmd = target_id;
+		     }
+		     dev->last_cmd |= 0x40;
+		}
+
 		if (i == 0x85)
 		{
+			if ((dev->last_cmd & 0xf0) != 0x40)
+			{
+			   dev->last_cmd = 0xff;
+			}
 			/*
 			 *	Flip wide
 			 */
@@ -188,8 +196,20 @@
 			dev->in_int = 0;
 			return;
 		}
+
+		if (i == 0x40)
+		{
+		     dev->last_cmd |= 0x40;
+		     dev->in_int = 0;
+		     return;
+		}
+
 		if (i == 0x21)
 		{
+			if ((dev->last_cmd & 0xf0) != 0x40)
+			{
+			   dev->last_cmd = 0xff;
+			}
 			tmport -= 0x05;
 			adrcntu = 0;
 			((unsigned char *) &adrcntu)[2] = inb(tmport++);
@@ -215,6 +235,10 @@
 				tmport += 0x0d;
 				lun = inb(tmport) & 0x07;
 			} else {
+				if ((dev->last_cmd & 0xf0) != 0x40)
+				{
+				   dev->last_cmd = 0xff;
+				}
 				if (j == 0x41)
 				{
 					tmport += 0x02;
@@ -245,6 +269,10 @@
 					return;
 				}
 			}
+			if (dev->last_cmd != 0xff)
+			{
+			   dev->last_cmd |= 0x40;
+			}
 			tmport = workportu + 0x10;
 			outb(0x45, tmport);
 			tmport += 0x06;
@@ -279,15 +307,31 @@
 			outb(0x80, tmport);
 
 			/* enable 32 bit fifo transfer */
-			tmport = workportu + 0x3a;
-			if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) ||
-			    (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a))
+			if (dev->deviceid != 0x8081)
 			{
-				outb((unsigned char)((inb(tmport) & 0xf3) | 0x08),tmport);
+			   tmport = workportu + 0x3a;
+			   if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) ||
+			       (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a))
+			   {
+			      outb((unsigned char)((inb(tmport) & 0xf3) | 0x08),tmport);
+			   }
+			   else
+			   {
+			      outb((unsigned char)(inb(tmport) & 0xf3),tmport);
+			   }
 			}
 			else
 			{
-				outb((unsigned char)(inb(tmport) & 0xf3),tmport);
+			   tmport = workportu - 0x05;
+			   if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) ||
+			       (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a))
+			   {
+			      outb((unsigned char)((inb(tmport) & 0x3f) | 0xc0),tmport);
+			   }
+			   else
+			   {
+			      outb((unsigned char)(inb(tmport) & 0x3f),tmport);
+			   }
 			}
 
 			tmport = workportu + 0x1b;
@@ -303,7 +347,7 @@
 			outb(j, tmport);
 			while ((inb(tmport) & 0x01) != j)
 			{
-				outb(j,tmport);
+			   outb(j,tmport);
 			}
 
 			if (dev->id[target_id].last_lenu == 0) {
@@ -365,12 +409,20 @@
 		workrequ = dev->id[target_id].curr_req;
 
 		if (i == 0x42) {
+			if ((dev->last_cmd & 0xf0) != 0x40)
+			{
+			   dev->last_cmd = 0xff;
+			}
 			errstus = 0x02;
 			workrequ->result = errstus;
 			goto go_42;
 		}
 		if (i == 0x16)
 		{
+			if ((dev->last_cmd & 0xf0) != 0x40)
+			{
+			   dev->last_cmd = 0xff;
+			}
 			errstus = 0;
 			tmport -= 0x08;
 			errstus = inb(tmport);
@@ -381,13 +433,13 @@
 			 */
 			spin_lock_irqsave(&io_request_lock, flags);
 			(*workrequ->scsi_done) (workrequ);
-			spin_unlock_irqrestore(&io_request_lock, flags);
 
 			/*
 			 *	Clear it off the queue
 			 */
 			dev->id[target_id].curr_req = 0;
 			dev->working--;
+			spin_unlock_irqrestore(&io_request_lock, flags);
 			/*
 			 *	Take it back wide
 			 */
@@ -396,7 +448,7 @@
 				outb(0x01,tmport);
 				while ((inb(tmport) & 0x01) != 0x01)
 				{
-					outb(0x01,tmport);
+				   outb(0x01,tmport);
 				}
 			}
 			/*
@@ -405,11 +457,15 @@
 			if (((dev->last_cmd != 0xff) || (dev->quhdu != dev->quendu)) &&
 			    (dev->in_snd == 0))
 			{
-				send_s870(h);
+			   send_s870(h);
 			}
 			dev->in_int = 0;
 			return;
 		}
+		if ((dev->last_cmd & 0xf0) != 0x40)
+		{
+		   dev->last_cmd = 0xff;
+		}
 		if (i == 0x4f) {
 			i = 0x89;
 		}
@@ -474,7 +530,7 @@
 
 int atp870u_queuecommand(Scsi_Cmnd * req_p, void (*done) (Scsi_Cmnd *))
 {
-	unsigned char i, h;
+	unsigned char h;
 	unsigned long flags;
 	unsigned short int m;
 	unsigned int tmport;
@@ -516,6 +572,8 @@
 	/*
 	 *	Count new command
 	 */
+	save_flags(flags);
+	cli();
 	dev->quendu++;
 	if (dev->quendu >= qcnt) {
 		dev->quendu = 0;
@@ -523,18 +581,17 @@
 	/*
 	 *	Check queue state
 	 */
-wait_que_empty:
 	if (dev->quhdu == dev->quendu) {
-		goto wait_que_empty;
+		if (dev->quendu == 0) {
+			dev->quendu = qcnt;
+		}
+		dev->quendu--;
+		req_p->result = 0x00020000;
+		done(req_p);
+		restore_flags(flags);
+		return 0;
 	}
-	save_flags(flags);
-	cli();
 	dev->querequ[dev->quendu] = req_p;
-	if (dev->quendu == 0) {
-		i = qcnt - 1;
-	} else {
-		i = dev->quendu - 1;
-	}
 	tmport = dev->ioport + 0x1c;
 	restore_flags(flags);
 	if ((inb(tmport) == 0) && (dev->in_int == 0) && (dev->in_snd == 0)) {
@@ -582,11 +639,17 @@
 		dev->last_cmd = 0xff;
 		if (dev->quhdu == dev->quendu)
 		{
-			dev->in_snd = 0;
-			restore_flags(flags);
-			return ;
+		   dev->in_snd = 0;
+		   restore_flags(flags);
+		   return ;
 		}
 	}
+	if ((dev->last_cmd != 0xff) && (dev->working != 0))
+	{
+	     dev->in_snd = 0;
+	     restore_flags(flags);
+	     return ;
+	}
 	dev->working++;
 	j = dev->quhdu;
 	dev->quhdu++;
@@ -629,15 +692,6 @@
 	if (dev->ata_cdbu[0] == 0x00) {
 		workrequ->request_bufflen = 0;
 	}
-	/*
-	 *	Why limit this ????
-	 */
-	if (dev->ata_cdbu[0] == INQUIRY) {
-		if (workrequ->request_bufflen > 0x24) {
-			workrequ->request_bufflen = 0x24;
-			dev->ata_cdbu[4] = 0x24;
-		}
-	}
 
 	tmport = workportu + 0x1b;
 	j = 0;
@@ -654,7 +708,7 @@
 	outb(j, tmport);
 	while ((inb(tmport) & 0x01) != j)
 	{
-		outb(j,tmport);
+	   outb(j,tmport);
 	}
 
 	/*
@@ -780,15 +834,31 @@
 	outb(0x00, tmpcip);
 	tmpcip = tmpcip - 2;
 
-	tmport = workportu + 0x3a;
-	if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) ||
-	    (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a))
+	if (dev->deviceid != 0x8081)
 	{
-		outb((unsigned char)((inb(tmport) & 0xf3) | 0x08),tmport);
+	   tmport = workportu + 0x3a;
+	   if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) ||
+	       (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a))
+	   {
+	      outb((unsigned char)((inb(tmport) & 0xf3) | 0x08),tmport);
+	   }
+	   else
+	   {
+	      outb((unsigned char)(inb(tmport) & 0xf3),tmport);
+	   }
 	}
 	else
 	{
-		outb((unsigned char)(inb(tmport) & 0xf3),tmport);
+	   tmport = workportu - 0x05;
+	   if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) ||
+	       (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a))
+	   {
+	      outb((unsigned char)((inb(tmport) & 0x3f) | 0xc0),tmport);
+	   }
+	   else
+	   {
+	      outb((unsigned char)(inb(tmport) & 0x3f),tmport);
+	   }
 	}
 	tmport = workportu + 0x1c;
 
@@ -1152,11 +1222,11 @@
 		}
 		tmport = wkport + 0x1b;
 		if (dev->chip_veru == 4) {
-			outb(0x01, tmport);
+		   outb(0x01, tmport);
 		}
 		else
 		{
-			outb(0x00, tmport);
+		   outb(0x00, tmport);
 		}
 		tmport = wkport + 1;
 		outb(0x08, tmport++);
@@ -1615,182 +1685,909 @@
 	outb((unsigned char) (inb(tmport) & 0xef), tmport);
 }
 
-/* return non-zero on detection */
-int atp870u_detect(Scsi_Host_Template * tpnt)
+void is880(unsigned long host, unsigned int wkport)
 {
-	unsigned char irq, h, k;
-	unsigned long flags;
-	unsigned int base_io, error, tmport;
-	unsigned short index = 0;
-	struct pci_dev *pdev[3];
-	unsigned char chip_ver[3], host_id;
-	struct Scsi_Host *shpnt = NULL;
-	int tmpcnt = 0;
-	int count = 0;
-
-	static unsigned short devid[8] = {
-		0x8002, 0x8010, 0x8020, 0x8030, 0x8040, 0x8050, 0x8060, 0
-	};
+	unsigned int tmport;
+	unsigned char i, j, k, rmb, n, lvdmode;
+	unsigned short int m;
+	static unsigned char mbuf[512];
+	static unsigned char satn[9] =	{0, 0, 0, 0, 0, 0, 0, 6, 6};
+	static unsigned char inqd[9] =	{0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6};
+	static unsigned char synn[6] =	{0x80, 1, 3, 1, 0x19, 0x0e};
+	static unsigned char synu[6] =	{0x80, 1, 3, 1, 0x0a, 0x0e};
+	static unsigned char synw[6] =	{0x80, 1, 3, 1, 0x0a, 0x0e};
+	static unsigned char wide[6] =	{0x80, 1, 2, 3, 1, 0};
+	static unsigned char u3[9] = { 0x80,1,6,4,0x09,00,0x0e,0x01,0x02 };
+	struct atp_unit *dev = &atp_unit[host];
 
-	printk(KERN_INFO "aec671x_detect: \n");
-	if (!pci_present()) {
-		printk(KERN_INFO"   NO PCI SUPPORT.\n");
-		return count;
-	}
-	tpnt->proc_name = "atp870u";
+	sync_idu = 0;
+	lvdmode=inb(wkport + 0x3f) & 0x40;
 
-	for (h = 0; h < 2; h++) {
-		struct atp_unit *dev = &atp_unit[h];
-		for(k=0;k<16;k++)
-		{
-			dev->id[k].prd_tableu = kmalloc(1024, GFP_KERNEL);
-			dev->id[k].devspu=0x20;
-			dev->id[k].devtypeu = 0;
-			dev->id[k].curr_req = NULL;
-		}
-		dev->active_idu = 0;
-		dev->wide_idu = 0;
-		dev->host_idu = 0x07;
-		dev->quhdu = 0;
-		dev->quendu = 0;
-		pdev[h]=NULL;
-		pdev[2]=NULL;
-		dev->chip_veru = 0;
-		dev->last_cmd = 0xff;
-		dev->in_snd = 0;
-		dev->in_int = 0;
-		for (k = 0; k < qcnt; k++) {
-			dev->querequ[k] = 0;
-		}
-		for (k = 0; k < 16; k++) {
-			dev->id[k].curr_req = 0;
-		}
-	}
-	h = 0;
-	while (devid[h] != 0) {
-		pdev[2] = pci_find_device(0x1191, devid[h], pdev[2]);
-		if (pdev[2] == NULL || pci_enable_device(pdev[2])) {
-			h++;
-			index = 0;
+	for (i = 0; i < 16; i++) {
+		m = 1;
+		m = m << i;
+		if ((m & dev->active_idu) != 0) {
 			continue;
 		}
-		chip_ver[2] = 0;
-
-		if (devid[h] == 0x8002) {
-			error = pci_read_config_byte(pdev[2], 0x08, &chip_ver[2]);
-			if (chip_ver[2] < 2) {
-				goto nxt_devfn;
-			}
-		}
-		if (devid[h] == 0x8010 || devid[h] == 0x8050) {
-			chip_ver[2] = 0x04;
-		}
-		pdev[tmpcnt] = pdev[2];
-		chip_ver[tmpcnt] = chip_ver[2];
-		tmpcnt++;
-	      nxt_devfn:
-		index++;
-		if (index > 3) {
-			index = 0;
-			h++;
+		if (i == dev->host_idu) {
+			printk(KERN_INFO "         ID: %2d  Host Adapter\n", dev->host_idu);
+			continue;
 		}
-		if(tmpcnt>1)
-			break;
-	}
-	for (h = 0; h < 2; h++) {
-		struct atp_unit *dev=&atp_unit[h];
-		if (pdev[h]==NULL) {
-			return count;
+		tmport = wkport + 0x5b;
+		outb(0x01, tmport);
+		tmport = wkport + 0x41;
+		outb(0x08, tmport++);
+		outb(0x7f, tmport++);
+		outb(satn[0], tmport++);
+		outb(satn[1], tmport++);
+		outb(satn[2], tmport++);
+		outb(satn[3], tmport++);
+		outb(satn[4], tmport++);
+		outb(satn[5], tmport++);
+		tmport += 0x06;
+		outb(0, tmport);
+		tmport += 0x02;
+		outb(dev->id[i].devspu, tmport++);
+		outb(0, tmport++);
+		outb(satn[6], tmport++);
+		outb(satn[7], tmport++);
+		j = i;
+		if ((j & 0x08) != 0) {
+			j = (j & 0x07) | 0x40;
 		}
+		outb(j, tmport);
+		tmport += 0x03;
+		outb(satn[8], tmport);
+		tmport += 0x07;
 
-		/* Found an atp870u/w. */
-		base_io = pci_resource_start(pdev[h], 0);
-		irq = pdev[h]->irq;
-		error = pci_read_config_byte(pdev[h],0x49,&host_id);
+		while ((inb(tmport) & 0x80) == 0x00);
+		tmport -= 0x08;
+		if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
+			continue;
+		}
+		while (inb(tmport) != 0x8e);
+		dev->active_idu |= m;
 
-		base_io &= 0xfffffff8;
+		tmport = wkport + 0x50;
+		outb(0x30, tmport);
+		tmport = wkport + 0x54;
+		outb(0x00, tmport);
 
-		if (check_region(base_io,0x40) != 0)
-		{  
-			return 0;
+phase_cmd:
+		tmport = wkport + 0x58;
+		outb(0x08, tmport);
+		tmport += 0x07;
+		while ((inb(tmport) & 0x80) == 0x00);
+		tmport -= 0x08;
+		j = inb(tmport);
+		if (j != 0x16) {
+			tmport = wkport + 0x50;
+			outb(0x41, tmport);
+			goto phase_cmd;
+		}
+sel_ok:
+		tmport = wkport + 0x43;
+		outb(inqd[0], tmport++);
+		outb(inqd[1], tmport++);
+		outb(inqd[2], tmport++);
+		outb(inqd[3], tmport++);
+		outb(inqd[4], tmport++);
+		outb(inqd[5], tmport);
+		tmport += 0x07;
+		outb(0, tmport);
+		tmport += 0x02;
+		outb(dev->id[i].devspu, tmport++);
+		outb(0, tmport++);
+		outb(inqd[6], tmport++);
+		outb(inqd[7], tmport++);
+		tmport += 0x03;
+		outb(inqd[8], tmport);
+		tmport += 0x07;
+		while ((inb(tmport) & 0x80) == 0x00);
+		tmport -= 0x08;
+		if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
+			continue;
 		}
-		printk(KERN_INFO "   ACARD AEC-671X PCI Ultra/W SCSI-3 Host Adapter: %d    IO:%x, IRQ:%d.\n"
-		       ,h, base_io, irq);
-		dev->ioport = base_io;
-		dev->pciport = base_io + 0x20;
-		irqnumu[h] = irq;
-		host_id &= 0x07;
-		dev->host_idu = host_id;
-		dev->chip_veru = chip_ver[h];
-
-		tmport = base_io + 0x22;
-		dev->scam_on = inb(tmport);
-		tmport += 0x0b;
-		dev->global_map = inb(tmport++);
-		dev->ultra_map = inw(tmport);
-		if (dev->ultra_map == 0) {
-			dev->scam_on = 0x00;
-			dev->global_map = 0x20;
-			dev->ultra_map = 0xffff;
+		while (inb(tmport) != 0x8e);
+		tmport = wkport + 0x5b;
+		outb(0x00, tmport);
+		tmport = wkport + 0x58;
+		outb(0x08, tmport);
+		tmport += 0x07;
+		j = 0;
+rd_inq_data:
+		k = inb(tmport);
+		if ((k & 0x01) != 0) {
+			tmport -= 0x06;
+			mbuf[j++] = inb(tmport);
+			tmport += 0x06;
+			goto rd_inq_data;
 		}
-		shpnt = scsi_register(tpnt, 4);
-		if(shpnt==NULL)
-			return count;
-
-		save_flags(flags);
-		cli();
-		if (request_irq(irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", dev)) {
-			printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n");
-			goto unregister;
+		if ((k & 0x80) == 0) {
+			goto rd_inq_data;
 		}
-
-		if (chip_ver[h] > 0x07) 	  /* check if atp876 chip   */
-		{				  /* then enable terminator */
-			tmport = base_io + 0x3e;
-			outb(0x30, tmport);
+		tmport -= 0x08;
+		j = inb(tmport);
+		if (j == 0x16) {
+			goto inq_ok;
 		}
-
-		tmport = base_io + 0x3a;
-		k = (inb(tmport) & 0xf3) | 0x10;
-		outb(k, tmport);
-		outb((k & 0xdf), tmport);
-		mydlyu(0x8000);
-		outb(k, tmport);
-		mydlyu(0x8000);
-		tmport = base_io;
-		outb((host_id | 0x08), tmport);
-		tmport += 0x18;
-		outb(0, tmport);
+		tmport = wkport + 0x50;
+		outb(0x46, tmport);
+		tmport += 0x02;
+		outb(0, tmport++);
+		outb(0, tmport++);
+		outb(0, tmport++);
+		tmport += 0x03;
+		outb(0x08, tmport);
 		tmport += 0x07;
-		while ((inb(tmport) & 0x80) == 0);
+		while ((inb(tmport) & 0x80) == 0x00);
 		tmport -= 0x08;
-		inb(tmport);
-		tmport = base_io + 1;
-		outb(8, tmport++);
-		outb(0x7f, tmport);
-		tmport = base_io + 0x11;
-		outb(0x20, tmport);
-
-		tscam(h);
-		is870(h, base_io);
-		tmport = base_io + 0x3a;
-		outb((inb(tmport) & 0xef), tmport);
-		tmport++;
-		outb((inb(tmport) | 0x20),tmport);
-
-		atp_host[h] = shpnt;
-		if (dev->chip_veru == 4) {
-			shpnt->max_id = 16;
+		if (inb(tmport) != 0x16) {
+			goto sel_ok;
 		}
-		shpnt->this_id = host_id;
-		shpnt->unique_id = base_io;
-		shpnt->io_port = base_io;
-		shpnt->n_io_port = 0x40;	/* Number of bytes of I/O space used */
-		shpnt->irq = irq;
-		scsi_set_pci_device(shpnt, pdev[h]);
-		restore_flags(flags);
-		request_region(base_io, 0x40, "atp870u");       /* Register the IO ports that we use */
-		count++;
+inq_ok:
+		mbuf[36] = 0;
+		printk(KERN_INFO "         ID: %2d  %s\n", i, &mbuf[8]);
+		dev->id[i].devtypeu = mbuf[0];
+		rmb = mbuf[1];
+		n = mbuf[7];
+		if ((mbuf[7] & 0x60) == 0) {
+			goto not_wide;
+		}
+		if ((dev->global_map & 0x20) == 0) {
+			goto not_wide;
+		}
+		if (lvdmode == 0)
+		{
+		   goto chg_wide;
+		}
+		if ((mbuf[2] & 0x07) < 0x03)	      // force u2
+		{
+		   goto chg_wide;
+		}
+		tmport = wkport + 0x5b;
+		outb(0x01, tmport);
+		tmport = wkport + 0x43;
+		outb(satn[0], tmport++);
+		outb(satn[1], tmport++);
+		outb(satn[2], tmport++);
+		outb(satn[3], tmport++);
+		outb(satn[4], tmport++);
+		outb(satn[5], tmport++);
+		tmport += 0x06;
+		outb(0, tmport);
+		tmport += 0x02;
+		outb(dev->id[i].devspu, tmport++);
+		outb(0, tmport++);
+		outb(satn[6], tmport++);
+		outb(satn[7], tmport++);
+		tmport += 0x03;
+		outb(satn[8], tmport);
+		tmport += 0x07;
+
+		while ((inb(tmport) & 0x80) == 0x00);
+		tmport -= 0x08;
+		if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
+			continue;
+		}
+		while (inb(tmport) != 0x8e);
+try_u3:
+		j = 0;
+		tmport = wkport + 0x54;
+		outb(0x09, tmport);
+		tmport += 0x04;
+		outb(0x20, tmport);
+		tmport += 0x07;
+
+		while ((inb(tmport) & 0x80) == 0) {
+			if ((inb(tmport) & 0x01) != 0) {
+				tmport -= 0x06;
+				outb(u3[j++], tmport);
+				tmport += 0x06;
+			}
+		}
+		tmport -= 0x08;
+		while ((inb(tmport) & 0x80) == 0x00);
+		j = inb(tmport) & 0x0f;
+		if (j == 0x0f) {
+			goto u3p_in;
+		}
+		if (j == 0x0a) {
+			goto u3p_cmd;
+		}
+		if (j == 0x0e) {
+			goto try_u3;
+		}
+		continue;
+u3p_out:
+		tmport = wkport + 0x58;
+		outb(0x20, tmport);
+		tmport += 0x07;
+		while ((inb(tmport) & 0x80) == 0) {
+			if ((inb(tmport) & 0x01) != 0) {
+				tmport -= 0x06;
+				outb(0, tmport);
+				tmport += 0x06;
+			}
+		}
+		tmport -= 0x08;
+		j = inb(tmport) & 0x0f;
+		if (j == 0x0f) {
+			goto u3p_in;
+		}
+		if (j == 0x0a) {
+			goto u3p_cmd;
+		}
+		if (j == 0x0e) {
+			goto u3p_out;
+		}
+		continue;
+u3p_in:
+		tmport = wkport + 0x54;
+		outb(0x09, tmport);
+		tmport += 0x04;
+		outb(0x20, tmport);
+		tmport += 0x07;
+		k = 0;
+u3p_in1:
+		j = inb(tmport);
+		if ((j & 0x01) != 0) {
+			tmport -= 0x06;
+			mbuf[k++] = inb(tmport);
+			tmport += 0x06;
+			goto u3p_in1;
+		}
+		if ((j & 0x80) == 0x00) {
+			goto u3p_in1;
+		}
+		tmport -= 0x08;
+		j = inb(tmport) & 0x0f;
+		if (j == 0x0f) {
+			goto u3p_in;
+		}
+		if (j == 0x0a) {
+			goto u3p_cmd;
+		}
+		if (j == 0x0e) {
+			goto u3p_out;
+		}
+		continue;
+u3p_cmd:
+		tmport = wkport + 0x50;
+		outb(0x30, tmport);
+		tmport = wkport + 0x54;
+		outb(0x00, tmport);
+		tmport += 0x04;
+		outb(0x08, tmport);
+		tmport += 0x07;
+		while ((inb(tmport) & 0x80) == 0x00);
+		tmport -= 0x08;
+		j = inb(tmport);
+		if (j != 0x16) {
+			if (j == 0x4e) {
+				goto u3p_out;
+			}
+			continue;
+		}
+		if (mbuf[0] != 0x01) {
+			goto chg_wide;
+		}
+		if (mbuf[1] != 0x06) {
+			goto chg_wide;
+		}
+		if (mbuf[2] != 0x04) {
+			goto chg_wide;
+		}
+		if (mbuf[3] == 0x09) {
+		   m = 1;
+		   m = m << i;
+		   dev->wide_idu |= m;
+		   dev->id[i].devspu = 0xce;
+		   continue;
+		}
+chg_wide:
+		tmport = wkport + 0x5b;
+		outb(0x01, tmport);
+		tmport = wkport + 0x43;
+		outb(satn[0], tmport++);
+		outb(satn[1], tmport++);
+		outb(satn[2], tmport++);
+		outb(satn[3], tmport++);
+		outb(satn[4], tmport++);
+		outb(satn[5], tmport++);
+		tmport += 0x06;
+		outb(0, tmport);
+		tmport += 0x02;
+		outb(dev->id[i].devspu, tmport++);
+		outb(0, tmport++);
+		outb(satn[6], tmport++);
+		outb(satn[7], tmport++);
+		tmport += 0x03;
+		outb(satn[8], tmport);
+		tmport += 0x07;
+
+		while ((inb(tmport) & 0x80) == 0x00);
+		tmport -= 0x08;
+		if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
+			continue;
+		}
+		while (inb(tmport) != 0x8e);
+try_wide:
+		j = 0;
+		tmport = wkport + 0x54;
+		outb(0x05, tmport);
+		tmport += 0x04;
+		outb(0x20, tmport);
+		tmport += 0x07;
+
+		while ((inb(tmport) & 0x80) == 0) {
+			if ((inb(tmport) & 0x01) != 0) {
+				tmport -= 0x06;
+				outb(wide[j++], tmport);
+				tmport += 0x06;
+			}
+		}
+		tmport -= 0x08;
+		while ((inb(tmport) & 0x80) == 0x00);
+		j = inb(tmport) & 0x0f;
+		if (j == 0x0f) {
+			goto widep_in;
+		}
+		if (j == 0x0a) {
+			goto widep_cmd;
+		}
+		if (j == 0x0e) {
+			goto try_wide;
+		}
+		continue;
+widep_out:
+		tmport = wkport + 0x58;
+		outb(0x20, tmport);
+		tmport += 0x07;
+		while ((inb(tmport) & 0x80) == 0) {
+			if ((inb(tmport) & 0x01) != 0) {
+				tmport -= 0x06;
+				outb(0, tmport);
+				tmport += 0x06;
+			}
+		}
+		tmport -= 0x08;
+		j = inb(tmport) & 0x0f;
+		if (j == 0x0f) {
+			goto widep_in;
+		}
+		if (j == 0x0a) {
+			goto widep_cmd;
+		}
+		if (j == 0x0e) {
+			goto widep_out;
+		}
+		continue;
+widep_in:
+		tmport = wkport + 0x54;
+		outb(0xff, tmport);
+		tmport += 0x04;
+		outb(0x20, tmport);
+		tmport += 0x07;
+		k = 0;
+widep_in1:
+		j = inb(tmport);
+		if ((j & 0x01) != 0) {
+			tmport -= 0x06;
+			mbuf[k++] = inb(tmport);
+			tmport += 0x06;
+			goto widep_in1;
+		}
+		if ((j & 0x80) == 0x00) {
+			goto widep_in1;
+		}
+		tmport -= 0x08;
+		j = inb(tmport) & 0x0f;
+		if (j == 0x0f) {
+			goto widep_in;
+		}
+		if (j == 0x0a) {
+			goto widep_cmd;
+		}
+		if (j == 0x0e) {
+			goto widep_out;
+		}
+		continue;
+widep_cmd:
+		tmport = wkport + 0x50;
+		outb(0x30, tmport);
+		tmport = wkport + 0x54;
+		outb(0x00, tmport);
+		tmport += 0x04;
+		outb(0x08, tmport);
+		tmport += 0x07;
+		while ((inb(tmport) & 0x80) == 0x00);
+		tmport -= 0x08;
+		j = inb(tmport);
+		if (j != 0x16) {
+			if (j == 0x4e) {
+				goto widep_out;
+			}
+			continue;
+		}
+		if (mbuf[0] != 0x01) {
+			goto not_wide;
+		}
+		if (mbuf[1] != 0x02) {
+			goto not_wide;
+		}
+		if (mbuf[2] != 0x03) {
+			goto not_wide;
+		}
+		if (mbuf[3] != 0x01) {
+			goto not_wide;
+		}
+		m = 1;
+		m = m << i;
+		dev->wide_idu |= m;
+not_wide:
+		if ((dev->id[i].devtypeu == 0x00) || (dev->id[i].devtypeu == 0x07) ||
+		    ((dev->id[i].devtypeu == 0x05) && ((n & 0x10) != 0)))
+		{
+			goto set_sync;
+		}
+		continue;
+set_sync:
+		tmport = wkport + 0x5b;
+		j = 0;
+		if ((m & dev->wide_idu) != 0) {
+			j |= 0x01;
+		}
+		outb(j, tmport);
+		tmport = wkport + 0x43;
+		outb(satn[0], tmport++);
+		outb(satn[1], tmport++);
+		outb(satn[2], tmport++);
+		outb(satn[3], tmport++);
+		outb(satn[4], tmport++);
+		outb(satn[5], tmport++);
+		tmport += 0x06;
+		outb(0, tmport);
+		tmport += 0x02;
+		outb(dev->id[i].devspu, tmport++);
+		outb(0, tmport++);
+		outb(satn[6], tmport++);
+		outb(satn[7], tmport++);
+		tmport += 0x03;
+		outb(satn[8], tmport);
+		tmport += 0x07;
+
+		while ((inb(tmport) & 0x80) == 0x00);
+		tmport -= 0x08;
+		if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
+			continue;
+		}
+		while (inb(tmport) != 0x8e);
+try_sync:
+		j = 0;
+		tmport = wkport + 0x54;
+		outb(0x06, tmport);
+		tmport += 0x04;
+		outb(0x20, tmport);
+		tmport += 0x07;
+
+		while ((inb(tmport) & 0x80) == 0) {
+			if ((inb(tmport) & 0x01) != 0) {
+				tmport -= 0x06;
+				if ((m & dev->wide_idu) != 0) {
+					outb(synw[j++], tmport);
+				} else {
+					if ((m & dev->ultra_map) != 0) {
+						outb(synu[j++], tmport);
+					} else {
+						outb(synn[j++], tmport);
+					}
+				}
+				tmport += 0x06;
+			}
+		}
+		tmport -= 0x08;
+		while ((inb(tmport) & 0x80) == 0x00);
+		j = inb(tmport) & 0x0f;
+		if (j == 0x0f) {
+			goto phase_ins;
+		}
+		if (j == 0x0a) {
+			goto phase_cmds;
+		}
+		if (j == 0x0e) {
+			goto try_sync;
+		}
+		continue;
+phase_outs:
+		tmport = wkport + 0x58;
+		outb(0x20, tmport);
+		tmport += 0x07;
+		while ((inb(tmport) & 0x80) == 0x00) {
+			if ((inb(tmport) & 0x01) != 0x00) {
+				tmport -= 0x06;
+				outb(0x00, tmport);
+				tmport += 0x06;
+			}
+		}
+		tmport -= 0x08;
+		j = inb(tmport);
+		if (j == 0x85) {
+			goto tar_dcons;
+		}
+		j &= 0x0f;
+		if (j == 0x0f) {
+			goto phase_ins;
+		}
+		if (j == 0x0a) {
+			goto phase_cmds;
+		}
+		if (j == 0x0e) {
+			goto phase_outs;
+		}
+		continue;
+phase_ins:
+		tmport = wkport + 0x54;
+		outb(0x06, tmport);
+		tmport += 0x04;
+		outb(0x20, tmport);
+		tmport += 0x07;
+		k = 0;
+phase_ins1:
+		j = inb(tmport);
+		if ((j & 0x01) != 0x00) {
+			tmport -= 0x06;
+			mbuf[k++] = inb(tmport);
+			tmport += 0x06;
+			goto phase_ins1;
+		}
+		if ((j & 0x80) == 0x00) {
+			goto phase_ins1;
+		}
+		tmport -= 0x08;
+		while ((inb(tmport) & 0x80) == 0x00);
+		j = inb(tmport);
+		if (j == 0x85) {
+			goto tar_dcons;
+		}
+		j &= 0x0f;
+		if (j == 0x0f) {
+			goto phase_ins;
+		}
+		if (j == 0x0a) {
+			goto phase_cmds;
+		}
+		if (j == 0x0e) {
+			goto phase_outs;
+		}
+		continue;
+phase_cmds:
+		tmport = wkport + 0x50;
+		outb(0x30, tmport);
+tar_dcons:
+		tmport = wkport + 0x54;
+		outb(0x00, tmport);
+		tmport += 0x04;
+		outb(0x08, tmport);
+		tmport += 0x07;
+		while ((inb(tmport) & 0x80) == 0x00);
+		tmport -= 0x08;
+		j = inb(tmport);
+		if (j != 0x16) {
+			continue;
+		}
+		if (mbuf[0] != 0x01) {
+			continue;
+		}
+		if (mbuf[1] != 0x03) {
+			continue;
+		}
+		if (mbuf[4] == 0x00) {
+			continue;
+		}
+		if (mbuf[3] > 0x64) {
+			continue;
+		}
+		if (mbuf[4] > 0x0e) {
+			mbuf[4] = 0x0e;
+		}
+		dev->id[i].devspu = mbuf[4];
+		if (mbuf[3] < 0x0c){
+			j = 0xb0;
+			goto set_syn_ok;
+		}
+		if ((mbuf[3] < 0x0d) && (rmb == 0)) {
+			j = 0xa0;
+			goto set_syn_ok;
+		}
+		if (mbuf[3] < 0x1a) {
+			j = 0x20;
+			goto set_syn_ok;
+		}
+		if (mbuf[3] < 0x33) {
+			j = 0x40;
+			goto set_syn_ok;
+		}
+		if (mbuf[3] < 0x4c) {
+			j = 0x50;
+			goto set_syn_ok;
+		}
+		j = 0x60;
+	      set_syn_ok:
+		dev->id[i].devspu = (dev->id[i].devspu & 0x0f) | j;
+	}
+}
+
+/* return non-zero on detection */
+int atp870u_detect(Scsi_Host_Template * tpnt)
+{
+	unsigned char irq, h, k;
+	unsigned long flags;
+	unsigned int base_io, error, tmport;
+	unsigned short index = 0;
+	struct pci_dev *pdev[3];
+	unsigned char chip_ver[3], host_id;
+	unsigned short dev_id[3];
+	struct Scsi_Host *shpnt = NULL;
+	int tmpcnt = 0;
+	int count = 0;
+
+	static unsigned short devid[9] = {
+	  0x8081, 0x8002, 0x8010, 0x8020, 0x8030, 0x8040, 0x8050, 0x8060, 0
+	};
+
+	printk(KERN_INFO "aec671x_detect: \n");
+	if (!pci_present()) {
+		printk(KERN_INFO"   NO PCI SUPPORT.\n");
+		return count;
+	}
+	tpnt->proc_name = "atp870u";
+
+	for (h = 0; h < 2; h++) {
+		struct atp_unit *dev = &atp_unit[h];
+		for(k=0;k<16;k++)
+		{
+			dev->id[k].prd_tableu = kmalloc(1024, GFP_KERNEL);
+			dev->id[k].devspu=0x20;
+			dev->id[k].devtypeu = 0;
+			dev->id[k].curr_req = NULL;
+		}
+		dev->active_idu = 0;
+		dev->wide_idu = 0;
+		dev->host_idu = 0x07;
+		dev->quhdu = 0;
+		dev->quendu = 0;
+		pdev[h]=NULL;
+		pdev[2]=NULL;
+		dev->chip_veru = 0;
+		dev->last_cmd = 0xff;
+		dev->in_snd = 0;
+		dev->in_int = 0;
+		for (k = 0; k < qcnt; k++) {
+			dev->querequ[k] = 0;
+		}
+		for (k = 0; k < 16; k++) {
+			dev->id[k].curr_req = 0;
+		}
+	}
+	h = 0;
+	while (devid[h] != 0) {
+		pdev[2] = pci_find_device(0x1191, devid[h], pdev[2]);
+		if (pdev[2] == NULL || pci_enable_device(pdev[2])) {
+			h++;
+			index = 0;
+			continue;
+		}
+		chip_ver[2] = 0;
+		dev_id[2] = devid[h];
+
+		if (devid[h] == 0x8002) {
+			error = pci_read_config_byte(pdev[2], 0x08, &chip_ver[2]);
+			if (chip_ver[2] < 2) {
+				goto nxt_devfn;
+			}
+		}
+		if (devid[h] == 0x8010 || devid[h] == 0x8081 || devid[h] == 0x8050)
+		{
+			chip_ver[2] = 0x04;
+		}
+		pdev[tmpcnt] = pdev[2];
+		chip_ver[tmpcnt] = chip_ver[2];
+		dev_id[tmpcnt] = dev_id[2];
+		tmpcnt++;
+	      nxt_devfn:
+		index++;
+		if (index > 3) {
+			index = 0;
+			h++;
+		}
+		if(tmpcnt>1)
+			break;
+	}
+	for (h = 0; h < 2; h++) {
+		struct atp_unit *dev=&atp_unit[h];
+		if (pdev[h]==NULL) {
+			return count;
+		}
+
+		/* Found an atp870u/w. */
+		base_io = pci_resource_start(pdev[h], 0);
+		irq = pdev[h]->irq;
+
+		if (dev_id[h] != 0x8081)
+		{
+		   error = pci_read_config_byte(pdev[h],0x49,&host_id);
+
+		   base_io &= 0xfffffff8;
+
+		   if (check_region(base_io,0x40) != 0)
+		   {
+			   return 0;
+		   }
+		   printk(KERN_INFO "   ACARD AEC-671X PCI Ultra/W SCSI-3 Host Adapter: %d    IO:%x, IRQ:%d.\n"
+			  ,h, base_io, irq);
+		   dev->ioport = base_io;
+		   dev->pciport = base_io + 0x20;
+		   dev->deviceid = dev_id[h];
+		   irqnumu[h] = irq;
+		   host_id &= 0x07;
+		   dev->host_idu = host_id;
+		   dev->chip_veru = chip_ver[h];
+
+		   tmport = base_io + 0x22;
+		   dev->scam_on = inb(tmport);
+		   tmport += 0x0b;
+		   dev->global_map = inb(tmport++);
+		   dev->ultra_map = inw(tmport);
+		   if (dev->ultra_map == 0) {
+			   dev->scam_on = 0x00;
+			   dev->global_map = 0x20;
+			   dev->ultra_map = 0xffff;
+		   }
+		   shpnt = scsi_register(tpnt, 4);
+		   if(shpnt==NULL)
+			   return count;
+
+		   save_flags(flags);
+		   cli();
+		   if (request_irq(irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", dev)) {
+			   printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n");
+			   goto unregister;
+		   }
+
+		   if (chip_ver[h] > 0x07)	     /* check if atp876 chip   */
+		   {				     /* then enable terminator */
+		      tmport = base_io + 0x3e;
+		      outb(0x00, tmport);
+		   }
+
+		   tmport = base_io + 0x3a;
+		   k = (inb(tmport) & 0xf3) | 0x10;
+		   outb(k, tmport);
+		   outb((k & 0xdf), tmport);
+		   mydlyu(0x8000);
+		   outb(k, tmport);
+		   mydlyu(0x8000);
+		   tmport = base_io;
+		   outb((host_id | 0x08), tmport);
+		   tmport += 0x18;
+		   outb(0, tmport);
+		   tmport += 0x07;
+		   while ((inb(tmport) & 0x80) == 0);
+		   tmport -= 0x08;
+		   inb(tmport);
+		   tmport = base_io + 1;
+		   outb(8, tmport++);
+		   outb(0x7f, tmport);
+		   tmport = base_io + 0x11;
+		   outb(0x20, tmport);
+
+		   tscam(h);
+		   is870(h, base_io);
+		   tmport = base_io + 0x3a;
+		   outb((inb(tmport) & 0xef), tmport);
+		   tmport++;
+		   outb((inb(tmport) | 0x20),tmport);
+		}
+		else
+		{
+		   base_io &= 0xfffffff8;
+
+		   if (check_region(base_io,0x60) != 0)
+		   {
+			   return 0;
+		   }
+		   host_id = inb(base_io + 0x39);
+		   host_id >>= 0x04;
+
+		   printk(KERN_INFO "   ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d    IO:%x, IRQ:%d.\n"
+			  ,h, base_io, irq);
+		   dev->ioport = base_io + 0x40;
+		   dev->pciport = base_io + 0x28;
+		   dev->deviceid = dev_id[h];
+		   irqnumu[h] = irq;
+		   dev->host_idu = host_id;
+		   dev->chip_veru = chip_ver[h];
+
+		   tmport = base_io + 0x22;
+		   dev->scam_on = inb(tmport);
+		   tmport += 0x13;
+		   dev->global_map = inb(tmport);
+		   tmport += 0x07;
+		   dev->ultra_map = inw(tmport);
+		   if (dev->ultra_map == 0) {
+			   dev->scam_on = 0x00;
+			   dev->global_map = 0x20;
+			   dev->ultra_map = 0xffff;
+		   }
+		   shpnt = scsi_register(tpnt, 4);
+		   if(shpnt==NULL)
+			   return count;
+
+		   save_flags(flags);
+		   cli();
+		   if (request_irq(irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", dev)) {
+			   printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n");
+			   goto unregister;
+		   }
+
+		   tmport = base_io + 0x38;
+		   k = inb(tmport) & 0x80;
+		   outb(k, tmport);
+		   tmport += 0x03;
+		   outb(0x20, tmport);
+		   mydlyu(0x8000);
+		   outb(0, tmport);
+		   mydlyu(0x8000);
+		   tmport = base_io + 0x5b;
+		   inb(tmport);
+		   tmport -= 0x04;
+		   inb(tmport);
+		   tmport = base_io + 0x40;
+		   outb((host_id | 0x08), tmport);
+		   tmport += 0x18;
+		   outb(0, tmport);
+		   tmport += 0x07;
+		   while ((inb(tmport) & 0x80) == 0);
+		   tmport -= 0x08;
+		   inb(tmport);
+		   tmport = base_io + 0x41;
+		   outb(8, tmport++);
+		   outb(0x7f, tmport);
+		   tmport = base_io + 0x51;
+		   outb(0x20, tmport);
+
+		   is880(h, base_io);
+		   tmport = base_io + 0x38;
+		   outb(0xb0, tmport);
+		}
+
+		atp_host[h] = shpnt;
+		if (dev->chip_veru == 4) {
+			shpnt->max_id = 16;
+		}
+		shpnt->this_id = host_id;
+		shpnt->unique_id = base_io;
+		shpnt->io_port = base_io;
+		if (dev_id[h] == 0x8081)
+		{
+		   shpnt->n_io_port = 0x60;	   /* Number of bytes of I/O space used */
+		}
+		else
+		{
+		   shpnt->n_io_port = 0x40;	   /* Number of bytes of I/O space used */
+		}
+		shpnt->irq = irq;
+		restore_flags(flags);
+		if (dev_id[h] == 0x8081)
+		{
+		   request_region(base_io, 0x60, "atp870u");       /* Register the IO ports that we use */
+		}
+		else
+		{
+		   request_region(base_io, 0x40, "atp870u");       /* Register the IO ports that we use */
+		}
+		count++;
 		index++;
 		continue;
 unregister:
@@ -1809,7 +2606,8 @@
 
 int atp870u_abort(Scsi_Cmnd * SCpnt)
 {
-	unsigned char h, j;
+	unsigned char h, j, k;
+	Scsi_Cmnd *workrequ;
 	unsigned int tmport;
 	struct atp_unit *dev;
 	for (h = 0; h <= admaxu; h++) {
@@ -1830,18 +2628,34 @@
 	printk(" r1c=%2x", inb(tmport));
 	tmport += 0x03;
 	printk(" r1f=%2x in_snd=%2x ", inb(tmport), dev->in_snd);
-	tmport++;
+	tmport= dev->pciport;
 	printk(" r20=%2x", inb(tmport));
 	tmport += 0x02;
 	printk(" r22=%2x", inb(tmport));
-	tmport += 0x18;
+	tmport = dev->ioport + 0x3a;
 	printk(" r3a=%2x \n",inb(tmport));
+	tmport = dev->ioport + 0x3b;
+	printk(" r3b=%2x \n",inb(tmport));
+	for(j=0;j<16;j++)
+	{
+	   if (dev->id[j].curr_req != NULL)
+	   {
+		workrequ = dev->id[j].curr_req;
+		printk("\n que cdb= ");
+		for (k=0; k < workrequ->cmd_len; k++)
+		{
+		    printk(" %2x ",workrequ->cmnd[k]);
+		}
+		printk(" last_lenu= %x ",dev->id[j].last_lenu);
+	   }
+	}
 	return (SCSI_ABORT_SNOOZE);
 }
 
 int atp870u_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
 {
 	unsigned char h;
+	struct atp_unit *dev;
 	/*
 	 * See if a bus reset was suggested.
 	 */
@@ -1852,6 +2666,7 @@
 	}
 	panic("Reset bus host not found !");
 find_host:
+	dev=&atp_unit[h];
 /*	SCpnt->result = 0x00080000;
 	SCpnt->scsi_done(SCpnt);
 	dev->working=0;
@@ -1865,7 +2680,7 @@
 {
 	static char buffer[128];
 
-	strcpy(buffer, "ACARD AEC-6710/6712 PCI Ultra/W SCSI-3 Adapter Driver V2.1+ac ");
+	strcpy(buffer, "ACARD AEC-6710/6712/67160 PCI Ultra/W/LVD SCSI-3 Adapter Driver V2.4+ac ");
 
 	return buffer;
 }
@@ -1910,7 +2725,7 @@
 	if (offset == 0) {
 		memset(buff, 0, sizeof(buff));
 	}
-	size += sprintf(BLS, "ACARD AEC-671X Driver Version: 2.1+ac\n");
+	size += sprintf(BLS, "ACARD AEC-671X Driver Version: 2.4+ac\n");
 	len += size;
 	pos = begin + len;
 	size = 0;
@@ -1976,3 +2791,4 @@
 
 static Scsi_Host_Template driver_template = ATP870U;
 #include "scsi_module.c"
+

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)