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 + -
显示快捷键?