brintos

brintos / linux-shallow public Read only

0
0
Text · 58.9 KiB · 928151e Raw
2383 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* 3 *  Copyright (C) 1997	Wu Ching Chen4 *  2.1.x update (C) 1998  Krzysztof G. Baranowski5 *  2.5.x update (C) 2002  Red Hat6 *  2.6.x update (C) 2004  Red Hat7 *8 * Marcelo Tosatti <marcelo@conectiva.com.br> : SMP fixes9 *10 * Wu Ching Chen : NULL pointer fixes  2000/06/0211 *		   support atp876 chip12 *		   enable 32 bit fifo transfer13 *		   support cdrom & remove device run ultra speed14 *		   fix disconnect bug  2000/12/2115 *		   support atp880 chip lvd u160 2001/05/1516 *		   fix prd table bug 2001/09/12 (7.1)17 *18 * atp885 support add by ACARD Hao Ping Lian 2005/01/0519 */20#include <linux/module.h>21#include <linux/init.h>22#include <linux/interrupt.h>23#include <linux/kernel.h>24#include <linux/types.h>25#include <linux/string.h>26#include <linux/ioport.h>27#include <linux/delay.h>28#include <linux/proc_fs.h>29#include <linux/spinlock.h>30#include <linux/pci.h>31#include <linux/blkdev.h>32#include <linux/dma-mapping.h>33#include <linux/slab.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 const struct scsi_host_template atp870u_template;44static void send_s870(struct atp_unit *dev,unsigned char c);45static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip,46		   unsigned char lvdmode);47 48static inline void atp_writeb_base(struct atp_unit *atp, u8 reg, u8 val)49{50	outb(val, atp->baseport + reg);51}52 53static inline void atp_writew_base(struct atp_unit *atp, u8 reg, u16 val)54{55	outw(val, atp->baseport + reg);56}57 58static inline void atp_writeb_io(struct atp_unit *atp, u8 channel, u8 reg, u8 val)59{60	outb(val, atp->ioport[channel] + reg);61}62 63static inline void atp_writew_io(struct atp_unit *atp, u8 channel, u8 reg, u16 val)64{65	outw(val, atp->ioport[channel] + reg);66}67 68static inline void atp_writeb_pci(struct atp_unit *atp, u8 channel, u8 reg, u8 val)69{70	outb(val, atp->pciport[channel] + reg);71}72 73static inline void atp_writel_pci(struct atp_unit *atp, u8 channel, u8 reg, u32 val)74{75	outl(val, atp->pciport[channel] + reg);76}77 78static inline u8 atp_readb_base(struct atp_unit *atp, u8 reg)79{80	return inb(atp->baseport + reg);81}82 83static inline u16 atp_readw_base(struct atp_unit *atp, u8 reg)84{85	return inw(atp->baseport + reg);86}87 88static inline u32 atp_readl_base(struct atp_unit *atp, u8 reg)89{90	return inl(atp->baseport + reg);91}92 93static inline u8 atp_readb_io(struct atp_unit *atp, u8 channel, u8 reg)94{95	return inb(atp->ioport[channel] + reg);96}97 98static inline u16 atp_readw_io(struct atp_unit *atp, u8 channel, u8 reg)99{100	return inw(atp->ioport[channel] + reg);101}102 103static inline u8 atp_readb_pci(struct atp_unit *atp, u8 channel, u8 reg)104{105	return inb(atp->pciport[channel] + reg);106}107 108static inline bool is880(struct atp_unit *atp)109{110	return atp->pdev->device == ATP880_DEVID1 ||111	       atp->pdev->device == ATP880_DEVID2;112}113 114static inline bool is885(struct atp_unit *atp)115{116	return atp->pdev->device == ATP885_DEVID;117}118 119static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)120{121	unsigned long flags;122	unsigned short int id;123	unsigned char i, j, c, target_id, lun,cmdp;124	unsigned char *prd;125	struct scsi_cmnd *workreq;126	unsigned long adrcnt, k;127#ifdef ED_DBGP128	unsigned long l;129#endif130	struct Scsi_Host *host = dev_id;131	struct atp_unit *dev = (struct atp_unit *)&host->hostdata;132 133	for (c = 0; c < 2; c++) {134		j = atp_readb_io(dev, c, 0x1f);135		if ((j & 0x80) != 0)136			break;137		dev->in_int[c] = 0;138	}139	if ((j & 0x80) == 0)140		return IRQ_NONE;141#ifdef ED_DBGP142	printk("atp870u_intr_handle enter\n");143#endif144	dev->in_int[c] = 1;145	cmdp = atp_readb_io(dev, c, 0x10);146	if (dev->working[c] != 0) {147		if (is885(dev)) {148			if ((atp_readb_io(dev, c, 0x16) & 0x80) == 0)149				atp_writeb_io(dev, c, 0x16,150					      (atp_readb_io(dev, c, 0x16) | 0x80));151		}152		if ((atp_readb_pci(dev, c, 0x00) & 0x08) != 0)153		{154			for (k=0; k < 1000; k++) {155				if ((atp_readb_pci(dev, c, 2) & 0x08) == 0)156					break;157				if ((atp_readb_pci(dev, c, 2) & 0x01) == 0)158					break;159			}160		}161		atp_writeb_pci(dev, c, 0, 0x00);162 163		i = atp_readb_io(dev, c, 0x17);164 165		if (is885(dev))166			atp_writeb_pci(dev, c, 2, 0x06);167 168		target_id = atp_readb_io(dev, c, 0x15);169 170		/*171		 *	Remap wide devices onto id numbers172		 */173 174		if ((target_id & 0x40) != 0) {175			target_id = (target_id & 0x07) | 0x08;176		} else {177			target_id &= 0x07;178		}179 180		if ((j & 0x40) != 0) {181		     if (dev->last_cmd[c] == 0xff) {182			dev->last_cmd[c] = target_id;183		     }184		     dev->last_cmd[c] |= 0x40;185		}186		if (is885(dev))187			dev->r1f[c][target_id] |= j;188#ifdef ED_DBGP189		printk("atp870u_intr_handle status = %x\n",i);190#endif191		if (i == 0x85) {192			if ((dev->last_cmd[c] & 0xf0) != 0x40) {193			   dev->last_cmd[c] = 0xff;194			}195			if (is885(dev)) {196				adrcnt = 0;197				((unsigned char *) &adrcnt)[2] =198					atp_readb_io(dev, c, 0x12);199				((unsigned char *) &adrcnt)[1] =200					atp_readb_io(dev, c, 0x13);201				((unsigned char *) &adrcnt)[0] =202					atp_readb_io(dev, c, 0x14);203				if (dev->id[c][target_id].last_len != adrcnt) {204					k = dev->id[c][target_id].last_len;205					k -= adrcnt;206					dev->id[c][target_id].tran_len = k;207					dev->id[c][target_id].last_len = adrcnt;208				}209#ifdef ED_DBGP210				printk("dev->id[c][target_id].last_len = %d "211				       "dev->id[c][target_id].tran_len = %d\n",212				       dev->id[c][target_id].last_len,213				       dev->id[c][target_id].tran_len);214#endif215			}216 217			/*218			 *      Flip wide219			 */220			if (dev->wide_id[c] != 0) {221				atp_writeb_io(dev, c, 0x1b, 0x01);222				while ((atp_readb_io(dev, c, 0x1b) & 0x01) != 0x01)223					atp_writeb_io(dev, c, 0x1b, 0x01);224			}225			/*226			 *	Issue more commands227			 */228			spin_lock_irqsave(dev->host->host_lock, flags);229			if (((dev->quhd[c] != dev->quend[c]) ||230			     (dev->last_cmd[c] != 0xff)) &&231			    (dev->in_snd[c] == 0)) {232#ifdef ED_DBGP233				printk("Call sent_s870\n");234#endif235				send_s870(dev,c);236			}237			spin_unlock_irqrestore(dev->host->host_lock, flags);238			/*239			 *	Done240			 */241			dev->in_int[c] = 0;242#ifdef ED_DBGP243				printk("Status 0x85 return\n");244#endif245			return IRQ_HANDLED;246		}247 248		if (i == 0x40) {249		     dev->last_cmd[c] |= 0x40;250		     dev->in_int[c] = 0;251		     return IRQ_HANDLED;252		}253 254		if (i == 0x21) {255			if ((dev->last_cmd[c] & 0xf0) != 0x40) {256			   dev->last_cmd[c] = 0xff;257			}258			adrcnt = 0;259			((unsigned char *) &adrcnt)[2] =260				atp_readb_io(dev, c, 0x12);261			((unsigned char *) &adrcnt)[1] =262				atp_readb_io(dev, c, 0x13);263			((unsigned char *) &adrcnt)[0] =264				atp_readb_io(dev, c, 0x14);265			k = dev->id[c][target_id].last_len;266			k -= adrcnt;267			dev->id[c][target_id].tran_len = k;268			dev->id[c][target_id].last_len = adrcnt;269			atp_writeb_io(dev, c, 0x10, 0x41);270			atp_writeb_io(dev, c, 0x18, 0x08);271			dev->in_int[c] = 0;272			return IRQ_HANDLED;273		}274 275		if (is885(dev)) {276			if ((i == 0x4c) || (i == 0x4d) || (i == 0x8c) || (i == 0x8d)) {277				if ((i == 0x4c) || (i == 0x8c))278					i=0x48;279				else280					i=0x49;281			}282		}283		if ((i == 0x80) || (i == 0x8f)) {284#ifdef ED_DBGP285			printk(KERN_DEBUG "Device reselect\n");286#endif287			lun = 0;288			if (cmdp == 0x44 || i == 0x80)289				lun = atp_readb_io(dev, c, 0x1d) & 0x07;290			else {291				if ((dev->last_cmd[c] & 0xf0) != 0x40) {292				   dev->last_cmd[c] = 0xff;293				}294				if (cmdp == 0x41) {295#ifdef ED_DBGP296					printk("cmdp = 0x41\n");297#endif298					adrcnt = 0;299					((unsigned char *) &adrcnt)[2] =300						atp_readb_io(dev, c, 0x12);301					((unsigned char *) &adrcnt)[1] =302						atp_readb_io(dev, c, 0x13);303					((unsigned char *) &adrcnt)[0] =304						atp_readb_io(dev, c, 0x14);305					k = dev->id[c][target_id].last_len;306					k -= adrcnt;307					dev->id[c][target_id].tran_len = k;308					dev->id[c][target_id].last_len = adrcnt;309					atp_writeb_io(dev, c, 0x18, 0x08);310					dev->in_int[c] = 0;311					return IRQ_HANDLED;312				} else {313#ifdef ED_DBGP314					printk("cmdp != 0x41\n");315#endif316					atp_writeb_io(dev, c, 0x10, 0x46);317					dev->id[c][target_id].dirct = 0x00;318					atp_writeb_io(dev, c, 0x12, 0x00);319					atp_writeb_io(dev, c, 0x13, 0x00);320					atp_writeb_io(dev, c, 0x14, 0x00);321					atp_writeb_io(dev, c, 0x18, 0x08);322					dev->in_int[c] = 0;323					return IRQ_HANDLED;324				}325			}326			if (dev->last_cmd[c] != 0xff) {327			   dev->last_cmd[c] |= 0x40;328			}329			if (is885(dev)) {330				j = atp_readb_base(dev, 0x29) & 0xfe;331				atp_writeb_base(dev, 0x29, j);332			} else333				atp_writeb_io(dev, c, 0x10, 0x45);334 335			target_id = atp_readb_io(dev, c, 0x16);336			/*337			 *	Remap wide identifiers338			 */339			if ((target_id & 0x10) != 0) {340				target_id = (target_id & 0x07) | 0x08;341			} else {342				target_id &= 0x07;343			}344			if (is885(dev))345				atp_writeb_io(dev, c, 0x10, 0x45);346			workreq = dev->id[c][target_id].curr_req;347#ifdef ED_DBGP348			scmd_printk(KERN_DEBUG, workreq, "CDB");349			for (l = 0; l < workreq->cmd_len; l++)350				printk(KERN_DEBUG " %x",workreq->cmnd[l]);351			printk("\n");352#endif353 354			atp_writeb_io(dev, c, 0x0f, lun);355			atp_writeb_io(dev, c, 0x11, dev->id[c][target_id].devsp);356			adrcnt = dev->id[c][target_id].tran_len;357			k = dev->id[c][target_id].last_len;358 359			atp_writeb_io(dev, c, 0x12, ((unsigned char *) &k)[2]);360			atp_writeb_io(dev, c, 0x13, ((unsigned char *) &k)[1]);361			atp_writeb_io(dev, c, 0x14, ((unsigned char *) &k)[0]);362#ifdef ED_DBGP363			printk("k %x, k[0] 0x%x k[1] 0x%x k[2] 0x%x\n", k,364			       atp_readb_io(dev, c, 0x14),365			       atp_readb_io(dev, c, 0x13),366			       atp_readb_io(dev, c, 0x12));367#endif368			/* Remap wide */369			j = target_id;370			if (target_id > 7) {371				j = (j & 0x07) | 0x40;372			}373			/* Add direction */374			j |= dev->id[c][target_id].dirct;375			atp_writeb_io(dev, c, 0x15, j);376			atp_writeb_io(dev, c, 0x16, 0x80);377 378			/* enable 32 bit fifo transfer */379			if (is885(dev)) {380				i = atp_readb_pci(dev, c, 1) & 0xf3;381				//j=workreq->cmnd[0];382				if ((workreq->cmnd[0] == READ_6) ||383				    (workreq->cmnd[0] == READ_10) ||384				    (workreq->cmnd[0] == WRITE_6) ||385				    (workreq->cmnd[0] == WRITE_10)) {386				   i |= 0x0c;387				}388				atp_writeb_pci(dev, c, 1, i);389			} else if (is880(dev)) {390				if ((workreq->cmnd[0] == READ_6) ||391				    (workreq->cmnd[0] == READ_10) ||392				    (workreq->cmnd[0] == WRITE_6) ||393				    (workreq->cmnd[0] == WRITE_10))394					atp_writeb_base(dev, 0x3b,395							(atp_readb_base(dev, 0x3b) & 0x3f) | 0xc0);396				else397					atp_writeb_base(dev, 0x3b,398							atp_readb_base(dev, 0x3b) & 0x3f);399			} else {400				if ((workreq->cmnd[0] == READ_6) ||401				    (workreq->cmnd[0] == READ_10) ||402				    (workreq->cmnd[0] == WRITE_6) ||403				    (workreq->cmnd[0] == WRITE_10))404					atp_writeb_base(dev, 0x3a,405							(atp_readb_base(dev, 0x3a) & 0xf3) | 0x08);406				else407					atp_writeb_base(dev, 0x3a,408							atp_readb_base(dev, 0x3a) & 0xf3);409			}410			j = 0;411			id = 1;412			id = id << target_id;413			/*414			 *	Is this a wide device415			 */416			if ((id & dev->wide_id[c]) != 0) {417				j |= 0x01;418			}419			atp_writeb_io(dev, c, 0x1b, j);420			while ((atp_readb_io(dev, c, 0x1b) & 0x01) != j)421				atp_writeb_io(dev, c, 0x1b, j);422			if (dev->id[c][target_id].last_len == 0) {423				atp_writeb_io(dev, c, 0x18, 0x08);424				dev->in_int[c] = 0;425#ifdef ED_DBGP426				printk("dev->id[c][target_id].last_len = 0\n");427#endif428				return IRQ_HANDLED;429			}430#ifdef ED_DBGP431			printk("target_id = %d adrcnt = %d\n",target_id,adrcnt);432#endif433			prd = dev->id[c][target_id].prd_pos;434			while (adrcnt != 0) {435				id = ((unsigned short int *)prd)[2];436				if (id == 0) {437					k = 0x10000;438				} else {439					k = id;440				}441				if (k > adrcnt) {442					((unsigned short int *)prd)[2] =443						(unsigned short int)(k - adrcnt);444					((unsigned long *)prd)[0] += adrcnt;445					adrcnt = 0;446					dev->id[c][target_id].prd_pos = prd;447				} else {448					adrcnt -= k;449					dev->id[c][target_id].prdaddr += 0x08;450					prd += 0x08;451					if (adrcnt == 0) {452						dev->id[c][target_id].prd_pos = prd;453					}454				}455			}456			atp_writel_pci(dev, c, 0x04, dev->id[c][target_id].prdaddr);457#ifdef ED_DBGP458			printk("dev->id[%d][%d].prdaddr 0x%8x\n",459			       c, target_id, dev->id[c][target_id].prdaddr);460#endif461			if (!is885(dev)) {462				atp_writeb_pci(dev, c, 2, 0x06);463				atp_writeb_pci(dev, c, 2, 0x00);464			}465			/*466			 *	Check transfer direction467			 */468			if (dev->id[c][target_id].dirct != 0) {469				atp_writeb_io(dev, c, 0x18, 0x08);470				atp_writeb_pci(dev, c, 0, 0x01);471				dev->in_int[c] = 0;472#ifdef ED_DBGP473				printk("status 0x80 return dirct != 0\n");474#endif475				return IRQ_HANDLED;476			}477			atp_writeb_io(dev, c, 0x18, 0x08);478			atp_writeb_pci(dev, c, 0, 0x09);479			dev->in_int[c] = 0;480#ifdef ED_DBGP481			printk("status 0x80 return dirct = 0\n");482#endif483			return IRQ_HANDLED;484		}485 486		/*487		 *	Current scsi request on this target488		 */489 490		workreq = dev->id[c][target_id].curr_req;491 492		if (i == 0x42 || i == 0x16) {493			if ((dev->last_cmd[c] & 0xf0) != 0x40) {494			   dev->last_cmd[c] = 0xff;495			}496			if (i == 0x16) {497				workreq->result = atp_readb_io(dev, c, 0x0f);498				if (((dev->r1f[c][target_id] & 0x10) != 0) && is885(dev)) {499					printk(KERN_WARNING "AEC67162 CRC ERROR !\n");500					workreq->result = SAM_STAT_CHECK_CONDITION;501				}502			} else503				workreq->result = SAM_STAT_CHECK_CONDITION;504 505			if (is885(dev)) {506				j = atp_readb_base(dev, 0x29) | 0x01;507				atp_writeb_base(dev, 0x29, j);508			}509			/*510			 *	Complete the command511			 */512			scsi_dma_unmap(workreq);513 514			spin_lock_irqsave(dev->host->host_lock, flags);515			scsi_done(workreq);516#ifdef ED_DBGP517			   printk("workreq->scsi_done\n");518#endif519			/*520			 *	Clear it off the queue521			 */522			dev->id[c][target_id].curr_req = NULL;523			dev->working[c]--;524			spin_unlock_irqrestore(dev->host->host_lock, flags);525			/*526			 *      Take it back wide527			 */528			if (dev->wide_id[c] != 0) {529				atp_writeb_io(dev, c, 0x1b, 0x01);530				while ((atp_readb_io(dev, c, 0x1b) & 0x01) != 0x01)531					atp_writeb_io(dev, c, 0x1b, 0x01);532			}533			/*534			 *	If there is stuff to send and nothing going then send it535			 */536			spin_lock_irqsave(dev->host->host_lock, flags);537			if (((dev->last_cmd[c] != 0xff) ||538			     (dev->quhd[c] != dev->quend[c])) &&539			    (dev->in_snd[c] == 0)) {540#ifdef ED_DBGP541			   printk("Call sent_s870(scsi_done)\n");542#endif543			   send_s870(dev,c);544			}545			spin_unlock_irqrestore(dev->host->host_lock, flags);546			dev->in_int[c] = 0;547			return IRQ_HANDLED;548		}549		if ((dev->last_cmd[c] & 0xf0) != 0x40) {550		   dev->last_cmd[c] = 0xff;551		}552		if (i == 0x4f) {553			i = 0x89;554		}555		i &= 0x0f;556		if (i == 0x09) {557			atp_writel_pci(dev, c, 4, dev->id[c][target_id].prdaddr);558			atp_writeb_pci(dev, c, 2, 0x06);559			atp_writeb_pci(dev, c, 2, 0x00);560			atp_writeb_io(dev, c, 0x10, 0x41);561			if (is885(dev)) {562				k = dev->id[c][target_id].last_len;563				atp_writeb_io(dev, c, 0x12,564					      ((unsigned char *) (&k))[2]);565				atp_writeb_io(dev, c, 0x13,566					      ((unsigned char *) (&k))[1]);567				atp_writeb_io(dev, c, 0x14,568					      ((unsigned char *) (&k))[0]);569				dev->id[c][target_id].dirct = 0x00;570			} else {571				dev->id[c][target_id].dirct = 0x00;572			}573			atp_writeb_io(dev, c, 0x18, 0x08);574			atp_writeb_pci(dev, c, 0, 0x09);575			dev->in_int[c] = 0;576			return IRQ_HANDLED;577		}578		if (i == 0x08) {579			atp_writel_pci(dev, c, 4, dev->id[c][target_id].prdaddr);580			atp_writeb_pci(dev, c, 2, 0x06);581			atp_writeb_pci(dev, c, 2, 0x00);582			atp_writeb_io(dev, c, 0x10, 0x41);583			if (is885(dev)) {584				k = dev->id[c][target_id].last_len;585				atp_writeb_io(dev, c, 0x12,586					      ((unsigned char *) (&k))[2]);587				atp_writeb_io(dev, c, 0x13,588					      ((unsigned char *) (&k))[1]);589				atp_writeb_io(dev, c, 0x14,590					      ((unsigned char *) (&k))[0]);591			}592			atp_writeb_io(dev, c, 0x15,593				      atp_readb_io(dev, c, 0x15) | 0x20);594			dev->id[c][target_id].dirct = 0x20;595			atp_writeb_io(dev, c, 0x18, 0x08);596			atp_writeb_pci(dev, c, 0, 0x01);597			dev->in_int[c] = 0;598			return IRQ_HANDLED;599		}600		if (i == 0x0a)601			atp_writeb_io(dev, c, 0x10, 0x30);602		else603			atp_writeb_io(dev, c, 0x10, 0x46);604		dev->id[c][target_id].dirct = 0x00;605		atp_writeb_io(dev, c, 0x12, 0x00);606		atp_writeb_io(dev, c, 0x13, 0x00);607		atp_writeb_io(dev, c, 0x14, 0x00);608		atp_writeb_io(dev, c, 0x18, 0x08);609	}610	dev->in_int[c] = 0;611 612	return IRQ_HANDLED;613}614/**615 *	atp870u_queuecommand_lck -	Queue SCSI command616 *	@req_p: request block617 *618 *	Queue a command to the ATP queue. Called with the host lock held.619 */620static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p)621{622	void (*done)(struct scsi_cmnd *) = scsi_done;623	unsigned char c;624	unsigned int m;625	struct atp_unit *dev;626	struct Scsi_Host *host;627 628	c = scmd_channel(req_p);629	req_p->sense_buffer[0]=0;630	scsi_set_resid(req_p, 0);631	if (scmd_channel(req_p) > 1) {632		req_p->result = DID_BAD_TARGET << 16;633		done(req_p);634#ifdef ED_DBGP635		printk("atp870u_queuecommand : req_p->device->channel > 1\n");636#endif637		return 0;638	}639 640	host = req_p->device->host;641	dev = (struct atp_unit *)&host->hostdata;642 643	m = 1;644	m = m << scmd_id(req_p);645 646	/*647	 *      Fake a timeout for missing targets648	 */649 650	if ((m & dev->active_id[c]) == 0) {651		req_p->result = DID_BAD_TARGET << 16;652		done(req_p);653		return 0;654	}655 656	/*657	 *	Count new command658	 */659	dev->quend[c]++;660	if (dev->quend[c] >= qcnt) {661		dev->quend[c] = 0;662	}663 664	/*665	 *	Check queue state666	 */667	if (dev->quhd[c] == dev->quend[c]) {668		if (dev->quend[c] == 0) {669			dev->quend[c] = qcnt;670		}671#ifdef ED_DBGP672		printk("atp870u_queuecommand : dev->quhd[c] == dev->quend[c]\n");673#endif674		dev->quend[c]--;675		req_p->result = DID_BUS_BUSY << 16;676		done(req_p);677		return 0;678	}679	dev->quereq[c][dev->quend[c]] = req_p;680#ifdef ED_DBGP681	printk("dev->ioport[c] = %x atp_readb_io(dev, c, 0x1c) = %x "682	       "dev->in_int[%d] = %d dev->in_snd[%d] = %d\n",683	       dev->ioport[c], atp_readb_io(dev, c, 0x1c), c,684	       dev->in_int[c],c,dev->in_snd[c]);685#endif686	if ((atp_readb_io(dev, c, 0x1c) == 0) &&687	    (dev->in_int[c] == 0) &&688	    (dev->in_snd[c] == 0)) {689#ifdef ED_DBGP690		printk("Call sent_s870(atp870u_queuecommand)\n");691#endif692		send_s870(dev,c);693	}694#ifdef ED_DBGP695	printk("atp870u_queuecommand : exit\n");696#endif697	return 0;698}699 700static DEF_SCSI_QCMD(atp870u_queuecommand)701 702/*703 *	send_s870	-	send a command to the controller704 *705 *	On entry there is work queued to be done. We move some of that work to the706 *	controller itself.707 *708 *	Caller holds the host lock.709 */710static void send_s870(struct atp_unit *dev, unsigned char c)711{712	struct scsi_cmnd *workreq = NULL;713	unsigned int i;//,k;714	unsigned char  j, target_id;715	unsigned char *prd;716	unsigned short int w;717	unsigned long l, bttl = 0;718	unsigned long  sg_count;719 720	if (dev->in_snd[c] != 0) {721#ifdef ED_DBGP722		printk("cmnd in_snd\n");723#endif724		return;725	}726#ifdef ED_DBGP727	printk("Sent_s870 enter\n");728#endif729	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) {734			dev->last_cmd[c] = 0xff;735			if (dev->quhd[c] == dev->quend[c]) {736				dev->in_snd[c] = 0;737				return;738			}739		}740	}741	if (!workreq) {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		workreq = dev->quereq[c][dev->quhd[c]];752		if (dev->id[c][scmd_id(workreq)].curr_req != NULL) {753			dev->quhd[c] = j;754			dev->working[c]--;755			dev->in_snd[c] = 0;756			return;757		}758		dev->id[c][scmd_id(workreq)].curr_req = workreq;759		dev->last_cmd[c] = scmd_id(workreq);760	}761	if ((atp_readb_io(dev, c, 0x1f) & 0xb0) != 0 ||762	    atp_readb_io(dev, c, 0x1c) != 0) {763#ifdef ED_DBGP764		printk("Abort to Send\n");765#endif766		dev->last_cmd[c] |= 0x40;767		dev->in_snd[c] = 0;768		return;769	}770#ifdef ED_DBGP771	printk("OK to Send\n");772	scmd_printk(KERN_DEBUG, workreq, "CDB");773	for(i=0;i<workreq->cmd_len;i++) {774		printk(" %x",workreq->cmnd[i]);775	}776	printk("\n");777#endif778	l = scsi_bufflen(workreq);779 780	if (is885(dev)) {781		j = atp_readb_base(dev, 0x29) & 0xfe;782		atp_writeb_base(dev, 0x29, j);783		dev->r1f[c][scmd_id(workreq)] = 0;784	}785 786	if (workreq->cmnd[0] == READ_CAPACITY) {787		if (l > 8)788			l = 8;789	}790	if (workreq->cmnd[0] == TEST_UNIT_READY) {791		l = 0;792	}793 794	j = 0;795	target_id = scmd_id(workreq);796 797	/*798	 *	Wide ?799	 */800	w = 1;801	w = w << target_id;802	if ((w & dev->wide_id[c]) != 0) {803		j |= 0x01;804	}805	atp_writeb_io(dev, c, 0x1b, j);806	while ((atp_readb_io(dev, c, 0x1b) & 0x01) != j) {807		atp_writeb_pci(dev, c, 0x1b, j);808#ifdef ED_DBGP809		printk("send_s870 while loop 1\n");810#endif811	}812	/*813	 *	Write the command814	 */815 816	atp_writeb_io(dev, c, 0x00, workreq->cmd_len);817	atp_writeb_io(dev, c, 0x01, 0x2c);818	if (is885(dev))819		atp_writeb_io(dev, c, 0x02, 0x7f);820	else821		atp_writeb_io(dev, c, 0x02, 0xcf);822	for (i = 0; i < workreq->cmd_len; i++)823		atp_writeb_io(dev, c, 0x03 + i, workreq->cmnd[i]);824	atp_writeb_io(dev, c, 0x0f, workreq->device->lun);825	/*826	 *	Write the target827	 */828	atp_writeb_io(dev, c, 0x11, dev->id[c][target_id].devsp);829#ifdef ED_DBGP830	printk("dev->id[%d][%d].devsp = %2x\n",c,target_id,831	       dev->id[c][target_id].devsp);832#endif833 834	sg_count = scsi_dma_map(workreq);835	/*836	 *	Write transfer size837	 */838	atp_writeb_io(dev, c, 0x12, ((unsigned char *) (&l))[2]);839	atp_writeb_io(dev, c, 0x13, ((unsigned char *) (&l))[1]);840	atp_writeb_io(dev, c, 0x14, ((unsigned char *) (&l))[0]);841	j = target_id;842	dev->id[c][j].last_len = l;843	dev->id[c][j].tran_len = 0;844#ifdef ED_DBGP845	printk("dev->id[%2d][%2d].last_len = %d\n",c,j,dev->id[c][j].last_len);846#endif847	/*848	 *	Flip the wide bits849	 */850	if ((j & 0x08) != 0) {851		j = (j & 0x07) | 0x40;852	}853	/*854	 *	Check transfer direction855	 */856	if (workreq->sc_data_direction == DMA_TO_DEVICE)857		atp_writeb_io(dev, c, 0x15, j | 0x20);858	else859		atp_writeb_io(dev, c, 0x15, j);860	atp_writeb_io(dev, c, 0x16, atp_readb_io(dev, c, 0x16) | 0x80);861	atp_writeb_io(dev, c, 0x16, 0x80);862	dev->id[c][target_id].dirct = 0;863	if (l == 0) {864		if (atp_readb_io(dev, c, 0x1c) == 0) {865#ifdef ED_DBGP866			printk("change SCSI_CMD_REG 0x08\n");867#endif868			atp_writeb_io(dev, c, 0x18, 0x08);869		} else870			dev->last_cmd[c] |= 0x40;871		dev->in_snd[c] = 0;872		return;873	}874	prd = dev->id[c][target_id].prd_table;875	dev->id[c][target_id].prd_pos = prd;876 877	/*878	 *	Now write the request list. Either as scatter/gather or as879	 *	a linear chain.880	 */881 882	if (l) {883		struct scatterlist *sgpnt;884		i = 0;885		scsi_for_each_sg(workreq, sgpnt, sg_count, j) {886			bttl = sg_dma_address(sgpnt);887			l=sg_dma_len(sgpnt);888#ifdef ED_DBGP889			printk("1. bttl %x, l %x\n",bttl, l);890#endif891			while (l > 0x10000) {892				(((u16 *) (prd))[i + 3]) = 0x0000;893				(((u16 *) (prd))[i + 2]) = 0x0000;894				(((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl);895				l -= 0x10000;896				bttl += 0x10000;897				i += 0x04;898			}899			(((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl);900			(((u16 *) (prd))[i + 2]) = cpu_to_le16(l);901			(((u16 *) (prd))[i + 3]) = 0;902			i += 0x04;903		}904		(((u16 *) (prd))[i - 1]) = cpu_to_le16(0x8000);905#ifdef ED_DBGP906		printk("prd %4x %4x %4x %4x\n",907		       (((unsigned short int *)prd)[0]),908		       (((unsigned short int *)prd)[1]),909		       (((unsigned short int *)prd)[2]),910		       (((unsigned short int *)prd)[3]));911		printk("2. bttl %x, l %x\n",bttl, l);912#endif913	}914#ifdef ED_DBGP915	printk("send_s870: prdaddr_2 0x%8x target_id %d\n",916	       dev->id[c][target_id].prdaddr,target_id);917#endif918	dev->id[c][target_id].prdaddr = dev->id[c][target_id].prd_bus;919	atp_writel_pci(dev, c, 4, dev->id[c][target_id].prdaddr);920	atp_writeb_pci(dev, c, 2, 0x06);921	atp_writeb_pci(dev, c, 2, 0x00);922	if (is885(dev)) {923		j = atp_readb_pci(dev, c, 1) & 0xf3;924		if ((workreq->cmnd[0] == READ_6) ||925		    (workreq->cmnd[0] == READ_10) ||926		    (workreq->cmnd[0] == WRITE_6) ||927		    (workreq->cmnd[0] == WRITE_10)) {928			j |= 0x0c;929		}930		atp_writeb_pci(dev, c, 1, j);931	} else if (is880(dev)) {932		if ((workreq->cmnd[0] == READ_6) ||933		    (workreq->cmnd[0] == READ_10) ||934		    (workreq->cmnd[0] == WRITE_6) ||935		    (workreq->cmnd[0] == WRITE_10))936			atp_writeb_base(dev, 0x3b,937					(atp_readb_base(dev, 0x3b) & 0x3f) | 0xc0);938		else939			atp_writeb_base(dev, 0x3b,940					atp_readb_base(dev, 0x3b) & 0x3f);941	} else {942		if ((workreq->cmnd[0] == READ_6) ||943		    (workreq->cmnd[0] == READ_10) ||944		    (workreq->cmnd[0] == WRITE_6) ||945		    (workreq->cmnd[0] == WRITE_10))946			atp_writeb_base(dev, 0x3a,947					(atp_readb_base(dev, 0x3a) & 0xf3) | 0x08);948		else949			atp_writeb_base(dev, 0x3a,950					atp_readb_base(dev, 0x3a) & 0xf3);951	}952 953	if(workreq->sc_data_direction == DMA_TO_DEVICE) {954		dev->id[c][target_id].dirct = 0x20;955		if (atp_readb_io(dev, c, 0x1c) == 0) {956			atp_writeb_io(dev, c, 0x18, 0x08);957			atp_writeb_pci(dev, c, 0, 0x01);958#ifdef ED_DBGP959		printk( "start DMA(to target)\n");960#endif961		} else {962			dev->last_cmd[c] |= 0x40;963		}964		dev->in_snd[c] = 0;965		return;966	}967	if (atp_readb_io(dev, c, 0x1c) == 0) {968		atp_writeb_io(dev, c, 0x18, 0x08);969		atp_writeb_pci(dev, c, 0, 0x09);970#ifdef ED_DBGP971		printk( "start DMA(to host)\n");972#endif973	} else {974		dev->last_cmd[c] |= 0x40;975	}976	dev->in_snd[c] = 0;977	return;978 979}980 981static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val)982{983	unsigned short int i, k;984	unsigned char j;985 986	atp_writew_io(dev, 0, 0x1c, *val);987	for (i = 0; i < 10; i++) {	/* stable >= bus settle delay(400 ns)  */988		k = atp_readw_io(dev, 0, 0x1c);989		j = (unsigned char) (k >> 8);990		if ((k & 0x8000) != 0)	/* DB7 all release?    */991			i = 0;992	}993	*val |= 0x4000;		/* assert DB6           */994	atp_writew_io(dev, 0, 0x1c, *val);995	*val &= 0xdfff;		/* assert DB5           */996	atp_writew_io(dev, 0, 0x1c, *val);997	for (i = 0; i < 10; i++) {	/* stable >= bus settle delay(400 ns) */998		if ((atp_readw_io(dev, 0, 0x1c) & 0x2000) != 0)	/* DB5 all release?       */999			i = 0;1000	}1001	*val |= 0x8000;		/* no DB4-0, assert DB7    */1002	*val &= 0xe0ff;1003	atp_writew_io(dev, 0, 0x1c, *val);1004	*val &= 0xbfff;		/* release DB6             */1005	atp_writew_io(dev, 0, 0x1c, *val);1006	for (i = 0; i < 10; i++) {	/* stable >= bus settle delay(400 ns)  */1007		if ((atp_readw_io(dev, 0, 0x1c) & 0x4000) != 0)	/* DB6 all release?  */1008			i = 0;1009	}1010 1011	return j;1012}1013 1014static void tscam(struct Scsi_Host *host, bool wide_chip, u8 scam_on)1015{1016 1017	unsigned char i, j, k;1018	unsigned long n;1019	unsigned short int m, assignid_map, val;1020	unsigned char mbuf[33], quintet[2];1021	struct atp_unit *dev = (struct atp_unit *)&host->hostdata;1022	static unsigned char g2q_tab[8] = {1023		0x38, 0x31, 0x32, 0x2b, 0x34, 0x2d, 0x2e, 0x271024	};1025 1026/*  I can't believe we need this before we've even done anything.  Remove it1027 *  and see if anyone bitches.1028	for (i = 0; i < 0x10; i++) {1029		udelay(0xffff);1030	}1031 */1032 1033	atp_writeb_io(dev, 0, 1, 0x08);1034	atp_writeb_io(dev, 0, 2, 0x7f);1035	atp_writeb_io(dev, 0, 0x11, 0x20);1036 1037	if ((scam_on & 0x40) == 0) {1038		return;1039	}1040	m = 1;1041	m <<= dev->host_id[0];1042	j = 16;1043	if (!wide_chip) {1044		m |= 0xff00;1045		j = 8;1046	}1047	assignid_map = m;1048	atp_writeb_io(dev, 0, 0x02, 0x02);	/* 2*2=4ms,3EH 2/32*3E=3.9ms */1049	atp_writeb_io(dev, 0, 0x03, 0);1050	atp_writeb_io(dev, 0, 0x04, 0);1051	atp_writeb_io(dev, 0, 0x05, 0);1052	atp_writeb_io(dev, 0, 0x06, 0);1053	atp_writeb_io(dev, 0, 0x07, 0);1054	atp_writeb_io(dev, 0, 0x08, 0);1055 1056	for (i = 0; i < j; i++) {1057		m = 1;1058		m = m << i;1059		if ((m & assignid_map) != 0) {1060			continue;1061		}1062		atp_writeb_io(dev, 0, 0x0f, 0);1063		atp_writeb_io(dev, 0, 0x12, 0);1064		atp_writeb_io(dev, 0, 0x13, 0);1065		atp_writeb_io(dev, 0, 0x14, 0);1066		if (i > 7) {1067			k = (i & 0x07) | 0x40;1068		} else {1069			k = i;1070		}1071		atp_writeb_io(dev, 0, 0x15, k);1072		if (wide_chip)1073			atp_writeb_io(dev, 0, 0x1b, 0x01);1074		else1075			atp_writeb_io(dev, 0, 0x1b, 0x00);1076		do {1077			atp_writeb_io(dev, 0, 0x18, 0x09);1078 1079			while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00)1080				cpu_relax();1081			k = atp_readb_io(dev, 0, 0x17);1082			if ((k == 0x85) || (k == 0x42))1083				break;1084			if (k != 0x16)1085				atp_writeb_io(dev, 0, 0x10, 0x41);1086		} while (k != 0x16);1087		if ((k == 0x85) || (k == 0x42))1088			continue;1089		assignid_map |= m;1090 1091	}1092	atp_writeb_io(dev, 0, 0x02, 0x7f);1093	atp_writeb_io(dev, 0, 0x1b, 0x02);1094 1095	udelay(2);1096 1097	val = 0x0080;		/* bsy  */1098	atp_writew_io(dev, 0, 0x1c, val);1099	val |= 0x0040;		/* sel  */1100	atp_writew_io(dev, 0, 0x1c, val);1101	val |= 0x0004;		/* msg  */1102	atp_writew_io(dev, 0, 0x1c, val);1103	udelay(2);		/* 2 deskew delay(45ns*2=90ns) */1104	val &= 0x007f;		/* no bsy  */1105	atp_writew_io(dev, 0, 0x1c, val);1106	msleep(128);1107	val &= 0x00fb;		/* after 1ms no msg */1108	atp_writew_io(dev, 0, 0x1c, val);1109	while ((atp_readb_io(dev, 0, 0x1c) & 0x04) != 0)1110		;1111	udelay(2);1112	udelay(100);1113	for (n = 0; n < 0x30000; n++)1114		if ((atp_readb_io(dev, 0, 0x1c) & 0x80) != 0)	/* bsy ? */1115			break;1116	if (n < 0x30000)1117		for (n = 0; n < 0x30000; n++)1118			if ((atp_readb_io(dev, 0, 0x1c) & 0x81) == 0x0081) {1119				udelay(2);1120				val |= 0x8003;		/* io,cd,db7  */1121				atp_writew_io(dev, 0, 0x1c, val);1122				udelay(2);1123				val &= 0x00bf;		/* no sel     */1124				atp_writew_io(dev, 0, 0x1c, val);1125				udelay(2);1126				break;1127			}1128	while (1) {1129	/*1130	 * The funny division into multiple delays is to accomodate1131	 * arches like ARM where udelay() multiplies its argument by1132	 * a large number to initialize a loop counter.  To avoid1133	 * overflow, the maximum supported udelay is 2000 microseconds.1134	 *1135	 * XXX it would be more polite to find a way to use msleep()1136	 */1137	mdelay(2);1138	udelay(48);1139	if ((atp_readb_io(dev, 0, 0x1c) & 0x80) == 0x00) {	/* bsy ? */1140		atp_writew_io(dev, 0, 0x1c, 0);1141		atp_writeb_io(dev, 0, 0x1b, 0);1142		atp_writeb_io(dev, 0, 0x15, 0);1143		atp_writeb_io(dev, 0, 0x18, 0x09);1144		while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0)1145			cpu_relax();1146		atp_readb_io(dev, 0, 0x17);1147		return;1148	}1149	val &= 0x00ff;		/* synchronization  */1150	val |= 0x3f00;1151	fun_scam(dev, &val);1152	udelay(2);1153	val &= 0x00ff;		/* isolation        */1154	val |= 0x2000;1155	fun_scam(dev, &val);1156	udelay(2);1157	i = 8;1158	j = 0;1159 1160	while (1) {1161		if ((atp_readw_io(dev, 0, 0x1c) & 0x2000) == 0)1162			continue;1163		udelay(2);1164		val &= 0x00ff;		/* get ID_STRING */1165		val |= 0x2000;1166		k = fun_scam(dev, &val);1167		if ((k & 0x03) == 0)1168			break;1169		mbuf[j] <<= 0x01;1170		mbuf[j] &= 0xfe;1171		if ((k & 0x02) != 0)1172			mbuf[j] |= 0x01;1173		i--;1174		if (i > 0)1175			continue;1176		j++;1177		i = 8;1178	}1179 1180	/* isolation complete..  */1181/*    mbuf[32]=0;1182	printk(" \n%x %x %x %s\n ",assignid_map,mbuf[0],mbuf[1],&mbuf[2]); */1183	i = 15;1184	j = mbuf[0];1185	if ((j & 0x20) != 0) {	/* bit5=1:ID up to 7      */1186		i = 7;1187	}1188	if ((j & 0x06) != 0) {	/* IDvalid?             */1189		k = mbuf[1];1190		while (1) {1191			m = 1;1192			m <<= k;1193			if ((m & assignid_map) == 0)1194				break;1195			if (k > 0)1196				k--;1197			else1198				break;1199		}1200	}1201	if ((m & assignid_map) != 0) {	/* srch from max acceptable ID#  */1202		k = i;			/* max acceptable ID#            */1203		while (1) {1204			m = 1;1205			m <<= k;1206			if ((m & assignid_map) == 0)1207				break;1208			if (k > 0)1209				k--;1210			else1211				break;1212		}1213	}1214	/* k=binID#,       */1215	assignid_map |= m;1216	if (k < 8) {1217		quintet[0] = 0x38;	/* 1st dft ID<8    */1218	} else {1219		quintet[0] = 0x31;	/* 1st  ID>=8      */1220	}1221	k &= 0x07;1222	quintet[1] = g2q_tab[k];1223 1224	val &= 0x00ff;		/* AssignID 1stQuintet,AH=001xxxxx  */1225	m = quintet[0] << 8;1226	val |= m;1227	fun_scam(dev, &val);1228	val &= 0x00ff;		/* AssignID 2ndQuintet,AH=001xxxxx */1229	m = quintet[1] << 8;1230	val |= m;1231	fun_scam(dev, &val);1232 1233	}1234}1235 1236static void atp870u_free_tables(struct Scsi_Host *host)1237{1238	struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata;1239	int j, k;1240	for (j=0; j < 2; j++) {1241		for (k = 0; k < 16; k++) {1242			if (!atp_dev->id[j][k].prd_table)1243				continue;1244			dma_free_coherent(&atp_dev->pdev->dev, 1024,1245					  atp_dev->id[j][k].prd_table,1246					  atp_dev->id[j][k].prd_bus);1247			atp_dev->id[j][k].prd_table = NULL;1248		}1249	}1250}1251 1252static int atp870u_init_tables(struct Scsi_Host *host)1253{1254	struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata;1255	int c,k;1256	for(c=0;c < 2;c++) {1257		for(k=0;k<16;k++) {1258			atp_dev->id[c][k].prd_table =1259				dma_alloc_coherent(&atp_dev->pdev->dev, 1024,1260						   &(atp_dev->id[c][k].prd_bus),1261						   GFP_KERNEL);1262			if (!atp_dev->id[c][k].prd_table) {1263				printk("atp870u_init_tables fail\n");1264				atp870u_free_tables(host);1265				return -ENOMEM;1266			}1267			atp_dev->id[c][k].prdaddr = atp_dev->id[c][k].prd_bus;1268			atp_dev->id[c][k].devsp=0x20;1269			atp_dev->id[c][k].devtype = 0x7f;1270			atp_dev->id[c][k].curr_req = NULL;1271		}1272 1273		atp_dev->active_id[c] = 0;1274		atp_dev->wide_id[c] = 0;1275		atp_dev->host_id[c] = 0x07;1276		atp_dev->quhd[c] = 0;1277		atp_dev->quend[c] = 0;1278		atp_dev->last_cmd[c] = 0xff;1279		atp_dev->in_snd[c] = 0;1280		atp_dev->in_int[c] = 0;1281 1282		for (k = 0; k < qcnt; k++) {1283			atp_dev->quereq[c][k] = NULL;1284		}1285		for (k = 0; k < 16; k++) {1286			   atp_dev->id[c][k].curr_req = NULL;1287			   atp_dev->sp[c][k] = 0x04;1288		}1289	}1290	return 0;1291}1292 1293static void atp_set_host_id(struct atp_unit *atp, u8 c, u8 host_id)1294{1295	atp_writeb_io(atp, c, 0, host_id | 0x08);1296	atp_writeb_io(atp, c, 0x18, 0);1297	while ((atp_readb_io(atp, c, 0x1f) & 0x80) == 0)1298		mdelay(1);1299	atp_readb_io(atp, c, 0x17);1300	atp_writeb_io(atp, c, 1, 8);1301	atp_writeb_io(atp, c, 2, 0x7f);1302	atp_writeb_io(atp, c, 0x11, 0x20);1303}1304 1305static void atp870_init(struct Scsi_Host *shpnt)1306{1307	struct atp_unit *atpdev = shost_priv(shpnt);1308	struct pci_dev *pdev = atpdev->pdev;1309	unsigned char k, host_id;1310	u8 scam_on;1311	bool wide_chip =1312		(pdev->device == PCI_DEVICE_ID_ARTOP_AEC7610 &&1313		 pdev->revision == 4) ||1314		(pdev->device == PCI_DEVICE_ID_ARTOP_AEC7612UW) ||1315		(pdev->device == PCI_DEVICE_ID_ARTOP_AEC7612SUW);1316 1317	pci_read_config_byte(pdev, 0x49, &host_id);1318 1319	dev_info(&pdev->dev, "ACARD AEC-671X PCI Ultra/W SCSI-2/3 "1320		 "Host Adapter: IO:%lx, IRQ:%d.\n",1321		 shpnt->io_port, shpnt->irq);1322 1323	atpdev->ioport[0] = shpnt->io_port;1324	atpdev->pciport[0] = shpnt->io_port + 0x20;1325	host_id &= 0x07;1326	atpdev->host_id[0] = host_id;1327	scam_on = atp_readb_pci(atpdev, 0, 2);1328	atpdev->global_map[0] = atp_readb_base(atpdev, 0x2d);1329	atpdev->ultra_map[0] = atp_readw_base(atpdev, 0x2e);1330 1331	if (atpdev->ultra_map[0] == 0) {1332		scam_on = 0x00;1333		atpdev->global_map[0] = 0x20;1334		atpdev->ultra_map[0] = 0xffff;1335	}1336 1337	if (pdev->revision > 0x07)	/* check if atp876 chip */1338		atp_writeb_base(atpdev, 0x3e, 0x00); /* enable terminator */1339 1340	k = (atp_readb_base(atpdev, 0x3a) & 0xf3) | 0x10;1341	atp_writeb_base(atpdev, 0x3a, k);1342	atp_writeb_base(atpdev, 0x3a, k & 0xdf);1343	msleep(32);1344	atp_writeb_base(atpdev, 0x3a, k);1345	msleep(32);1346	atp_set_host_id(atpdev, 0, host_id);1347 1348	tscam(shpnt, wide_chip, scam_on);1349	atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) | 0x10);1350	atp_is(atpdev, 0, wide_chip, 0);1351	atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) & 0xef);1352	atp_writeb_base(atpdev, 0x3b, atp_readb_base(atpdev, 0x3b) | 0x20);1353	shpnt->max_id = wide_chip ? 16 : 8;1354	shpnt->this_id = host_id;1355}1356 1357static void atp880_init(struct Scsi_Host *shpnt)1358{1359	struct atp_unit *atpdev = shost_priv(shpnt);1360	struct pci_dev *pdev = atpdev->pdev;1361	unsigned char k, m, host_id;1362	unsigned int n;1363 1364	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);1365 1366	atpdev->ioport[0] = shpnt->io_port + 0x40;1367	atpdev->pciport[0] = shpnt->io_port + 0x28;1368 1369	host_id = atp_readb_base(atpdev, 0x39) >> 4;1370 1371	dev_info(&pdev->dev, "ACARD AEC-67160 PCI Ultra3 LVD "1372		 "Host Adapter: IO:%lx, IRQ:%d.\n",1373		 shpnt->io_port, shpnt->irq);1374	atpdev->host_id[0] = host_id;1375 1376	atpdev->global_map[0] = atp_readb_base(atpdev, 0x35);1377	atpdev->ultra_map[0] = atp_readw_base(atpdev, 0x3c);1378 1379	n = 0x3f09;1380	while (n < 0x4000) {1381		m = 0;1382		atp_writew_base(atpdev, 0x34, n);1383		n += 0x0002;1384		if (atp_readb_base(atpdev, 0x30) == 0xff)1385			break;1386 1387		atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30);1388		atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31);1389		atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32);1390		atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33);1391		atp_writew_base(atpdev, 0x34, n);1392		n += 0x0002;1393		atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30);1394		atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31);1395		atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32);1396		atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33);1397		atp_writew_base(atpdev, 0x34, n);1398		n += 0x0002;1399		atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30);1400		atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31);1401		atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32);1402		atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33);1403		atp_writew_base(atpdev, 0x34, n);1404		n += 0x0002;1405		atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30);1406		atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31);1407		atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32);1408		atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33);1409		n += 0x0018;1410	}1411	atp_writew_base(atpdev, 0x34, 0);1412	atpdev->ultra_map[0] = 0;1413	atpdev->async[0] = 0;1414	for (k = 0; k < 16; k++) {1415		n = 1 << k;1416		if (atpdev->sp[0][k] > 1)1417			atpdev->ultra_map[0] |= n;1418		else1419			if (atpdev->sp[0][k] == 0)1420				atpdev->async[0] |= n;1421	}1422	atpdev->async[0] = ~(atpdev->async[0]);1423	atp_writeb_base(atpdev, 0x35, atpdev->global_map[0]);1424 1425	k = atp_readb_base(atpdev, 0x38) & 0x80;1426	atp_writeb_base(atpdev, 0x38, k);1427	atp_writeb_base(atpdev, 0x3b, 0x20);1428	msleep(32);1429	atp_writeb_base(atpdev, 0x3b, 0);1430	msleep(32);1431	atp_readb_io(atpdev, 0, 0x1b);1432	atp_readb_io(atpdev, 0, 0x17);1433 1434	atp_set_host_id(atpdev, 0, host_id);1435 1436	tscam(shpnt, true, atp_readb_base(atpdev, 0x22));1437	atp_is(atpdev, 0, true, atp_readb_base(atpdev, 0x3f) & 0x40);1438	atp_writeb_base(atpdev, 0x38, 0xb0);1439	shpnt->max_id = 16;1440	shpnt->this_id = host_id;1441}1442 1443static void atp885_init(struct Scsi_Host *shpnt)1444{1445	struct atp_unit *atpdev = shost_priv(shpnt);1446	struct pci_dev *pdev = atpdev->pdev;1447	unsigned char k, m, c;1448	unsigned int n;1449	unsigned char setupdata[2][16];1450 1451	dev_info(&pdev->dev, "ACARD AEC-67162 PCI Ultra3 LVD "1452		 "Host Adapter: IO:%lx, IRQ:%d.\n",1453		 shpnt->io_port, shpnt->irq);1454 1455	atpdev->ioport[0] = shpnt->io_port + 0x80;1456	atpdev->ioport[1] = shpnt->io_port + 0xc0;1457	atpdev->pciport[0] = shpnt->io_port + 0x40;1458	atpdev->pciport[1] = shpnt->io_port + 0x50;1459 1460	c = atp_readb_base(atpdev, 0x29);1461	atp_writeb_base(atpdev, 0x29, c | 0x04);1462 1463	n = 0x1f80;1464	while (n < 0x2000) {1465		atp_writew_base(atpdev, 0x3c, n);1466		if (atp_readl_base(atpdev, 0x38) == 0xffffffff)1467			break;1468		for (m = 0; m < 2; m++) {1469			atpdev->global_map[m] = 0;1470			for (k = 0; k < 4; k++) {1471				atp_writew_base(atpdev, 0x3c, n++);1472				((u32 *)&setupdata[m][0])[k] =1473					atp_readl_base(atpdev, 0x38);1474			}1475			for (k = 0; k < 4; k++) {1476				atp_writew_base(atpdev, 0x3c, n++);1477				((u32 *)&atpdev->sp[m][0])[k] =1478					atp_readl_base(atpdev, 0x38);1479			}1480			n += 8;1481		}1482	}1483	c = atp_readb_base(atpdev, 0x29);1484	atp_writeb_base(atpdev, 0x29, c & 0xfb);1485	for (c = 0; c < 2; c++) {1486		atpdev->ultra_map[c] = 0;1487		atpdev->async[c] = 0;1488		for (k = 0; k < 16; k++) {1489			n = 1 << k;1490			if (atpdev->sp[c][k] > 1)1491				atpdev->ultra_map[c] |= n;1492			else1493				if (atpdev->sp[c][k] == 0)1494					atpdev->async[c] |= n;1495		}1496		atpdev->async[c] = ~(atpdev->async[c]);1497 1498		if (atpdev->global_map[c] == 0) {1499			k = setupdata[c][1];1500			if ((k & 0x40) != 0)1501				atpdev->global_map[c] |= 0x20;1502			k &= 0x07;1503			atpdev->global_map[c] |= k;1504			if ((setupdata[c][2] & 0x04) != 0)1505				atpdev->global_map[c] |= 0x08;1506			atpdev->host_id[c] = setupdata[c][0] & 0x07;1507		}1508	}1509 1510	k = atp_readb_base(atpdev, 0x28) & 0x8f;1511	k |= 0x10;1512	atp_writeb_base(atpdev, 0x28, k);1513	atp_writeb_pci(atpdev, 0, 1, 0x80);1514	atp_writeb_pci(atpdev, 1, 1, 0x80);1515	msleep(100);1516	atp_writeb_pci(atpdev, 0, 1, 0);1517	atp_writeb_pci(atpdev, 1, 1, 0);1518	msleep(1000);1519	atp_readb_io(atpdev, 0, 0x1b);1520	atp_readb_io(atpdev, 0, 0x17);1521	atp_readb_io(atpdev, 1, 0x1b);1522	atp_readb_io(atpdev, 1, 0x17);1523 1524	k = atpdev->host_id[0];1525	if (k > 7)1526		k = (k & 0x07) | 0x40;1527	atp_set_host_id(atpdev, 0, k);1528 1529	k = atpdev->host_id[1];1530	if (k > 7)1531		k = (k & 0x07) | 0x40;1532	atp_set_host_id(atpdev, 1, k);1533 1534	msleep(600); /* this delay used to be called tscam_885() */1535	dev_info(&pdev->dev, "Scanning Channel A SCSI Device ...\n");1536	atp_is(atpdev, 0, true, atp_readb_io(atpdev, 0, 0x1b) >> 7);1537	atp_writeb_io(atpdev, 0, 0x16, 0x80);1538	dev_info(&pdev->dev, "Scanning Channel B SCSI Device ...\n");1539	atp_is(atpdev, 1, true, atp_readb_io(atpdev, 1, 0x1b) >> 7);1540	atp_writeb_io(atpdev, 1, 0x16, 0x80);1541	k = atp_readb_base(atpdev, 0x28) & 0xcf;1542	k |= 0xc0;1543	atp_writeb_base(atpdev, 0x28, k);1544	k = atp_readb_base(atpdev, 0x1f) | 0x80;1545	atp_writeb_base(atpdev, 0x1f, k);1546	k = atp_readb_base(atpdev, 0x29) | 0x01;1547	atp_writeb_base(atpdev, 0x29, k);1548	shpnt->max_id = 16;1549	shpnt->max_lun = (atpdev->global_map[0] & 0x07) + 1;1550	shpnt->max_channel = 1;1551	shpnt->this_id = atpdev->host_id[0];1552}1553 1554/* return non-zero on detection */1555static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)1556{1557	struct Scsi_Host *shpnt = NULL;1558	struct atp_unit *atpdev;1559	int err;1560 1561	if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610 && pdev->revision < 2) {1562		dev_err(&pdev->dev, "ATP850S chips (AEC6710L/F cards) are not supported.\n");1563		return -ENODEV;1564	}1565 1566	err = pci_enable_device(pdev);1567	if (err)1568		goto fail;1569 1570	if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {1571		printk(KERN_ERR "atp870u: DMA mask required but not available.\n");1572		err = -EIO;1573		goto disable_device;1574	}1575 1576	err = pci_request_regions(pdev, "atp870u");1577	if (err)1578		goto disable_device;1579	pci_set_master(pdev);1580 1581	err = -ENOMEM;1582	shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));1583	if (!shpnt)1584		goto release_region;1585 1586	atpdev = shost_priv(shpnt);1587 1588	atpdev->host = shpnt;1589	atpdev->pdev = pdev;1590	pci_set_drvdata(pdev, atpdev);1591 1592	shpnt->io_port = pci_resource_start(pdev, 0);1593	shpnt->io_port &= 0xfffffff8;1594	shpnt->n_io_port = pci_resource_len(pdev, 0);1595	atpdev->baseport = shpnt->io_port;1596	shpnt->unique_id = shpnt->io_port;1597	shpnt->irq = pdev->irq;1598 1599	err = atp870u_init_tables(shpnt);1600	if (err) {1601		dev_err(&pdev->dev, "Unable to allocate tables for Acard controller\n");1602		goto unregister;1603	}1604 1605	if (is880(atpdev))1606		atp880_init(shpnt);1607	else if (is885(atpdev))1608		atp885_init(shpnt);1609	else1610		atp870_init(shpnt);1611 1612	err = request_irq(shpnt->irq, atp870u_intr_handle, IRQF_SHARED, "atp870u", shpnt);1613	if (err) {1614		dev_err(&pdev->dev, "Unable to allocate IRQ %d.\n", shpnt->irq);1615		goto free_tables;1616	}1617 1618	err = scsi_add_host(shpnt, &pdev->dev);1619	if (err)1620		goto scsi_add_fail;1621	scsi_scan_host(shpnt);1622 1623	return 0;1624 1625scsi_add_fail:1626	free_irq(shpnt->irq, shpnt);1627free_tables:1628	atp870u_free_tables(shpnt);1629unregister:1630	scsi_host_put(shpnt);1631release_region:1632	pci_release_regions(pdev);1633disable_device:1634	pci_disable_device(pdev);1635fail:1636	return err;1637}1638 1639/* The abort command does not leave the device in a clean state where1640   it is available to be used again.  Until this gets worked out, we will1641   leave it commented out.  */1642 1643static int atp870u_abort(struct scsi_cmnd * SCpnt)1644{1645	unsigned char  j, k, c;1646	struct scsi_cmnd *workrequ;1647	struct atp_unit *dev;1648	struct Scsi_Host *host;1649	host = SCpnt->device->host;1650 1651	dev = (struct atp_unit *)&host->hostdata;1652	c = scmd_channel(SCpnt);1653	printk(" atp870u: abort Channel = %x \n", c);1654	printk("working=%x last_cmd=%x ", dev->working[c], dev->last_cmd[c]);1655	printk(" quhdu=%x quendu=%x ", dev->quhd[c], dev->quend[c]);1656	for (j = 0; j < 0x18; j++) {1657		printk(" r%2x=%2x", j, atp_readb_io(dev, c, j));1658	}1659	printk(" r1c=%2x", atp_readb_io(dev, c, 0x1c));1660	printk(" r1f=%2x in_snd=%2x ", atp_readb_io(dev, c, 0x1f), dev->in_snd[c]);1661	printk(" d00=%2x", atp_readb_pci(dev, c, 0x00));1662	printk(" d02=%2x", atp_readb_pci(dev, c, 0x02));1663	for(j=0;j<16;j++) {1664	   if (dev->id[c][j].curr_req != NULL) {1665		workrequ = dev->id[c][j].curr_req;1666		printk("\n que cdb= ");1667		for (k=0; k < workrequ->cmd_len; k++) {1668		    printk(" %2x ",workrequ->cmnd[k]);1669		}1670		printk(" last_lenu= %x ",(unsigned int)dev->id[c][j].last_len);1671	   }1672	}1673	return SUCCESS;1674}1675 1676static const char *atp870u_info(struct Scsi_Host *notused)1677{1678	static char buffer[128];1679 1680	strcpy(buffer, "ACARD AEC-6710/6712/67160 PCI Ultra/W/LVD SCSI-3 Adapter Driver V2.6+ac ");1681 1682	return buffer;1683}1684 1685static int atp870u_show_info(struct seq_file *m, struct Scsi_Host *HBAptr)1686{1687	seq_puts(m, "ACARD AEC-671X Driver Version: 2.6+ac\n\n"1688		"Adapter Configuration:\n");1689	seq_printf(m, "               Base IO: %#.4lx\n", HBAptr->io_port);1690	seq_printf(m, "                   IRQ: %d\n", HBAptr->irq);1691	return 0;1692}1693 1694 1695static int atp870u_biosparam(struct scsi_device *disk, struct block_device *dev,1696			sector_t capacity, int *ip)1697{1698	int heads, sectors, cylinders;1699 1700	heads = 64;1701	sectors = 32;1702	cylinders = (unsigned long)capacity / (heads * sectors);1703	if (cylinders > 1024) {1704		heads = 255;1705		sectors = 63;1706		cylinders = (unsigned long)capacity / (heads * sectors);1707	}1708	ip[0] = heads;1709	ip[1] = sectors;1710	ip[2] = cylinders;1711 1712	return 0;1713}1714 1715static void atp870u_remove (struct pci_dev *pdev)1716{1717	struct atp_unit *devext = pci_get_drvdata(pdev);1718	struct Scsi_Host *pshost = devext->host;1719 1720	scsi_remove_host(pshost);1721	free_irq(pshost->irq, pshost);1722	pci_release_regions(pdev);1723	pci_disable_device(pdev);1724	atp870u_free_tables(pshost);1725	scsi_host_put(pshost);1726}1727 1728MODULE_DESCRIPTION("ACARD SCSI host adapter driver");1729MODULE_LICENSE("GPL");1730 1731static const struct scsi_host_template atp870u_template = {1732     .module			= THIS_MODULE,1733     .name			= "atp870u"		/* name */,1734     .proc_name			= "atp870u",1735     .show_info			= atp870u_show_info,1736     .info			= atp870u_info		/* info */,1737     .queuecommand		= atp870u_queuecommand	/* queuecommand */,1738     .eh_abort_handler		= atp870u_abort		/* abort */,1739     .bios_param		= atp870u_biosparam	/* biosparm */,1740     .can_queue			= qcnt			/* can_queue */,1741     .this_id			= 7			/* SCSI ID */,1742     .sg_tablesize		= ATP870U_SCATTER	/*SG_ALL*/,1743     .max_sectors		= ATP870U_MAX_SECTORS,1744};1745 1746static struct pci_device_id atp870u_id_table[] = {1747	{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, ATP885_DEVID)			  },1748	{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, ATP880_DEVID1)		  },1749	{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, ATP880_DEVID2)		  },1750	{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7610)    },1751	{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612UW)  },1752	{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612U)   },1753	{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612S)   },1754	{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612D)	  },1755	{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612SUW) },1756	{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_8060)	  },1757	{ 0, },1758};1759 1760MODULE_DEVICE_TABLE(pci, atp870u_id_table);1761 1762static struct pci_driver atp870u_driver = {1763	.id_table	= atp870u_id_table,1764	.name		= "atp870u",1765	.probe		= atp870u_probe,1766	.remove		= atp870u_remove,1767};1768 1769module_pci_driver(atp870u_driver);1770 1771static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip,1772		   unsigned char lvdmode)1773{1774	unsigned char i, j, k, rmb, n;1775	unsigned short int m;1776	static unsigned char mbuf[512];1777	static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 };1778	static unsigned char inqd[9] = { 0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6 };1779	static unsigned char synn[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };1780	unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e };1781	static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };1782	static unsigned char synw_870[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 };1783	unsigned char synuw[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e };1784	static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 };1785	static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 };1786 1787	for (i = 0; i < 16; i++) {1788		if (!wide_chip && (i > 7))1789			break;1790		m = 1;1791		m = m << i;1792		if ((m & dev->active_id[c]) != 0) {1793			continue;1794		}1795		if (i == dev->host_id[c]) {1796			printk(KERN_INFO "         ID: %2d  Host Adapter\n", dev->host_id[c]);1797			continue;1798		}1799		atp_writeb_io(dev, c, 0x1b, wide_chip ? 0x01 : 0x00);1800		atp_writeb_io(dev, c, 1, 0x08);1801		atp_writeb_io(dev, c, 2, 0x7f);1802		atp_writeb_io(dev, c, 3, satn[0]);1803		atp_writeb_io(dev, c, 4, satn[1]);1804		atp_writeb_io(dev, c, 5, satn[2]);1805		atp_writeb_io(dev, c, 6, satn[3]);1806		atp_writeb_io(dev, c, 7, satn[4]);1807		atp_writeb_io(dev, c, 8, satn[5]);1808		atp_writeb_io(dev, c, 0x0f, 0);1809		atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp);1810		atp_writeb_io(dev, c, 0x12, 0);1811		atp_writeb_io(dev, c, 0x13, satn[6]);1812		atp_writeb_io(dev, c, 0x14, satn[7]);1813		j = i;1814		if ((j & 0x08) != 0) {1815			j = (j & 0x07) | 0x40;1816		}1817		atp_writeb_io(dev, c, 0x15, j);1818		atp_writeb_io(dev, c, 0x18, satn[8]);1819 1820		while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)1821			cpu_relax();1822 1823		if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e)1824			continue;1825 1826		while (atp_readb_io(dev, c, 0x17) != 0x8e)1827			cpu_relax();1828 1829		dev->active_id[c] |= m;1830 1831		atp_writeb_io(dev, c, 0x10, 0x30);1832		if (is885(dev) || is880(dev))1833			atp_writeb_io(dev, c, 0x14, 0x00);1834		else /* result of is870() merge - is this a bug? */1835			atp_writeb_io(dev, c, 0x04, 0x00);1836 1837phase_cmd:1838		atp_writeb_io(dev, c, 0x18, 0x08);1839 1840		while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)1841			cpu_relax();1842 1843		j = atp_readb_io(dev, c, 0x17);1844		if (j != 0x16) {1845			atp_writeb_io(dev, c, 0x10, 0x41);1846			goto phase_cmd;1847		}1848sel_ok:1849		atp_writeb_io(dev, c, 3, inqd[0]);1850		atp_writeb_io(dev, c, 4, inqd[1]);1851		atp_writeb_io(dev, c, 5, inqd[2]);1852		atp_writeb_io(dev, c, 6, inqd[3]);1853		atp_writeb_io(dev, c, 7, inqd[4]);1854		atp_writeb_io(dev, c, 8, inqd[5]);1855		atp_writeb_io(dev, c, 0x0f, 0);1856		atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp);1857		atp_writeb_io(dev, c, 0x12, 0);1858		atp_writeb_io(dev, c, 0x13, inqd[6]);1859		atp_writeb_io(dev, c, 0x14, inqd[7]);1860		atp_writeb_io(dev, c, 0x18, inqd[8]);1861 1862		while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)1863			cpu_relax();1864 1865		if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e)1866			continue;1867 1868		while (atp_readb_io(dev, c, 0x17) != 0x8e)1869			cpu_relax();1870 1871		if (wide_chip)1872			atp_writeb_io(dev, c, 0x1b, 0x00);1873 1874		atp_writeb_io(dev, c, 0x18, 0x08);1875		j = 0;1876rd_inq_data:1877		k = atp_readb_io(dev, c, 0x1f);1878		if ((k & 0x01) != 0) {1879			mbuf[j++] = atp_readb_io(dev, c, 0x19);1880			goto rd_inq_data;1881		}1882		if ((k & 0x80) == 0) {1883			goto rd_inq_data;1884		}1885		j = atp_readb_io(dev, c, 0x17);1886		if (j == 0x16) {1887			goto inq_ok;1888		}1889		atp_writeb_io(dev, c, 0x10, 0x46);1890		atp_writeb_io(dev, c, 0x12, 0);1891		atp_writeb_io(dev, c, 0x13, 0);1892		atp_writeb_io(dev, c, 0x14, 0);1893		atp_writeb_io(dev, c, 0x18, 0x08);1894 1895		while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)1896			cpu_relax();1897 1898		if (atp_readb_io(dev, c, 0x17) != 0x16)1899			goto sel_ok;1900 1901inq_ok:1902		mbuf[36] = 0;1903		printk(KERN_INFO "         ID: %2d  %s\n", i, &mbuf[8]);1904		dev->id[c][i].devtype = mbuf[0];1905		rmb = mbuf[1];1906		n = mbuf[7];1907		if (!wide_chip)1908			goto not_wide;1909		if ((mbuf[7] & 0x60) == 0) {1910			goto not_wide;1911		}1912		if (is885(dev) || is880(dev)) {1913			if ((i < 8) && ((dev->global_map[c] & 0x20) == 0))1914				goto not_wide;1915		} else { /* result of is870() merge - is this a bug? */1916			if ((dev->global_map[c] & 0x20) == 0)1917				goto not_wide;1918		}1919		if (lvdmode == 0) {1920			goto chg_wide;1921		}1922		if (dev->sp[c][i] != 0x04)	// force u21923		{1924			goto chg_wide;1925		}1926 1927		atp_writeb_io(dev, c, 0x1b, 0x01);1928		atp_writeb_io(dev, c, 3, satn[0]);1929		atp_writeb_io(dev, c, 4, satn[1]);1930		atp_writeb_io(dev, c, 5, satn[2]);1931		atp_writeb_io(dev, c, 6, satn[3]);1932		atp_writeb_io(dev, c, 7, satn[4]);1933		atp_writeb_io(dev, c, 8, satn[5]);1934		atp_writeb_io(dev, c, 0x0f, 0);1935		atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp);1936		atp_writeb_io(dev, c, 0x12, 0);1937		atp_writeb_io(dev, c, 0x13, satn[6]);1938		atp_writeb_io(dev, c, 0x14, satn[7]);1939		atp_writeb_io(dev, c, 0x18, satn[8]);1940 1941		while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)1942			cpu_relax();1943 1944		if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e)1945			continue;1946 1947		while (atp_readb_io(dev, c, 0x17) != 0x8e)1948			cpu_relax();1949 1950try_u3:1951		j = 0;1952		atp_writeb_io(dev, c, 0x14, 0x09);1953		atp_writeb_io(dev, c, 0x18, 0x20);1954 1955		while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) {1956			if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0)1957				atp_writeb_io(dev, c, 0x19, u3[j++]);1958			cpu_relax();1959		}1960 1961		while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00)1962			cpu_relax();1963 1964		j = atp_readb_io(dev, c, 0x17) & 0x0f;1965		if (j == 0x0f) {1966			goto u3p_in;1967		}1968		if (j == 0x0a) {1969			goto u3p_cmd;1970		}1971		if (j == 0x0e) {1972			goto try_u3;1973		}1974		continue;1975u3p_out:1976		atp_writeb_io(dev, c, 0x18, 0x20);1977		while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) {1978			if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0)1979				atp_writeb_io(dev, c, 0x19, 0);1980			cpu_relax();1981		}1982		j = atp_readb_io(dev, c, 0x17) & 0x0f;1983		if (j == 0x0f) {1984			goto u3p_in;1985		}1986		if (j == 0x0a) {1987			goto u3p_cmd;1988		}1989		if (j == 0x0e) {1990			goto u3p_out;1991		}1992		continue;1993u3p_in:1994		atp_writeb_io(dev, c, 0x14, 0x09);1995		atp_writeb_io(dev, c, 0x18, 0x20);1996		k = 0;1997u3p_in1:1998		j = atp_readb_io(dev, c, 0x1f);1999		if ((j & 0x01) != 0) {2000			mbuf[k++] = atp_readb_io(dev, c, 0x19);2001			goto u3p_in1;2002		}2003		if ((j & 0x80) == 0x00) {2004			goto u3p_in1;2005		}2006		j = atp_readb_io(dev, c, 0x17) & 0x0f;2007		if (j == 0x0f) {2008			goto u3p_in;2009		}2010		if (j == 0x0a) {2011			goto u3p_cmd;2012		}2013		if (j == 0x0e) {2014			goto u3p_out;2015		}2016		continue;2017u3p_cmd:2018		atp_writeb_io(dev, c, 0x10, 0x30);2019		atp_writeb_io(dev, c, 0x14, 0x00);2020		atp_writeb_io(dev, c, 0x18, 0x08);2021 2022		while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00);2023 2024		j = atp_readb_io(dev, c, 0x17);2025		if (j != 0x16) {2026			if (j == 0x4e) {2027				goto u3p_out;2028			}2029			continue;2030		}2031		if (mbuf[0] != 0x01) {2032			goto chg_wide;2033		}2034		if (mbuf[1] != 0x06) {2035			goto chg_wide;2036		}2037		if (mbuf[2] != 0x04) {2038			goto chg_wide;2039		}2040		if (mbuf[3] == 0x09) {2041			m = 1;2042			m = m << i;2043			dev->wide_id[c] |= m;2044			dev->id[c][i].devsp = 0xce;2045#ifdef ED_DBGP2046			printk("dev->id[%2d][%2d].devsp = %2x\n",2047			       c, i, dev->id[c][i].devsp);2048#endif2049			continue;2050		}2051chg_wide:2052		atp_writeb_io(dev, c, 0x1b, 0x01);2053		atp_writeb_io(dev, c, 3, satn[0]);2054		atp_writeb_io(dev, c, 4, satn[1]);2055		atp_writeb_io(dev, c, 5, satn[2]);2056		atp_writeb_io(dev, c, 6, satn[3]);2057		atp_writeb_io(dev, c, 7, satn[4]);2058		atp_writeb_io(dev, c, 8, satn[5]);2059		atp_writeb_io(dev, c, 0x0f, 0);2060		atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp);2061		atp_writeb_io(dev, c, 0x12, 0);2062		atp_writeb_io(dev, c, 0x13, satn[6]);2063		atp_writeb_io(dev, c, 0x14, satn[7]);2064		atp_writeb_io(dev, c, 0x18, satn[8]);2065 2066		while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)2067			cpu_relax();2068 2069		if (atp_readb_io(dev, c, 0x17) != 0x11 &&2070		    atp_readb_io(dev, c, 0x17) != 0x8e)2071			continue;2072 2073		while (atp_readb_io(dev, c, 0x17) != 0x8e)2074			cpu_relax();2075 2076try_wide:2077		j = 0;2078		atp_writeb_io(dev, c, 0x14, 0x05);2079		atp_writeb_io(dev, c, 0x18, 0x20);2080 2081		while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) {2082			if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0)2083				atp_writeb_io(dev, c, 0x19, wide[j++]);2084			cpu_relax();2085		}2086 2087		while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00)2088			cpu_relax();2089 2090		j = atp_readb_io(dev, c, 0x17) & 0x0f;2091		if (j == 0x0f) {2092			goto widep_in;2093		}2094		if (j == 0x0a) {2095			goto widep_cmd;2096		}2097		if (j == 0x0e) {2098			goto try_wide;2099		}2100		continue;2101widep_out:2102		atp_writeb_io(dev, c, 0x18, 0x20);2103		while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) {2104			if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0)2105				atp_writeb_io(dev, c, 0x19, 0);2106			cpu_relax();2107		}2108		j = atp_readb_io(dev, c, 0x17) & 0x0f;2109		if (j == 0x0f) {2110			goto widep_in;2111		}2112		if (j == 0x0a) {2113			goto widep_cmd;2114		}2115		if (j == 0x0e) {2116			goto widep_out;2117		}2118		continue;2119widep_in:2120		atp_writeb_io(dev, c, 0x14, 0xff);2121		atp_writeb_io(dev, c, 0x18, 0x20);2122		k = 0;2123widep_in1:2124		j = atp_readb_io(dev, c, 0x1f);2125		if ((j & 0x01) != 0) {2126			mbuf[k++] = atp_readb_io(dev, c, 0x19);2127			goto widep_in1;2128		}2129		if ((j & 0x80) == 0x00) {2130			goto widep_in1;2131		}2132		j = atp_readb_io(dev, c, 0x17) & 0x0f;2133		if (j == 0x0f) {2134			goto widep_in;2135		}2136		if (j == 0x0a) {2137			goto widep_cmd;2138		}2139		if (j == 0x0e) {2140			goto widep_out;2141		}2142		continue;2143widep_cmd:2144		atp_writeb_io(dev, c, 0x10, 0x30);2145		atp_writeb_io(dev, c, 0x14, 0x00);2146		atp_writeb_io(dev, c, 0x18, 0x08);2147 2148		while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)2149			cpu_relax();2150 2151		j = atp_readb_io(dev, c, 0x17);2152		if (j != 0x16) {2153			if (j == 0x4e) {2154				goto widep_out;2155			}2156			continue;2157		}2158		if (mbuf[0] != 0x01) {2159			goto not_wide;2160		}2161		if (mbuf[1] != 0x02) {2162			goto not_wide;2163		}2164		if (mbuf[2] != 0x03) {2165			goto not_wide;2166		}2167		if (mbuf[3] != 0x01) {2168			goto not_wide;2169		}2170		m = 1;2171		m = m << i;2172		dev->wide_id[c] |= m;2173not_wide:2174		if ((dev->id[c][i].devtype == 0x00) ||2175		    (dev->id[c][i].devtype == 0x07) ||2176		    ((dev->id[c][i].devtype == 0x05) && ((n & 0x10) != 0))) {2177			m = 1;2178			m = m << i;2179			if ((dev->async[c] & m) != 0) {2180				goto set_sync;2181			}2182		}2183		continue;2184set_sync:2185		if ((!is885(dev) && !is880(dev)) || (dev->sp[c][i] == 0x02)) {2186			synu[4] = 0x0c;2187			synuw[4] = 0x0c;2188		} else {2189			if (dev->sp[c][i] >= 0x03) {2190				synu[4] = 0x0a;2191				synuw[4] = 0x0a;2192			}2193		}2194		j = 0;2195		if ((m & dev->wide_id[c]) != 0) {2196			j |= 0x01;2197		}2198		atp_writeb_io(dev, c, 0x1b, j);2199		atp_writeb_io(dev, c, 3, satn[0]);2200		atp_writeb_io(dev, c, 4, satn[1]);2201		atp_writeb_io(dev, c, 5, satn[2]);2202		atp_writeb_io(dev, c, 6, satn[3]);2203		atp_writeb_io(dev, c, 7, satn[4]);2204		atp_writeb_io(dev, c, 8, satn[5]);2205		atp_writeb_io(dev, c, 0x0f, 0);2206		atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp);2207		atp_writeb_io(dev, c, 0x12, 0);2208		atp_writeb_io(dev, c, 0x13, satn[6]);2209		atp_writeb_io(dev, c, 0x14, satn[7]);2210		atp_writeb_io(dev, c, 0x18, satn[8]);2211 2212		while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)2213			cpu_relax();2214 2215		if (atp_readb_io(dev, c, 0x17) != 0x11 &&2216		    atp_readb_io(dev, c, 0x17) != 0x8e)2217			continue;2218 2219		while (atp_readb_io(dev, c, 0x17) != 0x8e)2220			cpu_relax();2221 2222try_sync:2223		j = 0;2224		atp_writeb_io(dev, c, 0x14, 0x06);2225		atp_writeb_io(dev, c, 0x18, 0x20);2226 2227		while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) {2228			if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) {2229				if ((m & dev->wide_id[c]) != 0) {2230					if (is885(dev) || is880(dev)) {2231						if ((m & dev->ultra_map[c]) != 0) {2232							atp_writeb_io(dev, c, 0x19, synuw[j++]);2233						} else {2234							atp_writeb_io(dev, c, 0x19, synw[j++]);2235						}2236					} else2237						atp_writeb_io(dev, c, 0x19, synw_870[j++]);2238				} else {2239					if ((m & dev->ultra_map[c]) != 0) {2240						atp_writeb_io(dev, c, 0x19, synu[j++]);2241					} else {2242						atp_writeb_io(dev, c, 0x19, synn[j++]);2243					}2244				}2245			}2246		}2247 2248		while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00)2249			cpu_relax();2250 2251		j = atp_readb_io(dev, c, 0x17) & 0x0f;2252		if (j == 0x0f) {2253			goto phase_ins;2254		}2255		if (j == 0x0a) {2256			goto phase_cmds;2257		}2258		if (j == 0x0e) {2259			goto try_sync;2260		}2261		continue;2262phase_outs:2263		atp_writeb_io(dev, c, 0x18, 0x20);2264		while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) {2265			if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0x00)2266				atp_writeb_io(dev, c, 0x19, 0x00);2267			cpu_relax();2268		}2269		j = atp_readb_io(dev, c, 0x17);2270		if (j == 0x85) {2271			goto tar_dcons;2272		}2273		j &= 0x0f;2274		if (j == 0x0f) {2275			goto phase_ins;2276		}2277		if (j == 0x0a) {2278			goto phase_cmds;2279		}2280		if (j == 0x0e) {2281			goto phase_outs;2282		}2283		continue;2284phase_ins:2285		if (is885(dev) || is880(dev))2286			atp_writeb_io(dev, c, 0x14, 0x06);2287		else2288			atp_writeb_io(dev, c, 0x14, 0xff);2289		atp_writeb_io(dev, c, 0x18, 0x20);2290		k = 0;2291phase_ins1:2292		j = atp_readb_io(dev, c, 0x1f);2293		if ((j & 0x01) != 0x00) {2294			mbuf[k++] = atp_readb_io(dev, c, 0x19);2295			goto phase_ins1;2296		}2297		if ((j & 0x80) == 0x00) {2298			goto phase_ins1;2299		}2300 2301		while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00);2302 2303		j = atp_readb_io(dev, c, 0x17);2304		if (j == 0x85) {2305			goto tar_dcons;2306		}2307		j &= 0x0f;2308		if (j == 0x0f) {2309			goto phase_ins;2310		}2311		if (j == 0x0a) {2312			goto phase_cmds;2313		}2314		if (j == 0x0e) {2315			goto phase_outs;2316		}2317		continue;2318phase_cmds:2319		atp_writeb_io(dev, c, 0x10, 0x30);2320tar_dcons:2321		atp_writeb_io(dev, c, 0x14, 0x00);2322		atp_writeb_io(dev, c, 0x18, 0x08);2323 2324		while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)2325			cpu_relax();2326 2327		j = atp_readb_io(dev, c, 0x17);2328		if (j != 0x16) {2329			continue;2330		}2331		if (mbuf[0] != 0x01) {2332			continue;2333		}2334		if (mbuf[1] != 0x03) {2335			continue;2336		}2337		if (mbuf[4] == 0x00) {2338			continue;2339		}2340		if (mbuf[3] > 0x64) {2341			continue;2342		}2343		if (is885(dev) || is880(dev)) {2344			if (mbuf[4] > 0x0e) {2345				mbuf[4] = 0x0e;2346			}2347		} else {2348			if (mbuf[4] > 0x0c) {2349				mbuf[4] = 0x0c;2350			}2351		}2352		dev->id[c][i].devsp = mbuf[4];2353		if (is885(dev) || is880(dev))2354			if (mbuf[3] < 0x0c) {2355				j = 0xb0;2356				goto set_syn_ok;2357			}2358		if ((mbuf[3] < 0x0d) && (rmb == 0)) {2359			j = 0xa0;2360			goto set_syn_ok;2361		}2362		if (mbuf[3] < 0x1a) {2363			j = 0x20;2364			goto set_syn_ok;2365		}2366		if (mbuf[3] < 0x33) {2367			j = 0x40;2368			goto set_syn_ok;2369		}2370		if (mbuf[3] < 0x4c) {2371			j = 0x50;2372			goto set_syn_ok;2373		}2374		j = 0x60;2375set_syn_ok:2376		dev->id[c][i].devsp = (dev->id[c][i].devsp & 0x0f) | j;2377#ifdef ED_DBGP2378		printk("dev->id[%2d][%2d].devsp = %2x\n",2379		       c,i,dev->id[c][i].devsp);2380#endif2381	}2382}2383