⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atp870u.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 4 页
字号:
	outb(workrequ->cmd_len, tmport++);	outb(0x2c, tmport++);	outb(0xcf, tmport++);	for (i = 0; i < workrequ->cmd_len; i++) {		outb(dev->ata_cdbu[i], tmport++);	}	tmport = workportu + 0x0f;	outb(workrequ->lun, tmport);	tmport += 0x02;	/*	 *	Write the target	 */	outb(dev->id[target_id].devspu, tmport++);	/*	 *	Figure out the transfer size	 */	if (workrequ->use_sg)	{		l = 0;		sgpnt = (struct scatterlist *) workrequ->request_buffer;		for (i = 0; i < workrequ->use_sg; i++)		{			if (sgpnt[i].length == 0 || workrequ->use_sg > ATP870U_SCATTER)			{				panic("Foooooooood fight!");			}			l += sgpnt[i].length;		}	} else {		l = workrequ->request_bufflen;	}	/*	 *	Write transfer size	 */	outb((unsigned char) (((unsigned char *) (&l))[2]), tmport++);	outb((unsigned char) (((unsigned char *) (&l))[1]), tmport++);	outb((unsigned char) (((unsigned char *) (&l))[0]), tmport++);	j = target_id;	dev->id[j].last_lenu = l;	dev->id[j].tran_lenu = 0;	/*	 *	Flip the wide bits	 */	if ((j & 0x08) != 0) {		j = (j & 0x07) | 0x40;	}	/*	 *	Check transfer direction	 */	if ((dev->ata_cdbu[0] == WRITE_6) || (dev->ata_cdbu[0] == WRITE_10) ||	    (dev->ata_cdbu[0] == WRITE_12) || (dev->ata_cdbu[0] == MODE_SELECT)) {		outb((unsigned char) (j | 0x20), tmport++);	} else {		outb(j, tmport++);	}	outb((unsigned char)(inb(tmport) | 0x80),tmport);	outb(0x80, tmport);	tmport = workportu + 0x1c;	dev->id[target_id].dirctu = 0;	if (l == 0) {		if (inb(tmport) == 0) {			tmport = workportu + 0x18;			outb(0x08, tmport);		} else {			dev->last_cmd |= 0x40;		}		dev->in_snd = 0;		restore_flags(flags);		return;	}	tmpcip = dev->pciport;	prd = dev->id[target_id].prd_tableu;	dev->id[target_id].prd_posu = prd;	/*	 *	Now write the request list. Either as scatter/gather or as	 *	a linear chain.	 */	if (workrequ->use_sg)	{		sgpnt = (struct scatterlist *) workrequ->request_buffer;		i = 0;		for (j = 0; j < workrequ->use_sg; j++) {			(unsigned long) (((unsigned long *) (prd))[i >> 1]) = virt_to_bus(sgpnt[j].address);			(unsigned short int) (((unsigned short int *) (prd))[i + 2]) = sgpnt[j].length;			(unsigned short int) (((unsigned short int *) (prd))[i + 3]) = 0;			i += 0x04;		}		(unsigned short int) (((unsigned short int *) (prd))[i - 1]) = 0x8000;	} else {		/*		 *	For a linear request write a chain of blocks		 */		bttl = virt_to_bus(workrequ->request_buffer);		l = workrequ->request_bufflen;		i = 0;		while (l > 0x10000) {			(unsigned short int) (((unsigned short int *) (prd))[i + 3]) = 0x0000;			(unsigned short int) (((unsigned short int *) (prd))[i + 2]) = 0x0000;			(unsigned long) (((unsigned long *) (prd))[i >> 1]) = bttl;			l -= 0x10000;			bttl += 0x10000;			i += 0x04;		}		(unsigned short int) (((unsigned short int *) (prd))[i + 3]) = 0x8000;		(unsigned short int) (((unsigned short int *) (prd))[i + 2]) = l;		(unsigned long) (((unsigned long *) (prd))[i >> 1]) = bttl;	}	tmpcip = tmpcip + 4;	dev->id[target_id].prdaddru = virt_to_bus(dev->id[target_id].prd_tableu);	outl(dev->id[target_id].prdaddru, tmpcip);	tmpcip = tmpcip - 2;	outb(0x06, tmpcip);	outb(0x00, tmpcip);	tmpcip = tmpcip - 2;	if (dev->deviceid != 0x8081)	{	   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	{	   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;	if ((dev->ata_cdbu[0] == WRITE_6) || (dev->ata_cdbu[0] == WRITE_10) ||	    (dev->ata_cdbu[0] == WRITE_12) || (dev->ata_cdbu[0] == MODE_SELECT))	{		dev->id[target_id].dirctu = 0x20;		if (inb(tmport) == 0) {			tmport = workportu + 0x18;			outb(0x08, tmport);			outb(0x01, tmpcip);		} else {			dev->last_cmd |= 0x40;		}		dev->in_snd = 0;		restore_flags(flags);		return;	}	if (inb(tmport) == 0)	{		tmport = workportu + 0x18;		outb(0x08, tmport);		outb(0x09, tmpcip);	} else {		dev->last_cmd |= 0x40;	}	dev->in_snd = 0;	restore_flags(flags);	return;}static void internal_done(Scsi_Cmnd * SCpnt){	SCpnt->SCp.Status++;}int atp870u_command(Scsi_Cmnd * SCpnt){	atp870u_queuecommand(SCpnt, internal_done);	SCpnt->SCp.Status = 0;	while (!SCpnt->SCp.Status)		barrier();	return SCpnt->result;}unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val){	unsigned int tmport;	unsigned short int i, k;	unsigned char j;	tmport = dev->ioport + 0x1c;	outw(*val, tmport);FUN_D7:	for (i = 0; i < 10; i++) {	/* stable >= bus settle delay(400 ns)  */		k = inw(tmport);		j = (unsigned char) (k >> 8);		if ((k & 0x8000) != 0) {	/* DB7 all release?    */			goto FUN_D7;		}	}	*val |= 0x4000; 	/* assert DB6		*/	outw(*val, tmport);	*val &= 0xdfff; 	/* assert DB5		*/	outw(*val, tmport);FUN_D5:	for (i = 0; i < 10; i++) {	/* stable >= bus settle delay(400 ns) */		if ((inw(tmport) & 0x2000) != 0) {	/* DB5 all release?	  */			goto FUN_D5;		}	}	*val |= 0x8000; 	/* no DB4-0, assert DB7    */	*val &= 0xe0ff;	outw(*val, tmport);	*val &= 0xbfff; 	/* release DB6		   */	outw(*val, tmport);      FUN_D6:	for (i = 0; i < 10; i++) {	/* stable >= bus settle delay(400 ns)  */		if ((inw(tmport) & 0x4000) != 0) {	/* DB6 all release?  */			goto FUN_D6;		}	}	return j;}void tscam(unsigned char host){	unsigned int tmport;	unsigned char i, j, k;	unsigned long n;	unsigned short int m, assignid_map, val;	unsigned char mbuf[33], quintet[2];	struct atp_unit *dev = &atp_unit[host];	static unsigned char g2q_tab[8] = {		0x38, 0x31, 0x32, 0x2b, 0x34, 0x2d, 0x2e, 0x27	};	for (i = 0; i < 0x10; i++) {		mydlyu(0xffff);	}	tmport = dev->ioport + 1;	outb(0x08, tmport++);	outb(0x7f, tmport);	tmport = dev->ioport + 0x11;	outb(0x20, tmport);	if ((dev->scam_on & 0x40) == 0) {		return;	}	m = 1;	m <<= dev->host_idu;	j = 16;	if (dev->chip_veru < 4) {		m |= 0xff00;		j = 8;	}	assignid_map = m;	tmport = dev->ioport + 0x02;	outb(0x02, tmport++);	/* 2*2=4ms,3EH 2/32*3E=3.9ms */	outb(0, tmport++);	outb(0, tmport++);	outb(0, tmport++);	outb(0, tmport++);	outb(0, tmport++);	outb(0, tmport++);	for (i = 0; i < j; i++) {		m = 1;		m = m << i;		if ((m & assignid_map) != 0) {			continue;		}		tmport = dev->ioport + 0x0f;		outb(0, tmport++);		tmport += 0x02;		outb(0, tmport++);		outb(0, tmport++);		outb(0, tmport++);		if (i > 7) {			k = (i & 0x07) | 0x40;		} else {			k = i;		}		outb(k, tmport++);		tmport = dev->ioport + 0x1b;		if (dev->chip_veru == 4) {			outb(0x01, tmport);		} else {			outb(0x00, tmport);		}wait_rdyok:		tmport = dev->ioport + 0x18;		outb(0x09, tmport);		tmport += 0x07;		while ((inb(tmport) & 0x80) == 0x00);		tmport -= 0x08;		k = inb(tmport);		if (k != 0x16) {			if ((k == 0x85) || (k == 0x42)) {				continue;			}			tmport = dev->ioport + 0x10;			outb(0x41, tmport);			goto wait_rdyok;		}		assignid_map |= m;	}	tmport = dev->ioport + 0x02;	outb(0x7f, tmport);	tmport = dev->ioport + 0x1b;	outb(0x02, tmport);	outb(0, 0x80);	val = 0x0080;		/* bsy	*/	tmport = dev->ioport + 0x1c;	outw(val, tmport);	val |= 0x0040;		/* sel	*/	outw(val, tmport);	val |= 0x0004;		/* msg	*/	outw(val, tmport);	inb(0x80);		/* 2 deskew delay(45ns*2=90ns) */	val &= 0x007f;		/* no bsy  */	outw(val, tmport);	mydlyu(0xffff); 	/* recommanded SCAM selection response time */	mydlyu(0xffff);	val &= 0x00fb;		/* after 1ms no msg */	outw(val, tmport);wait_nomsg:	if ((inb(tmport) & 0x04) != 0) {		goto wait_nomsg;	}	outb(1, 0x80);	mydlyu(100);	for (n = 0; n < 0x30000; n++) {		if ((inb(tmport) & 0x80) != 0) {	/* bsy ? */			goto wait_io;		}	}	goto TCM_SYNC;wait_io:	for (n = 0; n < 0x30000; n++) {		if ((inb(tmport) & 0x81) == 0x0081) {			goto wait_io1;		}	}	goto TCM_SYNC;wait_io1:	inb(0x80);	val |= 0x8003;		/* io,cd,db7  */	outw(val, tmport);	inb(0x80);	val &= 0x00bf;		/* no sel     */	outw(val, tmport);	outb(2, 0x80);TCM_SYNC:	mydlyu(0x800);	if ((inb(tmport) & 0x80) == 0x00) {	/* bsy ? */		outw(0, tmport--);		outb(0, tmport);		tmport = dev->ioport + 0x15;		outb(0, tmport);		tmport += 0x03;		outb(0x09, tmport);		tmport += 0x07;		while ((inb(tmport) & 0x80) == 0);		tmport -= 0x08;		inb(tmport);		return;	}	val &= 0x00ff;		/* synchronization  */	val |= 0x3f00;	fun_scam(dev, &val);	outb(3, 0x80);	val &= 0x00ff;		/* isolation	    */	val |= 0x2000;	fun_scam(dev, &val);	outb(4, 0x80);	i = 8;	j = 0;TCM_ID:	if ((inw(tmport) & 0x2000) == 0) {		goto TCM_ID;	}	outb(5, 0x80);	val &= 0x00ff;		/* get ID_STRING */	val |= 0x2000;	k = fun_scam(dev, &val);	if ((k & 0x03) == 0) {		goto TCM_5;	}	mbuf[j] <<= 0x01;	mbuf[j] &= 0xfe;	if ((k & 0x02) != 0) {		mbuf[j] |= 0x01;	}	i--;	if (i > 0) {		goto TCM_ID;	}	j++;	i = 8;	goto TCM_ID;TCM_5:			/* isolation complete..  *//*    mbuf[32]=0;	printk(" \n%x %x %x %s\n ",assignid_map,mbuf[0],mbuf[1],&mbuf[2]); */	i = 15;	j = mbuf[0];	if ((j & 0x20) != 0) {	/* bit5=1:ID upto 7	 */		i = 7;	}	if ((j & 0x06) == 0) {	/* IDvalid?		*/		goto G2Q5;	}	k = mbuf[1];small_id:	m = 1;	m <<= k;	if ((m & assignid_map) == 0) {		goto G2Q_QUIN;	}	if (k > 0) {		k--;		goto small_id;	}G2Q5:				/* srch from max acceptable ID#  */	k = i;			/* max acceptable ID#		 */G2Q_LP:	m = 1;	m <<= k;	if ((m & assignid_map) == 0) {		goto G2Q_QUIN;	}	if (k > 0) {		k--;		goto G2Q_LP;	}G2Q_QUIN:		/* k=binID#,	   */	assignid_map |= m;	if (k < 8) {		quintet[0] = 0x38;	/* 1st dft ID<8    */	} else {		quintet[0] = 0x31;	/* 1st	ID>=8	   */	}	k &= 0x07;	quintet[1] = g2q_tab[k];	val &= 0x00ff;		/* AssignID 1stQuintet,AH=001xxxxx  */	m = quintet[0] << 8;	val |= m;	fun_scam(dev, &val);	val &= 0x00ff;		/* AssignID 2ndQuintet,AH=001xxxxx */	m = quintet[1] << 8;	val |= m;	fun_scam(dev, &val);	goto TCM_SYNC;}void is870(unsigned long host, unsigned int wkport){	unsigned int tmport;	unsigned char i, j, k, rmb, n;	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, 0x0c, 0x0e};	static unsigned char synw[6] =	{0x80, 1, 3, 1, 0x0c, 0x07};	static unsigned char wide[6] =	{0x80, 1, 2, 3, 1, 0};	struct atp_unit *dev = &atp_unit[host];	sync_idu = 0;	tmport = wkport + 0x3a;	outb((unsigned char) (inb(tmport) | 0x10), tmport);	for (i = 0; i < 16; i++) {		if ((dev->chip_veru != 4) && (i > 7)) {			break;		}		m = 1;		m = m << i;		if ((m & dev->active_idu) != 0) {			continue;		}		if (i == dev->host_idu) {			printk(KERN_INFO "         ID: %2d  Host Adapter\n", dev->host_idu);			continue;		}		tmport = wkport + 0x1b;		if (dev->chip_veru == 4) {		   outb(0x01, tmport);		}		else		{		   outb(0x00, tmport);		}		tmport = wkport + 1;		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;		while ((inb(tmport) & 0x80) == 0x00);		tmport -= 0x08;		if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {			continue;		}		while (inb(tmport) != 0x8e);		dev->active_idu |= m;		tmport = wkport + 0x10;		outb(0x30, tmport);		tmport = wkport + 0x04;		outb(0x00, tmport);phase_cmd:		tmport = wkport + 0x18;		outb(0x08, tmport);		tmport += 0x07;		while ((inb(tmport) & 0x80) == 0x00);		tmport -= 0x08;		j = inb(tmport);		if (j != 0x16) {			tmport = wkport + 0x10;			outb(0x41, tmport);			goto phase_cmd;		}sel_ok:		tmport = wkport + 3;		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;		}		while (inb(tmport) != 0x8e);		tmport = wkport + 0x1b;		if (dev->chip_veru == 4) {			outb(0x00, tmport);		}		tmport = wkport + 0x18;		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;		}		if ((k & 0x80) == 0) {			goto rd_inq_data;		}		tmport -= 0x08;		j = inb(tmport);		if (j == 0x16) {			goto inq_ok;		}		tmport = wkport + 0x10;		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) == 0x00);		tmport -= 0x08;		if (inb(tmport) != 0x16) {			goto sel_ok;		}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 (dev->chip_veru != 4) {			goto not_wide;		}		if ((mbuf[7] & 0x60) == 0) {			goto not_wide;		}		if ((dev->global_map & 0x20) == 0) {			goto not_wide;		}		tmport = wkport + 0x1b;		outb(0x01, tmport);		tmport = wkport + 3;		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 + 0x14;		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 + 0x18;		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 + 0x14;		outb(0xff, tmport);		tmport += 0x04;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -