Esempio n. 1
0
static int __devinit avma1cs_config(struct pcmcia_device *link)
{
	int i = -1;
	char devname[128];
	IsdnCard_t	icard;
	int busy = 0;

	dev_dbg(&link->dev, "avma1cs_config(0x%p)\n", link);

	devname[0] = 0;
	if (link->prod_id[1])
		strlcpy(devname, link->prod_id[1], sizeof(devname));

	if (pcmcia_loop_config(link, avma1cs_configcheck, NULL))
		return -ENODEV;

	do {
		/*
		 * allocate an interrupt line
		 */
		if (!link->irq) {
			/* undo */
			pcmcia_disable_device(link);
			break;
		}

		/*
		 * configure the PCMCIA socket
		 */
		i = pcmcia_enable_device(link);
		if (i != 0) {
			pcmcia_disable_device(link);
			break;
		}

	} while (0);

	/* If any step failed, release any partially configured state */
	if (i != 0) {
		avma1cs_release(link);
		return -ENODEV;
	}

	icard.para[0] = link->irq;
	icard.para[1] = link->resource[0]->start;
	icard.protocol = isdnprot;
	icard.typ = ISDN_CTYPE_A1_PCMCIA;

	i = hisax_init_pcmcia(link, &busy, &icard);
	if (i < 0) {
		printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 "
		       "PCMCIA %d at i/o %#x\n", i,
		       (unsigned int) link->resource[0]->start);
		avma1cs_release(link);
		return -ENODEV;
	}
	link->priv = (void *) (unsigned long) i;

	return 0;
} /* avma1cs_config */
Esempio n. 2
0
static int avma1cs_event(event_t event, int priority,
			  event_callback_args_t *args)
{
    dev_link_t *link = args->client_data;

    DEBUG(1, "avma1cs_event(0x%06x)\n", event);
    
    switch (event) {
    case CS_EVENT_CARD_REMOVAL:
	link->state &= ~DEV_PRESENT;
	if (link->state & DEV_CONFIG)
		avma1cs_release(link);
	break;
    case CS_EVENT_CARD_INSERTION:
	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
	avma1cs_config(link);
	break;
    case CS_EVENT_PM_SUSPEND:
	link->state |= DEV_SUSPEND;
	/* Fall through... */
    case CS_EVENT_RESET_PHYSICAL:
	if (link->state & DEV_CONFIG)
	    CardServices(ReleaseConfiguration, link->handle);
	break;
    case CS_EVENT_PM_RESUME:
	link->state &= ~DEV_SUSPEND;
	/* Fall through... */
    case CS_EVENT_CARD_RESET:
	if (link->state & DEV_CONFIG)
	    CardServices(RequestConfiguration, link->handle, &link->conf);
	break;
    }
    return 0;
} /* avma1cs_event */
Esempio n. 3
0
static void __exit exit_avma1_cs(void)
{
	pcmcia_unregister_driver(&avma1cs_driver);

	/* XXX: this really needs to move into generic code.. */
	while (dev_list != NULL) {
		if (dev_list->state & DEV_CONFIG)
			avma1cs_release(dev_list);
		avma1cs_detach(dev_list);
	}
}
Esempio n. 4
0
static void __devexit avma1cs_detach(struct pcmcia_device *link)
{
	dev_dbg(&link->dev, "avma1cs_detach(0x%p)\n", link);
	avma1cs_release(link);
	kfree(link->priv);
} /* avma1cs_detach */
Esempio n. 5
0
static int avma1cs_config(struct pcmcia_device *link)
{
    tuple_t tuple;
    cisparse_t parse;
    cistpl_cftable_entry_t *cf = &parse.cftable_entry;
    local_info_t *dev;
    int i;
    u_char buf[64];
    char devname[128];
    IsdnCard_t	icard;
    int busy = 0;

    dev = link->priv;

    DEBUG(0, "avma1cs_config(0x%p)\n", link);

    /*
       This reads the card's CONFIG tuple to find its configuration
       registers.
    */
    do {
	tuple.DesiredTuple = CISTPL_CONFIG;
	i = pcmcia_get_first_tuple(link, &tuple);
	if (i != CS_SUCCESS) break;
	tuple.TupleData = buf;
	tuple.TupleDataMax = 64;
	tuple.TupleOffset = 0;
	i = pcmcia_get_tuple_data(link, &tuple);
	if (i != CS_SUCCESS) break;
	i = pcmcia_parse_tuple(link, &tuple, &parse);
	if (i != CS_SUCCESS) break;
	link->conf.ConfigBase = parse.config.base;
    } while (0);
    if (i != CS_SUCCESS) {
	cs_error(link, ParseTuple, i);
	return -ENODEV;
    }

    do {

	tuple.Attributes = 0;
	tuple.TupleData = buf;
	tuple.TupleDataMax = 254;
	tuple.TupleOffset = 0;
	tuple.DesiredTuple = CISTPL_VERS_1;

	devname[0] = 0;
	if( !first_tuple(link, &tuple, &parse) && parse.version_1.ns > 1 ) {
	    strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1], 
			sizeof(devname));
	}
	/*
         * find IO port
         */
	tuple.TupleData = (cisdata_t *)buf;
	tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
	tuple.Attributes = 0;
	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
	i = first_tuple(link, &tuple, &parse);
	while (i == CS_SUCCESS) {
	    if (cf->io.nwin > 0) {
		link->conf.ConfigIndex = cf->index;
		link->io.BasePort1 = cf->io.win[0].base;
		link->io.NumPorts1 = cf->io.win[0].len;
		link->io.NumPorts2 = 0;
		printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n",
			link->io.BasePort1,
			link->io.BasePort1+link->io.NumPorts1 - 1);
		i = pcmcia_request_io(link, &link->io);
		if (i == CS_SUCCESS) goto found_port;
	    }
	    i = next_tuple(link, &tuple, &parse);
	}

found_port:
	if (i != CS_SUCCESS) {
	    cs_error(link, RequestIO, i);
	    break;
	}
	
	/*
	 * allocate an interrupt line
	 */
	i = pcmcia_request_irq(link, &link->irq);
	if (i != CS_SUCCESS) {
	    cs_error(link, RequestIRQ, i);
	    /* undo */
	    pcmcia_disable_device(link);
	    break;
	}

	/*
	 * configure the PCMCIA socket
	 */
	i = pcmcia_request_configuration(link, &link->conf);
	if (i != CS_SUCCESS) {
	    cs_error(link, RequestConfiguration, i);
	    pcmcia_disable_device(link);
	    break;
	}

    } while (0);

    /* At this point, the dev_node_t structure(s) should be
       initialized and arranged in a linked list at link->dev. */

    strcpy(dev->node.dev_name, "A1");
    dev->node.major = 45;
    dev->node.minor = 0;
    link->dev_node = &dev->node;

    /* If any step failed, release any partially configured state */
    if (i != 0) {
	avma1cs_release(link);
	return -ENODEV;
    }

    printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n",
				link->io.BasePort1, link->irq.AssignedIRQ);

    icard.para[0] = link->irq.AssignedIRQ;
    icard.para[1] = link->io.BasePort1;
    icard.protocol = isdnprot;
    icard.typ = ISDN_CTYPE_A1_PCMCIA;
    
    i = hisax_init_pcmcia(link, &busy, &icard);
    if (i < 0) {
    	printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 PCMCIA %d at i/o %#x\n", i, link->io.BasePort1);
	avma1cs_release(link);
	return -ENODEV;
    }
    dev->node.minor = i;

    return 0;
} /* avma1cs_config */
Esempio n. 6
0
static void avma1cs_detach(struct pcmcia_device *link)
{
	DEBUG(0, "avma1cs_detach(0x%p)\n", link);
	avma1cs_release(link);
	kfree(link->priv);
} /* avma1cs_detach */
Esempio n. 7
0
static void avma1cs_config(dev_link_t *link)
{
    client_handle_t handle;
    tuple_t tuple;
    cisparse_t parse;
    cistpl_cftable_entry_t *cf = &parse.cftable_entry;
    local_info_t *dev;
    int i;
    u8 buf[64];
    char devname[128];
    int busy = 0;
    
    handle = link->handle;
    dev = link->priv;

    DEBUG(0, "avma1cs_config(0x%p)\n", link);

    /*
       This reads the card's CONFIG tuple to find its configuration
       registers.
    */
    do {
	tuple.DesiredTuple = CISTPL_CONFIG;
	i = CardServices(GetFirstTuple, handle, &tuple);
	if (i != CS_SUCCESS) break;
	tuple.TupleData = buf;
	tuple.TupleDataMax = 64;
	tuple.TupleOffset = 0;
	i = CardServices(GetTupleData, handle, &tuple);
	if (i != CS_SUCCESS) break;
	i = CardServices(ParseTuple, handle, &tuple, &parse);
	if (i != CS_SUCCESS) break;
	link->conf.ConfigBase = parse.config.base;
    } while (0);
    if (i != CS_SUCCESS) {
	cs_error(link->handle, ParseTuple, i);
	link->state &= ~DEV_CONFIG_PENDING;
	return;
    }
    
    /* Configure card */
    link->state |= DEV_CONFIG;

    do {

	tuple.Attributes = 0;
	tuple.TupleData = buf;
	tuple.TupleDataMax = 254;
	tuple.TupleOffset = 0;
	tuple.DesiredTuple = CISTPL_VERS_1;

	devname[0] = 0;
	if( !first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 1 ) {
	    strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1], 
			sizeof(devname));
	}
	/*
         * find IO port
         */
	tuple.TupleData = (cisdata_t *)buf;
	tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
	tuple.Attributes = 0;
	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
	i = first_tuple(handle, &tuple, &parse);
	while (i == CS_SUCCESS) {
	    if (cf->io.nwin > 0) {
		link->conf.ConfigIndex = cf->index;
		link->io.BasePort1 = cf->io.win[0].base;
		link->io.NumPorts1 = cf->io.win[0].len;
		link->io.NumPorts2 = 0;
                printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n",
			link->io.BasePort1,
		        link->io.BasePort1+link->io.NumPorts1 - 1);
		i = CardServices(RequestIO, link->handle, &link->io);
		if (i == CS_SUCCESS) goto found_port;
	    }
	    i = next_tuple(handle, &tuple, &parse);
	}

found_port:
	if (i != CS_SUCCESS) {
	    cs_error(link->handle, RequestIO, i);
	    break;
	}
	
	/*
	 * allocate an interrupt line
	 */
	i = CardServices(RequestIRQ, link->handle, &link->irq);
	if (i != CS_SUCCESS) {
	    cs_error(link->handle, RequestIRQ, i);
	    CardServices(ReleaseIO, link->handle, &link->io);
	    break;
	}
	
	/*
         * configure the PCMCIA socket
	  */
	i = CardServices(RequestConfiguration, link->handle, &link->conf);
	if (i != CS_SUCCESS) {
	    cs_error(link->handle, RequestConfiguration, i);
	    CardServices(ReleaseIO, link->handle, &link->io);
	    CardServices(ReleaseIRQ, link->handle, &link->irq);
	    break;
	}

    } while (0);

    /* At this point, the dev_node_t structure(s) should be
       initialized and arranged in a linked list at link->dev. */

    strcpy(dev->node.dev_name, "A1");
    dev->node.major = 45;
    dev->node.minor = 0;
    link->dev = &dev->node;
    
    link->state &= ~DEV_CONFIG_PENDING;
    /* If any step failed, release any partially configured state */
    if (i != 0) {
	avma1cs_release(link);
	return;
    }

    printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n",
				link->io.BasePort1, link->irq.AssignedIRQ);

    if (avm_a1_init_pcmcia((void *)(int)link->io.BasePort1,
                           link->irq.AssignedIRQ,
                           &busy, isdnprot) != 0) {
       printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 PCMCIA %d at i/o %#x\n", i, link->io.BasePort1);
       return;
    }

    i = 0; /* no returncode for cardnr :-( */

    dev->node.minor = i;

} /* avma1cs_config */