提交 86dca4f8 编写于 作者: L 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
  ...
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
code (as of 2.6.16)
void (*remove) (struct pcmcia_device *dev);
......
......@@ -65,7 +65,7 @@ MODULE_LICENSE("GPL");
typedef struct bluecard_info_t {
dev_link_t link;
struct pcmcia_device *p_dev;
dev_node_t node;
struct hci_dev *hdev;
......@@ -85,8 +85,8 @@ typedef struct bluecard_info_t {
} bluecard_info_t;
static void bluecard_config(dev_link_t *link);
static void bluecard_release(dev_link_t *link);
static int bluecard_config(struct pcmcia_device *link);
static void bluecard_release(struct pcmcia_device *link);
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)
{
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)))
return;
......@@ -179,7 +179,7 @@ static void bluecard_activity_led_timeout(u_long arg)
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)))
return;
......@@ -235,7 +235,7 @@ static void bluecard_write_wakeup(bluecard_info_t *info)
}
do {
register unsigned int iobase = info->link.io.BasePort1;
register unsigned int iobase = info->p_dev->io.BasePort1;
register unsigned int offset;
register unsigned char command;
register unsigned long ready_bit;
......@@ -244,7 +244,7 @@ static void bluecard_write_wakeup(bluecard_info_t *info)
clear_bit(XMIT_WAKEUP, &(info->tx_state));
if (!(info->link.state & DEV_PRESENT))
if (!pcmcia_dev_present(info->p_dev))
return;
if (test_bit(XMIT_BUFFER_NUMBER, &(info->tx_state))) {
......@@ -382,7 +382,7 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
return;
}
iobase = info->link.io.BasePort1;
iobase = info->p_dev->io.BasePort1;
if (test_bit(XMIT_SENDING_READY, &(info->tx_state)))
bluecard_enable_activity_led(info);
......@@ -512,7 +512,7 @@ static irqreturn_t bluecard_interrupt(int irq, void *dev_inst, struct pt_regs *r
if (!test_bit(CARD_READY, &(info->hw_state)))
return IRQ_HANDLED;
iobase = info->link.io.BasePort1;
iobase = info->p_dev->io.BasePort1;
spin_lock(&(info->lock));
......@@ -626,7 +626,7 @@ static int bluecard_hci_flush(struct hci_dev *hdev)
static int bluecard_hci_open(struct hci_dev *hdev)
{
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)))
bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE);
......@@ -646,7 +646,7 @@ static int bluecard_hci_open(struct hci_dev *hdev)
static int bluecard_hci_close(struct hci_dev *hdev)
{
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)))
return 0;
......@@ -713,7 +713,7 @@ static int bluecard_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned l
static int bluecard_open(bluecard_info_t *info)
{
unsigned int iobase = info->link.io.BasePort1;
unsigned int iobase = info->p_dev->io.BasePort1;
struct hci_dev *hdev;
unsigned char id;
......@@ -831,7 +831,7 @@ static int bluecard_open(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;
if (!hdev)
......@@ -856,17 +856,16 @@ static int bluecard_close(bluecard_info_t *info)
return 0;
}
static int bluecard_attach(struct pcmcia_device *p_dev)
static int bluecard_probe(struct pcmcia_device *link)
{
bluecard_info_t *info;
dev_link_t *link;
/* Create new info device */
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
link = &info->link;
info->p_dev = link;
link->priv = info;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
......@@ -878,32 +877,22 @@ static int bluecard_attach(struct pcmcia_device *p_dev)
link->irq.Instance = info;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
link->handle = p_dev;
p_dev->instance = link;
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
bluecard_config(link);
return 0;
return bluecard_config(link);
}
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;
if (link->state & DEV_CONFIG)
bluecard_release(link);
bluecard_release(link);
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;
......@@ -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);
}
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;
tuple_t tuple;
u_short buf[256];
cisparse_t parse;
config_info_t config;
int i, n, last_ret, last_fn;
tuple.TupleData = (cisdata_t *)buf;
......@@ -935,7 +922,7 @@ static void bluecard_config(dev_link_t *link)
/* Get configuration register information */
tuple.DesiredTuple = CISTPL_CONFIG;
last_ret = first_tuple(handle, &tuple, &parse);
last_ret = first_tuple(link, &tuple, &parse);
if (last_ret != CS_SUCCESS) {
last_fn = ParseTuple;
goto cs_failed;
......@@ -943,36 +930,31 @@ static void bluecard_config(dev_link_t *link)
link->conf.ConfigBase = parse.config.base;
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->io.NumPorts1 = 64;
link->io.IOAddrLines = 6;
for (n = 0; n < 0x400; n += 0x40) {
link->io.BasePort1 = n ^ 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) {
cs_error(link->handle, RequestIO, i);
cs_error(link, RequestIO, i);
goto failed;
}
i = pcmcia_request_irq(link->handle, &link->irq);
i = pcmcia_request_irq(link, &link->irq);
if (i != CS_SUCCESS) {
cs_error(link->handle, RequestIRQ, i);
cs_error(link, RequestIRQ, i);
link->irq.AssignedIRQ = 0;
}
i = pcmcia_request_configuration(link->handle, &link->conf);
i = pcmcia_request_configuration(link, &link->conf);
if (i != CS_SUCCESS) {
cs_error(link->handle, RequestConfiguration, i);
cs_error(link, RequestConfiguration, i);
goto failed;
}
......@@ -980,57 +962,28 @@ static void bluecard_config(dev_link_t *link)
goto failed;
strcpy(info->node.dev_name, info->hdev->name);
link->dev = &info->node;
link->state &= ~DEV_CONFIG_PENDING;
link->dev_node = &info->node;
return;
return 0;
cs_failed:
cs_error(link->handle, last_fn, last_ret);
cs_error(link, last_fn, last_ret);
failed:
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;
if (link->state & DEV_PRESENT)
bluecard_close(info);
bluecard_close(info);
del_timer(&(info->timer));
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 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;
pcmcia_disable_device(link);
}
static struct pcmcia_device_id bluecard_ids[] = {
......@@ -1046,11 +999,9 @@ static struct pcmcia_driver bluecard_driver = {
.drv = {
.name = "bluecard_cs",
},
.probe = bluecard_attach,
.probe = bluecard_probe,
.remove = bluecard_detach,
.id_table = bluecard_ids,
.suspend = bluecard_suspend,
.resume = bluecard_resume,
};
static int __init init_bluecard_cs(void)
......
......@@ -72,7 +72,7 @@ MODULE_LICENSE("GPL");
typedef struct bt3c_info_t {
dev_link_t link;
struct pcmcia_device *p_dev;
dev_node_t node;
struct hci_dev *hdev;
......@@ -88,8 +88,8 @@ typedef struct bt3c_info_t {
} bt3c_info_t;
static void bt3c_config(dev_link_t *link);
static void bt3c_release(dev_link_t *link);
static int bt3c_config(struct pcmcia_device *link);
static void bt3c_release(struct pcmcia_device *link);
static void bt3c_detach(struct pcmcia_device *p_dev);
......@@ -191,11 +191,11 @@ static void bt3c_write_wakeup(bt3c_info_t *info)
return;
do {
register unsigned int iobase = info->link.io.BasePort1;
register unsigned int iobase = info->p_dev->io.BasePort1;
register struct sk_buff *skb;
register int len;
if (!(info->link.state & DEV_PRESENT))
if (!pcmcia_dev_present(info->p_dev))
break;
......@@ -229,7 +229,7 @@ static void bt3c_receive(bt3c_info_t *info)
return;
}
iobase = info->link.io.BasePort1;
iobase = info->p_dev->io.BasePort1;
avail = bt3c_read(iobase, 0x7006);
//printk("bt3c_cs: receiving %d bytes\n", avail);
......@@ -350,7 +350,7 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
return IRQ_NONE;
}
iobase = info->link.io.BasePort1;
iobase = info->p_dev->io.BasePort1;
spin_lock(&(info->lock));
......@@ -481,7 +481,7 @@ static int bt3c_load_firmware(bt3c_info_t *info, unsigned char *firmware, int co
unsigned int iobase, size, addr, fcs, tmp;
int i, err = 0;
iobase = info->link.io.BasePort1;
iobase = info->p_dev->io.BasePort1;
/* Reset */
bt3c_io_write(iobase, 0x8040, 0x0404);
......@@ -562,7 +562,6 @@ static int bt3c_open(bt3c_info_t *info)
{
const struct firmware *firmware;
struct hci_dev *hdev;
client_handle_t handle;
int err;
spin_lock_init(&(info->lock));
......@@ -594,10 +593,8 @@ static int bt3c_open(bt3c_info_t *info)
hdev->owner = THIS_MODULE;
handle = info->link.handle;
/* 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) {
BT_ERR("Firmware request failed");
goto error;
......@@ -648,17 +645,16 @@ static int bt3c_close(bt3c_info_t *info)
return 0;
}
static int bt3c_attach(struct pcmcia_device *p_dev)
static int bt3c_probe(struct pcmcia_device *link)
{
bt3c_info_t *info;
dev_link_t *link;
/* Create new info device */
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
link = &info->link;
info->p_dev = link;
link->priv = info;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
......@@ -670,31 +666,21 @@ static int bt3c_attach(struct pcmcia_device *p_dev)
link->irq.Instance = info;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
link->handle = p_dev;
p_dev->instance = link;
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
bt3c_config(link);
return 0;
return bt3c_config(link);
}
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;
if (link->state & DEV_CONFIG)
bt3c_release(link);
bt3c_release(link);
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;
......@@ -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);
}
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)
return CS_NO_MORE_ITEMS;
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)
return CS_NO_MORE_ITEMS;
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 };
client_handle_t handle = link->handle;
bt3c_info_t *info = link->priv;
tuple_t tuple;
u_short buf[256];
cisparse_t parse;
cistpl_cftable_entry_t *cf = &parse.cftable_entry;
config_info_t config;
int i, j, try, last_ret, last_fn;
tuple.TupleData = (cisdata_t *)buf;
......@@ -738,7 +722,7 @@ static void bt3c_config(dev_link_t *link)
/* Get configuration register information */
tuple.DesiredTuple = CISTPL_CONFIG;
last_ret = first_tuple(handle, &tuple, &parse);
last_ret = first_tuple(link, &tuple, &parse);
if (last_ret != CS_SUCCESS) {
last_fn = ParseTuple;
goto cs_failed;
......@@ -746,11 +730,6 @@ static void bt3c_config(dev_link_t *link)
link->conf.ConfigBase = parse.config.base;
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. */
tuple.TupleData = (cisdata_t *)buf;
tuple.TupleOffset = 0;
......@@ -759,59 +738,59 @@ static void bt3c_config(dev_link_t *link)
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
/* Two tries: without IO aliases, then with aliases */
for (try = 0; try < 2; try++) {
i = first_tuple(handle, &tuple, &parse);
i = first_tuple(link, &tuple, &parse);
while (i != CS_NO_MORE_ITEMS) {
if (i != CS_SUCCESS)
goto next_entry;
if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
link->conf.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)) {
link->conf.ConfigIndex = cf->index;
link->io.BasePort1 = cf->io.win[0].base;
link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
i = pcmcia_request_io(link->handle, &link->io);
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS)
goto found_port;
}
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
its base address, then try to grab any standard serial 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) {
if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
link->conf.ConfigIndex = cf->index;
for (j = 0; j < 5; j++) {
link->io.BasePort1 = base[j];
link->io.IOAddrLines = base[j] ? 16 : 3;
i = pcmcia_request_io(link->handle, &link->io);
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS)
goto found_port;
}
}
i = next_tuple(handle, &tuple, &parse);
i = next_tuple(link, &tuple, &parse);
}
found_port:
if (i != CS_SUCCESS) {
BT_ERR("No usable port range found");
cs_error(link->handle, RequestIO, i);
cs_error(link, RequestIO, i);
goto failed;
}
i = pcmcia_request_irq(link->handle, &link->irq);
i = pcmcia_request_irq(link, &link->irq);
if (i != CS_SUCCESS) {
cs_error(link->handle, RequestIRQ, i);
cs_error(link, RequestIRQ, i);
link->irq.AssignedIRQ = 0;
}
i = pcmcia_request_configuration(link->handle, &link->conf);
i = pcmcia_request_configuration(link, &link->conf);
if (i != CS_SUCCESS) {
cs_error(link->handle, RequestConfiguration, i);
cs_error(link, RequestConfiguration, i);
goto failed;
}
......@@ -819,55 +798,26 @@ static void bt3c_config(dev_link_t *link)
goto failed;
strcpy(info->node.dev_name, info->hdev->name);
link->dev = &info->node;
link->state &= ~DEV_CONFIG_PENDING;
link->dev_node = &info->node;
return;
return 0;
cs_failed:
cs_error(link->handle, last_fn, last_ret);
cs_error(link, last_fn, last_ret);
failed:
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;
if (link->state & DEV_PRESENT)
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);
bt3c_close(info);
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int bt3c_resume(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state &= ~DEV_SUSPEND;
if (DEV_OK(link))
pcmcia_request_configuration(link->handle, &link->conf);
return 0;
pcmcia_disable_device(link);
}
......@@ -882,11 +832,9 @@ static struct pcmcia_driver bt3c_driver = {
.drv = {
.name = "bt3c_cs",
},
.probe = bt3c_attach,
.probe = bt3c_probe,
.remove = bt3c_detach,
.id_table = bt3c_ids,
.suspend = bt3c_suspend,
.resume = bt3c_resume,
};
static int __init init_bt3c_cs(void)
......
......@@ -68,7 +68,7 @@ MODULE_LICENSE("GPL");
typedef struct btuart_info_t {
dev_link_t link;
struct pcmcia_device *p_dev;
dev_node_t node;
struct hci_dev *hdev;
......@@ -84,8 +84,8 @@ typedef struct btuart_info_t {
} btuart_info_t;
static void btuart_config(dev_link_t *link);
static void btuart_release(dev_link_t *link);
static int btuart_config(struct pcmcia_device *link);
static void btuart_release(struct pcmcia_device *link);
static void btuart_detach(struct pcmcia_device *p_dev);
......@@ -146,13 +146,13 @@ static void btuart_write_wakeup(btuart_info_t *info)
}
do {
register unsigned int iobase = info->link.io.BasePort1;
register unsigned int iobase = info->p_dev->io.BasePort1;
register struct sk_buff *skb;
register int len;
clear_bit(XMIT_WAKEUP, &(info->tx_state));
if (!(info->link.state & DEV_PRESENT))
if (!pcmcia_dev_present(info->p_dev))
return;
if (!(skb = skb_dequeue(&(info->txq))))
......@@ -187,7 +187,7 @@ static void btuart_receive(btuart_info_t *info)
return;
}
iobase = info->link.io.BasePort1;
iobase = info->p_dev->io.BasePort1;
do {
info->hdev->stat.byte_rx++;
......@@ -301,7 +301,7 @@ static irqreturn_t btuart_interrupt(int irq, void *dev_inst, struct pt_regs *reg
return IRQ_NONE;
}
iobase = info->link.io.BasePort1;
iobase = info->p_dev->io.BasePort1;
spin_lock(&(info->lock));
......@@ -357,7 +357,7 @@ static void btuart_change_speed(btuart_info_t *info, unsigned int speed)
return;
}
iobase = info->link.io.BasePort1;
iobase = info->p_dev->io.BasePort1;
spin_lock_irqsave(&(info->lock), flags);
......@@ -481,7 +481,7 @@ static int btuart_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned lon
static int btuart_open(btuart_info_t *info)
{
unsigned long flags;
unsigned int iobase = info->link.io.BasePort1;
unsigned int iobase = info->p_dev->io.BasePort1;
struct hci_dev *hdev;
spin_lock_init(&(info->lock));
......@@ -550,7 +550,7 @@ static int btuart_open(btuart_info_t *info)
static int btuart_close(btuart_info_t *info)
{
unsigned long flags;
unsigned int iobase = info->link.io.BasePort1;
unsigned int iobase = info->p_dev->io.BasePort1;
struct hci_dev *hdev = info->hdev;
if (!hdev)
......@@ -576,17 +576,16 @@ static int btuart_close(btuart_info_t *info)
return 0;
}
static int btuart_attach(struct pcmcia_device *p_dev)
static int btuart_probe(struct pcmcia_device *link)
{
btuart_info_t *info;
dev_link_t *link;
/* Create new info device */
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
link = &info->link;
info->p_dev = link;
link->priv = info;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
......@@ -598,31 +597,21 @@ static int btuart_attach(struct pcmcia_device *p_dev)
link->irq.Instance = info;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
link->handle = p_dev;
p_dev->instance = link;
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
btuart_config(link);
return 0;
return btuart_config(link);
}
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;
if (link->state & DEV_CONFIG)
btuart_release(link);
btuart_release(link);
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;
......@@ -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);
}
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)
return CS_NO_MORE_ITEMS;
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)
return CS_NO_MORE_ITEMS;
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 };
client_handle_t handle = link->handle;
btuart_info_t *info = link->priv;
tuple_t tuple;
u_short buf[256];
cisparse_t parse;
cistpl_cftable_entry_t *cf = &parse.cftable_entry;
config_info_t config;
int i, j, try, last_ret, last_fn;
tuple.TupleData = (cisdata_t *)buf;
......@@ -666,7 +653,7 @@ static void btuart_config(dev_link_t *link)
/* Get configuration register information */
tuple.DesiredTuple = CISTPL_CONFIG;
last_ret = first_tuple(handle, &tuple, &parse);
last_ret = first_tuple(link, &tuple, &parse);
if (last_ret != CS_SUCCESS) {
last_fn = ParseTuple;
goto cs_failed;
......@@ -674,11 +661,6 @@ static void btuart_config(dev_link_t *link)
link->conf.ConfigBase = parse.config.base;
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. */
tuple.TupleData = (cisdata_t *) buf;
tuple.TupleOffset = 0;
......@@ -687,29 +669,29 @@ static void btuart_config(dev_link_t *link)
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
/* Two tries: without IO aliases, then with aliases */
for (try = 0; try < 2; try++) {
i = first_tuple(handle, &tuple, &parse);
i = first_tuple(link, &tuple, &parse);
while (i != CS_NO_MORE_ITEMS) {
if (i != CS_SUCCESS)
goto next_entry;
if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
link->conf.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)) {
link->conf.ConfigIndex = cf->index;
link->io.BasePort1 = cf->io.win[0].base;
link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
i = pcmcia_request_io(link->handle, &link->io);
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS)
goto found_port;
}
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
its base address, then try to grab any standard serial 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) {
if ((i == CS_SUCCESS) && (cf->io.nwin > 0)
&& ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
......@@ -717,30 +699,30 @@ static void btuart_config(dev_link_t *link)
for (j = 0; j < 5; j++) {
link->io.BasePort1 = base[j];
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)
goto found_port;
}
}
i = next_tuple(handle, &tuple, &parse);
i = next_tuple(link, &tuple, &parse);
}
found_port:
if (i != CS_SUCCESS) {
BT_ERR("No usable port range found");
cs_error(link->handle, RequestIO, i);
cs_error(link, RequestIO, i);
goto failed;
}
i = pcmcia_request_irq(link->handle, &link->irq);
i = pcmcia_request_irq(link, &link->irq);
if (i != CS_SUCCESS) {
cs_error(link->handle, RequestIRQ, i);
cs_error(link, RequestIRQ, i);
link->irq.AssignedIRQ = 0;
}
i = pcmcia_request_configuration(link->handle, &link->conf);
i = pcmcia_request_configuration(link, &link->conf);
if (i != CS_SUCCESS) {
cs_error(link->handle, RequestConfiguration, i);
cs_error(link, RequestConfiguration, i);
goto failed;
}
......@@ -748,58 +730,28 @@ static void btuart_config(dev_link_t *link)
goto failed;
strcpy(info->node.dev_name, info->hdev->name);
link->dev = &info->node;
link->state &= ~DEV_CONFIG_PENDING;
link->dev_node = &info->node;
return;
return 0;
cs_failed:
cs_error(link->handle, last_fn, last_ret);
cs_error(link, last_fn, last_ret);
failed:
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;
if (link->state & DEV_PRESENT)
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);
btuart_close(info);
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[] = {
/* don't use this driver. Use serial_cs + hci_uart instead */
PCMCIA_DEVICE_NULL
......@@ -811,11 +763,9 @@ static struct pcmcia_driver btuart_driver = {
.drv = {
.name = "btuart_cs",
},
.probe = btuart_attach,
.probe = btuart_probe,
.remove = btuart_detach,
.id_table = btuart_ids,
.suspend = btuart_suspend,
.resume = btuart_resume,
};
static int __init init_btuart_cs(void)
......
......@@ -68,7 +68,7 @@ MODULE_LICENSE("GPL");
typedef struct dtl1_info_t {
dev_link_t link;
struct pcmcia_device *p_dev;
dev_node_t node;
struct hci_dev *hdev;
......@@ -87,8 +87,8 @@ typedef struct dtl1_info_t {
} dtl1_info_t;
static void dtl1_config(dev_link_t *link);
static void dtl1_release(dev_link_t *link);
static int dtl1_config(struct pcmcia_device *link);
static void dtl1_release(struct pcmcia_device *link);
static void dtl1_detach(struct pcmcia_device *p_dev);
......@@ -153,13 +153,13 @@ static void dtl1_write_wakeup(dtl1_info_t *info)
}
do {
register unsigned int iobase = info->link.io.BasePort1;
register unsigned int iobase = info->p_dev->io.BasePort1;
register struct sk_buff *skb;
register int len;
clear_bit(XMIT_WAKEUP, &(info->tx_state));
if (!(info->link.state & DEV_PRESENT))
if (!pcmcia_dev_present(info->p_dev))
return;
if (!(skb = skb_dequeue(&(info->txq))))
......@@ -218,7 +218,7 @@ static void dtl1_receive(dtl1_info_t *info)
return;
}
iobase = info->link.io.BasePort1;
iobase = info->p_dev->io.BasePort1;
do {
info->hdev->stat.byte_rx++;
......@@ -305,7 +305,7 @@ static irqreturn_t dtl1_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
return IRQ_NONE;
}
iobase = info->link.io.BasePort1;
iobase = info->p_dev->io.BasePort1;
spin_lock(&(info->lock));
......@@ -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)
{
unsigned long flags;
unsigned int iobase = info->link.io.BasePort1;
unsigned int iobase = info->p_dev->io.BasePort1;
struct hci_dev *hdev;
spin_lock_init(&(info->lock));
......@@ -504,7 +504,7 @@ static int dtl1_open(dtl1_info_t *info)
outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */
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 */
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)
static int dtl1_close(dtl1_info_t *info)
{
unsigned long flags;
unsigned int iobase = info->link.io.BasePort1;
unsigned int iobase = info->p_dev->io.BasePort1;
struct hci_dev *hdev = info->hdev;
if (!hdev)
......@@ -555,17 +555,16 @@ static int dtl1_close(dtl1_info_t *info)
return 0;
}
static int dtl1_attach(struct pcmcia_device *p_dev)
static int dtl1_probe(struct pcmcia_device *link)
{
dtl1_info_t *info;
dev_link_t *link;
/* Create new info device */
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
link = &info->link;
info->p_dev = link;
link->priv = info;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
......@@ -577,31 +576,22 @@ static int dtl1_attach(struct pcmcia_device *p_dev)
link->irq.Instance = info;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
link->handle = p_dev;
p_dev->instance = link;
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
dtl1_config(link);
return 0;
return dtl1_config(link);
}
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;
if (link->state & DEV_CONFIG)
dtl1_release(link);
dtl1_release(link);
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;
......@@ -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);
}
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)
return CS_NO_MORE_ITEMS;
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)
return CS_NO_MORE_ITEMS;
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;
tuple_t tuple;
u_short buf[256];
cisparse_t parse;
cistpl_cftable_entry_t *cf = &parse.cftable_entry;
config_info_t config;
int i, last_ret, last_fn;
tuple.TupleData = (cisdata_t *)buf;
......@@ -644,7 +632,7 @@ static void dtl1_config(dev_link_t *link)
/* Get configuration register information */
tuple.DesiredTuple = CISTPL_CONFIG;
last_ret = first_tuple(handle, &tuple, &parse);
last_ret = first_tuple(link, &tuple, &parse);
if (last_ret != CS_SUCCESS) {
last_fn = ParseTuple;
goto cs_failed;
......@@ -652,11 +640,6 @@ static void dtl1_config(dev_link_t *link)
link->conf.ConfigBase = parse.config.base;
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.TupleOffset = 0;
tuple.TupleDataMax = 255;
......@@ -665,34 +648,34 @@ static void dtl1_config(dev_link_t *link)
/* Look for a generic full-sized window */
link->io.NumPorts1 = 8;
i = first_tuple(handle, &tuple, &parse);
i = first_tuple(link, &tuple, &parse);
while (i != CS_NO_MORE_ITEMS) {
if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
link->conf.ConfigIndex = cf->index;
link->io.BasePort1 = cf->io.win[0].base;
link->io.NumPorts1 = cf->io.win[0].len; /*yo */
link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
i = pcmcia_request_io(link->handle, &link->io);
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS)
break;
}
i = next_tuple(handle, &tuple, &parse);
i = next_tuple(link, &tuple, &parse);
}
if (i != CS_SUCCESS) {
cs_error(link->handle, RequestIO, i);
cs_error(link, RequestIO, i);
goto failed;
}
i = pcmcia_request_irq(link->handle, &link->irq);
i = pcmcia_request_irq(link, &link->irq);
if (i != CS_SUCCESS) {
cs_error(link->handle, RequestIRQ, i);
cs_error(link, RequestIRQ, i);
link->irq.AssignedIRQ = 0;
}
i = pcmcia_request_configuration(link->handle, &link->conf);
i = pcmcia_request_configuration(link, &link->conf);
if (i != CS_SUCCESS) {
cs_error(link->handle, RequestConfiguration, i);
cs_error(link, RequestConfiguration, i);
goto failed;
}
......@@ -700,55 +683,26 @@ static void dtl1_config(dev_link_t *link)
goto failed;
strcpy(info->node.dev_name, info->hdev->name);
link->dev = &info->node;
link->state &= ~DEV_CONFIG_PENDING;
link->dev_node = &info->node;
return;
return 0;
cs_failed:
cs_error(link->handle, last_fn, last_ret);
cs_error(link, last_fn, last_ret);
failed:
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;
if (link->state & DEV_PRESENT)
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);
dtl1_close(info);
link->state &= ~DEV_SUSPEND;
if (DEV_OK(link))
pcmcia_request_configuration(link->handle, &link->conf);
return 0;
pcmcia_disable_device(link);
}
......@@ -765,11 +719,9 @@ static struct pcmcia_driver dtl1_driver = {
.drv = {
.name = "dtl1_cs",
},
.probe = dtl1_attach,
.probe = dtl1_probe,
.remove = dtl1_detach,
.id_table = dtl1_ids,
.suspend = dtl1_suspend,
.resume = dtl1_resume,
};
static int __init init_dtl1_cs(void)
......
......@@ -46,7 +46,7 @@
/* #define ATR_CSUM */
#ifdef PCMCIA_DEBUG
#define reader_to_dev(x) (&handle_to_dev(x->link.handle))
#define reader_to_dev(x) (&handle_to_dev(x->p_dev->handle))
static int pc_debug = PCMCIA_DEBUG;
module_param(pc_debug, int, 0600);
#define DEBUGP(n, rdr, x, args...) do { \
......@@ -67,7 +67,7 @@ static char *version = "cm4000_cs.c v2.4.0gm6 - All bugs added by Harald Welte";
#define T_100MSEC msecs_to_jiffies(100)
#define T_500MSEC msecs_to_jiffies(500)
static void cm4000_release(dev_link_t *link);
static void cm4000_release(struct pcmcia_device *link);
static int major; /* major number we get from the kernel */
......@@ -106,7 +106,7 @@ static int major; /* major number we get from the kernel */
#define REG_STOPBITS(x) (x + 7)
struct cm4000_dev {
dev_link_t link; /* pcmcia link */
struct pcmcia_device *p_dev;
dev_node_t node; /* OS node (major,minor) */
unsigned char atr[MAX_ATR];
......@@ -149,14 +149,14 @@ struct cm4000_dev {
#define ZERO_DEV(dev) \
memset(&dev->atr_csum,0, \
sizeof(struct cm4000_dev) - \
/*link*/ sizeof(dev_link_t) - \
/*link*/ sizeof(struct pcmcia_device) - \
/*node*/ sizeof(dev_node_t) - \
/*atr*/ MAX_ATR*sizeof(char) - \
/*rbuf*/ 512*sizeof(char) - \
/*sbuf*/ 512*sizeof(char) - \
/*queue*/ 4*sizeof(wait_queue_head_t))
static dev_link_t *dev_table[CM4000_MAX_DEV];
static struct pcmcia_device *dev_table[CM4000_MAX_DEV];
static struct class *cmm_class;
/* This table doesn't use spaces after the comma between fields and thus
......@@ -454,7 +454,7 @@ static struct card_fixup card_fixups[] = {
static void set_cardparameter(struct cm4000_dev *dev)
{
int i;
ioaddr_t iobase = dev->link.io.BasePort1;
ioaddr_t iobase = dev->p_dev->io.BasePort1;
u_int8_t stopbits = 0x02; /* ISO default */
DEBUGP(3, dev, "-> set_cardparameter\n");
......@@ -487,7 +487,7 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq)
unsigned short num_bytes_read;
unsigned char pts_reply[4];
ssize_t rc;
ioaddr_t iobase = dev->link.io.BasePort1;
ioaddr_t iobase = dev->p_dev->io.BasePort1;
rc = 0;
......@@ -699,7 +699,7 @@ static void terminate_monitor(struct cm4000_dev *dev)
static void monitor_card(unsigned long p)
{
struct cm4000_dev *dev = (struct cm4000_dev *) p;
ioaddr_t iobase = dev->link.io.BasePort1;
ioaddr_t iobase = dev->p_dev->io.BasePort1;
unsigned short s;
struct ptsreq ptsreq;
int i, atrc;
......@@ -962,7 +962,7 @@ static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count,
loff_t *ppos)
{
struct cm4000_dev *dev = filp->private_data;
ioaddr_t iobase = dev->link.io.BasePort1;
ioaddr_t iobase = dev->p_dev->io.BasePort1;
ssize_t rc;
int i, j, k;
......@@ -971,7 +971,7 @@ static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count,
if (count == 0) /* according to manpage */
return 0;
if ((dev->link.state & DEV_PRESENT) == 0 || /* socket removed */
if (!pcmcia_dev_present(dev->p_dev) || /* device removed */
test_bit(IS_CMM_ABSENT, &dev->flags))
return -ENODEV;
......@@ -1083,7 +1083,7 @@ static ssize_t cmm_write(struct file *filp, const char __user *buf,
size_t count, loff_t *ppos)
{
struct cm4000_dev *dev = (struct cm4000_dev *) filp->private_data;
ioaddr_t iobase = dev->link.io.BasePort1;
ioaddr_t iobase = dev->p_dev->io.BasePort1;
unsigned short s;
unsigned char tmp;
unsigned char infolen;
......@@ -1108,7 +1108,7 @@ static ssize_t cmm_write(struct file *filp, const char __user *buf,
sendT0 = dev->proto ? 0 : nr > 5 ? 0x08 : 0;
if ((dev->link.state & DEV_PRESENT) == 0 || /* socket removed */
if (!pcmcia_dev_present(dev->p_dev) || /* device removed */
test_bit(IS_CMM_ABSENT, &dev->flags))
return -ENODEV;
......@@ -1440,8 +1440,8 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
struct cm4000_dev *dev = filp->private_data;
ioaddr_t iobase = dev->link.io.BasePort1;
dev_link_t *link;
ioaddr_t iobase = dev->p_dev->io.BasePort1;
struct pcmcia_device *link;
int size;
int rc;
void __user *argp = (void __user *)arg;
......@@ -1458,7 +1458,7 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
iminor(inode), ioctl_names[_IOC_NR(cmd)]);
link = dev_table[iminor(inode)];
if (!(DEV_OK(link))) {
if (!pcmcia_dev_present(link)) {
DEBUGP(4, dev, "DEV_OK false\n");
return -ENODEV;
}
......@@ -1660,14 +1660,14 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
static int cmm_open(struct inode *inode, struct file *filp)
{
struct cm4000_dev *dev;
dev_link_t *link;
struct pcmcia_device *link;
int rc, minor = iminor(inode);
if (minor >= CM4000_MAX_DEV)
return -ENODEV;
link = dev_table[minor];
if (link == NULL || !(DEV_OK(link)))
if (link == NULL || !pcmcia_dev_present(link))
return -ENODEV;
if (link->open)
......@@ -1709,7 +1709,7 @@ static int cmm_open(struct inode *inode, struct file *filp)
static int cmm_close(struct inode *inode, struct file *filp)
{
struct cm4000_dev *dev;
dev_link_t *link;
struct pcmcia_device *link;
int minor = iminor(inode);
if (minor >= CM4000_MAX_DEV)
......@@ -1735,7 +1735,7 @@ static int cmm_close(struct inode *inode, struct file *filp)
return 0;
}
static void cmm_cm4000_release(dev_link_t * link)
static void cmm_cm4000_release(struct pcmcia_device * link)
{
struct cm4000_dev *dev = link->priv;
......@@ -1759,13 +1759,11 @@ static void cmm_cm4000_release(dev_link_t * link)
/*==== Interface to PCMCIA Layer =======================================*/
static void cm4000_config(dev_link_t * link, int devno)
static int cm4000_config(struct pcmcia_device * link, int devno)
{
client_handle_t handle = link->handle;
struct cm4000_dev *dev;
tuple_t tuple;
cisparse_t parse;
config_info_t conf;
u_char buf[64];
int fail_fn, fail_rc;
int rc;
......@@ -1777,41 +1775,34 @@ static void cm4000_config(dev_link_t * link, int devno)
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
if ((fail_rc = pcmcia_get_first_tuple(handle, &tuple)) != CS_SUCCESS) {
if ((fail_rc = pcmcia_get_first_tuple(link, &tuple)) != CS_SUCCESS) {
fail_fn = GetFirstTuple;
goto cs_failed;
}
if ((fail_rc = pcmcia_get_tuple_data(handle, &tuple)) != CS_SUCCESS) {
if ((fail_rc = pcmcia_get_tuple_data(link, &tuple)) != CS_SUCCESS) {
fail_fn = GetTupleData;
goto cs_failed;
}
if ((fail_rc =
pcmcia_parse_tuple(handle, &tuple, &parse)) != CS_SUCCESS) {
pcmcia_parse_tuple(link, &tuple, &parse)) != CS_SUCCESS) {
fail_fn = ParseTuple;
goto cs_failed;
}
if ((fail_rc =
pcmcia_get_configuration_info(handle, &conf)) != CS_SUCCESS) {
fail_fn = GetConfigurationInfo;
goto cs_failed;
}
link->state |= DEV_CONFIG;
link->conf.ConfigBase = parse.config.base;
link->conf.Present = parse.config.rmask[0];
link->conf.Vcc = conf.Vcc;
link->io.BasePort2 = 0;
link->io.NumPorts2 = 0;
link->io.Attributes2 = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
for (rc = pcmcia_get_first_tuple(handle, &tuple);
rc == CS_SUCCESS; rc = pcmcia_get_next_tuple(handle, &tuple)) {
for (rc = pcmcia_get_first_tuple(link, &tuple);
rc == CS_SUCCESS; rc = pcmcia_get_next_tuple(link, &tuple)) {
rc = pcmcia_get_tuple_data(handle, &tuple);
rc = pcmcia_get_tuple_data(link, &tuple);
if (rc != CS_SUCCESS)
continue;
rc = pcmcia_parse_tuple(handle, &tuple, &parse);
rc = pcmcia_parse_tuple(link, &tuple, &parse);
if (rc != CS_SUCCESS)
continue;
......@@ -1831,7 +1822,7 @@ static void cm4000_config(dev_link_t * link, int devno)
link->io.IOAddrLines = parse.cftable_entry.io.flags
& CISTPL_IO_LINES_MASK;
rc = pcmcia_request_io(handle, &link->io);
rc = pcmcia_request_io(link, &link->io);
if (rc == CS_SUCCESS)
break; /* we are done */
}
......@@ -1841,7 +1832,7 @@ static void cm4000_config(dev_link_t * link, int devno)
link->conf.IntType = 00000002;
if ((fail_rc =
pcmcia_request_configuration(handle, &link->conf)) != CS_SUCCESS) {
pcmcia_request_configuration(link, &link->conf)) != CS_SUCCESS) {
fail_fn = RequestConfiguration;
goto cs_release;
}
......@@ -1851,63 +1842,48 @@ static void cm4000_config(dev_link_t * link, int devno)
dev->node.major = major;
dev->node.minor = devno;
dev->node.next = NULL;
link->dev = &dev->node;
link->state &= ~DEV_CONFIG_PENDING;
link->dev_node = &dev->node;
return;
return 0;
cs_failed:
cs_error(handle, fail_fn, fail_rc);
cs_error(link, fail_fn, fail_rc);
cs_release:
cm4000_release(link);
link->state &= ~DEV_CONFIG_PENDING;
return -ENODEV;
}
static int cm4000_suspend(struct pcmcia_device *p_dev)
static int cm4000_suspend(struct pcmcia_device *link)
{
dev_link_t *link = dev_to_instance(p_dev);
struct cm4000_dev *dev;
dev = link->priv;
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
stop_monitor(dev);
return 0;
}
static int cm4000_resume(struct pcmcia_device *p_dev)
static int cm4000_resume(struct pcmcia_device *link)
{
dev_link_t *link = dev_to_instance(p_dev);
struct cm4000_dev *dev;
dev = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open)
start_monitor(dev);
return 0;
}
static void cm4000_release(dev_link_t *link)
static void cm4000_release(struct pcmcia_device *link)
{
cmm_cm4000_release(link->priv); /* delay release until device closed */
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_disable_device(link);
}
static int cm4000_attach(struct pcmcia_device *p_dev)
static int cm4000_probe(struct pcmcia_device *link)
{
struct cm4000_dev *dev;
dev_link_t *link;
int i;
int i, ret;
for (i = 0; i < CM4000_MAX_DEV; i++)
if (dev_table[i] == NULL)
......@@ -1923,7 +1899,7 @@ static int cm4000_attach(struct pcmcia_device *p_dev)
if (dev == NULL)
return -ENOMEM;
link = &dev->link;
dev->p_dev = link;
link->priv = dev;
link->conf.IntType = INT_MEMORY_AND_IO;
dev_table[i] = link;
......@@ -1933,11 +1909,9 @@ static int cm4000_attach(struct pcmcia_device *p_dev)
init_waitqueue_head(&dev->atrq);
init_waitqueue_head(&dev->readq);
link->handle = p_dev;
p_dev->instance = link;
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
cm4000_config(link, i);
ret = cm4000_config(link, i);
if (ret)
return ret;
class_device_create(cmm_class, NULL, MKDEV(major, i), NULL,
"cmm%d", i);
......@@ -1945,9 +1919,8 @@ static int cm4000_attach(struct pcmcia_device *p_dev)
return 0;
}
static void cm4000_detach(struct pcmcia_device *p_dev)
static void cm4000_detach(struct pcmcia_device *link)
{
dev_link_t *link = dev_to_instance(p_dev);
struct cm4000_dev *dev = link->priv;
int devno;
......@@ -1958,11 +1931,9 @@ static void cm4000_detach(struct pcmcia_device *p_dev)
if (devno == CM4000_MAX_DEV)
return;
link->state &= ~DEV_PRESENT;
stop_monitor(dev);
if (link->state & DEV_CONFIG)
cm4000_release(link);
cm4000_release(link);
dev_table[devno] = NULL;
kfree(dev);
......@@ -1993,7 +1964,7 @@ static struct pcmcia_driver cm4000_driver = {
.drv = {
.name = "cm4000_cs",
},
.probe = cm4000_attach,
.probe = cm4000_probe,
.remove = cm4000_detach,
.suspend = cm4000_suspend,
.resume = cm4000_resume,
......
......@@ -41,7 +41,7 @@
#ifdef PCMCIA_DEBUG
#define reader_to_dev(x) (&handle_to_dev(x->link.handle))
#define reader_to_dev(x) (&handle_to_dev(x->p_dev->handle))
static int pc_debug = PCMCIA_DEBUG;
module_param(pc_debug, int, 0600);
#define DEBUGP(n, rdr, x, args...) do { \
......@@ -65,7 +65,7 @@ static char *version =
/* how often to poll for fifo status change */
#define POLL_PERIOD msecs_to_jiffies(10)
static void reader_release(dev_link_t *link);
static void reader_release(struct pcmcia_device *link);
static int major;
static struct class *cmx_class;
......@@ -74,7 +74,7 @@ static struct class *cmx_class;
#define BS_WRITABLE 0x02
struct reader_dev {
dev_link_t link;
struct pcmcia_device *p_dev;
dev_node_t node;
wait_queue_head_t devq;
wait_queue_head_t poll_wait;
......@@ -87,7 +87,7 @@ struct reader_dev {
struct timer_list poll_timer;
};
static dev_link_t *dev_table[CM_MAX_DEV];
static struct pcmcia_device *dev_table[CM_MAX_DEV];
#ifndef PCMCIA_DEBUG
#define xoutb outb
......@@ -116,7 +116,7 @@ static inline unsigned char xinb(unsigned short port)
static void cm4040_do_poll(unsigned long dummy)
{
struct reader_dev *dev = (struct reader_dev *) dummy;
unsigned int obs = xinb(dev->link.io.BasePort1
unsigned int obs = xinb(dev->p_dev->io.BasePort1
+ REG_OFFSET_BUFFER_STATUS);
if ((obs & BSR_BULK_IN_FULL)) {
......@@ -147,7 +147,7 @@ static void cm4040_stop_poll(struct reader_dev *dev)
static int wait_for_bulk_out_ready(struct reader_dev *dev)
{
int i, rc;
int iobase = dev->link.io.BasePort1;
int iobase = dev->p_dev->io.BasePort1;
for (i = 0; i < POLL_LOOP_COUNT; i++) {
if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS)
......@@ -177,7 +177,7 @@ static int wait_for_bulk_out_ready(struct reader_dev *dev)
/* Write to Sync Control Register */
static int write_sync_reg(unsigned char val, struct reader_dev *dev)
{
int iobase = dev->link.io.BasePort1;
int iobase = dev->p_dev->io.BasePort1;
int rc;
rc = wait_for_bulk_out_ready(dev);
......@@ -195,7 +195,7 @@ static int write_sync_reg(unsigned char val, struct reader_dev *dev)
static int wait_for_bulk_in_ready(struct reader_dev *dev)
{
int i, rc;
int iobase = dev->link.io.BasePort1;
int iobase = dev->p_dev->io.BasePort1;
for (i = 0; i < POLL_LOOP_COUNT; i++) {
if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS)
......@@ -225,7 +225,7 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf,
size_t count, loff_t *ppos)
{
struct reader_dev *dev = filp->private_data;
int iobase = dev->link.io.BasePort1;
int iobase = dev->p_dev->io.BasePort1;
size_t bytes_to_read;
unsigned long i;
size_t min_bytes_to_read;
......@@ -246,7 +246,7 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf,
return -EAGAIN;
}
if ((dev->link.state & DEV_PRESENT)==0)
if (!pcmcia_dev_present(dev->p_dev))
return -ENODEV;
for (i = 0; i < 5; i++) {
......@@ -328,7 +328,7 @@ static ssize_t cm4040_write(struct file *filp, const char __user *buf,
size_t count, loff_t *ppos)
{
struct reader_dev *dev = filp->private_data;
int iobase = dev->link.io.BasePort1;
int iobase = dev->p_dev->io.BasePort1;
ssize_t rc;
int i;
unsigned int bytes_to_write;
......@@ -351,7 +351,7 @@ static ssize_t cm4040_write(struct file *filp, const char __user *buf,
return -EAGAIN;
}
if ((dev->link.state & DEV_PRESENT) == 0)
if (!pcmcia_dev_present(dev->p_dev))
return -ENODEV;
bytes_to_write = count;
......@@ -445,14 +445,14 @@ static unsigned int cm4040_poll(struct file *filp, poll_table *wait)
static int cm4040_open(struct inode *inode, struct file *filp)
{
struct reader_dev *dev;
dev_link_t *link;
struct pcmcia_device *link;
int minor = iminor(inode);
if (minor >= CM_MAX_DEV)
return -ENODEV;
link = dev_table[minor];
if (link == NULL || !(DEV_OK(link)))
if (link == NULL || !pcmcia_dev_present(link))
return -ENODEV;
if (link->open)
......@@ -478,7 +478,7 @@ static int cm4040_open(struct inode *inode, struct file *filp)
static int cm4040_close(struct inode *inode, struct file *filp)
{
struct reader_dev *dev = filp->private_data;
dev_link_t *link;
struct pcmcia_device *link;
int minor = iminor(inode);
DEBUGP(2, dev, "-> cm4040_close(maj/min=%d.%d)\n", imajor(inode),
......@@ -500,7 +500,7 @@ static int cm4040_close(struct inode *inode, struct file *filp)
return 0;
}
static void cm4040_reader_release(dev_link_t *link)
static void cm4040_reader_release(struct pcmcia_device *link)
{
struct reader_dev *dev = link->priv;
......@@ -514,60 +514,49 @@ static void cm4040_reader_release(dev_link_t *link)
return;
}
static void reader_config(dev_link_t *link, int devno)
static int reader_config(struct pcmcia_device *link, int devno)
{
client_handle_t handle;
struct reader_dev *dev;
tuple_t tuple;
cisparse_t parse;
config_info_t conf;
u_char buf[64];
int fail_fn, fail_rc;
int rc;
handle = link->handle;
tuple.DesiredTuple = CISTPL_CONFIG;
tuple.Attributes = 0;
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
if ((fail_rc = pcmcia_get_first_tuple(handle, &tuple)) != CS_SUCCESS) {
if ((fail_rc = pcmcia_get_first_tuple(link, &tuple)) != CS_SUCCESS) {
fail_fn = GetFirstTuple;
goto cs_failed;
}
if ((fail_rc = pcmcia_get_tuple_data(handle, &tuple)) != CS_SUCCESS) {
if ((fail_rc = pcmcia_get_tuple_data(link, &tuple)) != CS_SUCCESS) {
fail_fn = GetTupleData;
goto cs_failed;
}
if ((fail_rc = pcmcia_parse_tuple(handle, &tuple, &parse))
if ((fail_rc = pcmcia_parse_tuple(link, &tuple, &parse))
!= CS_SUCCESS) {
fail_fn = ParseTuple;
goto cs_failed;
}
if ((fail_rc = pcmcia_get_configuration_info(handle, &conf))
!= CS_SUCCESS) {
fail_fn = GetConfigurationInfo;
goto cs_failed;
}
link->state |= DEV_CONFIG;
link->conf.ConfigBase = parse.config.base;
link->conf.Present = parse.config.rmask[0];
link->conf.Vcc = conf.Vcc;
link->io.BasePort2 = 0;
link->io.NumPorts2 = 0;
link->io.Attributes2 = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
for (rc = pcmcia_get_first_tuple(handle, &tuple);
for (rc = pcmcia_get_first_tuple(link, &tuple);
rc == CS_SUCCESS;
rc = pcmcia_get_next_tuple(handle, &tuple)) {
rc = pcmcia_get_tuple_data(handle, &tuple);
rc = pcmcia_get_next_tuple(link, &tuple)) {
rc = pcmcia_get_tuple_data(link, &tuple);
if (rc != CS_SUCCESS)
continue;
rc = pcmcia_parse_tuple(handle, &tuple, &parse);
rc = pcmcia_parse_tuple(link, &tuple, &parse);
if (rc != CS_SUCCESS)
continue;
......@@ -585,13 +574,13 @@ static void reader_config(dev_link_t *link, int devno)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.IOAddrLines = parse.cftable_entry.io.flags
& CISTPL_IO_LINES_MASK;
rc = pcmcia_request_io(handle, &link->io);
rc = pcmcia_request_io(link, &link->io);
dev_printk(KERN_INFO, &handle_to_dev(handle), "foo");
dev_printk(KERN_INFO, &handle_to_dev(link), "foo");
if (rc == CS_SUCCESS)
break;
else
dev_printk(KERN_INFO, &handle_to_dev(handle),
dev_printk(KERN_INFO, &handle_to_dev(link),
"pcmcia_request_io failed 0x%x\n", rc);
}
if (rc != CS_SUCCESS)
......@@ -599,10 +588,10 @@ static void reader_config(dev_link_t *link, int devno)
link->conf.IntType = 00000002;
if ((fail_rc = pcmcia_request_configuration(handle,&link->conf))
if ((fail_rc = pcmcia_request_configuration(link,&link->conf))
!=CS_SUCCESS) {
fail_fn = RequestConfiguration;
dev_printk(KERN_INFO, &handle_to_dev(handle),
dev_printk(KERN_INFO, &handle_to_dev(link),
"pcmcia_request_configuration failed 0x%x\n",
fail_rc);
goto cs_release;
......@@ -612,57 +601,31 @@ static void reader_config(dev_link_t *link, int devno)
sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno);
dev->node.major = major;
dev->node.minor = devno;
dev->node.next = NULL;
link->dev = &dev->node;
link->state &= ~DEV_CONFIG_PENDING;
dev->node.next = &dev->node;
DEBUGP(2, dev, "device " DEVICE_NAME "%d at 0x%.4x-0x%.4x\n", devno,
link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1);
DEBUGP(2, dev, "<- reader_config (succ)\n");
return;
return 0;
cs_failed:
cs_error(handle, fail_fn, fail_rc);
cs_error(link, fail_fn, fail_rc);
cs_release:
reader_release(link);
link->state &= ~DEV_CONFIG_PENDING;
}
static int reader_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
return -ENODEV;
}
static int reader_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
return 0;
}
static void reader_release(dev_link_t *link)
static void reader_release(struct pcmcia_device *link)
{
cm4040_reader_release(link->priv);
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_disable_device(link);
}
static int reader_attach(struct pcmcia_device *p_dev)
static int reader_probe(struct pcmcia_device *link)
{
struct reader_dev *dev;
dev_link_t *link;
int i;
int i, ret;
for (i = 0; i < CM_MAX_DEV; i++) {
if (dev_table[i] == NULL)
......@@ -679,8 +642,8 @@ static int reader_attach(struct pcmcia_device *p_dev)
dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT;
dev->buffer_status = 0;
link = &dev->link;
link->priv = dev;
dev->p_dev = link;
link->conf.IntType = INT_MEMORY_AND_IO;
dev_table[i] = link;
......@@ -692,11 +655,9 @@ static int reader_attach(struct pcmcia_device *p_dev)
init_timer(&dev->poll_timer);
dev->poll_timer.function = &cm4040_do_poll;
link->handle = p_dev;
p_dev->instance = link;
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
reader_config(link, i);
ret = reader_config(link, i);
if (ret)
return ret;
class_device_create(cmx_class, NULL, MKDEV(major, i), NULL,
"cmx%d", i);
......@@ -704,9 +665,8 @@ static int reader_attach(struct pcmcia_device *p_dev)
return 0;
}
static void reader_detach(struct pcmcia_device *p_dev)
static void reader_detach(struct pcmcia_device *link)
{
dev_link_t *link = dev_to_instance(p_dev);
struct reader_dev *dev = link->priv;
int devno;
......@@ -718,10 +678,7 @@ static void reader_detach(struct pcmcia_device *p_dev)
if (devno == CM_MAX_DEV)
return;
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG)
reader_release(link);
reader_release(link);
dev_table[devno] = NULL;
kfree(dev);
......@@ -753,10 +710,8 @@ static struct pcmcia_driver reader_driver = {
.drv = {
.name = "cm4040_cs",
},
.probe = reader_attach,
.probe = reader_probe,
.remove = reader_detach,
.suspend = reader_suspend,
.resume = reader_resume,
.id_table = cm4040_ids,
};
......
......@@ -228,7 +228,7 @@ typedef struct _mgslpc_info {
struct _input_signal_events input_signal_events;
/* PCMCIA support */
dev_link_t link;
struct pcmcia_device *p_dev;
dev_node_t node;
int stop;
......@@ -484,7 +484,7 @@ static void mgslpc_wait_until_sent(struct tty_struct *tty, int timeout);
/* PCMCIA prototypes */
static 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_detach(struct pcmcia_device *p_dev);
......@@ -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;
dev_link_t *link;
int ret;
if (debug_level >= DEBUG_LEVEL_INFO)
printk("mgslpc_attach\n");
info = (MGSLPC_INFO *)kmalloc(sizeof(MGSLPC_INFO), GFP_KERNEL);
if (!info) {
printk("Error can't allocate device instance data\n");
......@@ -565,25 +565,22 @@ static int mgslpc_attach(struct pcmcia_device *p_dev)
info->imrb_value = 0xffff;
info->pim_value = 0xff;
link = &info->link;
info->p_dev = link;
link->priv = info;
/* Initialize the dev_link_t structure */
/* Initialize the struct pcmcia_device structure */
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->irq.Handler = NULL;
link->conf.Attributes = 0;
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
link->handle = p_dev;
p_dev->instance = link;
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
mgslpc_config(link);
ret = mgslpc_config(link);
if (ret)
return ret;
mgslpc_add_device(info);
......@@ -596,15 +593,13 @@ static int mgslpc_attach(struct pcmcia_device *p_dev)
#define CS_CHECK(fn, ret) \
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;
tuple_t tuple;
cisparse_t parse;
int last_fn, last_ret;
u_char buf[64];
config_info_t conf;
cistpl_cftable_entry_t dflt = { 0 };
cistpl_cftable_entry_t *cfg;
......@@ -617,27 +612,20 @@ static void mgslpc_config(dev_link_t *link)
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
link->conf.ConfigBase = parse.config.base;
link->conf.Present = parse.config.rmask[0];
/* Configure card */
link->state |= DEV_CONFIG;
/* Look up the current Vcc */
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
link->conf.Vcc = conf.Vcc;
/* get CIS configuration entry */
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
cfg = &(parse.cftable_entry);
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
if (cfg->index == 0)
......@@ -658,11 +646,10 @@ static void mgslpc_config(dev_link_t *link)
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
link->io.BasePort1 = io->win[0].base;
link->io.NumPorts1 = io->win[0].len;
CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io));
CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
}
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 8;
link->conf.Present = PRESENT_OPTION;
......@@ -670,9 +657,9 @@ static void mgslpc_config(dev_link_t *link)
link->irq.Attributes |= IRQ_HANDLE_PRESENT;
link->irq.Handler = mgslpc_isr;
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->irq_level = link->irq.AssignedIRQ;
......@@ -680,7 +667,7 @@ static void mgslpc_config(dev_link_t *link)
/* add to linked list of devices */
sprintf(info->node.dev_name, "mgslpc0");
info->node.major = info->node.minor = 0;
link->dev = &info->node;
link->dev_node = &info->node;
printk(KERN_INFO "%s: index 0x%02x:",
info->node.dev_name, link->conf.ConfigIndex);
......@@ -690,13 +677,12 @@ static void mgslpc_config(dev_link_t *link)
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
link->io.BasePort1+link->io.NumPorts1-1);
printk("\n");
link->state &= ~DEV_CONFIG_PENDING;
return;
return 0;
cs_failed:
cs_error(link->handle, last_fn, last_ret);
cs_error(link, last_fn, last_ret);
mgslpc_release((u_long)link);
return -ENODEV;
}
/* Card has been removed.
......@@ -705,58 +691,38 @@ static void mgslpc_config(dev_link_t *link)
*/
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)
printk("mgslpc_release(0x%p)\n", link);
/* Unlink the device chain */
link->dev = NULL;
link->state &= ~DEV_CONFIG;
if (debug_level >= DEBUG_LEVEL_INFO)
printk("mgslpc_release(0x%p)\n", link);
pcmcia_release_configuration(link->handle);
if (link->io.NumPorts1)
pcmcia_release_io(link->handle, &link->io);
if (link->irq.AssignedIRQ)
pcmcia_release_irq(link->handle, &link->irq);
pcmcia_disable_device(link);
}
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_release((u_long)link);
}
((MGSLPC_INFO *)link->priv)->stop = 1;
mgslpc_release((u_long)link);
mgslpc_remove_device((MGSLPC_INFO *)link->priv);
mgslpc_remove_device((MGSLPC_INFO *)link->priv);
}
static int mgslpc_suspend(struct pcmcia_device *dev)
static int mgslpc_suspend(struct pcmcia_device *link)
{
dev_link_t *link = dev_to_instance(dev);
MGSLPC_INFO *info = link->priv;
link->state |= DEV_SUSPEND;
info->stop = 1;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int mgslpc_resume(struct pcmcia_device *dev)
static int mgslpc_resume(struct pcmcia_device *link)
{
dev_link_t *link = dev_to_instance(dev);
MGSLPC_INFO *info = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
info->stop = 0;
return 0;
......@@ -1280,7 +1246,7 @@ static irqreturn_t mgslpc_isr(int irq, void *dev_id, struct pt_regs * regs)
if (!info)
return IRQ_NONE;
if (!(info->link.state & DEV_CONFIG))
if (!(info->p_dev->_locked))
return IRQ_HANDLED;
spin_lock(&info->lock);
......@@ -3033,7 +2999,7 @@ static struct pcmcia_driver mgslpc_driver = {
.drv = {
.name = "synclink_cs",
},
.probe = mgslpc_attach,
.probe = mgslpc_probe,
.remove = mgslpc_detach,
.id_table = mgslpc_ids,
.suspend = mgslpc_suspend,
......
......@@ -81,14 +81,14 @@ static const char ide_major[] = {
};
typedef struct ide_info_t {
dev_link_t link;
struct pcmcia_device *p_dev;
int ndev;
dev_node_t node;
int hd;
} ide_info_t;
static void ide_release(dev_link_t *);
static void ide_config(dev_link_t *);
static void ide_release(struct pcmcia_device *);
static int ide_config(struct pcmcia_device *);
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;
dev_link_t *link;
DEBUG(0, "ide_attach()\n");
......@@ -114,7 +113,9 @@ static int ide_attach(struct pcmcia_device *p_dev)
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
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.Attributes2 = IO_DATA_PATH_WIDTH_8;
......@@ -122,16 +123,9 @@ static int ide_attach(struct pcmcia_device *p_dev)
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
link->handle = p_dev;
p_dev->instance = link;
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
ide_config(link);
return 0;
return ide_config(link);
} /* ide_attach */
/*======================================================================
......@@ -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);
if (link->state & DEV_CONFIG)
ide_release(link);
ide_release(link);
kfree(link->priv);
} /* ide_detach */
......@@ -177,9 +168,8 @@ static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq
#define CS_CHECK(fn, ret) \
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;
tuple_t tuple;
struct {
......@@ -203,34 +193,30 @@ static void ide_config(dev_link_t *link)
tuple.TupleDataMax = 255;
tuple.Attributes = 0;
tuple.DesiredTuple = CISTPL_CONFIG;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &stk->parse));
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &stk->parse));
link->conf.ConfigBase = stk->parse.config.base;
link->conf.Present = stk->parse.config.rmask[0];
tuple.DesiredTuple = CISTPL_MANFID;
if (!pcmcia_get_first_tuple(handle, &tuple) &&
!pcmcia_get_tuple_data(handle, &tuple) &&
!pcmcia_parse_tuple(handle, &tuple, &stk->parse))
if (!pcmcia_get_first_tuple(link, &tuple) &&
!pcmcia_get_tuple_data(link, &tuple) &&
!pcmcia_parse_tuple(link, &tuple, &stk->parse))
is_kme = ((stk->parse.manfid.manf == MANFID_KME) &&
((stk->parse.manfid.card == PRODID_KME_KXLC005_A) ||
(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 */
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &stk->conf));
link->conf.Vcc = stk->conf.Vcc;
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf));
pass = io_base = ctl_base = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
tuple.Attributes = 0;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) {
if (pcmcia_get_tuple_data(handle, &tuple) != 0) goto next_entry;
if (pcmcia_parse_tuple(handle, &tuple, &stk->parse) != 0) goto next_entry;
if (pcmcia_get_tuple_data(link, &tuple) != 0) goto next_entry;
if (pcmcia_parse_tuple(link, &tuple, &stk->parse) != 0) goto next_entry;
/* Check for matching Vcc, unless we're desperate */
if (!pass) {
......@@ -244,10 +230,10 @@ static void ide_config(dev_link_t *link)
}
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
link->conf.Vpp1 = link->conf.Vpp2 =
link->conf.Vpp =
cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
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;
if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) {
......@@ -261,14 +247,14 @@ static void ide_config(dev_link_t *link)
link->io.NumPorts1 = 8;
link->io.BasePort2 = io->win[1].base;
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;
io_base = link->io.BasePort1;
ctl_base = link->io.BasePort2;
} else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
link->io.NumPorts1 = io->win[0].len;
link->io.NumPorts2 = 0;
if (pcmcia_request_io(link->handle, &link->io) != 0)
if (pcmcia_request_io(link, &link->io) != 0)
goto next_entry;
io_base = link->io.BasePort1;
ctl_base = link->io.BasePort1 + 0x0e;
......@@ -281,16 +267,16 @@ static void ide_config(dev_link_t *link)
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
memcpy(&stk->dflt, cfg, sizeof(stk->dflt));
if (pass) {
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
} else if (pcmcia_get_next_tuple(handle, &tuple) != 0) {
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
} else if (pcmcia_get_next_tuple(link, &tuple) != 0) {
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
memset(&stk->dflt, 0, sizeof(stk->dflt));
pass++;
}
}
CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq));
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
/* disable drive interrupts during IDE probe */
outb(0x02, ctl_base);
......@@ -301,12 +287,12 @@ static void ide_config(dev_link_t *link)
/* retry registration in case device is still spinning up */
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 (link->io.NumPorts1 == 0x20) {
outb(0x02, ctl_base + 0x10);
hd = idecs_register(io_base + 0x10, ctl_base + 0x10,
link->irq.AssignedIRQ, handle);
link->irq.AssignedIRQ, link);
if (hd >= 0) {
io_base += 0x10;
ctl_base += 0x10;
......@@ -328,25 +314,23 @@ static void ide_config(dev_link_t *link)
info->node.major = ide_major[hd];
info->node.minor = 0;
info->hd = hd;
link->dev = &info->node;
printk(KERN_INFO "ide-cs: %s: Vcc = %d.%d, Vpp = %d.%d\n",
info->node.dev_name, link->conf.Vcc / 10, link->conf.Vcc % 10,
link->conf.Vpp1 / 10, link->conf.Vpp1 % 10);
link->dev_node = &info->node;
printk(KERN_INFO "ide-cs: %s: Vpp = %d.%d\n",
info->node.dev_name, link->conf.Vpp / 10, link->conf.Vpp % 10);
link->state &= ~DEV_CONFIG_PENDING;
kfree(stk);
return;
return 0;
err_mem:
printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n");
goto failed;
cs_failed:
cs_error(link->handle, last_fn, last_ret);
cs_error(link, last_fn, last_ret);
failed:
kfree(stk);
ide_release(link);
link->state &= ~DEV_CONFIG_PENDING;
return -ENODEV;
} /* ide_config */
/*======================================================================
......@@ -357,7 +341,7 @@ static void ide_config(dev_link_t *link)
======================================================================*/
void ide_release(dev_link_t *link)
void ide_release(struct pcmcia_device *link)
{
ide_info_t *info = link->priv;
......@@ -369,37 +353,10 @@ void ide_release(dev_link_t *link)
ide_unregister(info->hd);
}
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 */
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 = {
.drv = {
.name = "ide-cs",
},
.probe = ide_attach,
.probe = ide_probe,
.remove = ide_detach,
.id_table = ide_ids,
.suspend = ide_suspend,
.resume = ide_resume,
};
static int __init init_ide_cs(void)
......
......@@ -51,8 +51,8 @@ MODULE_LICENSE("GPL");
handler.
*/
static void avmcs_config(dev_link_t *link);
static void avmcs_release(dev_link_t *link);
static int avmcs_config(struct pcmcia_device *link);
static void avmcs_release(struct pcmcia_device *link);
/*
The attach() and detach() entry points are used to create and destroy
......@@ -65,10 +65,10 @@ static void avmcs_detach(struct pcmcia_device *p_dev);
/*
A linked list of "instances" of the skeleton device. Each actual
PCMCIA card corresponds to one device instance, and is described
by one dev_link_t structure (defined in ds.h).
by one struct pcmcia_device structure (defined in ds.h).
You may not want to use a linked list for this -- for example, the
memory card driver uses an array of dev_link_t pointers, where minor
memory card driver uses an array of struct pcmcia_device pointers, where minor
device numbers are used to derive the corresponding array index.
*/
......@@ -78,7 +78,7 @@ static void avmcs_detach(struct pcmcia_device *p_dev);
example, ethernet cards, modems). In other cases, there may be
many actual or logical devices (SCSI adapters, memory cards with
multiple partitions). The dev_node_t structures need to be kept
in a linked list starting at the 'dev' field of a dev_link_t
in a linked list starting at the 'dev' field of a struct pcmcia_device
structure. We allocate them in the card's private data structure,
because they generally can't be allocated dynamically.
*/
......@@ -99,54 +99,38 @@ typedef struct local_info_t {
======================================================================*/
static int avmcs_attach(struct pcmcia_device *p_dev)
static int avmcs_probe(struct pcmcia_device *p_dev)
{
dev_link_t *link;
local_info_t *local;
/* Initialize the dev_link_t structure */
link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
if (!link)
goto err;
memset(link, 0, sizeof(struct dev_link_t));
/* The io structure describes IO port mapping */
link->io.NumPorts1 = 16;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts2 = 0;
p_dev->io.NumPorts1 = 16;
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
p_dev->io.NumPorts2 = 0;
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
/* General socket configuration */
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1;
link->conf.Present = PRESENT_OPTION;
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
p_dev->conf.IntType = INT_MEMORY_AND_IO;
p_dev->conf.ConfigIndex = 1;
p_dev->conf.Present = PRESENT_OPTION;
/* Allocate space for private device-specific data */
local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
if (!local)
goto err_kfree;
goto err;
memset(local, 0, sizeof(local_info_t));
link->priv = local;
p_dev->priv = local;
link->handle = p_dev;
p_dev->instance = link;
return avmcs_config(p_dev);
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
avmcs_config(link);
return 0;
err_kfree:
kfree(link);
err:
return -EINVAL;
return -ENOMEM;
} /* avmcs_attach */
/*======================================================================
......@@ -158,15 +142,10 @@ static int avmcs_attach(struct pcmcia_device *p_dev)
======================================================================*/
static void avmcs_detach(struct pcmcia_device *p_dev)
static void avmcs_detach(struct pcmcia_device *link)
{
dev_link_t *link = dev_to_instance(p_dev);
if (link->state & DEV_CONFIG)
avmcs_release(link);
kfree(link->priv);
kfree(link);
kfree(link->priv);
} /* avmcs_detach */
/*======================================================================
......@@ -177,7 +156,7 @@ static void avmcs_detach(struct pcmcia_device *p_dev)
======================================================================*/
static int get_tuple(client_handle_t handle, tuple_t *tuple,
static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
{
int i = pcmcia_get_tuple_data(handle, tuple);
......@@ -185,7 +164,7 @@ static int get_tuple(client_handle_t handle, tuple_t *tuple,
return pcmcia_parse_tuple(handle, tuple, parse);
}
static int first_tuple(client_handle_t handle, tuple_t *tuple,
static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
{
int i = pcmcia_get_first_tuple(handle, tuple);
......@@ -193,7 +172,7 @@ static int first_tuple(client_handle_t handle, tuple_t *tuple,
return get_tuple(handle, tuple, parse);
}
static int next_tuple(client_handle_t handle, tuple_t *tuple,
static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
{
int i = pcmcia_get_next_tuple(handle, tuple);
......@@ -201,9 +180,8 @@ static int next_tuple(client_handle_t handle, tuple_t *tuple,
return get_tuple(handle, tuple, parse);
}
static void avmcs_config(dev_link_t *link)
static int avmcs_config(struct pcmcia_device *link)
{
client_handle_t handle;
tuple_t tuple;
cisparse_t parse;
cistpl_cftable_entry_t *cf = &parse.cftable_entry;
......@@ -213,8 +191,7 @@ static void avmcs_config(dev_link_t *link)
char devname[128];
int cardtype;
int (*addcard)(unsigned int port, unsigned irq);
handle = link->handle;
dev = link->priv;
/*
......@@ -223,25 +200,21 @@ static void avmcs_config(dev_link_t *link)
*/
do {
tuple.DesiredTuple = CISTPL_CONFIG;
i = pcmcia_get_first_tuple(handle, &tuple);
i = pcmcia_get_first_tuple(link, &tuple);
if (i != CS_SUCCESS) break;
tuple.TupleData = buf;
tuple.TupleDataMax = 64;
tuple.TupleOffset = 0;
i = pcmcia_get_tuple_data(handle, &tuple);
i = pcmcia_get_tuple_data(link, &tuple);
if (i != CS_SUCCESS) break;
i = pcmcia_parse_tuple(handle, &tuple, &parse);
i = pcmcia_parse_tuple(link, &tuple, &parse);
if (i != CS_SUCCESS) break;
link->conf.ConfigBase = parse.config.base;
} while (0);
if (i != CS_SUCCESS) {
cs_error(link->handle, ParseTuple, i);
link->state &= ~DEV_CONFIG_PENDING;
return;
cs_error(link, ParseTuple, i);
return -ENODEV;
}
/* Configure card */
link->state |= DEV_CONFIG;
do {
......@@ -252,7 +225,7 @@ static void avmcs_config(dev_link_t *link)
tuple.DesiredTuple = CISTPL_VERS_1;
devname[0] = 0;
if( !first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 1 ) {
if( !first_tuple(link, &tuple, &parse) && parse.version_1.ns > 1 ) {
strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1],
sizeof(devname));
}
......@@ -263,7 +236,7 @@ static void avmcs_config(dev_link_t *link)
tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
tuple.Attributes = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
i = first_tuple(handle, &tuple, &parse);
i = first_tuple(link, &tuple, &parse);
while (i == CS_SUCCESS) {
if (cf->io.nwin > 0) {
link->conf.ConfigIndex = cf->index;
......@@ -273,36 +246,36 @@ static void avmcs_config(dev_link_t *link)
printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n",
link->io.BasePort1,
link->io.BasePort1+link->io.NumPorts1-1);
i = pcmcia_request_io(link->handle, &link->io);
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS) goto found_port;
}
i = next_tuple(handle, &tuple, &parse);
i = next_tuple(link, &tuple, &parse);
}
found_port:
if (i != CS_SUCCESS) {
cs_error(link->handle, RequestIO, i);
cs_error(link, RequestIO, i);
break;
}
/*
* allocate an interrupt line
*/
i = pcmcia_request_irq(link->handle, &link->irq);
i = pcmcia_request_irq(link, &link->irq);
if (i != CS_SUCCESS) {
cs_error(link->handle, RequestIRQ, i);
pcmcia_release_io(link->handle, &link->io);
cs_error(link, RequestIRQ, i);
/* undo */
pcmcia_disable_device(link);
break;
}
/*
* configure the PCMCIA socket
*/
i = pcmcia_request_configuration(link->handle, &link->conf);
i = pcmcia_request_configuration(link, &link->conf);
if (i != CS_SUCCESS) {
cs_error(link->handle, RequestConfiguration, i);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
cs_error(link, RequestConfiguration, i);
pcmcia_disable_device(link);
break;
}
......@@ -331,13 +304,12 @@ static void avmcs_config(dev_link_t *link)
dev->node.major = 64;
dev->node.minor = 0;
link->dev = &dev->node;
link->state &= ~DEV_CONFIG_PENDING;
link->dev_node = &dev->node;
/* If any step failed, release any partially configured state */
if (i != 0) {
avmcs_release(link);
return;
return -ENODEV;
}
......@@ -351,9 +323,10 @@ static void avmcs_config(dev_link_t *link)
printk(KERN_ERR "avm_cs: failed to add AVM-%s-Controller at i/o %#x, irq %d\n",
dev->node.dev_name, link->io.BasePort1, link->irq.AssignedIRQ);
avmcs_release(link);
return;
return -ENODEV;
}
dev->node.minor = i;
return 0;
} /* avmcs_config */
......@@ -365,56 +338,12 @@ static void avmcs_config(dev_link_t *link)
======================================================================*/
static void avmcs_release(dev_link_t *link)
static void avmcs_release(struct pcmcia_device *link)
{
b1pcmcia_delcard(link->io.BasePort1, link->irq.AssignedIRQ);
/* Unlink the device chain */
link->dev = NULL;
/* Don't bother checking to see if these succeed or not */
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
b1pcmcia_delcard(link->io.BasePort1, link->irq.AssignedIRQ);
pcmcia_disable_device(link);
} /* avmcs_release */
static int avmcs_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 avmcs_resume(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
return 0;
}
/*======================================================================
The card status event handler. Mostly, this schedules other
stuff to run after an event is received. A CARD_REMOVAL event
also sets some flags to discourage the net drivers from trying
to talk to the card any more.
When a CARD_REMOVAL event is received, we immediately set a flag
to block future accesses to this device. All the functions that
actually access the device should check this flag to make sure
the card is still present.
======================================================================*/
static struct pcmcia_device_id avmcs_ids[] = {
PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN-Controller B1", 0x95d42008, 0x845dc335),
......@@ -429,11 +358,9 @@ static struct pcmcia_driver avmcs_driver = {
.drv = {
.name = "avm_cs",
},
.probe = avmcs_attach,
.probe = avmcs_probe,
.remove = avmcs_detach,
.id_table = avmcs_ids,
.suspend= avmcs_suspend,
.resume = avmcs_resume,
};
static int __init avmcs_init(void)
......
......@@ -67,8 +67,8 @@ module_param(isdnprot, int, 0);
handler.
*/
static void avma1cs_config(dev_link_t *link);
static void avma1cs_release(dev_link_t *link);
static int avma1cs_config(struct pcmcia_device *link);
static void avma1cs_release(struct pcmcia_device *link);
/*
The attach() and detach() entry points are used to create and destroy
......@@ -82,10 +82,10 @@ static void avma1cs_detach(struct pcmcia_device *p_dev);
/*
A linked list of "instances" of the skeleton device. Each actual
PCMCIA card corresponds to one device instance, and is described
by one dev_link_t structure (defined in ds.h).
by one struct pcmcia_device structure (defined in ds.h).
You may not want to use a linked list for this -- for example, the
memory card driver uses an array of dev_link_t pointers, where minor
memory card driver uses an array of struct pcmcia_device pointers, where minor
device numbers are used to derive the corresponding array index.
*/
......@@ -95,7 +95,7 @@ static void avma1cs_detach(struct pcmcia_device *p_dev);
example, ethernet cards, modems). In other cases, there may be
many actual or logical devices (SCSI adapters, memory cards with
multiple partitions). The dev_node_t structures need to be kept
in a linked list starting at the 'dev' field of a dev_link_t
in a linked list starting at the 'dev' field of a struct pcmcia_device
structure. We allocate them in the card's private data structure,
because they generally can't be allocated dynamically.
*/
......@@ -116,55 +116,40 @@ typedef struct local_info_t {
======================================================================*/
static int avma1cs_attach(struct pcmcia_device *p_dev)
static int avma1cs_probe(struct pcmcia_device *p_dev)
{
dev_link_t *link;
local_info_t *local;
DEBUG(0, "avma1cs_attach()\n");
/* Initialize the dev_link_t structure */
link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
if (!link)
return -ENOMEM;
memset(link, 0, sizeof(struct dev_link_t));
/* Allocate space for private device-specific data */
local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
if (!local) {
kfree(link);
if (!local)
return -ENOMEM;
}
memset(local, 0, sizeof(local_info_t));
link->priv = local;
p_dev->priv = local;
/* The io structure describes IO port mapping */
link->io.NumPorts1 = 16;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts2 = 16;
link->io.Attributes2 = IO_DATA_PATH_WIDTH_16;
link->io.IOAddrLines = 5;
p_dev->io.NumPorts1 = 16;
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
p_dev->io.NumPorts2 = 16;
p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_16;
p_dev->io.IOAddrLines = 5;
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
/* General socket configuration */
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1;
link->conf.Present = PRESENT_OPTION;
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
p_dev->conf.IntType = INT_MEMORY_AND_IO;
p_dev->conf.ConfigIndex = 1;
p_dev->conf.Present = PRESENT_OPTION;
link->handle = p_dev;
p_dev->instance = link;
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
avma1cs_config(link);
return 0;
return avma1cs_config(p_dev);
} /* avma1cs_attach */
/*======================================================================
......@@ -176,17 +161,11 @@ static int avma1cs_attach(struct pcmcia_device *p_dev)
======================================================================*/
static void avma1cs_detach(struct pcmcia_device *p_dev)
static void avma1cs_detach(struct pcmcia_device *link)
{
dev_link_t *link = dev_to_instance(p_dev);
DEBUG(0, "avma1cs_detach(0x%p)\n", link);
if (link->state & DEV_CONFIG)
avma1cs_release(link);
kfree(link->priv);
kfree(link);
DEBUG(0, "avma1cs_detach(0x%p)\n", link);
avma1cs_release(link);
kfree(link->priv);
} /* avma1cs_detach */
/*======================================================================
......@@ -197,7 +176,7 @@ static void avma1cs_detach(struct pcmcia_device *p_dev)
======================================================================*/
static int get_tuple(client_handle_t handle, tuple_t *tuple,
static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
{
int i = pcmcia_get_tuple_data(handle, tuple);
......@@ -205,7 +184,7 @@ static int get_tuple(client_handle_t handle, tuple_t *tuple,
return pcmcia_parse_tuple(handle, tuple, parse);
}
static int first_tuple(client_handle_t handle, tuple_t *tuple,
static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
{
int i = pcmcia_get_first_tuple(handle, tuple);
......@@ -213,7 +192,7 @@ static int first_tuple(client_handle_t handle, tuple_t *tuple,
return get_tuple(handle, tuple, parse);
}
static int next_tuple(client_handle_t handle, tuple_t *tuple,
static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
{
int i = pcmcia_get_next_tuple(handle, tuple);
......@@ -221,9 +200,8 @@ static int next_tuple(client_handle_t handle, tuple_t *tuple,
return get_tuple(handle, tuple, parse);
}
static void avma1cs_config(dev_link_t *link)
static int avma1cs_config(struct pcmcia_device *link)
{
client_handle_t handle;
tuple_t tuple;
cisparse_t parse;
cistpl_cftable_entry_t *cf = &parse.cftable_entry;
......@@ -233,8 +211,7 @@ static void avma1cs_config(dev_link_t *link)
char devname[128];
IsdnCard_t icard;
int busy = 0;
handle = link->handle;
dev = link->priv;
DEBUG(0, "avma1cs_config(0x%p)\n", link);
......@@ -245,25 +222,21 @@ static void avma1cs_config(dev_link_t *link)
*/
do {
tuple.DesiredTuple = CISTPL_CONFIG;
i = pcmcia_get_first_tuple(handle, &tuple);
i = pcmcia_get_first_tuple(link, &tuple);
if (i != CS_SUCCESS) break;
tuple.TupleData = buf;
tuple.TupleDataMax = 64;
tuple.TupleOffset = 0;
i = pcmcia_get_tuple_data(handle, &tuple);
i = pcmcia_get_tuple_data(link, &tuple);
if (i != CS_SUCCESS) break;
i = pcmcia_parse_tuple(handle, &tuple, &parse);
i = pcmcia_parse_tuple(link, &tuple, &parse);
if (i != CS_SUCCESS) break;
link->conf.ConfigBase = parse.config.base;
} while (0);
if (i != CS_SUCCESS) {
cs_error(link->handle, ParseTuple, i);
link->state &= ~DEV_CONFIG_PENDING;
return;
cs_error(link, ParseTuple, i);
return -ENODEV;
}
/* Configure card */
link->state |= DEV_CONFIG;
do {
......@@ -274,7 +247,7 @@ static void avma1cs_config(dev_link_t *link)
tuple.DesiredTuple = CISTPL_VERS_1;
devname[0] = 0;
if( !first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 1 ) {
if( !first_tuple(link, &tuple, &parse) && parse.version_1.ns > 1 ) {
strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1],
sizeof(devname));
}
......@@ -285,7 +258,7 @@ static void avma1cs_config(dev_link_t *link)
tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
tuple.Attributes = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
i = first_tuple(handle, &tuple, &parse);
i = first_tuple(link, &tuple, &parse);
while (i == CS_SUCCESS) {
if (cf->io.nwin > 0) {
link->conf.ConfigIndex = cf->index;
......@@ -295,36 +268,36 @@ static void avma1cs_config(dev_link_t *link)
printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n",
link->io.BasePort1,
link->io.BasePort1+link->io.NumPorts1 - 1);
i = pcmcia_request_io(link->handle, &link->io);
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS) goto found_port;
}
i = next_tuple(handle, &tuple, &parse);
i = next_tuple(link, &tuple, &parse);
}
found_port:
if (i != CS_SUCCESS) {
cs_error(link->handle, RequestIO, i);
cs_error(link, RequestIO, i);
break;
}
/*
* allocate an interrupt line
*/
i = pcmcia_request_irq(link->handle, &link->irq);
i = pcmcia_request_irq(link, &link->irq);
if (i != CS_SUCCESS) {
cs_error(link->handle, RequestIRQ, i);
pcmcia_release_io(link->handle, &link->io);
cs_error(link, RequestIRQ, i);
/* undo */
pcmcia_disable_device(link);
break;
}
/*
* configure the PCMCIA socket
*/
i = pcmcia_request_configuration(link->handle, &link->conf);
i = pcmcia_request_configuration(link, &link->conf);
if (i != CS_SUCCESS) {
cs_error(link->handle, RequestConfiguration, i);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
cs_error(link, RequestConfiguration, i);
pcmcia_disable_device(link);
break;
}
......@@ -336,13 +309,12 @@ static void avma1cs_config(dev_link_t *link)
strcpy(dev->node.dev_name, "A1");
dev->node.major = 45;
dev->node.minor = 0;
link->dev = &dev->node;
link->state &= ~DEV_CONFIG_PENDING;
link->dev_node = &dev->node;
/* If any step failed, release any partially configured state */
if (i != 0) {
avma1cs_release(link);
return;
return -ENODEV;
}
printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n",
......@@ -357,10 +329,11 @@ static void avma1cs_config(dev_link_t *link)
if (i < 0) {
printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 PCMCIA %d at i/o %#x\n", i, link->io.BasePort1);
avma1cs_release(link);
return;
return -ENODEV;
}
dev->node.minor = i;
return 0;
} /* avma1cs_config */
/*======================================================================
......@@ -371,47 +344,18 @@ static void avma1cs_config(dev_link_t *link)
======================================================================*/
static void avma1cs_release(dev_link_t *link)
static void avma1cs_release(struct pcmcia_device *link)
{
local_info_t *local = link->priv;
local_info_t *local = link->priv;
DEBUG(0, "avma1cs_release(0x%p)\n", link);
DEBUG(0, "avma1cs_release(0x%p)\n", link);
/* no unregister function with hisax */
HiSax_closecard(local->node.minor);
/* now unregister function with hisax */
HiSax_closecard(local->node.minor);
/* Unlink the device chain */
link->dev = NULL;
/* Don't bother checking to see if these succeed or not */
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);
} /* avma1cs_release */
static int avma1cs_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 avma1cs_resume(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
return 0;
}
static struct pcmcia_device_id avma1cs_ids[] = {
PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb),
......@@ -425,13 +369,11 @@ static struct pcmcia_driver avma1cs_driver = {
.drv = {
.name = "avma1_cs",
},
.probe = avma1cs_attach,
.probe = avma1cs_probe,
.remove = avma1cs_detach,
.id_table = avma1cs_ids,
.suspend = avma1cs_suspend,
.resume = avma1cs_resume,
};
/*====================================================================*/
static int __init init_avma1_cs(void)
......
......@@ -94,8 +94,8 @@ module_param(protocol, int, 0);
handler.
*/
static void elsa_cs_config(dev_link_t *link);
static void elsa_cs_release(dev_link_t *link);
static int elsa_cs_config(struct pcmcia_device *link);
static void elsa_cs_release(struct pcmcia_device *link);
/*
The attach() and detach() entry points are used to create and destroy
......@@ -111,7 +111,7 @@ static void elsa_cs_detach(struct pcmcia_device *p_dev);
example, ethernet cards, modems). In other cases, there may be
many actual or logical devices (SCSI adapters, memory cards with
multiple partitions). The dev_node_t structures need to be kept
in a linked list starting at the 'dev' field of a dev_link_t
in a linked list starting at the 'dev' field of a struct pcmcia_device
structure. We allocate them in the card's private data structure,
because they generally shouldn't be allocated dynamically.
In this case, we also provide a flag to indicate if a device is
......@@ -121,7 +121,7 @@ static void elsa_cs_detach(struct pcmcia_device *p_dev);
*/
typedef struct local_info_t {
dev_link_t link;
struct pcmcia_device *p_dev;
dev_node_t node;
int busy;
int cardnr;
......@@ -139,9 +139,8 @@ typedef struct local_info_t {
======================================================================*/
static int elsa_cs_attach(struct pcmcia_device *p_dev)
static int elsa_cs_probe(struct pcmcia_device *link)
{
dev_link_t *link;
local_info_t *local;
DEBUG(0, "elsa_cs_attach()\n");
......@@ -150,8 +149,11 @@ static int elsa_cs_attach(struct pcmcia_device *p_dev)
local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
if (!local) return -ENOMEM;
memset(local, 0, sizeof(local_info_t));
local->p_dev = link;
link->priv = local;
local->cardnr = -1;
link = &local->link; link->priv = local;
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
......@@ -170,16 +172,9 @@ static int elsa_cs_attach(struct pcmcia_device *p_dev)
link->io.IOAddrLines = 3;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
link->handle = p_dev;
p_dev->instance = link;
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
elsa_cs_config(link);
return 0;
return elsa_cs_config(link);
} /* elsa_cs_attach */
/*======================================================================
......@@ -191,20 +186,16 @@ static int elsa_cs_attach(struct pcmcia_device *p_dev)
======================================================================*/
static void elsa_cs_detach(struct pcmcia_device *p_dev)
static void elsa_cs_detach(struct pcmcia_device *link)
{
dev_link_t *link = dev_to_instance(p_dev);
local_info_t *info = link->priv;
local_info_t *info = link->priv;
DEBUG(0, "elsa_cs_detach(0x%p)\n", link);
DEBUG(0, "elsa_cs_detach(0x%p)\n", link);
if (link->state & DEV_CONFIG) {
info->busy = 1;
elsa_cs_release(link);
}
kfree(info);
info->busy = 1;
elsa_cs_release(link);
kfree(info);
} /* elsa_cs_detach */
/*======================================================================
......@@ -214,7 +205,7 @@ static void elsa_cs_detach(struct pcmcia_device *p_dev)
device available to the system.
======================================================================*/
static int get_tuple(client_handle_t handle, tuple_t *tuple,
static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
{
int i = pcmcia_get_tuple_data(handle, tuple);
......@@ -222,7 +213,7 @@ static int get_tuple(client_handle_t handle, tuple_t *tuple,
return pcmcia_parse_tuple(handle, tuple, parse);
}
static int first_tuple(client_handle_t handle, tuple_t *tuple,
static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
{
int i = pcmcia_get_first_tuple(handle, tuple);
......@@ -230,7 +221,7 @@ static int first_tuple(client_handle_t handle, tuple_t *tuple,
return get_tuple(handle, tuple, parse);
}
static int next_tuple(client_handle_t handle, tuple_t *tuple,
static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
{
int i = pcmcia_get_next_tuple(handle, tuple);
......@@ -238,9 +229,8 @@ static int next_tuple(client_handle_t handle, tuple_t *tuple,
return get_tuple(handle, tuple, parse);
}
static void elsa_cs_config(dev_link_t *link)
static int elsa_cs_config(struct pcmcia_device *link)
{
client_handle_t handle;
tuple_t tuple;
cisparse_t parse;
local_info_t *dev;
......@@ -250,7 +240,6 @@ static void elsa_cs_config(dev_link_t *link)
IsdnCard_t icard;
DEBUG(0, "elsa_config(0x%p)\n", link);
handle = link->handle;
dev = link->priv;
/*
......@@ -262,7 +251,7 @@ static void elsa_cs_config(dev_link_t *link)
tuple.TupleDataMax = 255;
tuple.TupleOffset = 0;
tuple.Attributes = 0;
i = first_tuple(handle, &tuple, &parse);
i = first_tuple(link, &tuple, &parse);
if (i != CS_SUCCESS) {
last_fn = ParseTuple;
goto cs_failed;
......@@ -270,32 +259,29 @@ static void elsa_cs_config(dev_link_t *link)
link->conf.ConfigBase = parse.config.base;
link->conf.Present = parse.config.rmask[0];
/* Configure card */
link->state |= DEV_CONFIG;
tuple.TupleData = (cisdata_t *)buf;
tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
tuple.Attributes = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
i = first_tuple(handle, &tuple, &parse);
i = first_tuple(link, &tuple, &parse);
while (i == CS_SUCCESS) {
if ( (cf->io.nwin > 0) && cf->io.win[0].base) {
printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n");
link->conf.ConfigIndex = cf->index;
link->io.BasePort1 = cf->io.win[0].base;
i = pcmcia_request_io(link->handle, &link->io);
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS) break;
} else {
printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n");
link->conf.ConfigIndex = cf->index;
for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) {
link->io.BasePort1 = j;
i = pcmcia_request_io(link->handle, &link->io);
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS) break;
}
break;
}
i = next_tuple(handle, &tuple, &parse);
i = next_tuple(link, &tuple, &parse);
}
if (i != CS_SUCCESS) {
......@@ -303,14 +289,14 @@ static void elsa_cs_config(dev_link_t *link)
goto cs_failed;
}
i = pcmcia_request_irq(link->handle, &link->irq);
i = pcmcia_request_irq(link, &link->irq);
if (i != CS_SUCCESS) {
link->irq.AssignedIRQ = 0;
last_fn = RequestIRQ;
goto cs_failed;
}
i = pcmcia_request_configuration(link->handle, &link->conf);
i = pcmcia_request_configuration(link, &link->conf);
if (i != CS_SUCCESS) {
last_fn = RequestConfiguration;
goto cs_failed;
......@@ -321,14 +307,11 @@ static void elsa_cs_config(dev_link_t *link)
sprintf(dev->node.dev_name, "elsa");
dev->node.major = dev->node.minor = 0x0;
link->dev = &dev->node;
link->dev_node = &dev->node;
/* Finally, report what we've done */
printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d",
dev->node.dev_name, link->conf.ConfigIndex,
link->conf.Vcc/10, link->conf.Vcc%10);
if (link->conf.Vpp1)
printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
printk(KERN_INFO "%s: index 0x%02x: ",
dev->node.dev_name, link->conf.ConfigIndex);
if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %d", link->irq.AssignedIRQ);
if (link->io.NumPorts1)
......@@ -339,8 +322,6 @@ static void elsa_cs_config(dev_link_t *link)
link->io.BasePort2+link->io.NumPorts2-1);
printk("\n");
link->state &= ~DEV_CONFIG_PENDING;
icard.para[0] = link->irq.AssignedIRQ;
icard.para[1] = link->io.BasePort1;
icard.protocol = protocol;
......@@ -354,10 +335,11 @@ static void elsa_cs_config(dev_link_t *link)
} else
((local_info_t*)link->priv)->cardnr = i;
return;
return 0;
cs_failed:
cs_error(link->handle, last_fn, i);
cs_error(link, last_fn, i);
elsa_cs_release(link);
return -ENODEV;
} /* elsa_cs_config */
/*======================================================================
......@@ -368,7 +350,7 @@ static void elsa_cs_config(dev_link_t *link)
======================================================================*/
static void elsa_cs_release(dev_link_t *link)
static void elsa_cs_release(struct pcmcia_device *link)
{
local_info_t *local = link->priv;
......@@ -380,39 +362,23 @@ static void elsa_cs_release(dev_link_t *link)
HiSax_closecard(local->cardnr);
}
}
/* Unlink the device chain */
link->dev = NULL;
/* Don't bother checking to see if these succeed or not */
if (link->win)
pcmcia_release_window(link->win);
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);
} /* elsa_cs_release */
static int elsa_suspend(struct pcmcia_device *p_dev)
static int elsa_suspend(struct pcmcia_device *link)
{
dev_link_t *link = dev_to_instance(p_dev);
local_info_t *dev = link->priv;
link->state |= DEV_SUSPEND;
dev->busy = 1;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int elsa_resume(struct pcmcia_device *p_dev)
static int elsa_resume(struct pcmcia_device *link)
{
dev_link_t *link = dev_to_instance(p_dev);
local_info_t *dev = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
dev->busy = 0;
return 0;
......@@ -430,7 +396,7 @@ static struct pcmcia_driver elsa_cs_driver = {
.drv = {
.name = "elsa_cs",
},
.probe = elsa_cs_attach,
.probe = elsa_cs_probe,
.remove = elsa_cs_detach,
.id_table = elsa_ids,
.suspend = elsa_suspend,
......
......@@ -95,8 +95,8 @@ module_param(protocol, int, 0);
event handler.
*/
static void sedlbauer_config(dev_link_t *link);
static void sedlbauer_release(dev_link_t *link);
static int sedlbauer_config(struct pcmcia_device *link);
static void sedlbauer_release(struct pcmcia_device *link);
/*
The attach() and detach() entry points are used to create and destroy
......@@ -119,7 +119,7 @@ static void sedlbauer_detach(struct pcmcia_device *p_dev);
example, ethernet cards, modems). In other cases, there may be
many actual or logical devices (SCSI adapters, memory cards with
multiple partitions). The dev_node_t structures need to be kept
in a linked list starting at the 'dev' field of a dev_link_t
in a linked list starting at the 'dev' field of a struct pcmcia_device
structure. We allocate them in the card's private data structure,
because they generally shouldn't be allocated dynamically.
......@@ -130,7 +130,7 @@ static void sedlbauer_detach(struct pcmcia_device *p_dev);
*/
typedef struct local_info_t {
dev_link_t link;
struct pcmcia_device *p_dev;
dev_node_t node;
int stop;
int cardnr;
......@@ -148,11 +148,10 @@ typedef struct local_info_t {
======================================================================*/
static int sedlbauer_attach(struct pcmcia_device *p_dev)
static int sedlbauer_probe(struct pcmcia_device *link)
{
local_info_t *local;
dev_link_t *link;
DEBUG(0, "sedlbauer_attach()\n");
/* Allocate space for private device-specific data */
......@@ -160,8 +159,10 @@ static int sedlbauer_attach(struct pcmcia_device *p_dev)
if (!local) return -ENOMEM;
memset(local, 0, sizeof(local_info_t));
local->cardnr = -1;
link = &local->link; link->priv = local;
local->p_dev = link;
link->priv = local;
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
......@@ -182,18 +183,10 @@ static int sedlbauer_attach(struct pcmcia_device *p_dev)
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.IOAddrLines = 3;
link->conf.Attributes = 0;
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
link->handle = p_dev;
p_dev->instance = link;
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
sedlbauer_config(link);
return 0;
return sedlbauer_config(link);
} /* sedlbauer_attach */
/*======================================================================
......@@ -205,19 +198,15 @@ static int sedlbauer_attach(struct pcmcia_device *p_dev)
======================================================================*/
static void sedlbauer_detach(struct pcmcia_device *p_dev)
static void sedlbauer_detach(struct pcmcia_device *link)
{
dev_link_t *link = dev_to_instance(p_dev);
DEBUG(0, "sedlbauer_detach(0x%p)\n", link);
DEBUG(0, "sedlbauer_detach(0x%p)\n", link);
if (link->state & DEV_CONFIG) {
((local_info_t *)link->priv)->stop = 1;
sedlbauer_release(link);
}
((local_info_t *)link->priv)->stop = 1;
sedlbauer_release(link);
/* This points to the parent local_info_t struct */
kfree(link->priv);
/* This points to the parent local_info_t struct */
kfree(link->priv);
} /* sedlbauer_detach */
/*======================================================================
......@@ -230,9 +219,8 @@ static void sedlbauer_detach(struct pcmcia_device *p_dev)
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
static void sedlbauer_config(dev_link_t *link)
static int sedlbauer_config(struct pcmcia_device *link)
{
client_handle_t handle = link->handle;
local_info_t *dev = link->priv;
tuple_t tuple;
cisparse_t parse;
......@@ -254,18 +242,13 @@ static void sedlbauer_config(dev_link_t *link)
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
link->conf.ConfigBase = parse.config.base;
link->conf.Present = parse.config.rmask[0];
/* Configure card */
link->state |= DEV_CONFIG;
/* Look up the current Vcc */
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
link->conf.Vcc = conf.Vcc;
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf));
/*
In this loop, we scan the CIS for configuration table entries,
......@@ -280,12 +263,12 @@ static void sedlbauer_config(dev_link_t *link)
will only use the CIS to fill in implementation-defined details.
*/
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) {
cistpl_cftable_entry_t dflt = { 0 };
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
pcmcia_parse_tuple(link, &tuple, &parse) != 0)
goto next_entry;
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
......@@ -309,10 +292,10 @@ static void sedlbauer_config(dev_link_t *link)
}
if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
link->conf.Vpp1 = link->conf.Vpp2 =
link->conf.Vpp =
cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
link->conf.Vpp1 = link->conf.Vpp2 =
link->conf.Vpp =
dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
/* Do we need to allocate an interrupt? */
......@@ -339,13 +322,13 @@ static void sedlbauer_config(dev_link_t *link)
link->io.NumPorts2 = io->win[1].len;
}
/* This reserves IO space but doesn't actually enable it */
if (pcmcia_request_io(link->handle, &link->io) != 0)
if (pcmcia_request_io(link, &link->io) != 0)
goto next_entry;
}
/*
Now set up a common memory window, if needed. There is room
in the dev_link_t structure for one memory window handle,
in the struct pcmcia_device structure for one memory window handle,
but if the base addresses need to be saved, or if multiple
windows are needed, the info should go in the private data
structure for this device.
......@@ -366,7 +349,7 @@ static void sedlbauer_config(dev_link_t *link)
req.Size = 0x1000;
*/
req.AccessSpeed = 0;
if (pcmcia_request_window(&link->handle, &req, &link->win) != 0)
if (pcmcia_request_window(&link, &req, &link->win) != 0)
goto next_entry;
map.Page = 0; map.CardOffset = mem->win[0].card_addr;
if (pcmcia_map_mem_page(link->win, &map) != 0)
......@@ -374,29 +357,25 @@ static void sedlbauer_config(dev_link_t *link)
}
/* If we got this far, we're cool! */
break;
next_entry:
/* new in dummy.cs 2001/01/28 MN
if (link->io.NumPorts1)
pcmcia_release_io(link->handle, &link->io);
*/
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
}
/*
Allocate an interrupt line. Note that this does not assign a
handler to the interrupt, unless the 'Handler' member of the
irq structure is initialized.
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ)
CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
/*
This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
/*
At this point, the dev_node_t structure(s) need to be
......@@ -404,14 +383,13 @@ static void sedlbauer_config(dev_link_t *link)
*/
sprintf(dev->node.dev_name, "sedlbauer");
dev->node.major = dev->node.minor = 0;
link->dev = &dev->node;
link->dev_node = &dev->node;
/* Finally, report what we've done */
printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d",
dev->node.dev_name, link->conf.ConfigIndex,
link->conf.Vcc/10, link->conf.Vcc%10);
if (link->conf.Vpp1)
printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
printk(KERN_INFO "%s: index 0x%02x:",
dev->node.dev_name, link->conf.ConfigIndex);
if (link->conf.Vpp)
printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %d", link->irq.AssignedIRQ);
if (link->io.NumPorts1)
......@@ -424,8 +402,6 @@ static void sedlbauer_config(dev_link_t *link)
printk(", mem 0x%06lx-0x%06lx", req.Base,
req.Base+req.Size-1);
printk("\n");
link->state &= ~DEV_CONFIG_PENDING;
icard.para[0] = link->irq.AssignedIRQ;
icard.para[1] = link->io.BasePort1;
......@@ -437,14 +413,16 @@ static void sedlbauer_config(dev_link_t *link)
printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n",
last_ret, link->io.BasePort1);
sedlbauer_release(link);
return -ENODEV;
} else
((local_info_t*)link->priv)->cardnr = last_ret;
return;
return 0;
cs_failed:
cs_error(link->handle, last_fn, last_ret);
cs_error(link, last_fn, last_ret);
sedlbauer_release(link);
return -ENODEV;
} /* sedlbauer_config */
......@@ -456,7 +434,7 @@ static void sedlbauer_config(dev_link_t *link)
======================================================================*/
static void sedlbauer_release(dev_link_t *link)
static void sedlbauer_release(struct pcmcia_device *link)
{
local_info_t *local = link->priv;
DEBUG(0, "sedlbauer_release(0x%p)\n", link);
......@@ -467,46 +445,23 @@ static void sedlbauer_release(dev_link_t *link)
HiSax_closecard(local->cardnr);
}
}
/* Unlink the device chain */
link->dev = NULL;
/*
In a normal driver, additional code may be needed to release
other kernel data structures associated with this device.
*/
/* Don't bother checking to see if these succeed or not */
if (link->win)
pcmcia_release_window(link->win);
pcmcia_release_configuration(link->handle);
if (link->io.NumPorts1)
pcmcia_release_io(link->handle, &link->io);
if (link->irq.AssignedIRQ)
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
pcmcia_disable_device(link);
} /* sedlbauer_release */
static int sedlbauer_suspend(struct pcmcia_device *p_dev)
static int sedlbauer_suspend(struct pcmcia_device *link)
{
dev_link_t *link = dev_to_instance(p_dev);
local_info_t *dev = link->priv;
link->state |= DEV_SUSPEND;
dev->stop = 1;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int sedlbauer_resume(struct pcmcia_device *p_dev)
static int sedlbauer_resume(struct pcmcia_device *link)
{
dev_link_t *link = dev_to_instance(p_dev);
local_info_t *dev = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
dev->stop = 0;
return 0;
......@@ -530,7 +485,7 @@ static struct pcmcia_driver sedlbauer_driver = {
.drv = {
.name = "sedlbauer_cs",
},
.probe = sedlbauer_attach,
.probe = sedlbauer_probe,
.remove = sedlbauer_detach,
.id_table = sedlbauer_ids,
.suspend = sedlbauer_suspend,
......
......@@ -75,8 +75,8 @@ module_param(protocol, int, 0);
handler.
*/
static void teles_cs_config(dev_link_t *link);
static void teles_cs_release(dev_link_t *link);
static int teles_cs_config(struct pcmcia_device *link);
static void teles_cs_release(struct pcmcia_device *link);
/*
The attach() and detach() entry points are used to create and destroy
......@@ -89,10 +89,10 @@ static void teles_detach(struct pcmcia_device *p_dev);
/*
A linked list of "instances" of the teles_cs device. Each actual
PCMCIA card corresponds to one device instance, and is described
by one dev_link_t structure (defined in ds.h).
by one struct pcmcia_device structure (defined in ds.h).
You may not want to use a linked list for this -- for example, the
memory card driver uses an array of dev_link_t pointers, where minor
memory card driver uses an array of struct pcmcia_device pointers, where minor
device numbers are used to derive the corresponding array index.
*/
......@@ -102,7 +102,7 @@ static void teles_detach(struct pcmcia_device *p_dev);
example, ethernet cards, modems). In other cases, there may be
many actual or logical devices (SCSI adapters, memory cards with
multiple partitions). The dev_node_t structures need to be kept
in a linked list starting at the 'dev' field of a dev_link_t
in a linked list starting at the 'dev' field of a struct pcmcia_device
structure. We allocate them in the card's private data structure,
because they generally shouldn't be allocated dynamically.
In this case, we also provide a flag to indicate if a device is
......@@ -112,7 +112,7 @@ static void teles_detach(struct pcmcia_device *p_dev);
*/
typedef struct local_info_t {
dev_link_t link;
struct pcmcia_device *p_dev;
dev_node_t node;
int busy;
int cardnr;
......@@ -130,9 +130,8 @@ typedef struct local_info_t {
======================================================================*/
static int teles_attach(struct pcmcia_device *p_dev)
static int teles_probe(struct pcmcia_device *link)
{
dev_link_t *link;
local_info_t *local;
DEBUG(0, "teles_attach()\n");
......@@ -142,7 +141,9 @@ static int teles_attach(struct pcmcia_device *p_dev)
if (!local) return -ENOMEM;
memset(local, 0, sizeof(local_info_t));
local->cardnr = -1;
link = &local->link; link->priv = local;
local->p_dev = link;
link->priv = local;
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
......@@ -161,16 +162,9 @@ static int teles_attach(struct pcmcia_device *p_dev)
link->io.IOAddrLines = 5;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
link->handle = p_dev;
p_dev->instance = link;
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
teles_cs_config(link);
return 0;
return teles_cs_config(link);
} /* teles_attach */
/*======================================================================
......@@ -182,20 +176,16 @@ static int teles_attach(struct pcmcia_device *p_dev)
======================================================================*/
static void teles_detach(struct pcmcia_device *p_dev)
static void teles_detach(struct pcmcia_device *link)
{
dev_link_t *link = dev_to_instance(p_dev);
local_info_t *info = link->priv;
DEBUG(0, "teles_detach(0x%p)\n", link);
local_info_t *info = link->priv;
if (link->state & DEV_CONFIG) {
info->busy = 1;
teles_cs_release(link);
}
DEBUG(0, "teles_detach(0x%p)\n", link);
kfree(info);
info->busy = 1;
teles_cs_release(link);
kfree(info);
} /* teles_detach */
/*======================================================================
......@@ -205,7 +195,7 @@ static void teles_detach(struct pcmcia_device *p_dev)
device available to the system.
======================================================================*/
static int get_tuple(client_handle_t handle, tuple_t *tuple,
static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
{
int i = pcmcia_get_tuple_data(handle, tuple);
......@@ -213,7 +203,7 @@ static int get_tuple(client_handle_t handle, tuple_t *tuple,
return pcmcia_parse_tuple(handle, tuple, parse);
}
static int first_tuple(client_handle_t handle, tuple_t *tuple,
static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
{
int i = pcmcia_get_first_tuple(handle, tuple);
......@@ -221,7 +211,7 @@ static int first_tuple(client_handle_t handle, tuple_t *tuple,
return get_tuple(handle, tuple, parse);
}
static int next_tuple(client_handle_t handle, tuple_t *tuple,
static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
{
int i = pcmcia_get_next_tuple(handle, tuple);
......@@ -229,9 +219,8 @@ static int next_tuple(client_handle_t handle, tuple_t *tuple,
return get_tuple(handle, tuple, parse);
}
static void teles_cs_config(dev_link_t *link)
static int teles_cs_config(struct pcmcia_device *link)
{
client_handle_t handle;
tuple_t tuple;
cisparse_t parse;
local_info_t *dev;
......@@ -241,7 +230,6 @@ static void teles_cs_config(dev_link_t *link)
IsdnCard_t icard;
DEBUG(0, "teles_config(0x%p)\n", link);
handle = link->handle;
dev = link->priv;
/*
......@@ -253,7 +241,7 @@ static void teles_cs_config(dev_link_t *link)
tuple.TupleDataMax = 255;
tuple.TupleOffset = 0;
tuple.Attributes = 0;
i = first_tuple(handle, &tuple, &parse);
i = first_tuple(link, &tuple, &parse);
if (i != CS_SUCCESS) {
last_fn = ParseTuple;
goto cs_failed;
......@@ -261,32 +249,29 @@ static void teles_cs_config(dev_link_t *link)
link->conf.ConfigBase = parse.config.base;
link->conf.Present = parse.config.rmask[0];
/* Configure card */
link->state |= DEV_CONFIG;
tuple.TupleData = (cisdata_t *)buf;
tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
tuple.Attributes = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
i = first_tuple(handle, &tuple, &parse);
i = first_tuple(link, &tuple, &parse);
while (i == CS_SUCCESS) {
if ( (cf->io.nwin > 0) && cf->io.win[0].base) {
printk(KERN_INFO "(teles_cs: looks like the 96 model)\n");
link->conf.ConfigIndex = cf->index;
link->io.BasePort1 = cf->io.win[0].base;
i = pcmcia_request_io(link->handle, &link->io);
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS) break;
} else {
printk(KERN_INFO "(teles_cs: looks like the 97 model)\n");
link->conf.ConfigIndex = cf->index;
for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) {
link->io.BasePort1 = j;
i = pcmcia_request_io(link->handle, &link->io);
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS) break;
}
break;
}
i = next_tuple(handle, &tuple, &parse);
i = next_tuple(link, &tuple, &parse);
}
if (i != CS_SUCCESS) {
......@@ -294,14 +279,14 @@ static void teles_cs_config(dev_link_t *link)
goto cs_failed;
}
i = pcmcia_request_irq(link->handle, &link->irq);
i = pcmcia_request_irq(link, &link->irq);
if (i != CS_SUCCESS) {
link->irq.AssignedIRQ = 0;
last_fn = RequestIRQ;
goto cs_failed;
}
i = pcmcia_request_configuration(link->handle, &link->conf);
i = pcmcia_request_configuration(link, &link->conf);
if (i != CS_SUCCESS) {
last_fn = RequestConfiguration;
goto cs_failed;
......@@ -312,14 +297,11 @@ static void teles_cs_config(dev_link_t *link)
sprintf(dev->node.dev_name, "teles");
dev->node.major = dev->node.minor = 0x0;
link->dev = &dev->node;
link->dev_node = &dev->node;
/* Finally, report what we've done */
printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d",
dev->node.dev_name, link->conf.ConfigIndex,
link->conf.Vcc/10, link->conf.Vcc%10);
if (link->conf.Vpp1)
printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
printk(KERN_INFO "%s: index 0x%02x:",
dev->node.dev_name, link->conf.ConfigIndex);
if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %d", link->irq.AssignedIRQ);
if (link->io.NumPorts1)
......@@ -330,8 +312,6 @@ static void teles_cs_config(dev_link_t *link)
link->io.BasePort2+link->io.NumPorts2-1);
printk("\n");
link->state &= ~DEV_CONFIG_PENDING;
icard.para[0] = link->irq.AssignedIRQ;
icard.para[1] = link->io.BasePort1;
icard.protocol = protocol;
......@@ -342,13 +322,16 @@ static void teles_cs_config(dev_link_t *link)
printk(KERN_ERR "teles_cs: failed to initialize Teles PCMCIA %d at i/o %#x\n",
i, link->io.BasePort1);
teles_cs_release(link);
} else
((local_info_t*)link->priv)->cardnr = i;
return -ENODEV;
}
((local_info_t*)link->priv)->cardnr = i;
return 0;
return;
cs_failed:
cs_error(link->handle, last_fn, i);
cs_error(link, last_fn, i);
teles_cs_release(link);
return -ENODEV;
} /* teles_cs_config */
/*======================================================================
......@@ -359,7 +342,7 @@ static void teles_cs_config(dev_link_t *link)
======================================================================*/
static void teles_cs_release(dev_link_t *link)
static void teles_cs_release(struct pcmcia_device *link)
{
local_info_t *local = link->priv;
......@@ -371,39 +354,23 @@ static void teles_cs_release(dev_link_t *link)
HiSax_closecard(local->cardnr);
}
}
/* Unlink the device chain */
link->dev = NULL;
/* Don't bother checking to see if these succeed or not */
if (link->win)
pcmcia_release_window(link->win);
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);
} /* teles_cs_release */
static int teles_suspend(struct pcmcia_device *p_dev)
static int teles_suspend(struct pcmcia_device *link)
{
dev_link_t *link = dev_to_instance(p_dev);
local_info_t *dev = link->priv;
link->state |= DEV_SUSPEND;
dev->busy = 1;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int teles_resume(struct pcmcia_device *p_dev)
static int teles_resume(struct pcmcia_device *link)
{
dev_link_t *link = dev_to_instance(p_dev);
local_info_t *dev = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
dev->busy = 0;
return 0;
......@@ -421,7 +388,7 @@ static struct pcmcia_driver teles_cs_driver = {
.drv = {
.name = "teles_cs",
},
.probe = teles_attach,
.probe = teles_probe,
.remove = teles_detach,
.id_table = teles_ids,
.suspend = teles_suspend,
......
......@@ -54,7 +54,7 @@ static const int debug = 0;
#define MAX_PCMCIA_ADDR 0x4000000
struct pcmciamtd_dev {
dev_link_t link; /* PCMCIA link */
struct pcmcia_device *p_dev;
dev_node_t node; /* device node */
caddr_t win_base; /* ioremapped address of PCMCIA window */
unsigned int win_size; /* size of window */
......@@ -111,8 +111,8 @@ static caddr_t remap_window(struct map_info *map, unsigned long to)
memreq_t mrq;
int ret;
if(!(dev->link.state & DEV_PRESENT)) {
DEBUG(1, "device removed state = 0x%4.4X", dev->link.state);
if (!pcmcia_dev_present(dev->p_dev)) {
DEBUG(1, "device removed");
return 0;
}
......@@ -122,7 +122,7 @@ static caddr_t remap_window(struct map_info *map, unsigned long to)
dev->offset, mrq.CardOffset);
mrq.Page = 0;
if( (ret = pcmcia_map_mem_page(win, &mrq)) != CS_SUCCESS) {
cs_error(dev->link.handle, MapMemPage, ret);
cs_error(dev->p_dev, MapMemPage, ret);
return NULL;
}
dev->offset = mrq.CardOffset;
......@@ -238,7 +238,7 @@ static void pcmcia_copy_to_remap(struct map_info *map, unsigned long to, const v
/* read/write{8,16} copy_{from,to} routines with direct access */
#define DEV_REMOVED(x) (!(*(u_int *)x->map_priv_1 & DEV_PRESENT))
#define DEV_REMOVED(x) (!(pcmcia_dev_present(((struct pcmciamtd_dev *)map->map_priv_1)->p_dev)))
static map_word pcmcia_read8(struct map_info *map, unsigned long ofs)
{
......@@ -319,7 +319,7 @@ static void pcmcia_copy_to(struct map_info *map, unsigned long to, const void *f
static void pcmciamtd_set_vpp(struct map_info *map, int on)
{
struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
dev_link_t *link = &dev->link;
struct pcmcia_device *link = dev->p_dev;
modconf_t mod;
int ret;
......@@ -328,9 +328,9 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on)
mod.Vpp1 = mod.Vpp2 = on ? dev->vpp : 0;
DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp);
ret = pcmcia_modify_configuration(link->handle, &mod);
ret = pcmcia_modify_configuration(link, &mod);
if(ret != CS_SUCCESS) {
cs_error(link->handle, ModifyConfiguration, ret);
cs_error(link, ModifyConfiguration, ret);
}
}
......@@ -340,7 +340,7 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on)
* still open, this will be postponed until it is closed.
*/
static void pcmciamtd_release(dev_link_t *link)
static void pcmciamtd_release(struct pcmcia_device *link)
{
struct pcmciamtd_dev *dev = link->priv;
......@@ -353,12 +353,11 @@ static void pcmciamtd_release(dev_link_t *link)
}
pcmcia_release_window(link->win);
}
pcmcia_release_configuration(link->handle);
link->state &= ~DEV_CONFIG;
pcmcia_disable_device(link);
}
static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_name)
static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name)
{
int rc;
tuple_t tuple;
......@@ -371,16 +370,16 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
tuple.TupleOffset = 0;
tuple.DesiredTuple = RETURN_FIRST_TUPLE;
rc = pcmcia_get_first_tuple(link->handle, &tuple);
rc = pcmcia_get_first_tuple(link, &tuple);
while(rc == CS_SUCCESS) {
rc = pcmcia_get_tuple_data(link->handle, &tuple);
rc = pcmcia_get_tuple_data(link, &tuple);
if(rc != CS_SUCCESS) {
cs_error(link->handle, GetTupleData, rc);
cs_error(link, GetTupleData, rc);
break;
}
rc = pcmcia_parse_tuple(link->handle, &tuple, &parse);
rc = pcmcia_parse_tuple(link, &tuple, &parse);
if(rc != CS_SUCCESS) {
cs_error(link->handle, ParseTuple, rc);
cs_error(link, ParseTuple, rc);
break;
}
......@@ -451,7 +450,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
DEBUG(2, "Unknown tuple code %d", tuple.TupleCode);
}
rc = pcmcia_get_next_tuple(link->handle, &tuple);
rc = pcmcia_get_next_tuple(link, &tuple);
}
if(!dev->pcmcia_map.size)
dev->pcmcia_map.size = MAX_PCMCIA_ADDR;
......@@ -488,7 +487,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
static void pcmciamtd_config(dev_link_t *link)
static int pcmciamtd_config(struct pcmcia_device *link)
{
struct pcmciamtd_dev *dev = link->priv;
struct mtd_info *mtd = NULL;
......@@ -504,13 +503,10 @@ static void pcmciamtd_config(dev_link_t *link)
DEBUG(3, "link=0x%p", link);
/* Configure card */
link->state |= DEV_CONFIG;
DEBUG(2, "Validating CIS");
ret = pcmcia_validate_cis(link->handle, &cisinfo);
ret = pcmcia_validate_cis(link, &cisinfo);
if(ret != CS_SUCCESS) {
cs_error(link->handle, GetTupleData, ret);
cs_error(link, GetTupleData, ret);
} else {
DEBUG(2, "ValidateCIS found %d chains", cisinfo.Chains);
}
......@@ -538,7 +534,7 @@ static void pcmciamtd_config(dev_link_t *link)
req.Attributes |= (dev->pcmcia_map.bankwidth == 1) ? WIN_DATA_WIDTH_8 : WIN_DATA_WIDTH_16;
req.Base = 0;
req.AccessSpeed = mem_speed;
link->win = (window_handle_t)link->handle;
link->win = (window_handle_t)link;
req.Size = (force_size) ? force_size << 20 : MAX_PCMCIA_ADDR;
dev->win_size = 0;
......@@ -546,7 +542,7 @@ static void pcmciamtd_config(dev_link_t *link)
int ret;
DEBUG(2, "requesting window with size = %dKiB memspeed = %d",
req.Size >> 10, req.AccessSpeed);
ret = pcmcia_request_window(&link->handle, &req, &link->win);
ret = pcmcia_request_window(&link, &req, &link->win);
DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size);
if(ret) {
req.Size >>= 1;
......@@ -562,19 +558,19 @@ static void pcmciamtd_config(dev_link_t *link)
if(!dev->win_size) {
err("Cant allocate memory window");
pcmciamtd_release(link);
return;
return -ENODEV;
}
DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10);
/* Get write protect status */
CS_CHECK(GetStatus, pcmcia_get_status(link->handle, &status));
CS_CHECK(GetStatus, pcmcia_get_status(link, &status));
DEBUG(2, "status value: 0x%x window handle = 0x%8.8lx",
status.CardState, (unsigned long)link->win);
dev->win_base = ioremap(req.Base, req.Size);
if(!dev->win_base) {
err("ioremap(%lu, %u) failed", req.Base, req.Size);
pcmciamtd_release(link);
return;
return -ENODEV;
}
DEBUG(1, "mapped window dev = %p req.base = 0x%lx base = %p size = 0x%x",
dev, req.Base, dev->win_base, req.Size);
......@@ -584,17 +580,14 @@ static void pcmciamtd_config(dev_link_t *link)
dev->pcmcia_map.map_priv_2 = (unsigned long)link->win;
DEBUG(2, "Getting configuration");
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link->handle, &t));
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &t));
DEBUG(2, "Vcc = %d Vpp1 = %d Vpp2 = %d", t.Vcc, t.Vpp1, t.Vpp2);
dev->vpp = (vpp) ? vpp : t.Vpp1;
link->conf.Attributes = 0;
link->conf.Vcc = t.Vcc;
if(setvpp == 2) {
link->conf.Vpp1 = dev->vpp;
link->conf.Vpp2 = dev->vpp;
link->conf.Vpp = dev->vpp;
} else {
link->conf.Vpp1 = 0;
link->conf.Vpp2 = 0;
link->conf.Vpp = 0;
}
link->conf.IntType = INT_MEMORY;
......@@ -606,9 +599,10 @@ static void pcmciamtd_config(dev_link_t *link)
link->conf.ConfigIndex = 0;
link->conf.Present = t.Present;
DEBUG(2, "Setting Configuration");
ret = pcmcia_request_configuration(link->handle, &link->conf);
ret = pcmcia_request_configuration(link, &link->conf);
if(ret != CS_SUCCESS) {
cs_error(link->handle, RequestConfiguration, ret);
cs_error(link, RequestConfiguration, ret);
return -ENODEV;
}
if(mem_type == 1) {
......@@ -629,7 +623,7 @@ static void pcmciamtd_config(dev_link_t *link)
if(!mtd) {
DEBUG(1, "Cant find an MTD");
pcmciamtd_release(link);
return;
return -ENODEV;
}
dev->mtd_info = mtd;
......@@ -654,7 +648,6 @@ static void pcmciamtd_config(dev_link_t *link)
use the faster non-remapping read/write functions */
if(mtd->size <= dev->win_size) {
DEBUG(1, "Using non remapping memory functions");
dev->pcmcia_map.map_priv_1 = (unsigned long)&(dev->link.state);
dev->pcmcia_map.map_priv_2 = (unsigned long)dev->win_base;
if (dev->pcmcia_map.bankwidth == 1) {
dev->pcmcia_map.read = pcmcia_read8;
......@@ -672,19 +665,18 @@ static void pcmciamtd_config(dev_link_t *link)
dev->mtd_info = NULL;
err("Couldnt register MTD device");
pcmciamtd_release(link);
return;
return -ENODEV;
}
snprintf(dev->node.dev_name, sizeof(dev->node.dev_name), "mtd%d", mtd->index);
info("mtd%d: %s", mtd->index, mtd->name);
link->state &= ~DEV_CONFIG_PENDING;
link->dev = &dev->node;
return;
link->dev_node = &dev->node;
return 0;
cs_failed:
cs_error(link->handle, last_fn, last_ret);
cs_error(link, last_fn, last_ret);
err("CS Error, exiting");
pcmciamtd_release(link);
return;
return -ENODEV;
}
......@@ -713,21 +705,18 @@ static int pcmciamtd_resume(struct pcmcia_device *dev)
* when the device is released.
*/
static void pcmciamtd_detach(struct pcmcia_device *p_dev)
static void pcmciamtd_detach(struct pcmcia_device *link)
{
dev_link_t *link = dev_to_instance(p_dev);
struct pcmciamtd_dev *dev = link->priv;
DEBUG(3, "link=0x%p", link);
if(link->state & DEV_CONFIG) {
struct pcmciamtd_dev *dev = link->priv;
if(dev->mtd_info) {
del_mtd_device(dev->mtd_info);
info("mtd%d: Removed", dev->mtd_info->index);
}
pcmciamtd_release(link);
if(dev->mtd_info) {
del_mtd_device(dev->mtd_info);
info("mtd%d: Removed", dev->mtd_info->index);
}
pcmciamtd_release(link);
}
......@@ -736,10 +725,9 @@ static void pcmciamtd_detach(struct pcmcia_device *p_dev)
* with Card Services.
*/
static int pcmciamtd_attach(struct pcmcia_device *p_dev)
static int pcmciamtd_probe(struct pcmcia_device *link)
{
struct pcmciamtd_dev *dev;
dev_link_t *link;
/* Create new memory card device */
dev = kmalloc(sizeof(*dev), GFP_KERNEL);
......@@ -747,20 +735,13 @@ static int pcmciamtd_attach(struct pcmcia_device *p_dev)
DEBUG(1, "dev=0x%p", dev);
memset(dev, 0, sizeof(*dev));
link = &dev->link;
dev->p_dev = link;
link->priv = dev;
link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY;
link->next = NULL;
link->handle = p_dev;
p_dev->instance = link;
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
pcmciamtd_config(link);
return 0;
return pcmciamtd_config(link);
}
static struct pcmcia_device_id pcmciamtd_ids[] = {
......@@ -794,7 +775,7 @@ static struct pcmcia_driver pcmciamtd_driver = {
.drv = {
.name = "pcmciamtd"
},
.probe = pcmciamtd_attach,
.probe = pcmciamtd_probe,
.remove = pcmciamtd_detach,
.owner = THIS_MODULE,
.id_table = pcmciamtd_ids,
......
......@@ -204,7 +204,7 @@ enum Window4 { /* Window 4: Xcvr/media bits. */
#define MEDIA_TP 0x00C0 /* Enable link beat and jabber for 10baseT. */
struct el3_private {
dev_link_t link;
struct pcmcia_device *p_dev;
dev_node_t node;
struct net_device_stats stats;
u16 advertising, partner; /* NWay media advertisement */
......@@ -225,8 +225,8 @@ static char mii_preamble_required = 0;
/* Index of functions. */
static void tc574_config(dev_link_t *link);
static void tc574_release(dev_link_t *link);
static int tc574_config(struct pcmcia_device *link);
static void tc574_release(struct pcmcia_device *link);
static void mdio_sync(kio_addr_t ioaddr, int bits);
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);
with Card Services.
*/
static int tc574_attach(struct pcmcia_device *p_dev)
static int tc574_probe(struct pcmcia_device *link)
{
struct el3_private *lp;
dev_link_t *link;
struct net_device *dev;
DEBUG(0, "3c574_attach()\n");
......@@ -269,8 +268,8 @@ static int tc574_attach(struct pcmcia_device *p_dev)
if (!dev)
return -ENOMEM;
lp = netdev_priv(dev);
link = &lp->link;
link->priv = dev;
lp->p_dev = link;
spin_lock_init(&lp->window_lock);
link->io.NumPorts1 = 32;
......@@ -280,7 +279,6 @@ static int tc574_attach(struct pcmcia_device *p_dev)
link->irq.Handler = &el3_interrupt;
link->irq.Instance = dev;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1;
link->conf.Present = PRESENT_OPTION;
......@@ -298,13 +296,7 @@ static int tc574_attach(struct pcmcia_device *p_dev)
dev->watchdog_timeo = TX_TIMEOUT;
#endif
link->handle = p_dev;
p_dev->instance = link;
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
tc574_config(link);
return 0;
return tc574_config(link);
} /* tc574_attach */
/*
......@@ -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;
DEBUG(0, "3c574_detach(0x%p)\n", link);
if (link->dev)
if (link->dev_node)
unregister_netdev(dev);
if (link->state & DEV_CONFIG)
tc574_release(link);
tc574_release(link);
free_netdev(dev);
} /* tc574_detach */
......@@ -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 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 el3_private *lp = netdev_priv(dev);
tuple_t tuple;
......@@ -363,30 +352,27 @@ static void tc574_config(dev_link_t *link)
tuple.Attributes = 0;
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.TupleDataMax = 64;
tuple.TupleOffset = 0;
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
link->conf.ConfigBase = parse.config.base;
link->conf.Present = parse.config.rmask[0];
/* Configure card */
link->state |= DEV_CONFIG;
link->io.IOAddrLines = 16;
for (i = j = 0; j < 0x400; j += 0x20) {
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) {
cs_error(link->handle, RequestIO, i);
cs_error(link, RequestIO, i);
goto failed;
}
CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
dev->irq = link->irq.AssignedIRQ;
dev->base_addr = link->io.BasePort1;
......@@ -397,8 +383,8 @@ static void tc574_config(dev_link_t *link)
the hardware address. The future products may include a modem chip
and put the address in the CIS. */
tuple.DesiredTuple = 0x88;
if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) {
pcmcia_get_tuple_data(handle, &tuple);
if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) {
pcmcia_get_tuple_data(link, &tuple);
for (i = 0; i < 3; i++)
phys_addr[i] = htons(buf[i]);
} else {
......@@ -412,9 +398,9 @@ static void tc574_config(dev_link_t *link)
}
}
tuple.DesiredTuple = CISTPL_VERS_1;
if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS &&
pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS &&
pcmcia_parse_tuple(handle, &tuple, &parse) == CS_SUCCESS) {
if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS &&
pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS &&
pcmcia_parse_tuple(link, &tuple, &parse) == CS_SUCCESS) {
cardname = parse.version_1.str + parse.version_1.ofs[1];
} else
cardname = "3Com 3c574";
......@@ -473,13 +459,12 @@ static void tc574_config(dev_link_t *link)
}
}
link->state &= ~DEV_CONFIG_PENDING;
link->dev = &lp->node;
SET_NETDEV_DEV(dev, &handle_to_dev(handle));
link->dev_node = &lp->node;
SET_NETDEV_DEV(dev, &handle_to_dev(link));
if (register_netdev(dev) != 0) {
printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n");
link->dev = NULL;
link->dev_node = NULL;
goto failed;
}
......@@ -493,13 +478,13 @@ static void tc574_config(dev_link_t *link)
8 << config.u.ram_size, ram_split[config.u.ram_split],
config.u.autoselect ? "autoselect " : "");
return;
return 0;
cs_failed:
cs_error(link->handle, last_fn, last_ret);
cs_error(link, last_fn, last_ret);
failed:
tc574_release(link);
return;
return -ENODEV;
} /* tc574_config */
......@@ -509,44 +494,28 @@ static void tc574_config(dev_link_t *link)
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_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);
}
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;
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
if (link->open)
netif_device_detach(dev);
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;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
tc574_reset(dev);
netif_device_attach(dev);
}
if (link->open) {
tc574_reset(dev);
netif_device_attach(dev);
}
return 0;
......@@ -757,9 +726,9 @@ static void tc574_reset(struct net_device *dev)
static int el3_open(struct net_device *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;
link->open++;
......@@ -1203,11 +1172,11 @@ static int el3_close(struct net_device *dev)
{
kio_addr_t ioaddr = dev->base_addr;
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);
if (DEV_OK(link)) {
if (pcmcia_dev_present(link)) {
unsigned long flags;
/* Turn off statistics ASAP. We update lp->stats below. */
......@@ -1246,7 +1215,7 @@ static struct pcmcia_driver tc574_driver = {
.drv = {
.name = "3c574_cs",
},
.probe = tc574_attach,
.probe = tc574_probe,
.remove = tc574_detach,
.id_table = tc574_ids,
.suspend = tc574_suspend,
......
......@@ -105,7 +105,7 @@ enum RxFilter {
#define TX_TIMEOUT ((400*HZ)/1000)
struct el3_private {
dev_link_t link;
struct pcmcia_device *p_dev;
dev_node_t node;
struct net_device_stats stats;
/* For transceiver monitoring */
......@@ -142,8 +142,8 @@ DRV_NAME ".c " DRV_VERSION " 2001/10/13 00:08:50 (David Hinds)";
/*====================================================================*/
static void tc589_config(dev_link_t *link);
static void tc589_release(dev_link_t *link);
static int tc589_config(struct pcmcia_device *link);
static void tc589_release(struct pcmcia_device *link);
static u16 read_eeprom(kio_addr_t ioaddr, int index);
static void tc589_reset(struct net_device *dev);
......@@ -170,10 +170,9 @@ static void tc589_detach(struct pcmcia_device *p_dev);
======================================================================*/
static int tc589_attach(struct pcmcia_device *p_dev)
static int tc589_probe(struct pcmcia_device *link)
{
struct el3_private *lp;
dev_link_t *link;
struct net_device *dev;
DEBUG(0, "3c589_attach()\n");
......@@ -183,8 +182,8 @@ static int tc589_attach(struct pcmcia_device *p_dev)
if (!dev)
return -ENOMEM;
lp = netdev_priv(dev);
link = &lp->link;
link->priv = dev;
lp->p_dev = link;
spin_lock_init(&lp->lock);
link->io.NumPorts1 = 16;
......@@ -194,7 +193,6 @@ static int tc589_attach(struct pcmcia_device *p_dev)
link->irq.Handler = &el3_interrupt;
link->irq.Instance = dev;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1;
link->conf.Present = PRESENT_OPTION;
......@@ -213,13 +211,7 @@ static int tc589_attach(struct pcmcia_device *p_dev)
#endif
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
link->handle = p_dev;
p_dev->instance = link;
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
tc589_config(link);
return 0;
return tc589_config(link);
} /* tc589_attach */
/*======================================================================
......@@ -231,18 +223,16 @@ static int tc589_attach(struct pcmcia_device *p_dev)
======================================================================*/
static void tc589_detach(struct pcmcia_device *p_dev)
static void tc589_detach(struct pcmcia_device *link)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
DEBUG(0, "3c589_detach(0x%p)\n", link);
if (link->dev)
if (link->dev_node)
unregister_netdev(dev);
if (link->state & DEV_CONFIG)
tc589_release(link);
tc589_release(link);
free_netdev(dev);
} /* tc589_detach */
......@@ -258,9 +248,8 @@ static void tc589_detach(struct pcmcia_device *p_dev)
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
static void tc589_config(dev_link_t *link)
static int tc589_config(struct pcmcia_device *link)
{
client_handle_t handle = link->handle;
struct net_device *dev = link->priv;
struct el3_private *lp = netdev_priv(dev);
tuple_t tuple;
......@@ -275,43 +264,40 @@ static void tc589_config(dev_link_t *link)
phys_addr = (u16 *)dev->dev_addr;
tuple.Attributes = 0;
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.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
link->conf.ConfigBase = parse.config.base;
link->conf.Present = parse.config.rmask[0];
/* Is this a 3c562? */
tuple.DesiredTuple = CISTPL_MANFID;
tuple.Attributes = TUPLE_RETURN_COMMON;
if ((pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) &&
(pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS)) {
if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) &&
(pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS)) {
if (le16_to_cpu(buf[0]) != MANFID_3COM)
printk(KERN_INFO "3c589_cs: hmmm, is this really a "
"3Com card??\n");
multi = (le16_to_cpu(buf[1]) == PRODID_3COM_3C562);
}
/* Configure card */
link->state |= DEV_CONFIG;
/* For the 3c562, the base address must be xx00-xx7f */
link->io.IOAddrLines = 16;
for (i = j = 0; j < 0x400; j += 0x10) {
if (multi && (j & 0x80)) continue;
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) {
cs_error(link->handle, RequestIO, i);
cs_error(link, RequestIO, i);
goto failed;
}
CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
dev->irq = link->irq.AssignedIRQ;
dev->base_addr = link->io.BasePort1;
......@@ -321,8 +307,8 @@ static void tc589_config(dev_link_t *link)
/* The 3c589 has an extra EEPROM for configuration info, including
the hardware address. The 3c562 puts the address in the CIS. */
tuple.DesiredTuple = 0x88;
if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) {
pcmcia_get_tuple_data(handle, &tuple);
if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) {
pcmcia_get_tuple_data(link, &tuple);
for (i = 0; i < 3; i++)
phys_addr[i] = htons(buf[i]);
} else {
......@@ -346,13 +332,12 @@ static void tc589_config(dev_link_t *link)
else
printk(KERN_ERR "3c589_cs: invalid if_port requested\n");
link->dev = &lp->node;
link->state &= ~DEV_CONFIG_PENDING;
SET_NETDEV_DEV(dev, &handle_to_dev(handle));
link->dev_node = &lp->node;
SET_NETDEV_DEV(dev, &handle_to_dev(link));
if (register_netdev(dev) != 0) {
printk(KERN_ERR "3c589_cs: register_netdev() failed\n");
link->dev = NULL;
link->dev_node = NULL;
goto failed;
}
......@@ -366,14 +351,13 @@ static void tc589_config(dev_link_t *link)
printk(KERN_INFO " %dK FIFO split %s Rx:Tx, %s xcvr\n",
(fifo & 7) ? 32 : 8, ram_split[(fifo >> 16) & 3],
if_names[dev->if_port]);
return;
return 0;
cs_failed:
cs_error(link->handle, last_fn, last_ret);
cs_error(link, last_fn, last_ret);
failed:
tc589_release(link);
return;
return -ENODEV;
} /* tc589_config */
/*======================================================================
......@@ -384,44 +368,28 @@ static void tc589_config(dev_link_t *link)
======================================================================*/
static void tc589_release(dev_link_t *link)
static void tc589_release(struct pcmcia_device *link)
{
DEBUG(0, "3c589_release(0x%p)\n", link);
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);
}
static int tc589_suspend(struct pcmcia_device *p_dev)
static int tc589_suspend(struct pcmcia_device *link)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
if (link->open)
netif_device_detach(dev);
return 0;
}
static int tc589_resume(struct pcmcia_device *p_dev)
static int tc589_resume(struct pcmcia_device *link)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
tc589_reset(dev);
netif_device_attach(dev);
}
if (link->open) {
tc589_reset(dev);
netif_device_attach(dev);
}
return 0;
......@@ -587,9 +555,9 @@ static int el3_config(struct net_device *dev, struct ifmap *map)
static int el3_open(struct net_device *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;
link->open++;
......@@ -848,9 +816,9 @@ static struct net_device_stats *el3_get_stats(struct net_device *dev)
{
struct el3_private *lp = netdev_priv(dev);
unsigned long flags;
dev_link_t *link = &lp->link;
struct pcmcia_device *link = lp->p_dev;
if (DEV_OK(link)) {
if (pcmcia_dev_present(link)) {
spin_lock_irqsave(&lp->lock, flags);
update_stats(dev);
spin_unlock_irqrestore(&lp->lock, flags);
......@@ -950,11 +918,11 @@ static int el3_rx(struct net_device *dev)
static void set_multicast_list(struct net_device *dev)
{
struct el3_private *lp = netdev_priv(dev);
dev_link_t *link = &lp->link;
struct pcmcia_device *link = lp->p_dev;
kio_addr_t ioaddr = dev->base_addr;
u16 opts = SetRxFilter | RxStation | RxBroadcast;
if (!(DEV_OK(link))) return;
if (!pcmcia_dev_present(link)) return;
if (dev->flags & IFF_PROMISC)
opts |= RxMulticast | RxProm;
else if (dev->mc_count || (dev->flags & IFF_ALLMULTI))
......@@ -965,12 +933,12 @@ static void set_multicast_list(struct net_device *dev)
static int el3_close(struct net_device *dev)
{
struct el3_private *lp = netdev_priv(dev);
dev_link_t *link = &lp->link;
struct pcmcia_device *link = lp->p_dev;
kio_addr_t ioaddr = dev->base_addr;
DEBUG(1, "%s: shutting down ethercard.\n", dev->name);
if (DEV_OK(link)) {
if (pcmcia_dev_present(link)) {
/* Turn off statistics ASAP. We update lp->stats below. */
outw(StatsDisable, ioaddr + EL3_CMD);
......@@ -1020,7 +988,7 @@ static struct pcmcia_driver tc589_driver = {
.drv = {
.name = "3c589_cs",
},
.probe = tc589_attach,
.probe = tc589_probe,
.remove = tc589_detach,
.id_table = tc589_ids,
.suspend = tc589_suspend,
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -31,7 +31,7 @@ typedef struct ray_dev_t {
void __iomem *sram; /* pointer to beginning of shared RAM */
void __iomem *amem; /* pointer to attribute mem 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;
long tx_ccs_lock;
long ccs_lock;
......
此差异已折叠。
此差异已折叠。
......@@ -602,7 +602,7 @@ struct net_local
dev_node_t node; /* ???? What is this stuff ???? */
struct net_device * dev; /* Reverse link... */
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 */
int nresets; /* Number of hw resets */
u_char configured; /* If it is configured */
......@@ -733,9 +733,9 @@ static int
static inline void
wv_hw_reset(struct net_device *); /* Same, + start receiver unit */
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
wv_pcmcia_release(dev_link_t *);/* Remove a device */
wv_pcmcia_release(struct pcmcia_device *);/* Remove a device */
/* ---------------------- INTERRUPT HANDLING ---------------------- */
static irqreturn_t
wavelan_interrupt(int, /* Interrupt handler */
......
......@@ -611,5 +611,6 @@ struct wl3501_card {
struct iw_spy_data spy_data;
struct iw_public_data wireless_data;
struct dev_node_t node;
struct pcmcia_device *p_dev;
};
#endif
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -12,7 +12,6 @@
* (C) 1999 David A. Hinds
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册