X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Fpcmcia%2Fsynclink_cs.c;h=8a8ca32822ba4ee800c076ebef798477ce25df5b;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=07213454c458c7038820cde11c409cb219f27ab1;hpb=f7ed79d23a47594e7834d66a8f14449796d4f3e6;p=linux-2.6.git diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 07213454c..8a8ca3282 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -228,7 +228,7 @@ typedef struct _mgslpc_info { struct _input_signal_events input_signal_events; /* PCMCIA support */ - struct pcmcia_device *p_dev; + dev_link_t link; dev_node_t node; int stop; @@ -484,7 +484,7 @@ static void mgslpc_wait_until_sent(struct tty_struct *tty, int timeout); /* PCMCIA prototypes */ -static int mgslpc_config(struct pcmcia_device *link); +static void mgslpc_config(dev_link_t *link); static void mgslpc_release(u_long arg); static void mgslpc_detach(struct pcmcia_device *p_dev); @@ -533,14 +533,14 @@ static void ldisc_receive_buf(struct tty_struct *tty, } } -static int mgslpc_probe(struct pcmcia_device *link) +static int mgslpc_attach(struct pcmcia_device *p_dev) { MGSLPC_INFO *info; - int ret; - + dev_link_t *link; + if (debug_level >= DEBUG_LEVEL_INFO) printk("mgslpc_attach\n"); - + info = (MGSLPC_INFO *)kmalloc(sizeof(MGSLPC_INFO), GFP_KERNEL); if (!info) { printk("Error can't allocate device instance data\n"); @@ -565,22 +565,25 @@ static int mgslpc_probe(struct pcmcia_device *link) info->imrb_value = 0xffff; info->pim_value = 0xff; - info->p_dev = link; + link = &info->link; link->priv = info; - - /* Initialize the struct pcmcia_device structure */ + + /* Initialize the dev_link_t structure */ /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->irq.Handler = NULL; - + link->conf.Attributes = 0; + link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - ret = mgslpc_config(link); - if (ret) - return ret; + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + mgslpc_config(link); mgslpc_add_device(info); @@ -593,13 +596,15 @@ static int mgslpc_probe(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int mgslpc_config(struct pcmcia_device *link) +static void mgslpc_config(dev_link_t *link) { + client_handle_t handle = link->handle; MGSLPC_INFO *info = link->priv; tuple_t tuple; cisparse_t parse; int last_fn, last_ret; u_char buf[64]; + config_info_t conf; cistpl_cftable_entry_t dflt = { 0 }; cistpl_cftable_entry_t *cfg; @@ -612,20 +617,27 @@ static int mgslpc_config(struct pcmcia_device *link) tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; + + /* Configure card */ + link->state |= DEV_CONFIG; + + /* Look up the current Vcc */ + CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); + link->conf.Vcc = conf.Vcc; /* get CIS configuration entry */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); cfg = &(parse.cftable_entry); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; if (cfg->index == 0) @@ -646,10 +658,11 @@ static int mgslpc_config(struct pcmcia_device *link) link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; link->io.BasePort1 = io->win[0].base; link->io.NumPorts1 = io->win[0].len; - CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); + CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io)); } link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 8; link->conf.Present = PRESENT_OPTION; @@ -657,9 +670,9 @@ static int mgslpc_config(struct pcmcia_device *link) link->irq.Attributes |= IRQ_HANDLE_PRESENT; link->irq.Handler = mgslpc_isr; link->irq.Instance = info; - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); info->io_base = link->io.BasePort1; info->irq_level = link->irq.AssignedIRQ; @@ -667,7 +680,7 @@ static int mgslpc_config(struct pcmcia_device *link) /* add to linked list of devices */ sprintf(info->node.dev_name, "mgslpc0"); info->node.major = info->node.minor = 0; - link->dev_node = &info->node; + link->dev = &info->node; printk(KERN_INFO "%s: index 0x%02x:", info->node.dev_name, link->conf.ConfigIndex); @@ -677,12 +690,13 @@ static int mgslpc_config(struct pcmcia_device *link) printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); printk("\n"); - return 0; + + link->state &= ~DEV_CONFIG_PENDING; + return; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); mgslpc_release((u_long)link); - return -ENODEV; } /* Card has been removed. @@ -691,38 +705,58 @@ cs_failed: */ static void mgslpc_release(u_long arg) { - struct pcmcia_device *link = (struct pcmcia_device *)arg; + dev_link_t *link = (dev_link_t *)arg; - if (debug_level >= DEBUG_LEVEL_INFO) - printk("mgslpc_release(0x%p)\n", link); + if (debug_level >= DEBUG_LEVEL_INFO) + printk("mgslpc_release(0x%p)\n", link); + + /* Unlink the device chain */ + link->dev = NULL; + link->state &= ~DEV_CONFIG; - pcmcia_disable_device(link); + pcmcia_release_configuration(link->handle); + if (link->io.NumPorts1) + pcmcia_release_io(link->handle, &link->io); + if (link->irq.AssignedIRQ) + pcmcia_release_irq(link->handle, &link->irq); } -static void mgslpc_detach(struct pcmcia_device *link) +static void mgslpc_detach(struct pcmcia_device *p_dev) { - if (debug_level >= DEBUG_LEVEL_INFO) - printk("mgslpc_detach(0x%p)\n", link); + dev_link_t *link = dev_to_instance(p_dev); - ((MGSLPC_INFO *)link->priv)->stop = 1; - mgslpc_release((u_long)link); + if (debug_level >= DEBUG_LEVEL_INFO) + printk("mgslpc_detach(0x%p)\n", link); + + if (link->state & DEV_CONFIG) { + ((MGSLPC_INFO *)link->priv)->stop = 1; + mgslpc_release((u_long)link); + } - mgslpc_remove_device((MGSLPC_INFO *)link->priv); + mgslpc_remove_device((MGSLPC_INFO *)link->priv); } -static int mgslpc_suspend(struct pcmcia_device *link) +static int mgslpc_suspend(struct pcmcia_device *dev) { + dev_link_t *link = dev_to_instance(dev); MGSLPC_INFO *info = link->priv; + link->state |= DEV_SUSPEND; info->stop = 1; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); return 0; } -static int mgslpc_resume(struct pcmcia_device *link) +static int mgslpc_resume(struct pcmcia_device *dev) { + dev_link_t *link = dev_to_instance(dev); MGSLPC_INFO *info = link->priv; + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_request_configuration(link->handle, &link->conf); info->stop = 0; return 0; @@ -1246,7 +1280,7 @@ static irqreturn_t mgslpc_isr(int irq, void *dev_id, struct pt_regs * regs) if (!info) return IRQ_NONE; - if (!(info->p_dev->_locked)) + if (!(info->link.state & DEV_CONFIG)) return IRQ_HANDLED; spin_lock(&info->lock); @@ -2999,7 +3033,7 @@ static struct pcmcia_driver mgslpc_driver = { .drv = { .name = "synclink_cs", }, - .probe = mgslpc_probe, + .probe = mgslpc_attach, .remove = mgslpc_detach, .id_table = mgslpc_ids, .suspend = mgslpc_suspend, @@ -4147,7 +4181,7 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding, } info->params.encoding = new_encoding; - info->params.crc_type = new_crctype; + info->params.crc_type = new_crctype;; /* if network interface up, reprogram hardware */ if (info->netcount)