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

Commit ff087058 authored by Dominik Brodowski's avatar Dominik Brodowski
Browse files

Merge branches 'pcmcia-config-loop' and 'pcmcia-printk' into pcmcia

* pcmcia-config-loop:
  pcmcia: pcmcia_config_loop() improvement by passing vcc
  pcmcia: pcmcia_config_loop() default CIS entry handling
  pcmcia: pcmcia_config_loop() ConfigIndex unification
  pcmcia: use pcmcia_loop_config in misc pcmcia drivers
  pcmcia: use pcmcia_loop_config in net pcmcia drivers
  pcmcia: use pcmcia_loop_config in ISDN pcmcia drivers
  pcmcia: use pcmcia_loop_config in scsi pcmcia drivers
  pcmcia: use pcmcia_loop_config in bluetooth drivers
  pcmcia: use pcmcia_loop_config in pata and ide drivers
  pcmcia: add pcmcia_loop_config() helper

* pcmcia-printk:
  pcmcia: don't add extra DEBUG cflag
  pcmcia: remove unused cs_socket_name() definition
  pcmcia: use dev_printk in module rsrc_nonstatic
  pcmcia: use dev_printk in module pcmcia
  pcmcia: use dev_printk in module pcmcia_core
  pcmcia: use dev_printk and dev_dbg in yenta_socket
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
This file details changes in 2.6 which affect PCMCIA card driver authors:
This file details changes in 2.6 which affect PCMCIA card driver authors:


* New configuration loop helper (as of 2.6.28)
   By calling pcmcia_loop_config(), a driver can iterate over all available
   configuration options. During a driver's probe() phase, one doesn't need
   to use pcmcia_get_{first,next}_tuple, pcmcia_get_tuple_data and
   pcmcia_parse_tuple directly in most if not all cases.

* New release helper (as of 2.6.17)
* New release helper (as of 2.6.17)
   Instead of calling pcmcia_release_{configuration,io,irq,win}, all that's
   Instead of calling pcmcia_release_{configuration,io,irq,win}, all that's
   necessary now is calling pcmcia_disable_device. As there is no valid
   necessary now is calling pcmcia_disable_device. As there is no valid
+73 −92
Original line number Original line Diff line number Diff line
@@ -148,6 +148,64 @@ static struct ata_port_operations pcmcia_8bit_port_ops = {
#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)



struct pcmcia_config_check {
	unsigned long ctl_base;
	int skip_vcc;
	int is_kme;
};

static int pcmcia_check_one_config(struct pcmcia_device *pdev,
				   cistpl_cftable_entry_t *cfg,
				   cistpl_cftable_entry_t *dflt,
				   unsigned int vcc,
				   void *priv_data)
{
	struct pcmcia_config_check *stk = priv_data;

	/* Check for matching Vcc, unless we're desperate */
	if (!stk->skip_vcc) {
		if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
			if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
				return -ENODEV;
		} else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
			if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000)
				return -ENODEV;
		}
	}

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

	if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
		cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
		pdev->io.BasePort1 = io->win[0].base;
		pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
		if (!(io->flags & CISTPL_IO_16BIT))
			pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
		if (io->nwin == 2) {
			pdev->io.NumPorts1 = 8;
			pdev->io.BasePort2 = io->win[1].base;
			pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1;
			if (pcmcia_request_io(pdev, &pdev->io) != 0)
				return -ENODEV;
			stk->ctl_base = pdev->io.BasePort2;
		} else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
			pdev->io.NumPorts1 = io->win[0].len;
			pdev->io.NumPorts2 = 0;
			if (pcmcia_request_io(pdev, &pdev->io) != 0)
				return -ENODEV;
			stk->ctl_base = pdev->io.BasePort1 + 0x0e;
		} else
			return -ENODEV;
		/* If we've got this far, we're done */
		return 0;
	}
	return -ENODEV;
}

/**
/**
 *	pcmcia_init_one		-	attach a PCMCIA interface
 *	pcmcia_init_one		-	attach a PCMCIA interface
 *	@pdev: pcmcia device
 *	@pdev: pcmcia device
@@ -161,19 +219,11 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
	struct ata_host *host;
	struct ata_host *host;
	struct ata_port *ap;
	struct ata_port *ap;
	struct ata_pcmcia_info *info;
	struct ata_pcmcia_info *info;
	tuple_t tuple;
	struct pcmcia_config_check *stk = NULL;
	struct {
	int last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM, p;
		unsigned short buf[128];
		cisparse_t parse;
		config_info_t conf;
		cistpl_cftable_entry_t dflt;
	} *stk = NULL;
	cistpl_cftable_entry_t *cfg;
	int pass, last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM, p;
	unsigned long io_base, ctl_base;
	unsigned long io_base, ctl_base;
	void __iomem *io_addr, *ctl_addr;
	void __iomem *io_addr, *ctl_addr;
	int n_ports = 1;
	int n_ports = 1;

	struct ata_port_operations *ops = &pcmcia_port_ops;
	struct ata_port_operations *ops = &pcmcia_port_ops;


	info = kzalloc(sizeof(*info), GFP_KERNEL);
	info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -193,96 +243,27 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
	pdev->conf.Attributes = CONF_ENABLE_IRQ;
	pdev->conf.Attributes = CONF_ENABLE_IRQ;
	pdev->conf.IntType = INT_MEMORY_AND_IO;
	pdev->conf.IntType = INT_MEMORY_AND_IO;


	/* Allocate resoure probing structures */

	stk = kzalloc(sizeof(*stk), GFP_KERNEL);
	if (!stk)
		goto out1;

	cfg = &stk->parse.cftable_entry;

	/* Tuples we are walking */
	tuple.TupleData = (cisdata_t *)&stk->buf;
	tuple.TupleOffset = 0;
	tuple.TupleDataMax = 255;
	tuple.Attributes = 0;

	/* See if we have a manufacturer identifier. Use it to set is_kme for
	/* See if we have a manufacturer identifier. Use it to set is_kme for
	   vendor quirks */
	   vendor quirks */
	is_kme = ((pdev->manf_id == MANFID_KME) &&
	is_kme = ((pdev->manf_id == MANFID_KME) &&
		  ((pdev->card_id == PRODID_KME_KXLC005_A) ||
		  ((pdev->card_id == PRODID_KME_KXLC005_A) ||
		   (pdev->card_id == PRODID_KME_KXLC005_B)));
		   (pdev->card_id == PRODID_KME_KXLC005_B)));


	/* Not sure if this is right... look up the current Vcc */
	/* Allocate resoure probing structures */
	CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(pdev, &stk->conf));
/*	link->conf.Vcc = stk->conf.Vcc; */

	pass = io_base = ctl_base = 0;
	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
	tuple.Attributes = 0;
	CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple));

	/* Now munch the resources looking for a suitable set */
	while (1) {
		if (pcmcia_get_tuple_data(pdev, &tuple) != 0)
			goto next_entry;
		if (pcmcia_parse_tuple(pdev, &tuple, &stk->parse) != 0)
			goto next_entry;
		/* Check for matching Vcc, unless we're desperate */
		if (!pass) {
			if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
				if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
					goto next_entry;
			} else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
				if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000)
					goto next_entry;
			}
		}


		if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
	stk = kzalloc(sizeof(*stk), GFP_KERNEL);
			pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
	if (!stk)
		else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
		goto out1;
			pdev->conf.Vpp = stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
	stk->is_kme = is_kme;
	stk->skip_vcc = io_base = ctl_base = 0;


		if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) {
	if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk)) {
			cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io;
		stk->skip_vcc = 1;
			pdev->conf.ConfigIndex = cfg->index;
		if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk))
			pdev->io.BasePort1 = io->win[0].base;
			goto failed; /* No suitable config found */
			pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
			if (!(io->flags & CISTPL_IO_16BIT))
				pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
			if (io->nwin == 2) {
				pdev->io.NumPorts1 = 8;
				pdev->io.BasePort2 = io->win[1].base;
				pdev->io.NumPorts2 = (is_kme) ? 2 : 1;
				if (pcmcia_request_io(pdev, &pdev->io) != 0)
					goto next_entry;
				io_base = pdev->io.BasePort1;
				ctl_base = pdev->io.BasePort2;
			} else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
				pdev->io.NumPorts1 = io->win[0].len;
				pdev->io.NumPorts2 = 0;
				if (pcmcia_request_io(pdev, &pdev->io) != 0)
					goto next_entry;
				io_base = pdev->io.BasePort1;
				ctl_base = pdev->io.BasePort1 + 0x0e;
			} else
				goto next_entry;
			/* If we've got this far, we're done */
			break;
	}
	}
next_entry:
	io_base = pdev->io.BasePort1;
		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
	ctl_base = stk->ctl_base;
			memcpy(&stk->dflt, cfg, sizeof(stk->dflt));
		if (pass) {
			CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(pdev, &tuple));
		} else if (pcmcia_get_next_tuple(pdev, &tuple) != 0) {
			CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple));
			memset(&stk->dflt, 0, sizeof(stk->dflt));
			pass++;
		}
	}

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


+49 −72
Original line number Original line Diff line number Diff line
@@ -678,93 +678,70 @@ static void bt3c_detach(struct pcmcia_device *link)
	kfree(info);
	kfree(info);
}
}


static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
static int bt3c_check_config(struct pcmcia_device *p_dev,
			     cistpl_cftable_entry_t *cf,
			     cistpl_cftable_entry_t *dflt,
			     unsigned int vcc,
			     void *priv_data)
{
{
	int i;
	unsigned long try = (unsigned long) priv_data;

	i = pcmcia_get_tuple_data(handle, tuple);
	if (i != CS_SUCCESS)
		return i;


	return pcmcia_parse_tuple(handle, tuple, parse);
	if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
		p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
	if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
	    (cf->io.win[0].base != 0)) {
		p_dev->io.BasePort1 = cf->io.win[0].base;
		p_dev->io.IOAddrLines = (try == 0) ? 16 :
			cf->io.flags & CISTPL_IO_LINES_MASK;
		if (!pcmcia_request_io(p_dev, &p_dev->io))
			return 0;
	}
	}

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


static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev,
				      cistpl_cftable_entry_t *cf,
				      cistpl_cftable_entry_t *dflt,
				      unsigned int vcc,
				      void *priv_data)
{
{
	if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
	static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
		return CS_NO_MORE_ITEMS;
	int j;
	return get_tuple(handle, tuple, parse);

	if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
		for (j = 0; j < 5; j++) {
			p_dev->io.BasePort1 = base[j];
			p_dev->io.IOAddrLines = base[j] ? 16 : 3;
			if (!pcmcia_request_io(p_dev, &p_dev->io))
				return 0;
		}
	}
	return -ENODEV;
}
}


static int bt3c_config(struct pcmcia_device *link)
static int bt3c_config(struct pcmcia_device *link)
{
{
	static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
	bt3c_info_t *info = link->priv;
	bt3c_info_t *info = link->priv;
	tuple_t tuple;
	int i;
	u_short buf[256];
	unsigned long try;
	cisparse_t parse;

	cistpl_cftable_entry_t *cf = &parse.cftable_entry;
	/* First pass: look for a config entry that looks normal.
	int i, j, try;
	   Two tries: without IO aliases, then with aliases */

	for (try = 0; try < 2; try++)
	/* First pass: look for a config entry that looks normal. */
		if (!pcmcia_loop_config(link, bt3c_check_config, (void *) try))
	tuple.TupleData = (cisdata_t *)buf;
	tuple.TupleOffset = 0;
	tuple.TupleDataMax = 255;
	tuple.Attributes = 0;
	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
	/* Two tries: without IO aliases, then with aliases */
	for (try = 0; try < 2; try++) {
		i = first_tuple(link, &tuple, &parse);
		while (i != CS_NO_MORE_ITEMS) {
			if (i != CS_SUCCESS)
				goto next_entry;
			if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
				link->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
			if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
				link->conf.ConfigIndex = cf->index;
				link->io.BasePort1 = cf->io.win[0].base;
				link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
				i = pcmcia_request_io(link, &link->io);
				if (i == CS_SUCCESS)
			goto found_port;
			goto found_port;
			}
next_entry:
			i = next_tuple(link, &tuple, &parse);
		}
	}


	/* Second pass: try to find an entry that isn't picky about
	/* Second pass: try to find an entry that isn't picky about
	   its base address, then try to grab any standard serial port
	   its base address, then try to grab any standard serial port
	   address, and finally try to get any free port. */
	   address, and finally try to get any free port. */
	i = first_tuple(link, &tuple, &parse);
	if (!pcmcia_loop_config(link, bt3c_check_config_notpicky, NULL))
	while (i != CS_NO_MORE_ITEMS) {
		if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
			link->conf.ConfigIndex = cf->index;
			for (j = 0; j < 5; j++) {
				link->io.BasePort1 = base[j];
				link->io.IOAddrLines = base[j] ? 16 : 3;
				i = pcmcia_request_io(link, &link->io);
				if (i == CS_SUCCESS)
		goto found_port;
		goto found_port;
			}
		}
		i = next_tuple(link, &tuple, &parse);
	}


found_port:
	if (i != CS_SUCCESS) {
	BT_ERR("No usable port range found");
	BT_ERR("No usable port range found");
		cs_error(link, RequestIO, i);
	cs_error(link, RequestIO, -ENODEV);
	goto failed;
	goto failed;
	}


found_port:
	i = pcmcia_request_irq(link, &link->irq);
	i = pcmcia_request_irq(link, &link->irq);
	if (i != CS_SUCCESS) {
	if (i != CS_SUCCESS) {
		cs_error(link, RequestIRQ, i);
		cs_error(link, RequestIRQ, i);
+49 −73
Original line number Original line Diff line number Diff line
@@ -607,94 +607,70 @@ static void btuart_detach(struct pcmcia_device *link)
	kfree(info);
	kfree(info);
}
}


static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
static int btuart_check_config(struct pcmcia_device *p_dev,
			       cistpl_cftable_entry_t *cf,
			       cistpl_cftable_entry_t *dflt,
			       unsigned int vcc,
			       void *priv_data)
{
{
	int i;
	int *try = priv_data;

	i = pcmcia_get_tuple_data(handle, tuple);
	if (i != CS_SUCCESS)
		return i;


	return pcmcia_parse_tuple(handle, tuple, parse);
	if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
		p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
	if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
	    (cf->io.win[0].base != 0)) {
		p_dev->io.BasePort1 = cf->io.win[0].base;
		p_dev->io.IOAddrLines = (*try == 0) ? 16 :
			cf->io.flags & CISTPL_IO_LINES_MASK;
		if (!pcmcia_request_io(p_dev, &p_dev->io))
			return 0;
	}
	}

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


static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
static int btuart_check_config_notpicky(struct pcmcia_device *p_dev,
					cistpl_cftable_entry_t *cf,
					cistpl_cftable_entry_t *dflt,
					unsigned int vcc,
					void *priv_data)
{
{
	if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
	static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
		return CS_NO_MORE_ITEMS;
	int j;
	return get_tuple(handle, tuple, parse);

	if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
		for (j = 0; j < 5; j++) {
			p_dev->io.BasePort1 = base[j];
			p_dev->io.IOAddrLines = base[j] ? 16 : 3;
			if (!pcmcia_request_io(p_dev, &p_dev->io))
				return 0;
		}
	}
	return -ENODEV;
}
}


static int btuart_config(struct pcmcia_device *link)
static int btuart_config(struct pcmcia_device *link)
{
{
	static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
	btuart_info_t *info = link->priv;
	btuart_info_t *info = link->priv;
	tuple_t tuple;
	int i;
	u_short buf[256];
	int try;
	cisparse_t parse;

	cistpl_cftable_entry_t *cf = &parse.cftable_entry;
	/* First pass: look for a config entry that looks normal.
	int i, j, try;
	   Two tries: without IO aliases, then with aliases */

	for (try = 0; try < 2; try++)
	/* First pass: look for a config entry that looks normal. */
		if (!pcmcia_loop_config(link, btuart_check_config, &try))
	tuple.TupleData = (cisdata_t *) buf;
	tuple.TupleOffset = 0;
	tuple.TupleDataMax = 255;
	tuple.Attributes = 0;
	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
	/* Two tries: without IO aliases, then with aliases */
	for (try = 0; try < 2; try++) {
		i = first_tuple(link, &tuple, &parse);
		while (i != CS_NO_MORE_ITEMS) {
			if (i != CS_SUCCESS)
				goto next_entry;
			if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
				link->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
			if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
				link->conf.ConfigIndex = cf->index;
				link->io.BasePort1 = cf->io.win[0].base;
				link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
				i = pcmcia_request_io(link, &link->io);
				if (i == CS_SUCCESS)
			goto found_port;
			goto found_port;
			}
next_entry:
			i = next_tuple(link, &tuple, &parse);
		}
	}


	/* Second pass: try to find an entry that isn't picky about
	/* Second pass: try to find an entry that isn't picky about
	   its base address, then try to grab any standard serial port
	   its base address, then try to grab any standard serial port
	   address, and finally try to get any free port. */
	   address, and finally try to get any free port. */
	i = first_tuple(link, &tuple, &parse);
	if (!pcmcia_loop_config(link, btuart_check_config_notpicky, NULL))
	while (i != CS_NO_MORE_ITEMS) {
		if ((i == CS_SUCCESS) && (cf->io.nwin > 0)
		    && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
			link->conf.ConfigIndex = cf->index;
			for (j = 0; j < 5; j++) {
				link->io.BasePort1 = base[j];
				link->io.IOAddrLines = base[j] ? 16 : 3;
				i = pcmcia_request_io(link, &link->io);
				if (i == CS_SUCCESS)
		goto found_port;
		goto found_port;
			}
		}
		i = next_tuple(link, &tuple, &parse);
	}


found_port:
	if (i != CS_SUCCESS) {
	BT_ERR("No usable port range found");
	BT_ERR("No usable port range found");
		cs_error(link, RequestIO, i);
	cs_error(link, RequestIO, -ENODEV);
	goto failed;
	goto failed;
	}


found_port:
	i = pcmcia_request_irq(link, &link->irq);
	i = pcmcia_request_irq(link, &link->irq);
	if (i != CS_SUCCESS) {
	if (i != CS_SUCCESS) {
		cs_error(link, RequestIRQ, i);
		cs_error(link, RequestIRQ, i);
+14 −49
Original line number Original line Diff line number Diff line
@@ -590,66 +590,31 @@ static void dtl1_detach(struct pcmcia_device *link)
	kfree(info);
	kfree(info);
}
}


static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
static int dtl1_confcheck(struct pcmcia_device *p_dev,
			  cistpl_cftable_entry_t *cf,
			  cistpl_cftable_entry_t *dflt,
			  unsigned int vcc,
			  void *priv_data)
{
{
	int i;
	if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {

		p_dev->io.BasePort1 = cf->io.win[0].base;
	i = pcmcia_get_tuple_data(handle, tuple);
		p_dev->io.NumPorts1 = cf->io.win[0].len;	/*yo */
	if (i != CS_SUCCESS)
		p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
		return i;
		if (!pcmcia_request_io(p_dev, &p_dev->io))

			return 0;
	return pcmcia_parse_tuple(handle, tuple, parse);
}

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

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


static int dtl1_config(struct pcmcia_device *link)
static int dtl1_config(struct pcmcia_device *link)
{
{
	dtl1_info_t *info = link->priv;
	dtl1_info_t *info = link->priv;
	tuple_t tuple;
	u_short buf[256];
	cisparse_t parse;
	cistpl_cftable_entry_t *cf = &parse.cftable_entry;
	int i;
	int i;


	tuple.TupleData = (cisdata_t *)buf;
	tuple.TupleOffset = 0;
	tuple.TupleDataMax = 255;
	tuple.Attributes = 0;
	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;

	/* Look for a generic full-sized window */
	/* Look for a generic full-sized window */
	link->io.NumPorts1 = 8;
	link->io.NumPorts1 = 8;
	i = first_tuple(link, &tuple, &parse);
	if (!pcmcia_loop_config(link, dtl1_confcheck, NULL))
	while (i != CS_NO_MORE_ITEMS) {
		if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
			link->conf.ConfigIndex = cf->index;
			link->io.BasePort1 = cf->io.win[0].base;
			link->io.NumPorts1 = cf->io.win[0].len;	/*yo */
			link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
			i = pcmcia_request_io(link, &link->io);
			if (i == CS_SUCCESS)
				break;
		}
		i = next_tuple(link, &tuple, &parse);
	}

	if (i != CS_SUCCESS) {
		cs_error(link, RequestIO, i);
		goto failed;
		goto failed;
	}


	i = pcmcia_request_irq(link, &link->irq);
	i = pcmcia_request_irq(link, &link->irq);
	if (i != CS_SUCCESS) {
	if (i != CS_SUCCESS) {
Loading