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

Commit 5fcd4da0 authored by Dominik Brodowski's avatar Dominik Brodowski
Browse files

pcmcia: use pcmcia_loop_config in ISDN pcmcia drivers



Use the config loop helper in ISDN pcmcia drivers.

CC: Karsten Keil <kkeil@suse.de>
Signed-off-by: default avatarDominik Brodowski <linux@dominikbrodowski.net>
parent 0e6f9d27
Loading
Loading
Loading
Loading
+23 −57
Original line number Original line Diff line number Diff line
@@ -154,45 +154,33 @@ static void avmcs_detach(struct pcmcia_device *link)
    
    
======================================================================*/
======================================================================*/


static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
static int avmcs_configcheck(struct pcmcia_device *p_dev,
		     cisparse_t *parse)
			     cistpl_cftable_entry_t *cf,
			     void *priv_data)
{
{
    int i = pcmcia_get_tuple_data(handle, tuple);
	if (cf->io.nwin <= 0)
    if (i != CS_SUCCESS) return i;
		return -ENODEV;
    return pcmcia_parse_tuple(handle, tuple, parse);
}

static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
		     cisparse_t *parse)
{
    int i = pcmcia_get_first_tuple(handle, tuple);
    if (i != CS_SUCCESS) return i;
    return get_tuple(handle, tuple, parse);
}


static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
	p_dev->conf.ConfigIndex = cf->index;
		     cisparse_t *parse)
	p_dev->io.BasePort1 = cf->io.win[0].base;
{
	p_dev->io.NumPorts1 = cf->io.win[0].len;
    int i = pcmcia_get_next_tuple(handle, tuple);
	p_dev->io.NumPorts2 = 0;
    if (i != CS_SUCCESS) return i;
	printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n",
    return get_tuple(handle, tuple, parse);
	       p_dev->io.BasePort1,
	       p_dev->io.BasePort1+p_dev->io.NumPorts1-1);
	return pcmcia_request_io(p_dev, &p_dev->io);
}
}


static int avmcs_config(struct pcmcia_device *link)
static int avmcs_config(struct pcmcia_device *link)
{
{
    tuple_t tuple;
    cisparse_t parse;
    cistpl_cftable_entry_t *cf = &parse.cftable_entry;
    local_info_t *dev;
    local_info_t *dev;
    int i;
    int i;
    u_char buf[64];
    char devname[128];
    char devname[128];
    int cardtype;
    int cardtype;
    int (*addcard)(unsigned int port, unsigned irq);
    int (*addcard)(unsigned int port, unsigned irq);


    dev = link->priv;
    dev = link->priv;


    do {
    devname[0] = 0;
    devname[0] = 0;
    if (link->prod_id[1])
    if (link->prod_id[1])
	    strlcpy(devname, link->prod_id[1], sizeof(devname));
	    strlcpy(devname, link->prod_id[1], sizeof(devname));
@@ -200,32 +188,10 @@ static int avmcs_config(struct pcmcia_device *link)
    /*
    /*
     * find IO port
     * find IO port
     */
     */
	tuple.TupleData = (cisdata_t *)buf;
    if (pcmcia_loop_config(link, avmcs_configcheck, NULL))
	tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
	    return -ENODEV;
	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 "avm_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;
	}


    do {
	/*
	/*
	 * allocate an interrupt line
	 * allocate an interrupt line
	 */
	 */
+20 −56
Original line number Original line Diff line number Diff line
@@ -174,38 +174,28 @@ static void avma1cs_detach(struct pcmcia_device *link)
    
    
======================================================================*/
======================================================================*/


static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
static int avma1cs_configcheck(struct pcmcia_device *p_dev,
		     cisparse_t *parse)
			     cistpl_cftable_entry_t *cf,
			     void *priv_data)
{
{
    int i = pcmcia_get_tuple_data(handle, tuple);
	if (cf->io.nwin <= 0)
    if (i != CS_SUCCESS) return i;
		return -ENODEV;
    return pcmcia_parse_tuple(handle, tuple, parse);
}


static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
	p_dev->conf.ConfigIndex = cf->index;
		     cisparse_t *parse)
	p_dev->io.BasePort1 = cf->io.win[0].base;
{
	p_dev->io.NumPorts1 = cf->io.win[0].len;
    int i = pcmcia_get_first_tuple(handle, tuple);
	p_dev->io.NumPorts2 = 0;
    if (i != CS_SUCCESS) return i;
	printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n",
    return get_tuple(handle, tuple, parse);
	       p_dev->io.BasePort1,
	       p_dev->io.BasePort1+p_dev->io.NumPorts1-1);
	return pcmcia_request_io(p_dev, &p_dev->io);
}
}


static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
		     cisparse_t *parse)
{
    int i = pcmcia_get_next_tuple(handle, tuple);
    if (i != CS_SUCCESS) return i;
    return get_tuple(handle, tuple, parse);
}


static int avma1cs_config(struct pcmcia_device *link)
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;
    local_info_t *dev;
    int i;
    int i;
    u_char buf[64];
    char devname[128];
    char devname[128];
    IsdnCard_t	icard;
    IsdnCard_t	icard;
    int busy = 0;
    int busy = 0;
@@ -214,40 +204,14 @@ static int avma1cs_config(struct pcmcia_device *link)


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


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


	/*
    if (pcmcia_loop_config(link, avma1cs_configcheck, NULL))
         * find IO port
	    return -ENODEV;
         */
	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;
	}


    do {
	/*
	/*
	 * allocate an interrupt line
	 * allocate an interrupt line
	 */
	 */
+23 −50
Original line number Original line Diff line number Diff line
@@ -203,68 +203,41 @@ static void elsa_cs_detach(struct pcmcia_device *link)
    device available to the system.
    device available to the system.


======================================================================*/
======================================================================*/
static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
                     cisparse_t *parse)
{
    int i = pcmcia_get_tuple_data(handle, tuple);
    if (i != CS_SUCCESS) return i;
    return pcmcia_parse_tuple(handle, tuple, parse);
}


static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
static int elsa_cs_configcheck(struct pcmcia_device *p_dev,
                     cisparse_t *parse)
			       cistpl_cftable_entry_t *cf,
			       void *priv_data)
{
{
    int i = pcmcia_get_first_tuple(handle, tuple);
	int j;
    if (i != CS_SUCCESS) return i;
    return get_tuple(handle, tuple, parse);
}


static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
	if ((cf->io.nwin > 0) && cf->io.win[0].base) {
                     cisparse_t *parse)
		printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n");
{
		p_dev->conf.ConfigIndex = cf->index;
    int i = pcmcia_get_next_tuple(handle, tuple);
		p_dev->io.BasePort1 = cf->io.win[0].base;
    if (i != CS_SUCCESS) return i;
		if (!pcmcia_request_io(p_dev, &p_dev->io))
    return get_tuple(handle, tuple, parse);
			return 0;
	} else {
		printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n");
		p_dev->conf.ConfigIndex = cf->index;
		for (j = 0x2f0; j > 0x100; j -= 0x10) {
			p_dev->io.BasePort1 = j;
			if (!pcmcia_request_io(p_dev, &p_dev->io))
				return 0;
		}
	}
	return -ENODEV;
}
}


static int elsa_cs_config(struct pcmcia_device *link)
static int elsa_cs_config(struct pcmcia_device *link)
{
{
    tuple_t tuple;
    cisparse_t parse;
    local_info_t *dev;
    local_info_t *dev;
    int i, j, last_fn;
    int i, last_fn;
    u_short buf[128];
    cistpl_cftable_entry_t *cf = &parse.cftable_entry;
    IsdnCard_t icard;
    IsdnCard_t icard;


    DEBUG(0, "elsa_config(0x%p)\n", link);
    DEBUG(0, "elsa_config(0x%p)\n", link);
    dev = link->priv;
    dev = link->priv;


    tuple.TupleData = (cisdata_t *)buf;
    i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL);
    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) && cf->io.win[0].base) {
            printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n");
            link->conf.ConfigIndex = cf->index;
            link->io.BasePort1 = cf->io.win[0].base;
            i = pcmcia_request_io(link, &link->io);
            if (i == CS_SUCCESS) break;
        } else {
          printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n");
          link->conf.ConfigIndex = cf->index;
          for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) {
            link->io.BasePort1 = j;
            i = pcmcia_request_io(link, &link->io);
            if (i == CS_SUCCESS) break;
          }
          break;
        }
        i = next_tuple(link, &tuple, &parse);
    }

    if (i != CS_SUCCESS) {
    if (i != CS_SUCCESS) {
	last_fn = RequestIO;
	last_fn = RequestIO;
	goto cs_failed;
	goto cs_failed;
+102 −106
Original line number Original line Diff line number Diff line
@@ -217,101 +217,68 @@ static void sedlbauer_detach(struct pcmcia_device *link)
#define CS_CHECK(fn, ret) \
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)


static int sedlbauer_config(struct pcmcia_device *link)
struct sedlbauer_config_data {
{
	cistpl_cftable_entry_t dflt;
    local_info_t *dev = link->priv;
    tuple_t tuple;
    cisparse_t parse;
    int last_fn, last_ret;
    u8 buf[64];
	config_info_t conf;
	config_info_t conf;
	win_req_t req;
	win_req_t req;
    memreq_t map;
};
    IsdnCard_t  icard;

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

    tuple.Attributes = 0;
    tuple.TupleData = buf;
    tuple.TupleDataMax = sizeof(buf);
    tuple.TupleOffset = 0;

    CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf));


    /*
static int sedlbauer_config_check(struct pcmcia_device *p_dev,
      In this loop, we scan the CIS for configuration table entries,
				  cistpl_cftable_entry_t *cfg,
      each of which describes a valid card configuration, including
				  void *priv_data)
      voltage, IO window, memory window, and interrupt settings.
{
	struct sedlbauer_config_data *cfg_mem = priv_data;


      We make no assumptions about the card to be configured: we use
	if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
      just the information available in the CIS.  In an ideal world,
		cfg_mem->dflt = *cfg;
      this would work for any PCMCIA card, but it requires a complete
	if (cfg->index == 0)
      and accurate CIS.  In practice, a driver usually "knows" most of
		return -ENODEV;
      these things without consulting the CIS, and most client drivers
	p_dev->conf.ConfigIndex = cfg->index;
      will only use the CIS to fill in implementation-defined details.
    */
    tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
    while (1) {
	cistpl_cftable_entry_t dflt = { 0 };
	cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
	if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
		pcmcia_parse_tuple(link, &tuple, &parse) != 0)
	    goto next_entry;

	if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
	if (cfg->index == 0) goto next_entry;
	link->conf.ConfigIndex = cfg->index;


	/* Does this card need audio output? */
	/* Does this card need audio output? */
	if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
	if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
	    link->conf.Attributes |= CONF_ENABLE_SPKR;
		p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
	    link->conf.Status = CCSR_AUDIO_ENA;
		p_dev->conf.Status = CCSR_AUDIO_ENA;
	}
	}


	/* Use power settings for Vcc and Vpp if present */
	/* Use power settings for Vcc and Vpp if present */
	/*  Note that the CIS values need to be rescaled */
	/*  Note that the CIS values need to be rescaled */
	if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
	if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
	    if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000)
		if (cfg_mem->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000)
		goto next_entry;
			return -ENODEV;
	} else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
	} else if (cfg_mem->dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
	    if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000)
		if (cfg_mem->conf.Vcc != cfg_mem->dflt.vcc.param[CISTPL_POWER_VNOM]/10000)
		goto next_entry;
			return -ENODEV;
	}
	}


	if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
	if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
	    link->conf.Vpp =
		p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
		cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
	else if (cfg_mem->dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
	else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
		p_dev->conf.Vpp = cfg_mem->dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
	    link->conf.Vpp =
		dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;


	/* Do we need to allocate an interrupt? */
	/* Do we need to allocate an interrupt? */
	if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
	if (cfg->irq.IRQInfo1 || cfg_mem->dflt.irq.IRQInfo1)
	    link->conf.Attributes |= CONF_ENABLE_IRQ;
		p_dev->conf.Attributes |= CONF_ENABLE_IRQ;


	/* IO window settings */
	/* IO window settings */
	link->io.NumPorts1 = link->io.NumPorts2 = 0;
	p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
	if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
	if ((cfg->io.nwin > 0) || (cfg_mem->dflt.io.nwin > 0)) {
	    cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
		cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &cfg_mem->dflt.io;
	    link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
		p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
		if (!(io->flags & CISTPL_IO_8BIT))
		if (!(io->flags & CISTPL_IO_8BIT))
		link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
			p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
		if (!(io->flags & CISTPL_IO_16BIT))
		if (!(io->flags & CISTPL_IO_16BIT))
		link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
			p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
/* new in dummy.cs 2001/01/28 MN 
		p_dev->io.BasePort1 = io->win[0].base;
            link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
		p_dev->io.NumPorts1 = io->win[0].len;
*/
	    link->io.BasePort1 = io->win[0].base;
	    link->io.NumPorts1 = io->win[0].len;
		if (io->nwin > 1) {
		if (io->nwin > 1) {
		link->io.Attributes2 = link->io.Attributes1;
			p_dev->io.Attributes2 = p_dev->io.Attributes1;
		link->io.BasePort2 = io->win[1].base;
			p_dev->io.BasePort2 = io->win[1].base;
		link->io.NumPorts2 = io->win[1].len;
			p_dev->io.NumPorts2 = io->win[1].len;
		}
		}
		/* This reserves IO space but doesn't actually enable it */
		/* This reserves IO space but doesn't actually enable it */
	    if (pcmcia_request_io(link, &link->io) != 0)
		if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
		goto next_entry;
			return -ENODEV;
	}
	}


	/*
	/*
@@ -325,31 +292,59 @@ static int sedlbauer_config(struct pcmcia_device *link)
	  needs to be mapped to virtual space with ioremap() before it
	  needs to be mapped to virtual space with ioremap() before it
	  is used.
	  is used.
	*/
	*/
	if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
	if ((cfg->mem.nwin > 0) || (cfg_mem->dflt.mem.nwin > 0)) {
	    cistpl_mem_t *mem =
		cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &cfg_mem->dflt.mem;
		(cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
		memreq_t map;
	    req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
		cfg_mem->req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
	    req.Attributes |= WIN_ENABLE;
		cfg_mem->req.Attributes |= WIN_ENABLE;
	    req.Base = mem->win[0].host_addr;
		cfg_mem->req.Base = mem->win[0].host_addr;
	    req.Size = mem->win[0].len;
		cfg_mem->req.Size = mem->win[0].len;
/* new in dummy.cs 2001/01/28 MN 
		cfg_mem->req.AccessSpeed = 0;
            if (req.Size < 0x1000)
		if (pcmcia_request_window(&p_dev, &cfg_mem->req, &p_dev->win) != 0)
                req.Size = 0x1000;
			return -ENODEV;
*/
		map.Page = 0;
	    req.AccessSpeed = 0;
		map.CardOffset = mem->win[0].card_addr;
	    if (pcmcia_request_window(&link, &req, &link->win) != 0)
		if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
		goto next_entry;
			return -ENODEV;
	    map.Page = 0; map.CardOffset = mem->win[0].card_addr;
	    if (pcmcia_map_mem_page(link->win, &map) != 0)
		goto next_entry;
	}
	}
	/* If we got this far, we're cool! */
	return 0;
	break;

    next_entry:
	CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
}
}




static int sedlbauer_config(struct pcmcia_device *link)
{
    local_info_t *dev = link->priv;
    struct sedlbauer_config_data *cfg_mem;
    int last_fn, last_ret;
    IsdnCard_t  icard;

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

    cfg_mem = kzalloc(sizeof(struct sedlbauer_config_data), GFP_KERNEL);
    if (!cfg_mem)
	    return -ENOMEM;

    /* Look up the current Vcc */
    CS_CHECK(GetConfigurationInfo,
	     pcmcia_get_configuration_info(link, &cfg_mem->conf));

    /*
      In this loop, we scan the CIS for configuration table entries,
      each of which describes a valid card configuration, including
      voltage, IO window, memory window, and interrupt settings.

      We make no assumptions about the card to be configured: we use
      just the information available in the CIS.  In an ideal world,
      this would work for any PCMCIA card, but it requires a complete
      and accurate CIS.  In practice, a driver usually "knows" most of
      these things without consulting the CIS, and most client drivers
      will only use the CIS to fill in implementation-defined details.
    */
    last_ret = pcmcia_loop_config(link, sedlbauer_config_check, cfg_mem);
    if (last_ret)
	    goto failed;

    /*
    /*
       Allocate an interrupt line.  Note that this does not assign a
       Allocate an interrupt line.  Note that this does not assign a
       handler to the interrupt, unless the 'Handler' member of the
       handler to the interrupt, unless the 'Handler' member of the
@@ -387,8 +382,8 @@ static int sedlbauer_config(struct pcmcia_device *link)
	printk(" & 0x%04x-0x%04x", link->io.BasePort2,
	printk(" & 0x%04x-0x%04x", link->io.BasePort2,
	       link->io.BasePort2+link->io.NumPorts2-1);
	       link->io.BasePort2+link->io.NumPorts2-1);
    if (link->win)
    if (link->win)
	printk(", mem 0x%06lx-0x%06lx", req.Base,
	printk(", mem 0x%06lx-0x%06lx", cfg_mem->req.Base,
	       req.Base+req.Size-1);
	       cfg_mem->req.Base+cfg_mem->req.Size-1);
    printk("\n");
    printk("\n");


    icard.para[0] = link->irq.AssignedIRQ;
    icard.para[0] = link->irq.AssignedIRQ;
@@ -409,6 +404,7 @@ static int sedlbauer_config(struct pcmcia_device *link)


cs_failed:
cs_failed:
    cs_error(link, last_fn, last_ret);
    cs_error(link, last_fn, last_ret);
failed:
    sedlbauer_release(link);
    sedlbauer_release(link);
    return -ENODEV;
    return -ENODEV;


+23 −50
Original line number Original line Diff line number Diff line
@@ -193,68 +193,41 @@ static void teles_detach(struct pcmcia_device *link)
    device available to the system.
    device available to the system.


======================================================================*/
======================================================================*/
static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
                     cisparse_t *parse)
{
    int i = pcmcia_get_tuple_data(handle, tuple);
    if (i != CS_SUCCESS) return i;
    return pcmcia_parse_tuple(handle, tuple, parse);
}


static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
static int teles_cs_configcheck(struct pcmcia_device *p_dev,
                     cisparse_t *parse)
				cistpl_cftable_entry_t *cf,
				void *priv_data)
{
{
    int i = pcmcia_get_first_tuple(handle, tuple);
	int j;
    if (i != CS_SUCCESS) return i;
    return get_tuple(handle, tuple, parse);
}


static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
	if ((cf->io.nwin > 0) && cf->io.win[0].base) {
                     cisparse_t *parse)
		printk(KERN_INFO "(teles_cs: looks like the 96 model)\n");
{
		p_dev->conf.ConfigIndex = cf->index;
    int i = pcmcia_get_next_tuple(handle, tuple);
		p_dev->io.BasePort1 = cf->io.win[0].base;
    if (i != CS_SUCCESS) return i;
		if (!pcmcia_request_io(p_dev, &p_dev->io))
    return get_tuple(handle, tuple, parse);
			return 0;
	} else {
		printk(KERN_INFO "(teles_cs: looks like the 97 model)\n");
		p_dev->conf.ConfigIndex = cf->index;
		for (j = 0x2f0; j > 0x100; j -= 0x10) {
			p_dev->io.BasePort1 = j;
			if (!pcmcia_request_io(p_dev, &p_dev->io))
				return 0;
		}
	}
	return -ENODEV;
}
}


static int teles_cs_config(struct pcmcia_device *link)
static int teles_cs_config(struct pcmcia_device *link)
{
{
    tuple_t tuple;
    cisparse_t parse;
    local_info_t *dev;
    local_info_t *dev;
    int i, j, last_fn;
    int i, last_fn;
    u_short buf[128];
    cistpl_cftable_entry_t *cf = &parse.cftable_entry;
    IsdnCard_t icard;
    IsdnCard_t icard;


    DEBUG(0, "teles_config(0x%p)\n", link);
    DEBUG(0, "teles_config(0x%p)\n", link);
    dev = link->priv;
    dev = link->priv;


    tuple.TupleData = (cisdata_t *)buf;
    i = pcmcia_loop_config(link, teles_cs_configcheck, NULL);
    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) && cf->io.win[0].base) {
            printk(KERN_INFO "(teles_cs: looks like the 96 model)\n");
            link->conf.ConfigIndex = cf->index;
            link->io.BasePort1 = cf->io.win[0].base;
            i = pcmcia_request_io(link, &link->io);
            if (i == CS_SUCCESS) break;
        } else {
          printk(KERN_INFO "(teles_cs: looks like the 97 model)\n");
          link->conf.ConfigIndex = cf->index;
          for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) {
            link->io.BasePort1 = j;
            i = pcmcia_request_io(link, &link->io);
            if (i == CS_SUCCESS) break;
          }
          break;
        }
        i = next_tuple(link, &tuple, &parse);
    }

    if (i != CS_SUCCESS) {
    if (i != CS_SUCCESS) {
	last_fn = RequestIO;
	last_fn = RequestIO;
	goto cs_failed;
	goto cs_failed;