Beispiel #1
0
/* This is the real probe routine.  */
static int cs89x0_probe1(struct device *dev, int ioaddr)
{
	struct net_local *lp;
	static unsigned version_printed = 0;
	int i;
	unsigned rev_type = 0;

	irq2dev_map[0] = dev;

#ifdef CONFIG_MWI

	/* chip select at 0x800000, 8kb */
	*(volatile unsigned short *)0xfffa5c = 0x8001;
	*(volatile unsigned short *)0xfffa5e = 0x7970;

#endif

#ifdef CONFIG_UCSIMM
	/* set up the chip select */
	*(volatile unsigned  char *)0xfffff42b |= 0x01; /* output /sleep */
	*(volatile unsigned short *)0xfffff428 |= 0x0101; /* not sleeping */

	*(volatile unsigned  char *)0xfffff42b &= ~0x02; /* input irq5 */
	*(volatile unsigned short *)0xfffff428 &= ~0x0202; /* irq5 fcn on */
	
	*(volatile unsigned short *)0xfffff102 = 0x8000; /* 0x04000000 */
	*(volatile unsigned short *)0xfffff112 = 0x01e1; /* 128k, 2ws, FLASH, en */
#endif

#ifdef CONFIG_ARCH_ATMEL
	/* Fixme -- set up the chip, irq, etc... */
#endif

#ifdef CONFIG_ALMA_ANS
        /* 
         * Make sure the chip select (CSA1) is enabled 
	 * Note, that we don't have to program the base address, since
         * it is programmed once for both CSA0 and CSA1 in *-head.S
	 */
        PFSEL &= ~PF_CSA1;
        PFDIR |= PF_CSA1;
 
        /* Make sure that interrupt line (irq3) is enabled too */
        PDSEL  &= ~PD_IRQ3;
        PDDIR  &= ~PD_IRQ3;
        PDKBEN |= PD_IRQ3;                                                       
#endif

	/* Initialize the device structure. */
	if (dev->priv == NULL) {
		dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
                memset(dev->priv, 0, sizeof(struct net_local));
        }
	dev->base_addr = ioaddr;
	lp = (struct net_local *)dev->priv;

	if (readreg(dev, PP_ChipID) != CHIP_EISA_ID_SIG) {
	  printk("cs89x0.c: No CrystalLan device found.\n");
		return ENODEV;
	}

	/* get the chip type */
	rev_type = readreg(dev, PRODUCT_ID_ADD);
	lp->chip_type = rev_type &~ REVISON_BITS;
	lp->chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';

	/* Check the chip type and revision in order to set the correct send command
	CS8920 revision C and CS8900 revision F can use the faster send. */
	lp->send_cmd = TX_AFTER_ALL;
#if 0
	if (lp->chip_type == CS8900 && lp->chip_revision >= 'F')
		lp->send_cmd = TX_NOW;
	if (lp->chip_type != CS8900 && lp->chip_revision >= 'C')
		lp->send_cmd = TX_NOW;
#endif
	if (net_debug  &&  version_printed++ == 0)
		printk(version);

	printk("%s: cs89%c0%s rev %c found at 0x%.8x %s",
	       dev->name,
	       lp->chip_type==CS8900?'0':'2',
	       lp->chip_type==CS8920M?"M":"",
	       lp->chip_revision,
	       dev->base_addr,
	       readreg(dev, PP_SelfST) & ACTIVE_33V ? "3.3Volts " : "5Volts ");

	reset_chip(dev);

	/* Fill this in, we don't have an EEPROM */
	lp->adapter_cnf = A_CNF_10B_T | A_CNF_MEDIA_10B_T;
	lp->auto_neg_cnf = EE_AUTO_NEG_ENABLE;

	printk(" media %s%s%s",
	       (lp->adapter_cnf & A_CNF_10B_T)?"RJ-45,":"",
	       (lp->adapter_cnf & A_CNF_AUI)?"AUI,":"",
	       (lp->adapter_cnf & A_CNF_10B_2)?"BNC,":"");
	lp->irq_map = 0xffff;

#ifdef CONFIG_MWI
	dev->dev_addr[0] = 0x00;
	dev->dev_addr[1] = 0x30;
	dev->dev_addr[2] = 0x0f;
	dev->dev_addr[3] = 0x00;
	dev->dev_addr[4] = 0x01;
	dev->dev_addr[5] = 0x0b;
#endif

#ifdef CONFIG_ALMA_ANS
	/* Bad hack, has to be fixed, since we have the SEEPROM on board */
	dev->dev_addr[0] = 0x00;
	dev->dev_addr[1] = 0x00;
	dev->dev_addr[2] = 0xc0;
	dev->dev_addr[3] = 0xff;
	dev->dev_addr[4] = 0xee;
	dev->dev_addr[5] = 0x01;
#endif

#ifdef CONFIG_UCSIMM
	{
 		extern unsigned char *cs8900a_hwaddr;
 		memcpy(dev->dev_addr, cs8900a_hwaddr, 6);
	}
#endif

#ifdef CONFIG_ARCH_ATMEL
	{
 		memcpy(dev->dev_addr, (unsigned long)CS8900_BASE, 6);
	}
#endif

	/* print the ethernet address. */
	printk("mac = %.2x", dev->dev_addr[0]);
	for (i = 1; i < ETH_ALEN; i++)
		printk(":%.2x", dev->dev_addr[i]);

#ifdef FIXME
	/* Grab the region so we can find another board if autoIRQ fails. */
	request_region(ioaddr, NETCARD_IO_EXTENT,"cs89x0");
#endif

	dev->open		= net_open;
	dev->stop		= net_close;
	dev->hard_start_xmit 	= net_send_packet;
	dev->get_stats		= net_get_stats;
	dev->set_multicast_list	= &set_multicast_list;
	dev->set_mac_address 	= &set_mac_address;

	/* Fill in the fields of the device structure with ethernet values. */
	ether_setup(dev);

	printk("\n");
	return 0;
}
Beispiel #2
0
static u_char
ReadISAC(struct IsdnCardState *cs, u_char offset)
{
	return (readreg(cs->hw.saphir.ale, cs->hw.saphir.isac, offset));
}
Beispiel #3
0
static u_char
ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
{
	return (readreg(cs->hw.mic.adr,
			cs->hw.mic.hscx, offset + (hscx ? 0x40 : 0)));
}
Beispiel #4
0
int __devinit
setup_sedlbauer(struct IsdnCard *card)
{
	int bytecnt, ver, val;
	struct IsdnCardState *cs = card->cs;
	char tmp[64];
	u16 sub_vendor_id, sub_id;

	strcpy(tmp, Sedlbauer_revision);
	printk(KERN_INFO "HiSax: Sedlbauer driver Rev. %s\n", HiSax_getrev(tmp));
	
 	if (cs->typ == ISDN_CTYPE_SEDLBAUER) {
 		cs->subtyp = SEDL_SPEED_CARD_WIN;
		cs->hw.sedl.bus = SEDL_BUS_ISA;
		cs->hw.sedl.chip = SEDL_CHIP_TEST;
 	} else if (cs->typ == ISDN_CTYPE_SEDLBAUER_PCMCIA) {	
 		cs->subtyp = SEDL_SPEED_STAR;
		cs->hw.sedl.bus = SEDL_BUS_PCMCIA;
		cs->hw.sedl.chip = SEDL_CHIP_TEST;
 	} else if (cs->typ == ISDN_CTYPE_SEDLBAUER_FAX) {	
 		cs->subtyp = SEDL_SPEED_FAX;
		cs->hw.sedl.bus = SEDL_BUS_ISA;
		cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
 	} else
		return (0);

	bytecnt = 8;
	if (card->para[1]) {
		cs->hw.sedl.cfg_reg = card->para[1];
		cs->irq = card->para[0];
		if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
			bytecnt = 16;
		}
	} else {
#ifdef __ISAPNP__
		if (isapnp_present()) {
			struct pnp_dev *pnp_d;
			while(ipid->card_vendor) {
				if ((pnp_c = pnp_find_card(ipid->card_vendor,
					ipid->card_device, pnp_c))) {
					pnp_d = NULL;
					if ((pnp_d = pnp_find_dev(pnp_c,
						ipid->vendor, ipid->function, pnp_d))) {
						int err;

						printk(KERN_INFO "HiSax: %s detected\n",
							(char *)ipid->driver_data);
						pnp_disable_dev(pnp_d);
						err = pnp_activate_dev(pnp_d);
						if (err<0) {
							printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n",
								__FUNCTION__, err);
							return(0);
						}
						card->para[1] = pnp_port_start(pnp_d, 0);
						card->para[0] = pnp_irq(pnp_d, 0);

						if (!card->para[0] || !card->para[1]) {
							printk(KERN_ERR "Sedlbauer PnP:some resources are missing %ld/%lx\n",
								card->para[0], card->para[1]);
							pnp_disable_dev(pnp_d);
							return(0);
						}
						cs->hw.sedl.cfg_reg = card->para[1];
						cs->irq = card->para[0];
						if (ipid->function == ISAPNP_FUNCTION(0x2)) {
							cs->subtyp = SEDL_SPEED_FAX;
							cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
							bytecnt = 16;
						} else {
							cs->subtyp = SEDL_SPEED_CARD_WIN;
							cs->hw.sedl.chip = SEDL_CHIP_TEST;
						}
						goto ready;
					} else {
						printk(KERN_ERR "Sedlbauer PnP: PnP error card found, no device\n");
						return(0);
					}
				}
				ipid++;
				pnp_c = NULL;
			} 
			if (!ipid->card_vendor) {
				printk(KERN_INFO "Sedlbauer PnP: no ISAPnP card found\n");
			}
		}
#endif
/* Probe for Sedlbauer speed pci */
#ifdef CONFIG_PCI
		if ((dev_sedl = pci_find_device(PCI_VENDOR_ID_TIGERJET,
				PCI_DEVICE_ID_TIGERJET_100, dev_sedl))) {
			if (pci_enable_device(dev_sedl))
				return(0);
			cs->irq = dev_sedl->irq;
			if (!cs->irq) {
				printk(KERN_WARNING "Sedlbauer: No IRQ for PCI card found\n");
				return(0);
			}
			cs->hw.sedl.cfg_reg = pci_resource_start(dev_sedl, 0);
		} else {
			printk(KERN_WARNING "Sedlbauer: No PCI card found\n");
			return(0);
		}
		cs->irq_flags |= IRQF_SHARED;
		cs->hw.sedl.bus = SEDL_BUS_PCI;
		sub_vendor_id = dev_sedl->subsystem_vendor;
		sub_id = dev_sedl->subsystem_device;
		printk(KERN_INFO "Sedlbauer: PCI subvendor:%x subid %x\n",
			sub_vendor_id, sub_id);
		printk(KERN_INFO "Sedlbauer: PCI base adr %#x\n",
			cs->hw.sedl.cfg_reg);
		if (sub_id != PCI_SUB_ID_SEDLBAUER) {
			printk(KERN_ERR "Sedlbauer: unknown sub id %#x\n", sub_id);
			return(0);
		}
		if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PYRAMID) {
			cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
			cs->subtyp = SEDL_SPEEDFAX_PYRAMID;
		} else if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PCI) {
			cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
			cs->subtyp = SEDL_SPEEDFAX_PCI;
		} else if (sub_vendor_id == PCI_SUBVENDOR_HST_SAPHIR3) {
			cs->hw.sedl.chip = SEDL_CHIP_IPAC;
			cs->subtyp = HST_SAPHIR3;
		} else if (sub_vendor_id == PCI_SUBVENDOR_SEDLBAUER_PCI) {
			cs->hw.sedl.chip = SEDL_CHIP_IPAC;
			cs->subtyp = SEDL_SPEED_PCI;
		} else {
			printk(KERN_ERR "Sedlbauer: unknown sub vendor id %#x\n",
				sub_vendor_id);
			return(0);
		}
		bytecnt = 256;
		cs->hw.sedl.reset_on = SEDL_ISAR_PCI_ISAR_RESET_ON;
		cs->hw.sedl.reset_off = SEDL_ISAR_PCI_ISAR_RESET_OFF;
		byteout(cs->hw.sedl.cfg_reg, 0xff);
		byteout(cs->hw.sedl.cfg_reg, 0x00);
		byteout(cs->hw.sedl.cfg_reg+ 2, 0xdd);
		byteout(cs->hw.sedl.cfg_reg+ 5, 0x02);
		byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_on);
		mdelay(2);
		byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
		mdelay(10);
#else
		printk(KERN_WARNING "Sedlbauer: NO_PCI_BIOS\n");
		return (0);
#endif /* CONFIG_PCI */
	}	

#ifdef __ISAPNP__
ready:	
#endif

	/* In case of the sedlbauer pcmcia card, this region is in use,
	 * reserved for us by the card manager. So we do not check it
	 * here, it would fail.
	 */
	if (cs->hw.sedl.bus != SEDL_BUS_PCMCIA &&
		!request_region(cs->hw.sedl.cfg_reg, bytecnt, "sedlbauer isdn")) {
		printk(KERN_WARNING
			"HiSax: %s config port %x-%x already in use\n",
			CardType[card->typ],
			cs->hw.sedl.cfg_reg,
			cs->hw.sedl.cfg_reg + bytecnt);
			return (0);
	}

	printk(KERN_INFO
	       "Sedlbauer: defined at 0x%x-0x%x IRQ %d\n",
	       cs->hw.sedl.cfg_reg,
	       cs->hw.sedl.cfg_reg + bytecnt,
	       cs->irq);

	cs->BC_Read_Reg = &ReadHSCX;
	cs->BC_Write_Reg = &WriteHSCX;
	cs->BC_Send_Data = &hscx_fill_fifo;
	cs->cardmsg = &Sedl_card_msg;

/*
 * testing ISA and PCMCIA Cards for IPAC, default is ISAC
 * do not test for PCI card, because ports are different
 * and PCI card uses only IPAC (for the moment)
 */	
	if (cs->hw.sedl.bus != SEDL_BUS_PCI) {
		val = readreg(cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR,
			cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC, IPAC_ID);
		printk(KERN_DEBUG "Sedlbauer: testing IPAC version %x\n", val);
	        if ((val == 1) || (val == 2)) {
			/* IPAC */
			cs->subtyp = SEDL_SPEED_WIN2_PC104;
			if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) {
				cs->subtyp = SEDL_SPEED_STAR2;
			}
			cs->hw.sedl.chip = SEDL_CHIP_IPAC;
		} else {
			/* ISAC_HSCX oder ISAC_ISAR */
			if (cs->hw.sedl.chip == SEDL_CHIP_TEST) {
				cs->hw.sedl.chip = SEDL_CHIP_ISAC_HSCX;
			}
		}
	}

/*
 * hw.sedl.chip is now properly set
 */
	printk(KERN_INFO "Sedlbauer: %s detected\n",
		Sedlbauer_Types[cs->subtyp]);

	setup_isac(cs);
	if (cs->hw.sedl.chip == SEDL_CHIP_IPAC) {
		if (cs->hw.sedl.bus == SEDL_BUS_PCI) {
	                cs->hw.sedl.adr  = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_ADR;
			cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC;
			cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC;
		} else {
	                cs->hw.sedl.adr  = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR;
			cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC;
			cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC;
		}
		test_and_set_bit(HW_IPAC, &cs->HW_Flags);
		cs->readisac = &ReadISAC_IPAC;
		cs->writeisac = &WriteISAC_IPAC;
		cs->readisacfifo = &ReadISACfifo_IPAC;
		cs->writeisacfifo = &WriteISACfifo_IPAC;
		cs->irq_func = &sedlbauer_interrupt_ipac;
		val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ID);
		printk(KERN_INFO "Sedlbauer: IPAC version %x\n", val);
	} else {
		/* ISAC_HSCX oder ISAC_ISAR */
		cs->readisac = &ReadISAC;
		cs->writeisac = &WriteISAC;
		cs->readisacfifo = &ReadISACfifo;
		cs->writeisacfifo = &WriteISACfifo;
		if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
			if (cs->hw.sedl.bus == SEDL_BUS_PCI) {
				cs->hw.sedl.adr = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_PCI_ADR;
				cs->hw.sedl.isac = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_PCI_ISAC;
				cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_PCI_ISAR;
			} else {
				cs->hw.sedl.adr = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_ISA_ADR;
				cs->hw.sedl.isac = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_ISA_ISAC;
				cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_ISA_ISAR;
				cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_ISA_ISAR_RESET_ON;
				cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_ISA_ISAR_RESET_OFF;
			}
			cs->bcs[0].hw.isar.reg = &cs->hw.sedl.isar;
			cs->bcs[1].hw.isar.reg = &cs->hw.sedl.isar;
			test_and_set_bit(HW_ISAR, &cs->HW_Flags);
			cs->irq_func = &sedlbauer_interrupt_isar;
			cs->auxcmd = &isar_auxcmd;
			ISACVersion(cs, "Sedlbauer:");
			cs->BC_Read_Reg = &ReadISAR;
			cs->BC_Write_Reg = &WriteISAR;
			cs->BC_Send_Data = &isar_fill_fifo;
			bytecnt = 3;
			while (bytecnt) {
				ver = ISARVersion(cs, "Sedlbauer:");
				if (ver < 0)
					printk(KERN_WARNING
						"Sedlbauer: wrong ISAR version (ret = %d)\n", ver);
				else
					break;
				reset_sedlbauer(cs);
				bytecnt--;
			}
			if (!bytecnt) {
				release_io_sedlbauer(cs);
				return (0);
			}
		} else {
			if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) {
				cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ADR;
				cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ISAC;
				cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_HSCX;
				cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET;
				cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET;
				cs->irq_flags |= IRQF_SHARED;
			} else {
				cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ADR;
				cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ISAC;
				cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_HSCX;
				cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_ON;
				cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_OFF;
			}
			cs->irq_func = &sedlbauer_interrupt;
			ISACVersion(cs, "Sedlbauer:");
		
			if (HscxVersion(cs, "Sedlbauer:")) {
				printk(KERN_WARNING
					"Sedlbauer: wrong HSCX versions check IO address\n");
				release_io_sedlbauer(cs);
				return (0);
			}
		}
	}
	return (1);
}
Beispiel #5
0
int __devinit
setup_sedlbauer(struct IsdnCard *card)
{
	int bytecnt = 8, ver, val, rc;
	struct IsdnCardState *cs = card->cs;
	char tmp[64];

	strcpy(tmp, Sedlbauer_revision);
	printk(KERN_INFO "HiSax: Sedlbauer driver Rev. %s\n", HiSax_getrev(tmp));

 	if (cs->typ == ISDN_CTYPE_SEDLBAUER) {
 		cs->subtyp = SEDL_SPEED_CARD_WIN;
		cs->hw.sedl.bus = SEDL_BUS_ISA;
		cs->hw.sedl.chip = SEDL_CHIP_TEST;
 	} else if (cs->typ == ISDN_CTYPE_SEDLBAUER_PCMCIA) {
 		cs->subtyp = SEDL_SPEED_STAR;
		cs->hw.sedl.bus = SEDL_BUS_PCMCIA;
		cs->hw.sedl.chip = SEDL_CHIP_TEST;
 	} else if (cs->typ == ISDN_CTYPE_SEDLBAUER_FAX) {
 		cs->subtyp = SEDL_SPEED_FAX;
		cs->hw.sedl.bus = SEDL_BUS_ISA;
		cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
 	} else
		return (0);

	bytecnt = 8;
	if (card->para[1]) {
		cs->hw.sedl.cfg_reg = card->para[1];
		cs->irq = card->para[0];
		if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
			bytecnt = 16;
		}
	} else {
		rc = setup_sedlbauer_isapnp(card, &bytecnt);
		if (!rc)
			return (0);
		if (rc > 0)
			goto ready;

		/* Probe for Sedlbauer speed pci */
		rc = setup_sedlbauer_pci(card);
		if (!rc)
			return (0);

		bytecnt = 256;
	}

ready:

	/* In case of the sedlbauer pcmcia card, this region is in use,
	 * reserved for us by the card manager. So we do not check it
	 * here, it would fail.
	 */
	if (cs->hw.sedl.bus != SEDL_BUS_PCMCIA &&
		!request_region(cs->hw.sedl.cfg_reg, bytecnt, "sedlbauer isdn")) {
		printk(KERN_WARNING
			"HiSax: %s config port %x-%x already in use\n",
			CardType[card->typ],
			cs->hw.sedl.cfg_reg,
			cs->hw.sedl.cfg_reg + bytecnt);
			return (0);
	}

	printk(KERN_INFO
	       "Sedlbauer: defined at 0x%x-0x%x IRQ %d\n",
	       cs->hw.sedl.cfg_reg,
	       cs->hw.sedl.cfg_reg + bytecnt,
	       cs->irq);

	cs->BC_Read_Reg = &ReadHSCX;
	cs->BC_Write_Reg = &WriteHSCX;
	cs->BC_Send_Data = &hscx_fill_fifo;
	cs->cardmsg = &Sedl_card_msg;

/*
 * testing ISA and PCMCIA Cards for IPAC, default is ISAC
 * do not test for PCI card, because ports are different
 * and PCI card uses only IPAC (for the moment)
 */
	if (cs->hw.sedl.bus != SEDL_BUS_PCI) {
		val = readreg(cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR,
			cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC, IPAC_ID);
		printk(KERN_DEBUG "Sedlbauer: testing IPAC version %x\n", val);
	        if ((val == 1) || (val == 2)) {
			/* IPAC */
			cs->subtyp = SEDL_SPEED_WIN2_PC104;
			if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) {
				cs->subtyp = SEDL_SPEED_STAR2;
			}
			cs->hw.sedl.chip = SEDL_CHIP_IPAC;
		} else {
			/* ISAC_HSCX oder ISAC_ISAR */
			if (cs->hw.sedl.chip == SEDL_CHIP_TEST) {
				cs->hw.sedl.chip = SEDL_CHIP_ISAC_HSCX;
			}
		}
	}

/*
 * hw.sedl.chip is now properly set
 */
	printk(KERN_INFO "Sedlbauer: %s detected\n",
		Sedlbauer_Types[cs->subtyp]);

	setup_isac(cs);
	if (cs->hw.sedl.chip == SEDL_CHIP_IPAC) {
		if (cs->hw.sedl.bus == SEDL_BUS_PCI) {
	                cs->hw.sedl.adr  = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_ADR;
			cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC;
			cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC;
		} else {
	                cs->hw.sedl.adr  = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR;
			cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC;
			cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC;
		}
		test_and_set_bit(HW_IPAC, &cs->HW_Flags);
		cs->readisac = &ReadISAC_IPAC;
		cs->writeisac = &WriteISAC_IPAC;
		cs->readisacfifo = &ReadISACfifo_IPAC;
		cs->writeisacfifo = &WriteISACfifo_IPAC;
		cs->irq_func = &sedlbauer_interrupt_ipac;
		val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ID);
		printk(KERN_INFO "Sedlbauer: IPAC version %x\n", val);
	} else {
		/* ISAC_HSCX oder ISAC_ISAR */
		cs->readisac = &ReadISAC;
		cs->writeisac = &WriteISAC;
		cs->readisacfifo = &ReadISACfifo;
		cs->writeisacfifo = &WriteISACfifo;
		if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
			if (cs->hw.sedl.bus == SEDL_BUS_PCI) {
				cs->hw.sedl.adr = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_PCI_ADR;
				cs->hw.sedl.isac = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_PCI_ISAC;
				cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_PCI_ISAR;
			} else {
				cs->hw.sedl.adr = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_ISA_ADR;
				cs->hw.sedl.isac = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_ISA_ISAC;
				cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_ISA_ISAR;
				cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_ISA_ISAR_RESET_ON;
				cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_ISA_ISAR_RESET_OFF;
			}
			cs->bcs[0].hw.isar.reg = &cs->hw.sedl.isar;
			cs->bcs[1].hw.isar.reg = &cs->hw.sedl.isar;
			test_and_set_bit(HW_ISAR, &cs->HW_Flags);
			cs->irq_func = &sedlbauer_interrupt_isar;
			cs->auxcmd = &isar_auxcmd;
			ISACVersion(cs, "Sedlbauer:");
			cs->BC_Read_Reg = &ReadISAR;
			cs->BC_Write_Reg = &WriteISAR;
			cs->BC_Send_Data = &isar_fill_fifo;
			bytecnt = 3;
			while (bytecnt) {
				ver = ISARVersion(cs, "Sedlbauer:");
				if (ver < 0)
					printk(KERN_WARNING
						"Sedlbauer: wrong ISAR version (ret = %d)\n", ver);
				else
					break;
				reset_sedlbauer(cs);
				bytecnt--;
			}
			if (!bytecnt) {
				release_io_sedlbauer(cs);
				return (0);
			}
		} else {
			if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) {
				cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ADR;
				cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ISAC;
				cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_HSCX;
				cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET;
				cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET;
				cs->irq_flags |= IRQF_SHARED;
			} else {
				cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ADR;
				cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ISAC;
				cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_HSCX;
				cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_ON;
				cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_OFF;
			}
			cs->irq_func = &sedlbauer_interrupt;
			ISACVersion(cs, "Sedlbauer:");

			if (HscxVersion(cs, "Sedlbauer:")) {
				printk(KERN_WARNING
					"Sedlbauer: wrong HSCX versions check IO address\n");
				release_io_sedlbauer(cs);
				return (0);
			}
		}
	}
	return (1);
}
Beispiel #6
0
void
cpu_initclocks(void)
{
	struct cpu_info * const ci = curcpu();
	uint32_t cnt;

	static struct timecounter tc =  {
		ingenic_count_read,		/* get_timecount */
		0,				/* no poll_pps */
		~0u,				/* counter_mask */
		12000000,			/* frequency */
		"Ingenic OS timer",		/* name */
		100,				/* quality */
	};

	curcpu()->ci_cctr_freq = tc.tc_frequency;

	tc_init(&tc);

	printf("starting timer interrupt...\n");
	/* start the timer interrupt */
	cnt = readreg(JZ_OST_CNT_LO);
	ci->ci_next_cp0_clk_intr = cnt + ci->ci_cycles_per_hz;
	writereg(JZ_TC_TFCR, TFR_OSTFLAG);
	writereg(JZ_OST_DATA, ci->ci_next_cp0_clk_intr);
	/*
	 * XXX
	 * We can use OST or one of the regular timers to generate the 100hz
	 * interrupt. OST interrupts need to be rescheduled every time and by
	 * only one core, the regular timer can be programmed to fire every
	 * 10ms without rescheduling and we'd still use the OST as time base.
	 * OST is supposed to fire on INT2 although I haven't been able to get
	 * that to work yet ( all I get is INT0 which is for hardware interrupts
	 * in general )
	 * So if we can get OST to fire on INT2 we can just block INT0 on core1
	 * and have a timer interrupt on both cores, if not the regular timer 
	 * would be more convenient but we'd have to shoot an IPI to core1 on
	 * every tick.
	 * For now, use OST and hope we'll figure out how to make it fire on
	 * INT2.
	 */
#ifdef USE_OST
	writereg(JZ_TC_TMCR, TFR_OSTFLAG);
#else
	writereg(JZ_TC_TECR, TESR_TCST5);	/* disable timer 5 */
	writereg(JZ_TC_TCNT(5), 0);
	writereg(JZ_TC_TDFR(5), 30000);	/* 10ms at 48MHz / 16 */
	writereg(JZ_TC_TDHR(5), 60000);	/* not reached */
	writereg(JZ_TC_TCSR(5), TCSR_EXT_EN| TCSR_DIV_16);
	writereg(JZ_TC_TMCR, TFR_FFLAG5);
	writereg(JZ_TC_TFCR, TFR_FFLAG5);
	writereg(JZ_TC_TESR, TESR_TCST5);	/* enable timer 5 */
#endif

#ifdef INGENIC_CLOCK_DEBUG
	printf("INTC %08x %08x\n", readreg(JZ_ICSR0), readreg(JZ_ICSR1));
	printf("ICMR0 %08x\n", readreg(JZ_ICMR0));
#endif
	writereg(JZ_ICMCR0, 0x0c000000); /* TCU2, OST */
	spl0();
#ifdef INGENIC_CLOCK_DEBUG
	printf("TFR: %08x\n", readreg(JZ_TC_TFR));
	printf("TMR: %08x\n", readreg(JZ_TC_TMR));
	printf("cnt5: %08x\n", readreg(JZ_TC_TCNT(5)));
	printf("CR: %08x\n", MFC0(MIPS_COP_0_CAUSE, 0));
	printf("SR: %08x\n", MFC0(MIPS_COP_0_STATUS, 0));
	delay(100000);
	printf("TFR: %08x\n", readreg(JZ_TC_TFR));
	printf("TMR: %08x\n", readreg(JZ_TC_TMR));
	printf("cnt5: %08x\n", readreg(JZ_TC_TCNT(5)));
	printf("CR: %08x\n", MFC0(MIPS_COP_0_CAUSE, 0));
	printf("SR: %08x\n", MFC0(MIPS_COP_0_STATUS, 0));
	printf("TFR: %08x\n", readreg(JZ_TC_TFR));
	printf("TMR: %08x\n", readreg(JZ_TC_TMR));
	printf("cnt5: %08x\n", readreg(JZ_TC_TCNT(5)));
	printf("CR: %08x\n", MFC0(MIPS_COP_0_CAUSE, 0));
	printf("SR: %08x\n", MFC0(MIPS_COP_0_STATUS, 0));
	
	printf("INTC %08x %08x\n", readreg(JZ_ICSR0), readreg(JZ_ICSR1));
	delay(3000000);
	printf("%s %d\n", __func__, MFC0(12, 3));
	printf("%s %08x\n", __func__, MFC0(12, 4));
#endif
}
Beispiel #7
0
static u_char ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
{
	return readreg(cs->hw.niccy.hscx_ale,
			cs->hw.niccy.hscx, offset + (hscx ? 0x40 : 0));
}
Beispiel #8
0
static void
bkm_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
{
	struct IsdnCardState *cs = dev_id;
	u_char ista, val, icnt = 5;
	int i;
	if (!cs) {
		printk(KERN_WARNING "HiSax: Scitel Quadro: Spurious interrupt!\n");
		return;
	}
	ista = readreg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_ISTA);

      Start_IPAC:
	if (cs->debug & L1_DEB_IPAC)
		debugl1(cs, "IPAC ISTA %02X", ista);
	if (ista & 0x0f) {
		val = readreg(cs->hw.ax.base, cs->hw.ax.data_adr, HSCX_ISTA + 0x40);
		if (ista & 0x01)
			val |= 0x01;
		if (ista & 0x04)
			val |= 0x02;
		if (ista & 0x08)
			val |= 0x04;
		if (val) {
			hscx_int_main(cs, val);
		}
	}
	if (ista & 0x20) {
		val = 0xfe & readreg(cs->hw.ax.base, cs->hw.ax.data_adr, ISAC_ISTA | 0x80);
		if (val) {
			isac_interrupt(cs, val);
		}
	}
	if (ista & 0x10) {
		val = 0x01;
		isac_interrupt(cs, val);
	}
	ista = readreg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_ISTA);
	if ((ista & 0x3f) && icnt) {
		icnt--;
		goto Start_IPAC;
	}
	if (!icnt)
		printk(KERN_WARNING "HiSax: %s (%s) IRQ LOOP\n",
		       CardType[cs->typ],
		       sct_quadro_subtypes[cs->subtyp]);
	writereg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_MASK, 0xFF);
	writereg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_MASK, 0xC0);

	/* Read out all interrupt sources from currently not active ipacs */
	/* "Handle" all interrupts from currently not active ipac by reading the regs */
	for (i = SCT_1; i <= SCT_4; i++)
		if (!is_ipac_active(i)) {
			u_int base = ipac_state[i].base;
			if (readreg(base, base + 4, 0xC1)) {
				readreg(base, base + 4, 0xA0);
				readreg(base, base + 4, 0xA4);
				readreg(base, base + 4, 0x20);
				readreg(base, base + 4, 0x24);
				readreg(base, base + 4, 0x60);
				readreg(base, base + 4, 0x64);
				readreg(base, base + 4, 0xC1);
				readreg(base, base + 4, ISAC_CIR0 + 0x80);
			}
		}
}
Beispiel #9
0
__initfunc(int
	   setup_sct_quadro(struct IsdnCard *card))
{
	struct IsdnCardState *cs = card->cs;
	char tmp[64];
#if CONFIG_PCI
	u_char pci_bus = 0, pci_device_fn = 0, pci_irq = 0, pci_rev_id;
	u_int found = 0;
	u_int pci_ioaddr1, pci_ioaddr2, pci_ioaddr3, pci_ioaddr4, pci_ioaddr5;
#endif

	strcpy(tmp, sct_quadro_revision);
	printk(KERN_INFO "HiSax: T-Berkom driver Rev. %s\n", HiSax_getrev(tmp));
	if (cs->typ == ISDN_CTYPE_SCT_QUADRO) {
		cs->subtyp = SCT_1;	/* Preset */
	} else
		return (0);

	/* Identify subtype by para[0] */
	if (card->para[0] >= SCT_1 && card->para[0] <= SCT_4)
		cs->subtyp = card->para[0];
	else
		printk(KERN_WARNING "HiSax: %s: Invalid subcontroller in configuration, default to 1\n",
		       CardType[card->typ]);
#if CONFIG_PCI
	if (!pci_present()) {
		printk(KERN_ERR "bkm_a4t: no PCI bus present\n");
		return (0);
	}
	if ((dev_a8 = pci_find_device(PLX_VENDOR_ID, PLX_DEVICE_ID, dev_a8))) {
		u_int sub_sys_id = 0;

		pci_read_config_dword(dev_a8, PCI_SUBSYSTEM_VENDOR_ID,
			&sub_sys_id);
		if (sub_sys_id == ((SCT_SUBSYS_ID << 16) | SCT_SUBVEN_ID)) {
			found = 1;
			pci_ioaddr1 = dev_a8->base_address[ 1];
			pci_irq = dev_a8->irq;
			pci_bus = dev_a8->bus->number;
			pci_device_fn = dev_a8->devfn;
		}
	}
	if (!found) {
		printk(KERN_WARNING "HiSax: %s (%s): Card not found\n",
		       CardType[card->typ],
		       sct_quadro_subtypes[cs->subtyp]);
		return (0);
	}
	if (!pci_irq) {		/* IRQ range check ?? */
		printk(KERN_WARNING "HiSax: %s (%s): No IRQ\n",
		       CardType[card->typ],
		       sct_quadro_subtypes[cs->subtyp]);
		return (0);
	}
#ifdef ATTEMPT_PCI_REMAPPING
/* HACK: PLX revision 1 bug: PLX address bit 7 must not be set */
	pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_REVISION_ID, &pci_rev_id);
	if ((pci_ioaddr1 & 0x80) && (pci_rev_id == 1)) {
		printk(KERN_WARNING "HiSax: %s (%s): PLX rev 1, remapping required!\n",
			CardType[card->typ],
			sct_quadro_subtypes[cs->subtyp]);
		/* Restart PCI negotiation */
		pcibios_write_config_dword(pci_bus, pci_device_fn,
			PCI_BASE_ADDRESS_1, (u_int) - 1);
		/* Move up by 0x80 byte */
		pci_ioaddr1 += 0x80;
		pci_ioaddr1 &= PCI_BASE_ADDRESS_IO_MASK;
		pcibios_write_config_dword(pci_bus, pci_device_fn,
			PCI_BASE_ADDRESS_1, pci_ioaddr1);
		dev_a8->base_address[ 1] = pci_ioaddr1;
	}
/* End HACK */
#endif
	pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_1, &pci_ioaddr1);
	pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_2, &pci_ioaddr2);
	pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_3, &pci_ioaddr3);
	pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_4, &pci_ioaddr4);
	pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_5, &pci_ioaddr5);
	if (!pci_ioaddr1 || !pci_ioaddr2 || !pci_ioaddr3 || !pci_ioaddr4 || !pci_ioaddr5) {
		printk(KERN_WARNING "HiSax: %s (%s): No IO base address(es)\n",
		       CardType[card->typ],
		       sct_quadro_subtypes[cs->subtyp]);
		return (0);
	}
	pci_ioaddr1 &= PCI_BASE_ADDRESS_IO_MASK;
	pci_ioaddr2 &= PCI_BASE_ADDRESS_IO_MASK;
	pci_ioaddr3 &= PCI_BASE_ADDRESS_IO_MASK;
	pci_ioaddr4 &= PCI_BASE_ADDRESS_IO_MASK;
	pci_ioaddr5 &= PCI_BASE_ADDRESS_IO_MASK;
	/* Take over */
	cs->irq = pci_irq;
	cs->irq_flags |= SA_SHIRQ;
	/* pci_ioaddr1 is unique to all subdevices */
	/* pci_ioaddr2 is for the fourth subdevice only */
	/* pci_ioaddr3 is for the third subdevice only */
	/* pci_ioaddr4 is for the second subdevice only */
	/* pci_ioaddr5 is for the first subdevice only */
	cs->hw.ax.plx_adr = pci_ioaddr1;
	/* Enter all ipac_base addresses */
	ipac_state[SCT_1].base = pci_ioaddr5 + 0x00;
	ipac_state[SCT_2].base = pci_ioaddr4 + 0x08;
	ipac_state[SCT_3].base = pci_ioaddr3 + 0x10;
	ipac_state[SCT_4].base = pci_ioaddr2 + 0x20;
	/* For isac and hscx control path */
	cs->hw.ax.base = ipac_state[cs->subtyp].base;
	/* For isac and hscx data path */
	cs->hw.ax.data_adr = cs->hw.ax.base + 4;
#else
	printk(KERN_WARNING "HiSax: %s (%s): NO_PCI_BIOS\n",
	       CardType[card->typ],
	       sct_quadro_subtypes[cs->subtyp]);
	printk(KERN_WARNING "HiSax: %s (%s): Unable to configure\n",
	       CardType[card->typ],
	       sct_quadro_subtypes[cs->subtyp]);
	return (0);
#endif				/* CONFIG_PCI */
	printk(KERN_INFO "HiSax: %s (%s) configured at 0x%.4X, 0x%.4X, 0x%.4X and IRQ %d\n",
	       CardType[card->typ],
	       sct_quadro_subtypes[cs->subtyp],
	       cs->hw.ax.plx_adr,
	       cs->hw.ax.base,
	       cs->hw.ax.data_adr,
	       cs->irq);

	test_and_set_bit(HW_IPAC, &cs->HW_Flags);

	/* Disable all currently not active ipacs */
	if (!is_ipac_active(SCT_1))
		set_ipac_active(SCT_1, 0);
	if (!is_ipac_active(SCT_2))
		set_ipac_active(SCT_2, 0);
	if (!is_ipac_active(SCT_3))
		set_ipac_active(SCT_3, 0);
	if (!is_ipac_active(SCT_4))
		set_ipac_active(SCT_4, 0);

	/* Perfom general reset (if possible) */
	reset_bkm(cs);

	cs->readisac = &ReadISAC;
	cs->writeisac = &WriteISAC;
	cs->readisacfifo = &ReadISACfifo;
	cs->writeisacfifo = &WriteISACfifo;

	cs->BC_Read_Reg = &ReadHSCX;
	cs->BC_Write_Reg = &WriteHSCX;
	cs->BC_Send_Data = &hscx_fill_fifo;
	cs->cardmsg = &BKM_card_msg;
	cs->irq_func = &bkm_interrupt_ipac;

	printk(KERN_INFO "HiSax: %s (%s): IPAC Version %d\n",
		CardType[card->typ],
		sct_quadro_subtypes[cs->subtyp],
		readreg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_ID));
	return (1);
}
Beispiel #10
0
__initfunc(int
setup_diva(struct IsdnCard *card))
{
	int bytecnt;
	u_char val;
	struct IsdnCardState *cs = card->cs;
	char tmp[64];

	strcpy(tmp, Diva_revision);
	printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp));
	if (cs->typ != ISDN_CTYPE_DIEHLDIVA)
		return(0);
	cs->hw.diva.status = 0;
	if (card->para[1]) {
		cs->hw.diva.ctrl_reg = 0;
		cs->hw.diva.cfg_reg = card->para[1];
		val = readreg(cs->hw.diva.cfg_reg + DIVA_IPAC_ADR,
			cs->hw.diva.cfg_reg + DIVA_IPAC_DATA, IPAC_ID);
		printk(KERN_INFO "Diva: IPAC version %x\n", val);
		if (val == 1) {
			cs->subtyp = DIVA_IPAC_ISA;
			cs->hw.diva.ctrl = 0;
			cs->hw.diva.isac = card->para[1] + DIVA_IPAC_DATA;
			cs->hw.diva.hscx = card->para[1] + DIVA_IPAC_DATA;
			cs->hw.diva.isac_adr = card->para[1] + DIVA_IPAC_ADR;
			cs->hw.diva.hscx_adr = card->para[1] + DIVA_IPAC_ADR;
			test_and_set_bit(HW_IPAC, &cs->HW_Flags);
		} else {
			cs->subtyp = DIVA_ISA;
			cs->hw.diva.ctrl = card->para[1] + DIVA_ISA_CTRL;
			cs->hw.diva.isac = card->para[1] + DIVA_ISA_ISAC_DATA;
			cs->hw.diva.hscx = card->para[1] + DIVA_HSCX_DATA;
			cs->hw.diva.isac_adr = card->para[1] + DIVA_ISA_ISAC_ADR;
			cs->hw.diva.hscx_adr = card->para[1] + DIVA_HSCX_ADR;
		}
		cs->irq = card->para[0];
		bytecnt = 8;
	} else {
#if CONFIG_PCI
		u_char pci_bus, pci_device_fn, pci_irq;
		u_int pci_ioaddr;

		cs->subtyp = 0;
		for (; pci_index < 0xff; pci_index++) {
			if (pcibios_find_device(PCI_VENDOR_EICON_DIEHL,
			   PCI_DIVA20_ID, pci_index, &pci_bus, &pci_device_fn)
			   == PCIBIOS_SUCCESSFUL)
				cs->subtyp = DIVA_PCI;
			else if (pcibios_find_device(PCI_VENDOR_EICON_DIEHL,
			   PCI_DIVA20_ID, pci_index, &pci_bus, &pci_device_fn)
			   == PCIBIOS_SUCCESSFUL)
			   	cs->subtyp = DIVA_PCI;
			else
				break;
			/* get IRQ */
			pcibios_read_config_byte(pci_bus, pci_device_fn,
				PCI_INTERRUPT_LINE, &pci_irq);

			/* get IO address */
			pcibios_read_config_dword(pci_bus, pci_device_fn,
				PCI_BASE_ADDRESS_2, &pci_ioaddr);
			if (cs->subtyp)
				break;
		}
		if (!cs->subtyp) {
			printk(KERN_WARNING "Diva: No PCI card found\n");
			return(0);
		}
		pci_index++;
		if (!pci_irq) {
			printk(KERN_WARNING "Diva: No IRQ for PCI card found\n");
			return(0);
		}

		if (!pci_ioaddr) {
			printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n");
			return(0);
		}
		pci_ioaddr &= ~3; /* remove io/mem flag */
		cs->hw.diva.cfg_reg = pci_ioaddr;
		cs->hw.diva.ctrl = pci_ioaddr + DIVA_PCI_CTRL;
		cs->hw.diva.isac = pci_ioaddr + DIVA_PCI_ISAC_DATA;
		cs->hw.diva.hscx = pci_ioaddr + DIVA_HSCX_DATA;
		cs->hw.diva.isac_adr = pci_ioaddr + DIVA_PCI_ISAC_ADR;
		cs->hw.diva.hscx_adr = pci_ioaddr + DIVA_HSCX_ADR;
		cs->irq = pci_irq;
		bytecnt = 32;
#else
		printk(KERN_WARNING "Diva: cfgreg 0 and NO_PCI_BIOS\n");
		printk(KERN_WARNING "Diva: unable to config DIVA PCI\n");
		return (0);
#endif /* CONFIG_PCI */
	}

	printk(KERN_INFO
		"Diva: %s card configured at 0x%x IRQ %d\n",
		(cs->subtyp == DIVA_PCI) ? "PCI" :
		(cs->subtyp == DIVA_ISA) ? "ISA" : "IPAC",
		cs->hw.diva.cfg_reg, cs->irq);
	if (check_region(cs->hw.diva.cfg_reg, bytecnt)) {
		printk(KERN_WARNING
		       "HiSax: %s config port %x-%x already in use\n",
		       CardType[card->typ],
		       cs->hw.diva.cfg_reg,
		       cs->hw.diva.cfg_reg + bytecnt);
		return (0);
	} else {
		request_region(cs->hw.diva.cfg_reg, bytecnt, "diva isdn");
	}

	reset_diva(cs);
	cs->BC_Read_Reg  = &ReadHSCX;
	cs->BC_Write_Reg = &WriteHSCX;
	cs->BC_Send_Data = &hscx_fill_fifo;
	cs->cardmsg = &Diva_card_msg;
	if (cs->subtyp == DIVA_IPAC_ISA) {
		cs->readisac  = &ReadISAC_IPAC;
		cs->writeisac = &WriteISAC_IPAC;
		cs->readisacfifo  = &ReadISACfifo_IPAC;
		cs->writeisacfifo = &WriteISACfifo_IPAC;
		val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ID);
		printk(KERN_INFO "Diva: IPAC version %x\n", val);
	} else {
		cs->hw.diva.tl.function = (void *) diva_led_handler;
		cs->hw.diva.tl.data = (long) cs;
		init_timer(&cs->hw.diva.tl);
		cs->readisac  = &ReadISAC;
		cs->writeisac = &WriteISAC;
		cs->readisacfifo  = &ReadISACfifo;
		cs->writeisacfifo = &WriteISACfifo;
		ISACVersion(cs, "Diva:");
		if (HscxVersion(cs, "Diva:")) {
			printk(KERN_WARNING
		       "Diva: wrong HSCX versions check IO address\n");
			release_io_diva(cs);
			return (0);
		}
	}
	return (1);
}
Beispiel #11
0
static int __devinit setup_diva_common(struct IsdnCardState *cs)
{
	int bytecnt;
	u_char val;

	if ((cs->subtyp == DIVA_ISA) || (cs->subtyp == DIVA_IPAC_ISA))
		bytecnt = 8;
	else
		bytecnt = 32;

	printk(KERN_INFO
		"Diva: %s card configured at %#lx IRQ %d\n",
		(cs->subtyp == DIVA_PCI) ? "PCI" :
		(cs->subtyp == DIVA_ISA) ? "ISA" : 
		(cs->subtyp == DIVA_IPAC_ISA) ? "IPAC ISA" :
		(cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI",
		cs->hw.diva.cfg_reg, cs->irq);
	if ((cs->subtyp == DIVA_IPAC_PCI)  || 
	    (cs->subtyp == DIVA_IPACX_PCI) || 
	    (cs->subtyp == DIVA_PCI)         )
		printk(KERN_INFO "Diva: %s space at %#lx\n",
			(cs->subtyp == DIVA_PCI) ? "PCI" :
			(cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI",
			cs->hw.diva.pci_cfg);
	if ((cs->subtyp != DIVA_IPAC_PCI) &&
	    (cs->subtyp != DIVA_IPACX_PCI)   ) {
		if (!request_region(cs->hw.diva.cfg_reg, bytecnt, "diva isdn")) {
			printk(KERN_WARNING
			       "HiSax: %s config port %lx-%lx already in use\n",
			       "diva",
			       cs->hw.diva.cfg_reg,
			       cs->hw.diva.cfg_reg + bytecnt);
			iounmap_diva(cs);
			return (0);
		}
	}
	cs->BC_Read_Reg  = &ReadHSCX;
	cs->BC_Write_Reg = &WriteHSCX;
	cs->BC_Send_Data = &hscx_fill_fifo;
	cs->cardmsg = &Diva_card_msg;
	setup_isac(cs);
	if (cs->subtyp == DIVA_IPAC_ISA) {
		cs->readisac  = &ReadISAC_IPAC;
		cs->writeisac = &WriteISAC_IPAC;
		cs->readisacfifo  = &ReadISACfifo_IPAC;
		cs->writeisacfifo = &WriteISACfifo_IPAC;
		cs->irq_func = &diva_irq_ipac_isa;
		val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ID);
		printk(KERN_INFO "Diva: IPAC version %x\n", val);
	} else if (cs->subtyp == DIVA_IPAC_PCI) {
		cs->readisac  = &MemReadISAC_IPAC;
		cs->writeisac = &MemWriteISAC_IPAC;
		cs->readisacfifo  = &MemReadISACfifo_IPAC;
		cs->writeisacfifo = &MemWriteISACfifo_IPAC;
		cs->BC_Read_Reg  = &MemReadHSCX;
		cs->BC_Write_Reg = &MemWriteHSCX;
		cs->BC_Send_Data = &Memhscx_fill_fifo;
		cs->irq_func = &diva_irq_ipac_pci;
		val = memreadreg(cs->hw.diva.cfg_reg, IPAC_ID);
		printk(KERN_INFO "Diva: IPAC version %x\n", val);
	} else if (cs->subtyp == DIVA_IPACX_PCI) {
		cs->readisac  = &MemReadISAC_IPACX;
		cs->writeisac = &MemWriteISAC_IPACX;
		cs->readisacfifo  = &MemReadISACfifo_IPACX;
		cs->writeisacfifo = &MemWriteISACfifo_IPACX;
		cs->BC_Read_Reg  = &MemReadHSCX_IPACX;
		cs->BC_Write_Reg = &MemWriteHSCX_IPACX;
		cs->BC_Send_Data = NULL; 
		cs->irq_func = &diva_irq_ipacx_pci;
		printk(KERN_INFO "Diva: IPACX Design Id: %x\n", 
			MemReadISAC_IPACX(cs, IPACX_ID) &0x3F);
	} else { 
		cs->hw.diva.tl.function = (void *) diva_led_handler;
		cs->hw.diva.tl.data = (long) cs;
		init_timer(&cs->hw.diva.tl);
		cs->readisac  = &ReadISAC;
		cs->writeisac = &WriteISAC;
		cs->readisacfifo  = &ReadISACfifo;
		cs->writeisacfifo = &WriteISACfifo;
		cs->irq_func = &diva_interrupt;
		ISACVersion(cs, "Diva:");
		if (HscxVersion(cs, "Diva:")) {
			printk(KERN_WARNING
		       "Diva: wrong HSCX versions check IO address\n");
			release_io_diva(cs);
			return (0);
		}
	}
	return (1);
}
Beispiel #12
0
int __init
setup_asuscom(struct IsdnCard *card)
{
	int bytecnt;
	struct IsdnCardState *cs = card->cs;
	u_char val;
	char tmp[64];

	strcpy(tmp, Asuscom_revision);
	printk(KERN_INFO "HiSax: Asuscom ISDNLink driver Rev. %s\n", HiSax_getrev(tmp));
	if (cs->typ != ISDN_CTYPE_ASUSCOM)
		return (0);
#ifdef __ISAPNP__
	if (!card->para[1] && isapnp_present()) {
		struct pci_bus *pb;
		struct pci_dev *pd;

		while(adev->card_vendor) {
			if ((pb = isapnp_find_card(adev->card_vendor,
				adev->card_device, pnp_c))) {
				pnp_c = pb;
				pd = NULL;
				if ((pd = isapnp_find_dev(pnp_c,
					adev->vendor, adev->function, pd))) {
					printk(KERN_INFO "HiSax: %s detected\n",
						(char *)adev->driver_data);
					pd->prepare(pd);
					pd->deactivate(pd);
					pd->activate(pd);
					card->para[1] = pd->resource[0].start;
					card->para[0] = pd->irq_resource[0].start;
					if (!card->para[0] || !card->para[1]) {
						printk(KERN_ERR "AsusPnP:some resources are missing %ld/%lx\n",
						card->para[0], card->para[1]);
						pd->deactivate(pd);
						return(0);
					}
					break;
				} else {
					printk(KERN_ERR "AsusPnP: PnP error card found, no device\n");
				}
			}
			adev++;
			pnp_c=NULL;
		} 
		if (!adev->card_vendor) {
			printk(KERN_INFO "AsusPnP: no ISAPnP card found\n");
			return(0);
		}
	}
#endif
	bytecnt = 8;
	cs->hw.asus.cfg_reg = card->para[1];
	cs->irq = card->para[0];
	if (check_region((cs->hw.asus.cfg_reg), bytecnt)) {
		printk(KERN_WARNING
		       "HiSax: %s config port %x-%x already in use\n",
		       CardType[card->typ],
		       cs->hw.asus.cfg_reg,
		       cs->hw.asus.cfg_reg + bytecnt);
		return (0);
	} else {
		request_region(cs->hw.asus.cfg_reg, bytecnt, "asuscom isdn");
	}
	printk(KERN_INFO "ISDNLink: defined at 0x%x IRQ %d\n",
		cs->hw.asus.cfg_reg, cs->irq);
	cs->BC_Read_Reg = &ReadHSCX;
	cs->BC_Write_Reg = &WriteHSCX;
	cs->BC_Send_Data = &hscx_fill_fifo;
	cs->cardmsg = &Asus_card_msg;
	val = readreg(cs->hw.asus.cfg_reg + ASUS_IPAC_ALE, 
		cs->hw.asus.cfg_reg + ASUS_IPAC_DATA, IPAC_ID);
	if ((val == 1) || (val == 2)) {
		cs->subtyp = ASUS_IPAC;
		cs->hw.asus.adr  = cs->hw.asus.cfg_reg + ASUS_IPAC_ALE;
		cs->hw.asus.isac = cs->hw.asus.cfg_reg + ASUS_IPAC_DATA;
		cs->hw.asus.hscx = cs->hw.asus.cfg_reg + ASUS_IPAC_DATA;
		test_and_set_bit(HW_IPAC, &cs->HW_Flags);
		cs->readisac = &ReadISAC_IPAC;
		cs->writeisac = &WriteISAC_IPAC;
		cs->readisacfifo = &ReadISACfifo_IPAC;
		cs->writeisacfifo = &WriteISACfifo_IPAC;
		cs->irq_func = &asuscom_interrupt_ipac;
		printk(KERN_INFO "Asus: IPAC version %x\n", val);
	} else {
		cs->subtyp = ASUS_ISACHSCX;
		cs->hw.asus.adr = cs->hw.asus.cfg_reg + ASUS_ADR;
		cs->hw.asus.isac = cs->hw.asus.cfg_reg + ASUS_ISAC;
		cs->hw.asus.hscx = cs->hw.asus.cfg_reg + ASUS_HSCX;
		cs->hw.asus.u7 = cs->hw.asus.cfg_reg + ASUS_CTRL_U7;
		cs->hw.asus.pots = cs->hw.asus.cfg_reg + ASUS_CTRL_POTS;
		cs->readisac = &ReadISAC;
		cs->writeisac = &WriteISAC;
		cs->readisacfifo = &ReadISACfifo;
		cs->writeisacfifo = &WriteISACfifo;
		cs->irq_func = &asuscom_interrupt;
		ISACVersion(cs, "ISDNLink:");
		if (HscxVersion(cs, "ISDNLink:")) {
			printk(KERN_WARNING
		     	"ISDNLink: wrong HSCX versions check IO address\n");
			release_io_asuscom(cs);
			return (0);
		}
	}
	printk(KERN_INFO "ISDNLink: resetting card\n");
	reset_asuscom(cs);
	return (1);
}
Beispiel #13
0
static int
net_send_packet(struct sk_buff *skb, struct device *dev)
{
	if (dev->tbusy) {
		/* If we get here, some higher level has decided we are broken.
		   There should really be a "kick me" function call instead. */
		int tickssofar = jiffies - dev->trans_start;
		if (tickssofar < 5)
			return 1;
		if (net_debug > 0) printk("%s: transmit timed out, %s?\n", dev->name,
			   tx_done(dev) ? "IRQ conflict" : "network cable problem");
		/* Try to restart the adaptor. */
		dev->tbusy=0;
		dev->trans_start = jiffies;
	}

	/* If some higher layer thinks we've missed an tx-done interrupt
	   we are passed NULL. Caution: dev_tint() handles the cli()/sti()
	   itself. */
	if (skb == NULL) {
		dev_tint(dev);
		return 0;
	}

	/* Block a timer-based transmit from overlapping.  This could better be
	   done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
	if (set_bit(0, (void*)&dev->tbusy) != 0)
		printk("%s: Transmitter access conflict.\n", dev->name);
	else {
		struct net_local *lp = (struct net_local *)dev->priv;
		unsigned long ioaddr = dev->base_addr;
		unsigned long flags;

		if (net_debug > 3)printk("%s: sent %ld byte packet of type %x\n", dev->name, skb->len, (skb->data[ETH_ALEN+ETH_ALEN] << 8) | skb->data[ETH_ALEN+ETH_ALEN+1]);

		/* keep the upload from being interrupted, since we
                   ask the chip to start transmitting before the
                   whole packet has been completely uploaded. */
		save_flags(flags);
		cli();

		/* initiate a transmit sequence */
		outw(lp->send_cmd, ioaddr + TX_CMD_PORT);
		outw(skb->len, ioaddr + TX_LEN_PORT);

		/* Test to see if the chip has allocated memory for the packet */
		if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
			/* Gasp!  It hasn't.  But that shouldn't happen since
			   we're waiting for TxOk, so return 1 and requeue this packet. */
			restore_flags(flags);
			printk("cs8900 did not allocate memory for tx!\n");
			return 1;
		}

		/* Write the contents of the packet */
                outsw(ioaddr + TX_FRAME_PORT,skb->data,(skb->len+1) >>1);

		restore_flags(flags);
		dev->trans_start = jiffies;
	}
	dev_kfree_skb (skb, FREE_WRITE);

	return 0;
}
Beispiel #14
0
/* Open/initialize the board.  This is called (in the current kernel)
   sometime after booting when the 'ifconfig' program is run.

   This routine should set everything up anew at each open, even
   registers that "should" only need to be set once at boot, so that
   there is non-reboot way to recover if something goes wrong.
   */
static int
net_open(struct device *dev)
{
	struct net_local *lp = (struct net_local *)dev->priv;
	int result = 0;
//	int i;

	write_irq(dev, lp->chip_type, 0);

	irq2dev_map[/* FIXME */ 0] = dev;
	writereg(dev, PP_BusCTL, 0); /* ints off! */

#ifdef CONFIG_UCSIMM
	*(volatile unsigned short *)0xfffff302 |= 0x0080; /* +ve pol irq */

        if (request_irq(IRQ_MACHSPEC | IRQ5_IRQ_NUM,
                        cs8900_interrupt,
                        IRQ_FLG_STD,
                        "CrystalLAN_cs8900a", NULL))
                panic("Unable to attach cs8900 intr\n");
#endif

#ifdef CONFIG_ARCH_ATMEL
	/* We use IRQ_IRQ1 for the network interrupt */
        if (request_irq(IRQ_MACHSPEC | IRQ_IRQ1,
                        cs8900_interrupt,
                        IRQ_FLG_STD,
                        "CrystalLAN_cs8900a", NULL))
                panic("Unable to attach cs8900 intr\n");                        
#endif

#ifdef CONFIG_ALMA_ANS
	/* We use positive polarity IRQ3 as a network interrupt */
	ICR |= ICR_POL3;

        if (request_irq(IRQ_MACHSPEC | IRQ3_IRQ_NUM,
                        cs8900_interrupt,
                        IRQ_FLG_STD,
                        "CrystalLAN_cs8900a", NULL))
                panic("Unable to attach cs8900 intr\n");                        
#endif

#ifdef CONFIG_MWI

	/* We use vector position 28 as network interrupt */
	if (request_irq(IRQ_MACHSPEC| 28,
			cs8900_interrupt,
			IRQ_FLG_STD,
			"cs8900a", NULL))
		panic("Unable to attach cs8900 intr\n");

	/* setup porte */
	*(volatile unsigned char *)0xfffa15 &= 0xfb;
	*(volatile unsigned char *)0xfffa17 |= 0x04;
	
	/* setup portf */
	*(volatile unsigned char *)0xfffa1d &= 0x7f;
	*(volatile unsigned char *)0xfffa1f |= 0x10;
#endif
	/* set the Ethernet address */
	set_mac_address(dev, dev->dev_addr);

	/* Set the LineCTL */
	lp->linectl = 0;

        /* check to make sure that they have the "right" hardware available */
	switch(lp->adapter_cnf & A_CNF_MEDIA_TYPE) {
	case A_CNF_MEDIA_10B_T:
		result = lp->adapter_cnf & A_CNF_10B_T;
		break;
	case A_CNF_MEDIA_AUI:
		result = lp->adapter_cnf & A_CNF_AUI;
		break;
	case A_CNF_MEDIA_10B_2:
		result = lp->adapter_cnf & A_CNF_10B_2;
		break;
        default:
		result = lp->adapter_cnf & 
		         (A_CNF_10B_T | A_CNF_AUI | A_CNF_10B_2);
        }
        if (!result) {
                printk("%s: EEPROM is configured for unavailable media\n", dev->name);
        release_irq:
                writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) & ~(SERIAL_TX_ON | SERIAL_RX_ON));
                irq2dev_map[dev->irq] = 0;
		return -EAGAIN;
	}

        /* set the hardware to the configured choice */
	switch(lp->adapter_cnf & A_CNF_MEDIA_TYPE) {
	case A_CNF_MEDIA_10B_T:
                result = detect_tp(dev);
                if (!result) printk("%s: 10Base-T (RJ-45) has no cable\n", dev->name);
                if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */
                        result = A_CNF_MEDIA_10B_T; /* Yes! I don't care if I see a link pulse */
		break;
	case A_CNF_MEDIA_AUI:
	  printk("AUI?  What stinking AUI?\n");
		break;
	case A_CNF_MEDIA_10B_2:
	  printk("10Base2?  What stinking 10Base2?\n");
		break;
	case A_CNF_MEDIA_AUTO:
		writereg(dev, PP_LineCTL, lp->linectl | AUTO_AUI_10BASET);
		if (lp->adapter_cnf & A_CNF_10B_T)
			if ((result = detect_tp(dev)) != 0)
				break;

		printk("%s: no media detected\n", dev->name);
                goto release_irq;
	}
	switch(result) {
	case 0: printk("%s: no network cable attached to configured media\n", dev->name);
                goto release_irq;
	case A_CNF_MEDIA_10B_T: printk("%s: using 10Base-T (RJ-45)\n", dev->name);break;
	case A_CNF_MEDIA_AUI:   printk("%s: using 10Base-5 (AUI)\n", dev->name);break;
	case A_CNF_MEDIA_10B_2: printk("%s: using 10Base-2 (BNC)\n", dev->name);break;
	default: printk("%s: unexpected result was %x\n", dev->name, result); goto release_irq;
	}

	/* Turn on both receive and transmit operations */
	writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON);

	/* Receive only error free packets addressed to this card */
	lp->rx_mode = 0;
	writereg(dev, PP_RxCTL, DEF_RX_ACCEPT);

	lp->curr_rx_cfg = RX_OK_ENBL | RX_CRC_ERROR_ENBL;
	if (lp->isa_config & STREAM_TRANSFER)
		lp->curr_rx_cfg |= RX_STREAM_ENBL;

	writereg(dev, PP_RxCFG, lp->curr_rx_cfg);

	writereg(dev, PP_TxCFG, TX_LOST_CRS_ENBL | TX_SQE_ERROR_ENBL | TX_OK_ENBL |
	       TX_LATE_COL_ENBL | TX_JBR_ENBL | TX_ANY_COL_ENBL | TX_16_COL_ENBL);

	writereg(dev, PP_BufCFG, READY_FOR_TX_ENBL | RX_MISS_COUNT_OVRFLOW_ENBL |
		 TX_COL_COUNT_OVRFLOW_ENBL | TX_UNDERRUN_ENBL);

	/* now that we've got our act together, enable everything */
	writereg(dev, PP_BusCTL, ENABLE_IRQ
                 );
	dev->tbusy = 0;
	dev->interrupt = 0;
	dev->start = 1;
	return 0;
}
Beispiel #15
0
static u_char
ReadISAC(struct IsdnCardState *cs, u_char offset)
{
	return (readreg(cs->hw.ax.base, cs->hw.ax.data_adr, offset | 0x80));
}
Beispiel #16
0
int __devinit
setup_diva(struct IsdnCard *card)
{
	int bytecnt = 8;
	u_char val;
	struct IsdnCardState *cs = card->cs;
	char tmp[64];

	strcpy(tmp, Diva_revision);
	printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp));
	if (cs->typ != ISDN_CTYPE_DIEHLDIVA)
		return(0);
	cs->hw.diva.status = 0;
	if (card->para[1]) {
		cs->hw.diva.ctrl_reg = 0;
		cs->hw.diva.cfg_reg = card->para[1];
		val = readreg(cs->hw.diva.cfg_reg + DIVA_IPAC_ADR,
			cs->hw.diva.cfg_reg + DIVA_IPAC_DATA, IPAC_ID);
		printk(KERN_INFO "Diva: IPAC version %x\n", val);
		if ((val == 1) || (val==2)) {
			cs->subtyp = DIVA_IPAC_ISA;
			cs->hw.diva.ctrl = 0;
			cs->hw.diva.isac = card->para[1] + DIVA_IPAC_DATA;
			cs->hw.diva.hscx = card->para[1] + DIVA_IPAC_DATA;
			cs->hw.diva.isac_adr = card->para[1] + DIVA_IPAC_ADR;
			cs->hw.diva.hscx_adr = card->para[1] + DIVA_IPAC_ADR;
			test_and_set_bit(HW_IPAC, &cs->HW_Flags);
		} else {
			cs->subtyp = DIVA_ISA;
			cs->hw.diva.ctrl = card->para[1] + DIVA_ISA_CTRL;
			cs->hw.diva.isac = card->para[1] + DIVA_ISA_ISAC_DATA;
			cs->hw.diva.hscx = card->para[1] + DIVA_HSCX_DATA;
			cs->hw.diva.isac_adr = card->para[1] + DIVA_ISA_ISAC_ADR;
			cs->hw.diva.hscx_adr = card->para[1] + DIVA_HSCX_ADR;
		}
		cs->irq = card->para[0];
	} else {
#ifdef __ISAPNP__
		if (isapnp_present()) {
			struct pnp_dev *pnp_d;
			while(ipid->card_vendor) {
				if ((pnp_c = pnp_find_card(ipid->card_vendor,
					ipid->card_device, pnp_c))) {
					pnp_d = NULL;
					if ((pnp_d = pnp_find_dev(pnp_c,
						ipid->vendor, ipid->function, pnp_d))) {
						int err;

						printk(KERN_INFO "HiSax: %s detected\n",
							(char *)ipid->driver_data);
						pnp_disable_dev(pnp_d);
						err = pnp_activate_dev(pnp_d);
						if (err<0) {
							printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n",
								__FUNCTION__, err);
							return(0);
						}
						card->para[1] = pnp_port_start(pnp_d, 0);
						card->para[0] = pnp_irq(pnp_d, 0);
						if (!card->para[0] || !card->para[1]) {
							printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n",
								card->para[0], card->para[1]);
							pnp_disable_dev(pnp_d); 
							return(0);
						}
						cs->hw.diva.cfg_reg  = card->para[1];
						cs->irq = card->para[0];
						if (ipid->function == ISAPNP_FUNCTION(0xA1)) {
							cs->subtyp = DIVA_IPAC_ISA;
							cs->hw.diva.ctrl = 0;
							cs->hw.diva.isac =
								card->para[1] + DIVA_IPAC_DATA;
							cs->hw.diva.hscx =
								card->para[1] + DIVA_IPAC_DATA;
							cs->hw.diva.isac_adr =
								card->para[1] + DIVA_IPAC_ADR;
							cs->hw.diva.hscx_adr =
								card->para[1] + DIVA_IPAC_ADR;
							test_and_set_bit(HW_IPAC, &cs->HW_Flags);
						} else {
							cs->subtyp = DIVA_ISA;
							cs->hw.diva.ctrl =
								card->para[1] + DIVA_ISA_CTRL;
							cs->hw.diva.isac =
								card->para[1] + DIVA_ISA_ISAC_DATA;
							cs->hw.diva.hscx =
								card->para[1] + DIVA_HSCX_DATA;
							cs->hw.diva.isac_adr =
								card->para[1] + DIVA_ISA_ISAC_ADR;
							cs->hw.diva.hscx_adr =
								card->para[1] + DIVA_HSCX_ADR;
						}
						goto ready;
					} else {
						printk(KERN_ERR "Diva PnP: PnP error card found, no device\n");
						return(0);
					}
				}
				ipid++;
				pnp_c=NULL;
			} 
			if (!ipid->card_vendor) {
				printk(KERN_INFO "Diva PnP: no ISAPnP card found\n");
			}
		}
#endif
#ifdef CONFIG_PCI
		cs->subtyp = 0;
		if ((dev_diva = pci_find_device(PCI_VENDOR_ID_EICON,
			PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) {
			if (pci_enable_device(dev_diva))
				return(0);
			cs->subtyp = DIVA_PCI;
			cs->irq = dev_diva->irq;
			cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2);
		} else if ((dev_diva_u = pci_find_device(PCI_VENDOR_ID_EICON,
			PCI_DEVICE_ID_EICON_DIVA20_U, dev_diva_u))) {
			if (pci_enable_device(dev_diva_u))
				return(0);
			cs->subtyp = DIVA_PCI;
			cs->irq = dev_diva_u->irq;
			cs->hw.diva.cfg_reg = pci_resource_start(dev_diva_u, 2);
		} else if ((dev_diva201 = pci_find_device(PCI_VENDOR_ID_EICON,
			PCI_DEVICE_ID_EICON_DIVA201, dev_diva201))) {
			if (pci_enable_device(dev_diva201))
				return(0);
			cs->subtyp = DIVA_IPAC_PCI;
			cs->irq = dev_diva201->irq;
			cs->hw.diva.pci_cfg =
				(ulong) ioremap(pci_resource_start(dev_diva201, 0), 4096);
			cs->hw.diva.cfg_reg =
				(ulong) ioremap(pci_resource_start(dev_diva201, 1), 4096);
		} else if ((dev_diva202 = pci_find_device(PCI_VENDOR_ID_EICON,
			PCI_DEVICE_ID_EICON_DIVA202, dev_diva202))) {
			if (pci_enable_device(dev_diva202))
				return(0);
			cs->subtyp = DIVA_IPACX_PCI;
			cs->irq = dev_diva202->irq;
			cs->hw.diva.pci_cfg =
				(ulong) ioremap(pci_resource_start(dev_diva202, 0), 4096);
			cs->hw.diva.cfg_reg =
				(ulong) ioremap(pci_resource_start(dev_diva202, 1), 4096);
		} else {
			printk(KERN_WARNING "Diva: No PCI card found\n");
			return(0);
		}

		if (!cs->irq) {
			printk(KERN_WARNING "Diva: No IRQ for PCI card found\n");
			iounmap_diva(cs);
			return(0);
		}

		if (!cs->hw.diva.cfg_reg) {
			printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n");
			iounmap_diva(cs);
			return(0);
		}
		cs->irq_flags |= IRQF_SHARED;
#else
		printk(KERN_WARNING "Diva: cfgreg 0 and NO_PCI_BIOS\n");
		printk(KERN_WARNING "Diva: unable to config DIVA PCI\n");
		return (0);
#endif /* CONFIG_PCI */
		if ((cs->subtyp == DIVA_IPAC_PCI) ||
		    (cs->subtyp == DIVA_IPACX_PCI)   ) {
			cs->hw.diva.ctrl = 0;
			cs->hw.diva.isac = 0;
			cs->hw.diva.hscx = 0;
			cs->hw.diva.isac_adr = 0;
			cs->hw.diva.hscx_adr = 0;
			test_and_set_bit(HW_IPAC, &cs->HW_Flags);
			bytecnt = 0;
		} else {
			cs->hw.diva.ctrl = cs->hw.diva.cfg_reg + DIVA_PCI_CTRL;
			cs->hw.diva.isac = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_DATA;
			cs->hw.diva.hscx = cs->hw.diva.cfg_reg + DIVA_HSCX_DATA;
			cs->hw.diva.isac_adr = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_ADR;
			cs->hw.diva.hscx_adr = cs->hw.diva.cfg_reg + DIVA_HSCX_ADR;
			bytecnt = 32;
		}
	}

#ifdef __ISAPNP__
ready:
#endif

	printk(KERN_INFO
		"Diva: %s card configured at %#lx IRQ %d\n",
		(cs->subtyp == DIVA_PCI) ? "PCI" :
		(cs->subtyp == DIVA_ISA) ? "ISA" : 
		(cs->subtyp == DIVA_IPAC_ISA) ? "IPAC ISA" :
		(cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI",
		cs->hw.diva.cfg_reg, cs->irq);
	if ((cs->subtyp == DIVA_IPAC_PCI)  || 
	    (cs->subtyp == DIVA_IPACX_PCI) || 
	    (cs->subtyp == DIVA_PCI)         )
		printk(KERN_INFO "Diva: %s space at %#lx\n",
			(cs->subtyp == DIVA_PCI) ? "PCI" :
			(cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI",
			cs->hw.diva.pci_cfg);
	if ((cs->subtyp != DIVA_IPAC_PCI) &&
	    (cs->subtyp != DIVA_IPACX_PCI)   ) {
		if (!request_region(cs->hw.diva.cfg_reg, bytecnt, "diva isdn")) {
			printk(KERN_WARNING
			       "HiSax: %s config port %lx-%lx already in use\n",
			       CardType[card->typ],
			       cs->hw.diva.cfg_reg,
			       cs->hw.diva.cfg_reg + bytecnt);
			iounmap_diva(cs);
			return (0);
		}
	}
	cs->BC_Read_Reg  = &ReadHSCX;
	cs->BC_Write_Reg = &WriteHSCX;
	cs->BC_Send_Data = &hscx_fill_fifo;
	cs->cardmsg = &Diva_card_msg;
	setup_isac(cs);
	if (cs->subtyp == DIVA_IPAC_ISA) {
		cs->readisac  = &ReadISAC_IPAC;
		cs->writeisac = &WriteISAC_IPAC;
		cs->readisacfifo  = &ReadISACfifo_IPAC;
		cs->writeisacfifo = &WriteISACfifo_IPAC;
		cs->irq_func = &diva_irq_ipac_isa;
		val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ID);
		printk(KERN_INFO "Diva: IPAC version %x\n", val);
	} else if (cs->subtyp == DIVA_IPAC_PCI) {
		cs->readisac  = &MemReadISAC_IPAC;
		cs->writeisac = &MemWriteISAC_IPAC;
		cs->readisacfifo  = &MemReadISACfifo_IPAC;
		cs->writeisacfifo = &MemWriteISACfifo_IPAC;
		cs->BC_Read_Reg  = &MemReadHSCX;
		cs->BC_Write_Reg = &MemWriteHSCX;
		cs->BC_Send_Data = &Memhscx_fill_fifo;
		cs->irq_func = &diva_irq_ipac_pci;
		val = memreadreg(cs->hw.diva.cfg_reg, IPAC_ID);
		printk(KERN_INFO "Diva: IPAC version %x\n", val);
	} else if (cs->subtyp == DIVA_IPACX_PCI) {
		cs->readisac  = &MemReadISAC_IPACX;
		cs->writeisac = &MemWriteISAC_IPACX;
		cs->readisacfifo  = &MemReadISACfifo_IPACX;
		cs->writeisacfifo = &MemWriteISACfifo_IPACX;
		cs->BC_Read_Reg  = &MemReadHSCX_IPACX;
		cs->BC_Write_Reg = &MemWriteHSCX_IPACX;
		cs->BC_Send_Data = NULL; // function located in ipacx module
		cs->irq_func = &diva_irq_ipacx_pci;
		printk(KERN_INFO "Diva: IPACX Design Id: %x\n", 
			MemReadISAC_IPACX(cs, IPACX_ID) &0x3F);
	} else { /* DIVA 2.0 */
		cs->hw.diva.tl.function = (void *) diva_led_handler;
		cs->hw.diva.tl.data = (long) cs;
		init_timer(&cs->hw.diva.tl);
		cs->readisac  = &ReadISAC;
		cs->writeisac = &WriteISAC;
		cs->readisacfifo  = &ReadISACfifo;
		cs->writeisacfifo = &WriteISACfifo;
		cs->irq_func = &diva_interrupt;
		ISACVersion(cs, "Diva:");
		if (HscxVersion(cs, "Diva:")) {
			printk(KERN_WARNING
		       "Diva: wrong HSCX versions check IO address\n");
			release_io_diva(cs);
			return (0);
		}
	}
	return (1);
}
Beispiel #17
0
static u_int
ingenic_count_read(struct timecounter *tc)
{
	return readreg(JZ_OST_CNT_LO);
}
Beispiel #18
0
static u_char
ReadISAC(struct IsdnCardState *cs, u_char offset)
{
	return (readreg(cs->hw.ax.isac_ale, cs->hw.ax.isac_adr, offset));
}
Beispiel #19
0
static u_char ReadISAC(struct IsdnCardState *cs, u_char offset)
{
	return readreg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, offset);
}
Beispiel #20
0
static u_char
ReadJADE(struct IsdnCardState *cs, int jade, u_char offset)
{
	return (readreg(cs->hw.ax.jade_ale, cs->hw.ax.jade_adr, offset + (jade == -1 ? 0 : (jade ? 0xC0 : 0x80))));
}
Beispiel #21
0
static u_char
ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
{
	return (readreg(cs->hw.teles3.hscx[hscx], offset));
}
static irqreturn_t
elsa_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
	struct IsdnCardState *cs = dev_id;
	u_long flags;
	u_char val;
	int icnt=5;

	if ((cs->typ == ISDN_CTYPE_ELSA_PCMCIA) && (*cs->busy_flag == 1)) {
	/* The card tends to generate interrupts while being removed
	   causing us to just crash the kernel. bad. */
		printk(KERN_WARNING "Elsa: card not available!\n");
		return IRQ_NONE;
	}
	spin_lock_irqsave(&cs->lock, flags);
#if ARCOFI_USE
	if (cs->hw.elsa.MFlag) {
		val = serial_inp(cs, UART_IIR);
		if (!(val & UART_IIR_NO_INT)) {
			debugl1(cs,"IIR %02x", val);
			rs_interrupt_elsa(intno, cs);
		}
	}
#endif
	val = readreg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_ISTA + 0x40);
      Start_HSCX:
	if (val) {
		hscx_int_main(cs, val);
	}
	val = readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, ISAC_ISTA);
      Start_ISAC:
	if (val) {
		isac_interrupt(cs, val);
	}
	val = readreg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_ISTA + 0x40);
	if (val && icnt) {
		if (cs->debug & L1_DEB_HSCX)
			debugl1(cs, "HSCX IntStat after IntRoutine");
		icnt--;
		goto Start_HSCX;
	}
	val = readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, ISAC_ISTA);
	if (val && icnt) {
		if (cs->debug & L1_DEB_ISAC)
			debugl1(cs, "ISAC IntStat after IntRoutine");
		icnt--;
		goto Start_ISAC;
	}
	if (!icnt)
		printk(KERN_WARNING"ELSA IRQ LOOP\n");
	writereg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_MASK, 0xFF);
	writereg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_MASK + 0x40, 0xFF);
	writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, ISAC_MASK, 0xFF);
	if (cs->hw.elsa.status & ELSA_TIMER_AKTIV) {
		if (!TimerRun(cs)) {
			/* Timer Restart */
			byteout(cs->hw.elsa.timer, 0);
			cs->hw.elsa.counter++;
		}
	}
#if ARCOFI_USE
	if (cs->hw.elsa.MFlag) {
		val = serial_inp(cs, UART_MCR);
		val ^= 0x8;
		serial_outp(cs, UART_MCR, val);
		val = serial_inp(cs, UART_MCR);
		val ^= 0x8;
		serial_outp(cs, UART_MCR, val);
	}
#endif
	if (cs->hw.elsa.trig)
		byteout(cs->hw.elsa.trig, 0x00);
	writereg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_MASK, 0x0);
	writereg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_MASK + 0x40, 0x0);
	writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, ISAC_MASK, 0x0);
	spin_unlock_irqrestore(&cs->lock, flags);
	return IRQ_HANDLED;
}
Beispiel #23
0
/* Probe for the CS8900 card in slot E.  We won't bother looking
   anywhere else until we have a really good reason to do so. */
struct net_device * __init mac89x0_probe(int unit)
{
	struct net_device *dev;
	static int once_is_enough;
	struct net_local *lp;
	static unsigned version_printed;
	int i, slot;
	unsigned rev_type = 0;
	unsigned long ioaddr;
	unsigned short sig;
	int err = -ENODEV;

	if (!MACH_IS_MAC)
		return ERR_PTR(-ENODEV);

	dev = alloc_etherdev(sizeof(struct net_local));
	if (!dev)
		return ERR_PTR(-ENOMEM);

	if (unit >= 0) {
		sprintf(dev->name, "eth%d", unit);
		netdev_boot_setup_check(dev);
	}

	if (once_is_enough)
		goto out;
	once_is_enough = 1;

	/* We might have to parameterize this later */
	slot = 0xE;
	/* Get out now if there's a real NuBus card in slot E */
	if (nubus_find_slot(slot, NULL) != NULL)
		goto out;

	/* The pseudo-ISA bits always live at offset 0x300 (gee,
           wonder why...) */
	ioaddr = (unsigned long)
		nubus_slot_addr(slot) | (((slot&0xf) << 20) + DEFAULTIOBASE);
	{
		unsigned long flags;
		int card_present;

		local_irq_save(flags);
		card_present = (hwreg_present((void*) ioaddr+4) &&
				hwreg_present((void*) ioaddr + DATA_PORT));
		local_irq_restore(flags);

		if (!card_present)
			goto out;
	}

	nubus_writew(0, ioaddr + ADD_PORT);
	sig = nubus_readw(ioaddr + DATA_PORT);
	if (sig != swab16(CHIP_EISA_ID_SIG))
		goto out;

	/* Initialize the net_device structure. */
	lp = netdev_priv(dev);

	/* Fill in the 'dev' fields. */
	dev->base_addr = ioaddr;
	dev->mem_start = (unsigned long)
		nubus_slot_addr(slot) | (((slot&0xf) << 20) + MMIOBASE);
	dev->mem_end = dev->mem_start + 0x1000;

	/* Turn on shared memory */
	writereg_io(dev, PP_BusCTL, MEMORY_ON);

	/* get the chip type */
	rev_type = readreg(dev, PRODUCT_ID_ADD);
	lp->chip_type = rev_type &~ REVISON_BITS;
	lp->chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';

	/* Check the chip type and revision in order to set the correct send command
	CS8920 revision C and CS8900 revision F can use the faster send. */
	lp->send_cmd = TX_AFTER_381;
	if (lp->chip_type == CS8900 && lp->chip_revision >= 'F')
		lp->send_cmd = TX_NOW;
	if (lp->chip_type != CS8900 && lp->chip_revision >= 'C')
		lp->send_cmd = TX_NOW;

	if (net_debug && version_printed++ == 0)
;

//	printk(KERN_INFO "%s: cs89%c0%s rev %c found at %#8lx",
//	       dev->name,
//	       lp->chip_type==CS8900?'0':'2',
//	       lp->chip_type==CS8920M?"M":"",
//	       lp->chip_revision,
;

	/* Try to read the MAC address */
	if ((readreg(dev, PP_SelfST) & (EEPROM_PRESENT | EEPROM_OK)) == 0) {
;
		goto out1;
        } else {
                for (i = 0; i < ETH_ALEN; i += 2) {
			/* Big-endian (why??!) */
			unsigned short s = readreg(dev, PP_IA + i);
                        dev->dev_addr[i] = s >> 8;
                        dev->dev_addr[i+1] = s & 0xff;
                }
        }

	dev->irq = SLOT2IRQ(slot);

	/* print the IRQ and ethernet address. */

;

	dev->netdev_ops		= &mac89x0_netdev_ops;

	err = register_netdev(dev);
	if (err)
		goto out1;
	return NULL;
out1:
	nubus_writew(0, dev->base_addr + ADD_PORT);
out:
	free_netdev(dev);
	return ERR_PTR(err);
}
static irqreturn_t
elsa_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
{
	struct IsdnCardState *cs = dev_id;
	u_long flags;
	u_char ista,val;
	int icnt=5;

	spin_lock_irqsave(&cs->lock, flags);
	if (cs->subtyp == ELSA_QS1000PCI || cs->subtyp == ELSA_QS3000PCI) {
		val = bytein(cs->hw.elsa.cfg + 0x4c); /* PCI IRQ */
		if (!(val & ELSA_PCI_IRQ_MASK)) {
			spin_unlock_irqrestore(&cs->lock, flags);
			return IRQ_NONE;
		}
	}
#if ARCOFI_USE
	if (cs->hw.elsa.MFlag) {
		val = serial_inp(cs, UART_IIR);
		if (!(val & UART_IIR_NO_INT)) {
			debugl1(cs,"IIR %02x", val);
			rs_interrupt_elsa(intno, cs);
		}
	}
#endif
	ista = readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ISTA);
Start_IPAC:
	if (cs->debug & L1_DEB_IPAC)
		debugl1(cs, "IPAC ISTA %02X", ista);
	if (ista & 0x0f) {
		val = readreg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_ISTA + 0x40);
		if (ista & 0x01)
			val |= 0x01;
		if (ista & 0x04)
			val |= 0x02;
		if (ista & 0x08)
			val |= 0x04;
		if (val)
			hscx_int_main(cs, val);
	}
	if (ista & 0x20) {
		val = 0xfe & readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, ISAC_ISTA + 0x80);
		if (val) {
			isac_interrupt(cs, val);
		}
	}
	if (ista & 0x10) {
		val = 0x01;
		isac_interrupt(cs, val);
	}
	ista  = readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ISTA);
	if ((ista & 0x3f) && icnt) {
		icnt--;
		goto Start_IPAC;
	}
	if (!icnt)
		printk(KERN_WARNING "ELSA IRQ LOOP\n");
	writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_MASK, 0xFF);
	writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_MASK, 0xC0);
	spin_unlock_irqrestore(&cs->lock, flags);
	return IRQ_HANDLED;
}
Beispiel #25
0
static u_char
ReadISAC(struct IsdnCardState *cs, u_char offset)
{
	cs->hw.hfc.cip = offset;
	return (readreg(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, offset));
}
Beispiel #26
0
static u_char
ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
{
	return (readreg(cs->hw.ax.base, cs->hw.ax.data_adr, offset + (hscx ? 0x40 : 0)));
}
Beispiel #27
0
static u_char
ReadISAC(struct IsdnCardState *cs, u_char offset)
{
	return (readreg(cs->hw.mic.adr, cs->hw.mic.isac, offset));
}
Beispiel #28
0
int __devinit
setup_sct_quadro(struct IsdnCard *card)
{
	struct IsdnCardState *cs = card->cs;
	char tmp[64];
	u_int found = 0;
	u_int pci_ioaddr1, pci_ioaddr2, pci_ioaddr3, pci_ioaddr4, pci_ioaddr5;

	strcpy(tmp, sct_quadro_revision);
	printk(KERN_INFO "HiSax: T-Berkom driver Rev. %s\n", HiSax_getrev(tmp));
	if (cs->typ == ISDN_CTYPE_SCT_QUADRO) {
		cs->subtyp = SCT_1;	/* Preset */
	} else
		return (0);

	/* Identify subtype by para[0] */
	if (card->para[0] >= SCT_1 && card->para[0] <= SCT_4)
		cs->subtyp = card->para[0];
	else {
		printk(KERN_WARNING "HiSax: Scitel Quadro: Invalid "
		       "subcontroller in configuration, default to 1\n");
		return (0);
	}
	if ((cs->subtyp != SCT_1) && ((sub_sys_id != PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO) ||
		(sub_vendor_id != PCI_VENDOR_ID_BERKOM)))
		return (0);
	if (cs->subtyp == SCT_1) {
		while ((dev_a8 = pci_find_device(PCI_VENDOR_ID_PLX,
			PCI_DEVICE_ID_PLX_9050, dev_a8))) {
			
			sub_vendor_id = dev_a8->subsystem_vendor;
			sub_sys_id = dev_a8->subsystem_device;
			if ((sub_sys_id == PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO) &&
				(sub_vendor_id == PCI_VENDOR_ID_BERKOM)) {
				if (pci_enable_device(dev_a8))
					return(0);
				pci_ioaddr1 = pci_resource_start(dev_a8, 1);
				pci_irq = dev_a8->irq;
				pci_bus = dev_a8->bus->number;
				pci_device_fn = dev_a8->devfn;
				found = 1;
				break;
			}
		}
		if (!found) {
			printk(KERN_WARNING "HiSax: Scitel Quadro (%s): "
				"Card not found\n",
				sct_quadro_subtypes[cs->subtyp]);
			return (0);
		}
#ifdef ATTEMPT_PCI_REMAPPING
/* HACK: PLX revision 1 bug: PLX address bit 7 must not be set */
		if ((pci_ioaddr1 & 0x80) && (dev_a8->revision == 1)) {
			printk(KERN_WARNING "HiSax: Scitel Quadro (%s): "
				"PLX rev 1, remapping required!\n",
				sct_quadro_subtypes[cs->subtyp]);
			/* Restart PCI negotiation */
			pci_write_config_dword(dev_a8, PCI_BASE_ADDRESS_1, (u_int) - 1);
			/* Move up by 0x80 byte */
			pci_ioaddr1 += 0x80;
			pci_ioaddr1 &= PCI_BASE_ADDRESS_IO_MASK;
			pci_write_config_dword(dev_a8, PCI_BASE_ADDRESS_1, pci_ioaddr1);
			dev_a8->resource[ 1].start = pci_ioaddr1;
		}
#endif /* End HACK */
	}
	if (!pci_irq) {		/* IRQ range check ?? */
		printk(KERN_WARNING "HiSax: Scitel Quadro (%s): No IRQ\n",
		       sct_quadro_subtypes[cs->subtyp]);
		return (0);
	}
	pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_1, &pci_ioaddr1);
	pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_2, &pci_ioaddr2);
	pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_3, &pci_ioaddr3);
	pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_4, &pci_ioaddr4);
	pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_5, &pci_ioaddr5);
	if (!pci_ioaddr1 || !pci_ioaddr2 || !pci_ioaddr3 || !pci_ioaddr4 || !pci_ioaddr5) {
		printk(KERN_WARNING "HiSax: Scitel Quadro (%s): "
		       "No IO base address(es)\n",
		       sct_quadro_subtypes[cs->subtyp]);
		return (0);
	}
	pci_ioaddr1 &= PCI_BASE_ADDRESS_IO_MASK;
	pci_ioaddr2 &= PCI_BASE_ADDRESS_IO_MASK;
	pci_ioaddr3 &= PCI_BASE_ADDRESS_IO_MASK;
	pci_ioaddr4 &= PCI_BASE_ADDRESS_IO_MASK;
	pci_ioaddr5 &= PCI_BASE_ADDRESS_IO_MASK;
	/* Take over */
	cs->irq = pci_irq;
	cs->irq_flags |= IRQF_SHARED;
	/* pci_ioaddr1 is unique to all subdevices */
	/* pci_ioaddr2 is for the fourth subdevice only */
	/* pci_ioaddr3 is for the third subdevice only */
	/* pci_ioaddr4 is for the second subdevice only */
	/* pci_ioaddr5 is for the first subdevice only */
	cs->hw.ax.plx_adr = pci_ioaddr1;
	/* Enter all ipac_base addresses */
	switch(cs->subtyp) {
		case 1:
			cs->hw.ax.base = pci_ioaddr5 + 0x00;
			if (sct_alloc_io(pci_ioaddr1, 128))
				return(0);
			if (sct_alloc_io(pci_ioaddr5, 64))
				return(0);
			/* disable all IPAC */
			writereg(pci_ioaddr5, pci_ioaddr5 + 4,
				IPAC_MASK, 0xFF);
			writereg(pci_ioaddr4 + 0x08, pci_ioaddr4 + 0x0c,
				IPAC_MASK, 0xFF);
			writereg(pci_ioaddr3 + 0x10, pci_ioaddr3 + 0x14,
				IPAC_MASK, 0xFF);
			writereg(pci_ioaddr2 + 0x20, pci_ioaddr2 + 0x24,
				IPAC_MASK, 0xFF);
			break;
		case 2:
			cs->hw.ax.base = pci_ioaddr4 + 0x08;
			if (sct_alloc_io(pci_ioaddr4, 64))
				return(0);
			break;
		case 3:
			cs->hw.ax.base = pci_ioaddr3 + 0x10;
			if (sct_alloc_io(pci_ioaddr3, 64))
				return(0);
			break;
		case 4:
			cs->hw.ax.base = pci_ioaddr2 + 0x20;
			if (sct_alloc_io(pci_ioaddr2, 64))
				return(0);
			break;
	}	
	/* For isac and hscx data path */
	cs->hw.ax.data_adr = cs->hw.ax.base + 4;

	printk(KERN_INFO "HiSax: Scitel Quadro (%s) configured at "
	       "0x%.4lX, 0x%.4lX, 0x%.4lX and IRQ %d\n",
	       sct_quadro_subtypes[cs->subtyp],
	       cs->hw.ax.plx_adr,
	       cs->hw.ax.base,
	       cs->hw.ax.data_adr,
	       cs->irq);

	test_and_set_bit(HW_IPAC, &cs->HW_Flags);

	cs->readisac = &ReadISAC;
	cs->writeisac = &WriteISAC;
	cs->readisacfifo = &ReadISACfifo;
	cs->writeisacfifo = &WriteISACfifo;

	cs->BC_Read_Reg = &ReadHSCX;
	cs->BC_Write_Reg = &WriteHSCX;
	cs->BC_Send_Data = &hscx_fill_fifo;
	cs->cardmsg = &BKM_card_msg;
	cs->irq_func = &bkm_interrupt_ipac;

	printk(KERN_INFO "HiSax: Scitel Quadro (%s): IPAC Version %d\n",
		sct_quadro_subtypes[cs->subtyp],
		readreg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_ID));
	return (1);
}
static u_char
ReadISAC_IPAC(struct IsdnCardState *cs, u_char offset)
{
	return (readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset+0x80));
}
Beispiel #30
0
__initfunc(int
setup_sedlbauer(struct IsdnCard *card))
{
	int bytecnt, ver, val;
	struct IsdnCardState *cs = card->cs;
	char tmp[64];
	u16 sub_vendor_id, sub_id;
	long flags;

	strcpy(tmp, Sedlbauer_revision);
	printk(KERN_INFO "HiSax: Sedlbauer driver Rev. %s\n", HiSax_getrev(tmp));
	
 	if (cs->typ == ISDN_CTYPE_SEDLBAUER) {
 		cs->subtyp = SEDL_SPEED_CARD_WIN;
		cs->hw.sedl.bus = SEDL_BUS_ISA;
		cs->hw.sedl.chip = SEDL_CHIP_TEST;
 	} else if (cs->typ == ISDN_CTYPE_SEDLBAUER_PCMCIA) {	
 		cs->subtyp = SEDL_SPEED_STAR;
		cs->hw.sedl.bus = SEDL_BUS_PCMCIA;
		cs->hw.sedl.chip = SEDL_CHIP_TEST;
 	} else if (cs->typ == ISDN_CTYPE_SEDLBAUER_FAX) {	
 		cs->subtyp = SEDL_SPEED_FAX;
		cs->hw.sedl.bus = SEDL_BUS_ISA;
		cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
 	} else
		return (0);

	bytecnt = 8;
	if (card->para[1]) {
		cs->hw.sedl.cfg_reg = card->para[1];
		cs->irq = card->para[0];
		if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
			bytecnt = 16;
		}
	} else {
/* Probe for Sedlbauer speed pci */
#if SEDLBAUER_PCI
#if CONFIG_PCI
		if (!pci_present()) {
			printk(KERN_ERR "Sedlbauer: no PCI bus present\n");
			return(0);
		}
		if ((dev_sedl = pci_find_device(PCI_VENDOR_SEDLBAUER,
				PCI_SPEEDPCI_ID, dev_sedl))) {
			cs->irq = dev_sedl->irq;
			if (!cs->irq) {
				printk(KERN_WARNING "Sedlbauer: No IRQ for PCI card found\n");
				return(0);
			}
			cs->hw.sedl.cfg_reg = dev_sedl->base_address[ 0] &
				PCI_BASE_ADDRESS_IO_MASK; 
		} else {
			printk(KERN_WARNING "Sedlbauer: No PCI card found\n");
			return(0);
		}
		cs->irq_flags |= SA_SHIRQ;
		cs->hw.sedl.bus = SEDL_BUS_PCI;
		pci_read_config_word(dev_sedl, PCI_SUBSYSTEM_VENDOR_ID,
			&sub_vendor_id);
		pci_read_config_word(dev_sedl, PCI_SUBSYSTEM_ID,
			&sub_id);
		printk(KERN_INFO "Sedlbauer: PCI subvendor:%x subid %x\n",
			sub_vendor_id, sub_id);
		printk(KERN_INFO "Sedlbauer: PCI base adr %#x\n",
			cs->hw.sedl.cfg_reg);
		if ((sub_vendor_id == PCI_SUBVENDOR_SEDLBAUER) &&
			(sub_id == PCI_SUB_ID_SPEEDFAXP)) {
			cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
			cs->subtyp = SEDL_SPEEDFAX_PCI;
		} else {
			cs->hw.sedl.chip = SEDL_CHIP_IPAC;
			cs->subtyp = SEDL_SPEED_PCI;
		}
		bytecnt = 256;
		cs->hw.sedl.reset_on = SEDL_ISAR_PCI_ISAR_RESET_ON;
		cs->hw.sedl.reset_off = SEDL_ISAR_PCI_ISAR_RESET_OFF;
		byteout(cs->hw.sedl.cfg_reg, 0xff);
		byteout(cs->hw.sedl.cfg_reg, 0x00);
		byteout(cs->hw.sedl.cfg_reg+ 2, 0xdd);
		byteout(cs->hw.sedl.cfg_reg+ 5, 0x02);
		byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_on);
		save_flags(flags);
		sti();
		current->state = TASK_UNINTERRUPTIBLE;
		schedule_timeout((10*HZ)/1000);
		byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
		restore_flags(flags);
#else
		printk(KERN_WARNING "Sedlbauer: NO_PCI_BIOS\n");
		return (0);
#endif /* CONFIG_PCI */
#endif /* SEDLBAUER_PCI */
	}	
	
       	/* In case of the sedlbauer pcmcia card, this region is in use,
           reserved for us by the card manager. So we do not check it
           here, it would fail. */
	if (cs->hw.sedl.bus != SEDL_BUS_PCMCIA &&
		check_region((cs->hw.sedl.cfg_reg), bytecnt)) {
		printk(KERN_WARNING
			"HiSax: %s config port %x-%x already in use\n",
			CardType[card->typ],
			cs->hw.sedl.cfg_reg,
			cs->hw.sedl.cfg_reg + bytecnt);
			return (0);
	} else {
		request_region(cs->hw.sedl.cfg_reg, bytecnt, "sedlbauer isdn");
	}

	printk(KERN_INFO
	       "Sedlbauer: defined at 0x%x-0x%x IRQ %d\n",
	       cs->hw.sedl.cfg_reg,
	       cs->hw.sedl.cfg_reg + bytecnt,
	       cs->irq);

	cs->BC_Read_Reg = &ReadHSCX;
	cs->BC_Write_Reg = &WriteHSCX;
	cs->BC_Send_Data = &hscx_fill_fifo;
	cs->cardmsg = &Sedl_card_msg;

/*
 * testing ISA and PCMCIA Cards for IPAC, default is ISAC 
 * do not test for PCI card, because ports are different
 * and PCI card uses only IPAC (for the moment)
 */	
	if (cs->hw.sedl.bus != SEDL_BUS_PCI) {
		val = readreg(cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR,
        	        cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC, IPAC_ID);
	        if (val == 1) {
		/* IPAC */
                	cs->subtyp = SEDL_SPEED_WIN2_PC104;
			if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) {
				cs->subtyp = SEDL_SPEED_STAR2;
			}
			cs->hw.sedl.chip = SEDL_CHIP_IPAC;
		} else {
		/* ISAC_HSCX oder ISAC_ISAR */
			if (cs->hw.sedl.chip == SEDL_CHIP_TEST) {
				cs->hw.sedl.chip = SEDL_CHIP_ISAC_HSCX;
			}
		}
	}

/*
 * hw.sedl.chip is now properly set
 */
	printk(KERN_INFO "Sedlbauer: %s detected\n",
		Sedlbauer_Types[cs->subtyp]);


	if (cs->hw.sedl.chip == SEDL_CHIP_IPAC) {
	/* IPAC */
		if (cs->hw.sedl.bus == SEDL_BUS_PCI) {
	                cs->hw.sedl.adr  = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_ADR;
        	        cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC;
                	cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC;
		} else {
	                cs->hw.sedl.adr  = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR;
        	        cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC;
                	cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC;
		}
                test_and_set_bit(HW_IPAC, &cs->HW_Flags);
                cs->readisac = &ReadISAC_IPAC;
                cs->writeisac = &WriteISAC_IPAC;
                cs->readisacfifo = &ReadISACfifo_IPAC;
                cs->writeisacfifo = &WriteISACfifo_IPAC;
                cs->irq_func = &sedlbauer_interrupt_ipac;

		val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ID);
                printk(KERN_INFO "Sedlbauer: IPAC version %x\n", val);
		reset_sedlbauer(cs);
	} else {
	/* ISAC_HSCX oder ISAC_ISAR */
		cs->readisac = &ReadISAC;
		cs->writeisac = &WriteISAC;
		cs->readisacfifo = &ReadISACfifo;
		cs->writeisacfifo = &WriteISACfifo;
		if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
			if (cs->hw.sedl.bus == SEDL_BUS_PCI) {
				cs->hw.sedl.adr = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_PCI_ADR;
				cs->hw.sedl.isac = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_PCI_ISAC;
				cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_PCI_ISAR;
			} else {
				cs->hw.sedl.adr = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_ISA_ADR;
				cs->hw.sedl.isac = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_ISA_ISAC;
				cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_ISA_ISAR;
				cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_ISA_ISAR_RESET_ON;
				cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg +
							SEDL_ISAR_ISA_ISAR_RESET_OFF;
			}
			cs->bcs[0].hw.isar.reg = &cs->hw.sedl.isar;
			cs->bcs[1].hw.isar.reg = &cs->hw.sedl.isar;
			test_and_set_bit(HW_ISAR, &cs->HW_Flags);
			cs->irq_func = &sedlbauer_interrupt_isar;
			cs->auxcmd = &isar_auxcmd;
			ISACVersion(cs, "Sedlbauer:");
			cs->BC_Read_Reg = &ReadISAR;
			cs->BC_Write_Reg = &WriteISAR;
			cs->BC_Send_Data = &isar_fill_fifo;
			ver = ISARVersion(cs, "Sedlbauer:");
			if (ver < 0) {
				printk(KERN_WARNING
					"Sedlbauer: wrong ISAR version (ret = %d)\n", ver);
				release_io_sedlbauer(cs);
				return (0);
			}
		} else {
			if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) {
				cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ADR;
				cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ISAC;
				cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_HSCX;
				cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET;
				cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET;
			} else {
				cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ADR;
				cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ISAC;
				cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_HSCX;
				cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_ON;
				cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_OFF;
			}
			cs->irq_func = &sedlbauer_interrupt;
			ISACVersion(cs, "Sedlbauer:");
		
			if (HscxVersion(cs, "Sedlbauer:")) {
				printk(KERN_WARNING
					"Sedlbauer: wrong HSCX versions check IO address\n");
				release_io_sedlbauer(cs);
				return (0);
			}
			reset_sedlbauer(cs);
		}
	}
	return (1);
}