📄 ibmtr.c
字号:
/* Query the adapter PIO base port which will return * indication of where MMIO was placed. We also have a * coded interrupt number. */ segment = inb(PIOaddr); if (segment < 0x40 || segment > 0xe0) { /* Out of range values so we'll assume non-existent IO device * but this is not necessarily a problem, esp if a turbo * adapter is being used. */#if IBMTR_DEBUG_MESSAGES DPRINTK("ibmtr_probe1(): unhappy that inb(0x%X) == 0x%X, " "Hardware Problem?\n",PIOaddr,segment);#endif return -ENODEV; } /* * Compute the linear base address of the MMIO area * as LINUX doesn't care about segments */ t_mmio = ioremap(((__u32) (segment & 0xfc) << 11) + 0x80000,2048); if (!t_mmio) { DPRINTK("Cannot remap mmiobase memory area") ; return -ENODEV ; } intr = segment & 0x03; /* low bits is coded interrupt # */ if (ibmtr_debug_trace & TRC_INIT) DPRINTK("PIOaddr: %4hx seg/intr: %2x mmio base: %p intr: %d\n" , PIOaddr, (int) segment, t_mmio, (int) intr); /* * Now we will compare expected 'channelid' strings with * what we is there to learn of ISA/MCA or not TR card */#ifdef PCMCIA iounmap(t_mmio); t_mmio = ti->mmio; /*BMS to get virtual address */ irq = ti->irq; /*BMS to display the irq! */#endif cd_chanid = (CHANNEL_ID + t_mmio); /* for efficiency */ tchanid = pcchannelid; cardpresent = TR_ISA; /* try ISA */ /* Suboptimize knowing first byte different */ ctemp = readb(cd_chanid) & 0x0f; if (ctemp != *tchanid) { /* NOT ISA card, try MCA */ tchanid = mcchannelid; cardpresent = TR_MCA; if (ctemp != *tchanid) /* Neither ISA nor MCA */ cardpresent = NOTOK; } if (cardpresent != NOTOK) { /* Know presumed type, try rest of ID */ for (i = 2, j = 1; i <= 46; i = i + 2, j++) { if( (readb(cd_chanid+i)&0x0f) == tchanid[j]) continue; /* match failed, not TR card */ cardpresent = NOTOK; break; } } /* * If we have an ISA board check for the ISA P&P version, * as it has different IRQ settings */ if (cardpresent == TR_ISA && (readb(AIPFID + t_mmio) == 0x0e)) cardpresent = TR_ISAPNP; if (cardpresent == NOTOK) { /* "channel_id" did not match, report */ if (!(ibmtr_debug_trace & TRC_INIT)) {#ifndef PCMCIA iounmap(t_mmio);#endif return -ENODEV; } DPRINTK( "Channel ID string not found for PIOaddr: %4hx\n", PIOaddr); DPRINTK("Expected for ISA: "); PrtChanID(pcchannelid, 1); DPRINTK(" found: ");/* BMS Note that this can be misleading, when hardware is flaky, because you are reading it a second time here. So with my flaky hardware, I'll see my- self in this block, with the HW ID matching the ISA ID exactly! */ HWPrtChanID(cd_chanid, 2); DPRINTK("Expected for MCA: "); PrtChanID(mcchannelid, 1); } /* Now, setup some of the pl0 buffers for this driver.. */ /* If called from PCMCIA, it is already set up, so no need to waste the memory, just use the existing structure */#ifndef PCMCIA ti->mmio = t_mmio; for (i = 0; i < IBMTR_MAX_ADAPTERS; i++) { if (turbo_io[i] != PIOaddr) continue;#if IBMTR_DEBUG_MESSAGES printk("ibmtr::tr_probe1, setting PIOaddr %x to Turbo\n", PIOaddr);#endif ti->turbo = 1; t_irq = turbo_irq[i]; }#endif /* !PCMCIA */ ti->readlog_pending = 0; init_waitqueue_head(&ti->wait_for_reset); /* if PCMCIA, the card can be recognized as either TR_ISA or TR_ISAPNP * depending which card is inserted. */ #ifndef PCMCIA switch (cardpresent) { case TR_ISA: if (intr == 0) irq = 9; /* irq2 really is irq9 */ if (intr == 1) irq = 3; if (intr == 2) irq = 6; if (intr == 3) irq = 7; ti->adapter_int_enable = PIOaddr + ADAPTINTREL; break; case TR_MCA: if (intr == 0) irq = 9; if (intr == 1) irq = 3; if (intr == 2) irq = 10; if (intr == 3) irq = 11; ti->global_int_enable = 0; ti->adapter_int_enable = 0; ti->sram_phys=(__u32)(inb(PIOaddr+ADAPTRESETREL) & 0xfe) << 12; break; case TR_ISAPNP: if (!t_irq) { if (intr == 0) irq = 9; if (intr == 1) irq = 3; if (intr == 2) irq = 10; if (intr == 3) irq = 11; } else irq=t_irq; timeout = jiffies + TR_SPIN_INTERVAL; while (!readb(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)){ if (!time_after(jiffies, timeout)) continue; DPRINTK( "Hardware timeout during initialization.\n"); iounmap(t_mmio); return -ENODEV; } ti->sram_phys = ((__u32)readb(ti->mmio+ACA_OFFSET+ACA_RW+RRR_EVEN)<<12); ti->adapter_int_enable = PIOaddr + ADAPTINTREL; break; } /*end switch (cardpresent) */#endif /*not PCMCIA */ if (ibmtr_debug_trace & TRC_INIT) { /* just report int */ DPRINTK("irq=%d", irq); printk(", sram_phys=0x%x", ti->sram_phys); if(ibmtr_debug_trace&TRC_INITV){ /* full chat in verbose only */ DPRINTK(", ti->mmio=%p", ti->mmio); printk(", segment=%02X", segment); } printk(".\n"); } /* Get hw address of token ring card */ j = 0; for (i = 0; i < 0x18; i = i + 2) { /* technical reference states to do this */ temp = readb(ti->mmio + AIP + i) & 0x0f; ti->hw_address[j] = temp; if (j & 1) dev->dev_addr[(j / 2)] = ti->hw_address[j]+ (ti->hw_address[j - 1] << 4); ++j; } /* get Adapter type: 'F' = Adapter/A, 'E' = 16/4 Adapter II,... */ ti->adapter_type = readb(ti->mmio + AIPADAPTYPE); /* get Data Rate: F=4Mb, E=16Mb, D=4Mb & 16Mb ?? */ ti->data_rate = readb(ti->mmio + AIPDATARATE); /* Get Early Token Release support?: F=no, E=4Mb, D=16Mb, C=4&16Mb */ ti->token_release = readb(ti->mmio + AIPEARLYTOKEN); /* How much shared RAM is on adapter ? */ if (ti->turbo) { ti->avail_shared_ram=127; } else { ti->avail_shared_ram = get_sram_size(ti);/*in 512 byte units */ } /* We need to set or do a bunch of work here based on previous results*/ /* Support paging? What sizes?: F=no, E=16k, D=32k, C=16 & 32k */ ti->shared_ram_paging = readb(ti->mmio + AIPSHRAMPAGE); /* Available DHB 4Mb size: F=2048, E=4096, D=4464 */ switch (readb(ti->mmio + AIP4MBDHB)) { case 0xe: ti->dhb_size4mb = 4096; break; case 0xd: ti->dhb_size4mb = 4464; break; default: ti->dhb_size4mb = 2048; break; } /* Available DHB 16Mb size: F=2048, E=4096, D=8192, C=16384, B=17960 */ switch (readb(ti->mmio + AIP16MBDHB)) { case 0xe: ti->dhb_size16mb = 4096; break; case 0xd: ti->dhb_size16mb = 8192; break; case 0xc: ti->dhb_size16mb = 16384; break; case 0xb: ti->dhb_size16mb = 17960; break; default: ti->dhb_size16mb = 2048; break; } /* We must figure out how much shared memory space this adapter * will occupy so that if there are two adapters we can fit both * in. Given a choice, we will limit this adapter to 32K. The * maximum space will will use for two adapters is 64K so if the * adapter we are working on demands 64K (it also doesn't support * paging), then only one adapter can be supported. */ /* * determine how much of total RAM is mapped into PC space */ ti->mapped_ram_size= /*sixteen to onehundredtwentyeight 512byte blocks*/ 1<< ((readb(ti->mmio+ACA_OFFSET+ACA_RW+RRR_ODD) >> 2 & 0x03) + 4); ti->page_mask = 0; if (ti->turbo) ti->page_mask=0xf0; else if (ti->shared_ram_paging == 0xf); /* No paging in adapter */ else {#ifdef ENABLE_PAGING unsigned char pg_size = 0; /* BMS: page size: PCMCIA, use configuration register; ISAPNP, use LANAIDC config tool from www.ibm.com */ switch (ti->shared_ram_paging) { case 0xf: break; case 0xe: ti->page_mask = (ti->mapped_ram_size == 32) ? 0xc0 : 0; pg_size = 32; /* 16KB page size */ break; case 0xd: ti->page_mask = (ti->mapped_ram_size == 64) ? 0x80 : 0; pg_size = 64; /* 32KB page size */ break; case 0xc: switch (ti->mapped_ram_size) { case 32: ti->page_mask = 0xc0; pg_size = 32; break; case 64: ti->page_mask = 0x80; pg_size = 64; break; } break; default: DPRINTK("Unknown shared ram paging info %01X\n", ti->shared_ram_paging); iounmap(t_mmio); return -ENODEV; break; } /*end switch shared_ram_paging */ if (ibmtr_debug_trace & TRC_INIT) DPRINTK("Shared RAM paging code: %02X, " "mapped RAM size: %dK, shared RAM size: %dK, " "page mask: %02X\n:", ti->shared_ram_paging, ti->mapped_ram_size / 2, ti->avail_shared_ram / 2, ti->page_mask);#endif /*ENABLE_PAGING */ }#ifndef PCMCIA /* finish figuring the shared RAM address */ if (cardpresent == TR_ISA) { static __u32 ram_bndry_mask[] = { 0xffffe000, 0xffffc000, 0xffff8000, 0xffff0000 }; __u32 new_base, rrr_32, chk_base, rbm; rrr_32=readb(ti->mmio+ACA_OFFSET+ACA_RW+RRR_ODD) >> 2 & 0x03; rbm = ram_bndry_mask[rrr_32]; new_base = (ibmtr_mem_base + (~rbm)) & rbm;/* up to boundary */ chk_base = new_base + (ti->mapped_ram_size << 9); if (chk_base > (ibmtr_mem_base + IBMTR_SHARED_RAM_SIZE)) { DPRINTK("Shared RAM for this adapter (%05x) exceeds " "driver limit (%05x), adapter not started.\n", chk_base, ibmtr_mem_base + IBMTR_SHARED_RAM_SIZE); iounmap(t_mmio); return -ENODEV; } else { /* seems cool, record what we have figured out */ ti->sram_base = new_base >> 12; ibmtr_mem_base = chk_base; } } else ti->sram_base = ti->sram_phys >> 12; /* The PCMCIA has already got the interrupt line and the io port, so no chance of anybody else getting it - MLP */ if (request_irq(dev->irq = irq, &tok_interrupt, 0, "ibmtr", dev) != 0) { DPRINTK("Could not grab irq %d. Halting Token Ring driver.\n", irq); iounmap(t_mmio); return -ENODEV; } /*?? Now, allocate some of the PIO PORTs for this driver.. */ /* record PIOaddr range as busy */ if (!request_region(PIOaddr, IBMTR_IO_EXTENT, "ibmtr")) { DPRINTK("Could not grab PIO range. Halting driver.\n"); free_irq(dev->irq, dev); iounmap(t_mmio); return -EBUSY; } if (!version_printed++) { printk(version); }#endif /* !PCMCIA */ DPRINTK("%s %s found\n", channel_def[cardpresent - 1], adapter_def(ti->adapter_type)); DPRINTK("using irq %d, PIOaddr %hx, %dK shared RAM.\n", irq, PIOaddr, ti->mapped_ram_size / 2); DPRINTK("Hardware address : %02X:%02X:%02X:%02X:%02X:%02X\n", dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); if (ti->page_mask) DPRINTK("Shared RAM paging enabled. " "Page size: %uK Shared Ram size %dK\n", ((ti->page_mask^0xff)+1) >>2, ti->avail_shared_ram / 2); else DPRINTK("Shared RAM paging disabled. ti->page_mask %x\n", ti->page_mask); /* Calculate the maximum DHB we can use */ /* two cases where avail_shared_ram doesn't equal mapped_ram_size: 1. avail_shared_ram is 127 but mapped_ram_size is 128 (typical) 2. user has configured adapter for less than avail_shared_ram but is not using paging (she should use paging, I believe) */ if (!ti->page_mask) { ti->avail_shared_ram= min(ti->mapped_ram_size,ti->avail_shared_ram); } switch (ti->avail_shared_ram) { case 16: /* 8KB shared RAM */ ti->dhb_size4mb = min(ti->dhb_size4mb, (unsigned short)2048); ti->rbuf_len4 = 1032; ti->rbuf_cnt4=2; ti->dhb_size16mb = min(ti->dhb_size16mb, (unsigned short)2048); ti->rbuf_len16 = 1032; ti->rbuf_cnt16=2; break; case 32: /* 16KB shared RAM */ ti->dhb_size4mb = min(ti->dhb_size4mb, (unsigned short)4464); ti->rbuf_len4 = 1032; ti->rbuf_cnt4=4; ti->dhb_size16mb = min(ti->dhb_size16mb, (unsigned short)4096); ti->rbuf_len16 = 1032; /*1024 usable */ ti->rbuf_cnt16=4; break; case 64: /* 32KB shared RAM */ ti->dhb_size4mb = min(ti->dhb_size4mb, (unsigned short)4464); ti->rbuf_len4 = 1032; ti->rbuf_cnt4=6; ti->dhb_size16mb = min(ti->dhb_size16mb, (unsigned short)10240); ti->rbuf_len16 = 1032; ti->rbuf_cnt16=6; break; case 127: /* 63.5KB shared RAM */ ti->dhb_size4mb = min(ti->dhb_size4mb, (unsigned short)4464); ti->rbuf_len4 = 1032; ti->rbuf_cnt4=6; ti->dhb_size16mb = min(ti->dhb_size16mb, (unsigned short)16384); ti->rbuf_len16 = 1032; ti->rbuf_cnt16=16; break; case 128: /* 64KB shared RAM */ ti->dhb_size4mb = min(ti->dhb_size4mb, (unsigned short)4464); ti->rbuf_len4 = 1032; ti->rbuf_cnt4=6; ti->dhb_size16mb = min(ti->dhb_size16mb, (unsigned short)17960); ti->rbuf_len16 = 1032; ti->rbuf_cnt16=16; break; default: ti->dhb_size4mb = 2048; ti->rbuf_len4 = 1032; ti->rbuf_cnt4=2; ti->dhb_size16mb = 2048; ti->rbuf_len16 = 1032; ti->rbuf_cnt16=2; break; } /* this formula is not smart enough for the paging case ti->rbuf_cnt<x> = (ti->avail_shared_ram * BLOCKSZ - ADAPT_PRIVATE - ARBLENGTH - SSBLENGTH - DLC_MAX_SAP * SAPLENGTH - DLC_MAX_STA * STALENGTH - ti->dhb_size<x>mb * NUM_DHB - SRBLENGTH - ASBLENGTH) / ti->rbuf_len<x>; */ ti->maxmtu16 = (ti->rbuf_len16 - 8) * ti->rbuf_cnt16 - TR_HLEN; ti->maxmtu4 = (ti->rbuf_len4 - 8) * ti->rbuf_cnt4 - TR_HLEN; /*BMS assuming 18 bytes of Routing Information (usually works) */ DPRINTK("Maximum Receive Internet Protocol MTU 16Mbps: %d, 4Mbps: %d\n", ti->maxmtu16, ti->maxmtu4);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -