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

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
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);
......
...@@ -65,7 +65,7 @@ MODULE_LICENSE("GPL"); ...@@ -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 { ...@@ -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); ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 = { ...@@ -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)
......
...@@ -72,7 +72,7 @@ MODULE_LICENSE("GPL"); ...@@ -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 { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 @@ found_port: ...@@ -819,55 +798,26 @@ found_port:
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_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; pcmcia_disable_device(link);
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 = { ...@@ -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)
......
...@@ -68,7 +68,7 @@ MODULE_LICENSE("GPL"); ...@@ -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 { ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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) ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 @@ next_entry: ...@@ -717,30 +699,30 @@ next_entry:
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 @@ found_port: ...@@ -748,58 +730,28 @@ found_port:
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_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; pcmcia_disable_device(link);
} }
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 = { ...@@ -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)
......
...@@ -68,7 +68,7 @@ MODULE_LICENSE("GPL"); ...@@ -68,7 +68,7 @@ MODULE_LICENSE("GPL");
typedef struct dtl1_info_t { typedef struct dtl1_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;
...@@ -87,8 +87,8 @@ typedef struct dtl1_info_t { ...@@ -87,8 +87,8 @@ typedef struct dtl1_info_t {
} dtl1_info_t; } dtl1_info_t;
static void dtl1_config(dev_link_t *link); static int dtl1_config(struct pcmcia_device *link);
static void dtl1_release(dev_link_t *link); static void dtl1_release(struct pcmcia_device *link);
static void dtl1_detach(struct pcmcia_device *p_dev); static void dtl1_detach(struct pcmcia_device *p_dev);
...@@ -153,13 +153,13 @@ static void dtl1_write_wakeup(dtl1_info_t *info) ...@@ -153,13 +153,13 @@ static void dtl1_write_wakeup(dtl1_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))))
...@@ -218,7 +218,7 @@ static void dtl1_receive(dtl1_info_t *info) ...@@ -218,7 +218,7 @@ static void dtl1_receive(dtl1_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++;
...@@ -305,7 +305,7 @@ static irqreturn_t dtl1_interrupt(int irq, void *dev_inst, struct pt_regs *regs) ...@@ -305,7 +305,7 @@ static irqreturn_t dtl1_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));
...@@ -458,7 +458,7 @@ static int dtl1_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long ...@@ -458,7 +458,7 @@ static int dtl1_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long
static int dtl1_open(dtl1_info_t *info) static int dtl1_open(dtl1_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));
...@@ -504,7 +504,7 @@ static int dtl1_open(dtl1_info_t *info) ...@@ -504,7 +504,7 @@ static int dtl1_open(dtl1_info_t *info)
outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */ outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */
outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR); outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
info->ri_latch = inb(info->link.io.BasePort1 + UART_MSR) & UART_MSR_RI; info->ri_latch = inb(info->p_dev->io.BasePort1 + UART_MSR) & UART_MSR_RI;
/* Turn on interrupts */ /* Turn on interrupts */
outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER); outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
...@@ -529,7 +529,7 @@ static int dtl1_open(dtl1_info_t *info) ...@@ -529,7 +529,7 @@ static int dtl1_open(dtl1_info_t *info)
static int dtl1_close(dtl1_info_t *info) static int dtl1_close(dtl1_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)
...@@ -555,17 +555,16 @@ static int dtl1_close(dtl1_info_t *info) ...@@ -555,17 +555,16 @@ static int dtl1_close(dtl1_info_t *info)
return 0; return 0;
} }
static int dtl1_attach(struct pcmcia_device *p_dev) static int dtl1_probe(struct pcmcia_device *link)
{ {
dtl1_info_t *info; dtl1_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;
...@@ -577,31 +576,22 @@ static int dtl1_attach(struct pcmcia_device *p_dev) ...@@ -577,31 +576,22 @@ static int dtl1_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 dtl1_config(link);
p_dev->instance = link;
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
dtl1_config(link);
return 0;
} }
static void dtl1_detach(struct pcmcia_device *p_dev) static void dtl1_detach(struct pcmcia_device *link)
{ {
dev_link_t *link = dev_to_instance(p_dev);
dtl1_info_t *info = link->priv; dtl1_info_t *info = link->priv;
if (link->state & DEV_CONFIG) dtl1_release(link);
dtl1_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;
...@@ -612,29 +602,27 @@ static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) ...@@ -612,29 +602,27 @@ 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 dtl1_config(dev_link_t *link) static int dtl1_config(struct pcmcia_device *link)
{ {
client_handle_t handle = link->handle;
dtl1_info_t *info = link->priv; dtl1_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, last_ret, last_fn; int i, last_ret, last_fn;
tuple.TupleData = (cisdata_t *)buf; tuple.TupleData = (cisdata_t *)buf;
...@@ -644,7 +632,7 @@ static void dtl1_config(dev_link_t *link) ...@@ -644,7 +632,7 @@ static void dtl1_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;
...@@ -652,11 +640,6 @@ static void dtl1_config(dev_link_t *link) ...@@ -652,11 +640,6 @@ static void dtl1_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;
tuple.TupleData = (cisdata_t *)buf; tuple.TupleData = (cisdata_t *)buf;
tuple.TupleOffset = 0; tuple.TupleOffset = 0;
tuple.TupleDataMax = 255; tuple.TupleDataMax = 255;
...@@ -665,34 +648,34 @@ static void dtl1_config(dev_link_t *link) ...@@ -665,34 +648,34 @@ static void dtl1_config(dev_link_t *link)
/* 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(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 == 1) && (cf->io.win[0].len > 8)) { if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
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.NumPorts1 = cf->io.win[0].len; /*yo */ link->io.NumPorts1 = cf->io.win[0].len; /*yo */
link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; link->io.IOAddrLines = 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)
break; break;
} }
i = next_tuple(handle, &tuple, &parse); i = next_tuple(link, &tuple, &parse);
} }
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;
} }
...@@ -700,55 +683,26 @@ static void dtl1_config(dev_link_t *link) ...@@ -700,55 +683,26 @@ static void dtl1_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:
dtl1_release(link); dtl1_release(link);
return -ENODEV;
} }
static void dtl1_release(dev_link_t *link) static void dtl1_release(struct pcmcia_device *link)
{ {
dtl1_info_t *info = link->priv; dtl1_info_t *info = link->priv;
if (link->state & DEV_PRESENT) dtl1_close(info);
dtl1_close(info);
link->dev = NULL;
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 dtl1_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 dtl1_resume(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state &= ~DEV_SUSPEND; pcmcia_disable_device(link);
if (DEV_OK(link))
pcmcia_request_configuration(link->handle, &link->conf);
return 0;
} }
...@@ -765,11 +719,9 @@ static struct pcmcia_driver dtl1_driver = { ...@@ -765,11 +719,9 @@ static struct pcmcia_driver dtl1_driver = {
.drv = { .drv = {
.name = "dtl1_cs", .name = "dtl1_cs",
}, },
.probe = dtl1_attach, .probe = dtl1_probe,
.remove = dtl1_detach, .remove = dtl1_detach,
.id_table = dtl1_ids, .id_table = dtl1_ids,
.suspend = dtl1_suspend,
.resume = dtl1_resume,
}; };
static int __init init_dtl1_cs(void) static int __init init_dtl1_cs(void)
......
This diff is collapsed.
This diff is collapsed.
...@@ -228,7 +228,7 @@ typedef struct _mgslpc_info { ...@@ -228,7 +228,7 @@ typedef struct _mgslpc_info {
struct _input_signal_events input_signal_events; struct _input_signal_events input_signal_events;
/* PCMCIA support */ /* PCMCIA support */
dev_link_t link; struct pcmcia_device *p_dev;
dev_node_t node; dev_node_t node;
int stop; int stop;
...@@ -484,7 +484,7 @@ static void mgslpc_wait_until_sent(struct tty_struct *tty, int timeout); ...@@ -484,7 +484,7 @@ static void mgslpc_wait_until_sent(struct tty_struct *tty, int timeout);
/* PCMCIA prototypes */ /* PCMCIA prototypes */
static void mgslpc_config(dev_link_t *link); static int mgslpc_config(struct pcmcia_device *link);
static void mgslpc_release(u_long arg); static void mgslpc_release(u_long arg);
static void mgslpc_detach(struct pcmcia_device *p_dev); static void mgslpc_detach(struct pcmcia_device *p_dev);
...@@ -533,14 +533,14 @@ static void ldisc_receive_buf(struct tty_struct *tty, ...@@ -533,14 +533,14 @@ static void ldisc_receive_buf(struct tty_struct *tty,
} }
} }
static int mgslpc_attach(struct pcmcia_device *p_dev) static int mgslpc_probe(struct pcmcia_device *link)
{ {
MGSLPC_INFO *info; MGSLPC_INFO *info;
dev_link_t *link; int ret;
if (debug_level >= DEBUG_LEVEL_INFO) if (debug_level >= DEBUG_LEVEL_INFO)
printk("mgslpc_attach\n"); printk("mgslpc_attach\n");
info = (MGSLPC_INFO *)kmalloc(sizeof(MGSLPC_INFO), GFP_KERNEL); info = (MGSLPC_INFO *)kmalloc(sizeof(MGSLPC_INFO), GFP_KERNEL);
if (!info) { if (!info) {
printk("Error can't allocate device instance data\n"); printk("Error can't allocate device instance data\n");
...@@ -565,25 +565,22 @@ static int mgslpc_attach(struct pcmcia_device *p_dev) ...@@ -565,25 +565,22 @@ static int mgslpc_attach(struct pcmcia_device *p_dev)
info->imrb_value = 0xffff; info->imrb_value = 0xffff;
info->pim_value = 0xff; info->pim_value = 0xff;
link = &info->link; info->p_dev = link;
link->priv = info; link->priv = info;
/* Initialize the dev_link_t structure */ /* Initialize the struct pcmcia_device structure */
/* Interrupt setup */ /* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->irq.Handler = NULL; link->irq.Handler = NULL;
link->conf.Attributes = 0; link->conf.Attributes = 0;
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
link->handle = p_dev; ret = mgslpc_config(link);
p_dev->instance = link; if (ret)
return ret;
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
mgslpc_config(link);
mgslpc_add_device(info); mgslpc_add_device(info);
...@@ -596,15 +593,13 @@ static int mgslpc_attach(struct pcmcia_device *p_dev) ...@@ -596,15 +593,13 @@ static int mgslpc_attach(struct pcmcia_device *p_dev)
#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 void mgslpc_config(dev_link_t *link) static int mgslpc_config(struct pcmcia_device *link)
{ {
client_handle_t handle = link->handle;
MGSLPC_INFO *info = link->priv; MGSLPC_INFO *info = link->priv;
tuple_t tuple; tuple_t tuple;
cisparse_t parse; cisparse_t parse;
int last_fn, last_ret; int last_fn, last_ret;
u_char buf[64]; u_char buf[64];
config_info_t conf;
cistpl_cftable_entry_t dflt = { 0 }; cistpl_cftable_entry_t dflt = { 0 };
cistpl_cftable_entry_t *cfg; cistpl_cftable_entry_t *cfg;
...@@ -617,27 +612,20 @@ static void mgslpc_config(dev_link_t *link) ...@@ -617,27 +612,20 @@ static void mgslpc_config(dev_link_t *link)
tuple.TupleData = buf; tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf); tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0; tuple.TupleOffset = 0;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
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;
/* Look up the current Vcc */
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
link->conf.Vcc = conf.Vcc;
/* get CIS configuration entry */ /* get CIS configuration entry */
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
cfg = &(parse.cftable_entry); cfg = &(parse.cftable_entry);
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
if (cfg->index == 0) if (cfg->index == 0)
...@@ -658,11 +646,10 @@ static void mgslpc_config(dev_link_t *link) ...@@ -658,11 +646,10 @@ static void mgslpc_config(dev_link_t *link)
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
link->io.BasePort1 = io->win[0].base; link->io.BasePort1 = io->win[0].base;
link->io.NumPorts1 = io->win[0].len; link->io.NumPorts1 = io->win[0].len;
CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io)); CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
} }
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->conf.ConfigIndex = 8; link->conf.ConfigIndex = 8;
link->conf.Present = PRESENT_OPTION; link->conf.Present = PRESENT_OPTION;
...@@ -670,9 +657,9 @@ static void mgslpc_config(dev_link_t *link) ...@@ -670,9 +657,9 @@ static void mgslpc_config(dev_link_t *link)
link->irq.Attributes |= IRQ_HANDLE_PRESENT; link->irq.Attributes |= IRQ_HANDLE_PRESENT;
link->irq.Handler = mgslpc_isr; link->irq.Handler = mgslpc_isr;
link->irq.Instance = info; link->irq.Instance = info;
CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
info->io_base = link->io.BasePort1; info->io_base = link->io.BasePort1;
info->irq_level = link->irq.AssignedIRQ; info->irq_level = link->irq.AssignedIRQ;
...@@ -680,7 +667,7 @@ static void mgslpc_config(dev_link_t *link) ...@@ -680,7 +667,7 @@ static void mgslpc_config(dev_link_t *link)
/* add to linked list of devices */ /* add to linked list of devices */
sprintf(info->node.dev_name, "mgslpc0"); sprintf(info->node.dev_name, "mgslpc0");
info->node.major = info->node.minor = 0; info->node.major = info->node.minor = 0;
link->dev = &info->node; link->dev_node = &info->node;
printk(KERN_INFO "%s: index 0x%02x:", printk(KERN_INFO "%s: index 0x%02x:",
info->node.dev_name, link->conf.ConfigIndex); info->node.dev_name, link->conf.ConfigIndex);
...@@ -690,13 +677,12 @@ static void mgslpc_config(dev_link_t *link) ...@@ -690,13 +677,12 @@ static void mgslpc_config(dev_link_t *link)
printk(", io 0x%04x-0x%04x", link->io.BasePort1, printk(", io 0x%04x-0x%04x", link->io.BasePort1,
link->io.BasePort1+link->io.NumPorts1-1); link->io.BasePort1+link->io.NumPorts1-1);
printk("\n"); printk("\n");
return 0;
link->state &= ~DEV_CONFIG_PENDING;
return;
cs_failed: cs_failed:
cs_error(link->handle, last_fn, last_ret); cs_error(link, last_fn, last_ret);
mgslpc_release((u_long)link); mgslpc_release((u_long)link);
return -ENODEV;
} }
/* Card has been removed. /* Card has been removed.
...@@ -705,58 +691,38 @@ cs_failed: ...@@ -705,58 +691,38 @@ cs_failed:
*/ */
static void mgslpc_release(u_long arg) static void mgslpc_release(u_long arg)
{ {
dev_link_t *link = (dev_link_t *)arg; struct pcmcia_device *link = (struct pcmcia_device *)arg;
if (debug_level >= DEBUG_LEVEL_INFO) if (debug_level >= DEBUG_LEVEL_INFO)
printk("mgslpc_release(0x%p)\n", link); printk("mgslpc_release(0x%p)\n", link);
/* Unlink the device chain */
link->dev = NULL;
link->state &= ~DEV_CONFIG;
pcmcia_release_configuration(link->handle); pcmcia_disable_device(link);
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 *p_dev) static void mgslpc_detach(struct pcmcia_device *link)
{ {
dev_link_t *link = dev_to_instance(p_dev); if (debug_level >= DEBUG_LEVEL_INFO)
printk("mgslpc_detach(0x%p)\n", 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_INFO *)link->priv)->stop = 1; mgslpc_release((u_long)link);
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 *dev) static int mgslpc_suspend(struct pcmcia_device *link)
{ {
dev_link_t *link = dev_to_instance(dev);
MGSLPC_INFO *info = link->priv; MGSLPC_INFO *info = link->priv;
link->state |= DEV_SUSPEND;
info->stop = 1; info->stop = 1;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0; return 0;
} }
static int mgslpc_resume(struct pcmcia_device *dev) static int mgslpc_resume(struct pcmcia_device *link)
{ {
dev_link_t *link = dev_to_instance(dev);
MGSLPC_INFO *info = link->priv; MGSLPC_INFO *info = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
info->stop = 0; info->stop = 0;
return 0; return 0;
...@@ -1280,7 +1246,7 @@ static irqreturn_t mgslpc_isr(int irq, void *dev_id, struct pt_regs * regs) ...@@ -1280,7 +1246,7 @@ static irqreturn_t mgslpc_isr(int irq, void *dev_id, struct pt_regs * regs)
if (!info) if (!info)
return IRQ_NONE; return IRQ_NONE;
if (!(info->link.state & DEV_CONFIG)) if (!(info->p_dev->_locked))
return IRQ_HANDLED; return IRQ_HANDLED;
spin_lock(&info->lock); spin_lock(&info->lock);
...@@ -3033,7 +2999,7 @@ static struct pcmcia_driver mgslpc_driver = { ...@@ -3033,7 +2999,7 @@ static struct pcmcia_driver mgslpc_driver = {
.drv = { .drv = {
.name = "synclink_cs", .name = "synclink_cs",
}, },
.probe = mgslpc_attach, .probe = mgslpc_probe,
.remove = mgslpc_detach, .remove = mgslpc_detach,
.id_table = mgslpc_ids, .id_table = mgslpc_ids,
.suspend = mgslpc_suspend, .suspend = mgslpc_suspend,
......
...@@ -81,14 +81,14 @@ static const char ide_major[] = { ...@@ -81,14 +81,14 @@ static const char ide_major[] = {
}; };
typedef struct ide_info_t { typedef struct ide_info_t {
dev_link_t link; struct pcmcia_device *p_dev;
int ndev; int ndev;
dev_node_t node; dev_node_t node;
int hd; int hd;
} ide_info_t; } ide_info_t;
static void ide_release(dev_link_t *); static void ide_release(struct pcmcia_device *);
static void ide_config(dev_link_t *); static int ide_config(struct pcmcia_device *);
static void ide_detach(struct pcmcia_device *p_dev); static void ide_detach(struct pcmcia_device *p_dev);
...@@ -103,10 +103,9 @@ static void ide_detach(struct pcmcia_device *p_dev); ...@@ -103,10 +103,9 @@ static void ide_detach(struct pcmcia_device *p_dev);
======================================================================*/ ======================================================================*/
static int ide_attach(struct pcmcia_device *p_dev) static int ide_probe(struct pcmcia_device *link)
{ {
ide_info_t *info; ide_info_t *info;
dev_link_t *link;
DEBUG(0, "ide_attach()\n"); DEBUG(0, "ide_attach()\n");
...@@ -114,7 +113,9 @@ static int ide_attach(struct pcmcia_device *p_dev) ...@@ -114,7 +113,9 @@ static int ide_attach(struct pcmcia_device *p_dev)
info = kzalloc(sizeof(*info), GFP_KERNEL); info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info) if (!info)
return -ENOMEM; return -ENOMEM;
link = &info->link; link->priv = info;
info->p_dev = link;
link->priv = info;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
...@@ -122,16 +123,9 @@ static int ide_attach(struct pcmcia_device *p_dev) ...@@ -122,16 +123,9 @@ static int ide_attach(struct pcmcia_device *p_dev)
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->irq.IRQInfo1 = IRQ_LEVEL_ID;
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 ide_config(link);
p_dev->instance = link;
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
ide_config(link);
return 0;
} /* ide_attach */ } /* ide_attach */
/*====================================================================== /*======================================================================
...@@ -143,14 +137,11 @@ static int ide_attach(struct pcmcia_device *p_dev) ...@@ -143,14 +137,11 @@ static int ide_attach(struct pcmcia_device *p_dev)
======================================================================*/ ======================================================================*/
static void ide_detach(struct pcmcia_device *p_dev) static void ide_detach(struct pcmcia_device *link)
{ {
dev_link_t *link = dev_to_instance(p_dev);
DEBUG(0, "ide_detach(0x%p)\n", link); DEBUG(0, "ide_detach(0x%p)\n", link);
if (link->state & DEV_CONFIG) ide_release(link);
ide_release(link);
kfree(link->priv); kfree(link->priv);
} /* ide_detach */ } /* ide_detach */
...@@ -177,9 +168,8 @@ static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq ...@@ -177,9 +168,8 @@ static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq
#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 void ide_config(dev_link_t *link) static int ide_config(struct pcmcia_device *link)
{ {
client_handle_t handle = link->handle;
ide_info_t *info = link->priv; ide_info_t *info = link->priv;
tuple_t tuple; tuple_t tuple;
struct { struct {
...@@ -203,34 +193,30 @@ static void ide_config(dev_link_t *link) ...@@ -203,34 +193,30 @@ static void ide_config(dev_link_t *link)
tuple.TupleDataMax = 255; tuple.TupleDataMax = 255;
tuple.Attributes = 0; tuple.Attributes = 0;
tuple.DesiredTuple = CISTPL_CONFIG; tuple.DesiredTuple = CISTPL_CONFIG;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &stk->parse)); CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &stk->parse));
link->conf.ConfigBase = stk->parse.config.base; link->conf.ConfigBase = stk->parse.config.base;
link->conf.Present = stk->parse.config.rmask[0]; link->conf.Present = stk->parse.config.rmask[0];
tuple.DesiredTuple = CISTPL_MANFID; tuple.DesiredTuple = CISTPL_MANFID;
if (!pcmcia_get_first_tuple(handle, &tuple) && if (!pcmcia_get_first_tuple(link, &tuple) &&
!pcmcia_get_tuple_data(handle, &tuple) && !pcmcia_get_tuple_data(link, &tuple) &&
!pcmcia_parse_tuple(handle, &tuple, &stk->parse)) !pcmcia_parse_tuple(link, &tuple, &stk->parse))
is_kme = ((stk->parse.manfid.manf == MANFID_KME) && is_kme = ((stk->parse.manfid.manf == MANFID_KME) &&
((stk->parse.manfid.card == PRODID_KME_KXLC005_A) || ((stk->parse.manfid.card == PRODID_KME_KXLC005_A) ||
(stk->parse.manfid.card == PRODID_KME_KXLC005_B))); (stk->parse.manfid.card == PRODID_KME_KXLC005_B)));
/* Configure card */
link->state |= DEV_CONFIG;
/* Not sure if this is right... look up the current Vcc */ /* Not sure if this is right... look up the current Vcc */
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &stk->conf)); CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf));
link->conf.Vcc = stk->conf.Vcc;
pass = io_base = ctl_base = 0; pass = io_base = ctl_base = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
tuple.Attributes = 0; tuple.Attributes = 0;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) { while (1) {
if (pcmcia_get_tuple_data(handle, &tuple) != 0) goto next_entry; if (pcmcia_get_tuple_data(link, &tuple) != 0) goto next_entry;
if (pcmcia_parse_tuple(handle, &tuple, &stk->parse) != 0) goto next_entry; if (pcmcia_parse_tuple(link, &tuple, &stk->parse) != 0) goto next_entry;
/* Check for matching Vcc, unless we're desperate */ /* Check for matching Vcc, unless we're desperate */
if (!pass) { if (!pass) {
...@@ -244,10 +230,10 @@ static void ide_config(dev_link_t *link) ...@@ -244,10 +230,10 @@ static void ide_config(dev_link_t *link)
} }
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
link->conf.Vpp1 = link->conf.Vpp2 = link->conf.Vpp =
cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
link->conf.Vpp1 = link->conf.Vpp2 = link->conf.Vpp =
stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) { if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) {
...@@ -261,14 +247,14 @@ static void ide_config(dev_link_t *link) ...@@ -261,14 +247,14 @@ static void ide_config(dev_link_t *link)
link->io.NumPorts1 = 8; link->io.NumPorts1 = 8;
link->io.BasePort2 = io->win[1].base; link->io.BasePort2 = io->win[1].base;
link->io.NumPorts2 = (is_kme) ? 2 : 1; link->io.NumPorts2 = (is_kme) ? 2 : 1;
if (pcmcia_request_io(link->handle, &link->io) != 0) if (pcmcia_request_io(link, &link->io) != 0)
goto next_entry; goto next_entry;
io_base = link->io.BasePort1; io_base = link->io.BasePort1;
ctl_base = link->io.BasePort2; ctl_base = link->io.BasePort2;
} else if ((io->nwin == 1) && (io->win[0].len >= 16)) { } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
link->io.NumPorts1 = io->win[0].len; link->io.NumPorts1 = io->win[0].len;
link->io.NumPorts2 = 0; link->io.NumPorts2 = 0;
if (pcmcia_request_io(link->handle, &link->io) != 0) if (pcmcia_request_io(link, &link->io) != 0)
goto next_entry; goto next_entry;
io_base = link->io.BasePort1; io_base = link->io.BasePort1;
ctl_base = link->io.BasePort1 + 0x0e; ctl_base = link->io.BasePort1 + 0x0e;
...@@ -281,16 +267,16 @@ static void ide_config(dev_link_t *link) ...@@ -281,16 +267,16 @@ static void ide_config(dev_link_t *link)
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
memcpy(&stk->dflt, cfg, sizeof(stk->dflt)); memcpy(&stk->dflt, cfg, sizeof(stk->dflt));
if (pass) { if (pass) {
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
} else if (pcmcia_get_next_tuple(handle, &tuple) != 0) { } else if (pcmcia_get_next_tuple(link, &tuple) != 0) {
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
memset(&stk->dflt, 0, sizeof(stk->dflt)); memset(&stk->dflt, 0, sizeof(stk->dflt));
pass++; pass++;
} }
} }
CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
/* disable drive interrupts during IDE probe */ /* disable drive interrupts during IDE probe */
outb(0x02, ctl_base); outb(0x02, ctl_base);
...@@ -301,12 +287,12 @@ static void ide_config(dev_link_t *link) ...@@ -301,12 +287,12 @@ static void ide_config(dev_link_t *link)
/* retry registration in case device is still spinning up */ /* retry registration in case device is still spinning up */
for (hd = -1, i = 0; i < 10; i++) { for (hd = -1, i = 0; i < 10; i++) {
hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, handle); hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link);
if (hd >= 0) break; if (hd >= 0) break;
if (link->io.NumPorts1 == 0x20) { if (link->io.NumPorts1 == 0x20) {
outb(0x02, ctl_base + 0x10); outb(0x02, ctl_base + 0x10);
hd = idecs_register(io_base + 0x10, ctl_base + 0x10, hd = idecs_register(io_base + 0x10, ctl_base + 0x10,
link->irq.AssignedIRQ, handle); link->irq.AssignedIRQ, link);
if (hd >= 0) { if (hd >= 0) {
io_base += 0x10; io_base += 0x10;
ctl_base += 0x10; ctl_base += 0x10;
...@@ -328,25 +314,23 @@ static void ide_config(dev_link_t *link) ...@@ -328,25 +314,23 @@ static void ide_config(dev_link_t *link)
info->node.major = ide_major[hd]; info->node.major = ide_major[hd];
info->node.minor = 0; info->node.minor = 0;
info->hd = hd; info->hd = hd;
link->dev = &info->node; link->dev_node = &info->node;
printk(KERN_INFO "ide-cs: %s: Vcc = %d.%d, Vpp = %d.%d\n", printk(KERN_INFO "ide-cs: %s: Vpp = %d.%d\n",
info->node.dev_name, link->conf.Vcc / 10, link->conf.Vcc % 10, info->node.dev_name, link->conf.Vpp / 10, link->conf.Vpp % 10);
link->conf.Vpp1 / 10, link->conf.Vpp1 % 10);
link->state &= ~DEV_CONFIG_PENDING;
kfree(stk); kfree(stk);
return; return 0;
err_mem: err_mem:
printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n"); printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n");
goto failed; goto failed;
cs_failed: cs_failed:
cs_error(link->handle, last_fn, last_ret); cs_error(link, last_fn, last_ret);
failed: failed:
kfree(stk); kfree(stk);
ide_release(link); ide_release(link);
link->state &= ~DEV_CONFIG_PENDING; return -ENODEV;
} /* ide_config */ } /* ide_config */
/*====================================================================== /*======================================================================
...@@ -357,7 +341,7 @@ failed: ...@@ -357,7 +341,7 @@ failed:
======================================================================*/ ======================================================================*/
void ide_release(dev_link_t *link) void ide_release(struct pcmcia_device *link)
{ {
ide_info_t *info = link->priv; ide_info_t *info = link->priv;
...@@ -369,37 +353,10 @@ void ide_release(dev_link_t *link) ...@@ -369,37 +353,10 @@ void ide_release(dev_link_t *link)
ide_unregister(info->hd); ide_unregister(info->hd);
} }
info->ndev = 0; info->ndev = 0;
link->dev = NULL;
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
pcmcia_disable_device(link);
} /* ide_release */ } /* ide_release */
static int ide_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 ide_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;
}
/*====================================================================== /*======================================================================
...@@ -459,11 +416,9 @@ static struct pcmcia_driver ide_cs_driver = { ...@@ -459,11 +416,9 @@ static struct pcmcia_driver ide_cs_driver = {
.drv = { .drv = {
.name = "ide-cs", .name = "ide-cs",
}, },
.probe = ide_attach, .probe = ide_probe,
.remove = ide_detach, .remove = ide_detach,
.id_table = ide_ids, .id_table = ide_ids,
.suspend = ide_suspend,
.resume = ide_resume,
}; };
static int __init init_ide_cs(void) static int __init init_ide_cs(void)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -204,7 +204,7 @@ enum Window4 { /* Window 4: Xcvr/media bits. */ ...@@ -204,7 +204,7 @@ enum Window4 { /* Window 4: Xcvr/media bits. */
#define MEDIA_TP 0x00C0 /* Enable link beat and jabber for 10baseT. */ #define MEDIA_TP 0x00C0 /* Enable link beat and jabber for 10baseT. */
struct el3_private { struct el3_private {
dev_link_t link; struct pcmcia_device *p_dev;
dev_node_t node; dev_node_t node;
struct net_device_stats stats; struct net_device_stats stats;
u16 advertising, partner; /* NWay media advertisement */ u16 advertising, partner; /* NWay media advertisement */
...@@ -225,8 +225,8 @@ static char mii_preamble_required = 0; ...@@ -225,8 +225,8 @@ static char mii_preamble_required = 0;
/* Index of functions. */ /* Index of functions. */
static void tc574_config(dev_link_t *link); static int tc574_config(struct pcmcia_device *link);
static void tc574_release(dev_link_t *link); static void tc574_release(struct pcmcia_device *link);
static void mdio_sync(kio_addr_t ioaddr, int bits); static void mdio_sync(kio_addr_t ioaddr, int bits);
static int mdio_read(kio_addr_t ioaddr, int phy_id, int location); static int mdio_read(kio_addr_t ioaddr, int phy_id, int location);
...@@ -256,10 +256,9 @@ static void tc574_detach(struct pcmcia_device *p_dev); ...@@ -256,10 +256,9 @@ static void tc574_detach(struct pcmcia_device *p_dev);
with Card Services. with Card Services.
*/ */
static int tc574_attach(struct pcmcia_device *p_dev) static int tc574_probe(struct pcmcia_device *link)
{ {
struct el3_private *lp; struct el3_private *lp;
dev_link_t *link;
struct net_device *dev; struct net_device *dev;
DEBUG(0, "3c574_attach()\n"); DEBUG(0, "3c574_attach()\n");
...@@ -269,8 +268,8 @@ static int tc574_attach(struct pcmcia_device *p_dev) ...@@ -269,8 +268,8 @@ static int tc574_attach(struct pcmcia_device *p_dev)
if (!dev) if (!dev)
return -ENOMEM; return -ENOMEM;
lp = netdev_priv(dev); lp = netdev_priv(dev);
link = &lp->link;
link->priv = dev; link->priv = dev;
lp->p_dev = link;
spin_lock_init(&lp->window_lock); spin_lock_init(&lp->window_lock);
link->io.NumPorts1 = 32; link->io.NumPorts1 = 32;
...@@ -280,7 +279,6 @@ static int tc574_attach(struct pcmcia_device *p_dev) ...@@ -280,7 +279,6 @@ static int tc574_attach(struct pcmcia_device *p_dev)
link->irq.Handler = &el3_interrupt; link->irq.Handler = &el3_interrupt;
link->irq.Instance = dev; link->irq.Instance = dev;
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->conf.ConfigIndex = 1; link->conf.ConfigIndex = 1;
link->conf.Present = PRESENT_OPTION; link->conf.Present = PRESENT_OPTION;
...@@ -298,13 +296,7 @@ static int tc574_attach(struct pcmcia_device *p_dev) ...@@ -298,13 +296,7 @@ static int tc574_attach(struct pcmcia_device *p_dev)
dev->watchdog_timeo = TX_TIMEOUT; dev->watchdog_timeo = TX_TIMEOUT;
#endif #endif
link->handle = p_dev; return tc574_config(link);
p_dev->instance = link;
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
tc574_config(link);
return 0;
} /* tc574_attach */ } /* tc574_attach */
/* /*
...@@ -316,18 +308,16 @@ static int tc574_attach(struct pcmcia_device *p_dev) ...@@ -316,18 +308,16 @@ static int tc574_attach(struct pcmcia_device *p_dev)
*/ */
static void tc574_detach(struct pcmcia_device *p_dev) static void tc574_detach(struct pcmcia_device *link)
{ {
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
DEBUG(0, "3c574_detach(0x%p)\n", link); DEBUG(0, "3c574_detach(0x%p)\n", link);
if (link->dev) if (link->dev_node)
unregister_netdev(dev); unregister_netdev(dev);
if (link->state & DEV_CONFIG) tc574_release(link);
tc574_release(link);
free_netdev(dev); free_netdev(dev);
} /* tc574_detach */ } /* tc574_detach */
...@@ -343,9 +333,8 @@ static void tc574_detach(struct pcmcia_device *p_dev) ...@@ -343,9 +333,8 @@ static void tc574_detach(struct pcmcia_device *p_dev)
static const char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; static const char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
static void tc574_config(dev_link_t *link) static int tc574_config(struct pcmcia_device *link)
{ {
client_handle_t handle = link->handle;
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
struct el3_private *lp = netdev_priv(dev); struct el3_private *lp = netdev_priv(dev);
tuple_t tuple; tuple_t tuple;
...@@ -363,30 +352,27 @@ static void tc574_config(dev_link_t *link) ...@@ -363,30 +352,27 @@ static void tc574_config(dev_link_t *link)
tuple.Attributes = 0; tuple.Attributes = 0;
tuple.DesiredTuple = CISTPL_CONFIG; tuple.DesiredTuple = CISTPL_CONFIG;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
tuple.TupleData = (cisdata_t *)buf; tuple.TupleData = (cisdata_t *)buf;
tuple.TupleDataMax = 64; tuple.TupleDataMax = 64;
tuple.TupleOffset = 0; tuple.TupleOffset = 0;
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
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;
link->io.IOAddrLines = 16; link->io.IOAddrLines = 16;
for (i = j = 0; j < 0x400; j += 0x20) { for (i = j = 0; j < 0x400; j += 0x20) {
link->io.BasePort1 = j ^ 0x300; link->io.BasePort1 = j ^ 0x300;
i = pcmcia_request_io(link->handle, &link->io); i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS) break; if (i == CS_SUCCESS) break;
} }
if (i != CS_SUCCESS) { if (i != CS_SUCCESS) {
cs_error(link->handle, RequestIO, i); cs_error(link, RequestIO, i);
goto failed; goto failed;
} }
CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
dev->irq = link->irq.AssignedIRQ; dev->irq = link->irq.AssignedIRQ;
dev->base_addr = link->io.BasePort1; dev->base_addr = link->io.BasePort1;
...@@ -397,8 +383,8 @@ static void tc574_config(dev_link_t *link) ...@@ -397,8 +383,8 @@ static void tc574_config(dev_link_t *link)
the hardware address. The future products may include a modem chip the hardware address. The future products may include a modem chip
and put the address in the CIS. */ and put the address in the CIS. */
tuple.DesiredTuple = 0x88; tuple.DesiredTuple = 0x88;
if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) { if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) {
pcmcia_get_tuple_data(handle, &tuple); pcmcia_get_tuple_data(link, &tuple);
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
phys_addr[i] = htons(buf[i]); phys_addr[i] = htons(buf[i]);
} else { } else {
...@@ -412,9 +398,9 @@ static void tc574_config(dev_link_t *link) ...@@ -412,9 +398,9 @@ static void tc574_config(dev_link_t *link)
} }
} }
tuple.DesiredTuple = CISTPL_VERS_1; tuple.DesiredTuple = CISTPL_VERS_1;
if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS && if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS &&
pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS && pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS &&
pcmcia_parse_tuple(handle, &tuple, &parse) == CS_SUCCESS) { pcmcia_parse_tuple(link, &tuple, &parse) == CS_SUCCESS) {
cardname = parse.version_1.str + parse.version_1.ofs[1]; cardname = parse.version_1.str + parse.version_1.ofs[1];
} else } else
cardname = "3Com 3c574"; cardname = "3Com 3c574";
...@@ -473,13 +459,12 @@ static void tc574_config(dev_link_t *link) ...@@ -473,13 +459,12 @@ static void tc574_config(dev_link_t *link)
} }
} }
link->state &= ~DEV_CONFIG_PENDING; link->dev_node = &lp->node;
link->dev = &lp->node; SET_NETDEV_DEV(dev, &handle_to_dev(link));
SET_NETDEV_DEV(dev, &handle_to_dev(handle));
if (register_netdev(dev) != 0) { if (register_netdev(dev) != 0) {
printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n"); printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n");
link->dev = NULL; link->dev_node = NULL;
goto failed; goto failed;
} }
...@@ -493,13 +478,13 @@ static void tc574_config(dev_link_t *link) ...@@ -493,13 +478,13 @@ static void tc574_config(dev_link_t *link)
8 << config.u.ram_size, ram_split[config.u.ram_split], 8 << config.u.ram_size, ram_split[config.u.ram_split],
config.u.autoselect ? "autoselect " : ""); config.u.autoselect ? "autoselect " : "");
return; return 0;
cs_failed: cs_failed:
cs_error(link->handle, last_fn, last_ret); cs_error(link, last_fn, last_ret);
failed: failed:
tc574_release(link); tc574_release(link);
return; return -ENODEV;
} /* tc574_config */ } /* tc574_config */
...@@ -509,44 +494,28 @@ failed: ...@@ -509,44 +494,28 @@ failed:
still open, this will be postponed until it is closed. still open, this will be postponed until it is closed.
*/ */
static void tc574_release(dev_link_t *link) static void tc574_release(struct pcmcia_device *link)
{ {
DEBUG(0, "3c574_release(0x%p)\n", link); 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 tc574_suspend(struct pcmcia_device *p_dev) static int tc574_suspend(struct pcmcia_device *link)
{ {
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
link->state |= DEV_SUSPEND; if (link->open)
if (link->state & DEV_CONFIG) { netif_device_detach(dev);
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
return 0; return 0;
} }
static int tc574_resume(struct pcmcia_device *p_dev) static int tc574_resume(struct pcmcia_device *link)
{ {
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
link->state &= ~DEV_SUSPEND; if (link->open) {
if (link->state & DEV_CONFIG) { tc574_reset(dev);
pcmcia_request_configuration(link->handle, &link->conf); netif_device_attach(dev);
if (link->open) {
tc574_reset(dev);
netif_device_attach(dev);
}
} }
return 0; return 0;
...@@ -757,9 +726,9 @@ static void tc574_reset(struct net_device *dev) ...@@ -757,9 +726,9 @@ static void tc574_reset(struct net_device *dev)
static int el3_open(struct net_device *dev) static int el3_open(struct net_device *dev)
{ {
struct el3_private *lp = netdev_priv(dev); struct el3_private *lp = netdev_priv(dev);
dev_link_t *link = &lp->link; struct pcmcia_device *link = lp->p_dev;
if (!DEV_OK(link)) if (!pcmcia_dev_present(link))
return -ENODEV; return -ENODEV;
link->open++; link->open++;
...@@ -1203,11 +1172,11 @@ static int el3_close(struct net_device *dev) ...@@ -1203,11 +1172,11 @@ static int el3_close(struct net_device *dev)
{ {
kio_addr_t ioaddr = dev->base_addr; kio_addr_t ioaddr = dev->base_addr;
struct el3_private *lp = netdev_priv(dev); struct el3_private *lp = netdev_priv(dev);
dev_link_t *link = &lp->link; struct pcmcia_device *link = lp->p_dev;
DEBUG(2, "%s: shutting down ethercard.\n", dev->name); DEBUG(2, "%s: shutting down ethercard.\n", dev->name);
if (DEV_OK(link)) { if (pcmcia_dev_present(link)) {
unsigned long flags; unsigned long flags;
/* Turn off statistics ASAP. We update lp->stats below. */ /* Turn off statistics ASAP. We update lp->stats below. */
...@@ -1246,7 +1215,7 @@ static struct pcmcia_driver tc574_driver = { ...@@ -1246,7 +1215,7 @@ static struct pcmcia_driver tc574_driver = {
.drv = { .drv = {
.name = "3c574_cs", .name = "3c574_cs",
}, },
.probe = tc574_attach, .probe = tc574_probe,
.remove = tc574_detach, .remove = tc574_detach,
.id_table = tc574_ids, .id_table = tc574_ids,
.suspend = tc574_suspend, .suspend = tc574_suspend,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -31,7 +31,7 @@ typedef struct ray_dev_t { ...@@ -31,7 +31,7 @@ typedef struct ray_dev_t {
void __iomem *sram; /* pointer to beginning of shared RAM */ void __iomem *sram; /* pointer to beginning of shared RAM */
void __iomem *amem; /* pointer to attribute mem window */ void __iomem *amem; /* pointer to attribute mem window */
void __iomem *rmem; /* pointer to receive buffer window */ void __iomem *rmem; /* pointer to receive buffer window */
dev_link_t *finder; /* pointer back to dev_link_t for card */ struct pcmcia_device *finder; /* pointer back to struct pcmcia_device for card */
struct timer_list timer; struct timer_list timer;
long tx_ccs_lock; long tx_ccs_lock;
long ccs_lock; long ccs_lock;
......
This diff is collapsed.
This diff is collapsed.
...@@ -602,7 +602,7 @@ struct net_local ...@@ -602,7 +602,7 @@ struct net_local
dev_node_t node; /* ???? What is this stuff ???? */ dev_node_t node; /* ???? What is this stuff ???? */
struct net_device * dev; /* Reverse link... */ struct net_device * dev; /* Reverse link... */
spinlock_t spinlock; /* Serialize access to the hardware (SMP) */ spinlock_t spinlock; /* Serialize access to the hardware (SMP) */
dev_link_t * link; /* pcmcia structure */ struct pcmcia_device * link; /* pcmcia structure */
en_stats stats; /* Ethernet interface statistics */ en_stats stats; /* Ethernet interface statistics */
int nresets; /* Number of hw resets */ int nresets; /* Number of hw resets */
u_char configured; /* If it is configured */ u_char configured; /* If it is configured */
...@@ -733,9 +733,9 @@ static int ...@@ -733,9 +733,9 @@ static int
static inline void static inline void
wv_hw_reset(struct net_device *); /* Same, + start receiver unit */ wv_hw_reset(struct net_device *); /* Same, + start receiver unit */
static inline int static inline int
wv_pcmcia_config(dev_link_t *); /* Configure the pcmcia interface */ wv_pcmcia_config(struct pcmcia_device *); /* Configure the pcmcia interface */
static void static void
wv_pcmcia_release(dev_link_t *);/* Remove a device */ wv_pcmcia_release(struct pcmcia_device *);/* Remove a device */
/* ---------------------- INTERRUPT HANDLING ---------------------- */ /* ---------------------- INTERRUPT HANDLING ---------------------- */
static irqreturn_t static irqreturn_t
wavelan_interrupt(int, /* Interrupt handler */ wavelan_interrupt(int, /* Interrupt handler */
......
...@@ -611,5 +611,6 @@ struct wl3501_card { ...@@ -611,5 +611,6 @@ struct wl3501_card {
struct iw_spy_data spy_data; struct iw_spy_data spy_data;
struct iw_public_data wireless_data; struct iw_public_data wireless_data;
struct dev_node_t node; struct dev_node_t node;
struct pcmcia_device *p_dev;
}; };
#endif #endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
* (C) 1999 David A. Hinds * (C) 1999 David A. Hinds
*/ */
#include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/kernel.h> #include <linux/kernel.h>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment