Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4b5a9b3d authored by Jeff Garzik's avatar Jeff Garzik
Browse files

[ISDN] HiSax diva: split setup into three smaller functions



Just code movement, and the glue to call the new functions.

Preparation for hotplug APIs.

Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent 7da0d980
Loading
Loading
Loading
Loading
+294 −219
Original line number Diff line number Diff line
@@ -25,8 +25,6 @@
#include <linux/pci.h>
#include <linux/isapnp.h>

extern const char *CardType[];

static const char *Diva_revision = "$Revision: 1.33.2.6 $";

#define byteout(addr,val) outb(val,addr)
@@ -906,53 +904,107 @@ Diva_card_msg(struct IsdnCardState *cs, int mt, void *arg)
	return(0);
}

static struct pci_dev *dev_diva __devinitdata = NULL;
static struct pci_dev *dev_diva_u __devinitdata = NULL;
static struct pci_dev *dev_diva201 __devinitdata = NULL;
static struct pci_dev *dev_diva202 __devinitdata = NULL;
static int __devinit setup_diva_common(struct IsdnCardState *cs)
{
	int bytecnt;
	u_char val;

#ifdef __ISAPNP__
static struct isapnp_device_id diva_ids[] __devinitdata = {
	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51),
	  ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), 
	  (unsigned long) "Diva picola" },
	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51),
	  ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x51), 
	  (unsigned long) "Diva picola" },
	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71),
	  ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), 
	  (unsigned long) "Diva 2.0" },
	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71),
	  ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x71), 
	  (unsigned long) "Diva 2.0" },
	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1),
	  ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), 
	  (unsigned long) "Diva 2.01" },
	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1),
	  ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0xA1), 
	  (unsigned long) "Diva 2.01" },
	{ 0, }
};
	if ((cs->subtyp == DIVA_ISA) || (cs->subtyp == DIVA_IPAC_ISA))
		bytecnt = 8;
	else
		bytecnt = 32;

static struct isapnp_device_id *ipid __devinitdata = &diva_ids[0];
static struct pnp_card *pnp_c __devinitdata = NULL;
#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",
			       "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; // 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);
}

#ifdef CONFIG_ISA

int __devinit
setup_diva(struct IsdnCard *card)
static int __devinit setup_diva_isa(struct IsdnCard *card)
{
	int bytecnt = 8;
	u_char val;
	struct IsdnCardState *cs = card->cs;
	char tmp[64];
	u_char val;

	if (!card->para[1])
		return (-1);	/* card not found; continue search */

	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,
@@ -975,10 +1027,53 @@ setup_diva(struct IsdnCard *card)
		cs->hw.diva.hscx_adr = card->para[1] + DIVA_HSCX_ADR;
	}
	cs->irq = card->para[0];
	} else {

	return (1);		/* card found */
}

#else	/* if !CONFIG_ISA */

static int __devinit setup_diva_isa(struct IsdnCard *card)
{
	return (-1);	/* card not found; continue search */
}

#endif	/* CONFIG_ISA */

#ifdef __ISAPNP__
		if (isapnp_present()) {
static struct isapnp_device_id diva_ids[] __devinitdata = {
	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51),
	  ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), 
	  (unsigned long) "Diva picola" },
	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51),
	  ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x51), 
	  (unsigned long) "Diva picola" },
	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71),
	  ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), 
	  (unsigned long) "Diva 2.0" },
	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71),
	  ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x71), 
	  (unsigned long) "Diva 2.0" },
	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1),
	  ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), 
	  (unsigned long) "Diva 2.01" },
	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1),
	  ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0xA1), 
	  (unsigned long) "Diva 2.01" },
	{ 0, }
};

static struct isapnp_device_id *ipid __devinitdata = &diva_ids[0];
static struct pnp_card *pnp_c __devinitdata = NULL;

static int __devinit setup_diva_isapnp(struct IsdnCard *card)
{
	struct IsdnCardState *cs = card->cs;
	struct pnp_dev *pnp_d;

	if (!isapnp_present())
		return (-1);	/* card not found; continue search */

	while(ipid->card_vendor) {
		if ((pnp_c = pnp_find_card(ipid->card_vendor,
			ipid->card_device, pnp_c))) {
@@ -1031,7 +1126,7 @@ setup_diva(struct IsdnCard *card)
					cs->hw.diva.hscx_adr =
						card->para[1] + DIVA_HSCX_ADR;
				}
						goto ready;
				return (1);		/* card found */
			} else {
				printk(KERN_ERR "Diva PnP: PnP error card found, no device\n");
				return(0);
@@ -1040,12 +1135,29 @@ setup_diva(struct IsdnCard *card)
		ipid++;
		pnp_c=NULL;
	} 
			if (!ipid->card_vendor) {
				printk(KERN_INFO "Diva PnP: no ISAPnP card found\n");

	return (-1);	/* card not found; continue search */
}

#else	/* if !ISAPNP */

static int __devinit setup_diva_isapnp(struct IsdnCard *card)
{
	return (-1);	/* card not found; continue search */
}
#endif

#endif	/* ISAPNP */

#ifdef CONFIG_PCI
static struct pci_dev *dev_diva __devinitdata = NULL;
static struct pci_dev *dev_diva_u __devinitdata = NULL;
static struct pci_dev *dev_diva201 __devinitdata = NULL;
static struct pci_dev *dev_diva202 __devinitdata = NULL;

static int __devinit setup_diva_pci(struct IsdnCard *card)
{
	struct IsdnCardState *cs = card->cs;

	cs->subtyp = 0;
	if ((dev_diva = pci_find_device(PCI_VENDOR_ID_EICON,
		PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) {
@@ -1082,8 +1194,7 @@ setup_diva(struct IsdnCard *card)
		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);
		return (-1);	/* card not found; continue search */
	}

	if (!cs->irq) {
@@ -1098,11 +1209,7 @@ setup_diva(struct IsdnCard *card)
		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;
@@ -1111,98 +1218,66 @@ setup_diva(struct IsdnCard *card)
		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;
	}

	return (1);		/* card found */
}

#ifdef __ISAPNP__
ready:
#endif
#else	/* if !CONFIG_PCI */

	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);
static int __devinit setup_diva_pci(struct IsdnCard *card)
{
	return (-1);	/* card not found; continue search */
}

#endif	/* CONFIG_PCI */

int __devinit
setup_diva(struct IsdnCard *card)
{
	int rc, have_card = 0;
	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;

	rc = setup_diva_isa(card);
	if (!rc)
		return rc;
	if (rc > 0) {
		have_card = 1;
		goto ready;
	}

	rc = setup_diva_isapnp(card);
	if (!rc)
		return rc;
	if (rc > 0) {
		have_card = 1;
		goto ready;
	}
	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);

	rc = setup_diva_pci(card);
	if (!rc)
		return rc;
	if (rc > 0)
		have_card = 1;

ready:
	if (!have_card) {
		printk(KERN_WARNING "Diva: No ISA, ISAPNP or PCI card found\n");
		return(0);
	}
	}
	return (1);

	return setup_diva_common(card->cs);
}