static void parport_detach(dev_link_t *link)
{
    dev_link_t **linkp;
    int ret;

    DEBUG(0, "parport_detach(0x%p)\n", link);
    
    /* Locate device structure */
    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
	if (*linkp == link) break;
    if (*linkp == NULL)
	return;

    del_timer(&link->release);
    if (link->state & DEV_CONFIG)
	parport_cs_release((u_long)link);
    
    if (link->handle) {
	ret = CardServices(DeregisterClient, link->handle);
	if (ret != CS_SUCCESS)
	    cs_error(link->handle, DeregisterClient, ret);
    }
    
    /* Unlink, free device structure */
    *linkp = link->next;
    kfree(link->priv);
    
} /* parport_detach */
示例#2
0
int parport_event(event_t event, int priority,
                  event_callback_args_t *args)
{
    dev_link_t *link = args->client_data;

    DEBUG(1, "parport_event(0x%06x)\n", event);

    switch (event) {
    case CS_EVENT_CARD_REMOVAL:
        link->state &= ~DEV_PRESENT;
        if (link->state & DEV_CONFIG)
            parport_cs_release(link);
        break;
    case CS_EVENT_CARD_INSERTION:
        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
        parport_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 (DEV_OK(link))
            CardServices(RequestConfiguration, link->handle, &link->conf);
        break;
    }
    return 0;
} /* parport_event */
示例#3
0
static void parport_detach(struct pcmcia_device *link)
{
    dev_dbg(&link->dev, "parport_detach\n");

    parport_cs_release(link);

    kfree(link->priv);
} /* parport_detach */
示例#4
0
static void parport_detach(struct pcmcia_device *link)
{
    DEBUG(0, "parport_detach(0x%p)\n", link);

    parport_cs_release(link);

    kfree(link->priv);
} /* parport_detach */
示例#5
0
static int parport_config(struct pcmcia_device *link)
{
    parport_info_t *info = link->priv;
    struct parport *p;
    int ret;

    dev_dbg(&link->dev, "parport_config\n");

    if (epp_mode)
	    link->config_index |= FORCE_EPP_MODE;

    ret = pcmcia_loop_config(link, parport_config_check, NULL);
    if (ret)
	    goto failed;

    if (!link->irq)
	    goto failed;
    ret = pcmcia_enable_device(link);
    if (ret)
	    goto failed;

    p = parport_pc_probe_port(link->resource[0]->start,
			      link->resource[1]->start,
			      link->irq, PARPORT_DMA_NONE,
			      &link->dev, IRQF_SHARED);
    if (p == NULL) {
#ifdef CONFIG_DEBUG_PRINTK
	printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at "
	       "0x%3x, irq %u failed\n",
	       (unsigned int) link->resource[0]->start,
	       link->irq);
#else
	;
#endif
	goto failed;
    }

    p->modes |= PARPORT_MODE_PCSPP;
    if (epp_mode)
	p->modes |= PARPORT_MODE_TRISTATE | PARPORT_MODE_EPP;
    info->ndev = 1;
    info->port = p;

    return 0;

failed:
    parport_cs_release(link);
    return -ENODEV;
} /* parport_config */
示例#6
0
static int parport_config(struct pcmcia_device *link)
{
    parport_info_t *info = link->priv;
    struct parport *p;
    int last_ret, last_fn;

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

    last_ret = pcmcia_loop_config(link, parport_config_check, NULL);
    if (last_ret) {
	    cs_error(link, RequestIO, last_ret);
	    goto failed;
    }

    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));

    p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2,
			      link->irq.AssignedIRQ, PARPORT_DMA_NONE,
			      &link->dev);
    if (p == NULL) {
	printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at "
	       "0x%3x, irq %u failed\n", link->io.BasePort1,
	       link->irq.AssignedIRQ);
	goto failed;
    }

    p->modes |= PARPORT_MODE_PCSPP;
    if (epp_mode)
	p->modes |= PARPORT_MODE_TRISTATE | PARPORT_MODE_EPP;
    info->ndev = 1;
    info->node.major = LP_MAJOR;
    info->node.minor = p->number;
    info->port = p;
    strcpy(info->node.dev_name, p->name);
    link->dev_node = &info->node;

    return 0;

cs_failed:
    cs_error(link, last_fn, last_ret);
failed:
    parport_cs_release(link);
    return -ENODEV;
} /* parport_config */
static int parport_config(struct pcmcia_device *link)
{
    parport_info_t *info = link->priv;
    struct parport *p;
    int ret;

    dev_dbg(&link->dev, "parport_config\n");

    ret = pcmcia_loop_config(link, parport_config_check, NULL);
    if (ret)
	    goto failed;

    if (!link->irq)
	    goto failed;
    ret = pcmcia_request_configuration(link, &link->conf);
    if (ret)
	    goto failed;

    p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2,
			      link->irq, PARPORT_DMA_NONE,
			      &link->dev, IRQF_SHARED);
    if (p == NULL) {
	printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at "
	       "0x%3x, irq %u failed\n", link->io.BasePort1,
	       link->irq);
	goto failed;
    }

    p->modes |= PARPORT_MODE_PCSPP;
    if (epp_mode)
	p->modes |= PARPORT_MODE_TRISTATE | PARPORT_MODE_EPP;
    info->ndev = 1;
    info->port = p;

    return 0;

failed:
    parport_cs_release(link);
    return -ENODEV;
} /* parport_config */
void parport_config(dev_link_t *link)
{
    client_handle_t handle = link->handle;
    parport_info_t *info = link->priv;
    tuple_t tuple;
    u_short buf[128];
    cisparse_t parse;
    config_info_t conf;
    cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
    cistpl_cftable_entry_t dflt = { 0 };
    struct parport *p;
    int last_ret, last_fn;
    
    DEBUG(0, "parport_config(0x%p)\n", link);
    
    tuple.TupleData = (cisdata_t *)buf;
    tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
    tuple.Attributes = 0;
    tuple.DesiredTuple = CISTPL_CONFIG;
    CS_CHECK(GetFirstTuple, handle, &tuple);
    CS_CHECK(GetTupleData, handle, &tuple);
    CS_CHECK(ParseTuple, handle, &tuple, &parse);
    link->conf.ConfigBase = parse.config.base;
    link->conf.Present = parse.config.rmask[0];
    
    /* Configure card */
    link->state |= DEV_CONFIG;

    /* Not sure if this is right... look up the current Vcc */
    CS_CHECK(GetConfigurationInfo, handle, &conf);
    
    tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
    tuple.Attributes = 0;
    CS_CHECK(GetFirstTuple, handle, &tuple);
    while (1) {
	CFG_CHECK(GetTupleData, handle, &tuple);
	CFG_CHECK(ParseTuple, handle, &tuple, &parse);

	if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
	    cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
	    link->conf.ConfigIndex = cfg->index;
	    if (epp_mode)
		link->conf.ConfigIndex |= FORCE_EPP_MODE;
	    link->io.BasePort1 = io->win[0].base;
	    link->io.NumPorts1 = io->win[0].len;
	    link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
	    if (io->nwin == 2) {
		link->io.BasePort2 = io->win[1].base;
		link->io.NumPorts2 = io->win[1].len;
	    }
	    CFG_CHECK(RequestIO, link->handle, &link->io);
	    /* If we've got this far, we're done */
	    break;
	}
	
    next_entry:
	if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
	CS_CHECK(GetNextTuple, handle, &tuple);
    }
    
    CS_CHECK(RequestIRQ, handle, &link->irq);
    CS_CHECK(RequestConfiguration, handle, &link->conf);

    release_region(link->io.BasePort1, link->io.NumPorts1);
    if (link->io.NumPorts2)
	release_region(link->io.BasePort2, link->io.NumPorts2);
    p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2,
			      link->irq.AssignedIRQ, PARPORT_DMA_NONE,
			      NULL);
    if (p == NULL) {
	printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at "
	       "0x%3x, irq %u failed\n", link->io.BasePort1,
	       link->irq.AssignedIRQ);
	goto failed;
    }

    p->modes |= PARPORT_MODE_PCSPP;
    if (epp_mode)
	p->modes |= PARPORT_MODE_TRISTATE | PARPORT_MODE_EPP;
    info->ndev = 1;
    info->node.major = LP_MAJOR;
    info->node.minor = p->number;
    info->port = p;
    strcpy(info->node.dev_name, p->name);
    link->dev = &info->node;

    link->state &= ~DEV_CONFIG_PENDING;
    return;
    
cs_failed:
    cs_error(link->handle, last_fn, last_ret);
failed:
    parport_cs_release((u_long)link);
    link->state &= ~DEV_CONFIG_PENDING;

} /* parport_config */