atp870u.c

来自「linux 内核源代码」· C语言 代码 · 共 2,946 行 · 第 1/5 页

C
2,946
字号
			if (dev->sp[0][i] >= 0x03) {				synu[4] = 0x0a;				synuw[4] = 0x0a;			}		}		tmport = wkport + 0x5b;		j = 0;		if ((m & dev->wide_id[0]) != 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[0][i].devsp, 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)			cpu_relax();		tmport -= 0x08;		if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {			continue;		}		while (inb(tmport) != 0x8e)			cpu_relax();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_id[0]) != 0) {					if ((m & dev->ultra_map[0]) != 0) {						outb(synuw[j++], tmport);					} else {						outb(synw[j++], tmport);					}				} else {					if ((m & dev->ultra_map[0]) != 0) {						outb(synu[j++], tmport);					} else {						outb(synn[j++], tmport);					}				}				tmport += 0x06;			}		}		tmport -= 0x08;		while ((inb(tmport) & 0x80) == 0x00)			cpu_relax();		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)			cpu_relax();		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)			cpu_relax();		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[0][i].devsp = 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[0][i].devsp = (dev->id[0][i].devsp & 0x0f) | j;	}}static void atp870u_free_tables(struct Scsi_Host *host){	struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata;	int j, k;	for (j=0; j < 2; j++) {		for (k = 0; k < 16; k++) {			if (!atp_dev->id[j][k].prd_table)				continue;			pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[j][k].prd_table, atp_dev->id[j][k].prd_bus);			atp_dev->id[j][k].prd_table = NULL;		}	}}static int atp870u_init_tables(struct Scsi_Host *host){	struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata;	int c,k;	for(c=0;c < 2;c++) {	   	for(k=0;k<16;k++) {	   			atp_dev->id[c][k].prd_table = pci_alloc_consistent(atp_dev->pdev, 1024, &(atp_dev->id[c][k].prd_bus));	   			if (!atp_dev->id[c][k].prd_table) {	   				printk("atp870u_init_tables fail\n");				atp870u_free_tables(host);				return -ENOMEM;			}			atp_dev->id[c][k].prdaddr = atp_dev->id[c][k].prd_bus;			atp_dev->id[c][k].devsp=0x20;			atp_dev->id[c][k].devtype = 0x7f;			atp_dev->id[c][k].curr_req = NULL;			   	   	}	   				   	atp_dev->active_id[c] = 0;	   	atp_dev->wide_id[c] = 0;	   	atp_dev->host_id[c] = 0x07;	   	atp_dev->quhd[c] = 0;	   	atp_dev->quend[c] = 0;	   	atp_dev->last_cmd[c] = 0xff;	   	atp_dev->in_snd[c] = 0;	   	atp_dev->in_int[c] = 0;	   		   	for (k = 0; k < qcnt; k++) {	   		  atp_dev->quereq[c][k] = NULL;	   	}	   		   	   	for (k = 0; k < 16; k++) {			   atp_dev->id[c][k].curr_req = NULL;			   atp_dev->sp[c][k] = 0x04;	   	}		   	}	return 0;}/* return non-zero on detection */static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent){	unsigned char k, m, c;	unsigned long flags;	unsigned int base_io, tmport, error,n;	unsigned char host_id;	struct Scsi_Host *shpnt = NULL;	struct atp_unit *atpdev, *p;	unsigned char setupdata[2][16];	int count = 0;	atpdev = kzalloc(sizeof(*atpdev), GFP_KERNEL);	if (!atpdev)		return -ENOMEM;	if (pci_enable_device(pdev))		goto err_eio;        if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {                printk(KERN_INFO "atp870u: use 32bit DMA mask.\n");        } else {                printk(KERN_ERR "atp870u: DMA mask required but not available.\n");		goto err_eio;        }	/*	 * It's probably easier to weed out some revisions like	 * this than via the PCI device table	 */	if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) {		error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atpdev->chip_ver);		if (atpdev->chip_ver < 2)			goto err_eio;	}	switch (ent->device) {	case PCI_DEVICE_ID_ARTOP_AEC7612UW:	case PCI_DEVICE_ID_ARTOP_AEC7612SUW:	case ATP880_DEVID1:		case ATP880_DEVID2:		case ATP885_DEVID:			atpdev->chip_ver = 0x04;	default:		break;	}	base_io = pci_resource_start(pdev, 0);	base_io &= 0xfffffff8;	if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) {		error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atpdev->chip_ver);		pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803		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", count, base_io, pdev->irq);		atpdev->ioport[0] = base_io + 0x40;		atpdev->pciport[0] = base_io + 0x28;		atpdev->dev_id = ent->device;		atpdev->host_id[0] = host_id;		tmport = base_io + 0x22;		atpdev->scam_on = inb(tmport);		tmport += 0x13;		atpdev->global_map[0] = inb(tmport);		tmport += 0x07;		atpdev->ultra_map[0] = inw(tmport);		n = 0x3f09;next_fblk_880:		if (n >= 0x4000)			goto flash_ok_880;		m = 0;		outw(n, base_io + 0x34);		n += 0x0002;		if (inb(base_io + 0x30) == 0xff)			goto flash_ok_880;		atpdev->sp[0][m++] = inb(base_io + 0x30);		atpdev->sp[0][m++] = inb(base_io + 0x31);		atpdev->sp[0][m++] = inb(base_io + 0x32);		atpdev->sp[0][m++] = inb(base_io + 0x33);		outw(n, base_io + 0x34);		n += 0x0002;		atpdev->sp[0][m++] = inb(base_io + 0x30);		atpdev->sp[0][m++] = inb(base_io + 0x31);		atpdev->sp[0][m++] = inb(base_io + 0x32);		atpdev->sp[0][m++] = inb(base_io + 0x33);		outw(n, base_io + 0x34);		n += 0x0002;		atpdev->sp[0][m++] = inb(base_io + 0x30);		atpdev->sp[0][m++] = inb(base_io + 0x31);		atpdev->sp[0][m++] = inb(base_io + 0x32);		atpdev->sp[0][m++] = inb(base_io + 0x33);		outw(n, base_io + 0x34);		n += 0x0002;		atpdev->sp[0][m++] = inb(base_io + 0x30);		atpdev->sp[0][m++] = inb(base_io + 0x31);		atpdev->sp[0][m++] = inb(base_io + 0x32);		atpdev->sp[0][m++] = inb(base_io + 0x33);		n += 0x0018;		goto next_fblk_880;flash_ok_880:		outw(0, base_io + 0x34);		atpdev->ultra_map[0] = 0;		atpdev->async[0] = 0;		for (k = 0; k < 16; k++) {			n = 1;			n = n << k;			if (atpdev->sp[0][k] > 1) {				atpdev->ultra_map[0] |= n;			} else {				if (atpdev->sp[0][k] == 0)					atpdev->async[0] |= n; 			}	 	}		atpdev->async[0] = ~(atpdev->async[0]);		outb(atpdev->global_map[0], base_io + 0x35); 		shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));		if (!shpnt)			goto err_nomem;		p = (struct atp_unit *)&shpnt->hostdata;		atpdev->host = shpnt;		atpdev->pdev = pdev;		pci_set_drvdata(pdev, p);		memcpy(p, atpdev, sizeof(*atpdev));		if (atp870u_init_tables(shpnt) < 0) {			printk(KERN_ERR "Unable to allocate tables for Acard controller\n");			goto unregister;		}		if (request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp880i", shpnt)) { 			printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", pdev->irq);			goto free_tables;		}		spin_lock_irqsave(shpnt->host_lock, flags);		tmport = base_io + 0x38;		k = inb(tmport) & 0x80;		outb(k, tmport);		tmport += 0x03;		outb(0x20, tmport);		mdelay(32);		outb(0, tmport);		mdelay(32);		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)			mdelay(1);		tmport -= 0x08;		inb(tmport);		tmport = base_io + 0x41;		outb(8, tmport++);		outb(0x7f, tmport);		tmport = base_io + 0x51;		outb(0x20, tmport);		tscam(shpnt);		is880(p, base_io);		tmport = base_io + 0x38;		outb(0xb0, tmport);		shpnt->max_id = 16;		shpnt->this_id = host_id;		shpnt->unique_id = base_io;		shpnt->io_port = base_io;		shpnt->n_io_port = 0x60;	/* Number of bytes of I/O space used */		shpnt->irq = pdev->irq;				} else if (ent->device == ATP885_DEVID) {				printk(KERN_INFO "   ACARD AEC-67162 PCI Ultra3 LVD Host Adapter:  IO:%x, IRQ:%d.\n"			       , base_io, pdev->irq);        			atpdev->pdev = pdev;		atpdev->dev_id  = ent->device;		atpdev->baseport = base_io;		atpdev->ioport[0] = base_io + 0x80;		atpdev->ioport[1] = base_io + 0xc0;		atpdev->pciport[0] = base_io + 0x40;		atpdev->pciport[1] = base_io + 0x50;						shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));		if (!shpnt)			goto err_nomem;        			p = (struct atp_unit *)&shpnt->hostdata;        			atpdev->host = shpnt;		atpdev->pdev = pdev;		pci_set_drvdata(pdev, p);		memcpy(p, atpdev, sizeof(struct atp_unit));		if (atp870u_init_tables(shpnt) < 0)			goto unregister;			#ifdef ED_DBGP			printk("request_irq() shpnt %p hostdata %p\n", shpnt, p);#endif	        		if (request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp870u", shpnt)) {				printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n");			goto free_tables;		}				spin_lock_irqsave(shpnt->host_lock, flags);        					        					c=inb(base_io + 0x29);		outb((c | 0x04),base_io + 0x29);        			n=0x1f80;next_fblk_885:		if (n >= 0x2000) {		   goto flash_ok_885;		}		outw(n,base_io + 0x3c);		if (inl(base_io + 0x38) == 0xffffffff) {		   goto flash_ok_885;		}		for (m=0; m < 2; m++) {		    p->global_map[m]= 0;		    for (k=0; k < 4; k++) {			outw(n++,base_io + 0x3c);			((unsigned long *)&setupdata[m][0])[k]=inl(base_io + 0x38);		    }		    for (k=0; k < 4; k++) {			outw(n++,base_io + 0x3c);			((unsigned long *)&p->sp[m][0])[k]=inl(base_io + 0x38);		    }		    n += 8;		}		goto next_fblk_885;flash_ok_885:#ifdef ED_DBGP		printk( "Flash Read OK\n");#endif			c=inb(base_io + 0x29);		outb((c & 0xfb),base_io + 0x29);		for (c=0;c < 2;c++) {		    p->ultra_map[c]=0;		    p->async[c] = 0;		    for (k=0; k < 16; k++) {			n=1;			n = n << k;			if (p->sp[c][k] > 1) {			   p->ultra_map[c] |= n;			} else {			   if (p->sp[c][k] == 0) {			      p->async[c] |= n;			   }			}		    }		    p->async[c] = ~(p->async[c]);		    if (p->global_map[c] == 0) {		       k=setupdata[c][1];		       if ((k & 0x40) != 0)			  p->global_map[c] |= 0x20;		       k &= 0x07;		       p->global_map[c] |= k;		       if ((setupdata[c][2] & 0x04) != 0)			  p->global_map[c] |= 0x08;		       p->host_id[c] = setupdata[c][0] & 0x07;		    }		}		k = inb(base_io + 0x28) & 0x8f;		k |= 0x10;		outb(k, base_io + 0x28);		outb(0x80, base_io + 0x41);		outb(0x80, base_io + 0x51);		mdelay(100);		outb(0, base_io + 0x41);		outb(0, base_io + 0x51);		mdelay(1000);		inb(base_io + 0x9b);		inb(base_io + 0x97);		inb(base_io + 0xdb);		inb(base_io + 0xd7);		tmport = base_io + 0x80;		k=p->host_id[0];		if (k > 7)		   k = (k & 0x07) | 0x40;		k |= 0x08;		outb(k, tmport);		tmport += 0x18;		outb(0, tmport);		tmport += 0x07;		while ((inb(tmport) & 0x80) == 0)			cpu_relax();			tmport -= 0x08;		inb(tmport);		tmport = base_io + 0x81;		outb(8, tmport++);		outb(0x7f, tmport);		tmport = base_io + 0x91;		outb(0x20, tmport);		tmport = base_io + 0xc0;		k=p->host_id[1];		if (k > 7)		   k = (k & 0x07) | 0x40;		k |= 0x08;		outb(k, tmport);		tmport += 0x18;		outb(0, tmport);		tmport += 0x07;		while ((inb(tmport) & 0x80) == 0)			cpu_relax();		tmport -= 0x08;		inb(tmport);		tmport = base_io + 0xc1;		outb(8, tmport++);		outb(0x7f, tmport);		tmport = base_io + 

⌨️ 快捷键说明

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