Commit 86dca4f8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge master.kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6: (33 commits)
  [PATCH] pcmcia: declare pccard_iodyn_ops (fix m8xx_pcmcia.c compilation error)
  [PATCH] pcmcia: fix pcmcia_device_remove oops
  [PATCH] pcmcia: Add support for Possio GCC AKA PCMCIA Siemens MC45
  [PATCH] pcmcia: pseudo device handling update
  [PATCH] pcmcia: convert DEV_OK to pcmcia_dev_present
  [PATCH] pcmcia: use bitfield instead of p_state and state
  [PATCH] pcmcia: remove unused p_dev->state flags
  [PATCH] pcmcia: make pcmcia_release_{io,irq} static
  [PATCH] pcmcia: add return value to _config() functions
  [PATCH] pcmcia: remove dev_link_t and client_handle_t indirection
  [PATCH] pcmcia: embed dev_link_t into struct pcmcia_device
  [PATCH] pcmcia: rename pcmcia_device.state
  [PATCH] pcmcia: remove unneeded Vcc pseudo setting
  [PATCH] pcmcia: remove export of pcmcia_release_configuration
  [PATCH] pcmcia: default suspend and resume handling
  [PATCH] pcmcia: convert remaining users of pcmcia_release_io and _irq
  [PATCH] pcmcia: add pcmcia_disable_device
  [PATCH] serial_cs: add Merlin U630 IDs
  [PATCH] pcmcia: AT91RM9200 Compact Flash driver
  [PATCH] pcmcia: socket.functions starts with 1
  ...
parents 9c8680e2 553ee5dc
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 release helper (as of 2.6.17)
   Instead of calling pcmcia_release_{configuration,io,irq,win}, all that's
   necessary now is calling pcmcia_disable_device. As there is no valid
   reason left to call pcmcia_release_io and pcmcia_release_irq, the
   exports for them were removed.

* Unify detach and REMOVAL event code, as well as attach and INSERTION
* Unify detach and REMOVAL event code, as well as attach and INSERTION
  code (as of 2.6.16)
  code (as of 2.6.16)
       void (*remove)          (struct pcmcia_device *dev);
       void (*remove)          (struct pcmcia_device *dev);
+35 −84
Original line number Original line Diff line number Diff line
@@ -65,7 +65,7 @@ MODULE_LICENSE("GPL");




typedef struct bluecard_info_t {
typedef struct bluecard_info_t {
	dev_link_t link;
	struct pcmcia_device *p_dev;
	dev_node_t node;
	dev_node_t node;


	struct hci_dev *hdev;
	struct hci_dev *hdev;
@@ -85,8 +85,8 @@ typedef struct bluecard_info_t {
} bluecard_info_t;
} bluecard_info_t;




static void bluecard_config(dev_link_t *link);
static int bluecard_config(struct pcmcia_device *link);
static void bluecard_release(dev_link_t *link);
static void bluecard_release(struct pcmcia_device *link);


static void bluecard_detach(struct pcmcia_device *p_dev);
static void bluecard_detach(struct pcmcia_device *p_dev);


@@ -162,7 +162,7 @@ static void bluecard_detach(struct pcmcia_device *p_dev);
static void bluecard_activity_led_timeout(u_long arg)
static void bluecard_activity_led_timeout(u_long arg)
{
{
	bluecard_info_t *info = (bluecard_info_t *)arg;
	bluecard_info_t *info = (bluecard_info_t *)arg;
	unsigned int iobase = info->link.io.BasePort1;
	unsigned int iobase = info->p_dev->io.BasePort1;


	if (!test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
	if (!test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
		return;
		return;
@@ -179,7 +179,7 @@ static void bluecard_activity_led_timeout(u_long arg)


static void bluecard_enable_activity_led(bluecard_info_t *info)
static void bluecard_enable_activity_led(bluecard_info_t *info)
{
{
	unsigned int iobase = info->link.io.BasePort1;
	unsigned int iobase = info->p_dev->io.BasePort1;


	if (!test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
	if (!test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
		return;
		return;
@@ -235,7 +235,7 @@ static void bluecard_write_wakeup(bluecard_info_t *info)
	}
	}


	do {
	do {
		register unsigned int iobase = info->link.io.BasePort1;
		register unsigned int iobase = info->p_dev->io.BasePort1;
		register unsigned int offset;
		register unsigned int offset;
		register unsigned char command;
		register unsigned char command;
		register unsigned long ready_bit;
		register unsigned long ready_bit;
@@ -244,7 +244,7 @@ static void bluecard_write_wakeup(bluecard_info_t *info)


		clear_bit(XMIT_WAKEUP, &(info->tx_state));
		clear_bit(XMIT_WAKEUP, &(info->tx_state));


		if (!(info->link.state & DEV_PRESENT))
		if (!pcmcia_dev_present(info->p_dev))
			return;
			return;


		if (test_bit(XMIT_BUFFER_NUMBER, &(info->tx_state))) {
		if (test_bit(XMIT_BUFFER_NUMBER, &(info->tx_state))) {
@@ -382,7 +382,7 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
		return;
		return;
	}
	}


	iobase = info->link.io.BasePort1;
	iobase = info->p_dev->io.BasePort1;


	if (test_bit(XMIT_SENDING_READY, &(info->tx_state)))
	if (test_bit(XMIT_SENDING_READY, &(info->tx_state)))
		bluecard_enable_activity_led(info);
		bluecard_enable_activity_led(info);
@@ -512,7 +512,7 @@ static irqreturn_t bluecard_interrupt(int irq, void *dev_inst, struct pt_regs *r
	if (!test_bit(CARD_READY, &(info->hw_state)))
	if (!test_bit(CARD_READY, &(info->hw_state)))
		return IRQ_HANDLED;
		return IRQ_HANDLED;


	iobase = info->link.io.BasePort1;
	iobase = info->p_dev->io.BasePort1;


	spin_lock(&(info->lock));
	spin_lock(&(info->lock));


@@ -626,7 +626,7 @@ static int bluecard_hci_flush(struct hci_dev *hdev)
static int bluecard_hci_open(struct hci_dev *hdev)
static int bluecard_hci_open(struct hci_dev *hdev)
{
{
	bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
	bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
	unsigned int iobase = info->link.io.BasePort1;
	unsigned int iobase = info->p_dev->io.BasePort1;


	if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
	if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
		bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE);
		bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE);
@@ -646,7 +646,7 @@ static int bluecard_hci_open(struct hci_dev *hdev)
static int bluecard_hci_close(struct hci_dev *hdev)
static int bluecard_hci_close(struct hci_dev *hdev)
{
{
	bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
	bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
	unsigned int iobase = info->link.io.BasePort1;
	unsigned int iobase = info->p_dev->io.BasePort1;


	if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
	if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
		return 0;
		return 0;
@@ -713,7 +713,7 @@ static int bluecard_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned l


static int bluecard_open(bluecard_info_t *info)
static int bluecard_open(bluecard_info_t *info)
{
{
	unsigned int iobase = info->link.io.BasePort1;
	unsigned int iobase = info->p_dev->io.BasePort1;
	struct hci_dev *hdev;
	struct hci_dev *hdev;
	unsigned char id;
	unsigned char id;


@@ -831,7 +831,7 @@ static int bluecard_open(bluecard_info_t *info)


static int bluecard_close(bluecard_info_t *info)
static int bluecard_close(bluecard_info_t *info)
{
{
	unsigned int iobase = info->link.io.BasePort1;
	unsigned int iobase = info->p_dev->io.BasePort1;
	struct hci_dev *hdev = info->hdev;
	struct hci_dev *hdev = info->hdev;


	if (!hdev)
	if (!hdev)
@@ -856,17 +856,16 @@ static int bluecard_close(bluecard_info_t *info)
	return 0;
	return 0;
}
}


static int bluecard_attach(struct pcmcia_device *p_dev)
static int bluecard_probe(struct pcmcia_device *link)
{
{
	bluecard_info_t *info;
	bluecard_info_t *info;
	dev_link_t *link;


	/* Create new info device */
	/* Create new info device */
	info = kzalloc(sizeof(*info), GFP_KERNEL);
	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!info)
	if (!info)
		return -ENOMEM;
		return -ENOMEM;


	link = &info->link;
	info->p_dev = link;
	link->priv = info;
	link->priv = info;


	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
@@ -878,32 +877,22 @@ static int bluecard_attach(struct pcmcia_device *p_dev)
	link->irq.Instance = info;
	link->irq.Instance = info;


	link->conf.Attributes = CONF_ENABLE_IRQ;
	link->conf.Attributes = CONF_ENABLE_IRQ;
	link->conf.Vcc = 50;
	link->conf.IntType = INT_MEMORY_AND_IO;
	link->conf.IntType = INT_MEMORY_AND_IO;


	link->handle = p_dev;
	return bluecard_config(link);
	p_dev->instance = link;

	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
	bluecard_config(link);

	return 0;
}
}




static void bluecard_detach(struct pcmcia_device *p_dev)
static void bluecard_detach(struct pcmcia_device *link)
{
{
	dev_link_t *link = dev_to_instance(p_dev);
	bluecard_info_t *info = link->priv;
	bluecard_info_t *info = link->priv;


	if (link->state & DEV_CONFIG)
	bluecard_release(link);
	bluecard_release(link);

	kfree(info);
	kfree(info);
}
}




static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
{
{
	int i;
	int i;


@@ -918,14 +907,12 @@ static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse
	return pcmcia_parse_tuple(handle, tuple, parse);
	return pcmcia_parse_tuple(handle, tuple, parse);
}
}


static void bluecard_config(dev_link_t *link)
static int bluecard_config(struct pcmcia_device *link)
{
{
	client_handle_t handle = link->handle;
	bluecard_info_t *info = link->priv;
	bluecard_info_t *info = link->priv;
	tuple_t tuple;
	tuple_t tuple;
	u_short buf[256];
	u_short buf[256];
	cisparse_t parse;
	cisparse_t parse;
	config_info_t config;
	int i, n, last_ret, last_fn;
	int i, n, last_ret, last_fn;


	tuple.TupleData = (cisdata_t *)buf;
	tuple.TupleData = (cisdata_t *)buf;
@@ -935,7 +922,7 @@ static void bluecard_config(dev_link_t *link)


	/* Get configuration register information */
	/* Get configuration register information */
	tuple.DesiredTuple = CISTPL_CONFIG;
	tuple.DesiredTuple = CISTPL_CONFIG;
	last_ret = first_tuple(handle, &tuple, &parse);
	last_ret = first_tuple(link, &tuple, &parse);
	if (last_ret != CS_SUCCESS) {
	if (last_ret != CS_SUCCESS) {
		last_fn = ParseTuple;
		last_fn = ParseTuple;
		goto cs_failed;
		goto cs_failed;
@@ -943,36 +930,31 @@ static void bluecard_config(dev_link_t *link)
	link->conf.ConfigBase = parse.config.base;
	link->conf.ConfigBase = parse.config.base;
	link->conf.Present = parse.config.rmask[0];
	link->conf.Present = parse.config.rmask[0];


	/* Configure card */
	link->state |= DEV_CONFIG;
	i = pcmcia_get_configuration_info(handle, &config);
	link->conf.Vcc = config.Vcc;

	link->conf.ConfigIndex = 0x20;
	link->conf.ConfigIndex = 0x20;
	link->io.NumPorts1 = 64;
	link->io.NumPorts1 = 64;
	link->io.IOAddrLines = 6;
	link->io.IOAddrLines = 6;


	for (n = 0; n < 0x400; n += 0x40) {
	for (n = 0; n < 0x400; n += 0x40) {
		link->io.BasePort1 = n ^ 0x300;
		link->io.BasePort1 = n ^ 0x300;
		i = pcmcia_request_io(link->handle, &link->io);
		i = pcmcia_request_io(link, &link->io);
		if (i == CS_SUCCESS)
		if (i == CS_SUCCESS)
			break;
			break;
	}
	}


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


	i = pcmcia_request_irq(link->handle, &link->irq);
	i = pcmcia_request_irq(link, &link->irq);
	if (i != CS_SUCCESS) {
	if (i != CS_SUCCESS) {
		cs_error(link->handle, RequestIRQ, i);
		cs_error(link, RequestIRQ, i);
		link->irq.AssignedIRQ = 0;
		link->irq.AssignedIRQ = 0;
	}
	}


	i = pcmcia_request_configuration(link->handle, &link->conf);
	i = pcmcia_request_configuration(link, &link->conf);
	if (i != CS_SUCCESS) {
	if (i != CS_SUCCESS) {
		cs_error(link->handle, RequestConfiguration, i);
		cs_error(link, RequestConfiguration, i);
		goto failed;
		goto failed;
	}
	}


@@ -980,57 +962,28 @@ static void bluecard_config(dev_link_t *link)
		goto failed;
		goto failed;


	strcpy(info->node.dev_name, info->hdev->name);
	strcpy(info->node.dev_name, info->hdev->name);
	link->dev = &info->node;
	link->dev_node = &info->node;
	link->state &= ~DEV_CONFIG_PENDING;


	return;
	return 0;


cs_failed:
cs_failed:
	cs_error(link->handle, last_fn, last_ret);
	cs_error(link, last_fn, last_ret);


failed:
failed:
	bluecard_release(link);
	bluecard_release(link);
	return -ENODEV;
}
}




static void bluecard_release(dev_link_t *link)
static void bluecard_release(struct pcmcia_device *link)
{
{
	bluecard_info_t *info = link->priv;
	bluecard_info_t *info = link->priv;


	if (link->state & DEV_PRESENT)
	bluecard_close(info);
	bluecard_close(info);


	del_timer(&(info->timer));
	del_timer(&(info->timer));


	link->dev = NULL;
	pcmcia_disable_device(link);

	pcmcia_release_configuration(link->handle);
	pcmcia_release_io(link->handle, &link->io);
	pcmcia_release_irq(link->handle, &link->irq);

	link->state &= ~DEV_CONFIG;
}

static int bluecard_suspend(struct pcmcia_device *dev)
{
	dev_link_t *link = dev_to_instance(dev);

	link->state |= DEV_SUSPEND;
	if (link->state & DEV_CONFIG)
		pcmcia_release_configuration(link->handle);

	return 0;
}

static int bluecard_resume(struct pcmcia_device *dev)
{
	dev_link_t *link = dev_to_instance(dev);

	link->state &= ~DEV_SUSPEND;
	if (DEV_OK(link))
		pcmcia_request_configuration(link->handle, &link->conf);

	return 0;
}
}


static struct pcmcia_device_id bluecard_ids[] = {
static struct pcmcia_device_id bluecard_ids[] = {
@@ -1046,11 +999,9 @@ static struct pcmcia_driver bluecard_driver = {
	.drv		= {
	.drv		= {
		.name	= "bluecard_cs",
		.name	= "bluecard_cs",
	},
	},
	.probe		= bluecard_attach,
	.probe		= bluecard_probe,
	.remove		= bluecard_detach,
	.remove		= bluecard_detach,
	.id_table	= bluecard_ids,
	.id_table	= bluecard_ids,
	.suspend	= bluecard_suspend,
	.resume		= bluecard_resume,
};
};


static int __init init_bluecard_cs(void)
static int __init init_bluecard_cs(void)
+39 −91
Original line number Original line Diff line number Diff line
@@ -72,7 +72,7 @@ MODULE_LICENSE("GPL");




typedef struct bt3c_info_t {
typedef struct bt3c_info_t {
	dev_link_t link;
	struct pcmcia_device *p_dev;
	dev_node_t node;
	dev_node_t node;


	struct hci_dev *hdev;
	struct hci_dev *hdev;
@@ -88,8 +88,8 @@ typedef struct bt3c_info_t {
} bt3c_info_t;
} bt3c_info_t;




static void bt3c_config(dev_link_t *link);
static int bt3c_config(struct pcmcia_device *link);
static void bt3c_release(dev_link_t *link);
static void bt3c_release(struct pcmcia_device *link);


static void bt3c_detach(struct pcmcia_device *p_dev);
static void bt3c_detach(struct pcmcia_device *p_dev);


@@ -191,11 +191,11 @@ static void bt3c_write_wakeup(bt3c_info_t *info)
		return;
		return;


	do {
	do {
		register unsigned int iobase = info->link.io.BasePort1;
		register unsigned int iobase = info->p_dev->io.BasePort1;
		register struct sk_buff *skb;
		register struct sk_buff *skb;
		register int len;
		register int len;


		if (!(info->link.state & DEV_PRESENT))
		if (!pcmcia_dev_present(info->p_dev))
			break;
			break;




@@ -229,7 +229,7 @@ static void bt3c_receive(bt3c_info_t *info)
		return;
		return;
	}
	}


	iobase = info->link.io.BasePort1;
	iobase = info->p_dev->io.BasePort1;


	avail = bt3c_read(iobase, 0x7006);
	avail = bt3c_read(iobase, 0x7006);
	//printk("bt3c_cs: receiving %d bytes\n", avail);
	//printk("bt3c_cs: receiving %d bytes\n", avail);
@@ -350,7 +350,7 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
		return IRQ_NONE;
		return IRQ_NONE;
	}
	}


	iobase = info->link.io.BasePort1;
	iobase = info->p_dev->io.BasePort1;


	spin_lock(&(info->lock));
	spin_lock(&(info->lock));


@@ -481,7 +481,7 @@ static int bt3c_load_firmware(bt3c_info_t *info, unsigned char *firmware, int co
	unsigned int iobase, size, addr, fcs, tmp;
	unsigned int iobase, size, addr, fcs, tmp;
	int i, err = 0;
	int i, err = 0;


	iobase = info->link.io.BasePort1;
	iobase = info->p_dev->io.BasePort1;


	/* Reset */
	/* Reset */
	bt3c_io_write(iobase, 0x8040, 0x0404);
	bt3c_io_write(iobase, 0x8040, 0x0404);
@@ -562,7 +562,6 @@ static int bt3c_open(bt3c_info_t *info)
{
{
	const struct firmware *firmware;
	const struct firmware *firmware;
	struct hci_dev *hdev;
	struct hci_dev *hdev;
	client_handle_t handle;
	int err;
	int err;


	spin_lock_init(&(info->lock));
	spin_lock_init(&(info->lock));
@@ -594,10 +593,8 @@ static int bt3c_open(bt3c_info_t *info)


	hdev->owner = THIS_MODULE;
	hdev->owner = THIS_MODULE;


	handle = info->link.handle;

	/* Load firmware */
	/* Load firmware */
	err = request_firmware(&firmware, "BT3CPCC.bin", &handle_to_dev(handle));
	err = request_firmware(&firmware, "BT3CPCC.bin", &info->p_dev->dev);
	if (err < 0) {
	if (err < 0) {
		BT_ERR("Firmware request failed");
		BT_ERR("Firmware request failed");
		goto error;
		goto error;
@@ -648,17 +645,16 @@ static int bt3c_close(bt3c_info_t *info)
	return 0;
	return 0;
}
}


static int bt3c_attach(struct pcmcia_device *p_dev)
static int bt3c_probe(struct pcmcia_device *link)
{
{
	bt3c_info_t *info;
	bt3c_info_t *info;
	dev_link_t *link;


	/* Create new info device */
	/* Create new info device */
	info = kzalloc(sizeof(*info), GFP_KERNEL);
	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!info)
	if (!info)
		return -ENOMEM;
		return -ENOMEM;


	link = &info->link;
	info->p_dev = link;
	link->priv = info;
	link->priv = info;


	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
@@ -670,31 +666,21 @@ static int bt3c_attach(struct pcmcia_device *p_dev)
	link->irq.Instance = info;
	link->irq.Instance = info;


	link->conf.Attributes = CONF_ENABLE_IRQ;
	link->conf.Attributes = CONF_ENABLE_IRQ;
	link->conf.Vcc = 50;
	link->conf.IntType = INT_MEMORY_AND_IO;
	link->conf.IntType = INT_MEMORY_AND_IO;


	link->handle = p_dev;
	return bt3c_config(link);
	p_dev->instance = link;

	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
	bt3c_config(link);

	return 0;
}
}




static void bt3c_detach(struct pcmcia_device *p_dev)
static void bt3c_detach(struct pcmcia_device *link)
{
{
	dev_link_t *link = dev_to_instance(p_dev);
	bt3c_info_t *info = link->priv;
	bt3c_info_t *info = link->priv;


	if (link->state & DEV_CONFIG)
	bt3c_release(link);
	bt3c_release(link);

	kfree(info);
	kfree(info);
}
}


static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
{
{
	int i;
	int i;


@@ -705,30 +691,28 @@ static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
	return pcmcia_parse_tuple(handle, tuple, parse);
	return pcmcia_parse_tuple(handle, tuple, parse);
}
}


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


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


static void bt3c_config(dev_link_t *link)
static int bt3c_config(struct pcmcia_device *link)
{
{
	static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
	static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
	client_handle_t handle = link->handle;
	bt3c_info_t *info = link->priv;
	bt3c_info_t *info = link->priv;
	tuple_t tuple;
	tuple_t tuple;
	u_short buf[256];
	u_short buf[256];
	cisparse_t parse;
	cisparse_t parse;
	cistpl_cftable_entry_t *cf = &parse.cftable_entry;
	cistpl_cftable_entry_t *cf = &parse.cftable_entry;
	config_info_t config;
	int i, j, try, last_ret, last_fn;
	int i, j, try, last_ret, last_fn;


	tuple.TupleData = (cisdata_t *)buf;
	tuple.TupleData = (cisdata_t *)buf;
@@ -738,7 +722,7 @@ static void bt3c_config(dev_link_t *link)


	/* Get configuration register information */
	/* Get configuration register information */
	tuple.DesiredTuple = CISTPL_CONFIG;
	tuple.DesiredTuple = CISTPL_CONFIG;
	last_ret = first_tuple(handle, &tuple, &parse);
	last_ret = first_tuple(link, &tuple, &parse);
	if (last_ret != CS_SUCCESS) {
	if (last_ret != CS_SUCCESS) {
		last_fn = ParseTuple;
		last_fn = ParseTuple;
		goto cs_failed;
		goto cs_failed;
@@ -746,11 +730,6 @@ static void bt3c_config(dev_link_t *link)
	link->conf.ConfigBase = parse.config.base;
	link->conf.ConfigBase = parse.config.base;
	link->conf.Present = parse.config.rmask[0];
	link->conf.Present = parse.config.rmask[0];


	/* Configure card */
	link->state |= DEV_CONFIG;
	i = pcmcia_get_configuration_info(handle, &config);
	link->conf.Vcc = config.Vcc;

	/* First pass: look for a config entry that looks normal. */
	/* First pass: look for a config entry that looks normal. */
	tuple.TupleData = (cisdata_t *)buf;
	tuple.TupleData = (cisdata_t *)buf;
	tuple.TupleOffset = 0;
	tuple.TupleOffset = 0;
@@ -759,59 +738,59 @@ static void bt3c_config(dev_link_t *link)
	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
	/* Two tries: without IO aliases, then with aliases */
	/* Two tries: without IO aliases, then with aliases */
	for (try = 0; try < 2; try++) {
	for (try = 0; try < 2; try++) {
		i = first_tuple(handle, &tuple, &parse);
		i = first_tuple(link, &tuple, &parse);
		while (i != CS_NO_MORE_ITEMS) {
		while (i != CS_NO_MORE_ITEMS) {
			if (i != CS_SUCCESS)
			if (i != CS_SUCCESS)
				goto next_entry;
				goto next_entry;
			if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
			if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
				link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
				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)) {
			if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
				link->conf.ConfigIndex = cf->index;
				link->conf.ConfigIndex = cf->index;
				link->io.BasePort1 = cf->io.win[0].base;
				link->io.BasePort1 = cf->io.win[0].base;
				link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
				link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
				i = pcmcia_request_io(link->handle, &link->io);
				i = pcmcia_request_io(link, &link->io);
				if (i == CS_SUCCESS)
				if (i == CS_SUCCESS)
					goto found_port;
					goto found_port;
			}
			}
next_entry:
next_entry:
			i = next_tuple(handle, &tuple, &parse);
			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(handle, &tuple, &parse);
	i = first_tuple(link, &tuple, &parse);
	while (i != CS_NO_MORE_ITEMS) {
	while (i != CS_NO_MORE_ITEMS) {
		if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
		if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
			link->conf.ConfigIndex = cf->index;
			link->conf.ConfigIndex = cf->index;
			for (j = 0; j < 5; j++) {
			for (j = 0; j < 5; j++) {
				link->io.BasePort1 = base[j];
				link->io.BasePort1 = base[j];
				link->io.IOAddrLines = base[j] ? 16 : 3;
				link->io.IOAddrLines = base[j] ? 16 : 3;
				i = pcmcia_request_io(link->handle, &link->io);
				i = pcmcia_request_io(link, &link->io);
				if (i == CS_SUCCESS)
				if (i == CS_SUCCESS)
					goto found_port;
					goto found_port;
			}
			}
		}
		}
		i = next_tuple(handle, &tuple, &parse);
		i = next_tuple(link, &tuple, &parse);
	}
	}


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


	i = pcmcia_request_irq(link->handle, &link->irq);
	i = pcmcia_request_irq(link, &link->irq);
	if (i != CS_SUCCESS) {
	if (i != CS_SUCCESS) {
		cs_error(link->handle, RequestIRQ, i);
		cs_error(link, RequestIRQ, i);
		link->irq.AssignedIRQ = 0;
		link->irq.AssignedIRQ = 0;
	}
	}


	i = pcmcia_request_configuration(link->handle, &link->conf);
	i = pcmcia_request_configuration(link, &link->conf);
	if (i != CS_SUCCESS) {
	if (i != CS_SUCCESS) {
		cs_error(link->handle, RequestConfiguration, i);
		cs_error(link, RequestConfiguration, i);
		goto failed;
		goto failed;
	}
	}


@@ -819,55 +798,26 @@ static void bt3c_config(dev_link_t *link)
		goto failed;
		goto failed;


	strcpy(info->node.dev_name, info->hdev->name);
	strcpy(info->node.dev_name, info->hdev->name);
	link->dev = &info->node;
	link->dev_node = &info->node;
	link->state &= ~DEV_CONFIG_PENDING;


	return;
	return 0;


cs_failed:
cs_failed:
	cs_error(link->handle, last_fn, last_ret);
	cs_error(link, last_fn, last_ret);


failed:
failed:
	bt3c_release(link);
	bt3c_release(link);
	return -ENODEV;
}
}




static void bt3c_release(dev_link_t *link)
static void bt3c_release(struct pcmcia_device *link)
{
{
	bt3c_info_t *info = link->priv;
	bt3c_info_t *info = link->priv;


	if (link->state & DEV_PRESENT)
	bt3c_close(info);
	bt3c_close(info);


	link->dev = NULL;
	pcmcia_disable_device(link);

	pcmcia_release_configuration(link->handle);
	pcmcia_release_io(link->handle, &link->io);
	pcmcia_release_irq(link->handle, &link->irq);

	link->state &= ~DEV_CONFIG;
}

static int bt3c_suspend(struct pcmcia_device *dev)
{
	dev_link_t *link = dev_to_instance(dev);

	link->state |= DEV_SUSPEND;
	if (link->state & DEV_CONFIG)
		pcmcia_release_configuration(link->handle);

	return 0;
}

static int bt3c_resume(struct pcmcia_device *dev)
{
	dev_link_t *link = dev_to_instance(dev);

	link->state &= ~DEV_SUSPEND;
	if (DEV_OK(link))
		pcmcia_request_configuration(link->handle, &link->conf);

	return 0;
}
}




@@ -882,11 +832,9 @@ static struct pcmcia_driver bt3c_driver = {
	.drv		= {
	.drv		= {
		.name	= "bt3c_cs",
		.name	= "bt3c_cs",
	},
	},
	.probe		= bt3c_attach,
	.probe		= bt3c_probe,
	.remove		= bt3c_detach,
	.remove		= bt3c_detach,
	.id_table	= bt3c_ids,
	.id_table	= bt3c_ids,
	.suspend	= bt3c_suspend,
	.resume		= bt3c_resume,
};
};


static int __init init_bt3c_cs(void)
static int __init init_bt3c_cs(void)
+40 −90
Original line number Original line Diff line number Diff line
@@ -68,7 +68,7 @@ MODULE_LICENSE("GPL");




typedef struct btuart_info_t {
typedef struct btuart_info_t {
	dev_link_t link;
	struct pcmcia_device *p_dev;
	dev_node_t node;
	dev_node_t node;


	struct hci_dev *hdev;
	struct hci_dev *hdev;
@@ -84,8 +84,8 @@ typedef struct btuart_info_t {
} btuart_info_t;
} btuart_info_t;




static void btuart_config(dev_link_t *link);
static int btuart_config(struct pcmcia_device *link);
static void btuart_release(dev_link_t *link);
static void btuart_release(struct pcmcia_device *link);


static void btuart_detach(struct pcmcia_device *p_dev);
static void btuart_detach(struct pcmcia_device *p_dev);


@@ -146,13 +146,13 @@ static void btuart_write_wakeup(btuart_info_t *info)
	}
	}


	do {
	do {
		register unsigned int iobase = info->link.io.BasePort1;
		register unsigned int iobase = info->p_dev->io.BasePort1;
		register struct sk_buff *skb;
		register struct sk_buff *skb;
		register int len;
		register int len;


		clear_bit(XMIT_WAKEUP, &(info->tx_state));
		clear_bit(XMIT_WAKEUP, &(info->tx_state));


		if (!(info->link.state & DEV_PRESENT))
		if (!pcmcia_dev_present(info->p_dev))
			return;
			return;


		if (!(skb = skb_dequeue(&(info->txq))))
		if (!(skb = skb_dequeue(&(info->txq))))
@@ -187,7 +187,7 @@ static void btuart_receive(btuart_info_t *info)
		return;
		return;
	}
	}


	iobase = info->link.io.BasePort1;
	iobase = info->p_dev->io.BasePort1;


	do {
	do {
		info->hdev->stat.byte_rx++;
		info->hdev->stat.byte_rx++;
@@ -301,7 +301,7 @@ static irqreturn_t btuart_interrupt(int irq, void *dev_inst, struct pt_regs *reg
		return IRQ_NONE;
		return IRQ_NONE;
	}
	}


	iobase = info->link.io.BasePort1;
	iobase = info->p_dev->io.BasePort1;


	spin_lock(&(info->lock));
	spin_lock(&(info->lock));


@@ -357,7 +357,7 @@ static void btuart_change_speed(btuart_info_t *info, unsigned int speed)
		return;
		return;
	}
	}


	iobase = info->link.io.BasePort1;
	iobase = info->p_dev->io.BasePort1;


	spin_lock_irqsave(&(info->lock), flags);
	spin_lock_irqsave(&(info->lock), flags);


@@ -481,7 +481,7 @@ static int btuart_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned lon
static int btuart_open(btuart_info_t *info)
static int btuart_open(btuart_info_t *info)
{
{
	unsigned long flags;
	unsigned long flags;
	unsigned int iobase = info->link.io.BasePort1;
	unsigned int iobase = info->p_dev->io.BasePort1;
	struct hci_dev *hdev;
	struct hci_dev *hdev;


	spin_lock_init(&(info->lock));
	spin_lock_init(&(info->lock));
@@ -550,7 +550,7 @@ static int btuart_open(btuart_info_t *info)
static int btuart_close(btuart_info_t *info)
static int btuart_close(btuart_info_t *info)
{
{
	unsigned long flags;
	unsigned long flags;
	unsigned int iobase = info->link.io.BasePort1;
	unsigned int iobase = info->p_dev->io.BasePort1;
	struct hci_dev *hdev = info->hdev;
	struct hci_dev *hdev = info->hdev;


	if (!hdev)
	if (!hdev)
@@ -576,17 +576,16 @@ static int btuart_close(btuart_info_t *info)
	return 0;
	return 0;
}
}


static int btuart_attach(struct pcmcia_device *p_dev)
static int btuart_probe(struct pcmcia_device *link)
{
{
	btuart_info_t *info;
	btuart_info_t *info;
	dev_link_t *link;


	/* Create new info device */
	/* Create new info device */
	info = kzalloc(sizeof(*info), GFP_KERNEL);
	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!info)
	if (!info)
		return -ENOMEM;
		return -ENOMEM;


	link = &info->link;
	info->p_dev = link;
	link->priv = info;
	link->priv = info;


	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
@@ -598,31 +597,21 @@ static int btuart_attach(struct pcmcia_device *p_dev)
	link->irq.Instance = info;
	link->irq.Instance = info;


	link->conf.Attributes = CONF_ENABLE_IRQ;
	link->conf.Attributes = CONF_ENABLE_IRQ;
	link->conf.Vcc = 50;
	link->conf.IntType = INT_MEMORY_AND_IO;
	link->conf.IntType = INT_MEMORY_AND_IO;


	link->handle = p_dev;
	return btuart_config(link);
	p_dev->instance = link;

	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
	btuart_config(link);

	return 0;
}
}




static void btuart_detach(struct pcmcia_device *p_dev)
static void btuart_detach(struct pcmcia_device *link)
{
{
	dev_link_t *link = dev_to_instance(p_dev);
	btuart_info_t *info = link->priv;
	btuart_info_t *info = link->priv;


	if (link->state & DEV_CONFIG)
	btuart_release(link);
	btuart_release(link);

	kfree(info);
	kfree(info);
}
}


static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
{
{
	int i;
	int i;


@@ -633,30 +622,28 @@ static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
	return pcmcia_parse_tuple(handle, tuple, parse);
	return pcmcia_parse_tuple(handle, tuple, parse);
}
}


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


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


static void btuart_config(dev_link_t *link)
static int btuart_config(struct pcmcia_device *link)
{
{
	static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
	static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
	client_handle_t handle = link->handle;
	btuart_info_t *info = link->priv;
	btuart_info_t *info = link->priv;
	tuple_t tuple;
	tuple_t tuple;
	u_short buf[256];
	u_short buf[256];
	cisparse_t parse;
	cisparse_t parse;
	cistpl_cftable_entry_t *cf = &parse.cftable_entry;
	cistpl_cftable_entry_t *cf = &parse.cftable_entry;
	config_info_t config;
	int i, j, try, last_ret, last_fn;
	int i, j, try, last_ret, last_fn;


	tuple.TupleData = (cisdata_t *)buf;
	tuple.TupleData = (cisdata_t *)buf;
@@ -666,7 +653,7 @@ static void btuart_config(dev_link_t *link)


	/* Get configuration register information */
	/* Get configuration register information */
	tuple.DesiredTuple = CISTPL_CONFIG;
	tuple.DesiredTuple = CISTPL_CONFIG;
	last_ret = first_tuple(handle, &tuple, &parse);
	last_ret = first_tuple(link, &tuple, &parse);
	if (last_ret != CS_SUCCESS) {
	if (last_ret != CS_SUCCESS) {
		last_fn = ParseTuple;
		last_fn = ParseTuple;
		goto cs_failed;
		goto cs_failed;
@@ -674,11 +661,6 @@ static void btuart_config(dev_link_t *link)
	link->conf.ConfigBase = parse.config.base;
	link->conf.ConfigBase = parse.config.base;
	link->conf.Present = parse.config.rmask[0];
	link->conf.Present = parse.config.rmask[0];


	/* Configure card */
	link->state |= DEV_CONFIG;
	i = pcmcia_get_configuration_info(handle, &config);
	link->conf.Vcc = config.Vcc;

	/* First pass: look for a config entry that looks normal. */
	/* First pass: look for a config entry that looks normal. */
	tuple.TupleData = (cisdata_t *) buf;
	tuple.TupleData = (cisdata_t *) buf;
	tuple.TupleOffset = 0;
	tuple.TupleOffset = 0;
@@ -687,29 +669,29 @@ static void btuart_config(dev_link_t *link)
	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
	/* Two tries: without IO aliases, then with aliases */
	/* Two tries: without IO aliases, then with aliases */
	for (try = 0; try < 2; try++) {
	for (try = 0; try < 2; try++) {
		i = first_tuple(handle, &tuple, &parse);
		i = first_tuple(link, &tuple, &parse);
		while (i != CS_NO_MORE_ITEMS) {
		while (i != CS_NO_MORE_ITEMS) {
			if (i != CS_SUCCESS)
			if (i != CS_SUCCESS)
				goto next_entry;
				goto next_entry;
			if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
			if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
				link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
				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)) {
			if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
				link->conf.ConfigIndex = cf->index;
				link->conf.ConfigIndex = cf->index;
				link->io.BasePort1 = cf->io.win[0].base;
				link->io.BasePort1 = cf->io.win[0].base;
				link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
				link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
				i = pcmcia_request_io(link->handle, &link->io);
				i = pcmcia_request_io(link, &link->io);
				if (i == CS_SUCCESS)
				if (i == CS_SUCCESS)
					goto found_port;
					goto found_port;
			}
			}
next_entry:
next_entry:
			i = next_tuple(handle, &tuple, &parse);
			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(handle, &tuple, &parse);
	i = first_tuple(link, &tuple, &parse);
	while (i != CS_NO_MORE_ITEMS) {
	while (i != CS_NO_MORE_ITEMS) {
		if ((i == CS_SUCCESS) && (cf->io.nwin > 0)
		if ((i == CS_SUCCESS) && (cf->io.nwin > 0)
		    && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
		    && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
@@ -717,30 +699,30 @@ static void btuart_config(dev_link_t *link)
			for (j = 0; j < 5; j++) {
			for (j = 0; j < 5; j++) {
				link->io.BasePort1 = base[j];
				link->io.BasePort1 = base[j];
				link->io.IOAddrLines = base[j] ? 16 : 3;
				link->io.IOAddrLines = base[j] ? 16 : 3;
				i = pcmcia_request_io(link->handle, &link->io);
				i = pcmcia_request_io(link, &link->io);
				if (i == CS_SUCCESS)
				if (i == CS_SUCCESS)
					goto found_port;
					goto found_port;
			}
			}
		}
		}
		i = next_tuple(handle, &tuple, &parse);
		i = next_tuple(link, &tuple, &parse);
	}
	}


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


	i = pcmcia_request_irq(link->handle, &link->irq);
	i = pcmcia_request_irq(link, &link->irq);
	if (i != CS_SUCCESS) {
	if (i != CS_SUCCESS) {
		cs_error(link->handle, RequestIRQ, i);
		cs_error(link, RequestIRQ, i);
		link->irq.AssignedIRQ = 0;
		link->irq.AssignedIRQ = 0;
	}
	}


	i = pcmcia_request_configuration(link->handle, &link->conf);
	i = pcmcia_request_configuration(link, &link->conf);
	if (i != CS_SUCCESS) {
	if (i != CS_SUCCESS) {
		cs_error(link->handle, RequestConfiguration, i);
		cs_error(link, RequestConfiguration, i);
		goto failed;
		goto failed;
	}
	}


@@ -748,58 +730,28 @@ static void btuart_config(dev_link_t *link)
		goto failed;
		goto failed;


	strcpy(info->node.dev_name, info->hdev->name);
	strcpy(info->node.dev_name, info->hdev->name);
	link->dev = &info->node;
	link->dev_node = &info->node;
	link->state &= ~DEV_CONFIG_PENDING;


	return;
	return 0;


cs_failed:
cs_failed:
	cs_error(link->handle, last_fn, last_ret);
	cs_error(link, last_fn, last_ret);


failed:
failed:
	btuart_release(link);
	btuart_release(link);
	return -ENODEV;
}
}




static void btuart_release(dev_link_t *link)
static void btuart_release(struct pcmcia_device *link)
{
{
	btuart_info_t *info = link->priv;
	btuart_info_t *info = link->priv;


	if (link->state & DEV_PRESENT)
	btuart_close(info);
	btuart_close(info);


	link->dev = NULL;
	pcmcia_disable_device(link);

	pcmcia_release_configuration(link->handle);
	pcmcia_release_io(link->handle, &link->io);
	pcmcia_release_irq(link->handle, &link->irq);

	link->state &= ~DEV_CONFIG;
}
}


static int btuart_suspend(struct pcmcia_device *dev)
{
	dev_link_t *link = dev_to_instance(dev);

	link->state |= DEV_SUSPEND;
	if (link->state & DEV_CONFIG)
		pcmcia_release_configuration(link->handle);

	return 0;
}

static int btuart_resume(struct pcmcia_device *dev)
{
	dev_link_t *link = dev_to_instance(dev);

	link->state &= ~DEV_SUSPEND;
	if (DEV_OK(link))
		pcmcia_request_configuration(link->handle, &link->conf);

	return 0;
}


static struct pcmcia_device_id btuart_ids[] = {
static struct pcmcia_device_id btuart_ids[] = {
	/* don't use this driver. Use serial_cs + hci_uart instead */
	/* don't use this driver. Use serial_cs + hci_uart instead */
	PCMCIA_DEVICE_NULL
	PCMCIA_DEVICE_NULL
@@ -811,11 +763,9 @@ static struct pcmcia_driver btuart_driver = {
	.drv		= {
	.drv		= {
		.name	= "btuart_cs",
		.name	= "btuart_cs",
	},
	},
	.probe		= btuart_attach,
	.probe		= btuart_probe,
	.remove		= btuart_detach,
	.remove		= btuart_detach,
	.id_table	= btuart_ids,
	.id_table	= btuart_ids,
	.suspend	= btuart_suspend,
	.resume		= btuart_resume,
};
};


static int __init init_btuart_cs(void)
static int __init init_btuart_cs(void)
+36 −84

File changed.

Preview size limit exceeded, changes collapsed.

Loading