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 commit is contained in:
commit
86dca4f8e6
77 changed files with 3156 additions and 4574 deletions
|
@ -1,5 +1,11 @@
|
|||
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);
|
||||
bt3c_close(info);
|
||||
|
||||
link->dev = NULL;
|
||||
|
||||
pcmcia_release_configuration(link->handle);
|
||||
pcmcia_release_io(link->handle, &link->io);
|
||||
pcmcia_release_irq(link->handle, &link->irq);
|
||||
|
||||
link->state &= ~DEV_CONFIG;
|
||||
}
|
||||
|
||||
static int bt3c_suspend(struct pcmcia_device *dev)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(dev);
|
||||
|
||||
link->state |= DEV_SUSPEND;
|
||||
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);
|
||||
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;
|
||||
pcmcia_disable_device(link);
|
||||
}
|
||||
|
||||
static int btuart_suspend(struct pcmcia_device *dev)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(dev);
|
||||
|
||||
link->state |= DEV_SUSPEND;
|
||||
if (link->state & DEV_CONFIG)
|
||||
pcmcia_release_configuration(link->handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int btuart_resume(struct pcmcia_device *dev)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(dev);
|
||||
|
||||
link->state &= ~DEV_SUSPEND;
|
||||
if (DEV_OK(link))
|
||||
pcmcia_request_configuration(link->handle, &link->conf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct pcmcia_device_id btuart_ids[] = {
|
||||
/* 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);
|
||||
dtl1_close(info);
|
||||
|
||||
link->dev = NULL;
|
||||
|
||||
pcmcia_release_configuration(link->handle);
|
||||
pcmcia_release_io(link->handle, &link->io);
|
||||
pcmcia_release_irq(link->handle, &link->irq);
|
||||
|
||||
link->state &= ~DEV_CONFIG;
|
||||
}
|
||||
|
||||
static int dtl1_suspend(struct pcmcia_device *dev)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(dev);
|
||||
|
||||
link->state |= DEV_SUSPEND;
|
||||
if (link->state & DEV_CONFIG)
|
||||
pcmcia_release_configuration(link->handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dtl1_resume(struct pcmcia_device *dev)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(dev);
|
||||
|
||||
link->state &= ~DEV_SUSPEND;
|
||||
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;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
if (debug_level >= DEBUG_LEVEL_INFO)
|
||||
printk("mgslpc_release(0x%p)\n", link);
|
||||
|
||||
/* Unlink the device chain */
|
||||
link->dev = NULL;
|
||||
link->state &= ~DEV_CONFIG;
|
||||
|
||||
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);
|
||||
((MGSLPC_INFO *)link->priv)->stop = 1;
|
||||
mgslpc_release((u_long)link);
|
||||
|
||||
if (link->state & DEV_CONFIG) {
|
||||
((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);
|
||||
((local_info_t *)link->priv)->stop = 1;
|
||||
sedlbauer_release(link);
|
||||
|
||||
if (link->state & DEV_CONFIG) {
|
||||
((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;
|
||||
local_info_t *info = link->priv;
|
||||
|
||||
DEBUG(0, "teles_detach(0x%p)\n", link);
|
||||
DEBUG(0, "teles_detach(0x%p)\n", link);
|
||||
|
||||
if (link->state & DEV_CONFIG) {
|
||||
info->busy = 1;
|
||||
teles_cs_release(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,
|
||||
|
|
|
@ -86,8 +86,8 @@ static char *version =
|
|||
|
||||
/*====================================================================*/
|
||||
|
||||
static void axnet_config(dev_link_t *link);
|
||||
static void axnet_release(dev_link_t *link);
|
||||
static int axnet_config(struct pcmcia_device *link);
|
||||
static void axnet_release(struct pcmcia_device *link);
|
||||
static int axnet_open(struct net_device *dev);
|
||||
static int axnet_close(struct net_device *dev);
|
||||
static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
|
||||
|
@ -117,7 +117,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id, struct pt_regs *regs);
|
|||
/*====================================================================*/
|
||||
|
||||
typedef struct axnet_dev_t {
|
||||
dev_link_t link;
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
caddr_t base;
|
||||
struct timer_list watchdog;
|
||||
|
@ -142,10 +142,9 @@ static inline axnet_dev_t *PRIV(struct net_device *dev)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static int axnet_attach(struct pcmcia_device *p_dev)
|
||||
static int axnet_probe(struct pcmcia_device *link)
|
||||
{
|
||||
axnet_dev_t *info;
|
||||
dev_link_t *link;
|
||||
struct net_device *dev;
|
||||
|
||||
DEBUG(0, "axnet_attach()\n");
|
||||
|
@ -157,7 +156,7 @@ static int axnet_attach(struct pcmcia_device *p_dev)
|
|||
return -ENOMEM;
|
||||
|
||||
info = PRIV(dev);
|
||||
link = &info->link;
|
||||
info->p_dev = link;
|
||||
link->priv = dev;
|
||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
|
@ -169,13 +168,7 @@ static int axnet_attach(struct pcmcia_device *p_dev)
|
|||
dev->do_ioctl = &axnet_ioctl;
|
||||
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
|
||||
|
||||
link->handle = p_dev;
|
||||
p_dev->instance = link;
|
||||
|
||||
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
|
||||
axnet_config(link);
|
||||
|
||||
return 0;
|
||||
return axnet_config(link);
|
||||
} /* axnet_attach */
|
||||
|
||||
/*======================================================================
|
||||
|
@ -187,18 +180,16 @@ static int axnet_attach(struct pcmcia_device *p_dev)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static void axnet_detach(struct pcmcia_device *p_dev)
|
||||
static void axnet_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
DEBUG(0, "axnet_detach(0x%p)\n", link);
|
||||
|
||||
if (link->dev)
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
||||
if (link->state & DEV_CONFIG)
|
||||
axnet_release(link);
|
||||
axnet_release(link);
|
||||
|
||||
free_netdev(dev);
|
||||
} /* axnet_detach */
|
||||
|
@ -209,7 +200,7 @@ static void axnet_detach(struct pcmcia_device *p_dev)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static int get_prom(dev_link_t *link)
|
||||
static int get_prom(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
kio_addr_t ioaddr = dev->base_addr;
|
||||
|
@ -263,7 +254,7 @@ static int get_prom(dev_link_t *link)
|
|||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static int try_io_port(dev_link_t *link)
|
||||
static int try_io_port(struct pcmcia_device *link)
|
||||
{
|
||||
int j, ret;
|
||||
if (link->io.NumPorts1 == 32) {
|
||||
|
@ -284,25 +275,23 @@ static int try_io_port(dev_link_t *link)
|
|||
for (j = 0; j < 0x400; j += 0x20) {
|
||||
link->io.BasePort1 = j ^ 0x300;
|
||||
link->io.BasePort2 = (j ^ 0x300) + 0x10;
|
||||
ret = pcmcia_request_io(link->handle, &link->io);
|
||||
ret = pcmcia_request_io(link, &link->io);
|
||||
if (ret == CS_SUCCESS) return ret;
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
return pcmcia_request_io(link->handle, &link->io);
|
||||
return pcmcia_request_io(link, &link->io);
|
||||
}
|
||||
}
|
||||
|
||||
static void axnet_config(dev_link_t *link)
|
||||
static int axnet_config(struct pcmcia_device *link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
struct net_device *dev = link->priv;
|
||||
axnet_dev_t *info = PRIV(dev);
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
int i, j, last_ret, last_fn;
|
||||
u_short buf[64];
|
||||
config_info_t conf;
|
||||
|
||||
DEBUG(0, "axnet_config(0x%p)\n", link);
|
||||
|
||||
|
@ -311,29 +300,22 @@ static void axnet_config(dev_link_t *link)
|
|||
tuple.TupleDataMax = sizeof(buf);
|
||||
tuple.TupleOffset = 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, &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;
|
||||
/* don't trust the CIS on this; Linksys got it wrong */
|
||||
link->conf.Present = 0x63;
|
||||
|
||||
/* Configure card */
|
||||
link->state |= DEV_CONFIG;
|
||||
|
||||
/* Look up current Vcc */
|
||||
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
|
||||
link->conf.Vcc = conf.Vcc;
|
||||
|
||||
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 (last_ret == CS_SUCCESS) {
|
||||
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
|
||||
cistpl_io_t *io = &(parse.cftable_entry.io);
|
||||
|
||||
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 ||
|
||||
cfg->index == 0 || cfg->io.nwin == 0)
|
||||
goto next_entry;
|
||||
|
||||
|
@ -355,21 +337,21 @@ static void axnet_config(dev_link_t *link)
|
|||
if (last_ret == CS_SUCCESS) break;
|
||||
}
|
||||
next_entry:
|
||||
last_ret = pcmcia_get_next_tuple(handle, &tuple);
|
||||
last_ret = pcmcia_get_next_tuple(link, &tuple);
|
||||
}
|
||||
if (last_ret != CS_SUCCESS) {
|
||||
cs_error(handle, RequestIO, last_ret);
|
||||
cs_error(link, RequestIO, last_ret);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq));
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
|
||||
if (link->io.NumPorts2 == 8) {
|
||||
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||
link->conf.Status = CCSR_AUDIO_ENA;
|
||||
}
|
||||
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
|
||||
|
@ -406,7 +388,7 @@ static void axnet_config(dev_link_t *link)
|
|||
Bit 2 of CCSR is active low. */
|
||||
if (i == 32) {
|
||||
conf_reg_t reg = { 0, CS_WRITE, CISREG_CCSR, 0x04 };
|
||||
pcmcia_access_configuration_register(link->handle, ®);
|
||||
pcmcia_access_configuration_register(link, ®);
|
||||
for (i = 0; i < 32; i++) {
|
||||
j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1);
|
||||
if ((j != 0) && (j != 0xffff)) break;
|
||||
|
@ -414,13 +396,12 @@ static void axnet_config(dev_link_t *link)
|
|||
}
|
||||
|
||||
info->phy_id = (i < 32) ? i : -1;
|
||||
link->dev = &info->node;
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(handle));
|
||||
link->dev_node = &info->node;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
|
||||
if (register_netdev(dev) != 0) {
|
||||
printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n");
|
||||
link->dev = NULL;
|
||||
link->dev_node = NULL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@ -436,14 +417,13 @@ static void axnet_config(dev_link_t *link)
|
|||
} else {
|
||||
printk(KERN_NOTICE " No MII transceivers found!\n");
|
||||
}
|
||||
return;
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
axnet_release(link);
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
return;
|
||||
return -ENODEV;
|
||||
} /* axnet_config */
|
||||
|
||||
/*======================================================================
|
||||
|
@ -454,45 +434,29 @@ static void axnet_config(dev_link_t *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static void axnet_release(dev_link_t *link)
|
||||
static void axnet_release(struct pcmcia_device *link)
|
||||
{
|
||||
DEBUG(0, "axnet_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 axnet_suspend(struct pcmcia_device *p_dev)
|
||||
static int axnet_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 axnet_resume(struct pcmcia_device *p_dev)
|
||||
static int axnet_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) {
|
||||
axnet_reset_8390(dev);
|
||||
AX88190_init(dev, 1);
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
if (link->open) {
|
||||
axnet_reset_8390(dev);
|
||||
AX88190_init(dev, 1);
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -562,11 +526,11 @@ static void mdio_write(kio_addr_t addr, int phy_id, int loc, int value)
|
|||
static int axnet_open(struct net_device *dev)
|
||||
{
|
||||
axnet_dev_t *info = PRIV(dev);
|
||||
dev_link_t *link = &info->link;
|
||||
struct pcmcia_device *link = info->p_dev;
|
||||
|
||||
DEBUG(2, "axnet_open('%s')\n", dev->name);
|
||||
|
||||
if (!DEV_OK(link))
|
||||
if (!pcmcia_dev_present(link))
|
||||
return -ENODEV;
|
||||
|
||||
link->open++;
|
||||
|
@ -588,7 +552,7 @@ static int axnet_open(struct net_device *dev)
|
|||
static int axnet_close(struct net_device *dev)
|
||||
{
|
||||
axnet_dev_t *info = PRIV(dev);
|
||||
dev_link_t *link = &info->link;
|
||||
struct pcmcia_device *link = info->p_dev;
|
||||
|
||||
DEBUG(2, "axnet_close('%s')\n", dev->name);
|
||||
|
||||
|
@ -833,7 +797,7 @@ static struct pcmcia_driver axnet_cs_driver = {
|
|||
.drv = {
|
||||
.name = "axnet_cs",
|
||||
},
|
||||
.probe = axnet_attach,
|
||||
.probe = axnet_probe,
|
||||
.remove = axnet_detach,
|
||||
.id_table = axnet_ids,
|
||||
.suspend = axnet_suspend,
|
||||
|
|
|
@ -118,8 +118,8 @@ MODULE_LICENSE("GPL");
|
|||
|
||||
/*====================================================================*/
|
||||
|
||||
static void com20020_config(dev_link_t *link);
|
||||
static void com20020_release(dev_link_t *link);
|
||||
static int com20020_config(struct pcmcia_device *link);
|
||||
static void com20020_release(struct pcmcia_device *link);
|
||||
|
||||
static void com20020_detach(struct pcmcia_device *p_dev);
|
||||
|
||||
|
@ -138,9 +138,8 @@ typedef struct com20020_dev_t {
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static int com20020_attach(struct pcmcia_device *p_dev)
|
||||
static int com20020_probe(struct pcmcia_device *p_dev)
|
||||
{
|
||||
dev_link_t *link;
|
||||
com20020_dev_t *info;
|
||||
struct net_device *dev;
|
||||
struct arcnet_local *lp;
|
||||
|
@ -148,10 +147,6 @@ static int com20020_attach(struct pcmcia_device *p_dev)
|
|||
DEBUG(0, "com20020_attach()\n");
|
||||
|
||||
/* Create new network device */
|
||||
link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
|
||||
if (!link)
|
||||
return -ENOMEM;
|
||||
|
||||
info = kmalloc(sizeof(struct com20020_dev_t), GFP_KERNEL);
|
||||
if (!info)
|
||||
goto fail_alloc_info;
|
||||
|
@ -161,7 +156,6 @@ static int com20020_attach(struct pcmcia_device *p_dev)
|
|||
goto fail_alloc_dev;
|
||||
|
||||
memset(info, 0, sizeof(struct com20020_dev_t));
|
||||
memset(link, 0, sizeof(struct dev_link_t));
|
||||
lp = dev->priv;
|
||||
lp->timeout = timeout;
|
||||
lp->backplane = backplane;
|
||||
|
@ -172,28 +166,23 @@ static int com20020_attach(struct pcmcia_device *p_dev)
|
|||
/* fill in our module parameters as defaults */
|
||||
dev->dev_addr[0] = node;
|
||||
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
link->io.NumPorts1 = 16;
|
||||
link->io.IOAddrLines = 16;
|
||||
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->conf.Present = PRESENT_OPTION;
|
||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
p_dev->io.NumPorts1 = 16;
|
||||
p_dev->io.IOAddrLines = 16;
|
||||
p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
p_dev->conf.IntType = INT_MEMORY_AND_IO;
|
||||
p_dev->conf.Present = PRESENT_OPTION;
|
||||
|
||||
link->irq.Instance = info->dev = dev;
|
||||
link->priv = info;
|
||||
p_dev->irq.Instance = info->dev = dev;
|
||||
p_dev->priv = info;
|
||||
|
||||
link->state |= DEV_PRESENT;
|
||||
com20020_config(link);
|
||||
|
||||
return 0;
|
||||
return com20020_config(p_dev);
|
||||
|
||||
fail_alloc_dev:
|
||||
kfree(info);
|
||||
fail_alloc_info:
|
||||
kfree(link);
|
||||
return -ENOMEM;
|
||||
} /* com20020_attach */
|
||||
|
||||
|
@ -206,9 +195,8 @@ static int com20020_attach(struct pcmcia_device *p_dev)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static void com20020_detach(struct pcmcia_device *p_dev)
|
||||
static void com20020_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct com20020_dev_t *info = link->priv;
|
||||
struct net_device *dev = info->dev;
|
||||
|
||||
|
@ -216,7 +204,7 @@ static void com20020_detach(struct pcmcia_device *p_dev)
|
|||
|
||||
DEBUG(0, "com20020_detach(0x%p)\n", link);
|
||||
|
||||
if (link->dev) {
|
||||
if (link->dev_node) {
|
||||
DEBUG(1,"unregister...\n");
|
||||
|
||||
unregister_netdev(dev);
|
||||
|
@ -229,8 +217,7 @@ static void com20020_detach(struct pcmcia_device *p_dev)
|
|||
free_irq(dev->irq, dev);
|
||||
}
|
||||
|
||||
if (link->state & DEV_CONFIG)
|
||||
com20020_release(link);
|
||||
com20020_release(link);
|
||||
|
||||
/* Unlink device structure, free bits */
|
||||
DEBUG(1,"unlinking...\n");
|
||||
|
@ -245,8 +232,6 @@ static void com20020_detach(struct pcmcia_device *p_dev)
|
|||
DEBUG(1,"kfree2...\n");
|
||||
kfree(info);
|
||||
}
|
||||
DEBUG(1,"kfree3...\n");
|
||||
kfree(link);
|
||||
|
||||
} /* com20020_detach */
|
||||
|
||||
|
@ -261,10 +246,9 @@ static void com20020_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 com20020_config(dev_link_t *link)
|
||||
static int com20020_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct arcnet_local *lp;
|
||||
client_handle_t handle;
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
com20020_dev_t *info;
|
||||
|
@ -273,7 +257,6 @@ static void com20020_config(dev_link_t *link)
|
|||
u_char buf[64];
|
||||
int ioaddr;
|
||||
|
||||
handle = link->handle;
|
||||
info = link->priv;
|
||||
dev = info->dev;
|
||||
|
||||
|
@ -286,14 +269,11 @@ static void com20020_config(dev_link_t *link)
|
|||
tuple.TupleDataMax = 64;
|
||||
tuple.TupleOffset = 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, &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;
|
||||
|
||||
/* Configure card */
|
||||
link->state |= DEV_CONFIG;
|
||||
|
||||
DEBUG(1,"arcnet: baseport1 is %Xh\n", link->io.BasePort1);
|
||||
i = !CS_SUCCESS;
|
||||
if (!link->io.BasePort1)
|
||||
|
@ -301,13 +281,13 @@ static void com20020_config(dev_link_t *link)
|
|||
for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x10)
|
||||
{
|
||||
link->io.BasePort1 = ioaddr;
|
||||
i = pcmcia_request_io(link->handle, &link->io);
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
if (i == CS_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
i = pcmcia_request_io(link->handle, &link->io);
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
|
||||
if (i != CS_SUCCESS)
|
||||
{
|
||||
|
@ -321,7 +301,7 @@ static void com20020_config(dev_link_t *link)
|
|||
DEBUG(1,"arcnet: request IRQ %d (%Xh/%Xh)\n",
|
||||
link->irq.AssignedIRQ,
|
||||
link->irq.IRQInfo1, link->irq.IRQInfo2);
|
||||
i = pcmcia_request_irq(link->handle, &link->irq);
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != CS_SUCCESS)
|
||||
{
|
||||
DEBUG(1,"arcnet: requestIRQ failed totally!\n");
|
||||
|
@ -330,7 +310,7 @@ static void com20020_config(dev_link_t *link)
|
|||
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
|
||||
if (com20020_check(dev))
|
||||
{
|
||||
|
@ -342,15 +322,14 @@ static void com20020_config(dev_link_t *link)
|
|||
lp->card_name = "PCMCIA COM20020";
|
||||
lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
|
||||
|
||||
link->dev = &info->node;
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(handle));
|
||||
link->dev_node = &info->node;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
|
||||
i = com20020_found(dev, 0); /* calls register_netdev */
|
||||
|
||||
if (i != 0) {
|
||||
DEBUG(1,KERN_NOTICE "com20020_cs: com20020_found() failed\n");
|
||||
link->dev = NULL;
|
||||
link->dev_node = NULL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@ -358,13 +337,14 @@ static void com20020_config(dev_link_t *link)
|
|||
|
||||
DEBUG(1,KERN_INFO "%s: port %#3lx, irq %d\n",
|
||||
dev->name, dev->base_addr, dev->irq);
|
||||
return;
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
DEBUG(1,"com20020_config failed...\n");
|
||||
com20020_release(link);
|
||||
return -ENODEV;
|
||||
} /* com20020_config */
|
||||
|
||||
/*======================================================================
|
||||
|
@ -375,52 +355,33 @@ static void com20020_config(dev_link_t *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static void com20020_release(dev_link_t *link)
|
||||
static void com20020_release(struct pcmcia_device *link)
|
||||
{
|
||||
|
||||
DEBUG(1,"release...\n");
|
||||
|
||||
DEBUG(0, "com20020_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 | DEV_RELEASE_PENDING);
|
||||
DEBUG(0, "com20020_release(0x%p)\n", link);
|
||||
pcmcia_disable_device(link);
|
||||
}
|
||||
|
||||
static int com20020_suspend(struct pcmcia_device *p_dev)
|
||||
static int com20020_suspend(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
com20020_dev_t *info = link->priv;
|
||||
struct net_device *dev = info->dev;
|
||||
|
||||
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 com20020_resume(struct pcmcia_device *p_dev)
|
||||
static int com20020_resume(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
com20020_dev_t *info = link->priv;
|
||||
struct net_device *dev = info->dev;
|
||||
|
||||
link->state &= ~DEV_SUSPEND;
|
||||
if (link->state & DEV_CONFIG) {
|
||||
pcmcia_request_configuration(link->handle, &link->conf);
|
||||
if (link->open) {
|
||||
int ioaddr = dev->base_addr;
|
||||
struct arcnet_local *lp = dev->priv;
|
||||
ARCRESET;
|
||||
}
|
||||
}
|
||||
if (link->open) {
|
||||
int ioaddr = dev->base_addr;
|
||||
struct arcnet_local *lp = dev->priv;
|
||||
ARCRESET;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -436,7 +397,7 @@ static struct pcmcia_driver com20020_cs_driver = {
|
|||
.drv = {
|
||||
.name = "com20020_cs",
|
||||
},
|
||||
.probe = com20020_attach,
|
||||
.probe = com20020_probe,
|
||||
.remove = com20020_detach,
|
||||
.id_table = com20020_ids,
|
||||
.suspend = com20020_suspend,
|
||||
|
|
|
@ -84,10 +84,10 @@ static char *version = DRV_NAME ".c " DRV_VERSION " 2002/03/23";
|
|||
/*
|
||||
PCMCIA event handlers
|
||||
*/
|
||||
static void fmvj18x_config(dev_link_t *link);
|
||||
static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id);
|
||||
static int fmvj18x_setup_mfc(dev_link_t *link);
|
||||
static void fmvj18x_release(dev_link_t *link);
|
||||
static int fmvj18x_config(struct pcmcia_device *link);
|
||||
static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id);
|
||||
static int fmvj18x_setup_mfc(struct pcmcia_device *link);
|
||||
static void fmvj18x_release(struct pcmcia_device *link);
|
||||
static void fmvj18x_detach(struct pcmcia_device *p_dev);
|
||||
|
||||
/*
|
||||
|
@ -116,7 +116,7 @@ typedef enum { MBH10302, MBH10304, TDK, CONTEC, LA501, UNGERMANN,
|
|||
driver specific data structure
|
||||
*/
|
||||
typedef struct local_info_t {
|
||||
dev_link_t link;
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
struct net_device_stats stats;
|
||||
long open_time;
|
||||
|
@ -228,10 +228,9 @@ typedef struct local_info_t {
|
|||
#define BANK_1U 0x24 /* bank 1 (CONFIG_1) */
|
||||
#define BANK_2U 0x28 /* bank 2 (CONFIG_1) */
|
||||
|
||||
static int fmvj18x_attach(struct pcmcia_device *p_dev)
|
||||
static int fmvj18x_probe(struct pcmcia_device *link)
|
||||
{
|
||||
local_info_t *lp;
|
||||
dev_link_t *link;
|
||||
struct net_device *dev;
|
||||
|
||||
DEBUG(0, "fmvj18x_attach()\n");
|
||||
|
@ -241,8 +240,8 @@ static int fmvj18x_attach(struct pcmcia_device *p_dev)
|
|||
if (!dev)
|
||||
return -ENOMEM;
|
||||
lp = netdev_priv(dev);
|
||||
link = &lp->link;
|
||||
link->priv = dev;
|
||||
lp->p_dev = link;
|
||||
|
||||
/* The io structure describes IO port mapping */
|
||||
link->io.NumPorts1 = 32;
|
||||
|
@ -257,7 +256,6 @@ static int fmvj18x_attach(struct pcmcia_device *p_dev)
|
|||
|
||||
/* General socket configuration */
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.Vcc = 50;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
/* The FMVJ18x specific entries in the device structure. */
|
||||
|
@ -274,29 +272,21 @@ static int fmvj18x_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;
|
||||
fmvj18x_config(link);
|
||||
|
||||
return 0;
|
||||
return fmvj18x_config(link);
|
||||
} /* fmvj18x_attach */
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
static void fmvj18x_detach(struct pcmcia_device *p_dev)
|
||||
static void fmvj18x_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
DEBUG(0, "fmvj18x_detach(0x%p)\n", link);
|
||||
|
||||
if (link->dev)
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
||||
if (link->state & DEV_CONFIG)
|
||||
fmvj18x_release(link);
|
||||
fmvj18x_release(link);
|
||||
|
||||
free_netdev(dev);
|
||||
} /* fmvj18x_detach */
|
||||
|
@ -306,7 +296,7 @@ static void fmvj18x_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 int mfc_try_io_port(dev_link_t *link)
|
||||
static int mfc_try_io_port(struct pcmcia_device *link)
|
||||
{
|
||||
int i, ret;
|
||||
static const kio_addr_t serial_base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
|
||||
|
@ -318,13 +308,13 @@ static int mfc_try_io_port(dev_link_t *link)
|
|||
link->io.NumPorts2 = 0;
|
||||
printk(KERN_NOTICE "fmvj18x_cs: out of resource for serial\n");
|
||||
}
|
||||
ret = pcmcia_request_io(link->handle, &link->io);
|
||||
ret = pcmcia_request_io(link, &link->io);
|
||||
if (ret == CS_SUCCESS) return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ungermann_try_io_port(dev_link_t *link)
|
||||
static int ungermann_try_io_port(struct pcmcia_device *link)
|
||||
{
|
||||
int ret;
|
||||
kio_addr_t ioaddr;
|
||||
|
@ -334,7 +324,7 @@ static int ungermann_try_io_port(dev_link_t *link)
|
|||
*/
|
||||
for (ioaddr = 0x300; ioaddr < 0x3e0; ioaddr += 0x20) {
|
||||
link->io.BasePort1 = ioaddr;
|
||||
ret = pcmcia_request_io(link->handle, &link->io);
|
||||
ret = pcmcia_request_io(link, &link->io);
|
||||
if (ret == CS_SUCCESS) {
|
||||
/* calculate ConfigIndex value */
|
||||
link->conf.ConfigIndex =
|
||||
|
@ -345,9 +335,8 @@ static int ungermann_try_io_port(dev_link_t *link)
|
|||
return ret; /* RequestIO failed */
|
||||
}
|
||||
|
||||
static void fmvj18x_config(dev_link_t *link)
|
||||
static int fmvj18x_config(struct pcmcia_device *link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
struct net_device *dev = link->priv;
|
||||
local_info_t *lp = netdev_priv(dev);
|
||||
tuple_t tuple;
|
||||
|
@ -366,42 +355,34 @@ static void fmvj18x_config(dev_link_t *link)
|
|||
registers.
|
||||
*/
|
||||
tuple.DesiredTuple = CISTPL_CONFIG;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
tuple.TupleData = (u_char *)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));
|
||||
|
||||
/* Configure card */
|
||||
link->state |= DEV_CONFIG;
|
||||
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];
|
||||
|
||||
tuple.DesiredTuple = CISTPL_FUNCE;
|
||||
tuple.TupleOffset = 0;
|
||||
if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) {
|
||||
if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) {
|
||||
/* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
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.ConfigIndex = parse.cftable_entry.index;
|
||||
tuple.DesiredTuple = CISTPL_MANFID;
|
||||
if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS)
|
||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
|
||||
if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS)
|
||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
|
||||
else
|
||||
buf[0] = 0xffff;
|
||||
switch (le16_to_cpu(buf[0])) {
|
||||
case MANFID_TDK:
|
||||
cardtype = TDK;
|
||||
if (le16_to_cpu(buf[1]) == PRODID_TDK_CF010) {
|
||||
cs_status_t status;
|
||||
pcmcia_get_status(handle, &status);
|
||||
if (status.CardState & CS_EVENT_3VCARD)
|
||||
link->conf.Vcc = 33; /* inserted in 3.3V slot */
|
||||
} else if (le16_to_cpu(buf[1]) == PRODID_TDK_GN3410
|
||||
if (le16_to_cpu(buf[1]) == PRODID_TDK_GN3410
|
||||
|| le16_to_cpu(buf[1]) == PRODID_TDK_NP9610
|
||||
|| le16_to_cpu(buf[1]) == PRODID_TDK_MN3200) {
|
||||
/* MultiFunction Card */
|
||||
|
@ -429,8 +410,8 @@ static void fmvj18x_config(dev_link_t *link)
|
|||
} else {
|
||||
/* old type card */
|
||||
tuple.DesiredTuple = CISTPL_MANFID;
|
||||
if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS)
|
||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
|
||||
if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS)
|
||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
|
||||
else
|
||||
buf[0] = 0xffff;
|
||||
switch (le16_to_cpu(buf[0])) {
|
||||
|
@ -461,10 +442,10 @@ static void fmvj18x_config(dev_link_t *link)
|
|||
ret = ungermann_try_io_port(link);
|
||||
if (ret != CS_SUCCESS) goto cs_failed;
|
||||
} else {
|
||||
CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io));
|
||||
CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
|
||||
}
|
||||
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;
|
||||
|
||||
|
@ -493,17 +474,17 @@ static void fmvj18x_config(dev_link_t *link)
|
|||
case CONTEC:
|
||||
tuple.DesiredTuple = CISTPL_FUNCE;
|
||||
tuple.TupleOffset = 0;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
tuple.TupleOffset = 0;
|
||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
|
||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
|
||||
if (cardtype == MBH10304) {
|
||||
/* MBH10304's CIS_FUNCE is corrupted */
|
||||
node_id = &(tuple.TupleData[5]);
|
||||
card_name = "FMV-J182";
|
||||
} else {
|
||||
while (tuple.TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID ) {
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
|
||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
|
||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
|
||||
}
|
||||
node_id = &(tuple.TupleData[2]);
|
||||
if( cardtype == TDK ) {
|
||||
|
@ -545,13 +526,12 @@ static void fmvj18x_config(dev_link_t *link)
|
|||
}
|
||||
|
||||
lp->cardtype = cardtype;
|
||||
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_NOTICE "fmvj18x_cs: register_netdev() failed\n");
|
||||
link->dev = NULL;
|
||||
link->dev_node = NULL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@ -564,19 +544,18 @@ static void fmvj18x_config(dev_link_t *link)
|
|||
for (i = 0; i < 6; i++)
|
||||
printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
|
||||
|
||||
return;
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
/* All Card Services errors end up here */
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
fmvj18x_release(link);
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
|
||||
return -ENODEV;
|
||||
} /* fmvj18x_config */
|
||||
/*====================================================================*/
|
||||
|
||||
static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id)
|
||||
static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)
|
||||
{
|
||||
win_req_t req;
|
||||
memreq_t mem;
|
||||
|
@ -587,9 +566,9 @@ static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id)
|
|||
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
||||
req.Base = 0; req.Size = 0;
|
||||
req.AccessSpeed = 0;
|
||||
i = pcmcia_request_window(&link->handle, &req, &link->win);
|
||||
i = pcmcia_request_window(&link, &req, &link->win);
|
||||
if (i != CS_SUCCESS) {
|
||||
cs_error(link->handle, RequestWindow, i);
|
||||
cs_error(link, RequestWindow, i);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -623,13 +602,13 @@ static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id)
|
|||
iounmap(base);
|
||||
j = pcmcia_release_window(link->win);
|
||||
if (j != CS_SUCCESS)
|
||||
cs_error(link->handle, ReleaseWindow, j);
|
||||
cs_error(link, ReleaseWindow, j);
|
||||
return (i != 0x200) ? 0 : -1;
|
||||
|
||||
} /* fmvj18x_get_hwinfo */
|
||||
/*====================================================================*/
|
||||
|
||||
static int fmvj18x_setup_mfc(dev_link_t *link)
|
||||
static int fmvj18x_setup_mfc(struct pcmcia_device *link)
|
||||
{
|
||||
win_req_t req;
|
||||
memreq_t mem;
|
||||
|
@ -642,9 +621,9 @@ static int fmvj18x_setup_mfc(dev_link_t *link)
|
|||
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
||||
req.Base = 0; req.Size = 0;
|
||||
req.AccessSpeed = 0;
|
||||
i = pcmcia_request_window(&link->handle, &req, &link->win);
|
||||
i = pcmcia_request_window(&link, &req, &link->win);
|
||||
if (i != CS_SUCCESS) {
|
||||
cs_error(link->handle, RequestWindow, i);
|
||||
cs_error(link, RequestWindow, i);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -666,54 +645,35 @@ static int fmvj18x_setup_mfc(dev_link_t *link)
|
|||
iounmap(base);
|
||||
j = pcmcia_release_window(link->win);
|
||||
if (j != CS_SUCCESS)
|
||||
cs_error(link->handle, ReleaseWindow, j);
|
||||
cs_error(link, ReleaseWindow, j);
|
||||
return 0;
|
||||
|
||||
}
|
||||
/*====================================================================*/
|
||||
|
||||
static void fmvj18x_release(dev_link_t *link)
|
||||
static void fmvj18x_release(struct pcmcia_device *link)
|
||||
{
|
||||
|
||||
DEBUG(0, "fmvj18x_release(0x%p)\n", link);
|
||||
|
||||
/* Don't bother checking to see if these succeed or not */
|
||||
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;
|
||||
DEBUG(0, "fmvj18x_release(0x%p)\n", link);
|
||||
pcmcia_disable_device(link);
|
||||
}
|
||||
|
||||
static int fmvj18x_suspend(struct pcmcia_device *p_dev)
|
||||
static int fmvj18x_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 fmvj18x_resume(struct pcmcia_device *p_dev)
|
||||
static int fmvj18x_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) {
|
||||
fjn_reset(dev);
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
if (link->open) {
|
||||
fjn_reset(dev);
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -751,7 +711,7 @@ static struct pcmcia_driver fmvj18x_cs_driver = {
|
|||
.drv = {
|
||||
.name = "fmvj18x_cs",
|
||||
},
|
||||
.probe = fmvj18x_attach,
|
||||
.probe = fmvj18x_probe,
|
||||
.remove = fmvj18x_detach,
|
||||
.id_table = fmvj18x_ids,
|
||||
.suspend = fmvj18x_suspend,
|
||||
|
@ -1148,11 +1108,11 @@ static int fjn_config(struct net_device *dev, struct ifmap *map){
|
|||
static int fjn_open(struct net_device *dev)
|
||||
{
|
||||
struct local_info_t *lp = netdev_priv(dev);
|
||||
dev_link_t *link = &lp->link;
|
||||
struct pcmcia_device *link = lp->p_dev;
|
||||
|
||||
DEBUG(4, "fjn_open('%s').\n", dev->name);
|
||||
|
||||
if (!DEV_OK(link))
|
||||
if (!pcmcia_dev_present(link))
|
||||
return -ENODEV;
|
||||
|
||||
link->open++;
|
||||
|
@ -1173,7 +1133,7 @@ static int fjn_open(struct net_device *dev)
|
|||
static int fjn_close(struct net_device *dev)
|
||||
{
|
||||
struct local_info_t *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(4, "fjn_close('%s').\n", dev->name);
|
||||
|
|
|
@ -105,15 +105,15 @@ MODULE_LICENSE("GPL");
|
|||
|
||||
/*====================================================================*/
|
||||
|
||||
static void ibmtr_config(dev_link_t *link);
|
||||
static int ibmtr_config(struct pcmcia_device *link);
|
||||
static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase);
|
||||
static void ibmtr_release(dev_link_t *link);
|
||||
static void ibmtr_release(struct pcmcia_device *link);
|
||||
static void ibmtr_detach(struct pcmcia_device *p_dev);
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
typedef struct ibmtr_dev_t {
|
||||
dev_link_t link;
|
||||
struct pcmcia_device *p_dev;
|
||||
struct net_device *dev;
|
||||
dev_node_t node;
|
||||
window_handle_t sram_win_handle;
|
||||
|
@ -138,12 +138,11 @@ static struct ethtool_ops netdev_ethtool_ops = {
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static int ibmtr_attach(struct pcmcia_device *p_dev)
|
||||
static int ibmtr_attach(struct pcmcia_device *link)
|
||||
{
|
||||
ibmtr_dev_t *info;
|
||||
dev_link_t *link;
|
||||
struct net_device *dev;
|
||||
|
||||
|
||||
DEBUG(0, "ibmtr_attach()\n");
|
||||
|
||||
/* Create new token-ring device */
|
||||
|
@ -156,7 +155,7 @@ static int ibmtr_attach(struct pcmcia_device *p_dev)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
link = &info->link;
|
||||
info->p_dev = link;
|
||||
link->priv = info;
|
||||
info->ti = netdev_priv(dev);
|
||||
|
||||
|
@ -167,21 +166,14 @@ static int ibmtr_attach(struct pcmcia_device *p_dev)
|
|||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->irq.Handler = &tok_interrupt;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.Vcc = 50;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
link->conf.Present = PRESENT_OPTION;
|
||||
|
||||
link->irq.Instance = info->dev = dev;
|
||||
|
||||
|
||||
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
|
||||
|
||||
link->handle = p_dev;
|
||||
p_dev->instance = link;
|
||||
|
||||
link->state |= DEV_PRESENT;
|
||||
ibmtr_config(link);
|
||||
|
||||
return 0;
|
||||
return ibmtr_config(link);
|
||||
} /* ibmtr_attach */
|
||||
|
||||
/*======================================================================
|
||||
|
@ -193,23 +185,22 @@ static int ibmtr_attach(struct pcmcia_device *p_dev)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static void ibmtr_detach(struct pcmcia_device *p_dev)
|
||||
static void ibmtr_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct ibmtr_dev_t *info = link->priv;
|
||||
struct net_device *dev = info->dev;
|
||||
|
||||
DEBUG(0, "ibmtr_detach(0x%p)\n", link);
|
||||
|
||||
if (link->dev)
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
||||
{
|
||||
struct tok_info *ti = netdev_priv(dev);
|
||||
del_timer_sync(&(ti->tr_timer));
|
||||
}
|
||||
if (link->state & DEV_CONFIG)
|
||||
ibmtr_release(link);
|
||||
|
||||
ibmtr_release(link);
|
||||
|
||||
free_netdev(dev);
|
||||
kfree(info);
|
||||
|
@ -226,9 +217,8 @@ static void ibmtr_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 ibmtr_config(dev_link_t *link)
|
||||
static int ibmtr_config(struct pcmcia_device *link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
ibmtr_dev_t *info = link->priv;
|
||||
struct net_device *dev = info->dev;
|
||||
struct tok_info *ti = netdev_priv(dev);
|
||||
|
@ -246,29 +236,25 @@ static void ibmtr_config(dev_link_t *link)
|
|||
tuple.TupleDataMax = 64;
|
||||
tuple.TupleOffset = 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, &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;
|
||||
|
||||
/* Configure card */
|
||||
link->state |= DEV_CONFIG;
|
||||
|
||||
link->conf.ConfigIndex = 0x61;
|
||||
|
||||
/* Determine if this is PRIMARY or ALTERNATE. */
|
||||
|
||||
/* Try PRIMARY card at 0xA20-0xA23 */
|
||||
link->io.BasePort1 = 0xA20;
|
||||
i = pcmcia_request_io(link->handle, &link->io);
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
if (i != CS_SUCCESS) {
|
||||
/* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */
|
||||
link->io.BasePort1 = 0xA24;
|
||||
CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io));
|
||||
CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
|
||||
}
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
ti->irq = link->irq.AssignedIRQ;
|
||||
ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
|
||||
|
@ -279,7 +265,7 @@ static void ibmtr_config(dev_link_t *link)
|
|||
req.Base = 0;
|
||||
req.Size = 0x2000;
|
||||
req.AccessSpeed = 250;
|
||||
CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win));
|
||||
CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
|
||||
|
||||
mem.CardOffset = mmiobase;
|
||||
mem.Page = 0;
|
||||
|
@ -292,7 +278,7 @@ static void ibmtr_config(dev_link_t *link)
|
|||
req.Base = 0;
|
||||
req.Size = sramsize * 1024;
|
||||
req.AccessSpeed = 250;
|
||||
CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &info->sram_win_handle));
|
||||
CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &info->sram_win_handle));
|
||||
|
||||
mem.CardOffset = srambase;
|
||||
mem.Page = 0;
|
||||
|
@ -302,21 +288,20 @@ static void ibmtr_config(dev_link_t *link)
|
|||
ti->sram_virt = ioremap(req.Base, req.Size);
|
||||
ti->sram_phys = req.Base;
|
||||
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
|
||||
/* Set up the Token-Ring Controller Configuration Register and
|
||||
turn on the card. Check the "Local Area Network Credit Card
|
||||
Adapters Technical Reference" SC30-3585 for this info. */
|
||||
ibmtr_hw_setup(dev, mmiobase);
|
||||
|
||||
link->dev = &info->node;
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(handle));
|
||||
link->dev_node = &info->node;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
|
||||
i = ibmtr_probe_card(dev);
|
||||
if (i != 0) {
|
||||
printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n");
|
||||
link->dev = NULL;
|
||||
link->dev_node = NULL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@ -330,12 +315,13 @@ static void ibmtr_config(dev_link_t *link)
|
|||
for (i = 0; i < TR_ALEN; i++)
|
||||
printk("%02X", dev->dev_addr[i]);
|
||||
printk("\n");
|
||||
return;
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
ibmtr_release(link);
|
||||
return -ENODEV;
|
||||
} /* ibmtr_config */
|
||||
|
||||
/*======================================================================
|
||||
|
@ -346,56 +332,41 @@ static void ibmtr_config(dev_link_t *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static void ibmtr_release(dev_link_t *link)
|
||||
static void ibmtr_release(struct pcmcia_device *link)
|
||||
{
|
||||
ibmtr_dev_t *info = link->priv;
|
||||
struct net_device *dev = info->dev;
|
||||
|
||||
DEBUG(0, "ibmtr_release(0x%p)\n", link);
|
||||
|
||||
pcmcia_release_configuration(link->handle);
|
||||
pcmcia_release_io(link->handle, &link->io);
|
||||
pcmcia_release_irq(link->handle, &link->irq);
|
||||
if (link->win) {
|
||||
struct tok_info *ti = netdev_priv(dev);
|
||||
iounmap(ti->mmio);
|
||||
pcmcia_release_window(link->win);
|
||||
pcmcia_release_window(info->sram_win_handle);
|
||||
}
|
||||
|
||||
link->state &= ~DEV_CONFIG;
|
||||
}
|
||||
|
||||
static int ibmtr_suspend(struct pcmcia_device *p_dev)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
ibmtr_dev_t *info = link->priv;
|
||||
struct net_device *dev = info->dev;
|
||||
|
||||
link->state |= DEV_SUSPEND;
|
||||
if (link->state & DEV_CONFIG) {
|
||||
if (link->open)
|
||||
netif_device_detach(dev);
|
||||
pcmcia_release_configuration(link->handle);
|
||||
}
|
||||
DEBUG(0, "ibmtr_release(0x%p)\n", link);
|
||||
|
||||
if (link->win) {
|
||||
struct tok_info *ti = netdev_priv(dev);
|
||||
iounmap(ti->mmio);
|
||||
pcmcia_release_window(info->sram_win_handle);
|
||||
}
|
||||
pcmcia_disable_device(link);
|
||||
}
|
||||
|
||||
static int ibmtr_suspend(struct pcmcia_device *link)
|
||||
{
|
||||
ibmtr_dev_t *info = link->priv;
|
||||
struct net_device *dev = info->dev;
|
||||
|
||||
if (link->open)
|
||||
netif_device_detach(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ibmtr_resume(struct pcmcia_device *p_dev)
|
||||
static int ibmtr_resume(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
ibmtr_dev_t *info = link->priv;
|
||||
struct net_device *dev = info->dev;
|
||||
|
||||
link->state &= ~DEV_SUSPEND;
|
||||
if (link->state & DEV_CONFIG) {
|
||||
pcmcia_request_configuration(link->handle, &link->conf);
|
||||
if (link->open) {
|
||||
ibmtr_probe(dev); /* really? */
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
}
|
||||
if (link->open) {
|
||||
ibmtr_probe(dev); /* really? */
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -362,7 +362,7 @@ typedef struct _mace_statistics {
|
|||
} mace_statistics;
|
||||
|
||||
typedef struct _mace_private {
|
||||
dev_link_t link;
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
struct net_device_stats linux_stats; /* Linux statistics counters */
|
||||
mace_statistics mace_stats; /* MACE chip statistics counters */
|
||||
|
@ -417,8 +417,8 @@ INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
|
|||
Function Prototypes
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
static void nmclan_config(dev_link_t *link);
|
||||
static void nmclan_release(dev_link_t *link);
|
||||
static int nmclan_config(struct pcmcia_device *link);
|
||||
static void nmclan_release(struct pcmcia_device *link);
|
||||
|
||||
static void nmclan_reset(struct net_device *dev);
|
||||
static int mace_config(struct net_device *dev, struct ifmap *map);
|
||||
|
@ -443,10 +443,9 @@ nmclan_attach
|
|||
Services.
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
static int nmclan_attach(struct pcmcia_device *p_dev)
|
||||
static int nmclan_probe(struct pcmcia_device *link)
|
||||
{
|
||||
mace_private *lp;
|
||||
dev_link_t *link;
|
||||
struct net_device *dev;
|
||||
|
||||
DEBUG(0, "nmclan_attach()\n");
|
||||
|
@ -457,7 +456,7 @@ static int nmclan_attach(struct pcmcia_device *p_dev)
|
|||
if (!dev)
|
||||
return -ENOMEM;
|
||||
lp = netdev_priv(dev);
|
||||
link = &lp->link;
|
||||
lp->p_dev = link;
|
||||
link->priv = dev;
|
||||
|
||||
spin_lock_init(&lp->bank_lock);
|
||||
|
@ -469,7 +468,6 @@ static int nmclan_attach(struct pcmcia_device *p_dev)
|
|||
link->irq.Handler = &mace_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;
|
||||
|
@ -489,13 +487,7 @@ static int nmclan_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;
|
||||
nmclan_config(link);
|
||||
|
||||
return 0;
|
||||
return nmclan_config(link);
|
||||
} /* nmclan_attach */
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
|
@ -506,18 +498,16 @@ nmclan_detach
|
|||
when the device is released.
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
static void nmclan_detach(struct pcmcia_device *p_dev)
|
||||
static void nmclan_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
DEBUG(0, "nmclan_detach(0x%p)\n", link);
|
||||
|
||||
if (link->dev)
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
||||
if (link->state & DEV_CONFIG)
|
||||
nmclan_release(link);
|
||||
nmclan_release(link);
|
||||
|
||||
free_netdev(dev);
|
||||
} /* nmclan_detach */
|
||||
|
@ -661,9 +651,8 @@ nmclan_config
|
|||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static void nmclan_config(dev_link_t *link)
|
||||
static int nmclan_config(struct pcmcia_device *link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
struct net_device *dev = link->priv;
|
||||
mace_private *lp = netdev_priv(dev);
|
||||
tuple_t tuple;
|
||||
|
@ -679,17 +668,14 @@ static void nmclan_config(dev_link_t *link)
|
|||
tuple.TupleDataMax = 64;
|
||||
tuple.TupleOffset = 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, &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;
|
||||
|
||||
/* Configure card */
|
||||
link->state |= DEV_CONFIG;
|
||||
|
||||
CS_CHECK(RequestIO, pcmcia_request_io(handle, &link->io));
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
|
||||
CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
|
||||
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;
|
||||
|
||||
|
@ -700,8 +686,8 @@ static void nmclan_config(dev_link_t *link)
|
|||
tuple.TupleData = buf;
|
||||
tuple.TupleDataMax = 64;
|
||||
tuple.TupleOffset = 0;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
|
||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
|
||||
memcpy(dev->dev_addr, tuple.TupleData, ETHER_ADDR_LEN);
|
||||
|
||||
/* Verify configuration by reading the MACE ID. */
|
||||
|
@ -716,8 +702,7 @@ static void nmclan_config(dev_link_t *link)
|
|||
} else {
|
||||
printk(KERN_NOTICE "nmclan_cs: mace id not found: %x %x should"
|
||||
" be 0x40 0x?9\n", sig[0], sig[1]);
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
return;
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -730,14 +715,13 @@ static void nmclan_config(dev_link_t *link)
|
|||
else
|
||||
printk(KERN_NOTICE "nmclan_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));
|
||||
|
||||
i = register_netdev(dev);
|
||||
if (i != 0) {
|
||||
printk(KERN_NOTICE "nmclan_cs: register_netdev() failed\n");
|
||||
link->dev = NULL;
|
||||
link->dev_node = NULL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@ -747,14 +731,13 @@ static void nmclan_config(dev_link_t *link)
|
|||
dev->name, dev->base_addr, dev->irq, if_names[dev->if_port]);
|
||||
for (i = 0; i < 6; i++)
|
||||
printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
|
||||
return;
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
nmclan_release(link);
|
||||
return;
|
||||
|
||||
nmclan_release(link);
|
||||
return -ENODEV;
|
||||
} /* nmclan_config */
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
|
@ -763,46 +746,29 @@ nmclan_release
|
|||
net device, and release the PCMCIA configuration. If the device
|
||||
is still open, this will be postponed until it is closed.
|
||||
---------------------------------------------------------------------------- */
|
||||
static void nmclan_release(dev_link_t *link)
|
||||
static void nmclan_release(struct pcmcia_device *link)
|
||||
{
|
||||
|
||||
DEBUG(0, "nmclan_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;
|
||||
DEBUG(0, "nmclan_release(0x%p)\n", link);
|
||||
pcmcia_disable_device(link);
|
||||
}
|
||||
|
||||
static int nmclan_suspend(struct pcmcia_device *p_dev)
|
||||
static int nmclan_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 nmclan_resume(struct pcmcia_device *p_dev)
|
||||
static int nmclan_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) {
|
||||
nmclan_reset(dev);
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
if (link->open) {
|
||||
nmclan_reset(dev);
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -818,7 +784,7 @@ static void nmclan_reset(struct net_device *dev)
|
|||
mace_private *lp = netdev_priv(dev);
|
||||
|
||||
#if RESET_XILINX
|
||||
dev_link_t *link = &lp->link;
|
||||
struct pcmcia_device *link = &lp->link;
|
||||
conf_reg_t reg;
|
||||
u_long OrigCorValue;
|
||||
|
||||
|
@ -827,7 +793,7 @@ static void nmclan_reset(struct net_device *dev)
|
|||
reg.Action = CS_READ;
|
||||
reg.Offset = CISREG_COR;
|
||||
reg.Value = 0;
|
||||
pcmcia_access_configuration_register(link->handle, ®);
|
||||
pcmcia_access_configuration_register(link, ®);
|
||||
OrigCorValue = reg.Value;
|
||||
|
||||
/* Reset Xilinx */
|
||||
|
@ -836,12 +802,12 @@ static void nmclan_reset(struct net_device *dev)
|
|||
DEBUG(1, "nmclan_reset: OrigCorValue=0x%lX, resetting...\n",
|
||||
OrigCorValue);
|
||||
reg.Value = COR_SOFT_RESET;
|
||||
pcmcia_access_configuration_register(link->handle, ®);
|
||||
pcmcia_access_configuration_register(link, ®);
|
||||
/* Need to wait for 20 ms for PCMCIA to finish reset. */
|
||||
|
||||
/* Restore original COR configuration index */
|
||||
reg.Value = COR_LEVEL_REQ | (OrigCorValue & COR_CONFIG_MASK);
|
||||
pcmcia_access_configuration_register(link->handle, ®);
|
||||
pcmcia_access_configuration_register(link, ®);
|
||||
/* Xilinx is now completely reset along with the MACE chip. */
|
||||
lp->tx_free_frames=AM2150_MAX_TX_FRAMES;
|
||||
|
||||
|
@ -885,9 +851,9 @@ static int mace_open(struct net_device *dev)
|
|||
{
|
||||
kio_addr_t ioaddr = dev->base_addr;
|
||||
mace_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++;
|
||||
|
@ -908,7 +874,7 @@ static int mace_close(struct net_device *dev)
|
|||
{
|
||||
kio_addr_t ioaddr = dev->base_addr;
|
||||
mace_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);
|
||||
|
||||
|
@ -963,12 +929,12 @@ mace_start_xmit
|
|||
static void mace_tx_timeout(struct net_device *dev)
|
||||
{
|
||||
mace_private *lp = netdev_priv(dev);
|
||||
dev_link_t *link = &lp->link;
|
||||
struct pcmcia_device *link = lp->p_dev;
|
||||
|
||||
printk(KERN_NOTICE "%s: transmit timed out -- ", dev->name);
|
||||
#if RESET_ON_TIMEOUT
|
||||
printk("resetting card\n");
|
||||
pcmcia_reset_card(link->handle, NULL);
|
||||
pcmcia_reset_card(link, NULL);
|
||||
#else /* #if RESET_ON_TIMEOUT */
|
||||
printk("NOT resetting card\n");
|
||||
#endif /* #if RESET_ON_TIMEOUT */
|
||||
|
@ -1635,7 +1601,7 @@ static struct pcmcia_driver nmclan_cs_driver = {
|
|||
.drv = {
|
||||
.name = "nmclan_cs",
|
||||
},
|
||||
.probe = nmclan_attach,
|
||||
.probe = nmclan_probe,
|
||||
.remove = nmclan_detach,
|
||||
.id_table = nmclan_ids,
|
||||
.suspend = nmclan_suspend,
|
||||
|
|
|
@ -103,8 +103,8 @@ module_param_array(hw_addr, int, NULL, 0);
|
|||
/*====================================================================*/
|
||||
|
||||
static void mii_phy_probe(struct net_device *dev);
|
||||
static void pcnet_config(dev_link_t *link);
|
||||
static void pcnet_release(dev_link_t *link);
|
||||
static int pcnet_config(struct pcmcia_device *link);
|
||||
static void pcnet_release(struct pcmcia_device *link);
|
||||
static int pcnet_open(struct net_device *dev);
|
||||
static int pcnet_close(struct net_device *dev);
|
||||
static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
|
||||
|
@ -113,9 +113,9 @@ static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs);
|
|||
static void ei_watchdog(u_long arg);
|
||||
static void pcnet_reset_8390(struct net_device *dev);
|
||||
static int set_config(struct net_device *dev, struct ifmap *map);
|
||||
static int setup_shmem_window(dev_link_t *link, int start_pg,
|
||||
static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
|
||||
int stop_pg, int cm_offset);
|
||||
static int setup_dma_config(dev_link_t *link, int start_pg,
|
||||
static int setup_dma_config(struct pcmcia_device *link, int start_pg,
|
||||
int stop_pg);
|
||||
|
||||
static void pcnet_detach(struct pcmcia_device *p_dev);
|
||||
|
@ -214,7 +214,7 @@ static hw_info_t dl10019_info = { 0, 0, 0, 0, IS_DL10019|HAS_MII };
|
|||
static hw_info_t dl10022_info = { 0, 0, 0, 0, IS_DL10022|HAS_MII };
|
||||
|
||||
typedef struct pcnet_dev_t {
|
||||
dev_link_t link;
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
u_int flags;
|
||||
void __iomem *base;
|
||||
|
@ -240,10 +240,9 @@ static inline pcnet_dev_t *PRIV(struct net_device *dev)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static int pcnet_probe(struct pcmcia_device *p_dev)
|
||||
static int pcnet_probe(struct pcmcia_device *link)
|
||||
{
|
||||
pcnet_dev_t *info;
|
||||
dev_link_t *link;
|
||||
struct net_device *dev;
|
||||
|
||||
DEBUG(0, "pcnet_attach()\n");
|
||||
|
@ -252,7 +251,7 @@ static int pcnet_probe(struct pcmcia_device *p_dev)
|
|||
dev = __alloc_ei_netdev(sizeof(pcnet_dev_t));
|
||||
if (!dev) return -ENOMEM;
|
||||
info = PRIV(dev);
|
||||
link = &info->link;
|
||||
info->p_dev = link;
|
||||
link->priv = dev;
|
||||
|
||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||
|
@ -265,13 +264,7 @@ static int pcnet_probe(struct pcmcia_device *p_dev)
|
|||
dev->stop = &pcnet_close;
|
||||
dev->set_config = &set_config;
|
||||
|
||||
link->handle = p_dev;
|
||||
p_dev->instance = link;
|
||||
|
||||
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
|
||||
pcnet_config(link);
|
||||
|
||||
return 0;
|
||||
return pcnet_config(link);
|
||||
} /* pcnet_attach */
|
||||
|
||||
/*======================================================================
|
||||
|
@ -283,18 +276,16 @@ static int pcnet_probe(struct pcmcia_device *p_dev)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static void pcnet_detach(struct pcmcia_device *p_dev)
|
||||
static void pcnet_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
DEBUG(0, "pcnet_detach(0x%p)\n", link);
|
||||
|
||||
if (link->dev)
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
||||
if (link->state & DEV_CONFIG)
|
||||
pcnet_release(link);
|
||||
pcnet_release(link);
|
||||
|
||||
free_netdev(dev);
|
||||
} /* pcnet_detach */
|
||||
|
@ -306,7 +297,7 @@ static void pcnet_detach(struct pcmcia_device *p_dev)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static hw_info_t *get_hwinfo(dev_link_t *link)
|
||||
static hw_info_t *get_hwinfo(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
win_req_t req;
|
||||
|
@ -318,9 +309,9 @@ static hw_info_t *get_hwinfo(dev_link_t *link)
|
|||
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
||||
req.Base = 0; req.Size = 0;
|
||||
req.AccessSpeed = 0;
|
||||
i = pcmcia_request_window(&link->handle, &req, &link->win);
|
||||
i = pcmcia_request_window(&link, &req, &link->win);
|
||||
if (i != CS_SUCCESS) {
|
||||
cs_error(link->handle, RequestWindow, i);
|
||||
cs_error(link, RequestWindow, i);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -343,7 +334,7 @@ static hw_info_t *get_hwinfo(dev_link_t *link)
|
|||
iounmap(virt);
|
||||
j = pcmcia_release_window(link->win);
|
||||
if (j != CS_SUCCESS)
|
||||
cs_error(link->handle, ReleaseWindow, j);
|
||||
cs_error(link, ReleaseWindow, j);
|
||||
return (i < NR_INFO) ? hw_info+i : NULL;
|
||||
} /* get_hwinfo */
|
||||
|
||||
|
@ -355,7 +346,7 @@ static hw_info_t *get_hwinfo(dev_link_t *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static hw_info_t *get_prom(dev_link_t *link)
|
||||
static hw_info_t *get_prom(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
kio_addr_t ioaddr = dev->base_addr;
|
||||
|
@ -409,7 +400,7 @@ static hw_info_t *get_prom(dev_link_t *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static hw_info_t *get_dl10019(dev_link_t *link)
|
||||
static hw_info_t *get_dl10019(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
int i;
|
||||
|
@ -431,7 +422,7 @@ static hw_info_t *get_dl10019(dev_link_t *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static hw_info_t *get_ax88190(dev_link_t *link)
|
||||
static hw_info_t *get_ax88190(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
kio_addr_t ioaddr = dev->base_addr;
|
||||
|
@ -464,7 +455,7 @@ static hw_info_t *get_ax88190(dev_link_t *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static hw_info_t *get_hwired(dev_link_t *link)
|
||||
static hw_info_t *get_hwired(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
int i;
|
||||
|
@ -491,7 +482,7 @@ static hw_info_t *get_hwired(dev_link_t *link)
|
|||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static int try_io_port(dev_link_t *link)
|
||||
static int try_io_port(struct pcmcia_device *link)
|
||||
{
|
||||
int j, ret;
|
||||
if (link->io.NumPorts1 == 32) {
|
||||
|
@ -512,18 +503,17 @@ static int try_io_port(dev_link_t *link)
|
|||
for (j = 0; j < 0x400; j += 0x20) {
|
||||
link->io.BasePort1 = j ^ 0x300;
|
||||
link->io.BasePort2 = (j ^ 0x300) + 0x10;
|
||||
ret = pcmcia_request_io(link->handle, &link->io);
|
||||
ret = pcmcia_request_io(link, &link->io);
|
||||
if (ret == CS_SUCCESS) return ret;
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
return pcmcia_request_io(link->handle, &link->io);
|
||||
return pcmcia_request_io(link, &link->io);
|
||||
}
|
||||
}
|
||||
|
||||
static void pcnet_config(dev_link_t *link)
|
||||
static int pcnet_config(struct pcmcia_device *link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
struct net_device *dev = link->priv;
|
||||
pcnet_dev_t *info = PRIV(dev);
|
||||
tuple_t tuple;
|
||||
|
@ -531,7 +521,6 @@ static void pcnet_config(dev_link_t *link)
|
|||
int i, last_ret, last_fn, start_pg, stop_pg, cm_offset;
|
||||
int manfid = 0, prodid = 0, has_shmem = 0;
|
||||
u_short buf[64];
|
||||
config_info_t conf;
|
||||
hw_info_t *hw_info;
|
||||
|
||||
DEBUG(0, "pcnet_config(0x%p)\n", link);
|
||||
|
@ -541,36 +530,29 @@ static void pcnet_config(dev_link_t *link)
|
|||
tuple.TupleDataMax = sizeof(buf);
|
||||
tuple.TupleOffset = 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, &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 current Vcc */
|
||||
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
|
||||
link->conf.Vcc = conf.Vcc;
|
||||
|
||||
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)) {
|
||||
manfid = le16_to_cpu(buf[0]);
|
||||
prodid = le16_to_cpu(buf[1]);
|
||||
}
|
||||
|
||||
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 (last_ret == CS_SUCCESS) {
|
||||
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
|
||||
cistpl_io_t *io = &(parse.cftable_entry.io);
|
||||
|
||||
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 ||
|
||||
cfg->index == 0 || cfg->io.nwin == 0)
|
||||
goto next_entry;
|
||||
|
||||
|
@ -594,14 +576,14 @@ static void pcnet_config(dev_link_t *link)
|
|||
if (last_ret == CS_SUCCESS) break;
|
||||
}
|
||||
next_entry:
|
||||
last_ret = pcmcia_get_next_tuple(handle, &tuple);
|
||||
last_ret = pcmcia_get_next_tuple(link, &tuple);
|
||||
}
|
||||
if (last_ret != CS_SUCCESS) {
|
||||
cs_error(handle, RequestIO, last_ret);
|
||||
cs_error(link, RequestIO, last_ret);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq));
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
|
||||
if (link->io.NumPorts2 == 8) {
|
||||
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||
|
@ -611,7 +593,7 @@ static void pcnet_config(dev_link_t *link)
|
|||
(prodid == PRODID_IBM_HOME_AND_AWAY))
|
||||
link->conf.ConfigIndex |= 0x10;
|
||||
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
if (info->flags & HAS_MISC_REG) {
|
||||
|
@ -679,9 +661,8 @@ static void pcnet_config(dev_link_t *link)
|
|||
info->eth_phy = 0;
|
||||
}
|
||||
|
||||
link->dev = &info->node;
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(handle));
|
||||
link->dev_node = &info->node;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
dev->poll_controller = ei_poll;
|
||||
|
@ -689,7 +670,7 @@ static void pcnet_config(dev_link_t *link)
|
|||
|
||||
if (register_netdev(dev) != 0) {
|
||||
printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n");
|
||||
link->dev = NULL;
|
||||
link->dev_node = NULL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@ -712,14 +693,13 @@ static void pcnet_config(dev_link_t *link)
|
|||
printk(" hw_addr ");
|
||||
for (i = 0; i < 6; i++)
|
||||
printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
|
||||
return;
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
pcnet_release(link);
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
return;
|
||||
return -ENODEV;
|
||||
} /* pcnet_config */
|
||||
|
||||
/*======================================================================
|
||||
|
@ -730,21 +710,16 @@ static void pcnet_config(dev_link_t *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static void pcnet_release(dev_link_t *link)
|
||||
static void pcnet_release(struct pcmcia_device *link)
|
||||
{
|
||||
pcnet_dev_t *info = PRIV(link->priv);
|
||||
pcnet_dev_t *info = PRIV(link->priv);
|
||||
|
||||
DEBUG(0, "pcnet_release(0x%p)\n", link);
|
||||
DEBUG(0, "pcnet_release(0x%p)\n", link);
|
||||
|
||||
if (info->flags & USE_SHMEM) {
|
||||
iounmap(info->base);
|
||||
pcmcia_release_window(link->win);
|
||||
}
|
||||
pcmcia_release_configuration(link->handle);
|
||||
pcmcia_release_io(link->handle, &link->io);
|
||||
pcmcia_release_irq(link->handle, &link->irq);
|
||||
if (info->flags & USE_SHMEM)
|
||||
iounmap(info->base);
|
||||
|
||||
link->state &= ~DEV_CONFIG;
|
||||
pcmcia_disable_device(link);
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
|
@ -756,34 +731,24 @@ static void pcnet_release(dev_link_t *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static int pcnet_suspend(struct pcmcia_device *p_dev)
|
||||
static int pcnet_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 pcnet_resume(struct pcmcia_device *p_dev)
|
||||
static int pcnet_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) {
|
||||
pcnet_reset_8390(dev);
|
||||
NS8390_init(dev, 1);
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
if (link->open) {
|
||||
pcnet_reset_8390(dev);
|
||||
NS8390_init(dev, 1);
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1023,11 +988,11 @@ static void mii_phy_probe(struct net_device *dev)
|
|||
static int pcnet_open(struct net_device *dev)
|
||||
{
|
||||
pcnet_dev_t *info = PRIV(dev);
|
||||
dev_link_t *link = &info->link;
|
||||
|
||||
struct pcmcia_device *link = info->p_dev;
|
||||
|
||||
DEBUG(2, "pcnet_open('%s')\n", dev->name);
|
||||
|
||||
if (!DEV_OK(link))
|
||||
if (!pcmcia_dev_present(link))
|
||||
return -ENODEV;
|
||||
|
||||
link->open++;
|
||||
|
@ -1051,7 +1016,7 @@ static int pcnet_open(struct net_device *dev)
|
|||
static int pcnet_close(struct net_device *dev)
|
||||
{
|
||||
pcnet_dev_t *info = PRIV(dev);
|
||||
dev_link_t *link = &info->link;
|
||||
struct pcmcia_device *link = info->p_dev;
|
||||
|
||||
DEBUG(2, "pcnet_close('%s')\n", dev->name);
|
||||
|
||||
|
@ -1429,7 +1394,7 @@ static void dma_block_output(struct net_device *dev, int count,
|
|||
|
||||
/*====================================================================*/
|
||||
|
||||
static int setup_dma_config(dev_link_t *link, int start_pg,
|
||||
static int setup_dma_config(struct pcmcia_device *link, int start_pg,
|
||||
int stop_pg)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
|
@ -1532,7 +1497,7 @@ static void shmem_block_output(struct net_device *dev, int count,
|
|||
|
||||
/*====================================================================*/
|
||||
|
||||
static int setup_shmem_window(dev_link_t *link, int start_pg,
|
||||
static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
|
||||
int stop_pg, int cm_offset)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
|
@ -1554,7 +1519,7 @@ static int setup_shmem_window(dev_link_t *link, int start_pg,
|
|||
req.Attributes |= WIN_USE_WAIT;
|
||||
req.Base = 0; req.Size = window_size;
|
||||
req.AccessSpeed = mem_speed;
|
||||
CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win));
|
||||
CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
|
||||
|
||||
mem.CardOffset = (start_pg << 8) + cm_offset;
|
||||
offset = mem.CardOffset % window_size;
|
||||
|
@ -1595,7 +1560,7 @@ static int setup_shmem_window(dev_link_t *link, int start_pg,
|
|||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include <pcmcia/cisreg.h>
|
||||
#include <pcmcia/ciscode.h>
|
||||
#include <pcmcia/ds.h>
|
||||
#include <pcmcia/ss.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/system.h>
|
||||
|
@ -103,7 +104,7 @@ static const char *version =
|
|||
#define MEMORY_WAIT_TIME 8
|
||||
|
||||
struct smc_private {
|
||||
dev_link_t link;
|
||||
struct pcmcia_device *p_dev;
|
||||
spinlock_t lock;
|
||||
u_short manfid;
|
||||
u_short cardid;
|
||||
|
@ -278,8 +279,8 @@ enum RxCfg { RxAllMulti = 0x0004, RxPromisc = 0x0002,
|
|||
/*====================================================================*/
|
||||
|
||||
static void smc91c92_detach(struct pcmcia_device *p_dev);
|
||||
static void smc91c92_config(dev_link_t *link);
|
||||
static void smc91c92_release(dev_link_t *link);
|
||||
static int smc91c92_config(struct pcmcia_device *link);
|
||||
static void smc91c92_release(struct pcmcia_device *link);
|
||||
|
||||
static int smc_open(struct net_device *dev);
|
||||
static int smc_close(struct net_device *dev);
|
||||
|
@ -308,10 +309,9 @@ static struct ethtool_ops ethtool_ops;
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static int smc91c92_attach(struct pcmcia_device *p_dev)
|
||||
static int smc91c92_probe(struct pcmcia_device *link)
|
||||
{
|
||||
struct smc_private *smc;
|
||||
dev_link_t *link;
|
||||
struct net_device *dev;
|
||||
|
||||
DEBUG(0, "smc91c92_attach()\n");
|
||||
|
@ -321,7 +321,7 @@ static int smc91c92_attach(struct pcmcia_device *p_dev)
|
|||
if (!dev)
|
||||
return -ENOMEM;
|
||||
smc = netdev_priv(dev);
|
||||
link = &smc->link;
|
||||
smc->p_dev = link;
|
||||
link->priv = dev;
|
||||
|
||||
spin_lock_init(&smc->lock);
|
||||
|
@ -333,7 +333,6 @@ static int smc91c92_attach(struct pcmcia_device *p_dev)
|
|||
link->irq.Handler = &smc_interrupt;
|
||||
link->irq.Instance = dev;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.Vcc = 50;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
/* The SMC91c92-specific entries in the device structure. */
|
||||
|
@ -357,13 +356,7 @@ static int smc91c92_attach(struct pcmcia_device *p_dev)
|
|||
smc->mii_if.phy_id_mask = 0x1f;
|
||||
smc->mii_if.reg_num_mask = 0x1f;
|
||||
|
||||
link->handle = p_dev;
|
||||
p_dev->instance = link;
|
||||
|
||||
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
|
||||
smc91c92_config(link);
|
||||
|
||||
return 0;
|
||||
return smc91c92_config(link);
|
||||
} /* smc91c92_attach */
|
||||
|
||||
/*======================================================================
|
||||
|
@ -375,18 +368,16 @@ static int smc91c92_attach(struct pcmcia_device *p_dev)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static void smc91c92_detach(struct pcmcia_device *p_dev)
|
||||
static void smc91c92_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
DEBUG(0, "smc91c92_detach(0x%p)\n", link);
|
||||
|
||||
if (link->dev)
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
||||
if (link->state & DEV_CONFIG)
|
||||
smc91c92_release(link);
|
||||
smc91c92_release(link);
|
||||
|
||||
free_netdev(dev);
|
||||
} /* smc91c92_detach */
|
||||
|
@ -414,7 +405,7 @@ static int cvt_ascii_address(struct net_device *dev, char *s)
|
|||
|
||||
/*====================================================================*/
|
||||
|
||||
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;
|
||||
|
@ -425,7 +416,7 @@ static int first_tuple(client_handle_t handle, tuple_t *tuple,
|
|||
return pcmcia_parse_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;
|
||||
|
@ -447,7 +438,7 @@ static int next_tuple(client_handle_t handle, tuple_t *tuple,
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static int mhz_3288_power(dev_link_t *link)
|
||||
static int mhz_3288_power(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
struct smc_private *smc = netdev_priv(dev);
|
||||
|
@ -469,7 +460,7 @@ static int mhz_3288_power(dev_link_t *link)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int mhz_mfc_config(dev_link_t *link)
|
||||
static int mhz_mfc_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
struct smc_private *smc = netdev_priv(dev);
|
||||
|
@ -504,7 +495,7 @@ static int mhz_mfc_config(dev_link_t *link)
|
|||
tuple->TupleDataMax = 255;
|
||||
tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
|
||||
i = first_tuple(link->handle, tuple, parse);
|
||||
i = first_tuple(link, tuple, parse);
|
||||
/* The Megahertz combo cards have modem-like CIS entries, so
|
||||
we have to explicitly try a bunch of port combinations. */
|
||||
while (i == CS_SUCCESS) {
|
||||
|
@ -513,11 +504,11 @@ static int mhz_mfc_config(dev_link_t *link)
|
|||
for (k = 0; k < 0x400; k += 0x10) {
|
||||
if (k & 0x80) continue;
|
||||
link->io.BasePort1 = k ^ 0x300;
|
||||
i = pcmcia_request_io(link->handle, &link->io);
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
if (i == CS_SUCCESS) break;
|
||||
}
|
||||
if (i == CS_SUCCESS) break;
|
||||
i = next_tuple(link->handle, tuple, parse);
|
||||
i = next_tuple(link, tuple, parse);
|
||||
}
|
||||
if (i != CS_SUCCESS)
|
||||
goto free_cfg_mem;
|
||||
|
@ -527,7 +518,7 @@ static int mhz_mfc_config(dev_link_t *link)
|
|||
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
||||
req.Base = req.Size = 0;
|
||||
req.AccessSpeed = 0;
|
||||
i = pcmcia_request_window(&link->handle, &req, &link->win);
|
||||
i = pcmcia_request_window(&link, &req, &link->win);
|
||||
if (i != CS_SUCCESS)
|
||||
goto free_cfg_mem;
|
||||
smc->base = ioremap(req.Base, req.Size);
|
||||
|
@ -546,9 +537,8 @@ static int mhz_mfc_config(dev_link_t *link)
|
|||
return i;
|
||||
}
|
||||
|
||||
static int mhz_setup(dev_link_t *link)
|
||||
static int mhz_setup(struct pcmcia_device *link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
struct net_device *dev = link->priv;
|
||||
struct smc_cfg_mem *cfg_mem;
|
||||
tuple_t *tuple;
|
||||
|
@ -571,13 +561,13 @@ static int mhz_setup(dev_link_t *link)
|
|||
/* Read the station address from the CIS. It is stored as the last
|
||||
(fourth) string in the Version 1 Version/ID tuple. */
|
||||
tuple->DesiredTuple = CISTPL_VERS_1;
|
||||
if (first_tuple(handle, tuple, parse) != CS_SUCCESS) {
|
||||
if (first_tuple(link, tuple, parse) != CS_SUCCESS) {
|
||||
rc = -1;
|
||||
goto free_cfg_mem;
|
||||
}
|
||||
/* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
|
||||
if (next_tuple(handle, tuple, parse) != CS_SUCCESS)
|
||||
first_tuple(handle, tuple, parse);
|
||||
if (next_tuple(link, tuple, parse) != CS_SUCCESS)
|
||||
first_tuple(link, tuple, parse);
|
||||
if (parse->version_1.ns > 3) {
|
||||
station_addr = parse->version_1.str + parse->version_1.ofs[3];
|
||||
if (cvt_ascii_address(dev, station_addr) == 0) {
|
||||
|
@ -588,11 +578,11 @@ static int mhz_setup(dev_link_t *link)
|
|||
|
||||
/* Another possibility: for the EM3288, in a special tuple */
|
||||
tuple->DesiredTuple = 0x81;
|
||||
if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) {
|
||||
if (pcmcia_get_first_tuple(link, tuple) != CS_SUCCESS) {
|
||||
rc = -1;
|
||||
goto free_cfg_mem;
|
||||
}
|
||||
if (pcmcia_get_tuple_data(handle, tuple) != CS_SUCCESS) {
|
||||
if (pcmcia_get_tuple_data(link, tuple) != CS_SUCCESS) {
|
||||
rc = -1;
|
||||
goto free_cfg_mem;
|
||||
}
|
||||
|
@ -616,7 +606,7 @@ static int mhz_setup(dev_link_t *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static void mot_config(dev_link_t *link)
|
||||
static void mot_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
struct smc_private *smc = netdev_priv(dev);
|
||||
|
@ -637,7 +627,7 @@ static void mot_config(dev_link_t *link)
|
|||
mdelay(100);
|
||||
}
|
||||
|
||||
static int mot_setup(dev_link_t *link)
|
||||
static int mot_setup(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
kio_addr_t ioaddr = dev->base_addr;
|
||||
|
@ -671,7 +661,7 @@ static int mot_setup(dev_link_t *link)
|
|||
|
||||
/*====================================================================*/
|
||||
|
||||
static int smc_config(dev_link_t *link)
|
||||
static int smc_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
struct smc_cfg_mem *cfg_mem;
|
||||
|
@ -696,16 +686,16 @@ static int smc_config(dev_link_t *link)
|
|||
tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
|
||||
link->io.NumPorts1 = 16;
|
||||
i = first_tuple(link->handle, tuple, parse);
|
||||
i = first_tuple(link, tuple, parse);
|
||||
while (i != CS_NO_MORE_ITEMS) {
|
||||
if (i == CS_SUCCESS) {
|
||||
link->conf.ConfigIndex = cf->index;
|
||||
link->io.BasePort1 = cf->io.win[0].base;
|
||||
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(link->handle, tuple, parse);
|
||||
i = next_tuple(link, tuple, parse);
|
||||
}
|
||||
if (i == CS_SUCCESS)
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
|
@ -714,9 +704,8 @@ static int smc_config(dev_link_t *link)
|
|||
return i;
|
||||
}
|
||||
|
||||
static int smc_setup(dev_link_t *link)
|
||||
static int smc_setup(struct pcmcia_device *link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
struct net_device *dev = link->priv;
|
||||
struct smc_cfg_mem *cfg_mem;
|
||||
tuple_t *tuple;
|
||||
|
@ -739,11 +728,11 @@ static int smc_setup(dev_link_t *link)
|
|||
|
||||
/* Check for a LAN function extension tuple */
|
||||
tuple->DesiredTuple = CISTPL_FUNCE;
|
||||
i = first_tuple(handle, tuple, parse);
|
||||
i = first_tuple(link, tuple, parse);
|
||||
while (i == CS_SUCCESS) {
|
||||
if (parse->funce.type == CISTPL_FUNCE_LAN_NODE_ID)
|
||||
break;
|
||||
i = next_tuple(handle, tuple, parse);
|
||||
i = next_tuple(link, tuple, parse);
|
||||
}
|
||||
if (i == CS_SUCCESS) {
|
||||
node_id = (cistpl_lan_node_id_t *)parse->funce.data;
|
||||
|
@ -756,7 +745,7 @@ static int smc_setup(dev_link_t *link)
|
|||
}
|
||||
/* Try the third string in the Version 1 Version/ID tuple. */
|
||||
tuple->DesiredTuple = CISTPL_VERS_1;
|
||||
if (first_tuple(handle, tuple, parse) != CS_SUCCESS) {
|
||||
if (first_tuple(link, tuple, parse) != CS_SUCCESS) {
|
||||
rc = -1;
|
||||
goto free_cfg_mem;
|
||||
}
|
||||
|
@ -774,7 +763,7 @@ static int smc_setup(dev_link_t *link)
|
|||
|
||||
/*====================================================================*/
|
||||
|
||||
static int osi_config(dev_link_t *link)
|
||||
static int osi_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
static const kio_addr_t com[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
|
||||
|
@ -794,22 +783,21 @@ static int osi_config(dev_link_t *link)
|
|||
|
||||
for (i = j = 0; j < 4; j++) {
|
||||
link->io.BasePort2 = com[j];
|
||||
i = pcmcia_request_io(link->handle, &link->io);
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
if (i == CS_SUCCESS) break;
|
||||
}
|
||||
if (i != CS_SUCCESS) {
|
||||
/* Fallback: turn off hard decode */
|
||||
link->conf.ConfigIndex = 0x03;
|
||||
link->io.NumPorts2 = 0;
|
||||
i = pcmcia_request_io(link->handle, &link->io);
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
}
|
||||
dev->base_addr = link->io.BasePort1 + 0x10;
|
||||
return i;
|
||||
}
|
||||
|
||||
static int osi_setup(dev_link_t *link, u_short manfid, u_short cardid)
|
||||
static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
struct net_device *dev = link->priv;
|
||||
struct smc_cfg_mem *cfg_mem;
|
||||
tuple_t *tuple;
|
||||
|
@ -830,12 +818,12 @@ static int osi_setup(dev_link_t *link, u_short manfid, u_short cardid)
|
|||
|
||||
/* Read the station address from tuple 0x90, subtuple 0x04 */
|
||||
tuple->DesiredTuple = 0x90;
|
||||
i = pcmcia_get_first_tuple(handle, tuple);
|
||||
i = pcmcia_get_first_tuple(link, tuple);
|
||||
while (i == CS_SUCCESS) {
|
||||
i = pcmcia_get_tuple_data(handle, tuple);
|
||||
i = pcmcia_get_tuple_data(link, tuple);
|
||||
if ((i != CS_SUCCESS) || (buf[0] == 0x04))
|
||||
break;
|
||||
i = pcmcia_get_next_tuple(handle, tuple);
|
||||
i = pcmcia_get_next_tuple(link, tuple);
|
||||
}
|
||||
if (i != CS_SUCCESS) {
|
||||
rc = -1;
|
||||
|
@ -868,57 +856,47 @@ static int osi_setup(dev_link_t *link, u_short manfid, u_short cardid)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int smc91c92_suspend(struct pcmcia_device *p_dev)
|
||||
static int smc91c92_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 smc91c92_resume(struct pcmcia_device *p_dev)
|
||||
static int smc91c92_resume(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct net_device *dev = link->priv;
|
||||
struct smc_private *smc = netdev_priv(dev);
|
||||
int i;
|
||||
|
||||
link->state &= ~DEV_SUSPEND;
|
||||
if (link->state & DEV_CONFIG) {
|
||||
if ((smc->manfid == MANFID_MEGAHERTZ) &&
|
||||
(smc->cardid == PRODID_MEGAHERTZ_EM3288))
|
||||
mhz_3288_power(link);
|
||||
pcmcia_request_configuration(link->handle, &link->conf);
|
||||
if (smc->manfid == MANFID_MOTOROLA)
|
||||
mot_config(link);
|
||||
if ((smc->manfid == MANFID_OSITECH) &&
|
||||
(smc->cardid != PRODID_OSITECH_SEVEN)) {
|
||||
/* Power up the card and enable interrupts */
|
||||
set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR);
|
||||
set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR);
|
||||
}
|
||||
if (((smc->manfid == MANFID_OSITECH) &&
|
||||
(smc->cardid == PRODID_OSITECH_SEVEN)) ||
|
||||
((smc->manfid == MANFID_PSION) &&
|
||||
(smc->cardid == PRODID_PSION_NET100))) {
|
||||
/* Download the Seven of Diamonds firmware */
|
||||
for (i = 0; i < sizeof(__Xilinx7OD); i++) {
|
||||
outb(__Xilinx7OD[i], link->io.BasePort1+2);
|
||||
udelay(50);
|
||||
}
|
||||
}
|
||||
if (link->open) {
|
||||
smc_reset(dev);
|
||||
netif_device_attach(dev);
|
||||
if ((smc->manfid == MANFID_MEGAHERTZ) &&
|
||||
(smc->cardid == PRODID_MEGAHERTZ_EM3288))
|
||||
mhz_3288_power(link);
|
||||
if (smc->manfid == MANFID_MOTOROLA)
|
||||
mot_config(link);
|
||||
if ((smc->manfid == MANFID_OSITECH) &&
|
||||
(smc->cardid != PRODID_OSITECH_SEVEN)) {
|
||||
/* Power up the card and enable interrupts */
|
||||
set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR);
|
||||
set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR);
|
||||
}
|
||||
if (((smc->manfid == MANFID_OSITECH) &&
|
||||
(smc->cardid == PRODID_OSITECH_SEVEN)) ||
|
||||
((smc->manfid == MANFID_PSION) &&
|
||||
(smc->cardid == PRODID_PSION_NET100))) {
|
||||
/* Download the Seven of Diamonds firmware */
|
||||
for (i = 0; i < sizeof(__Xilinx7OD); i++) {
|
||||
outb(__Xilinx7OD[i], link->io.BasePort1+2);
|
||||
udelay(50);
|
||||
}
|
||||
}
|
||||
if (link->open) {
|
||||
smc_reset(dev);
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -931,7 +909,7 @@ static int smc91c92_resume(struct pcmcia_device *p_dev)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static int check_sig(dev_link_t *link)
|
||||
static int check_sig(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
kio_addr_t ioaddr = dev->base_addr;
|
||||
|
@ -964,13 +942,15 @@ static int check_sig(dev_link_t *link)
|
|||
}
|
||||
|
||||
if (width) {
|
||||
printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n");
|
||||
smc91c92_suspend(link->handle);
|
||||
pcmcia_release_io(link->handle, &link->io);
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
pcmcia_request_io(link->handle, &link->io);
|
||||
smc91c92_resume(link->handle);
|
||||
return check_sig(link);
|
||||
modconf_t mod = {
|
||||
.Attributes = CONF_IO_CHANGE_WIDTH,
|
||||
};
|
||||
printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n");
|
||||
|
||||
smc91c92_suspend(link);
|
||||
pcmcia_modify_configuration(link, &mod);
|
||||
smc91c92_resume(link);
|
||||
return check_sig(link);
|
||||
}
|
||||
return -ENODEV;
|
||||
}
|
||||
|
@ -984,11 +964,10 @@ static int check_sig(dev_link_t *link)
|
|||
======================================================================*/
|
||||
|
||||
#define CS_EXIT_TEST(ret, svc, label) \
|
||||
if (ret != CS_SUCCESS) { cs_error(link->handle, svc, ret); goto label; }
|
||||
if (ret != CS_SUCCESS) { cs_error(link, svc, ret); goto label; }
|
||||
|
||||
static void smc91c92_config(dev_link_t *link)
|
||||
static int smc91c92_config(struct pcmcia_device *link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
struct net_device *dev = link->priv;
|
||||
struct smc_private *smc = netdev_priv(dev);
|
||||
struct smc_cfg_mem *cfg_mem;
|
||||
|
@ -1015,21 +994,18 @@ static void smc91c92_config(dev_link_t *link)
|
|||
tuple->TupleDataMax = 64;
|
||||
|
||||
tuple->DesiredTuple = CISTPL_CONFIG;
|
||||
i = first_tuple(handle, tuple, parse);
|
||||
i = first_tuple(link, tuple, parse);
|
||||
CS_EXIT_TEST(i, ParseTuple, config_failed);
|
||||
link->conf.ConfigBase = parse->config.base;
|
||||
link->conf.Present = parse->config.rmask[0];
|
||||
|
||||
tuple->DesiredTuple = CISTPL_MANFID;
|
||||
tuple->Attributes = TUPLE_RETURN_COMMON;
|
||||
if (first_tuple(handle, tuple, parse) == CS_SUCCESS) {
|
||||
if (first_tuple(link, tuple, parse) == CS_SUCCESS) {
|
||||
smc->manfid = parse->manfid.manf;
|
||||
smc->cardid = parse->manfid.card;
|
||||
}
|
||||
|
||||
/* Configure card */
|
||||
link->state |= DEV_CONFIG;
|
||||
|
||||
if ((smc->manfid == MANFID_OSITECH) &&
|
||||
(smc->cardid != PRODID_OSITECH_SEVEN)) {
|
||||
i = osi_config(link);
|
||||
|
@ -1043,9 +1019,9 @@ static void smc91c92_config(dev_link_t *link)
|
|||
}
|
||||
CS_EXIT_TEST(i, RequestIO, config_failed);
|
||||
|
||||
i = pcmcia_request_irq(link->handle, &link->irq);
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
CS_EXIT_TEST(i, RequestIRQ, config_failed);
|
||||
i = pcmcia_request_configuration(link->handle, &link->conf);
|
||||
i = pcmcia_request_configuration(link, &link->conf);
|
||||
CS_EXIT_TEST(i, RequestConfiguration, config_failed);
|
||||
|
||||
if (smc->manfid == MANFID_MOTOROLA)
|
||||
|
@ -1124,13 +1100,12 @@ static void smc91c92_config(dev_link_t *link)
|
|||
SMC_SELECT_BANK(0);
|
||||
}
|
||||
|
||||
link->dev = &smc->node;
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(handle));
|
||||
link->dev_node = &smc->node;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
|
||||
if (register_netdev(dev) != 0) {
|
||||
printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n");
|
||||
link->dev = NULL;
|
||||
link->dev_node = NULL;
|
||||
goto config_undo;
|
||||
}
|
||||
|
||||
|
@ -1160,15 +1135,14 @@ static void smc91c92_config(dev_link_t *link)
|
|||
}
|
||||
}
|
||||
kfree(cfg_mem);
|
||||
return;
|
||||
return 0;
|
||||
|
||||
config_undo:
|
||||
unregister_netdev(dev);
|
||||
config_failed: /* CS_EXIT_TEST() calls jump to here... */
|
||||
smc91c92_release(link);
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
kfree(cfg_mem);
|
||||
|
||||
return -ENODEV;
|
||||
} /* smc91c92_config */
|
||||
|
||||
/*======================================================================
|
||||
|
@ -1179,22 +1153,15 @@ static void smc91c92_config(dev_link_t *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static void smc91c92_release(dev_link_t *link)
|
||||
static void smc91c92_release(struct pcmcia_device *link)
|
||||
{
|
||||
|
||||
DEBUG(0, "smc91c92_release(0x%p)\n", link);
|
||||
|
||||
pcmcia_release_configuration(link->handle);
|
||||
pcmcia_release_io(link->handle, &link->io);
|
||||
pcmcia_release_irq(link->handle, &link->irq);
|
||||
if (link->win) {
|
||||
struct net_device *dev = link->priv;
|
||||
struct smc_private *smc = netdev_priv(dev);
|
||||
iounmap(smc->base);
|
||||
pcmcia_release_window(link->win);
|
||||
}
|
||||
|
||||
link->state &= ~DEV_CONFIG;
|
||||
DEBUG(0, "smc91c92_release(0x%p)\n", link);
|
||||
if (link->win) {
|
||||
struct net_device *dev = link->priv;
|
||||
struct smc_private *smc = netdev_priv(dev);
|
||||
iounmap(smc->base);
|
||||
}
|
||||
pcmcia_disable_device(link);
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
|
@ -1283,7 +1250,7 @@ static void smc_dump(struct net_device *dev)
|
|||
static int smc_open(struct net_device *dev)
|
||||
{
|
||||
struct smc_private *smc = netdev_priv(dev);
|
||||
dev_link_t *link = &smc->link;
|
||||
struct pcmcia_device *link = smc->p_dev;
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
DEBUG(0, "%s: smc_open(%p), ID/Window %4.4x.\n",
|
||||
|
@ -1292,7 +1259,7 @@ static int smc_open(struct net_device *dev)
|
|||
#endif
|
||||
|
||||
/* Check that the PCMCIA card is still here. */
|
||||
if (!DEV_OK(link))
|
||||
if (!pcmcia_dev_present(link))
|
||||
return -ENODEV;
|
||||
/* Physical device present signature. */
|
||||
if (check_sig(link) < 0) {
|
||||
|
@ -1320,7 +1287,7 @@ static int smc_open(struct net_device *dev)
|
|||
static int smc_close(struct net_device *dev)
|
||||
{
|
||||
struct smc_private *smc = netdev_priv(dev);
|
||||
dev_link_t *link = &smc->link;
|
||||
struct pcmcia_device *link = smc->p_dev;
|
||||
kio_addr_t ioaddr = dev->base_addr;
|
||||
|
||||
DEBUG(0, "%s: smc_close(), status %4.4x.\n",
|
||||
|
@ -2311,7 +2278,7 @@ static struct pcmcia_driver smc91c92_cs_driver = {
|
|||
.drv = {
|
||||
.name = "smc91c92_cs",
|
||||
},
|
||||
.probe = smc91c92_attach,
|
||||
.probe = smc91c92_probe,
|
||||
.remove = smc91c92_detach,
|
||||
.id_table = smc91c92_ids,
|
||||
.suspend = smc91c92_suspend,
|
||||
|
|
|
@ -289,9 +289,9 @@ static void mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg,
|
|||
* and ejection events. They are invoked from the event handler.
|
||||
*/
|
||||
|
||||
static int has_ce2_string(dev_link_t * link);
|
||||
static void xirc2ps_config(dev_link_t * link);
|
||||
static void xirc2ps_release(dev_link_t * link);
|
||||
static int has_ce2_string(struct pcmcia_device * link);
|
||||
static int xirc2ps_config(struct pcmcia_device * link);
|
||||
static void xirc2ps_release(struct pcmcia_device * link);
|
||||
|
||||
/****************
|
||||
* The attach() and detach() entry points are used to create and destroy
|
||||
|
@ -313,10 +313,10 @@ static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs
|
|||
/****************
|
||||
* A linked list of "instances" of the 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.
|
||||
*/
|
||||
|
||||
|
@ -326,13 +326,13 @@ static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs
|
|||
* 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.
|
||||
*/
|
||||
|
||||
typedef struct local_info_t {
|
||||
dev_link_t link;
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
struct net_device_stats stats;
|
||||
int card_type;
|
||||
|
@ -355,7 +355,7 @@ static void do_tx_timeout(struct net_device *dev);
|
|||
static struct net_device_stats *do_get_stats(struct net_device *dev);
|
||||
static void set_addresses(struct net_device *dev);
|
||||
static void set_multicast_list(struct net_device *dev);
|
||||
static int set_card_type(dev_link_t *link, const void *s);
|
||||
static int set_card_type(struct pcmcia_device *link, const void *s);
|
||||
static int do_config(struct net_device *dev, struct ifmap *map);
|
||||
static int do_open(struct net_device *dev);
|
||||
static int do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
|
||||
|
@ -368,7 +368,7 @@ static int do_stop(struct net_device *dev);
|
|||
|
||||
/*=============== Helper functions =========================*/
|
||||
static int
|
||||
first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
|
||||
first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -379,7 +379,7 @@ first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
|
|||
}
|
||||
|
||||
static int
|
||||
next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
|
||||
next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -553,9 +553,8 @@ mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg, unsigned data, int len)
|
|||
*/
|
||||
|
||||
static int
|
||||
xirc2ps_attach(struct pcmcia_device *p_dev)
|
||||
xirc2ps_probe(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link;
|
||||
struct net_device *dev;
|
||||
local_info_t *local;
|
||||
|
||||
|
@ -566,12 +565,11 @@ xirc2ps_attach(struct pcmcia_device *p_dev)
|
|||
if (!dev)
|
||||
return -ENOMEM;
|
||||
local = netdev_priv(dev);
|
||||
link = &local->link;
|
||||
local->p_dev = link;
|
||||
link->priv = dev;
|
||||
|
||||
/* 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;
|
||||
|
@ -593,13 +591,7 @@ xirc2ps_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;
|
||||
xirc2ps_config(link);
|
||||
|
||||
return 0;
|
||||
return xirc2ps_config(link);
|
||||
} /* xirc2ps_attach */
|
||||
|
||||
/****************
|
||||
|
@ -610,18 +602,16 @@ xirc2ps_attach(struct pcmcia_device *p_dev)
|
|||
*/
|
||||
|
||||
static void
|
||||
xirc2ps_detach(struct pcmcia_device *p_dev)
|
||||
xirc2ps_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
DEBUG(0, "detach(0x%p)\n", link);
|
||||
|
||||
if (link->dev)
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
||||
if (link->state & DEV_CONFIG)
|
||||
xirc2ps_release(link);
|
||||
xirc2ps_release(link);
|
||||
|
||||
free_netdev(dev);
|
||||
} /* xirc2ps_detach */
|
||||
|
@ -645,7 +635,7 @@ xirc2ps_detach(struct pcmcia_device *p_dev)
|
|||
*
|
||||
*/
|
||||
static int
|
||||
set_card_type(dev_link_t *link, const void *s)
|
||||
set_card_type(struct pcmcia_device *link, const void *s)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
local_info_t *local = netdev_priv(dev);
|
||||
|
@ -714,9 +704,8 @@ set_card_type(dev_link_t *link, const void *s)
|
|||
* Returns: true if this is a CE2
|
||||
*/
|
||||
static int
|
||||
has_ce2_string(dev_link_t * link)
|
||||
has_ce2_string(struct pcmcia_device * link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
u_char buf[256];
|
||||
|
@ -726,7 +715,7 @@ has_ce2_string(dev_link_t * link)
|
|||
tuple.TupleDataMax = 254;
|
||||
tuple.TupleOffset = 0;
|
||||
tuple.DesiredTuple = CISTPL_VERS_1;
|
||||
if (!first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 2) {
|
||||
if (!first_tuple(link, &tuple, &parse) && parse.version_1.ns > 2) {
|
||||
if (strstr(parse.version_1.str + parse.version_1.ofs[2], "CE2"))
|
||||
return 1;
|
||||
}
|
||||
|
@ -738,10 +727,9 @@ has_ce2_string(dev_link_t * link)
|
|||
* is received, to configure the PCMCIA socket, and to make the
|
||||
* ethernet device available to the system.
|
||||
*/
|
||||
static void
|
||||
xirc2ps_config(dev_link_t * link)
|
||||
static int
|
||||
xirc2ps_config(struct pcmcia_device * link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
struct net_device *dev = link->priv;
|
||||
local_info_t *local = netdev_priv(dev);
|
||||
tuple_t tuple;
|
||||
|
@ -767,7 +755,7 @@ xirc2ps_config(dev_link_t * link)
|
|||
|
||||
/* Is this a valid card */
|
||||
tuple.DesiredTuple = CISTPL_MANFID;
|
||||
if ((err=first_tuple(handle, &tuple, &parse))) {
|
||||
if ((err=first_tuple(link, &tuple, &parse))) {
|
||||
printk(KNOT_XIRC "manfid not found in CIS\n");
|
||||
goto failure;
|
||||
}
|
||||
|
@ -803,15 +791,15 @@ xirc2ps_config(dev_link_t * link)
|
|||
|
||||
/* get configuration stuff */
|
||||
tuple.DesiredTuple = CISTPL_CONFIG;
|
||||
if ((err=first_tuple(handle, &tuple, &parse)))
|
||||
if ((err=first_tuple(link, &tuple, &parse)))
|
||||
goto cis_error;
|
||||
link->conf.ConfigBase = parse.config.base;
|
||||
link->conf.Present = parse.config.rmask[0];
|
||||
|
||||
/* get the ethernet address from the CIS */
|
||||
tuple.DesiredTuple = CISTPL_FUNCE;
|
||||
for (err = first_tuple(handle, &tuple, &parse); !err;
|
||||
err = next_tuple(handle, &tuple, &parse)) {
|
||||
for (err = first_tuple(link, &tuple, &parse); !err;
|
||||
err = next_tuple(link, &tuple, &parse)) {
|
||||
/* Once I saw two CISTPL_FUNCE_LAN_NODE_ID entries:
|
||||
* the first one with a length of zero the second correct -
|
||||
* so I skip all entries with length 0 */
|
||||
|
@ -821,8 +809,8 @@ xirc2ps_config(dev_link_t * link)
|
|||
}
|
||||
if (err) { /* not found: try to get the node-id from tuple 0x89 */
|
||||
tuple.DesiredTuple = 0x89; /* data layout looks like tuple 0x22 */
|
||||
if ((err = pcmcia_get_first_tuple(handle, &tuple)) == 0 &&
|
||||
(err = pcmcia_get_tuple_data(handle, &tuple)) == 0) {
|
||||
if ((err = pcmcia_get_first_tuple(link, &tuple)) == 0 &&
|
||||
(err = pcmcia_get_tuple_data(link, &tuple)) == 0) {
|
||||
if (tuple.TupleDataLen == 8 && *buf == CISTPL_FUNCE_LAN_NODE_ID)
|
||||
memcpy(&parse, buf, 8);
|
||||
else
|
||||
|
@ -831,8 +819,8 @@ xirc2ps_config(dev_link_t * link)
|
|||
}
|
||||
if (err) { /* another try (James Lehmer's CE2 version 4.1)*/
|
||||
tuple.DesiredTuple = CISTPL_FUNCE;
|
||||
for (err = first_tuple(handle, &tuple, &parse); !err;
|
||||
err = next_tuple(handle, &tuple, &parse)) {
|
||||
for (err = first_tuple(link, &tuple, &parse); !err;
|
||||
err = next_tuple(link, &tuple, &parse)) {
|
||||
if (parse.funce.type == 0x02 && parse.funce.data[0] == 1
|
||||
&& parse.funce.data[1] == 6 && tuple.TupleDataLen == 13) {
|
||||
buf[1] = 4;
|
||||
|
@ -853,9 +841,6 @@ xirc2ps_config(dev_link_t * link)
|
|||
for (i=0; i < 6; i++)
|
||||
dev->dev_addr[i] = node_id->id[i];
|
||||
|
||||
/* Configure card */
|
||||
link->state |= DEV_CONFIG;
|
||||
|
||||
link->io.IOAddrLines =10;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||
link->irq.Attributes = IRQ_HANDLE_PRESENT;
|
||||
|
@ -875,14 +860,14 @@ xirc2ps_config(dev_link_t * link)
|
|||
* Ethernet port */
|
||||
link->io.NumPorts1 = 16; /* no Mako stuff anymore */
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
for (err = first_tuple(handle, &tuple, &parse); !err;
|
||||
err = next_tuple(handle, &tuple, &parse)) {
|
||||
for (err = first_tuple(link, &tuple, &parse); !err;
|
||||
err = next_tuple(link, &tuple, &parse)) {
|
||||
if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) {
|
||||
for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
|
||||
link->conf.ConfigIndex = cf->index ;
|
||||
link->io.BasePort2 = cf->io.win[0].base;
|
||||
link->io.BasePort1 = ioaddr;
|
||||
if (!(err=pcmcia_request_io(link->handle, &link->io)))
|
||||
if (!(err=pcmcia_request_io(link, &link->io)))
|
||||
goto port_found;
|
||||
}
|
||||
}
|
||||
|
@ -896,15 +881,15 @@ xirc2ps_config(dev_link_t * link)
|
|||
*/
|
||||
for (pass=0; pass < 2; pass++) {
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
for (err = first_tuple(handle, &tuple, &parse); !err;
|
||||
err = next_tuple(handle, &tuple, &parse)){
|
||||
for (err = first_tuple(link, &tuple, &parse); !err;
|
||||
err = next_tuple(link, &tuple, &parse)){
|
||||
if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8){
|
||||
link->conf.ConfigIndex = cf->index ;
|
||||
link->io.BasePort2 = cf->io.win[0].base;
|
||||
link->io.BasePort1 = link->io.BasePort2
|
||||
+ (pass ? (cf->index & 0x20 ? -24:8)
|
||||
: (cf->index & 0x20 ? 8:-24));
|
||||
if (!(err=pcmcia_request_io(link->handle, &link->io)))
|
||||
if (!(err=pcmcia_request_io(link, &link->io)))
|
||||
goto port_found;
|
||||
}
|
||||
}
|
||||
|
@ -919,12 +904,12 @@ xirc2ps_config(dev_link_t * link)
|
|||
link->io.NumPorts1 = 16;
|
||||
for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
|
||||
link->io.BasePort1 = ioaddr;
|
||||
if (!(err=pcmcia_request_io(link->handle, &link->io)))
|
||||
if (!(err=pcmcia_request_io(link, &link->io)))
|
||||
goto port_found;
|
||||
}
|
||||
link->io.BasePort1 = 0; /* let CS decide */
|
||||
if ((err=pcmcia_request_io(link->handle, &link->io))) {
|
||||
cs_error(link->handle, RequestIO, err);
|
||||
if ((err=pcmcia_request_io(link, &link->io))) {
|
||||
cs_error(link, RequestIO, err);
|
||||
goto config_error;
|
||||
}
|
||||
}
|
||||
|
@ -936,8 +921,8 @@ xirc2ps_config(dev_link_t * link)
|
|||
* Now allocate an interrupt line. Note that this does not
|
||||
* actually assign a handler to the interrupt.
|
||||
*/
|
||||
if ((err=pcmcia_request_irq(link->handle, &link->irq))) {
|
||||
cs_error(link->handle, RequestIRQ, err);
|
||||
if ((err=pcmcia_request_irq(link, &link->irq))) {
|
||||
cs_error(link, RequestIRQ, err);
|
||||
goto config_error;
|
||||
}
|
||||
|
||||
|
@ -945,8 +930,8 @@ xirc2ps_config(dev_link_t * link)
|
|||
* This actually configures the PCMCIA socket -- setting up
|
||||
* the I/O windows and the interrupt mapping.
|
||||
*/
|
||||
if ((err=pcmcia_request_configuration(link->handle, &link->conf))) {
|
||||
cs_error(link->handle, RequestConfiguration, err);
|
||||
if ((err=pcmcia_request_configuration(link, &link->conf))) {
|
||||
cs_error(link, RequestConfiguration, err);
|
||||
goto config_error;
|
||||
}
|
||||
|
||||
|
@ -963,15 +948,15 @@ xirc2ps_config(dev_link_t * link)
|
|||
reg.Action = CS_WRITE;
|
||||
reg.Offset = CISREG_IOBASE_0;
|
||||
reg.Value = link->io.BasePort2 & 0xff;
|
||||
if ((err = pcmcia_access_configuration_register(link->handle, ®))) {
|
||||
cs_error(link->handle, AccessConfigurationRegister, err);
|
||||
if ((err = pcmcia_access_configuration_register(link, ®))) {
|
||||
cs_error(link, AccessConfigurationRegister, err);
|
||||
goto config_error;
|
||||
}
|
||||
reg.Action = CS_WRITE;
|
||||
reg.Offset = CISREG_IOBASE_1;
|
||||
reg.Value = (link->io.BasePort2 >> 8) & 0xff;
|
||||
if ((err = pcmcia_access_configuration_register(link->handle, ®))) {
|
||||
cs_error(link->handle, AccessConfigurationRegister, err);
|
||||
if ((err = pcmcia_access_configuration_register(link, ®))) {
|
||||
cs_error(link, AccessConfigurationRegister, err);
|
||||
goto config_error;
|
||||
}
|
||||
|
||||
|
@ -982,15 +967,15 @@ xirc2ps_config(dev_link_t * link)
|
|||
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
||||
req.Base = req.Size = 0;
|
||||
req.AccessSpeed = 0;
|
||||
if ((err = pcmcia_request_window(&link->handle, &req, &link->win))) {
|
||||
cs_error(link->handle, RequestWindow, err);
|
||||
if ((err = pcmcia_request_window(&link, &req, &link->win))) {
|
||||
cs_error(link, RequestWindow, err);
|
||||
goto config_error;
|
||||
}
|
||||
local->dingo_ccr = ioremap(req.Base,0x1000) + 0x0800;
|
||||
mem.CardOffset = 0x0;
|
||||
mem.Page = 0;
|
||||
if ((err = pcmcia_map_mem_page(link->win, &mem))) {
|
||||
cs_error(link->handle, MapMemPage, err);
|
||||
cs_error(link, MapMemPage, err);
|
||||
goto config_error;
|
||||
}
|
||||
|
||||
|
@ -1050,13 +1035,12 @@ xirc2ps_config(dev_link_t * link)
|
|||
if (local->dingo)
|
||||
do_reset(dev, 1); /* a kludge to make the cem56 work */
|
||||
|
||||
link->dev = &local->node;
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(handle));
|
||||
link->dev_node = &local->node;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
|
||||
if ((err=register_netdev(dev))) {
|
||||
printk(KNOT_XIRC "register_netdev() failed\n");
|
||||
link->dev = NULL;
|
||||
link->dev_node = NULL;
|
||||
goto config_error;
|
||||
}
|
||||
|
||||
|
@ -1069,17 +1053,16 @@ xirc2ps_config(dev_link_t * link)
|
|||
printk("%c%02X", i?':':' ', dev->dev_addr[i]);
|
||||
printk("\n");
|
||||
|
||||
return;
|
||||
return 0;
|
||||
|
||||
config_error:
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
xirc2ps_release(link);
|
||||
return;
|
||||
return -ENODEV;
|
||||
|
||||
cis_error:
|
||||
printk(KNOT_XIRC "unable to parse CIS\n");
|
||||
failure:
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
return -ENODEV;
|
||||
} /* xirc2ps_config */
|
||||
|
||||
/****************
|
||||
|
@ -1088,57 +1071,41 @@ xirc2ps_config(dev_link_t * link)
|
|||
* still open, this will be postponed until it is closed.
|
||||
*/
|
||||
static void
|
||||
xirc2ps_release(dev_link_t *link)
|
||||
xirc2ps_release(struct pcmcia_device *link)
|
||||
{
|
||||
DEBUG(0, "release(0x%p)\n", link);
|
||||
|
||||
DEBUG(0, "release(0x%p)\n", link);
|
||||
|
||||
if (link->win) {
|
||||
struct net_device *dev = link->priv;
|
||||
local_info_t *local = netdev_priv(dev);
|
||||
if (local->dingo)
|
||||
iounmap(local->dingo_ccr - 0x0800);
|
||||
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;
|
||||
|
||||
if (link->win) {
|
||||
struct net_device *dev = link->priv;
|
||||
local_info_t *local = netdev_priv(dev);
|
||||
if (local->dingo)
|
||||
iounmap(local->dingo_ccr - 0x0800);
|
||||
}
|
||||
pcmcia_disable_device(link);
|
||||
} /* xirc2ps_release */
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
|
||||
static int xirc2ps_suspend(struct pcmcia_device *p_dev)
|
||||
static int xirc2ps_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);
|
||||
do_powerdown(dev);
|
||||
}
|
||||
pcmcia_release_configuration(link->handle);
|
||||
if (link->open) {
|
||||
netif_device_detach(dev);
|
||||
do_powerdown(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xirc2ps_resume(struct pcmcia_device *p_dev)
|
||||
static int xirc2ps_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) {
|
||||
do_reset(dev,1);
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
if (link->open) {
|
||||
do_reset(dev,1);
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1552,13 +1519,13 @@ static int
|
|||
do_open(struct net_device *dev)
|
||||
{
|
||||
local_info_t *lp = netdev_priv(dev);
|
||||
dev_link_t *link = &lp->link;
|
||||
struct pcmcia_device *link = lp->p_dev;
|
||||
|
||||
DEBUG(0, "do_open(%p)\n", dev);
|
||||
|
||||
/* Check that the PCMCIA card is still here. */
|
||||
/* Physical device present signature. */
|
||||
if (!DEV_OK(link))
|
||||
if (!pcmcia_dev_present(link))
|
||||
return -ENODEV;
|
||||
|
||||
/* okay */
|
||||
|
@ -1882,7 +1849,7 @@ do_stop(struct net_device *dev)
|
|||
{
|
||||
kio_addr_t ioaddr = dev->base_addr;
|
||||
local_info_t *lp = netdev_priv(dev);
|
||||
dev_link_t *link = &lp->link;
|
||||
struct pcmcia_device *link = lp->p_dev;
|
||||
|
||||
DEBUG(0, "do_stop(%p)\n", dev);
|
||||
|
||||
|
@ -1935,7 +1902,7 @@ static struct pcmcia_driver xirc2ps_cs_driver = {
|
|||
.drv = {
|
||||
.name = "xirc2ps_cs",
|
||||
},
|
||||
.probe = xirc2ps_attach,
|
||||
.probe = xirc2ps_probe,
|
||||
.remove = xirc2ps_detach,
|
||||
.id_table = xirc2ps_ids,
|
||||
.suspend = xirc2ps_suspend,
|
||||
|
|
|
@ -80,8 +80,8 @@ MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");
|
|||
event handler.
|
||||
*/
|
||||
|
||||
static void airo_config(dev_link_t *link);
|
||||
static void airo_release(dev_link_t *link);
|
||||
static int airo_config(struct pcmcia_device *link);
|
||||
static void airo_release(struct pcmcia_device *link);
|
||||
|
||||
/*
|
||||
The attach() and detach() entry points are used to create and destroy
|
||||
|
@ -101,10 +101,10 @@ static void airo_detach(struct pcmcia_device *p_dev);
|
|||
/*
|
||||
A linked list of "instances" of the aironet 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.
|
||||
*/
|
||||
|
||||
|
@ -114,7 +114,7 @@ static void airo_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.
|
||||
|
||||
|
@ -141,24 +141,16 @@ typedef struct local_info_t {
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static int airo_attach(struct pcmcia_device *p_dev)
|
||||
static int airo_probe(struct pcmcia_device *p_dev)
|
||||
{
|
||||
dev_link_t *link;
|
||||
local_info_t *local;
|
||||
|
||||
DEBUG(0, "airo_attach()\n");
|
||||
|
||||
/* Initialize the dev_link_t structure */
|
||||
link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
|
||||
if (!link) {
|
||||
printk(KERN_ERR "airo_cs: no memory for new device\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Interrupt setup */
|
||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->irq.Handler = NULL;
|
||||
p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
p_dev->irq.Handler = NULL;
|
||||
|
||||
/*
|
||||
General socket configuration defaults can go here. In this
|
||||
|
@ -167,26 +159,18 @@ static int airo_attach(struct pcmcia_device *p_dev)
|
|||
and attributes of IO windows) are fixed by the nature of the
|
||||
device, and can be hard-wired here.
|
||||
*/
|
||||
link->conf.Attributes = 0;
|
||||
link->conf.Vcc = 50;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
p_dev->conf.Attributes = 0;
|
||||
p_dev->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
/* Allocate space for private device-specific data */
|
||||
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
|
||||
if (!local) {
|
||||
printk(KERN_ERR "airo_cs: no memory for new device\n");
|
||||
kfree (link);
|
||||
return -ENOMEM;
|
||||
}
|
||||
link->priv = local;
|
||||
p_dev->priv = local;
|
||||
|
||||
link->handle = p_dev;
|
||||
p_dev->instance = link;
|
||||
|
||||
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
|
||||
airo_config(link);
|
||||
|
||||
return 0;
|
||||
return airo_config(p_dev);
|
||||
} /* airo_attach */
|
||||
|
||||
/*======================================================================
|
||||
|
@ -198,14 +182,11 @@ static int airo_attach(struct pcmcia_device *p_dev)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static void airo_detach(struct pcmcia_device *p_dev)
|
||||
static void airo_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
|
||||
DEBUG(0, "airo_detach(0x%p)\n", link);
|
||||
|
||||
if (link->state & DEV_CONFIG)
|
||||
airo_release(link);
|
||||
airo_release(link);
|
||||
|
||||
if ( ((local_info_t*)link->priv)->eth_dev ) {
|
||||
stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 );
|
||||
|
@ -213,7 +194,6 @@ static void airo_detach(struct pcmcia_device *p_dev)
|
|||
((local_info_t*)link->priv)->eth_dev = NULL;
|
||||
|
||||
kfree(link->priv);
|
||||
kfree(link);
|
||||
} /* airo_detach */
|
||||
|
||||
/*======================================================================
|
||||
|
@ -227,9 +207,8 @@ static void airo_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 airo_config(dev_link_t *link)
|
||||
static int airo_config(struct pcmcia_device *link)
|
||||
{
|
||||
client_handle_t handle;
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
local_info_t *dev;
|
||||
|
@ -237,8 +216,7 @@ static void airo_config(dev_link_t *link)
|
|||
u_char buf[64];
|
||||
win_req_t req;
|
||||
memreq_t map;
|
||||
|
||||
handle = link->handle;
|
||||
|
||||
dev = link->priv;
|
||||
|
||||
DEBUG(0, "airo_config(0x%p)\n", link);
|
||||
|
@ -252,15 +230,12 @@ static void airo_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;
|
||||
|
||||
|
||||
/*
|
||||
In this loop, we scan the CIS for configuration table entries,
|
||||
each of which describes a valid card configuration, including
|
||||
|
@ -274,12 +249,12 @@ static void airo_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;
|
||||
|
@ -294,16 +269,11 @@ static void airo_config(dev_link_t *link)
|
|||
|
||||
/* Use power settings for Vcc and Vpp if present */
|
||||
/* Note that the CIS values need to be rescaled */
|
||||
if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM))
|
||||
link->conf.Vcc = cfg->vcc.param[CISTPL_POWER_VNOM]/10000;
|
||||
else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM))
|
||||
link->conf.Vcc = dflt.vcc.param[CISTPL_POWER_VNOM]/10000;
|
||||
|
||||
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? */
|
||||
|
@ -329,12 +299,12 @@ static void airo_config(dev_link_t *link)
|
|||
}
|
||||
|
||||
/* 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.
|
||||
|
@ -350,7 +320,7 @@ static void airo_config(dev_link_t *link)
|
|||
req.Base = mem->win[0].host_addr;
|
||||
req.Size = mem->win[0].len;
|
||||
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)
|
||||
|
@ -360,7 +330,7 @@ static void airo_config(dev_link_t *link)
|
|||
break;
|
||||
|
||||
next_entry:
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -369,33 +339,32 @@ static void airo_config(dev_link_t *link)
|
|||
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));
|
||||
((local_info_t*)link->priv)->eth_dev =
|
||||
init_airo_card( link->irq.AssignedIRQ,
|
||||
link->io.BasePort1, 1, &handle_to_dev(handle) );
|
||||
link->io.BasePort1, 1, &handle_to_dev(link) );
|
||||
if (!((local_info_t*)link->priv)->eth_dev) goto cs_failed;
|
||||
|
||||
/*
|
||||
At this point, the dev_node_t structure(s) need to be
|
||||
initialized and arranged in a linked list at link->dev.
|
||||
initialized and arranged in a linked list at link->dev_node.
|
||||
*/
|
||||
strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
|
||||
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)
|
||||
|
@ -408,14 +377,12 @@ static void airo_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;
|
||||
return;
|
||||
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
cs_error(link, last_fn, last_ret);
|
||||
airo_release(link);
|
||||
|
||||
return -ENODEV;
|
||||
} /* airo_config */
|
||||
|
||||
/*======================================================================
|
||||
|
@ -426,51 +393,26 @@ static void airo_config(dev_link_t *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static void airo_release(dev_link_t *link)
|
||||
static void airo_release(struct pcmcia_device *link)
|
||||
{
|
||||
DEBUG(0, "airo_release(0x%p)\n", link);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
static int airo_suspend(struct pcmcia_device *p_dev)
|
||||
static int airo_suspend(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
local_info_t *local = link->priv;
|
||||
|
||||
link->state |= DEV_SUSPEND;
|
||||
if (link->state & DEV_CONFIG) {
|
||||
netif_device_detach(local->eth_dev);
|
||||
pcmcia_release_configuration(link->handle);
|
||||
}
|
||||
netif_device_detach(local->eth_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int airo_resume(struct pcmcia_device *p_dev)
|
||||
static int airo_resume(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
local_info_t *local = link->priv;
|
||||
|
||||
link->state &= ~DEV_SUSPEND;
|
||||
if (link->state & DEV_CONFIG) {
|
||||
pcmcia_request_configuration(link->handle, &link->conf);
|
||||
if (link->open) {
|
||||
reset_airo_card(local->eth_dev);
|
||||
netif_device_attach(local->eth_dev);
|
||||
}
|
||||
|
@ -492,7 +434,7 @@ static struct pcmcia_driver airo_driver = {
|
|||
.drv = {
|
||||
.name = "airo_cs",
|
||||
},
|
||||
.probe = airo_attach,
|
||||
.probe = airo_probe,
|
||||
.remove = airo_detach,
|
||||
.id_table = airo_ids,
|
||||
.suspend = airo_suspend,
|
||||
|
|
|
@ -91,8 +91,8 @@ MODULE_SUPPORTED_DEVICE("Atmel at76c50x PCMCIA cards");
|
|||
event handler.
|
||||
*/
|
||||
|
||||
static void atmel_config(dev_link_t *link);
|
||||
static void atmel_release(dev_link_t *link);
|
||||
static int atmel_config(struct pcmcia_device *link);
|
||||
static void atmel_release(struct pcmcia_device *link);
|
||||
|
||||
/*
|
||||
The attach() and detach() entry points are used to create and destroy
|
||||
|
@ -112,10 +112,10 @@ static void atmel_detach(struct pcmcia_device *p_dev);
|
|||
/*
|
||||
A linked list of "instances" of the atmelnet 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.
|
||||
*/
|
||||
|
||||
|
@ -125,7 +125,7 @@ static void atmel_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.
|
||||
|
||||
|
@ -152,24 +152,16 @@ typedef struct local_info_t {
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static int atmel_attach(struct pcmcia_device *p_dev)
|
||||
static int atmel_probe(struct pcmcia_device *p_dev)
|
||||
{
|
||||
dev_link_t *link;
|
||||
local_info_t *local;
|
||||
|
||||
DEBUG(0, "atmel_attach()\n");
|
||||
|
||||
/* Initialize the dev_link_t structure */
|
||||
link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
|
||||
if (!link) {
|
||||
printk(KERN_ERR "atmel_cs: no memory for new device\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Interrupt setup */
|
||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->irq.Handler = NULL;
|
||||
p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
p_dev->irq.Handler = NULL;
|
||||
|
||||
/*
|
||||
General socket configuration defaults can go here. In this
|
||||
|
@ -178,26 +170,18 @@ static int atmel_attach(struct pcmcia_device *p_dev)
|
|||
and attributes of IO windows) are fixed by the nature of the
|
||||
device, and can be hard-wired here.
|
||||
*/
|
||||
link->conf.Attributes = 0;
|
||||
link->conf.Vcc = 50;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
p_dev->conf.Attributes = 0;
|
||||
p_dev->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
/* Allocate space for private device-specific data */
|
||||
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
|
||||
if (!local) {
|
||||
printk(KERN_ERR "atmel_cs: no memory for new device\n");
|
||||
kfree (link);
|
||||
return -ENOMEM;
|
||||
}
|
||||
link->priv = local;
|
||||
p_dev->priv = local;
|
||||
|
||||
link->handle = p_dev;
|
||||
p_dev->instance = link;
|
||||
|
||||
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
|
||||
atmel_config(link);
|
||||
|
||||
return 0;
|
||||
return atmel_config(p_dev);
|
||||
} /* atmel_attach */
|
||||
|
||||
/*======================================================================
|
||||
|
@ -209,17 +193,13 @@ static int atmel_attach(struct pcmcia_device *p_dev)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static void atmel_detach(struct pcmcia_device *p_dev)
|
||||
static void atmel_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
|
||||
DEBUG(0, "atmel_detach(0x%p)\n", link);
|
||||
|
||||
if (link->state & DEV_CONFIG)
|
||||
atmel_release(link);
|
||||
atmel_release(link);
|
||||
|
||||
kfree(link->priv);
|
||||
kfree(link);
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
|
@ -236,19 +216,17 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|||
/* Call-back function to interrogate PCMCIA-specific information
|
||||
about the current existance of the card */
|
||||
static int card_present(void *arg)
|
||||
{
|
||||
dev_link_t *link = (dev_link_t *)arg;
|
||||
if (link->state & DEV_SUSPEND)
|
||||
return 0;
|
||||
else if (link->state & DEV_PRESENT)
|
||||
{
|
||||
struct pcmcia_device *link = (struct pcmcia_device *)arg;
|
||||
|
||||
if (pcmcia_dev_present(link))
|
||||
return 1;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void atmel_config(dev_link_t *link)
|
||||
static int atmel_config(struct pcmcia_device *link)
|
||||
{
|
||||
client_handle_t handle;
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
local_info_t *dev;
|
||||
|
@ -256,9 +234,8 @@ static void atmel_config(dev_link_t *link)
|
|||
u_char buf[64];
|
||||
struct pcmcia_device_id *did;
|
||||
|
||||
handle = link->handle;
|
||||
dev = link->priv;
|
||||
did = handle_to_dev(handle).driver_data;
|
||||
did = handle_to_dev(link).driver_data;
|
||||
|
||||
DEBUG(0, "atmel_config(0x%p)\n", link);
|
||||
|
||||
|
@ -272,15 +249,12 @@ static void atmel_config(dev_link_t *link)
|
|||
registers.
|
||||
*/
|
||||
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, &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;
|
||||
|
||||
|
||||
/*
|
||||
In this loop, we scan the CIS for configuration table entries,
|
||||
each of which describes a valid card configuration, including
|
||||
|
@ -294,12 +268,12 @@ static void atmel_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;
|
||||
|
@ -314,16 +288,11 @@ static void atmel_config(dev_link_t *link)
|
|||
|
||||
/* Use power settings for Vcc and Vpp if present */
|
||||
/* Note that the CIS values need to be rescaled */
|
||||
if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM))
|
||||
link->conf.Vcc = cfg->vcc.param[CISTPL_POWER_VNOM]/10000;
|
||||
else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM))
|
||||
link->conf.Vcc = dflt.vcc.param[CISTPL_POWER_VNOM]/10000;
|
||||
|
||||
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? */
|
||||
|
@ -349,14 +318,14 @@ static void atmel_config(dev_link_t *link)
|
|||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
/* If we got this far, we're cool! */
|
||||
break;
|
||||
|
||||
next_entry:
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -365,14 +334,14 @@ static void atmel_config(dev_link_t *link)
|
|||
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));
|
||||
|
||||
if (link->irq.AssignedIRQ == 0) {
|
||||
printk(KERN_ALERT
|
||||
|
@ -384,7 +353,7 @@ static void atmel_config(dev_link_t *link)
|
|||
init_atmel_card(link->irq.AssignedIRQ,
|
||||
link->io.BasePort1,
|
||||
did ? did->driver_info : ATMEL_FW_TYPE_NONE,
|
||||
&handle_to_dev(handle),
|
||||
&handle_to_dev(link),
|
||||
card_present,
|
||||
link);
|
||||
if (!((local_info_t*)link->priv)->eth_dev)
|
||||
|
@ -393,18 +362,18 @@ static void atmel_config(dev_link_t *link)
|
|||
|
||||
/*
|
||||
At this point, the dev_node_t structure(s) need to be
|
||||
initialized and arranged in a linked list at link->dev.
|
||||
initialized and arranged in a linked list at link->dev_node.
|
||||
*/
|
||||
strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
|
||||
dev->node.major = dev->node.minor = 0;
|
||||
link->dev = &dev->node;
|
||||
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
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);
|
||||
atmel_release(link);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
|
@ -415,53 +384,34 @@ static void atmel_config(dev_link_t *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static void atmel_release(dev_link_t *link)
|
||||
static void atmel_release(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = ((local_info_t*)link->priv)->eth_dev;
|
||||
|
||||
|
||||
DEBUG(0, "atmel_release(0x%p)\n", link);
|
||||
|
||||
/* Unlink the device chain */
|
||||
link->dev = NULL;
|
||||
|
||||
if (dev)
|
||||
|
||||
if (dev)
|
||||
stop_atmel_card(dev);
|
||||
((local_info_t*)link->priv)->eth_dev = NULL;
|
||||
|
||||
/* Don't bother checking to see if these succeed or not */
|
||||
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;
|
||||
((local_info_t*)link->priv)->eth_dev = NULL;
|
||||
|
||||
pcmcia_disable_device(link);
|
||||
}
|
||||
|
||||
static int atmel_suspend(struct pcmcia_device *dev)
|
||||
static int atmel_suspend(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(dev);
|
||||
local_info_t *local = link->priv;
|
||||
|
||||
link->state |= DEV_SUSPEND;
|
||||
if (link->state & DEV_CONFIG) {
|
||||
netif_device_detach(local->eth_dev);
|
||||
pcmcia_release_configuration(link->handle);
|
||||
}
|
||||
netif_device_detach(local->eth_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int atmel_resume(struct pcmcia_device *dev)
|
||||
static int atmel_resume(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(dev);
|
||||
local_info_t *local = link->priv;
|
||||
|
||||
link->state &= ~DEV_SUSPEND;
|
||||
if (link->state & DEV_CONFIG) {
|
||||
pcmcia_request_configuration(link->handle, &link->conf);
|
||||
atmel_open(local->eth_dev);
|
||||
netif_device_attach(local->eth_dev);
|
||||
}
|
||||
atmel_open(local->eth_dev);
|
||||
netif_device_attach(local->eth_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -515,7 +465,7 @@ static struct pcmcia_driver atmel_driver = {
|
|||
.drv = {
|
||||
.name = "atmel_cs",
|
||||
},
|
||||
.probe = atmel_attach,
|
||||
.probe = atmel_probe,
|
||||
.remove = atmel_detach,
|
||||
.id_table = atmel_ids,
|
||||
.suspend = atmel_suspend,
|
||||
|
|
|
@ -42,7 +42,7 @@ MODULE_PARM_DESC(ignore_cis_vcc, "Ignore broken CIS VCC entry");
|
|||
/* struct local_info::hw_priv */
|
||||
struct hostap_cs_priv {
|
||||
dev_node_t node;
|
||||
dev_link_t *link;
|
||||
struct pcmcia_device *link;
|
||||
int sandisk_connectplus;
|
||||
};
|
||||
|
||||
|
@ -204,15 +204,13 @@ static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len)
|
|||
|
||||
static void prism2_detach(struct pcmcia_device *p_dev);
|
||||
static void prism2_release(u_long arg);
|
||||
static int prism2_config(dev_link_t *link);
|
||||
static int prism2_config(struct pcmcia_device *link);
|
||||
|
||||
|
||||
static int prism2_pccard_card_present(local_info_t *local)
|
||||
{
|
||||
struct hostap_cs_priv *hw_priv = local->hw_priv;
|
||||
if (hw_priv != NULL && hw_priv->link != NULL &&
|
||||
((hw_priv->link->state & (DEV_PRESENT | DEV_CONFIG)) ==
|
||||
(DEV_PRESENT | DEV_CONFIG)))
|
||||
if (hw_priv != NULL && hw_priv->link != NULL && pcmcia_dev_present(hw_priv->link))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -237,7 +235,7 @@ static void sandisk_set_iobase(local_info_t *local)
|
|||
reg.Action = CS_WRITE;
|
||||
reg.Offset = 0x10; /* 0x3f0 IO base 1 */
|
||||
reg.Value = hw_priv->link->io.BasePort1 & 0x00ff;
|
||||
res = pcmcia_access_configuration_register(hw_priv->link->handle,
|
||||
res = pcmcia_access_configuration_register(hw_priv->link,
|
||||
®);
|
||||
if (res != CS_SUCCESS) {
|
||||
printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 0 -"
|
||||
|
@ -249,7 +247,7 @@ static void sandisk_set_iobase(local_info_t *local)
|
|||
reg.Action = CS_WRITE;
|
||||
reg.Offset = 0x12; /* 0x3f2 IO base 2 */
|
||||
reg.Value = (hw_priv->link->io.BasePort1 & 0xff00) >> 8;
|
||||
res = pcmcia_access_configuration_register(hw_priv->link->handle,
|
||||
res = pcmcia_access_configuration_register(hw_priv->link,
|
||||
®);
|
||||
if (res != CS_SUCCESS) {
|
||||
printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 1 -"
|
||||
|
@ -301,9 +299,9 @@ static int sandisk_enable_wireless(struct net_device *dev)
|
|||
tuple.TupleData = buf;
|
||||
tuple.TupleDataMax = sizeof(buf);
|
||||
tuple.TupleOffset = 0;
|
||||
if (pcmcia_get_first_tuple(hw_priv->link->handle, &tuple) ||
|
||||
pcmcia_get_tuple_data(hw_priv->link->handle, &tuple) ||
|
||||
pcmcia_parse_tuple(hw_priv->link->handle, &tuple, parse) ||
|
||||
if (pcmcia_get_first_tuple(hw_priv->link, &tuple) ||
|
||||
pcmcia_get_tuple_data(hw_priv->link, &tuple) ||
|
||||
pcmcia_parse_tuple(hw_priv->link, &tuple, parse) ||
|
||||
parse->manfid.manf != 0xd601 || parse->manfid.card != 0x0101) {
|
||||
/* No SanDisk manfid found */
|
||||
ret = -ENODEV;
|
||||
|
@ -311,9 +309,9 @@ static int sandisk_enable_wireless(struct net_device *dev)
|
|||
}
|
||||
|
||||
tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
|
||||
if (pcmcia_get_first_tuple(hw_priv->link->handle, &tuple) ||
|
||||
pcmcia_get_tuple_data(hw_priv->link->handle, &tuple) ||
|
||||
pcmcia_parse_tuple(hw_priv->link->handle, &tuple, parse) ||
|
||||
if (pcmcia_get_first_tuple(hw_priv->link, &tuple) ||
|
||||
pcmcia_get_tuple_data(hw_priv->link, &tuple) ||
|
||||
pcmcia_parse_tuple(hw_priv->link, &tuple, parse) ||
|
||||
parse->longlink_mfc.nfn < 2) {
|
||||
/* No multi-function links found */
|
||||
ret = -ENODEV;
|
||||
|
@ -328,7 +326,7 @@ static int sandisk_enable_wireless(struct net_device *dev)
|
|||
reg.Action = CS_WRITE;
|
||||
reg.Offset = CISREG_COR;
|
||||
reg.Value = COR_SOFT_RESET;
|
||||
res = pcmcia_access_configuration_register(hw_priv->link->handle,
|
||||
res = pcmcia_access_configuration_register(hw_priv->link,
|
||||
®);
|
||||
if (res != CS_SUCCESS) {
|
||||
printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n",
|
||||
|
@ -345,7 +343,7 @@ static int sandisk_enable_wireless(struct net_device *dev)
|
|||
* will be enabled during the first cor_sreset call.
|
||||
*/
|
||||
reg.Value = COR_LEVEL_REQ | 0x8 | COR_ADDR_DECODE | COR_FUNC_ENA;
|
||||
res = pcmcia_access_configuration_register(hw_priv->link->handle,
|
||||
res = pcmcia_access_configuration_register(hw_priv->link,
|
||||
®);
|
||||
if (res != CS_SUCCESS) {
|
||||
printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n",
|
||||
|
@ -380,7 +378,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local)
|
|||
reg.Action = CS_READ;
|
||||
reg.Offset = CISREG_COR;
|
||||
reg.Value = 0;
|
||||
res = pcmcia_access_configuration_register(hw_priv->link->handle,
|
||||
res = pcmcia_access_configuration_register(hw_priv->link,
|
||||
®);
|
||||
if (res != CS_SUCCESS) {
|
||||
printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 1 (%d)\n",
|
||||
|
@ -392,7 +390,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local)
|
|||
|
||||
reg.Action = CS_WRITE;
|
||||
reg.Value |= COR_SOFT_RESET;
|
||||
res = pcmcia_access_configuration_register(hw_priv->link->handle,
|
||||
res = pcmcia_access_configuration_register(hw_priv->link,
|
||||
®);
|
||||
if (res != CS_SUCCESS) {
|
||||
printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 2 (%d)\n",
|
||||
|
@ -405,7 +403,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local)
|
|||
reg.Value &= ~COR_SOFT_RESET;
|
||||
if (hw_priv->sandisk_connectplus)
|
||||
reg.Value |= COR_IREQ_ENA;
|
||||
res = pcmcia_access_configuration_register(hw_priv->link->handle,
|
||||
res = pcmcia_access_configuration_register(hw_priv->link,
|
||||
®);
|
||||
if (res != CS_SUCCESS) {
|
||||
printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 3 (%d)\n",
|
||||
|
@ -439,7 +437,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
|
|||
reg.Action = CS_READ;
|
||||
reg.Offset = CISREG_COR;
|
||||
reg.Value = 0;
|
||||
res = pcmcia_access_configuration_register(hw_priv->link->handle,
|
||||
res = pcmcia_access_configuration_register(hw_priv->link,
|
||||
®);
|
||||
if (res != CS_SUCCESS) {
|
||||
printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 1 "
|
||||
|
@ -452,7 +450,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
|
|||
|
||||
reg.Action = CS_WRITE;
|
||||
reg.Value |= COR_SOFT_RESET;
|
||||
res = pcmcia_access_configuration_register(hw_priv->link->handle,
|
||||
res = pcmcia_access_configuration_register(hw_priv->link,
|
||||
®);
|
||||
if (res != CS_SUCCESS) {
|
||||
printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 2 "
|
||||
|
@ -466,7 +464,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
|
|||
reg.Action = CS_WRITE;
|
||||
reg.Value = hcr;
|
||||
reg.Offset = CISREG_CCSR;
|
||||
res = pcmcia_access_configuration_register(hw_priv->link->handle,
|
||||
res = pcmcia_access_configuration_register(hw_priv->link,
|
||||
®);
|
||||
if (res != CS_SUCCESS) {
|
||||
printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 3 "
|
||||
|
@ -478,7 +476,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
|
|||
reg.Action = CS_WRITE;
|
||||
reg.Offset = CISREG_COR;
|
||||
reg.Value = old_cor & ~COR_SOFT_RESET;
|
||||
res = pcmcia_access_configuration_register(hw_priv->link->handle,
|
||||
res = pcmcia_access_configuration_register(hw_priv->link,
|
||||
®);
|
||||
if (res != CS_SUCCESS) {
|
||||
printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 4 "
|
||||
|
@ -501,40 +499,27 @@ static struct prism2_helper_functions prism2_pccard_funcs =
|
|||
|
||||
/* allocate local data and register with CardServices
|
||||
* initialize dev_link structure, but do not configure the card yet */
|
||||
static int prism2_attach(struct pcmcia_device *p_dev)
|
||||
static int hostap_cs_probe(struct pcmcia_device *p_dev)
|
||||
{
|
||||
dev_link_t *link;
|
||||
|
||||
link = kmalloc(sizeof(dev_link_t), GFP_KERNEL);
|
||||
if (link == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(link, 0, sizeof(dev_link_t));
|
||||
int ret;
|
||||
|
||||
PDEBUG(DEBUG_HW, "%s: setting Vcc=33 (constant)\n", dev_info);
|
||||
link->conf.Vcc = 33;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
p_dev->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
link->handle = p_dev;
|
||||
p_dev->instance = link;
|
||||
|
||||
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
|
||||
if (prism2_config(link))
|
||||
ret = prism2_config(p_dev);
|
||||
if (ret) {
|
||||
PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void prism2_detach(struct pcmcia_device *p_dev)
|
||||
static void prism2_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
|
||||
PDEBUG(DEBUG_FLOW, "prism2_detach\n");
|
||||
|
||||
if (link->state & DEV_CONFIG) {
|
||||
prism2_release((u_long)link);
|
||||
}
|
||||
prism2_release((u_long)link);
|
||||
|
||||
/* release net devices */
|
||||
if (link->priv) {
|
||||
|
@ -547,7 +532,6 @@ static void prism2_detach(struct pcmcia_device *p_dev)
|
|||
prism2_free_local_data(dev);
|
||||
kfree(hw_priv);
|
||||
}
|
||||
kfree(link);
|
||||
}
|
||||
|
||||
|
||||
|
@ -558,7 +542,7 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|||
do { int ret = (retf); \
|
||||
if (ret != 0) { \
|
||||
PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", ret); \
|
||||
cs_error(link->handle, fn, ret); \
|
||||
cs_error(link, fn, ret); \
|
||||
goto next_entry; \
|
||||
} \
|
||||
} while (0)
|
||||
|
@ -566,7 +550,7 @@ if (ret != 0) { \
|
|||
|
||||
/* run after a CARD_INSERTION event is received to configure the PCMCIA
|
||||
* socket and make the device available to the system */
|
||||
static int prism2_config(dev_link_t *link)
|
||||
static int prism2_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev;
|
||||
struct hostap_interface *iface;
|
||||
|
@ -595,27 +579,24 @@ static int prism2_config(dev_link_t *link)
|
|||
tuple.TupleData = buf;
|
||||
tuple.TupleDataMax = sizeof(buf);
|
||||
tuple.TupleOffset = 0;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link->handle, &tuple));
|
||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link->handle, &tuple));
|
||||
CS_CHECK(ParseTuple, pcmcia_parse_tuple(link->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];
|
||||
|
||||
CS_CHECK(GetConfigurationInfo,
|
||||
pcmcia_get_configuration_info(link->handle, &conf));
|
||||
PDEBUG(DEBUG_HW, "%s: %s Vcc=%d (from config)\n", dev_info,
|
||||
ignore_cis_vcc ? "ignoring" : "setting", conf.Vcc);
|
||||
link->conf.Vcc = conf.Vcc;
|
||||
pcmcia_get_configuration_info(link, &conf));
|
||||
|
||||
/* Look for an appropriate configuration table entry in the CIS */
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link->handle, &tuple));
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
for (;;) {
|
||||
cistpl_cftable_entry_t *cfg = &(parse->cftable_entry);
|
||||
CFG_CHECK2(GetTupleData,
|
||||
pcmcia_get_tuple_data(link->handle, &tuple));
|
||||
pcmcia_get_tuple_data(link, &tuple));
|
||||
CFG_CHECK2(ParseTuple,
|
||||
pcmcia_parse_tuple(link->handle, &tuple, parse));
|
||||
pcmcia_parse_tuple(link, &tuple, parse));
|
||||
|
||||
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
|
||||
dflt = *cfg;
|
||||
|
@ -650,10 +631,10 @@ static int prism2_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? */
|
||||
|
@ -695,19 +676,19 @@ static int prism2_config(dev_link_t *link)
|
|||
|
||||
/* This reserves IO space but doesn't actually enable it */
|
||||
CFG_CHECK2(RequestIO,
|
||||
pcmcia_request_io(link->handle, &link->io));
|
||||
pcmcia_request_io(link, &link->io));
|
||||
|
||||
/* This configuration table entry is OK */
|
||||
break;
|
||||
|
||||
next_entry:
|
||||
CS_CHECK(GetNextTuple,
|
||||
pcmcia_get_next_tuple(link->handle, &tuple));
|
||||
pcmcia_get_next_tuple(link, &tuple));
|
||||
}
|
||||
|
||||
/* Need to allocate net_device before requesting IRQ handler */
|
||||
dev = prism2_init_local_data(&prism2_pccard_funcs, 0,
|
||||
&handle_to_dev(link->handle));
|
||||
&handle_to_dev(link));
|
||||
if (dev == NULL)
|
||||
goto failed;
|
||||
link->priv = dev;
|
||||
|
@ -717,7 +698,7 @@ static int prism2_config(dev_link_t *link)
|
|||
local->hw_priv = hw_priv;
|
||||
hw_priv->link = link;
|
||||
strcpy(hw_priv->node.dev_name, dev->name);
|
||||
link->dev = &hw_priv->node;
|
||||
link->dev_node = &hw_priv->node;
|
||||
|
||||
/*
|
||||
* Allocate an interrupt line. Note that this does not assign a
|
||||
|
@ -730,7 +711,7 @@ static int prism2_config(dev_link_t *link)
|
|||
link->irq.Handler = prism2_interrupt;
|
||||
link->irq.Instance = dev;
|
||||
CS_CHECK(RequestIRQ,
|
||||
pcmcia_request_irq(link->handle, &link->irq));
|
||||
pcmcia_request_irq(link, &link->irq));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -739,18 +720,17 @@ static int prism2_config(dev_link_t *link)
|
|||
* card and host interface into "Memory and IO" mode.
|
||||
*/
|
||||
CS_CHECK(RequestConfiguration,
|
||||
pcmcia_request_configuration(link->handle, &link->conf));
|
||||
pcmcia_request_configuration(link, &link->conf));
|
||||
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
|
||||
/* Finally, report what we've done */
|
||||
printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d",
|
||||
dev_info, 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_info, 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)
|
||||
|
@ -761,9 +741,6 @@ static int prism2_config(dev_link_t *link)
|
|||
link->io.BasePort2+link->io.NumPorts2-1);
|
||||
printk("\n");
|
||||
|
||||
link->state |= DEV_CONFIG;
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
|
||||
local->shutdown = 0;
|
||||
|
||||
sandisk_enable_wireless(dev);
|
||||
|
@ -778,7 +755,7 @@ static int prism2_config(dev_link_t *link)
|
|||
return ret;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
cs_error(link, last_fn, last_ret);
|
||||
|
||||
failed:
|
||||
kfree(parse);
|
||||
|
@ -790,7 +767,7 @@ static int prism2_config(dev_link_t *link)
|
|||
|
||||
static void prism2_release(u_long arg)
|
||||
{
|
||||
dev_link_t *link = (dev_link_t *)arg;
|
||||
struct pcmcia_device *link = (struct pcmcia_device *)arg;
|
||||
|
||||
PDEBUG(DEBUG_FLOW, "prism2_release\n");
|
||||
|
||||
|
@ -799,71 +776,54 @@ static void prism2_release(u_long arg)
|
|||
struct hostap_interface *iface;
|
||||
|
||||
iface = netdev_priv(dev);
|
||||
if (link->state & DEV_CONFIG)
|
||||
prism2_hw_shutdown(dev, 0);
|
||||
prism2_hw_shutdown(dev, 0);
|
||||
iface->local->shutdown = 1;
|
||||
}
|
||||
|
||||
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);
|
||||
PDEBUG(DEBUG_FLOW, "release - done\n");
|
||||
}
|
||||
|
||||
static int hostap_cs_suspend(struct pcmcia_device *p_dev)
|
||||
static int hostap_cs_suspend(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct net_device *dev = (struct net_device *) link->priv;
|
||||
int dev_open = 0;
|
||||
struct hostap_interface *iface = NULL;
|
||||
|
||||
if (dev)
|
||||
iface = netdev_priv(dev);
|
||||
|
||||
PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info);
|
||||
|
||||
link->state |= DEV_SUSPEND;
|
||||
|
||||
if (link->state & DEV_CONFIG) {
|
||||
struct hostap_interface *iface = netdev_priv(dev);
|
||||
if (iface && iface->local)
|
||||
dev_open = iface->local->num_dev_open > 0;
|
||||
if (dev_open) {
|
||||
netif_stop_queue(dev);
|
||||
netif_device_detach(dev);
|
||||
}
|
||||
prism2_suspend(dev);
|
||||
pcmcia_release_configuration(link->handle);
|
||||
if (iface && iface->local)
|
||||
dev_open = iface->local->num_dev_open > 0;
|
||||
if (dev_open) {
|
||||
netif_stop_queue(dev);
|
||||
netif_device_detach(dev);
|
||||
}
|
||||
prism2_suspend(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hostap_cs_resume(struct pcmcia_device *p_dev)
|
||||
static int hostap_cs_resume(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct net_device *dev = (struct net_device *) link->priv;
|
||||
int dev_open = 0;
|
||||
struct hostap_interface *iface = NULL;
|
||||
|
||||
if (dev)
|
||||
iface = netdev_priv(dev);
|
||||
|
||||
PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info);
|
||||
|
||||
link->state &= ~DEV_SUSPEND;
|
||||
if (link->state & DEV_CONFIG) {
|
||||
struct hostap_interface *iface = netdev_priv(dev);
|
||||
if (iface && iface->local)
|
||||
dev_open = iface->local->num_dev_open > 0;
|
||||
if (iface && iface->local)
|
||||
dev_open = iface->local->num_dev_open > 0;
|
||||
|
||||
pcmcia_request_configuration(link->handle, &link->conf);
|
||||
|
||||
prism2_hw_shutdown(dev, 1);
|
||||
prism2_hw_config(dev, dev_open ? 0 : 1);
|
||||
if (dev_open) {
|
||||
netif_device_attach(dev);
|
||||
netif_start_queue(dev);
|
||||
}
|
||||
prism2_hw_shutdown(dev, 1);
|
||||
prism2_hw_config(dev, dev_open ? 0 : 1);
|
||||
if (dev_open) {
|
||||
netif_device_attach(dev);
|
||||
netif_start_queue(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -930,7 +890,7 @@ static struct pcmcia_driver hostap_driver = {
|
|||
.drv = {
|
||||
.name = "hostap_cs",
|
||||
},
|
||||
.probe = prism2_attach,
|
||||
.probe = hostap_cs_probe,
|
||||
.remove = prism2_detach,
|
||||
.owner = THIS_MODULE,
|
||||
.id_table = hostap_cs_ids,
|
||||
|
|
|
@ -190,8 +190,8 @@ module_param(mem_speed, int, 0);
|
|||
/*====================================================================*/
|
||||
|
||||
/* PCMCIA (Card Services) related functions */
|
||||
static void netwave_release(dev_link_t *link); /* Card removal */
|
||||
static void netwave_pcmcia_config(dev_link_t *arg); /* Runs after card
|
||||
static void netwave_release(struct pcmcia_device *link); /* Card removal */
|
||||
static int netwave_pcmcia_config(struct pcmcia_device *arg); /* Runs after card
|
||||
insertion */
|
||||
static void netwave_detach(struct pcmcia_device *p_dev); /* Destroy instance */
|
||||
|
||||
|
@ -221,10 +221,10 @@ static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev);
|
|||
static void set_multicast_list(struct net_device *dev);
|
||||
|
||||
/*
|
||||
A dev_link_t structure has fields for most things that are needed
|
||||
A struct pcmcia_device structure has fields for most things that are needed
|
||||
to keep track of a socket, but there will usually be some device
|
||||
specific information that also needs to be kept track of. The
|
||||
'priv' pointer in a dev_link_t structure can be used to point to
|
||||
'priv' pointer in a struct pcmcia_device structure can be used to point to
|
||||
a device-specific private data structure, like this.
|
||||
|
||||
A driver needs to provide a dev_node_t structure for each device
|
||||
|
@ -232,7 +232,7 @@ static void set_multicast_list(struct net_device *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.
|
||||
*/
|
||||
|
@ -268,7 +268,7 @@ struct site_survey {
|
|||
};
|
||||
|
||||
typedef struct netwave_private {
|
||||
dev_link_t link;
|
||||
struct pcmcia_device *p_dev;
|
||||
spinlock_t spinlock; /* Serialize access to the hardware (SMP) */
|
||||
dev_node_t node;
|
||||
u_char __iomem *ramBase;
|
||||
|
@ -376,20 +376,19 @@ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)
|
|||
* configure the card at this point -- we wait until we receive a
|
||||
* card insertion event.
|
||||
*/
|
||||
static int netwave_attach(struct pcmcia_device *p_dev)
|
||||
static int netwave_probe(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link;
|
||||
struct net_device *dev;
|
||||
netwave_private *priv;
|
||||
|
||||
DEBUG(0, "netwave_attach()\n");
|
||||
|
||||
/* Initialize the dev_link_t structure */
|
||||
/* Initialize the struct pcmcia_device structure */
|
||||
dev = alloc_etherdev(sizeof(netwave_private));
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
priv = netdev_priv(dev);
|
||||
link = &priv->link;
|
||||
priv->p_dev = link;
|
||||
link->priv = dev;
|
||||
|
||||
/* The io structure describes IO port mapping */
|
||||
|
@ -406,7 +405,6 @@ static int netwave_attach(struct pcmcia_device *p_dev)
|
|||
|
||||
/* 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;
|
||||
|
@ -430,13 +428,7 @@ static int netwave_attach(struct pcmcia_device *p_dev)
|
|||
dev->stop = &netwave_close;
|
||||
link->irq.Instance = dev;
|
||||
|
||||
link->handle = p_dev;
|
||||
p_dev->instance = link;
|
||||
|
||||
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
|
||||
netwave_pcmcia_config( link);
|
||||
|
||||
return 0;
|
||||
return netwave_pcmcia_config( link);
|
||||
} /* netwave_attach */
|
||||
|
||||
/*
|
||||
|
@ -447,17 +439,15 @@ static int netwave_attach(struct pcmcia_device *p_dev)
|
|||
* structures are freed. Otherwise, the structures will be freed
|
||||
* when the device is released.
|
||||
*/
|
||||
static void netwave_detach(struct pcmcia_device *p_dev)
|
||||
static void netwave_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
DEBUG(0, "netwave_detach(0x%p)\n", link);
|
||||
|
||||
if (link->state & DEV_CONFIG)
|
||||
netwave_release(link);
|
||||
netwave_release(link);
|
||||
|
||||
if (link->dev)
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
||||
free_netdev(dev);
|
||||
|
@ -743,8 +733,7 @@ static const struct iw_handler_def netwave_handler_def =
|
|||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static void netwave_pcmcia_config(dev_link_t *link) {
|
||||
client_handle_t handle = link->handle;
|
||||
static int netwave_pcmcia_config(struct pcmcia_device *link) {
|
||||
struct net_device *dev = link->priv;
|
||||
netwave_private *priv = netdev_priv(dev);
|
||||
tuple_t tuple;
|
||||
|
@ -766,15 +755,12 @@ static void netwave_pcmcia_config(dev_link_t *link) {
|
|||
tuple.TupleDataMax = 64;
|
||||
tuple.TupleOffset = 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, &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;
|
||||
|
||||
/*
|
||||
* Try allocating IO ports. This tries a few fixed addresses.
|
||||
* If you want, you can also read the card's config table to
|
||||
|
@ -782,11 +768,11 @@ static void netwave_pcmcia_config(dev_link_t *link) {
|
|||
*/
|
||||
for (i = j = 0x0; 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;
|
||||
}
|
||||
|
||||
|
@ -794,16 +780,16 @@ static void netwave_pcmcia_config(dev_link_t *link) {
|
|||
* Now allocate an interrupt line. Note that this does not
|
||||
* actually assign a handler to the interrupt.
|
||||
*/
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(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.
|
||||
*/
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
|
||||
/*
|
||||
* Allocate a 32K memory window. Note that the dev_link_t
|
||||
* Allocate a 32K memory window. Note that the struct pcmcia_device
|
||||
* structure provides space for one window handle -- if your
|
||||
* device needs several windows, you'll need to keep track of
|
||||
* the handles in your private data structure, dev->priv.
|
||||
|
@ -813,7 +799,7 @@ static void netwave_pcmcia_config(dev_link_t *link) {
|
|||
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
|
||||
req.Base = 0; req.Size = 0x8000;
|
||||
req.AccessSpeed = mem_speed;
|
||||
CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win));
|
||||
CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
|
||||
mem.CardOffset = 0x20000; mem.Page = 0;
|
||||
CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
|
||||
|
||||
|
@ -823,7 +809,7 @@ static void netwave_pcmcia_config(dev_link_t *link) {
|
|||
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(handle));
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
|
||||
if (register_netdev(dev) != 0) {
|
||||
printk(KERN_DEBUG "netwave_cs: register_netdev() failed\n");
|
||||
|
@ -831,8 +817,7 @@ static void netwave_pcmcia_config(dev_link_t *link) {
|
|||
}
|
||||
|
||||
strcpy(priv->node.dev_name, dev->name);
|
||||
link->dev = &priv->node;
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
link->dev_node = &priv->node;
|
||||
|
||||
/* Reset card before reading physical address */
|
||||
netwave_doreset(dev->base_addr, ramBase);
|
||||
|
@ -852,12 +837,13 @@ static void netwave_pcmcia_config(dev_link_t *link) {
|
|||
printk(KERN_DEBUG "Netwave_reset: revision %04x %04x\n",
|
||||
get_uint16(ramBase + NETWAVE_EREG_ARW),
|
||||
get_uint16(ramBase + NETWAVE_EREG_ARW+2));
|
||||
return;
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
netwave_release(link);
|
||||
return -ENODEV;
|
||||
} /* netwave_pcmcia_config */
|
||||
|
||||
/*
|
||||
|
@ -867,52 +853,35 @@ static void netwave_pcmcia_config(dev_link_t *link) {
|
|||
* device, and release the PCMCIA configuration. If the device is
|
||||
* still open, this will be postponed until it is closed.
|
||||
*/
|
||||
static void netwave_release(dev_link_t *link)
|
||||
static void netwave_release(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
netwave_private *priv = netdev_priv(dev);
|
||||
struct net_device *dev = link->priv;
|
||||
netwave_private *priv = netdev_priv(dev);
|
||||
|
||||
DEBUG(0, "netwave_release(0x%p)\n", link);
|
||||
DEBUG(0, "netwave_release(0x%p)\n", link);
|
||||
|
||||
/* Don't bother checking to see if these succeed or not */
|
||||
if (link->win) {
|
||||
iounmap(priv->ramBase);
|
||||
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);
|
||||
if (link->win)
|
||||
iounmap(priv->ramBase);
|
||||
}
|
||||
|
||||
static int netwave_suspend(struct pcmcia_device *p_dev)
|
||||
static int netwave_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 netwave_resume(struct pcmcia_device *p_dev)
|
||||
static int netwave_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) {
|
||||
netwave_reset(dev);
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
if (link->open) {
|
||||
netwave_reset(dev);
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1119,7 +1088,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id, struct pt_regs *regs
|
|||
u_char __iomem *ramBase;
|
||||
struct net_device *dev = (struct net_device *)dev_id;
|
||||
struct netwave_private *priv = netdev_priv(dev);
|
||||
dev_link_t *link = &priv->link;
|
||||
struct pcmcia_device *link = priv->p_dev;
|
||||
int i;
|
||||
|
||||
if (!netif_device_present(dev))
|
||||
|
@ -1138,7 +1107,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id, struct pt_regs *regs
|
|||
|
||||
status = inb(iobase + NETWAVE_REG_ASR);
|
||||
|
||||
if (!DEV_OK(link)) {
|
||||
if (!pcmcia_dev_present(link)) {
|
||||
DEBUG(1, "netwave_interrupt: Interrupt with status 0x%x "
|
||||
"from removed or suspended card!\n", status);
|
||||
break;
|
||||
|
@ -1373,11 +1342,11 @@ static int netwave_rx(struct net_device *dev)
|
|||
|
||||
static int netwave_open(struct net_device *dev) {
|
||||
netwave_private *priv = netdev_priv(dev);
|
||||
dev_link_t *link = &priv->link;
|
||||
struct pcmcia_device *link = priv->p_dev;
|
||||
|
||||
DEBUG(1, "netwave_open: starting.\n");
|
||||
|
||||
if (!DEV_OK(link))
|
||||
if (!pcmcia_dev_present(link))
|
||||
return -ENODEV;
|
||||
|
||||
link->open++;
|
||||
|
@ -1390,7 +1359,7 @@ static int netwave_open(struct net_device *dev) {
|
|||
|
||||
static int netwave_close(struct net_device *dev) {
|
||||
netwave_private *priv = netdev_priv(dev);
|
||||
dev_link_t *link = &priv->link;
|
||||
struct pcmcia_device *link = priv->p_dev;
|
||||
|
||||
DEBUG(1, "netwave_close: finishing.\n");
|
||||
|
||||
|
@ -1411,7 +1380,7 @@ static struct pcmcia_driver netwave_driver = {
|
|||
.drv = {
|
||||
.name = "netwave_cs",
|
||||
},
|
||||
.probe = netwave_attach,
|
||||
.probe = netwave_probe,
|
||||
.remove = netwave_detach,
|
||||
.id_table = netwave_ids,
|
||||
.suspend = netwave_suspend,
|
||||
|
|
|
@ -49,7 +49,7 @@ MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket
|
|||
/* PCMCIA specific device information (goes in the card field of
|
||||
* struct orinoco_private */
|
||||
struct orinoco_pccard {
|
||||
dev_link_t link;
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
|
||||
/* Used to handle hard reset */
|
||||
|
@ -63,8 +63,8 @@ struct orinoco_pccard {
|
|||
/* Function prototypes */
|
||||
/********************************************************************/
|
||||
|
||||
static void orinoco_cs_config(dev_link_t *link);
|
||||
static void orinoco_cs_release(dev_link_t *link);
|
||||
static int orinoco_cs_config(struct pcmcia_device *link);
|
||||
static void orinoco_cs_release(struct pcmcia_device *link);
|
||||
static void orinoco_cs_detach(struct pcmcia_device *p_dev);
|
||||
|
||||
/********************************************************************/
|
||||
|
@ -75,13 +75,13 @@ static int
|
|||
orinoco_cs_hard_reset(struct orinoco_private *priv)
|
||||
{
|
||||
struct orinoco_pccard *card = priv->card;
|
||||
dev_link_t *link = &card->link;
|
||||
struct pcmcia_device *link = card->p_dev;
|
||||
int err;
|
||||
|
||||
/* We need atomic ops here, because we're not holding the lock */
|
||||
set_bit(0, &card->hard_reset_in_progress);
|
||||
|
||||
err = pcmcia_reset_card(link->handle, NULL);
|
||||
err = pcmcia_reset_card(link, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -104,12 +104,11 @@ orinoco_cs_hard_reset(struct orinoco_private *priv)
|
|||
* configure the card at this point -- we wait until we receive a card
|
||||
* insertion event. */
|
||||
static int
|
||||
orinoco_cs_attach(struct pcmcia_device *p_dev)
|
||||
orinoco_cs_probe(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev;
|
||||
struct orinoco_private *priv;
|
||||
struct orinoco_pccard *card;
|
||||
dev_link_t *link;
|
||||
|
||||
dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset);
|
||||
if (! dev)
|
||||
|
@ -118,7 +117,7 @@ orinoco_cs_attach(struct pcmcia_device *p_dev)
|
|||
card = priv->card;
|
||||
|
||||
/* Link both structures together */
|
||||
link = &card->link;
|
||||
card->p_dev = link;
|
||||
link->priv = dev;
|
||||
|
||||
/* Interrupt setup */
|
||||
|
@ -135,16 +134,7 @@ orinoco_cs_attach(struct pcmcia_device *p_dev)
|
|||
link->conf.Attributes = 0;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
/* Register with Card Services */
|
||||
link->next = NULL;
|
||||
|
||||
link->handle = p_dev;
|
||||
p_dev->instance = link;
|
||||
|
||||
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
|
||||
orinoco_cs_config(link);
|
||||
|
||||
return 0;
|
||||
return orinoco_cs_config(link);
|
||||
} /* orinoco_cs_attach */
|
||||
|
||||
/*
|
||||
|
@ -153,16 +143,14 @@ orinoco_cs_attach(struct pcmcia_device *p_dev)
|
|||
* are freed. Otherwise, the structures will be freed when the device
|
||||
* is released.
|
||||
*/
|
||||
static void orinoco_cs_detach(struct pcmcia_device *p_dev)
|
||||
static void orinoco_cs_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
if (link->state & DEV_CONFIG)
|
||||
orinoco_cs_release(link);
|
||||
orinoco_cs_release(link);
|
||||
|
||||
DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev);
|
||||
if (link->dev) {
|
||||
DEBUG(0, PFX "detach: link=%p link->dev_node=%p\n", link, link->dev_node);
|
||||
if (link->dev_node) {
|
||||
DEBUG(0, PFX "About to unregister net device %p\n",
|
||||
dev);
|
||||
unregister_netdev(dev);
|
||||
|
@ -180,11 +168,10 @@ static void orinoco_cs_detach(struct pcmcia_device *p_dev)
|
|||
last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; \
|
||||
} while (0)
|
||||
|
||||
static void
|
||||
orinoco_cs_config(dev_link_t *link)
|
||||
static int
|
||||
orinoco_cs_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
client_handle_t handle = link->handle;
|
||||
struct orinoco_private *priv = netdev_priv(dev);
|
||||
struct orinoco_pccard *card = priv->card;
|
||||
hermes_t *hw = &priv->hw;
|
||||
|
@ -196,7 +183,7 @@ orinoco_cs_config(dev_link_t *link)
|
|||
cisparse_t parse;
|
||||
void __iomem *mem;
|
||||
|
||||
CS_CHECK(ValidateCIS, pcmcia_validate_cis(handle, &info));
|
||||
CS_CHECK(ValidateCIS, pcmcia_validate_cis(link, &info));
|
||||
|
||||
/*
|
||||
* This reads the card's CONFIG tuple to find its
|
||||
|
@ -207,19 +194,15 @@ orinoco_cs_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;
|
||||
pcmcia_get_configuration_info(link, &conf));
|
||||
|
||||
/*
|
||||
* In this loop, we scan the CIS for configuration table
|
||||
|
@ -236,13 +219,13 @@ orinoco_cs_config(dev_link_t *link)
|
|||
* 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 *cfg = &(parse.cftable_entry);
|
||||
cistpl_cftable_entry_t dflt = { .index = 0 };
|
||||
|
||||
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)
|
||||
|
@ -274,10 +257,10 @@ orinoco_cs_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? */
|
||||
|
@ -307,7 +290,7 @@ orinoco_cs_config(dev_link_t *link)
|
|||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
@ -317,9 +300,8 @@ orinoco_cs_config(dev_link_t *link)
|
|||
break;
|
||||
|
||||
next_entry:
|
||||
if (link->io.NumPorts1)
|
||||
pcmcia_release_io(link->handle, &link->io);
|
||||
last_ret = pcmcia_get_next_tuple(handle, &tuple);
|
||||
pcmcia_disable_device(link);
|
||||
last_ret = pcmcia_get_next_tuple(link, &tuple);
|
||||
if (last_ret == CS_NO_MORE_ITEMS) {
|
||||
printk(KERN_ERR PFX "GetNextTuple(): No matching "
|
||||
"CIS configuration. Maybe you need the "
|
||||
|
@ -333,7 +315,7 @@ orinoco_cs_config(dev_link_t *link)
|
|||
* a handler to the interrupt, unless the 'Handler' member of
|
||||
* the irq structure is initialized.
|
||||
*/
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
|
||||
/* We initialize the hermes structure before completing PCMCIA
|
||||
* configuration just in case the interrupt handler gets
|
||||
|
@ -350,7 +332,7 @@ orinoco_cs_config(dev_link_t *link)
|
|||
* card and host interface into "Memory and IO" mode.
|
||||
*/
|
||||
CS_CHECK(RequestConfiguration,
|
||||
pcmcia_request_configuration(link->handle, &link->conf));
|
||||
pcmcia_request_configuration(link, &link->conf));
|
||||
|
||||
/* Ok, we have the configuration, prepare to register the netdev */
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
|
@ -358,7 +340,7 @@ orinoco_cs_config(dev_link_t *link)
|
|||
SET_MODULE_OWNER(dev);
|
||||
card->node.major = card->node.minor = 0;
|
||||
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(handle));
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
/* Tell the stack we exist */
|
||||
if (register_netdev(dev) != 0) {
|
||||
printk(KERN_ERR PFX "register_netdev() failed\n");
|
||||
|
@ -366,20 +348,18 @@ orinoco_cs_config(dev_link_t *link)
|
|||
}
|
||||
|
||||
/* At this point, the dev_node_t structure(s) needs to be
|
||||
* initialized and arranged in a linked list at link->dev. */
|
||||
* initialized and arranged in a linked list at link->dev_node. */
|
||||
strcpy(card->node.dev_name, dev->name);
|
||||
link->dev = &card->node; /* link->dev being non-NULL is also
|
||||
link->dev_node = &card->node; /* link->dev_node being non-NULL is also
|
||||
used to indicate that the
|
||||
net_device has been registered */
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
|
||||
/* Finally, report what we've done */
|
||||
printk(KERN_DEBUG "%s: index 0x%02x: Vcc %d.%d",
|
||||
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_DEBUG "%s: index 0x%02x: ",
|
||||
dev->name, link->conf.ConfigIndex);
|
||||
if (link->conf.Vpp)
|
||||
printk(", Vpp %d.%d", link->conf.Vpp / 10,
|
||||
link->conf.Vpp % 10);
|
||||
printk(", irq %d", link->irq.AssignedIRQ);
|
||||
if (link->io.NumPorts1)
|
||||
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
|
||||
|
@ -389,13 +369,14 @@ orinoco_cs_config(dev_link_t *link)
|
|||
link->io.BasePort2 + link->io.NumPorts2 - 1);
|
||||
printk("\n");
|
||||
|
||||
return;
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
cs_error(link, last_fn, last_ret);
|
||||
|
||||
failed:
|
||||
orinoco_cs_release(link);
|
||||
return -ENODEV;
|
||||
} /* orinoco_cs_config */
|
||||
|
||||
/*
|
||||
|
@ -404,7 +385,7 @@ orinoco_cs_config(dev_link_t *link)
|
|||
* still open, this will be postponed until it is closed.
|
||||
*/
|
||||
static void
|
||||
orinoco_cs_release(dev_link_t *link)
|
||||
orinoco_cs_release(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
struct orinoco_private *priv = netdev_priv(dev);
|
||||
|
@ -416,88 +397,68 @@ orinoco_cs_release(dev_link_t *link)
|
|||
priv->hw_unavailable++;
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
/* Don't bother checking to see if these succeed or not */
|
||||
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);
|
||||
if (priv->hw.iobase)
|
||||
ioport_unmap(priv->hw.iobase);
|
||||
} /* orinoco_cs_release */
|
||||
|
||||
static int orinoco_cs_suspend(struct pcmcia_device *p_dev)
|
||||
static int orinoco_cs_suspend(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct net_device *dev = link->priv;
|
||||
struct orinoco_private *priv = netdev_priv(dev);
|
||||
struct orinoco_pccard *card = priv->card;
|
||||
int err = 0;
|
||||
unsigned long flags;
|
||||
|
||||
link->state |= DEV_SUSPEND;
|
||||
if (link->state & DEV_CONFIG) {
|
||||
/* This is probably racy, but I can't think of
|
||||
a better way, short of rewriting the PCMCIA
|
||||
layer to not suck :-( */
|
||||
if (! test_bit(0, &card->hard_reset_in_progress)) {
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
/* This is probably racy, but I can't think of
|
||||
a better way, short of rewriting the PCMCIA
|
||||
layer to not suck :-( */
|
||||
if (! test_bit(0, &card->hard_reset_in_progress)) {
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
|
||||
err = __orinoco_down(dev);
|
||||
if (err)
|
||||
printk(KERN_WARNING "%s: Error %d downing interface\n",
|
||||
dev->name, err);
|
||||
err = __orinoco_down(dev);
|
||||
if (err)
|
||||
printk(KERN_WARNING "%s: Error %d downing interface\n",
|
||||
dev->name, err);
|
||||
|
||||
netif_device_detach(dev);
|
||||
priv->hw_unavailable++;
|
||||
netif_device_detach(dev);
|
||||
priv->hw_unavailable++;
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
pcmcia_release_configuration(link->handle);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int orinoco_cs_resume(struct pcmcia_device *p_dev)
|
||||
static int orinoco_cs_resume(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct net_device *dev = link->priv;
|
||||
struct orinoco_private *priv = netdev_priv(dev);
|
||||
struct orinoco_pccard *card = priv->card;
|
||||
int err = 0;
|
||||
unsigned long flags;
|
||||
|
||||
link->state &= ~DEV_SUSPEND;
|
||||
if (link->state & DEV_CONFIG) {
|
||||
/* FIXME: should we double check that this is
|
||||
* the same card as we had before */
|
||||
pcmcia_request_configuration(link->handle, &link->conf);
|
||||
|
||||
if (! test_bit(0, &card->hard_reset_in_progress)) {
|
||||
err = orinoco_reinit_firmware(dev);
|
||||
if (err) {
|
||||
printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
|
||||
dev->name, err);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
|
||||
netif_device_attach(dev);
|
||||
priv->hw_unavailable--;
|
||||
|
||||
if (priv->open && ! priv->hw_unavailable) {
|
||||
err = __orinoco_up(dev);
|
||||
if (err)
|
||||
printk(KERN_ERR "%s: Error %d restarting card\n",
|
||||
dev->name, err);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
if (! test_bit(0, &card->hard_reset_in_progress)) {
|
||||
err = orinoco_reinit_firmware(dev);
|
||||
if (err) {
|
||||
printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
|
||||
dev->name, err);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
|
||||
netif_device_attach(dev);
|
||||
priv->hw_unavailable--;
|
||||
|
||||
if (priv->open && ! priv->hw_unavailable) {
|
||||
err = __orinoco_up(dev);
|
||||
if (err)
|
||||
printk(KERN_ERR "%s: Error %d restarting card\n",
|
||||
dev->name, err);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -604,7 +565,7 @@ static struct pcmcia_driver orinoco_driver = {
|
|||
.drv = {
|
||||
.name = DRIVER_NAME,
|
||||
},
|
||||
.probe = orinoco_cs_attach,
|
||||
.probe = orinoco_cs_probe,
|
||||
.remove = orinoco_cs_detach,
|
||||
.id_table = orinoco_cs_ids,
|
||||
.suspend = orinoco_cs_suspend,
|
||||
|
|
|
@ -90,8 +90,8 @@ module_param(pc_debug, int, 0);
|
|||
#define DEBUG(n, args...)
|
||||
#endif
|
||||
/** Prototypes based on PCMCIA skeleton driver *******************************/
|
||||
static void ray_config(dev_link_t *link);
|
||||
static void ray_release(dev_link_t *link);
|
||||
static int ray_config(struct pcmcia_device *link);
|
||||
static void ray_release(struct pcmcia_device *link);
|
||||
static void ray_detach(struct pcmcia_device *p_dev);
|
||||
|
||||
/***** Prototypes indicated by device structure ******************************/
|
||||
|
@ -190,20 +190,17 @@ static int bc;
|
|||
static char *phy_addr = NULL;
|
||||
|
||||
|
||||
/* A linked list of "instances" of the ray device. Each actual
|
||||
PCMCIA card corresponds to one device instance, and is described
|
||||
by one dev_link_t structure (defined in ds.h).
|
||||
*/
|
||||
static dev_link_t *dev_list = NULL;
|
||||
|
||||
/* A dev_link_t structure has fields for most things that are needed
|
||||
/* A struct pcmcia_device structure has fields for most things that are needed
|
||||
to keep track of a socket, but there will usually be some device
|
||||
specific information that also needs to be kept track of. The
|
||||
'priv' pointer in a dev_link_t structure can be used to point to
|
||||
'priv' pointer in a struct pcmcia_device structure can be used to point to
|
||||
a device-specific private data structure, like this.
|
||||
*/
|
||||
static unsigned int ray_mem_speed = 500;
|
||||
|
||||
/* WARNING: THIS DRIVER IS NOT CAPABLE OF HANDLING MULTIPLE DEVICES! */
|
||||
static struct pcmcia_device *this_device = NULL;
|
||||
|
||||
MODULE_AUTHOR("Corey Thomas <corey@world.std.com>");
|
||||
MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -306,56 +303,46 @@ static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.
|
|||
configure the card at this point -- we wait until we receive a
|
||||
card insertion event.
|
||||
=============================================================================*/
|
||||
static int ray_attach(struct pcmcia_device *p_dev)
|
||||
static int ray_probe(struct pcmcia_device *p_dev)
|
||||
{
|
||||
dev_link_t *link;
|
||||
ray_dev_t *local;
|
||||
struct net_device *dev;
|
||||
|
||||
|
||||
DEBUG(1, "ray_attach()\n");
|
||||
|
||||
/* Initialize the dev_link_t structure */
|
||||
link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
|
||||
|
||||
if (!link)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Allocate space for private device-specific data */
|
||||
dev = alloc_etherdev(sizeof(ray_dev_t));
|
||||
|
||||
if (!dev)
|
||||
goto fail_alloc_dev;
|
||||
|
||||
local = dev->priv;
|
||||
|
||||
memset(link, 0, sizeof(struct dev_link_t));
|
||||
local->finder = p_dev;
|
||||
|
||||
/* The io structure describes IO port mapping. None used here */
|
||||
link->io.NumPorts1 = 0;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
link->io.IOAddrLines = 5;
|
||||
p_dev->io.NumPorts1 = 0;
|
||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
p_dev->io.IOAddrLines = 5;
|
||||
|
||||
/* Interrupt setup. For PCMCIA, driver takes what's given */
|
||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->irq.Handler = &ray_interrupt;
|
||||
p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
|
||||
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
p_dev->irq.Handler = &ray_interrupt;
|
||||
|
||||
/* 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->priv = dev;
|
||||
link->irq.Instance = dev;
|
||||
p_dev->priv = dev;
|
||||
p_dev->irq.Instance = dev;
|
||||
|
||||
local->finder = link;
|
||||
local->finder = p_dev;
|
||||
local->card_status = CARD_INSERTED;
|
||||
local->authentication_state = UNAUTHENTICATED;
|
||||
local->num_multi = 0;
|
||||
DEBUG(2,"ray_attach link = %p, dev = %p, local = %p, intr = %p\n",
|
||||
link,dev,local,&ray_interrupt);
|
||||
DEBUG(2,"ray_attach p_dev = %p, dev = %p, local = %p, intr = %p\n",
|
||||
p_dev,dev,local,&ray_interrupt);
|
||||
|
||||
/* Raylink entries in the device structure */
|
||||
dev->hard_start_xmit = &ray_dev_start_xmit;
|
||||
|
@ -379,16 +366,10 @@ static int ray_attach(struct pcmcia_device *p_dev)
|
|||
|
||||
init_timer(&local->timer);
|
||||
|
||||
link->handle = p_dev;
|
||||
p_dev->instance = link;
|
||||
|
||||
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
|
||||
ray_config(link);
|
||||
|
||||
return 0;
|
||||
this_device = p_dev;
|
||||
return ray_config(p_dev);
|
||||
|
||||
fail_alloc_dev:
|
||||
kfree(link);
|
||||
return -ENOMEM;
|
||||
} /* ray_attach */
|
||||
/*=============================================================================
|
||||
|
@ -397,37 +378,25 @@ static int ray_attach(struct pcmcia_device *p_dev)
|
|||
structures are freed. Otherwise, the structures will be freed
|
||||
when the device is released.
|
||||
=============================================================================*/
|
||||
static void ray_detach(struct pcmcia_device *p_dev)
|
||||
static void ray_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
dev_link_t **linkp;
|
||||
struct net_device *dev;
|
||||
ray_dev_t *local;
|
||||
|
||||
DEBUG(1, "ray_detach(0x%p)\n", link);
|
||||
|
||||
/* Locate device structure */
|
||||
for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
|
||||
if (*linkp == link) break;
|
||||
if (*linkp == NULL)
|
||||
return;
|
||||
|
||||
this_device = NULL;
|
||||
dev = link->priv;
|
||||
|
||||
if (link->state & DEV_CONFIG) {
|
||||
ray_release(link);
|
||||
ray_release(link);
|
||||
|
||||
local = (ray_dev_t *)dev->priv;
|
||||
del_timer(&local->timer);
|
||||
}
|
||||
local = (ray_dev_t *)dev->priv;
|
||||
del_timer(&local->timer);
|
||||
|
||||
/* Unlink device structure, free pieces */
|
||||
*linkp = link->next;
|
||||
if (link->priv) {
|
||||
if (link->dev) unregister_netdev(dev);
|
||||
if (link->dev_node) unregister_netdev(dev);
|
||||
free_netdev(dev);
|
||||
}
|
||||
kfree(link);
|
||||
DEBUG(2,"ray_cs ray_detach ending\n");
|
||||
} /* ray_detach */
|
||||
/*=============================================================================
|
||||
|
@ -438,9 +407,8 @@ static void ray_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)
|
||||
#define MAX_TUPLE_SIZE 128
|
||||
static void ray_config(dev_link_t *link)
|
||||
static int ray_config(struct pcmcia_device *link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
int last_fn = 0, last_ret = 0;
|
||||
|
@ -455,48 +423,45 @@ static void ray_config(dev_link_t *link)
|
|||
|
||||
/* This reads the card's CONFIG tuple to find its configuration regs */
|
||||
tuple.DesiredTuple = CISTPL_CONFIG;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
tuple.TupleData = buf;
|
||||
tuple.TupleDataMax = MAX_TUPLE_SIZE;
|
||||
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];
|
||||
|
||||
/* Determine card type and firmware version */
|
||||
buf[0] = buf[MAX_TUPLE_SIZE - 1] = 0;
|
||||
tuple.DesiredTuple = CISTPL_VERS_1;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
tuple.TupleData = buf;
|
||||
tuple.TupleDataMax = MAX_TUPLE_SIZE;
|
||||
tuple.TupleOffset = 2;
|
||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
|
||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
|
||||
|
||||
for (i=0; i<tuple.TupleDataLen - 4; i++)
|
||||
if (buf[i] == 0) buf[i] = ' ';
|
||||
printk(KERN_INFO "ray_cs Detected: %s\n",buf);
|
||||
|
||||
/* Configure card */
|
||||
link->state |= DEV_CONFIG;
|
||||
|
||||
/* Now allocate an interrupt line. Note that this does not
|
||||
actually assign a handler to the interrupt.
|
||||
*/
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
|
||||
/* This actually configures the PCMCIA socket -- setting up
|
||||
the I/O windows and the interrupt mapping.
|
||||
*/
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
|
||||
/*** Set up 32k window for shared memory (transmit and control) ************/
|
||||
req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
|
||||
req.Base = 0;
|
||||
req.Size = 0x8000;
|
||||
req.AccessSpeed = ray_mem_speed;
|
||||
CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win));
|
||||
CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
|
||||
mem.CardOffset = 0x0000; mem.Page = 0;
|
||||
CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
|
||||
local->sram = ioremap(req.Base,req.Size);
|
||||
|
@ -506,7 +471,7 @@ static void ray_config(dev_link_t *link)
|
|||
req.Base = 0;
|
||||
req.Size = 0x4000;
|
||||
req.AccessSpeed = ray_mem_speed;
|
||||
CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &local->rmem_handle));
|
||||
CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &local->rmem_handle));
|
||||
mem.CardOffset = 0x8000; mem.Page = 0;
|
||||
CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->rmem_handle, &mem));
|
||||
local->rmem = ioremap(req.Base,req.Size);
|
||||
|
@ -516,7 +481,7 @@ static void ray_config(dev_link_t *link)
|
|||
req.Base = 0;
|
||||
req.Size = 0x1000;
|
||||
req.AccessSpeed = ray_mem_speed;
|
||||
CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &local->amem_handle));
|
||||
CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &local->amem_handle));
|
||||
mem.CardOffset = 0x0000; mem.Page = 0;
|
||||
CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->amem_handle, &mem));
|
||||
local->amem = ioremap(req.Base,req.Size);
|
||||
|
@ -526,32 +491,32 @@ static void ray_config(dev_link_t *link)
|
|||
DEBUG(3,"ray_config amem=%p\n",local->amem);
|
||||
if (ray_init(dev) < 0) {
|
||||
ray_release(link);
|
||||
return;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(handle));
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
i = register_netdev(dev);
|
||||
if (i != 0) {
|
||||
printk("ray_config register_netdev() failed\n");
|
||||
ray_release(link);
|
||||
return;
|
||||
return i;
|
||||
}
|
||||
|
||||
strcpy(local->node.dev_name, dev->name);
|
||||
link->dev = &local->node;
|
||||
link->dev_node = &local->node;
|
||||
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
printk(KERN_INFO "%s: RayLink, irq %d, hw_addr ",
|
||||
dev->name, dev->irq);
|
||||
for (i = 0; i < 6; i++)
|
||||
printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
|
||||
|
||||
return;
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
cs_error(link, last_fn, last_ret);
|
||||
|
||||
ray_release(link);
|
||||
return -ENODEV;
|
||||
} /* ray_config */
|
||||
|
||||
static inline struct ccs __iomem *ccs_base(ray_dev_t *dev)
|
||||
|
@ -578,9 +543,9 @@ static int ray_init(struct net_device *dev)
|
|||
UCHAR *p;
|
||||
struct ccs __iomem *pccs;
|
||||
ray_dev_t *local = (ray_dev_t *)dev->priv;
|
||||
dev_link_t *link = local->finder;
|
||||
struct pcmcia_device *link = local->finder;
|
||||
DEBUG(1, "ray_init(0x%p)\n", dev);
|
||||
if (!(link->state & DEV_PRESENT)) {
|
||||
if (!(pcmcia_dev_present(link))) {
|
||||
DEBUG(0,"ray_init - device not present\n");
|
||||
return -1;
|
||||
}
|
||||
|
@ -640,10 +605,10 @@ static int dl_startup_params(struct net_device *dev)
|
|||
int ccsindex;
|
||||
ray_dev_t *local = (ray_dev_t *)dev->priv;
|
||||
struct ccs __iomem *pccs;
|
||||
dev_link_t *link = local->finder;
|
||||
struct pcmcia_device *link = local->finder;
|
||||
|
||||
DEBUG(1,"dl_startup_params entered\n");
|
||||
if (!(link->state & DEV_PRESENT)) {
|
||||
if (!(pcmcia_dev_present(link))) {
|
||||
DEBUG(2,"ray_cs dl_startup_params - device not present\n");
|
||||
return -1;
|
||||
}
|
||||
|
@ -747,9 +712,9 @@ static void verify_dl_startup(u_long data)
|
|||
ray_dev_t *local = (ray_dev_t *)data;
|
||||
struct ccs __iomem *pccs = ccs_base(local) + local->dl_param_ccs;
|
||||
UCHAR status;
|
||||
dev_link_t *link = local->finder;
|
||||
struct pcmcia_device *link = local->finder;
|
||||
|
||||
if (!(link->state & DEV_PRESENT)) {
|
||||
if (!(pcmcia_dev_present(link))) {
|
||||
DEBUG(2,"ray_cs verify_dl_startup - device not present\n");
|
||||
return;
|
||||
}
|
||||
|
@ -787,8 +752,8 @@ static void start_net(u_long data)
|
|||
ray_dev_t *local = (ray_dev_t *)data;
|
||||
struct ccs __iomem *pccs;
|
||||
int ccsindex;
|
||||
dev_link_t *link = local->finder;
|
||||
if (!(link->state & DEV_PRESENT)) {
|
||||
struct pcmcia_device *link = local->finder;
|
||||
if (!(pcmcia_dev_present(link))) {
|
||||
DEBUG(2,"ray_cs start_net - device not present\n");
|
||||
return;
|
||||
}
|
||||
|
@ -814,9 +779,9 @@ static void join_net(u_long data)
|
|||
|
||||
struct ccs __iomem *pccs;
|
||||
int ccsindex;
|
||||
dev_link_t *link = local->finder;
|
||||
struct pcmcia_device *link = local->finder;
|
||||
|
||||
if (!(link->state & DEV_PRESENT)) {
|
||||
if (!(pcmcia_dev_present(link))) {
|
||||
DEBUG(2,"ray_cs join_net - device not present\n");
|
||||
return;
|
||||
}
|
||||
|
@ -840,7 +805,7 @@ static void join_net(u_long data)
|
|||
device, and release the PCMCIA configuration. If the device is
|
||||
still open, this will be postponed until it is closed.
|
||||
=============================================================================*/
|
||||
static void ray_release(dev_link_t *link)
|
||||
static void ray_release(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
ray_dev_t *local = dev->priv;
|
||||
|
@ -849,56 +814,38 @@ static void ray_release(dev_link_t *link)
|
|||
DEBUG(1, "ray_release(0x%p)\n", link);
|
||||
|
||||
del_timer(&local->timer);
|
||||
link->state &= ~DEV_CONFIG;
|
||||
|
||||
iounmap(local->sram);
|
||||
iounmap(local->rmem);
|
||||
iounmap(local->amem);
|
||||
/* Do bother checking to see if these succeed or not */
|
||||
i = pcmcia_release_window(link->win);
|
||||
if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(link->win) ret = %x\n",i);
|
||||
i = pcmcia_release_window(local->amem_handle);
|
||||
if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i);
|
||||
i = pcmcia_release_window(local->rmem_handle);
|
||||
if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i);
|
||||
i = pcmcia_release_configuration(link->handle);
|
||||
if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseConfiguration ret = %x\n",i);
|
||||
i = pcmcia_release_irq(link->handle, &link->irq);
|
||||
if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseIRQ ret = %x\n",i);
|
||||
pcmcia_disable_device(link);
|
||||
|
||||
DEBUG(2,"ray_release ending\n");
|
||||
}
|
||||
|
||||
static int ray_suspend(struct pcmcia_device *p_dev)
|
||||
static int ray_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 ray_resume(struct pcmcia_device *p_dev)
|
||||
static int ray_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) {
|
||||
ray_reset(dev);
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
}
|
||||
if (link->open) {
|
||||
ray_reset(dev);
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -910,10 +857,10 @@ int ray_dev_init(struct net_device *dev)
|
|||
int i;
|
||||
#endif /* RAY_IMMEDIATE_INIT */
|
||||
ray_dev_t *local = dev->priv;
|
||||
dev_link_t *link = local->finder;
|
||||
struct pcmcia_device *link = local->finder;
|
||||
|
||||
DEBUG(1,"ray_dev_init(dev=%p)\n",dev);
|
||||
if (!(link->state & DEV_PRESENT)) {
|
||||
if (!(pcmcia_dev_present(link))) {
|
||||
DEBUG(2,"ray_dev_init - device not present\n");
|
||||
return -1;
|
||||
}
|
||||
|
@ -944,10 +891,10 @@ int ray_dev_init(struct net_device *dev)
|
|||
static int ray_dev_config(struct net_device *dev, struct ifmap *map)
|
||||
{
|
||||
ray_dev_t *local = dev->priv;
|
||||
dev_link_t *link = local->finder;
|
||||
struct pcmcia_device *link = local->finder;
|
||||
/* Dummy routine to satisfy device structure */
|
||||
DEBUG(1,"ray_dev_config(dev=%p,ifmap=%p)\n",dev,map);
|
||||
if (!(link->state & DEV_PRESENT)) {
|
||||
if (!(pcmcia_dev_present(link))) {
|
||||
DEBUG(2,"ray_dev_config - device not present\n");
|
||||
return -1;
|
||||
}
|
||||
|
@ -958,10 +905,10 @@ static int ray_dev_config(struct net_device *dev, struct ifmap *map)
|
|||
static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
ray_dev_t *local = dev->priv;
|
||||
dev_link_t *link = local->finder;
|
||||
struct pcmcia_device *link = local->finder;
|
||||
short length = skb->len;
|
||||
|
||||
if (!(link->state & DEV_PRESENT)) {
|
||||
if (!(pcmcia_dev_present(link))) {
|
||||
DEBUG(2,"ray_dev_start_xmit - device not present\n");
|
||||
return -1;
|
||||
}
|
||||
|
@ -1570,7 +1517,7 @@ static int ray_commit(struct net_device *dev,
|
|||
static iw_stats * ray_get_wireless_stats(struct net_device * dev)
|
||||
{
|
||||
ray_dev_t * local = (ray_dev_t *) dev->priv;
|
||||
dev_link_t *link = local->finder;
|
||||
struct pcmcia_device *link = local->finder;
|
||||
struct status __iomem *p = local->sram + STATUS_BASE;
|
||||
|
||||
if(local == (ray_dev_t *) NULL)
|
||||
|
@ -1588,7 +1535,7 @@ static iw_stats * ray_get_wireless_stats(struct net_device * dev)
|
|||
}
|
||||
#endif /* WIRELESS_SPY */
|
||||
|
||||
if((link->state & DEV_PRESENT)) {
|
||||
if(pcmcia_dev_present(link)) {
|
||||
local->wstats.qual.noise = readb(&p->rxnoise);
|
||||
local->wstats.qual.updated |= 4;
|
||||
}
|
||||
|
@ -1657,18 +1604,14 @@ static const struct iw_handler_def ray_handler_def =
|
|||
/*===========================================================================*/
|
||||
static int ray_open(struct net_device *dev)
|
||||
{
|
||||
dev_link_t *link;
|
||||
ray_dev_t *local = (ray_dev_t *)dev->priv;
|
||||
struct pcmcia_device *link;
|
||||
link = local->finder;
|
||||
|
||||
DEBUG(1, "ray_open('%s')\n", dev->name);
|
||||
|
||||
for (link = dev_list; link; link = link->next)
|
||||
if (link->priv == dev) break;
|
||||
if (!DEV_OK(link)) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (link->open == 0) local->num_multi = 0;
|
||||
if (link->open == 0)
|
||||
local->num_multi = 0;
|
||||
link->open++;
|
||||
|
||||
/* If the card is not started, time to start it ! - Jean II */
|
||||
|
@ -1695,15 +1638,12 @@ static int ray_open(struct net_device *dev)
|
|||
/*===========================================================================*/
|
||||
static int ray_dev_close(struct net_device *dev)
|
||||
{
|
||||
dev_link_t *link;
|
||||
ray_dev_t *local = (ray_dev_t *)dev->priv;
|
||||
struct pcmcia_device *link;
|
||||
link = local->finder;
|
||||
|
||||
DEBUG(1, "ray_dev_close('%s')\n", dev->name);
|
||||
|
||||
for (link = dev_list; link; link = link->next)
|
||||
if (link->priv == dev) break;
|
||||
if (link == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
link->open--;
|
||||
netif_stop_queue(dev);
|
||||
|
||||
|
@ -1725,9 +1665,9 @@ static void ray_reset(struct net_device *dev) {
|
|||
static int interrupt_ecf(ray_dev_t *local, int ccs)
|
||||
{
|
||||
int i = 50;
|
||||
dev_link_t *link = local->finder;
|
||||
struct pcmcia_device *link = local->finder;
|
||||
|
||||
if (!(link->state & DEV_PRESENT)) {
|
||||
if (!(pcmcia_dev_present(link))) {
|
||||
DEBUG(2,"ray_cs interrupt_ecf - device not present\n");
|
||||
return -1;
|
||||
}
|
||||
|
@ -1752,9 +1692,9 @@ static int get_free_tx_ccs(ray_dev_t *local)
|
|||
{
|
||||
int i;
|
||||
struct ccs __iomem *pccs = ccs_base(local);
|
||||
dev_link_t *link = local->finder;
|
||||
struct pcmcia_device *link = local->finder;
|
||||
|
||||
if (!(link->state & DEV_PRESENT)) {
|
||||
if (!(pcmcia_dev_present(link))) {
|
||||
DEBUG(2,"ray_cs get_free_tx_ccs - device not present\n");
|
||||
return ECARDGONE;
|
||||
}
|
||||
|
@ -1783,9 +1723,9 @@ static int get_free_ccs(ray_dev_t *local)
|
|||
{
|
||||
int i;
|
||||
struct ccs __iomem *pccs = ccs_base(local);
|
||||
dev_link_t *link = local->finder;
|
||||
struct pcmcia_device *link = local->finder;
|
||||
|
||||
if (!(link->state & DEV_PRESENT)) {
|
||||
if (!(pcmcia_dev_present(link))) {
|
||||
DEBUG(2,"ray_cs get_free_ccs - device not present\n");
|
||||
return ECARDGONE;
|
||||
}
|
||||
|
@ -1858,9 +1798,9 @@ static int parse_addr(char *in_str, UCHAR *out)
|
|||
static struct net_device_stats *ray_get_stats(struct net_device *dev)
|
||||
{
|
||||
ray_dev_t *local = (ray_dev_t *)dev->priv;
|
||||
dev_link_t *link = local->finder;
|
||||
struct pcmcia_device *link = local->finder;
|
||||
struct status __iomem *p = local->sram + STATUS_BASE;
|
||||
if (!(link->state & DEV_PRESENT)) {
|
||||
if (!(pcmcia_dev_present(link))) {
|
||||
DEBUG(2,"ray_cs net_device_stats - device not present\n");
|
||||
return &local->stats;
|
||||
}
|
||||
|
@ -1888,12 +1828,12 @@ static struct net_device_stats *ray_get_stats(struct net_device *dev)
|
|||
static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len)
|
||||
{
|
||||
ray_dev_t *local = (ray_dev_t *)dev->priv;
|
||||
dev_link_t *link = local->finder;
|
||||
struct pcmcia_device *link = local->finder;
|
||||
int ccsindex;
|
||||
int i;
|
||||
struct ccs __iomem *pccs;
|
||||
|
||||
if (!(link->state & DEV_PRESENT)) {
|
||||
if (!(pcmcia_dev_present(link))) {
|
||||
DEBUG(2,"ray_update_parm - device not present\n");
|
||||
return;
|
||||
}
|
||||
|
@ -1925,10 +1865,10 @@ static void ray_update_multi_list(struct net_device *dev, int all)
|
|||
struct ccs __iomem *pccs;
|
||||
int i = 0;
|
||||
ray_dev_t *local = (ray_dev_t *)dev->priv;
|
||||
dev_link_t *link = local->finder;
|
||||
struct pcmcia_device *link = local->finder;
|
||||
void __iomem *p = local->sram + HOST_TO_ECF_BASE;
|
||||
|
||||
if (!(link->state & DEV_PRESENT)) {
|
||||
if (!(pcmcia_dev_present(link))) {
|
||||
DEBUG(2,"ray_update_multi_list - device not present\n");
|
||||
return;
|
||||
}
|
||||
|
@ -2005,7 +1945,7 @@ static void set_multicast_list(struct net_device *dev)
|
|||
static irqreturn_t ray_interrupt(int irq, void *dev_id, struct pt_regs * regs)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *)dev_id;
|
||||
dev_link_t *link;
|
||||
struct pcmcia_device *link;
|
||||
ray_dev_t *local;
|
||||
struct ccs __iomem *pccs;
|
||||
struct rcs __iomem *prcs;
|
||||
|
@ -2020,8 +1960,8 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id, struct pt_regs * regs)
|
|||
DEBUG(4,"ray_cs: interrupt for *dev=%p\n",dev);
|
||||
|
||||
local = (ray_dev_t *)dev->priv;
|
||||
link = (dev_link_t *)local->finder;
|
||||
if ( ! (link->state & DEV_PRESENT) || link->state & DEV_SUSPEND ) {
|
||||
link = (struct pcmcia_device *)local->finder;
|
||||
if (!pcmcia_dev_present(link)) {
|
||||
DEBUG(2,"ray_cs interrupt from device not present or suspended.\n");
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
@ -2540,9 +2480,9 @@ static void release_frag_chain(ray_dev_t *local, struct rcs __iomem * prcs)
|
|||
/*===========================================================================*/
|
||||
static void authenticate(ray_dev_t *local)
|
||||
{
|
||||
dev_link_t *link = local->finder;
|
||||
struct pcmcia_device *link = local->finder;
|
||||
DEBUG(0,"ray_cs Starting authentication.\n");
|
||||
if (!(link->state & DEV_PRESENT)) {
|
||||
if (!(pcmcia_dev_present(link))) {
|
||||
DEBUG(2,"ray_cs authenticate - device not present\n");
|
||||
return;
|
||||
}
|
||||
|
@ -2606,10 +2546,10 @@ static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs,
|
|||
static void associate(ray_dev_t *local)
|
||||
{
|
||||
struct ccs __iomem *pccs;
|
||||
dev_link_t *link = local->finder;
|
||||
struct pcmcia_device *link = local->finder;
|
||||
struct net_device *dev = link->priv;
|
||||
int ccsindex;
|
||||
if (!(link->state & DEV_PRESENT)) {
|
||||
if (!(pcmcia_dev_present(link))) {
|
||||
DEBUG(2,"ray_cs associate - device not present\n");
|
||||
return;
|
||||
}
|
||||
|
@ -2689,14 +2629,14 @@ static int ray_cs_proc_read(char *buf, char **start, off_t offset, int len)
|
|||
* eg ifconfig
|
||||
*/
|
||||
int i;
|
||||
dev_link_t *link;
|
||||
struct pcmcia_device *link;
|
||||
struct net_device *dev;
|
||||
ray_dev_t *local;
|
||||
UCHAR *p;
|
||||
struct freq_hop_element *pfh;
|
||||
UCHAR c[33];
|
||||
|
||||
link = dev_list;
|
||||
link = this_device;
|
||||
if (!link)
|
||||
return 0;
|
||||
dev = (struct net_device *)link->priv;
|
||||
|
@ -2898,7 +2838,7 @@ static struct pcmcia_driver ray_driver = {
|
|||
.drv = {
|
||||
.name = "ray_cs",
|
||||
},
|
||||
.probe = ray_attach,
|
||||
.probe = ray_probe,
|
||||
.remove = ray_detach,
|
||||
.id_table = ray_ids,
|
||||
.suspend = ray_suspend,
|
||||
|
@ -2940,7 +2880,6 @@ static void __exit exit_ray_cs(void)
|
|||
#endif
|
||||
|
||||
pcmcia_unregister_driver(&ray_driver);
|
||||
BUG_ON(dev_list != NULL);
|
||||
} /* exit_ray_cs */
|
||||
|
||||
module_init(init_ray_cs);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -63,7 +63,7 @@ MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket
|
|||
/* PCMCIA specific device information (goes in the card field of
|
||||
* struct orinoco_private */
|
||||
struct orinoco_pccard {
|
||||
dev_link_t link;
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
};
|
||||
|
||||
|
@ -71,8 +71,8 @@ struct orinoco_pccard {
|
|||
/* Function prototypes */
|
||||
/********************************************************************/
|
||||
|
||||
static void spectrum_cs_config(dev_link_t *link);
|
||||
static void spectrum_cs_release(dev_link_t *link);
|
||||
static int spectrum_cs_config(struct pcmcia_device *link);
|
||||
static void spectrum_cs_release(struct pcmcia_device *link);
|
||||
|
||||
/********************************************************************/
|
||||
/* Firmware downloader */
|
||||
|
@ -238,14 +238,14 @@ spectrum_aux_open(hermes_t *hw)
|
|||
* If IDLE is 1, stop the firmware, so that it can be safely rewritten.
|
||||
*/
|
||||
static int
|
||||
spectrum_reset(dev_link_t *link, int idle)
|
||||
spectrum_reset(struct pcmcia_device *link, int idle)
|
||||
{
|
||||
int last_ret, last_fn;
|
||||
conf_reg_t reg;
|
||||
u_int save_cor;
|
||||
|
||||
/* Doing it if hardware is gone is guaranteed crash */
|
||||
if (!(link->state & DEV_CONFIG))
|
||||
if (pcmcia_dev_present(link))
|
||||
return -ENODEV;
|
||||
|
||||
/* Save original COR value */
|
||||
|
@ -253,7 +253,7 @@ spectrum_reset(dev_link_t *link, int idle)
|
|||
reg.Action = CS_READ;
|
||||
reg.Offset = CISREG_COR;
|
||||
CS_CHECK(AccessConfigurationRegister,
|
||||
pcmcia_access_configuration_register(link->handle, ®));
|
||||
pcmcia_access_configuration_register(link, ®));
|
||||
save_cor = reg.Value;
|
||||
|
||||
/* Soft-Reset card */
|
||||
|
@ -261,14 +261,14 @@ spectrum_reset(dev_link_t *link, int idle)
|
|||
reg.Offset = CISREG_COR;
|
||||
reg.Value = (save_cor | COR_SOFT_RESET);
|
||||
CS_CHECK(AccessConfigurationRegister,
|
||||
pcmcia_access_configuration_register(link->handle, ®));
|
||||
pcmcia_access_configuration_register(link, ®));
|
||||
udelay(1000);
|
||||
|
||||
/* Read CCSR */
|
||||
reg.Action = CS_READ;
|
||||
reg.Offset = CISREG_CCSR;
|
||||
CS_CHECK(AccessConfigurationRegister,
|
||||
pcmcia_access_configuration_register(link->handle, ®));
|
||||
pcmcia_access_configuration_register(link, ®));
|
||||
|
||||
/*
|
||||
* Start or stop the firmware. Memory width bit should be
|
||||
|
@ -278,7 +278,7 @@ spectrum_reset(dev_link_t *link, int idle)
|
|||
reg.Offset = CISREG_CCSR;
|
||||
reg.Value = (idle ? HCR_IDLE : HCR_RUN) | (reg.Value & HCR_MEM16);
|
||||
CS_CHECK(AccessConfigurationRegister,
|
||||
pcmcia_access_configuration_register(link->handle, ®));
|
||||
pcmcia_access_configuration_register(link, ®));
|
||||
udelay(1000);
|
||||
|
||||
/* Restore original COR configuration index */
|
||||
|
@ -286,12 +286,12 @@ spectrum_reset(dev_link_t *link, int idle)
|
|||
reg.Offset = CISREG_COR;
|
||||
reg.Value = (save_cor & ~COR_SOFT_RESET);
|
||||
CS_CHECK(AccessConfigurationRegister,
|
||||
pcmcia_access_configuration_register(link->handle, ®));
|
||||
pcmcia_access_configuration_register(link, ®));
|
||||
udelay(1000);
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
cs_error(link, last_fn, last_ret);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
@ -441,7 +441,7 @@ spectrum_load_blocks(hermes_t *hw, const struct dblock *first_block)
|
|||
* care of the PDA - read it and then write it on top of the firmware.
|
||||
*/
|
||||
static int
|
||||
spectrum_dl_image(hermes_t *hw, dev_link_t *link,
|
||||
spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link,
|
||||
const unsigned char *image)
|
||||
{
|
||||
int ret;
|
||||
|
@ -505,14 +505,13 @@ spectrum_dl_image(hermes_t *hw, dev_link_t *link,
|
|||
* reset on the card, to make sure it's in a sane state.
|
||||
*/
|
||||
static int
|
||||
spectrum_dl_firmware(hermes_t *hw, dev_link_t *link)
|
||||
spectrum_dl_firmware(hermes_t *hw, struct pcmcia_device *link)
|
||||
{
|
||||
int ret;
|
||||
client_handle_t handle = link->handle;
|
||||
const struct firmware *fw_entry;
|
||||
|
||||
if (request_firmware(&fw_entry, primary_fw_name,
|
||||
&handle_to_dev(handle)) == 0) {
|
||||
&handle_to_dev(link)) == 0) {
|
||||
primsym = fw_entry->data;
|
||||
} else {
|
||||
printk(KERN_ERR PFX "Cannot find firmware: %s\n",
|
||||
|
@ -521,7 +520,7 @@ spectrum_dl_firmware(hermes_t *hw, dev_link_t *link)
|
|||
}
|
||||
|
||||
if (request_firmware(&fw_entry, secondary_fw_name,
|
||||
&handle_to_dev(handle)) == 0) {
|
||||
&handle_to_dev(link)) == 0) {
|
||||
secsym = fw_entry->data;
|
||||
} else {
|
||||
printk(KERN_ERR PFX "Cannot find firmware: %s\n",
|
||||
|
@ -554,12 +553,12 @@ static int
|
|||
spectrum_cs_hard_reset(struct orinoco_private *priv)
|
||||
{
|
||||
struct orinoco_pccard *card = priv->card;
|
||||
dev_link_t *link = &card->link;
|
||||
struct pcmcia_device *link = card->p_dev;
|
||||
int err;
|
||||
|
||||
if (!hermes_present(&priv->hw)) {
|
||||
/* The firmware needs to be reloaded */
|
||||
if (spectrum_dl_firmware(&priv->hw, &card->link) != 0) {
|
||||
if (spectrum_dl_firmware(&priv->hw, link) != 0) {
|
||||
printk(KERN_ERR PFX "Firmware download failed\n");
|
||||
err = -ENODEV;
|
||||
}
|
||||
|
@ -584,12 +583,11 @@ spectrum_cs_hard_reset(struct orinoco_private *priv)
|
|||
* configure the card at this point -- we wait until we receive a card
|
||||
* insertion event. */
|
||||
static int
|
||||
spectrum_cs_attach(struct pcmcia_device *p_dev)
|
||||
spectrum_cs_probe(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev;
|
||||
struct orinoco_private *priv;
|
||||
struct orinoco_pccard *card;
|
||||
dev_link_t *link;
|
||||
|
||||
dev = alloc_orinocodev(sizeof(*card), spectrum_cs_hard_reset);
|
||||
if (! dev)
|
||||
|
@ -598,7 +596,7 @@ spectrum_cs_attach(struct pcmcia_device *p_dev)
|
|||
card = priv->card;
|
||||
|
||||
/* Link both structures together */
|
||||
link = &card->link;
|
||||
card->p_dev = link;
|
||||
link->priv = dev;
|
||||
|
||||
/* Interrupt setup */
|
||||
|
@ -615,13 +613,7 @@ spectrum_cs_attach(struct pcmcia_device *p_dev)
|
|||
link->conf.Attributes = 0;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
link->handle = p_dev;
|
||||
p_dev->instance = link;
|
||||
|
||||
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
|
||||
spectrum_cs_config(link);
|
||||
|
||||
return 0;
|
||||
return spectrum_cs_config(link);
|
||||
} /* spectrum_cs_attach */
|
||||
|
||||
/*
|
||||
|
@ -630,16 +622,14 @@ spectrum_cs_attach(struct pcmcia_device *p_dev)
|
|||
* are freed. Otherwise, the structures will be freed when the device
|
||||
* is released.
|
||||
*/
|
||||
static void spectrum_cs_detach(struct pcmcia_device *p_dev)
|
||||
static void spectrum_cs_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
if (link->state & DEV_CONFIG)
|
||||
spectrum_cs_release(link);
|
||||
spectrum_cs_release(link);
|
||||
|
||||
DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev);
|
||||
if (link->dev) {
|
||||
DEBUG(0, PFX "detach: link=%p link->dev_node=%p\n", link, link->dev_node);
|
||||
if (link->dev_node) {
|
||||
DEBUG(0, PFX "About to unregister net device %p\n",
|
||||
dev);
|
||||
unregister_netdev(dev);
|
||||
|
@ -653,11 +643,10 @@ static void spectrum_cs_detach(struct pcmcia_device *p_dev)
|
|||
* device available to the system.
|
||||
*/
|
||||
|
||||
static void
|
||||
spectrum_cs_config(dev_link_t *link)
|
||||
static int
|
||||
spectrum_cs_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
client_handle_t handle = link->handle;
|
||||
struct orinoco_private *priv = netdev_priv(dev);
|
||||
struct orinoco_pccard *card = priv->card;
|
||||
hermes_t *hw = &priv->hw;
|
||||
|
@ -669,7 +658,7 @@ spectrum_cs_config(dev_link_t *link)
|
|||
cisparse_t parse;
|
||||
void __iomem *mem;
|
||||
|
||||
CS_CHECK(ValidateCIS, pcmcia_validate_cis(handle, &info));
|
||||
CS_CHECK(ValidateCIS, pcmcia_validate_cis(link, &info));
|
||||
|
||||
/*
|
||||
* This reads the card's CONFIG tuple to find its
|
||||
|
@ -680,19 +669,15 @@ spectrum_cs_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;
|
||||
pcmcia_get_configuration_info(link, &conf));
|
||||
|
||||
/*
|
||||
* In this loop, we scan the CIS for configuration table
|
||||
|
@ -709,13 +694,13 @@ spectrum_cs_config(dev_link_t *link)
|
|||
* 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 *cfg = &(parse.cftable_entry);
|
||||
cistpl_cftable_entry_t dflt = { .index = 0 };
|
||||
|
||||
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)
|
||||
|
@ -747,10 +732,10 @@ spectrum_cs_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? */
|
||||
|
@ -780,7 +765,7 @@ spectrum_cs_config(dev_link_t *link)
|
|||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
@ -790,9 +775,8 @@ spectrum_cs_config(dev_link_t *link)
|
|||
break;
|
||||
|
||||
next_entry:
|
||||
if (link->io.NumPorts1)
|
||||
pcmcia_release_io(link->handle, &link->io);
|
||||
last_ret = pcmcia_get_next_tuple(handle, &tuple);
|
||||
pcmcia_disable_device(link);
|
||||
last_ret = pcmcia_get_next_tuple(link, &tuple);
|
||||
if (last_ret == CS_NO_MORE_ITEMS) {
|
||||
printk(KERN_ERR PFX "GetNextTuple(): No matching "
|
||||
"CIS configuration. Maybe you need the "
|
||||
|
@ -806,7 +790,7 @@ spectrum_cs_config(dev_link_t *link)
|
|||
* a handler to the interrupt, unless the 'Handler' member of
|
||||
* the irq structure is initialized.
|
||||
*/
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
|
||||
/* We initialize the hermes structure before completing PCMCIA
|
||||
* configuration just in case the interrupt handler gets
|
||||
|
@ -823,7 +807,7 @@ spectrum_cs_config(dev_link_t *link)
|
|||
* card and host interface into "Memory and IO" mode.
|
||||
*/
|
||||
CS_CHECK(RequestConfiguration,
|
||||
pcmcia_request_configuration(link->handle, &link->conf));
|
||||
pcmcia_request_configuration(link, &link->conf));
|
||||
|
||||
/* Ok, we have the configuration, prepare to register the netdev */
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
|
@ -836,7 +820,7 @@ spectrum_cs_config(dev_link_t *link)
|
|||
goto failed;
|
||||
}
|
||||
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(handle));
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
/* Tell the stack we exist */
|
||||
if (register_netdev(dev) != 0) {
|
||||
printk(KERN_ERR PFX "register_netdev() failed\n");
|
||||
|
@ -844,20 +828,18 @@ spectrum_cs_config(dev_link_t *link)
|
|||
}
|
||||
|
||||
/* At this point, the dev_node_t structure(s) needs to be
|
||||
* initialized and arranged in a linked list at link->dev. */
|
||||
* initialized and arranged in a linked list at link->dev_node. */
|
||||
strcpy(card->node.dev_name, dev->name);
|
||||
link->dev = &card->node; /* link->dev being non-NULL is also
|
||||
link->dev_node = &card->node; /* link->dev_node being non-NULL is also
|
||||
used to indicate that the
|
||||
net_device has been registered */
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
|
||||
/* Finally, report what we've done */
|
||||
printk(KERN_DEBUG "%s: index 0x%02x: Vcc %d.%d",
|
||||
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_DEBUG "%s: index 0x%02x: ",
|
||||
dev->name, link->conf.ConfigIndex);
|
||||
if (link->conf.Vpp)
|
||||
printk(", Vpp %d.%d", link->conf.Vpp / 10,
|
||||
link->conf.Vpp % 10);
|
||||
printk(", irq %d", link->irq.AssignedIRQ);
|
||||
if (link->io.NumPorts1)
|
||||
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
|
||||
|
@ -867,13 +849,14 @@ spectrum_cs_config(dev_link_t *link)
|
|||
link->io.BasePort2 + link->io.NumPorts2 - 1);
|
||||
printk("\n");
|
||||
|
||||
return;
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
cs_error(link, last_fn, last_ret);
|
||||
|
||||
failed:
|
||||
spectrum_cs_release(link);
|
||||
return -ENODEV;
|
||||
} /* spectrum_cs_config */
|
||||
|
||||
/*
|
||||
|
@ -882,7 +865,7 @@ spectrum_cs_config(dev_link_t *link)
|
|||
* still open, this will be postponed until it is closed.
|
||||
*/
|
||||
static void
|
||||
spectrum_cs_release(dev_link_t *link)
|
||||
spectrum_cs_release(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
struct orinoco_private *priv = netdev_priv(dev);
|
||||
|
@ -894,64 +877,46 @@ spectrum_cs_release(dev_link_t *link)
|
|||
priv->hw_unavailable++;
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
/* Don't bother checking to see if these succeed or not */
|
||||
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);
|
||||
if (priv->hw.iobase)
|
||||
ioport_unmap(priv->hw.iobase);
|
||||
} /* spectrum_cs_release */
|
||||
|
||||
|
||||
static int
|
||||
spectrum_cs_suspend(struct pcmcia_device *p_dev)
|
||||
spectrum_cs_suspend(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct net_device *dev = link->priv;
|
||||
struct orinoco_private *priv = netdev_priv(dev);
|
||||
unsigned long flags;
|
||||
int err = 0;
|
||||
|
||||
link->state |= DEV_SUSPEND;
|
||||
/* Mark the device as stopped, to block IO until later */
|
||||
if (link->state & DEV_CONFIG) {
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
|
||||
err = __orinoco_down(dev);
|
||||
if (err)
|
||||
printk(KERN_WARNING "%s: Error %d downing interface\n",
|
||||
dev->name, err);
|
||||
err = __orinoco_down(dev);
|
||||
if (err)
|
||||
printk(KERN_WARNING "%s: Error %d downing interface\n",
|
||||
dev->name, err);
|
||||
|
||||
netif_device_detach(dev);
|
||||
priv->hw_unavailable++;
|
||||
netif_device_detach(dev);
|
||||
priv->hw_unavailable++;
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
pcmcia_release_configuration(link->handle);
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
spectrum_cs_resume(struct pcmcia_device *p_dev)
|
||||
spectrum_cs_resume(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct net_device *dev = link->priv;
|
||||
struct orinoco_private *priv = netdev_priv(dev);
|
||||
|
||||
link->state &= ~DEV_SUSPEND;
|
||||
if (link->state & DEV_CONFIG) {
|
||||
/* FIXME: should we double check that this is
|
||||
* the same card as we had before */
|
||||
pcmcia_request_configuration(link->handle, &link->conf);
|
||||
netif_device_attach(dev);
|
||||
priv->hw_unavailable--;
|
||||
schedule_work(&priv->reset_work);
|
||||
}
|
||||
netif_device_attach(dev);
|
||||
priv->hw_unavailable--;
|
||||
schedule_work(&priv->reset_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -979,7 +944,7 @@ static struct pcmcia_driver orinoco_driver = {
|
|||
.drv = {
|
||||
.name = DRIVER_NAME,
|
||||
},
|
||||
.probe = spectrum_cs_attach,
|
||||
.probe = spectrum_cs_probe,
|
||||
.remove = spectrum_cs_detach,
|
||||
.suspend = spectrum_cs_suspend,
|
||||
.resume = spectrum_cs_resume,
|
||||
|
|
|
@ -1005,7 +1005,7 @@ static inline void
|
|||
wv_82593_reconfig(struct net_device * dev)
|
||||
{
|
||||
net_local * lp = netdev_priv(dev);
|
||||
dev_link_t * link = lp->link;
|
||||
struct pcmcia_device * link = lp->link;
|
||||
unsigned long flags;
|
||||
|
||||
/* Arm the flag, will be cleard in wv_82593_config() */
|
||||
|
@ -3744,16 +3744,16 @@ wv_pcmcia_reset(struct net_device * dev)
|
|||
{
|
||||
int i;
|
||||
conf_reg_t reg = { 0, CS_READ, CISREG_COR, 0 };
|
||||
dev_link_t * link = ((net_local *)netdev_priv(dev))->link;
|
||||
struct pcmcia_device * link = ((net_local *)netdev_priv(dev))->link;
|
||||
|
||||
#ifdef DEBUG_CONFIG_TRACE
|
||||
printk(KERN_DEBUG "%s: ->wv_pcmcia_reset()\n", dev->name);
|
||||
#endif
|
||||
|
||||
i = pcmcia_access_configuration_register(link->handle, ®);
|
||||
i = pcmcia_access_configuration_register(link, ®);
|
||||
if(i != CS_SUCCESS)
|
||||
{
|
||||
cs_error(link->handle, AccessConfigurationRegister, i);
|
||||
cs_error(link, AccessConfigurationRegister, i);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -3764,19 +3764,19 @@ wv_pcmcia_reset(struct net_device * dev)
|
|||
|
||||
reg.Action = CS_WRITE;
|
||||
reg.Value = reg.Value | COR_SW_RESET;
|
||||
i = pcmcia_access_configuration_register(link->handle, ®);
|
||||
i = pcmcia_access_configuration_register(link, ®);
|
||||
if(i != CS_SUCCESS)
|
||||
{
|
||||
cs_error(link->handle, AccessConfigurationRegister, i);
|
||||
cs_error(link, AccessConfigurationRegister, i);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
reg.Action = CS_WRITE;
|
||||
reg.Value = COR_LEVEL_IRQ | COR_CONFIG;
|
||||
i = pcmcia_access_configuration_register(link->handle, ®);
|
||||
i = pcmcia_access_configuration_register(link, ®);
|
||||
if(i != CS_SUCCESS)
|
||||
{
|
||||
cs_error(link->handle, AccessConfigurationRegister, i);
|
||||
cs_error(link, AccessConfigurationRegister, i);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -3940,9 +3940,8 @@ wv_hw_reset(struct net_device * dev)
|
|||
* (called by wavelan_event())
|
||||
*/
|
||||
static inline int
|
||||
wv_pcmcia_config(dev_link_t * link)
|
||||
wv_pcmcia_config(struct pcmcia_device * link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
struct net_device * dev = (struct net_device *) link->priv;
|
||||
|
@ -3965,16 +3964,16 @@ wv_pcmcia_config(dev_link_t * link)
|
|||
{
|
||||
tuple.Attributes = 0;
|
||||
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 = (cisdata_t *)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;
|
||||
|
@ -3983,19 +3982,16 @@ wv_pcmcia_config(dev_link_t * link)
|
|||
while(0);
|
||||
if(i != CS_SUCCESS)
|
||||
{
|
||||
cs_error(link->handle, ParseTuple, i);
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
cs_error(link, ParseTuple, i);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Configure card */
|
||||
link->state |= DEV_CONFIG;
|
||||
|
||||
do
|
||||
{
|
||||
i = pcmcia_request_io(link->handle, &link->io);
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
if(i != CS_SUCCESS)
|
||||
{
|
||||
cs_error(link->handle, RequestIO, i);
|
||||
cs_error(link, RequestIO, i);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -4003,10 +3999,10 @@ wv_pcmcia_config(dev_link_t * link)
|
|||
* Now allocate an interrupt line. Note that this does not
|
||||
* actually assign a handler to the interrupt.
|
||||
*/
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -4015,15 +4011,15 @@ wv_pcmcia_config(dev_link_t * link)
|
|||
* the I/O windows and the interrupt mapping.
|
||||
*/
|
||||
link->conf.ConfigIndex = 1;
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a small memory window. Note that the dev_link_t
|
||||
* Allocate a small memory window. Note that the struct pcmcia_device
|
||||
* structure provides space for one window handle -- if your
|
||||
* device needs several windows, you'll need to keep track of
|
||||
* the handles in your private data structure, link->priv.
|
||||
|
@ -4031,10 +4027,10 @@ wv_pcmcia_config(dev_link_t * link)
|
|||
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
||||
req.Base = req.Size = 0;
|
||||
req.AccessSpeed = mem_speed;
|
||||
i = pcmcia_request_window(&link->handle, &req, &link->win);
|
||||
i = pcmcia_request_window(&link, &req, &link->win);
|
||||
if(i != CS_SUCCESS)
|
||||
{
|
||||
cs_error(link->handle, RequestWindow, i);
|
||||
cs_error(link, RequestWindow, i);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -4046,7 +4042,7 @@ wv_pcmcia_config(dev_link_t * link)
|
|||
i = pcmcia_map_mem_page(link->win, &mem);
|
||||
if(i != CS_SUCCESS)
|
||||
{
|
||||
cs_error(link->handle, MapMemPage, i);
|
||||
cs_error(link, MapMemPage, i);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -4060,7 +4056,7 @@ wv_pcmcia_config(dev_link_t * link)
|
|||
lp->mem, dev->irq, (u_int) dev->base_addr);
|
||||
#endif
|
||||
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(handle));
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
i = register_netdev(dev);
|
||||
if(i != 0)
|
||||
{
|
||||
|
@ -4072,7 +4068,6 @@ wv_pcmcia_config(dev_link_t * link)
|
|||
}
|
||||
while(0); /* Humm... Disguised goto !!! */
|
||||
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
/* If any step failed, release any partially configured state */
|
||||
if(i != 0)
|
||||
{
|
||||
|
@ -4081,7 +4076,7 @@ wv_pcmcia_config(dev_link_t * link)
|
|||
}
|
||||
|
||||
strcpy(((net_local *) netdev_priv(dev))->node.dev_name, dev->name);
|
||||
link->dev = &((net_local *) netdev_priv(dev))->node;
|
||||
link->dev_node = &((net_local *) netdev_priv(dev))->node;
|
||||
|
||||
#ifdef DEBUG_CONFIG_TRACE
|
||||
printk(KERN_DEBUG "<-wv_pcmcia_config()\n");
|
||||
|
@ -4096,26 +4091,20 @@ wv_pcmcia_config(dev_link_t * link)
|
|||
* still open, this will be postponed until it is closed.
|
||||
*/
|
||||
static void
|
||||
wv_pcmcia_release(dev_link_t *link)
|
||||
wv_pcmcia_release(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device * dev = (struct net_device *) link->priv;
|
||||
net_local * lp = netdev_priv(dev);
|
||||
struct net_device * dev = (struct net_device *) link->priv;
|
||||
net_local * lp = netdev_priv(dev);
|
||||
|
||||
#ifdef DEBUG_CONFIG_TRACE
|
||||
printk(KERN_DEBUG "%s: -> wv_pcmcia_release(0x%p)\n", dev->name, link);
|
||||
printk(KERN_DEBUG "%s: -> wv_pcmcia_release(0x%p)\n", dev->name, link);
|
||||
#endif
|
||||
|
||||
/* Don't bother checking to see if these succeed or not */
|
||||
iounmap(lp->mem);
|
||||
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;
|
||||
iounmap(lp->mem);
|
||||
pcmcia_disable_device(link);
|
||||
|
||||
#ifdef DEBUG_CONFIG_TRACE
|
||||
printk(KERN_DEBUG "%s: <- wv_pcmcia_release()\n", dev->name);
|
||||
printk(KERN_DEBUG "%s: <- wv_pcmcia_release()\n", dev->name);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -4479,7 +4468,7 @@ static int
|
|||
wavelan_open(struct net_device * dev)
|
||||
{
|
||||
net_local * lp = netdev_priv(dev);
|
||||
dev_link_t * link = lp->link;
|
||||
struct pcmcia_device * link = lp->link;
|
||||
kio_addr_t base = dev->base_addr;
|
||||
|
||||
#ifdef DEBUG_CALLBACK_TRACE
|
||||
|
@ -4533,7 +4522,7 @@ wavelan_open(struct net_device * dev)
|
|||
static int
|
||||
wavelan_close(struct net_device * dev)
|
||||
{
|
||||
dev_link_t * link = ((net_local *)netdev_priv(dev))->link;
|
||||
struct pcmcia_device * link = ((net_local *)netdev_priv(dev))->link;
|
||||
kio_addr_t base = dev->base_addr;
|
||||
|
||||
#ifdef DEBUG_CALLBACK_TRACE
|
||||
|
@ -4587,45 +4576,36 @@ wavelan_close(struct net_device * dev)
|
|||
* card insertion event.
|
||||
*/
|
||||
static int
|
||||
wavelan_attach(struct pcmcia_device *p_dev)
|
||||
wavelan_probe(struct pcmcia_device *p_dev)
|
||||
{
|
||||
dev_link_t * link; /* Info for cardmgr */
|
||||
struct net_device * dev; /* Interface generic data */
|
||||
net_local * lp; /* Interface specific data */
|
||||
int ret;
|
||||
|
||||
#ifdef DEBUG_CALLBACK_TRACE
|
||||
printk(KERN_DEBUG "-> wavelan_attach()\n");
|
||||
#endif
|
||||
|
||||
/* Initialize the dev_link_t structure */
|
||||
link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
|
||||
if (!link) return -ENOMEM;
|
||||
|
||||
/* The io structure describes IO port mapping */
|
||||
link->io.NumPorts1 = 8;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
link->io.IOAddrLines = 3;
|
||||
p_dev->io.NumPorts1 = 8;
|
||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
p_dev->io.IOAddrLines = 3;
|
||||
|
||||
/* Interrupt setup */
|
||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->irq.Handler = wavelan_interrupt;
|
||||
p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
|
||||
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
p_dev->irq.Handler = wavelan_interrupt;
|
||||
|
||||
/* General socket configuration */
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.Vcc = 50;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
/* Chain drivers */
|
||||
link->next = NULL;
|
||||
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
p_dev->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
/* Allocate the generic data structure */
|
||||
dev = alloc_etherdev(sizeof(net_local));
|
||||
if (!dev) {
|
||||
kfree(link);
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
}
|
||||
link->priv = link->irq.Instance = dev;
|
||||
|
||||
p_dev->priv = p_dev->irq.Instance = dev;
|
||||
|
||||
lp = netdev_priv(dev);
|
||||
|
||||
|
@ -4642,7 +4622,6 @@ wavelan_attach(struct pcmcia_device *p_dev)
|
|||
spin_lock_init(&lp->spinlock);
|
||||
|
||||
/* back links */
|
||||
lp->link = link;
|
||||
lp->dev = dev;
|
||||
|
||||
/* wavelan NET3 callbacks */
|
||||
|
@ -4668,15 +4647,18 @@ wavelan_attach(struct pcmcia_device *p_dev)
|
|||
/* Other specific data */
|
||||
dev->mtu = WAVELAN_MTU;
|
||||
|
||||
link->handle = p_dev;
|
||||
p_dev->instance = link;
|
||||
ret = wv_pcmcia_config(p_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
|
||||
if(wv_pcmcia_config(link) &&
|
||||
wv_hw_config(dev))
|
||||
wv_init_info(dev);
|
||||
else
|
||||
ret = wv_hw_config(dev);
|
||||
if (ret) {
|
||||
dev->irq = 0;
|
||||
pcmcia_disable_device(p_dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
wv_init_info(dev);
|
||||
|
||||
#ifdef DEBUG_CALLBACK_TRACE
|
||||
printk(KERN_DEBUG "<- wavelan_attach()\n");
|
||||
|
@ -4693,25 +4675,14 @@ wavelan_attach(struct pcmcia_device *p_dev)
|
|||
* is released.
|
||||
*/
|
||||
static void
|
||||
wavelan_detach(struct pcmcia_device *p_dev)
|
||||
wavelan_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
|
||||
#ifdef DEBUG_CALLBACK_TRACE
|
||||
printk(KERN_DEBUG "-> wavelan_detach(0x%p)\n", link);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If the device is currently configured and active, we won't
|
||||
* actually delete it yet. Instead, it is marked so that when the
|
||||
* release() function is called, that will trigger a proper
|
||||
* detach().
|
||||
*/
|
||||
if(link->state & DEV_CONFIG)
|
||||
{
|
||||
/* Some others haven't done their job : give them another chance */
|
||||
wv_pcmcia_release(link);
|
||||
}
|
||||
/* Some others haven't done their job : give them another chance */
|
||||
wv_pcmcia_release(link);
|
||||
|
||||
/* Free pieces */
|
||||
if(link->priv)
|
||||
|
@ -4720,23 +4691,21 @@ wavelan_detach(struct pcmcia_device *p_dev)
|
|||
|
||||
/* Remove ourselves from the kernel list of ethernet devices */
|
||||
/* Warning : can't be called from interrupt, timer or wavelan_close() */
|
||||
if (link->dev)
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
link->dev = NULL;
|
||||
link->dev_node = NULL;
|
||||
((net_local *)netdev_priv(dev))->link = NULL;
|
||||
((net_local *)netdev_priv(dev))->dev = NULL;
|
||||
free_netdev(dev);
|
||||
}
|
||||
kfree(link);
|
||||
|
||||
#ifdef DEBUG_CALLBACK_TRACE
|
||||
printk(KERN_DEBUG "<- wavelan_detach()\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static int wavelan_suspend(struct pcmcia_device *p_dev)
|
||||
static int wavelan_suspend(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct net_device * dev = (struct net_device *) link->priv;
|
||||
|
||||
/* NB: wavelan_close will be called, but too late, so we are
|
||||
|
@ -4748,36 +4717,22 @@ static int wavelan_suspend(struct pcmcia_device *p_dev)
|
|||
/* Stop receiving new messages and wait end of transmission */
|
||||
wv_ru_stop(dev);
|
||||
|
||||
if (link->open)
|
||||
netif_device_detach(dev);
|
||||
|
||||
/* Power down the module */
|
||||
hacr_write(dev->base_addr, HACR_DEFAULT & (~HACR_PWR_STAT));
|
||||
|
||||
/* The card is now suspended */
|
||||
link->state |= DEV_SUSPEND;
|
||||
|
||||
if(link->state & DEV_CONFIG)
|
||||
{
|
||||
if(link->open)
|
||||
netif_device_detach(dev);
|
||||
pcmcia_release_configuration(link->handle);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wavelan_resume(struct pcmcia_device *p_dev)
|
||||
static int wavelan_resume(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct net_device * dev = (struct net_device *) link->priv;
|
||||
|
||||
link->state &= ~DEV_SUSPEND;
|
||||
if(link->state & DEV_CONFIG)
|
||||
{
|
||||
pcmcia_request_configuration(link->handle, &link->conf);
|
||||
if(link->open) /* If RESET -> True, If RESUME -> False ? */
|
||||
{
|
||||
wv_hw_reset(dev);
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
if (link->open) {
|
||||
wv_hw_reset(dev);
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -4798,7 +4753,7 @@ static struct pcmcia_driver wavelan_driver = {
|
|||
.drv = {
|
||||
.name = "wavelan_cs",
|
||||
},
|
||||
.probe = wavelan_attach,
|
||||
.probe = wavelan_probe,
|
||||
.remove = wavelan_detach,
|
||||
.id_table = wavelan_ids,
|
||||
.suspend = wavelan_suspend,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -103,8 +103,8 @@ module_param(pc_debug, int, 0);
|
|||
* release a socket, in response to card insertion and ejection events. They
|
||||
* are invoked from the wl24 event handler.
|
||||
*/
|
||||
static void wl3501_config(dev_link_t *link);
|
||||
static void wl3501_release(dev_link_t *link);
|
||||
static int wl3501_config(struct pcmcia_device *link);
|
||||
static void wl3501_release(struct pcmcia_device *link);
|
||||
|
||||
/*
|
||||
* The dev_info variable is the "key" that is used to match up this
|
||||
|
@ -226,17 +226,6 @@ static void iw_copy_mgmt_info_element(struct iw_mgmt_info_element *to,
|
|||
iw_set_mgmt_info_element(from->id, to, from->data, from->len);
|
||||
}
|
||||
|
||||
/*
|
||||
* A linked list of "instances" of the wl24 device. Each actual PCMCIA card
|
||||
* corresponds to one device instance, and is described by one dev_link_t
|
||||
* 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 device numbers
|
||||
* are used to derive the corresponding array index.
|
||||
*/
|
||||
static dev_link_t *wl3501_dev_list;
|
||||
|
||||
static inline void wl3501_switch_page(struct wl3501_card *this, u8 page)
|
||||
{
|
||||
wl3501_outb(page, this->base_addr + WL3501_NIC_BSS);
|
||||
|
@ -1281,15 +1270,10 @@ static int wl3501_close(struct net_device *dev)
|
|||
struct wl3501_card *this = dev->priv;
|
||||
int rc = -ENODEV;
|
||||
unsigned long flags;
|
||||
dev_link_t *link;
|
||||
struct pcmcia_device *link;
|
||||
link = this->p_dev;
|
||||
|
||||
spin_lock_irqsave(&this->lock, flags);
|
||||
/* Check if the device is in wl3501_dev_list */
|
||||
for (link = wl3501_dev_list; link; link = link->next)
|
||||
if (link->priv == dev)
|
||||
break;
|
||||
if (!link)
|
||||
goto out;
|
||||
link->open--;
|
||||
|
||||
/* Stop wl3501_hard_start_xmit() from now on */
|
||||
|
@ -1301,7 +1285,6 @@ static int wl3501_close(struct net_device *dev)
|
|||
|
||||
rc = 0;
|
||||
printk(KERN_INFO "%s: WL3501 closed\n", dev->name);
|
||||
out:
|
||||
spin_unlock_irqrestore(&this->lock, flags);
|
||||
return rc;
|
||||
}
|
||||
|
@ -1400,14 +1383,11 @@ static int wl3501_open(struct net_device *dev)
|
|||
int rc = -ENODEV;
|
||||
struct wl3501_card *this = dev->priv;
|
||||
unsigned long flags;
|
||||
dev_link_t *link;
|
||||
struct pcmcia_device *link;
|
||||
link = this->p_dev;
|
||||
|
||||
spin_lock_irqsave(&this->lock, flags);
|
||||
/* Check if the device is in wl3501_dev_list */
|
||||
for (link = wl3501_dev_list; link; link = link->next)
|
||||
if (link->priv == dev)
|
||||
break;
|
||||
if (!DEV_OK(link))
|
||||
if (!pcmcia_dev_present(link))
|
||||
goto out;
|
||||
netif_device_attach(dev);
|
||||
link->open++;
|
||||
|
@ -1497,38 +1477,23 @@ static struct ethtool_ops ops = {
|
|||
* Services. If it has been released, all local data structures are freed.
|
||||
* Otherwise, the structures will be freed when the device is released.
|
||||
*/
|
||||
static void wl3501_detach(struct pcmcia_device *p_dev)
|
||||
static void wl3501_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
dev_link_t **linkp;
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
/* Locate device structure */
|
||||
for (linkp = &wl3501_dev_list; *linkp; linkp = &(*linkp)->next)
|
||||
if (*linkp == link)
|
||||
break;
|
||||
if (!*linkp)
|
||||
goto out;
|
||||
|
||||
/* If the device is currently configured and active, we won't actually
|
||||
* delete it yet. Instead, it is marked so that when the release()
|
||||
* function is called, that will trigger a proper detach(). */
|
||||
|
||||
if (link->state & DEV_CONFIG) {
|
||||
while (link->open > 0)
|
||||
wl3501_close(dev);
|
||||
while (link->open > 0)
|
||||
wl3501_close(dev);
|
||||
|
||||
netif_device_detach(dev);
|
||||
wl3501_release(link);
|
||||
}
|
||||
|
||||
/* Unlink device structure, free pieces */
|
||||
*linkp = link->next;
|
||||
netif_device_detach(dev);
|
||||
wl3501_release(link);
|
||||
|
||||
if (link->priv)
|
||||
free_netdev(link->priv);
|
||||
kfree(link);
|
||||
out:
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1953,33 +1918,26 @@ static const struct iw_handler_def wl3501_handler_def = {
|
|||
* The dev_link structure is initialized, but we don't actually configure the
|
||||
* card at this point -- we wait until we receive a card insertion event.
|
||||
*/
|
||||
static int wl3501_attach(struct pcmcia_device *p_dev)
|
||||
static int wl3501_probe(struct pcmcia_device *p_dev)
|
||||
{
|
||||
dev_link_t *link;
|
||||
struct net_device *dev;
|
||||
struct wl3501_card *this;
|
||||
|
||||
/* Initialize the dev_link_t structure */
|
||||
link = kzalloc(sizeof(*link), GFP_KERNEL);
|
||||
if (!link)
|
||||
return -ENOMEM;
|
||||
|
||||
/* The io structure describes IO port mapping */
|
||||
link->io.NumPorts1 = 16;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
link->io.IOAddrLines = 5;
|
||||
p_dev->io.NumPorts1 = 16;
|
||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
p_dev->io.IOAddrLines = 5;
|
||||
|
||||
/* Interrupt setup */
|
||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->irq.Handler = wl3501_interrupt;
|
||||
p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
|
||||
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
p_dev->irq.Handler = wl3501_interrupt;
|
||||
|
||||
/* 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;
|
||||
|
||||
dev = alloc_etherdev(sizeof(struct wl3501_card));
|
||||
if (!dev)
|
||||
|
@ -1992,22 +1950,15 @@ static int wl3501_attach(struct pcmcia_device *p_dev)
|
|||
dev->get_stats = wl3501_get_stats;
|
||||
this = dev->priv;
|
||||
this->wireless_data.spy_data = &this->spy_data;
|
||||
this->p_dev = p_dev;
|
||||
dev->wireless_data = &this->wireless_data;
|
||||
dev->wireless_handlers = (struct iw_handler_def *)&wl3501_handler_def;
|
||||
SET_ETHTOOL_OPS(dev, &ops);
|
||||
netif_stop_queue(dev);
|
||||
link->priv = link->irq.Instance = dev;
|
||||
p_dev->priv = p_dev->irq.Instance = dev;
|
||||
|
||||
link->handle = p_dev;
|
||||
p_dev->instance = link;
|
||||
|
||||
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
|
||||
wl3501_config(link);
|
||||
|
||||
return 0;
|
||||
return wl3501_config(p_dev);
|
||||
out_link:
|
||||
kfree(link);
|
||||
link = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
@ -2022,11 +1973,10 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|||
* received, to configure the PCMCIA socket, and to make the ethernet device
|
||||
* available to the system.
|
||||
*/
|
||||
static void wl3501_config(dev_link_t *link)
|
||||
static int wl3501_config(struct pcmcia_device *link)
|
||||
{
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
client_handle_t handle = link->handle;
|
||||
struct net_device *dev = link->priv;
|
||||
int i = 0, j, last_fn, last_ret;
|
||||
unsigned char bf[64];
|
||||
|
@ -2035,18 +1985,15 @@ static void wl3501_config(dev_link_t *link)
|
|||
/* This reads the card's CONFIG tuple to find its config registers. */
|
||||
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 = bf;
|
||||
tuple.TupleDataMax = sizeof(bf);
|
||||
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;
|
||||
|
||||
/* Try allocating IO ports. This tries a few fixed addresses. If you
|
||||
* want, you can also read the card's config table to pick addresses --
|
||||
* see the serial driver for an example. */
|
||||
|
@ -2056,28 +2003,28 @@ static void wl3501_config(dev_link_t *link)
|
|||
* 0x200-0x2ff, and so on, because this seems safer */
|
||||
link->io.BasePort1 = j;
|
||||
link->io.BasePort2 = link->io.BasePort1 + 0x10;
|
||||
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;
|
||||
}
|
||||
|
||||
/* Now allocate an interrupt line. Note that this does not actually
|
||||
* assign a handler to the interrupt. */
|
||||
|
||||
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. */
|
||||
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(handle));
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
if (register_netdev(dev)) {
|
||||
printk(KERN_NOTICE "wl3501_cs: register_netdev() failed\n");
|
||||
goto failed;
|
||||
|
@ -2088,10 +2035,9 @@ static void wl3501_config(dev_link_t *link)
|
|||
this = dev->priv;
|
||||
/*
|
||||
* At this point, the dev_node_t structure(s) should be initialized and
|
||||
* arranged in a linked list at link->dev.
|
||||
* arranged in a linked list at link->dev_node.
|
||||
*/
|
||||
link->dev = &this->node;
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
link->dev_node = &this->node;
|
||||
|
||||
this->base_addr = dev->base_addr;
|
||||
|
||||
|
@ -2127,13 +2073,13 @@ static void wl3501_config(dev_link_t *link)
|
|||
spin_lock_init(&this->lock);
|
||||
init_waitqueue_head(&this->wait);
|
||||
netif_start_queue(dev);
|
||||
goto out;
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
wl3501_release(link);
|
||||
out:
|
||||
return;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2144,52 +2090,36 @@ static void wl3501_config(dev_link_t *link)
|
|||
* and release the PCMCIA configuration. If the device is still open, this
|
||||
* will be postponed until it is closed.
|
||||
*/
|
||||
static void wl3501_release(dev_link_t *link)
|
||||
static void wl3501_release(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
/* Unlink the device chain */
|
||||
if (link->dev) {
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
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);
|
||||
}
|
||||
|
||||
static int wl3501_suspend(struct pcmcia_device *p_dev)
|
||||
static int wl3501_suspend(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
link->state |= DEV_SUSPEND;
|
||||
|
||||
wl3501_pwr_mgmt(dev->priv, WL3501_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 wl3501_resume(struct pcmcia_device *p_dev)
|
||||
static int wl3501_resume(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
wl3501_pwr_mgmt(dev->priv, WL3501_RESUME);
|
||||
if (link->state & DEV_CONFIG) {
|
||||
pcmcia_request_configuration(link->handle, &link->conf);
|
||||
if (link->open) {
|
||||
wl3501_reset(dev);
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
if (link->open) {
|
||||
wl3501_reset(dev);
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -2207,7 +2137,7 @@ static struct pcmcia_driver wl3501_driver = {
|
|||
.drv = {
|
||||
.name = "wl3501_cs",
|
||||
},
|
||||
.probe = wl3501_attach,
|
||||
.probe = wl3501_probe,
|
||||
.remove = wl3501_detach,
|
||||
.id_table = wl3501_ids,
|
||||
.suspend = wl3501_suspend,
|
||||
|
@ -2221,9 +2151,7 @@ static int __init wl3501_init_module(void)
|
|||
|
||||
static void __exit wl3501_exit_module(void)
|
||||
{
|
||||
dprintk(0, ": unloading");
|
||||
pcmcia_unregister_driver(&wl3501_driver);
|
||||
BUG_ON(wl3501_dev_list != NULL);
|
||||
}
|
||||
|
||||
module_init(wl3501_init_module);
|
||||
|
|
|
@ -81,15 +81,15 @@ static char *version =
|
|||
#define FORCE_EPP_MODE 0x08
|
||||
|
||||
typedef struct parport_info_t {
|
||||
dev_link_t link;
|
||||
struct pcmcia_device *p_dev;
|
||||
int ndev;
|
||||
dev_node_t node;
|
||||
struct parport *port;
|
||||
} parport_info_t;
|
||||
|
||||
static void parport_detach(struct pcmcia_device *p_dev);
|
||||
static void parport_config(dev_link_t *link);
|
||||
static void parport_cs_release(dev_link_t *);
|
||||
static int parport_config(struct pcmcia_device *link);
|
||||
static void parport_cs_release(struct pcmcia_device *);
|
||||
|
||||
/*======================================================================
|
||||
|
||||
|
@ -99,10 +99,9 @@ static void parport_cs_release(dev_link_t *);
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static int parport_attach(struct pcmcia_device *p_dev)
|
||||
static int parport_probe(struct pcmcia_device *link)
|
||||
{
|
||||
parport_info_t *info;
|
||||
dev_link_t *link;
|
||||
|
||||
DEBUG(0, "parport_attach()\n");
|
||||
|
||||
|
@ -110,23 +109,17 @@ static int parport_attach(struct pcmcia_device *p_dev)
|
|||
info = kmalloc(sizeof(*info), GFP_KERNEL);
|
||||
if (!info) return -ENOMEM;
|
||||
memset(info, 0, sizeof(*info));
|
||||
link = &info->link; link->priv = info;
|
||||
link->priv = info;
|
||||
info->p_dev = link;
|
||||
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
||||
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;
|
||||
parport_config(link);
|
||||
|
||||
return 0;
|
||||
return parport_config(link);
|
||||
} /* parport_attach */
|
||||
|
||||
/*======================================================================
|
||||
|
@ -138,14 +131,11 @@ static int parport_attach(struct pcmcia_device *p_dev)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static void parport_detach(struct pcmcia_device *p_dev)
|
||||
static void parport_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
|
||||
DEBUG(0, "parport_detach(0x%p)\n", link);
|
||||
|
||||
if (link->state & DEV_CONFIG)
|
||||
parport_cs_release(link);
|
||||
parport_cs_release(link);
|
||||
|
||||
kfree(link->priv);
|
||||
} /* parport_detach */
|
||||
|
@ -161,14 +151,12 @@ static void parport_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)
|
||||
|
||||
void parport_config(dev_link_t *link)
|
||||
static int parport_config(struct pcmcia_device *link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
parport_info_t *info = link->priv;
|
||||
tuple_t tuple;
|
||||
u_short buf[128];
|
||||
cisparse_t parse;
|
||||
config_info_t conf;
|
||||
cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
|
||||
cistpl_cftable_entry_t dflt = { 0 };
|
||||
struct parport *p;
|
||||
|
@ -180,24 +168,18 @@ void parport_config(dev_link_t *link)
|
|||
tuple.TupleOffset = 0; 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, &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;
|
||||
|
||||
/* Not sure if this is right... look up the current Vcc */
|
||||
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
|
||||
|
||||
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 ||
|
||||
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->io.nwin > 0) || (dflt.io.nwin > 0)) {
|
||||
|
@ -212,7 +194,7 @@ void parport_config(dev_link_t *link)
|
|||
link->io.BasePort2 = io->win[1].base;
|
||||
link->io.NumPorts2 = io->win[1].len;
|
||||
}
|
||||
if (pcmcia_request_io(link->handle, &link->io) != 0)
|
||||
if (pcmcia_request_io(link, &link->io) != 0)
|
||||
goto next_entry;
|
||||
/* If we've got this far, we're done */
|
||||
break;
|
||||
|
@ -220,15 +202,12 @@ void parport_config(dev_link_t *link)
|
|||
|
||||
next_entry:
|
||||
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
release_region(link->io.BasePort1, link->io.NumPorts1);
|
||||
if (link->io.NumPorts2)
|
||||
release_region(link->io.BasePort2, link->io.NumPorts2);
|
||||
p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2,
|
||||
link->irq.AssignedIRQ, PARPORT_DMA_NONE,
|
||||
NULL);
|
||||
|
@ -247,17 +226,15 @@ void parport_config(dev_link_t *link)
|
|||
info->node.minor = p->number;
|
||||
info->port = p;
|
||||
strcpy(info->node.dev_name, p->name);
|
||||
link->dev = &info->node;
|
||||
link->dev_node = &info->node;
|
||||
|
||||
return 0;
|
||||
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
return;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
parport_cs_release(link);
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
|
||||
return -ENODEV;
|
||||
} /* parport_config */
|
||||
|
||||
/*======================================================================
|
||||
|
@ -268,53 +245,21 @@ void parport_config(dev_link_t *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
void parport_cs_release(dev_link_t *link)
|
||||
void parport_cs_release(struct pcmcia_device *link)
|
||||
{
|
||||
parport_info_t *info = link->priv;
|
||||
|
||||
DEBUG(0, "parport_release(0x%p)\n", link);
|
||||
parport_info_t *info = link->priv;
|
||||
|
||||
if (info->ndev) {
|
||||
struct parport *p = info->port;
|
||||
parport_pc_unregister_port(p);
|
||||
request_region(link->io.BasePort1, link->io.NumPorts1,
|
||||
info->node.dev_name);
|
||||
if (link->io.NumPorts2)
|
||||
request_region(link->io.BasePort2, link->io.NumPorts2,
|
||||
info->node.dev_name);
|
||||
}
|
||||
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;
|
||||
DEBUG(0, "parport_release(0x%p)\n", link);
|
||||
|
||||
if (info->ndev) {
|
||||
struct parport *p = info->port;
|
||||
parport_pc_unregister_port(p);
|
||||
}
|
||||
info->ndev = 0;
|
||||
|
||||
pcmcia_disable_device(link);
|
||||
} /* parport_cs_release */
|
||||
|
||||
static int parport_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 parport_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 parport_ids[] = {
|
||||
PCMCIA_DEVICE_FUNC_ID(3),
|
||||
|
@ -328,11 +273,9 @@ static struct pcmcia_driver parport_cs_driver = {
|
|||
.drv = {
|
||||
.name = "parport_cs",
|
||||
},
|
||||
.probe = parport_attach,
|
||||
.probe = parport_probe,
|
||||
.remove = parport_detach,
|
||||
.id_table = parport_ids,
|
||||
.suspend = parport_suspend,
|
||||
.resume = parport_resume,
|
||||
};
|
||||
|
||||
static int __init init_parport_cs(void)
|
||||
|
|
|
@ -263,6 +263,13 @@ config OMAP_CF
|
|||
Say Y here to support the CompactFlash controller on OMAP.
|
||||
Note that this doesn't support "True IDE" mode.
|
||||
|
||||
config AT91_CF
|
||||
tristate "AT91 CompactFlash Controller"
|
||||
depends on PCMCIA && ARCH_AT91RM9200
|
||||
help
|
||||
Say Y here to support the CompactFlash controller on AT91 chips.
|
||||
Or choose M to compile the driver as a module named "at91_cf".
|
||||
|
||||
config PCCARD_NONSTATIC
|
||||
tristate
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ pcmcia_core-y += cs.o cistpl.o rsrc_mgr.o socket_sysfs.o
|
|||
pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o
|
||||
obj-$(CONFIG_PCCARD) += pcmcia_core.o
|
||||
|
||||
pcmcia-y += ds.o pcmcia_compat.o pcmcia_resource.o
|
||||
pcmcia-y += ds.o pcmcia_resource.o
|
||||
pcmcia-$(CONFIG_PCMCIA_IOCTL) += pcmcia_ioctl.o
|
||||
obj-$(CONFIG_PCMCIA) += pcmcia.o
|
||||
|
||||
|
@ -36,6 +36,7 @@ obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o
|
|||
obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o
|
||||
obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o
|
||||
obj-$(CONFIG_OMAP_CF) += omap_cf.o
|
||||
obj-$(CONFIG_AT91_CF) += at91_cf.o
|
||||
|
||||
sa11xx_core-y += soc_common.o sa11xx_base.o
|
||||
pxa2xx_core-y += soc_common.o pxa2xx_base.o
|
||||
|
|
365
drivers/pcmcia/at91_cf.c
Normal file
365
drivers/pcmcia/at91_cf.c
Normal file
|
@ -0,0 +1,365 @@
|
|||
/*
|
||||
* at91_cf.c -- AT91 CompactFlash controller driver
|
||||
*
|
||||
* Copyright (C) 2005 David Brownell
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include <pcmcia/ss.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/sizes.h>
|
||||
|
||||
#include <asm/arch/at91rm9200.h>
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
|
||||
|
||||
#define CF_SIZE 0x30000000 /* CS5+CS6: unavailable */
|
||||
|
||||
/*
|
||||
* A0..A10 work in each range; A23 indicates I/O space; A25 is CFRNW;
|
||||
* some other bit in {A24,A22..A11} is nREG to flag memory access
|
||||
* (vs attributes). So more than 2KB/region would just be waste.
|
||||
*/
|
||||
#define CF_ATTR_PHYS (AT91_CF_BASE)
|
||||
#define CF_IO_PHYS (AT91_CF_BASE + (1 << 23))
|
||||
#define CF_MEM_PHYS (AT91_CF_BASE + 0x017ff800)
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
static const char driver_name[] = "at91_cf";
|
||||
|
||||
struct at91_cf_socket {
|
||||
struct pcmcia_socket socket;
|
||||
|
||||
unsigned present:1;
|
||||
|
||||
struct platform_device *pdev;
|
||||
struct at91_cf_data *board;
|
||||
};
|
||||
|
||||
#define SZ_2K (2 * SZ_1K)
|
||||
|
||||
static inline int at91_cf_present(struct at91_cf_socket *cf)
|
||||
{
|
||||
return !at91_get_gpio_value(cf->board->det_pin);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
static int at91_cf_ss_init(struct pcmcia_socket *s)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t at91_cf_irq(int irq, void *_cf, struct pt_regs *r)
|
||||
{
|
||||
struct at91_cf_socket *cf = (struct at91_cf_socket *) _cf;
|
||||
|
||||
if (irq == cf->board->det_pin) {
|
||||
unsigned present = at91_cf_present(cf);
|
||||
|
||||
/* kick pccard as needed */
|
||||
if (present != cf->present) {
|
||||
cf->present = present;
|
||||
pr_debug("%s: card %s\n", driver_name, present ? "present" : "gone");
|
||||
pcmcia_parse_events(&cf->socket, SS_DETECT);
|
||||
}
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int at91_cf_get_status(struct pcmcia_socket *s, u_int *sp)
|
||||
{
|
||||
struct at91_cf_socket *cf;
|
||||
|
||||
if (!sp)
|
||||
return -EINVAL;
|
||||
|
||||
cf = container_of(s, struct at91_cf_socket, socket);
|
||||
|
||||
/* NOTE: we assume 3VCARD, not XVCARD... */
|
||||
if (at91_cf_present(cf)) {
|
||||
int rdy = cf->board->irq_pin; /* RDY/nIRQ */
|
||||
int vcc = cf->board->vcc_pin;
|
||||
|
||||
*sp = SS_DETECT | SS_3VCARD;
|
||||
if (!rdy || at91_get_gpio_value(rdy))
|
||||
*sp |= SS_READY;
|
||||
if (!vcc || at91_get_gpio_value(vcc))
|
||||
*sp |= SS_POWERON;
|
||||
} else
|
||||
*sp = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int at91_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s)
|
||||
{
|
||||
struct at91_cf_socket *cf;
|
||||
|
||||
cf = container_of(sock, struct at91_cf_socket, socket);
|
||||
|
||||
/* switch Vcc if needed and possible */
|
||||
if (cf->board->vcc_pin) {
|
||||
switch (s->Vcc) {
|
||||
case 0:
|
||||
at91_set_gpio_value(cf->board->vcc_pin, 0);
|
||||
break;
|
||||
case 33:
|
||||
at91_set_gpio_value(cf->board->vcc_pin, 1);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* toggle reset if needed */
|
||||
at91_set_gpio_value(cf->board->rst_pin, s->flags & SS_RESET);
|
||||
|
||||
pr_debug("%s: Vcc %d, io_irq %d, flags %04x csc %04x\n",
|
||||
driver_name, s->Vcc, s->io_irq, s->flags, s->csc_mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int at91_cf_ss_suspend(struct pcmcia_socket *s)
|
||||
{
|
||||
return at91_cf_set_socket(s, &dead_socket);
|
||||
}
|
||||
|
||||
/* we already mapped the I/O region */
|
||||
static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
|
||||
{
|
||||
struct at91_cf_socket *cf;
|
||||
u32 csr;
|
||||
|
||||
cf = container_of(s, struct at91_cf_socket, socket);
|
||||
io->flags &= (MAP_ACTIVE | MAP_16BIT | MAP_AUTOSZ);
|
||||
|
||||
/*
|
||||
* Use 16 bit accesses unless/until we need 8-bit i/o space.
|
||||
* Always set CSR4 ... PCMCIA won't always unmap things.
|
||||
*/
|
||||
csr = at91_sys_read(AT91_SMC_CSR(4)) & ~AT91_SMC_DBW;
|
||||
|
||||
/*
|
||||
* NOTE: this CF controller ignores IOIS16, so we can't really do
|
||||
* MAP_AUTOSZ. The 16bit mode allows single byte access on either
|
||||
* D0-D7 (even addr) or D8-D15 (odd), so it's close enough for many
|
||||
* purposes (and handles ide-cs).
|
||||
*
|
||||
* The 8bit mode is needed for odd byte access on D0-D7. It seems
|
||||
* some cards only like that way to get at the odd byte, despite
|
||||
* CF 3.0 spec table 35 also giving the D8-D15 option.
|
||||
*/
|
||||
if (!(io->flags & (MAP_16BIT|MAP_AUTOSZ))) {
|
||||
csr |= AT91_SMC_DBW_8;
|
||||
pr_debug("%s: 8bit i/o bus\n", driver_name);
|
||||
} else {
|
||||
csr |= AT91_SMC_DBW_16;
|
||||
pr_debug("%s: 16bit i/o bus\n", driver_name);
|
||||
}
|
||||
at91_sys_write(AT91_SMC_CSR(4), csr);
|
||||
|
||||
io->start = cf->socket.io_offset;
|
||||
io->stop = io->start + SZ_2K - 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* pcmcia layer maps/unmaps mem regions */
|
||||
static int at91_cf_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *map)
|
||||
{
|
||||
struct at91_cf_socket *cf;
|
||||
|
||||
if (map->card_start)
|
||||
return -EINVAL;
|
||||
|
||||
cf = container_of(s, struct at91_cf_socket, socket);
|
||||
|
||||
map->flags &= MAP_ACTIVE|MAP_ATTRIB|MAP_16BIT;
|
||||
if (map->flags & MAP_ATTRIB)
|
||||
map->static_start = CF_ATTR_PHYS;
|
||||
else
|
||||
map->static_start = CF_MEM_PHYS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct pccard_operations at91_cf_ops = {
|
||||
.init = at91_cf_ss_init,
|
||||
.suspend = at91_cf_ss_suspend,
|
||||
.get_status = at91_cf_get_status,
|
||||
.set_socket = at91_cf_set_socket,
|
||||
.set_io_map = at91_cf_set_io_map,
|
||||
.set_mem_map = at91_cf_set_mem_map,
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
static int __init at91_cf_probe(struct device *dev)
|
||||
{
|
||||
struct at91_cf_socket *cf;
|
||||
struct at91_cf_data *board = dev->platform_data;
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
unsigned int csa;
|
||||
int status;
|
||||
|
||||
if (!board || !board->det_pin || !board->rst_pin)
|
||||
return -ENODEV;
|
||||
|
||||
cf = kcalloc(1, sizeof *cf, GFP_KERNEL);
|
||||
if (!cf)
|
||||
return -ENOMEM;
|
||||
|
||||
cf->board = board;
|
||||
cf->pdev = pdev;
|
||||
dev_set_drvdata(dev, cf);
|
||||
|
||||
/* CF takes over CS4, CS5, CS6 */
|
||||
csa = at91_sys_read(AT91_EBI_CSA);
|
||||
at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH);
|
||||
|
||||
/* force poweron defaults for these pins ... */
|
||||
(void) at91_set_A_periph(AT91_PIN_PC9, 0); /* A25/CFRNW */
|
||||
(void) at91_set_A_periph(AT91_PIN_PC10, 0); /* NCS4/CFCS */
|
||||
(void) at91_set_A_periph(AT91_PIN_PC11, 0); /* NCS5/CFCE1 */
|
||||
(void) at91_set_A_periph(AT91_PIN_PC12, 0); /* NCS6/CFCE2 */
|
||||
|
||||
/* nWAIT is _not_ a default setting */
|
||||
(void) at91_set_A_periph(AT91_PIN_PC6, 1); /* nWAIT */
|
||||
|
||||
/*
|
||||
* Static memory controller timing adjustments.
|
||||
* REVISIT: these timings are in terms of MCK cycles, so
|
||||
* when MCK changes (cpufreq etc) so must these values...
|
||||
*/
|
||||
at91_sys_write(AT91_SMC_CSR(4), AT91_SMC_ACSS_STD | AT91_SMC_DBW_16 | AT91_SMC_BAT | AT91_SMC_WSEN
|
||||
| AT91_SMC_NWS_(32) /* wait states */
|
||||
| AT91_SMC_RWSETUP_(6) /* setup time */
|
||||
| AT91_SMC_RWHOLD_(4) /* hold time */
|
||||
);
|
||||
|
||||
/* must be a GPIO; ergo must trigger on both edges */
|
||||
status = request_irq(board->det_pin, at91_cf_irq,
|
||||
SA_SAMPLE_RANDOM, driver_name, cf);
|
||||
if (status < 0)
|
||||
goto fail0;
|
||||
|
||||
/*
|
||||
* The card driver will request this irq later as needed.
|
||||
* but it causes lots of "irqNN: nobody cared" messages
|
||||
* unless we report that we handle everything (sigh).
|
||||
* (Note: DK board doesn't wire the IRQ pin...)
|
||||
*/
|
||||
if (board->irq_pin) {
|
||||
status = request_irq(board->irq_pin, at91_cf_irq,
|
||||
SA_SHIRQ, driver_name, cf);
|
||||
if (status < 0)
|
||||
goto fail0a;
|
||||
cf->socket.pci_irq = board->irq_pin;
|
||||
}
|
||||
else
|
||||
cf->socket.pci_irq = NR_IRQS + 1;
|
||||
|
||||
/* pcmcia layer only remaps "real" memory not iospace */
|
||||
cf->socket.io_offset = (unsigned long) ioremap(CF_IO_PHYS, SZ_2K);
|
||||
if (!cf->socket.io_offset)
|
||||
goto fail1;
|
||||
|
||||
/* reserve CS4, CS5, and CS6 regions; but use just CS4 */
|
||||
if (!request_mem_region(AT91_CF_BASE, CF_SIZE, driver_name))
|
||||
goto fail1;
|
||||
|
||||
pr_info("%s: irqs det #%d, io #%d\n", driver_name,
|
||||
board->det_pin, board->irq_pin);
|
||||
|
||||
cf->socket.owner = THIS_MODULE;
|
||||
cf->socket.dev.dev = dev;
|
||||
cf->socket.ops = &at91_cf_ops;
|
||||
cf->socket.resource_ops = &pccard_static_ops;
|
||||
cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP
|
||||
| SS_CAP_MEM_ALIGN;
|
||||
cf->socket.map_size = SZ_2K;
|
||||
cf->socket.io[0].NumPorts = SZ_2K;
|
||||
|
||||
status = pcmcia_register_socket(&cf->socket);
|
||||
if (status < 0)
|
||||
goto fail2;
|
||||
|
||||
return 0;
|
||||
|
||||
fail2:
|
||||
iounmap((void __iomem *) cf->socket.io_offset);
|
||||
release_mem_region(AT91_CF_BASE, CF_SIZE);
|
||||
fail1:
|
||||
if (board->irq_pin)
|
||||
free_irq(board->irq_pin, cf);
|
||||
fail0a:
|
||||
free_irq(board->det_pin, cf);
|
||||
fail0:
|
||||
at91_sys_write(AT91_EBI_CSA, csa);
|
||||
kfree(cf);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int __exit at91_cf_remove(struct device *dev)
|
||||
{
|
||||
struct at91_cf_socket *cf = dev_get_drvdata(dev);
|
||||
unsigned int csa;
|
||||
|
||||
pcmcia_unregister_socket(&cf->socket);
|
||||
free_irq(cf->board->irq_pin, cf);
|
||||
free_irq(cf->board->det_pin, cf);
|
||||
iounmap((void __iomem *) cf->socket.io_offset);
|
||||
release_mem_region(AT91_CF_BASE, CF_SIZE);
|
||||
|
||||
csa = at91_sys_read(AT91_EBI_CSA);
|
||||
at91_sys_write(AT91_EBI_CSA, csa & ~AT91_EBI_CS4A);
|
||||
|
||||
kfree(cf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct device_driver at91_cf_driver = {
|
||||
.name = (char *) driver_name,
|
||||
.bus = &platform_bus_type,
|
||||
.probe = at91_cf_probe,
|
||||
.remove = __exit_p(at91_cf_remove),
|
||||
.suspend = pcmcia_socket_dev_suspend,
|
||||
.resume = pcmcia_socket_dev_resume,
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
static int __init at91_cf_init(void)
|
||||
{
|
||||
return driver_register(&at91_cf_driver);
|
||||
}
|
||||
module_init(at91_cf_init);
|
||||
|
||||
static void __exit at91_cf_exit(void)
|
||||
{
|
||||
driver_unregister(&at91_cf_driver);
|
||||
}
|
||||
module_exit(at91_cf_exit);
|
||||
|
||||
MODULE_DESCRIPTION("AT91 Compact Flash Driver");
|
||||
MODULE_AUTHOR("David Brownell");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -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>
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include <linux/moduleparam.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/config.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/errno.h>
|
||||
|
@ -111,9 +110,9 @@ int pcmcia_socket_dev_suspend(struct device *dev, pm_message_t state)
|
|||
list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
|
||||
if (socket->dev.dev != dev)
|
||||
continue;
|
||||
down(&socket->skt_sem);
|
||||
mutex_lock(&socket->skt_mutex);
|
||||
socket_suspend(socket);
|
||||
up(&socket->skt_sem);
|
||||
mutex_unlock(&socket->skt_mutex);
|
||||
}
|
||||
up_read(&pcmcia_socket_list_rwsem);
|
||||
|
||||
|
@ -129,9 +128,9 @@ int pcmcia_socket_dev_resume(struct device *dev)
|
|||
list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
|
||||
if (socket->dev.dev != dev)
|
||||
continue;
|
||||
down(&socket->skt_sem);
|
||||
mutex_lock(&socket->skt_mutex);
|
||||
socket_resume(socket);
|
||||
up(&socket->skt_sem);
|
||||
mutex_unlock(&socket->skt_mutex);
|
||||
}
|
||||
up_read(&pcmcia_socket_list_rwsem);
|
||||
|
||||
|
@ -237,7 +236,7 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
|
|||
init_completion(&socket->socket_released);
|
||||
init_completion(&socket->thread_done);
|
||||
init_waitqueue_head(&socket->thread_wait);
|
||||
init_MUTEX(&socket->skt_sem);
|
||||
mutex_init(&socket->skt_mutex);
|
||||
spin_lock_init(&socket->thread_lock);
|
||||
|
||||
ret = kernel_thread(pccardd, socket, CLONE_KERNEL);
|
||||
|
@ -406,8 +405,6 @@ static void socket_shutdown(struct pcmcia_socket *s)
|
|||
cb_free(s);
|
||||
#endif
|
||||
s->functions = 0;
|
||||
kfree(s->config);
|
||||
s->config = NULL;
|
||||
|
||||
s->ops->get_status(s, &status);
|
||||
if (status & SS_POWERON) {
|
||||
|
@ -664,7 +661,7 @@ static int pccardd(void *__skt)
|
|||
spin_unlock_irqrestore(&skt->thread_lock, flags);
|
||||
|
||||
if (events) {
|
||||
down(&skt->skt_sem);
|
||||
mutex_lock(&skt->skt_mutex);
|
||||
if (events & SS_DETECT)
|
||||
socket_detect_change(skt);
|
||||
if (events & SS_BATDEAD)
|
||||
|
@ -673,7 +670,7 @@ static int pccardd(void *__skt)
|
|||
send_event(skt, CS_EVENT_BATTERY_LOW, CS_EVENT_PRI_LOW);
|
||||
if (events & SS_READY)
|
||||
send_event(skt, CS_EVENT_READY_CHANGE, CS_EVENT_PRI_LOW);
|
||||
up(&skt->skt_sem);
|
||||
mutex_unlock(&skt->skt_mutex);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -717,8 +714,8 @@ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
|
|||
{
|
||||
int ret = 0;
|
||||
|
||||
/* s->skt_sem also protects s->callback */
|
||||
down(&s->skt_sem);
|
||||
/* s->skt_mutex also protects s->callback */
|
||||
mutex_lock(&s->skt_mutex);
|
||||
|
||||
if (c) {
|
||||
/* registration */
|
||||
|
@ -734,7 +731,7 @@ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
|
|||
} else
|
||||
s->callback = NULL;
|
||||
err:
|
||||
up(&s->skt_sem);
|
||||
mutex_unlock(&s->skt_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -752,7 +749,7 @@ int pccard_reset_card(struct pcmcia_socket *skt)
|
|||
|
||||
cs_dbg(skt, 1, "resetting socket\n");
|
||||
|
||||
down(&skt->skt_sem);
|
||||
mutex_lock(&skt->skt_mutex);
|
||||
do {
|
||||
if (!(skt->state & SOCKET_PRESENT)) {
|
||||
ret = CS_NO_CARD;
|
||||
|
@ -781,7 +778,7 @@ int pccard_reset_card(struct pcmcia_socket *skt)
|
|||
|
||||
ret = CS_SUCCESS;
|
||||
} while (0);
|
||||
up(&skt->skt_sem);
|
||||
mutex_unlock(&skt->skt_mutex);
|
||||
|
||||
return ret;
|
||||
} /* reset_card */
|
||||
|
@ -797,7 +794,7 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt)
|
|||
|
||||
cs_dbg(skt, 1, "suspending socket\n");
|
||||
|
||||
down(&skt->skt_sem);
|
||||
mutex_lock(&skt->skt_mutex);
|
||||
do {
|
||||
if (!(skt->state & SOCKET_PRESENT)) {
|
||||
ret = CS_NO_CARD;
|
||||
|
@ -814,7 +811,7 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt)
|
|||
}
|
||||
ret = socket_suspend(skt);
|
||||
} while (0);
|
||||
up(&skt->skt_sem);
|
||||
mutex_unlock(&skt->skt_mutex);
|
||||
|
||||
return ret;
|
||||
} /* suspend_card */
|
||||
|
@ -827,7 +824,7 @@ int pcmcia_resume_card(struct pcmcia_socket *skt)
|
|||
|
||||
cs_dbg(skt, 1, "waking up socket\n");
|
||||
|
||||
down(&skt->skt_sem);
|
||||
mutex_lock(&skt->skt_mutex);
|
||||
do {
|
||||
if (!(skt->state & SOCKET_PRESENT)) {
|
||||
ret = CS_NO_CARD;
|
||||
|
@ -841,7 +838,7 @@ int pcmcia_resume_card(struct pcmcia_socket *skt)
|
|||
if (!ret && skt->callback)
|
||||
skt->callback->resume(skt);
|
||||
} while (0);
|
||||
up(&skt->skt_sem);
|
||||
mutex_unlock(&skt->skt_mutex);
|
||||
|
||||
return ret;
|
||||
} /* resume_card */
|
||||
|
@ -855,7 +852,7 @@ int pcmcia_eject_card(struct pcmcia_socket *skt)
|
|||
|
||||
cs_dbg(skt, 1, "user eject request\n");
|
||||
|
||||
down(&skt->skt_sem);
|
||||
mutex_lock(&skt->skt_mutex);
|
||||
do {
|
||||
if (!(skt->state & SOCKET_PRESENT)) {
|
||||
ret = -ENODEV;
|
||||
|
@ -871,7 +868,7 @@ int pcmcia_eject_card(struct pcmcia_socket *skt)
|
|||
socket_remove(skt);
|
||||
ret = 0;
|
||||
} while (0);
|
||||
up(&skt->skt_sem);
|
||||
mutex_unlock(&skt->skt_mutex);
|
||||
|
||||
return ret;
|
||||
} /* eject_card */
|
||||
|
@ -884,7 +881,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
|
|||
|
||||
cs_dbg(skt, 1, "user insert request\n");
|
||||
|
||||
down(&skt->skt_sem);
|
||||
mutex_lock(&skt->skt_mutex);
|
||||
do {
|
||||
if (skt->state & SOCKET_PRESENT) {
|
||||
ret = -EBUSY;
|
||||
|
@ -896,7 +893,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
|
|||
}
|
||||
ret = 0;
|
||||
} while (0);
|
||||
up(&skt->skt_sem);
|
||||
mutex_unlock(&skt->skt_mutex);
|
||||
|
||||
return ret;
|
||||
} /* insert_card */
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#ifndef _LINUX_CS_INTERNAL_H
|
||||
#define _LINUX_CS_INTERNAL_H
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/kref.h>
|
||||
|
||||
/* Flags in client state */
|
||||
#define CLIENT_CONFIG_LOCKED 0x0001
|
||||
|
@ -23,7 +23,7 @@
|
|||
#define CLIENT_IO_REQ 0x0004
|
||||
#define CLIENT_UNBOUND 0x0008
|
||||
#define CLIENT_STALE 0x0010
|
||||
#define CLIENT_WIN_REQ(i) (0x20<<(i))
|
||||
#define CLIENT_WIN_REQ(i) (0x1<<(i))
|
||||
#define CLIENT_CARDBUS 0x8000
|
||||
|
||||
#define REGION_MAGIC 0xE3C9
|
||||
|
@ -31,7 +31,7 @@ typedef struct region_t {
|
|||
u_short region_magic;
|
||||
u_short state;
|
||||
dev_info_t dev_info;
|
||||
client_handle_t mtd;
|
||||
struct pcmcia_device *mtd;
|
||||
u_int MediaID;
|
||||
region_info_t info;
|
||||
} region_t;
|
||||
|
@ -40,12 +40,12 @@ typedef struct region_t {
|
|||
|
||||
/* Each card function gets one of these guys */
|
||||
typedef struct config_t {
|
||||
struct kref ref;
|
||||
u_int state;
|
||||
u_int Attributes;
|
||||
u_int IntType;
|
||||
u_int ConfigBase;
|
||||
u_char Status, Pin, Copy, Option, ExtStatus;
|
||||
u_int Present;
|
||||
u_int CardValues;
|
||||
io_req_t io;
|
||||
struct {
|
||||
|
@ -95,12 +95,6 @@ static inline void cs_socket_put(struct pcmcia_socket *skt)
|
|||
}
|
||||
}
|
||||
|
||||
#define CHECK_SOCKET(s) \
|
||||
(((s) >= sockets) || (socket_table[s]->ops == NULL))
|
||||
|
||||
#define SOCKET(h) (h->socket)
|
||||
#define CONFIG(h) (&SOCKET(h)->config[(h)->func])
|
||||
|
||||
/* In cardbus.c */
|
||||
int cb_alloc(struct pcmcia_socket *s);
|
||||
void cb_free(struct pcmcia_socket *s);
|
||||
|
@ -133,10 +127,9 @@ extern struct class_interface pccard_sysfs_interface;
|
|||
extern struct rw_semaphore pcmcia_socket_list_rwsem;
|
||||
extern struct list_head pcmcia_socket_list;
|
||||
int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, int idx, win_req_t *req);
|
||||
int pccard_get_configuration_info(struct pcmcia_socket *s, unsigned int function, config_info_t *config);
|
||||
int pccard_get_configuration_info(struct pcmcia_socket *s, struct pcmcia_device *p_dev, config_info_t *config);
|
||||
int pccard_reset_card(struct pcmcia_socket *skt);
|
||||
int pccard_get_status(struct pcmcia_socket *s, unsigned int function, cs_status_t *status);
|
||||
int pccard_access_configuration_register(struct pcmcia_socket *s, unsigned int function, conf_reg_t *reg);
|
||||
int pccard_get_status(struct pcmcia_socket *s, struct pcmcia_device *p_dev, cs_status_t *status);
|
||||
|
||||
|
||||
struct pcmcia_callback{
|
||||
|
|
|
@ -10,10 +10,9 @@
|
|||
* are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
|
||||
*
|
||||
* (C) 1999 David A. Hinds
|
||||
* (C) 2003 - 2005 Dominik Brodowski
|
||||
* (C) 2003 - 2006 Dominik Brodowski
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
|
@ -23,6 +22,7 @@
|
|||
#include <linux/workqueue.h>
|
||||
#include <linux/crc32.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/kref.h>
|
||||
|
||||
#define IN_CARD_SERVICES
|
||||
#include <pcmcia/cs_types.h>
|
||||
|
@ -343,12 +343,19 @@ void pcmcia_put_dev(struct pcmcia_device *p_dev)
|
|||
put_device(&p_dev->dev);
|
||||
}
|
||||
|
||||
static void pcmcia_release_function(struct kref *ref)
|
||||
{
|
||||
struct config_t *c = container_of(ref, struct config_t, ref);
|
||||
kfree(c);
|
||||
}
|
||||
|
||||
static void pcmcia_release_dev(struct device *dev)
|
||||
{
|
||||
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
|
||||
ds_dbg(1, "releasing dev %p\n", p_dev);
|
||||
pcmcia_put_socket(p_dev->socket);
|
||||
kfree(p_dev->devname);
|
||||
kref_put(&p_dev->function_config->ref, pcmcia_release_function);
|
||||
kfree(p_dev);
|
||||
}
|
||||
|
||||
|
@ -377,29 +384,12 @@ static int pcmcia_device_probe(struct device * dev)
|
|||
p_drv = to_pcmcia_drv(dev->driver);
|
||||
s = p_dev->socket;
|
||||
|
||||
if ((!p_drv->probe) || (!try_module_get(p_drv->owner))) {
|
||||
if ((!p_drv->probe) || (!p_dev->function_config) ||
|
||||
(!try_module_get(p_drv->owner))) {
|
||||
ret = -EINVAL;
|
||||
goto put_dev;
|
||||
}
|
||||
|
||||
p_dev->state &= ~CLIENT_UNBOUND;
|
||||
|
||||
/* set up the device configuration, if it hasn't been done before */
|
||||
if (!s->functions) {
|
||||
cistpl_longlink_mfc_t mfc;
|
||||
if (pccard_read_tuple(s, p_dev->func, CISTPL_LONGLINK_MFC,
|
||||
&mfc) == CS_SUCCESS)
|
||||
s->functions = mfc.nfn;
|
||||
else
|
||||
s->functions = 1;
|
||||
s->config = kzalloc(sizeof(config_t) * s->functions,
|
||||
GFP_KERNEL);
|
||||
if (!s->config) {
|
||||
ret = -ENOMEM;
|
||||
goto put_module;
|
||||
}
|
||||
}
|
||||
|
||||
ret = p_drv->probe(p_dev);
|
||||
if (ret)
|
||||
goto put_module;
|
||||
|
@ -425,15 +415,61 @@ static int pcmcia_device_probe(struct device * dev)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Removes a PCMCIA card from the device tree and socket list.
|
||||
*/
|
||||
static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *leftover)
|
||||
{
|
||||
struct pcmcia_device *p_dev;
|
||||
struct pcmcia_device *tmp;
|
||||
unsigned long flags;
|
||||
|
||||
ds_dbg(2, "unbind_request(%d)\n", s->sock);
|
||||
|
||||
|
||||
if (!leftover)
|
||||
s->device_count = 0;
|
||||
else
|
||||
s->device_count = 1;
|
||||
|
||||
/* unregister all pcmcia_devices registered with this socket, except leftover */
|
||||
list_for_each_entry_safe(p_dev, tmp, &s->devices_list, socket_device_list) {
|
||||
if (p_dev == leftover)
|
||||
continue;
|
||||
|
||||
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
|
||||
list_del(&p_dev->socket_device_list);
|
||||
p_dev->_removed=1;
|
||||
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
|
||||
|
||||
device_unregister(&p_dev->dev);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static int pcmcia_device_remove(struct device * dev)
|
||||
{
|
||||
struct pcmcia_device *p_dev;
|
||||
struct pcmcia_driver *p_drv;
|
||||
struct pcmcia_device_id *did;
|
||||
int i;
|
||||
|
||||
/* detach the "instance" */
|
||||
p_dev = to_pcmcia_dev(dev);
|
||||
p_drv = to_pcmcia_drv(dev->driver);
|
||||
|
||||
/* If we're removing the primary module driving a
|
||||
* pseudo multi-function card, we need to unbind
|
||||
* all devices
|
||||
*/
|
||||
did = (struct pcmcia_device_id *) p_dev->dev.driver_data;
|
||||
if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) &&
|
||||
(p_dev->socket->device_count != 0) &&
|
||||
(p_dev->device_no == 0))
|
||||
pcmcia_card_remove(p_dev->socket, p_dev);
|
||||
|
||||
/* detach the "instance" */
|
||||
if (!p_drv)
|
||||
return 0;
|
||||
|
||||
|
@ -441,17 +477,16 @@ static int pcmcia_device_remove(struct device * dev)
|
|||
p_drv->remove(p_dev);
|
||||
|
||||
/* check for proper unloading */
|
||||
if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
|
||||
if (p_dev->_irq || p_dev->_io || p_dev->_locked)
|
||||
printk(KERN_INFO "pcmcia: driver %s did not release config properly\n",
|
||||
p_drv->drv.name);
|
||||
|
||||
for (i = 0; i < MAX_WIN; i++)
|
||||
if (p_dev->state & CLIENT_WIN_REQ(i))
|
||||
if (p_dev->_win & CLIENT_WIN_REQ(i))
|
||||
printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n",
|
||||
p_drv->drv.name);
|
||||
|
||||
/* references from pcmcia_probe_device */
|
||||
p_dev->state = CLIENT_UNBOUND;
|
||||
pcmcia_put_dev(p_dev);
|
||||
module_put(p_drv->owner);
|
||||
|
||||
|
@ -459,37 +494,6 @@ static int pcmcia_device_remove(struct device * dev)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Removes a PCMCIA card from the device tree and socket list.
|
||||
*/
|
||||
static void pcmcia_card_remove(struct pcmcia_socket *s)
|
||||
{
|
||||
struct pcmcia_device *p_dev;
|
||||
unsigned long flags;
|
||||
|
||||
ds_dbg(2, "unbind_request(%d)\n", s->sock);
|
||||
|
||||
s->device_count = 0;
|
||||
|
||||
for (;;) {
|
||||
/* unregister all pcmcia_devices registered with this socket*/
|
||||
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
|
||||
if (list_empty(&s->devices_list)) {
|
||||
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
|
||||
return;
|
||||
}
|
||||
p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list);
|
||||
list_del(&p_dev->socket_device_list);
|
||||
p_dev->state |= CLIENT_STALE;
|
||||
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
|
||||
|
||||
device_unregister(&p_dev->dev);
|
||||
}
|
||||
|
||||
return;
|
||||
} /* unbind_request */
|
||||
|
||||
|
||||
/*
|
||||
* pcmcia_device_query -- determine information about a pcmcia device
|
||||
*/
|
||||
|
@ -546,7 +550,7 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
|
|||
tmp = vers1->str + vers1->ofs[i];
|
||||
|
||||
length = strlen(tmp) + 1;
|
||||
if ((length < 3) || (length > 255))
|
||||
if ((length < 2) || (length > 255))
|
||||
continue;
|
||||
|
||||
p_dev->prod_id[i] = kmalloc(sizeof(char) * length,
|
||||
|
@ -571,11 +575,11 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
|
|||
* won't work, this doesn't matter much at the moment: the driver core doesn't
|
||||
* support it either.
|
||||
*/
|
||||
static DECLARE_MUTEX(device_add_lock);
|
||||
static DEFINE_MUTEX(device_add_lock);
|
||||
|
||||
struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function)
|
||||
{
|
||||
struct pcmcia_device *p_dev;
|
||||
struct pcmcia_device *p_dev, *tmp_dev;
|
||||
unsigned long flags;
|
||||
int bus_id_len;
|
||||
|
||||
|
@ -583,7 +587,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
|
|||
if (!s)
|
||||
return NULL;
|
||||
|
||||
down(&device_add_lock);
|
||||
mutex_lock(&device_add_lock);
|
||||
|
||||
/* max of 2 devices per card */
|
||||
if (s->device_count == 2)
|
||||
|
@ -596,6 +600,8 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
|
|||
p_dev->socket = s;
|
||||
p_dev->device_no = (s->device_count++);
|
||||
p_dev->func = function;
|
||||
if (s->functions <= function)
|
||||
s->functions = function + 1;
|
||||
|
||||
p_dev->dev.bus = &pcmcia_bus_type;
|
||||
p_dev->dev.parent = s->dev.dev;
|
||||
|
@ -608,36 +614,55 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
|
|||
sprintf (p_dev->devname, "pcmcia%s", p_dev->dev.bus_id);
|
||||
|
||||
/* compat */
|
||||
p_dev->state = CLIENT_UNBOUND;
|
||||
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
|
||||
|
||||
/*
|
||||
* p_dev->function_config must be the same for all card functions.
|
||||
* Note that this is serialized by the device_add_lock, so that
|
||||
* only one such struct will be created.
|
||||
*/
|
||||
list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list)
|
||||
if (p_dev->func == tmp_dev->func) {
|
||||
p_dev->function_config = tmp_dev->function_config;
|
||||
kref_get(&p_dev->function_config->ref);
|
||||
}
|
||||
|
||||
/* Add to the list in pcmcia_bus_socket */
|
||||
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
|
||||
list_add_tail(&p_dev->socket_device_list, &s->devices_list);
|
||||
|
||||
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
|
||||
|
||||
if (!p_dev->function_config) {
|
||||
p_dev->function_config = kzalloc(sizeof(struct config_t),
|
||||
GFP_KERNEL);
|
||||
if (!p_dev->function_config)
|
||||
goto err_unreg;
|
||||
kref_init(&p_dev->function_config->ref);
|
||||
}
|
||||
|
||||
printk(KERN_NOTICE "pcmcia: registering new device %s\n",
|
||||
p_dev->devname);
|
||||
|
||||
pcmcia_device_query(p_dev);
|
||||
|
||||
if (device_register(&p_dev->dev)) {
|
||||
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
|
||||
list_del(&p_dev->socket_device_list);
|
||||
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
|
||||
if (device_register(&p_dev->dev))
|
||||
goto err_unreg;
|
||||
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
up(&device_add_lock);
|
||||
mutex_unlock(&device_add_lock);
|
||||
|
||||
return p_dev;
|
||||
|
||||
err_unreg:
|
||||
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
|
||||
list_del(&p_dev->socket_device_list);
|
||||
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
|
||||
|
||||
err_free:
|
||||
kfree(p_dev->devname);
|
||||
kfree(p_dev);
|
||||
s->device_count--;
|
||||
err_put:
|
||||
up(&device_add_lock);
|
||||
mutex_unlock(&device_add_lock);
|
||||
pcmcia_put_socket(s);
|
||||
|
||||
return NULL;
|
||||
|
@ -696,7 +721,7 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt)
|
|||
int no_devices=0;
|
||||
unsigned long flags;
|
||||
|
||||
/* must be called with skt_sem held */
|
||||
/* must be called with skt_mutex held */
|
||||
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
|
||||
if (list_empty(&skt->devices_list))
|
||||
no_devices=1;
|
||||
|
@ -819,9 +844,11 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
|
|||
struct pcmcia_driver * p_drv = to_pcmcia_drv(drv);
|
||||
struct pcmcia_device_id *did = p_drv->id_table;
|
||||
|
||||
#ifdef CONFIG_PCMCIA_IOCTL
|
||||
/* matching by cardmgr */
|
||||
if (p_dev->cardmgr == p_drv)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
while (did && did->match_flags) {
|
||||
if (pcmcia_devmatch(p_dev, did))
|
||||
|
@ -927,7 +954,7 @@ static ssize_t pcmcia_show_pm_state(struct device *dev, struct device_attribute
|
|||
{
|
||||
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
|
||||
|
||||
if (p_dev->dev.power.power_state.event != PM_EVENT_ON)
|
||||
if (p_dev->suspended)
|
||||
return sprintf(buf, "off\n");
|
||||
else
|
||||
return sprintf(buf, "on\n");
|
||||
|
@ -942,11 +969,9 @@ static ssize_t pcmcia_store_pm_state(struct device *dev, struct device_attribute
|
|||
if (!count)
|
||||
return -EINVAL;
|
||||
|
||||
if ((p_dev->dev.power.power_state.event == PM_EVENT_ON) &&
|
||||
(!strncmp(buf, "off", 3)))
|
||||
if ((!p_dev->suspended) && !strncmp(buf, "off", 3))
|
||||
ret = dpm_runtime_suspend(dev, PMSG_SUSPEND);
|
||||
else if ((p_dev->dev.power.power_state.event != PM_EVENT_ON) &&
|
||||
(!strncmp(buf, "on", 2)))
|
||||
else if (p_dev->suspended && !strncmp(buf, "on", 2))
|
||||
dpm_runtime_resume(dev);
|
||||
|
||||
return ret ? ret : count;
|
||||
|
@ -982,9 +1007,9 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev,
|
|||
if (!count)
|
||||
return -EINVAL;
|
||||
|
||||
down(&p_dev->socket->skt_sem);
|
||||
mutex_lock(&p_dev->socket->skt_mutex);
|
||||
p_dev->allow_func_id_match = 1;
|
||||
up(&p_dev->socket->skt_sem);
|
||||
mutex_unlock(&p_dev->socket->skt_mutex);
|
||||
|
||||
bus_rescan_devices(&pcmcia_bus_type);
|
||||
|
||||
|
@ -1012,14 +1037,27 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
|
|||
{
|
||||
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
|
||||
struct pcmcia_driver *p_drv = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (dev->driver)
|
||||
p_drv = to_pcmcia_drv(dev->driver);
|
||||
|
||||
if (p_drv && p_drv->suspend)
|
||||
return p_drv->suspend(p_dev);
|
||||
if (!p_drv)
|
||||
goto out;
|
||||
|
||||
return 0;
|
||||
if (p_drv->suspend) {
|
||||
ret = p_drv->suspend(p_dev);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (p_dev->device_no == p_dev->func)
|
||||
pcmcia_release_configuration(p_dev);
|
||||
|
||||
out:
|
||||
if (!ret)
|
||||
p_dev->suspended = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1027,14 +1065,27 @@ static int pcmcia_dev_resume(struct device * dev)
|
|||
{
|
||||
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
|
||||
struct pcmcia_driver *p_drv = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (dev->driver)
|
||||
p_drv = to_pcmcia_drv(dev->driver);
|
||||
|
||||
if (p_drv && p_drv->resume)
|
||||
return p_drv->resume(p_dev);
|
||||
if (!p_drv)
|
||||
goto out;
|
||||
|
||||
return 0;
|
||||
if (p_dev->device_no == p_dev->func) {
|
||||
ret = pcmcia_request_configuration(p_dev, &p_dev->conf);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (p_drv->resume)
|
||||
ret = p_drv->resume(p_dev);
|
||||
|
||||
out:
|
||||
if (!ret)
|
||||
p_dev->suspended = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1100,7 +1151,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
|
|||
switch (event) {
|
||||
case CS_EVENT_CARD_REMOVAL:
|
||||
s->pcmcia_state.present = 0;
|
||||
pcmcia_card_remove(skt);
|
||||
pcmcia_card_remove(skt, NULL);
|
||||
handle_event(skt, event);
|
||||
break;
|
||||
|
||||
|
@ -1128,6 +1179,32 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
|
|||
} /* ds_event */
|
||||
|
||||
|
||||
struct pcmcia_device * pcmcia_dev_present(struct pcmcia_device *_p_dev)
|
||||
{
|
||||
struct pcmcia_device *p_dev;
|
||||
struct pcmcia_device *ret = NULL;
|
||||
|
||||
p_dev = pcmcia_get_dev(_p_dev);
|
||||
if (!p_dev)
|
||||
return NULL;
|
||||
|
||||
if (!p_dev->socket->pcmcia_state.present)
|
||||
goto out;
|
||||
|
||||
if (p_dev->_removed)
|
||||
goto out;
|
||||
|
||||
if (p_dev->suspended)
|
||||
goto out;
|
||||
|
||||
ret = p_dev;
|
||||
out:
|
||||
pcmcia_put_dev(p_dev);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(pcmcia_dev_present);
|
||||
|
||||
|
||||
static struct pcmcia_callback pcmcia_bus_callback = {
|
||||
.owner = THIS_MODULE,
|
||||
.event = ds_event,
|
||||
|
|
|
@ -8,6 +8,8 @@ extern void pcmcia_put_dev(struct pcmcia_device *p_dev);
|
|||
|
||||
struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function);
|
||||
|
||||
extern int pcmcia_release_configuration(struct pcmcia_device *p_dev);
|
||||
|
||||
#ifdef CONFIG_PCMCIA_IOCTL
|
||||
extern void __init pcmcia_setup_ioctl(void);
|
||||
extern void __exit pcmcia_cleanup_ioctl(void);
|
||||
|
@ -15,7 +17,7 @@ extern void handle_event(struct pcmcia_socket *s, event_t event);
|
|||
extern int handle_request(struct pcmcia_socket *s, event_t event);
|
||||
#else
|
||||
static inline void __init pcmcia_setup_ioctl(void) { return; }
|
||||
static inline void __init pcmcia_cleanup_ioctl(void) { return; }
|
||||
static inline void __exit pcmcia_cleanup_ioctl(void) { return; }
|
||||
static inline void handle_event(struct pcmcia_socket *s, event_t event) { return; }
|
||||
static inline int handle_request(struct pcmcia_socket *s, event_t event) { return CS_SUCCESS; }
|
||||
#endif
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/config.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/string.h>
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* PCMCIA 16-bit compatibility functions
|
||||
*
|
||||
* The initial developer of the original code is David A. Hinds
|
||||
* <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
|
||||
* are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
|
||||
*
|
||||
* Copyright (C) 2004 Dominik Brodowski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#define IN_CARD_SERVICES
|
||||
#include <pcmcia/cs_types.h>
|
||||
#include <pcmcia/cs.h>
|
||||
#include <pcmcia/bulkmem.h>
|
||||
#include <pcmcia/cistpl.h>
|
||||
#include <pcmcia/ds.h>
|
||||
#include <pcmcia/ss.h>
|
||||
|
||||
#include "cs_internal.h"
|
||||
|
||||
int pcmcia_get_first_tuple(struct pcmcia_device *p_dev, tuple_t *tuple)
|
||||
{
|
||||
return pccard_get_first_tuple(p_dev->socket, p_dev->func, tuple);
|
||||
}
|
||||
EXPORT_SYMBOL(pcmcia_get_first_tuple);
|
||||
|
||||
int pcmcia_get_next_tuple(struct pcmcia_device *p_dev, tuple_t *tuple)
|
||||
{
|
||||
return pccard_get_next_tuple(p_dev->socket, p_dev->func, tuple);
|
||||
}
|
||||
EXPORT_SYMBOL(pcmcia_get_next_tuple);
|
||||
|
||||
int pcmcia_get_tuple_data(struct pcmcia_device *p_dev, tuple_t *tuple)
|
||||
{
|
||||
return pccard_get_tuple_data(p_dev->socket, tuple);
|
||||
}
|
||||
EXPORT_SYMBOL(pcmcia_get_tuple_data);
|
||||
|
||||
int pcmcia_parse_tuple(struct pcmcia_device *p_dev, tuple_t *tuple, cisparse_t *parse)
|
||||
{
|
||||
return pccard_parse_tuple(tuple, parse);
|
||||
}
|
||||
EXPORT_SYMBOL(pcmcia_parse_tuple);
|
||||
|
||||
int pcmcia_validate_cis(struct pcmcia_device *p_dev, cisinfo_t *info)
|
||||
{
|
||||
return pccard_validate_cis(p_dev->socket, p_dev->func, info);
|
||||
}
|
||||
EXPORT_SYMBOL(pcmcia_validate_cis);
|
||||
|
||||
|
||||
int pcmcia_reset_card(struct pcmcia_device *p_dev, client_req_t *req)
|
||||
{
|
||||
return pccard_reset_card(p_dev->socket);
|
||||
}
|
||||
EXPORT_SYMBOL(pcmcia_reset_card);
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
|
@ -70,10 +69,26 @@ extern int ds_pc_debug;
|
|||
#define ds_dbg(lvl, fmt, arg...) do { } while (0)
|
||||
#endif
|
||||
|
||||
static struct pcmcia_device *get_pcmcia_device(struct pcmcia_socket *s,
|
||||
unsigned int function)
|
||||
{
|
||||
struct pcmcia_device *p_dev = NULL;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
|
||||
list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
|
||||
if (p_dev->func == function) {
|
||||
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
|
||||
return pcmcia_get_dev(p_dev);
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* backwards-compatible accessing of driver --- by name! */
|
||||
|
||||
static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info)
|
||||
static struct pcmcia_driver *get_pcmcia_driver(dev_info_t *dev_info)
|
||||
{
|
||||
struct device_driver *drv;
|
||||
struct pcmcia_driver *p_drv;
|
||||
|
@ -214,7 +229,7 @@ static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
|
|||
* by userspace before, we need to
|
||||
* return the "instance". */
|
||||
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
|
||||
bind_info->instance = p_dev->instance;
|
||||
bind_info->instance = p_dev;
|
||||
ret = -EBUSY;
|
||||
goto err_put_module;
|
||||
} else {
|
||||
|
@ -253,9 +268,9 @@ static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
|
|||
/*
|
||||
* Prevent this racing with a card insertion.
|
||||
*/
|
||||
down(&s->skt_sem);
|
||||
mutex_lock(&s->skt_mutex);
|
||||
bus_rescan_devices(&pcmcia_bus_type);
|
||||
up(&s->skt_sem);
|
||||
mutex_unlock(&s->skt_mutex);
|
||||
|
||||
/* check whether the driver indeed matched. I don't care if this
|
||||
* is racy or not, because it can only happen on cardmgr access
|
||||
|
@ -289,6 +304,7 @@ static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int
|
|||
{
|
||||
dev_node_t *node;
|
||||
struct pcmcia_device *p_dev;
|
||||
struct pcmcia_driver *p_drv;
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
|
@ -343,16 +359,16 @@ static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int
|
|||
found:
|
||||
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
|
||||
|
||||
if ((!p_dev->instance) ||
|
||||
(p_dev->instance->state & DEV_CONFIG_PENDING)) {
|
||||
p_drv = to_pcmcia_drv(p_dev->dev.driver);
|
||||
if (p_drv && !p_dev->_locked) {
|
||||
ret = -EAGAIN;
|
||||
goto err_put;
|
||||
}
|
||||
|
||||
if (first)
|
||||
node = p_dev->instance->dev;
|
||||
node = p_dev->dev_node;
|
||||
else
|
||||
for (node = p_dev->instance->dev; node; node = node->next)
|
||||
for (node = p_dev->dev_node; node; node = node->next)
|
||||
if (node == bind_info->next)
|
||||
break;
|
||||
if (!node) {
|
||||
|
@ -583,14 +599,16 @@ static int ds_ioctl(struct inode * inode, struct file * file,
|
|||
if (buf->config.Function &&
|
||||
(buf->config.Function >= s->functions))
|
||||
ret = CS_BAD_ARGS;
|
||||
else
|
||||
ret = pccard_get_configuration_info(s,
|
||||
buf->config.Function, &buf->config);
|
||||
else {
|
||||
struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function);
|
||||
ret = pccard_get_configuration_info(s, p_dev, &buf->config);
|
||||
pcmcia_put_dev(p_dev);
|
||||
}
|
||||
break;
|
||||
case DS_GET_FIRST_TUPLE:
|
||||
down(&s->skt_sem);
|
||||
mutex_lock(&s->skt_mutex);
|
||||
pcmcia_validate_mem(s);
|
||||
up(&s->skt_sem);
|
||||
mutex_unlock(&s->skt_mutex);
|
||||
ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple);
|
||||
break;
|
||||
case DS_GET_NEXT_TUPLE:
|
||||
|
@ -609,16 +627,19 @@ static int ds_ioctl(struct inode * inode, struct file * file,
|
|||
ret = pccard_reset_card(s);
|
||||
break;
|
||||
case DS_GET_STATUS:
|
||||
if (buf->status.Function &&
|
||||
(buf->status.Function >= s->functions))
|
||||
ret = CS_BAD_ARGS;
|
||||
else
|
||||
ret = pccard_get_status(s, buf->status.Function, &buf->status);
|
||||
break;
|
||||
if (buf->status.Function &&
|
||||
(buf->status.Function >= s->functions))
|
||||
ret = CS_BAD_ARGS;
|
||||
else {
|
||||
struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function);
|
||||
ret = pccard_get_status(s, p_dev, &buf->status);
|
||||
pcmcia_put_dev(p_dev);
|
||||
}
|
||||
break;
|
||||
case DS_VALIDATE_CIS:
|
||||
down(&s->skt_sem);
|
||||
mutex_lock(&s->skt_mutex);
|
||||
pcmcia_validate_mem(s);
|
||||
up(&s->skt_sem);
|
||||
mutex_unlock(&s->skt_mutex);
|
||||
ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo);
|
||||
break;
|
||||
case DS_SUSPEND_CARD:
|
||||
|
@ -638,12 +659,16 @@ static int ds_ioctl(struct inode * inode, struct file * file,
|
|||
err = -EPERM;
|
||||
goto free_out;
|
||||
}
|
||||
if (buf->conf_reg.Function &&
|
||||
(buf->conf_reg.Function >= s->functions))
|
||||
ret = CS_BAD_ARGS;
|
||||
else
|
||||
ret = pccard_access_configuration_register(s,
|
||||
buf->conf_reg.Function, &buf->conf_reg);
|
||||
|
||||
ret = CS_BAD_ARGS;
|
||||
|
||||
if (!(buf->conf_reg.Function &&
|
||||
(buf->conf_reg.Function >= s->functions))) {
|
||||
struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->conf_reg.Function);
|
||||
if (p_dev)
|
||||
ret = pcmcia_access_configuration_register(p_dev, &buf->conf_reg);
|
||||
pcmcia_put_dev(p_dev);
|
||||
}
|
||||
break;
|
||||
case DS_GET_FIRST_REGION:
|
||||
case DS_GET_NEXT_REGION:
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
@ -89,7 +88,7 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base,
|
|||
}
|
||||
if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) {
|
||||
*base = s->io_offset | (*base & 0x0fff);
|
||||
s->io[0].Attributes = attr;
|
||||
s->io[0].res->flags = (s->io[0].res->flags & ~IORESOURCE_BITS) | (attr & IORESOURCE_BITS);
|
||||
return 0;
|
||||
}
|
||||
/* Check for an already-allocated window that must conflict with
|
||||
|
@ -97,38 +96,36 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base,
|
|||
* potential conflicts, just the most obvious ones.
|
||||
*/
|
||||
for (i = 0; i < MAX_IO_WIN; i++)
|
||||
if ((s->io[i].NumPorts != 0) &&
|
||||
((s->io[i].BasePort & (align-1)) == *base))
|
||||
if ((s->io[i].res) &&
|
||||
((s->io[i].res->start & (align-1)) == *base))
|
||||
return 1;
|
||||
for (i = 0; i < MAX_IO_WIN; i++) {
|
||||
if (s->io[i].NumPorts == 0) {
|
||||
if (!s->io[i].res) {
|
||||
s->io[i].res = pcmcia_find_io_region(*base, num, align, s);
|
||||
if (s->io[i].res) {
|
||||
s->io[i].Attributes = attr;
|
||||
s->io[i].BasePort = *base = s->io[i].res->start;
|
||||
s->io[i].NumPorts = s->io[i].InUse = num;
|
||||
*base = s->io[i].res->start;
|
||||
s->io[i].res->flags = (s->io[i].res->flags & ~IORESOURCE_BITS) | (attr & IORESOURCE_BITS);
|
||||
s->io[i].InUse = num;
|
||||
break;
|
||||
} else
|
||||
return 1;
|
||||
} else if (s->io[i].Attributes != attr)
|
||||
} else if ((s->io[i].res->flags & IORESOURCE_BITS) != (attr & IORESOURCE_BITS))
|
||||
continue;
|
||||
/* Try to extend top of window */
|
||||
try = s->io[i].BasePort + s->io[i].NumPorts;
|
||||
try = s->io[i].res->end + 1;
|
||||
if ((*base == 0) || (*base == try))
|
||||
if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start,
|
||||
s->io[i].res->end + num, s) == 0) {
|
||||
*base = try;
|
||||
s->io[i].NumPorts += num;
|
||||
s->io[i].InUse += num;
|
||||
break;
|
||||
}
|
||||
/* Try to extend bottom of window */
|
||||
try = s->io[i].BasePort - num;
|
||||
try = s->io[i].res->start - num;
|
||||
if ((*base == 0) || (*base == try))
|
||||
if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start - num,
|
||||
s->io[i].res->end, s) == 0) {
|
||||
s->io[i].BasePort = *base = try;
|
||||
s->io[i].NumPorts += num;
|
||||
*base = try;
|
||||
s->io[i].InUse += num;
|
||||
break;
|
||||
}
|
||||
|
@ -143,12 +140,13 @@ static void release_io_space(struct pcmcia_socket *s, ioaddr_t base,
|
|||
int i;
|
||||
|
||||
for (i = 0; i < MAX_IO_WIN; i++) {
|
||||
if ((s->io[i].BasePort <= base) &&
|
||||
(s->io[i].BasePort+s->io[i].NumPorts >= base+num)) {
|
||||
if (!s->io[i].res)
|
||||
continue;
|
||||
if ((s->io[i].res->start <= base) &&
|
||||
(s->io[i].res->end >= base+num-1)) {
|
||||
s->io[i].InUse -= num;
|
||||
/* Free the window if no one else is using it */
|
||||
if (s->io[i].InUse == 0) {
|
||||
s->io[i].NumPorts = 0;
|
||||
release_resource(s->io[i].res);
|
||||
kfree(s->io[i].res);
|
||||
s->io[i].res = NULL;
|
||||
|
@ -165,21 +163,19 @@ static void release_io_space(struct pcmcia_socket *s, ioaddr_t base,
|
|||
* this and the tuple reading services.
|
||||
*/
|
||||
|
||||
int pccard_access_configuration_register(struct pcmcia_socket *s,
|
||||
unsigned int function,
|
||||
int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
|
||||
conf_reg_t *reg)
|
||||
{
|
||||
struct pcmcia_socket *s;
|
||||
config_t *c;
|
||||
int addr;
|
||||
u_char val;
|
||||
|
||||
if (!s || !s->config)
|
||||
if (!p_dev || !p_dev->function_config)
|
||||
return CS_NO_CARD;
|
||||
|
||||
c = &s->config[function];
|
||||
|
||||
if (c == NULL)
|
||||
return CS_NO_CARD;
|
||||
s = p_dev->socket;
|
||||
c = p_dev->function_config;
|
||||
|
||||
if (!(c->state & CONFIG_LOCKED))
|
||||
return CS_CONFIGURATION_LOCKED;
|
||||
|
@ -200,20 +196,12 @@ int pccard_access_configuration_register(struct pcmcia_socket *s,
|
|||
break;
|
||||
}
|
||||
return CS_SUCCESS;
|
||||
} /* pccard_access_configuration_register */
|
||||
|
||||
int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
|
||||
conf_reg_t *reg)
|
||||
{
|
||||
return pccard_access_configuration_register(p_dev->socket,
|
||||
p_dev->func, reg);
|
||||
}
|
||||
} /* pcmcia_access_configuration_register */
|
||||
EXPORT_SYMBOL(pcmcia_access_configuration_register);
|
||||
|
||||
|
||||
|
||||
int pccard_get_configuration_info(struct pcmcia_socket *s,
|
||||
unsigned int function,
|
||||
struct pcmcia_device *p_dev,
|
||||
config_info_t *config)
|
||||
{
|
||||
config_t *c;
|
||||
|
@ -221,7 +209,7 @@ int pccard_get_configuration_info(struct pcmcia_socket *s,
|
|||
if (!(s->state & SOCKET_PRESENT))
|
||||
return CS_NO_CARD;
|
||||
|
||||
config->Function = function;
|
||||
config->Function = p_dev->func;
|
||||
|
||||
#ifdef CONFIG_CARDBUS
|
||||
if (s->state & SOCKET_CARDBUS) {
|
||||
|
@ -235,14 +223,14 @@ int pccard_get_configuration_info(struct pcmcia_socket *s,
|
|||
config->AssignedIRQ = s->irq.AssignedIRQ;
|
||||
if (config->AssignedIRQ)
|
||||
config->Attributes |= CONF_ENABLE_IRQ;
|
||||
config->BasePort1 = s->io[0].BasePort;
|
||||
config->NumPorts1 = s->io[0].NumPorts;
|
||||
config->BasePort1 = s->io[0].res->start;
|
||||
config->NumPorts1 = s->io[0].res->end - config->BasePort1 + 1;
|
||||
}
|
||||
return CS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
c = (s->config != NULL) ? &s->config[function] : NULL;
|
||||
c = (p_dev) ? p_dev->function_config : NULL;
|
||||
|
||||
if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {
|
||||
config->Attributes = 0;
|
||||
|
@ -271,7 +259,7 @@ int pccard_get_configuration_info(struct pcmcia_socket *s,
|
|||
int pcmcia_get_configuration_info(struct pcmcia_device *p_dev,
|
||||
config_info_t *config)
|
||||
{
|
||||
return pccard_get_configuration_info(p_dev->socket, p_dev->func,
|
||||
return pccard_get_configuration_info(p_dev->socket, p_dev,
|
||||
config);
|
||||
}
|
||||
EXPORT_SYMBOL(pcmcia_get_configuration_info);
|
||||
|
@ -317,7 +305,7 @@ EXPORT_SYMBOL(pcmcia_get_window);
|
|||
* SocketState yet: I haven't seen any point for it.
|
||||
*/
|
||||
|
||||
int pccard_get_status(struct pcmcia_socket *s, unsigned int function,
|
||||
int pccard_get_status(struct pcmcia_socket *s, struct pcmcia_device *p_dev,
|
||||
cs_status_t *status)
|
||||
{
|
||||
config_t *c;
|
||||
|
@ -334,11 +322,12 @@ int pccard_get_status(struct pcmcia_socket *s, unsigned int function,
|
|||
if (!(s->state & SOCKET_PRESENT))
|
||||
return CS_NO_CARD;
|
||||
|
||||
c = (s->config != NULL) ? &s->config[function] : NULL;
|
||||
c = (p_dev) ? p_dev->function_config : NULL;
|
||||
|
||||
if ((c != NULL) && (c->state & CONFIG_LOCKED) &&
|
||||
(c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {
|
||||
u_char reg;
|
||||
if (c->Present & PRESENT_PIN_REPLACE) {
|
||||
if (c->CardValues & PRESENT_PIN_REPLACE) {
|
||||
pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, ®);
|
||||
status->CardState |=
|
||||
(reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;
|
||||
|
@ -352,7 +341,7 @@ int pccard_get_status(struct pcmcia_socket *s, unsigned int function,
|
|||
/* No PRR? Then assume we're always ready */
|
||||
status->CardState |= CS_EVENT_READY_CHANGE;
|
||||
}
|
||||
if (c->Present & PRESENT_EXT_STATUS) {
|
||||
if (c->CardValues & PRESENT_EXT_STATUS) {
|
||||
pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, ®);
|
||||
status->CardState |=
|
||||
(reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;
|
||||
|
@ -370,11 +359,9 @@ int pccard_get_status(struct pcmcia_socket *s, unsigned int function,
|
|||
return CS_SUCCESS;
|
||||
} /* pccard_get_status */
|
||||
|
||||
int pcmcia_get_status(client_handle_t handle, cs_status_t *status)
|
||||
int pcmcia_get_status(struct pcmcia_device *p_dev, cs_status_t *status)
|
||||
{
|
||||
struct pcmcia_socket *s;
|
||||
s = SOCKET(handle);
|
||||
return pccard_get_status(s, handle->func, status);
|
||||
return pccard_get_status(p_dev->socket, p_dev, status);
|
||||
}
|
||||
EXPORT_SYMBOL(pcmcia_get_status);
|
||||
|
||||
|
@ -422,7 +409,8 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
|
|||
config_t *c;
|
||||
|
||||
s = p_dev->socket;
|
||||
c = CONFIG(p_dev);
|
||||
c = p_dev->function_config;
|
||||
|
||||
if (!(s->state & SOCKET_PRESENT))
|
||||
return CS_NO_CARD;
|
||||
if (!(c->state & CONFIG_LOCKED))
|
||||
|
@ -454,6 +442,28 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
|
|||
(mod->Attributes & CONF_VPP2_CHANGE_VALID))
|
||||
return CS_BAD_VPP;
|
||||
|
||||
if (mod->Attributes & CONF_IO_CHANGE_WIDTH) {
|
||||
pccard_io_map io_off = { 0, 0, 0, 0, 1 };
|
||||
pccard_io_map io_on;
|
||||
int i;
|
||||
|
||||
io_on.speed = io_speed;
|
||||
for (i = 0; i < MAX_IO_WIN; i++) {
|
||||
if (!s->io[i].res)
|
||||
continue;
|
||||
io_off.map = i;
|
||||
io_on.map = i;
|
||||
|
||||
io_on.flags = MAP_ACTIVE | IO_DATA_PATH_WIDTH_8;
|
||||
io_on.start = s->io[i].res->start;
|
||||
io_on.stop = s->io[i].res->end;
|
||||
|
||||
s->ops->set_io_map(s, &io_off);
|
||||
mdelay(40);
|
||||
s->ops->set_io_map(s, &io_on);
|
||||
}
|
||||
}
|
||||
|
||||
return CS_SUCCESS;
|
||||
} /* modify_configuration */
|
||||
EXPORT_SYMBOL(pcmcia_modify_configuration);
|
||||
|
@ -463,23 +473,23 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev)
|
|||
{
|
||||
pccard_io_map io = { 0, 0, 0, 0, 1 };
|
||||
struct pcmcia_socket *s = p_dev->socket;
|
||||
config_t *c = p_dev->function_config;
|
||||
int i;
|
||||
|
||||
if (!(p_dev->state & CLIENT_CONFIG_LOCKED))
|
||||
return CS_BAD_HANDLE;
|
||||
p_dev->state &= ~CLIENT_CONFIG_LOCKED;
|
||||
|
||||
if (!(p_dev->state & CLIENT_STALE)) {
|
||||
config_t *c = CONFIG(p_dev);
|
||||
if (p_dev->_locked) {
|
||||
p_dev->_locked = 0;
|
||||
if (--(s->lock_count) == 0) {
|
||||
s->socket.flags = SS_OUTPUT_ENA; /* Is this correct? */
|
||||
s->socket.Vpp = 0;
|
||||
s->socket.io_irq = 0;
|
||||
s->ops->set_socket(s, &s->socket);
|
||||
}
|
||||
}
|
||||
if (c->state & CONFIG_LOCKED) {
|
||||
c->state &= ~CONFIG_LOCKED;
|
||||
if (c->state & CONFIG_IO_REQ)
|
||||
for (i = 0; i < MAX_IO_WIN; i++) {
|
||||
if (s->io[i].NumPorts == 0)
|
||||
if (!s->io[i].res)
|
||||
continue;
|
||||
s->io[i].Config--;
|
||||
if (s->io[i].Config != 0)
|
||||
|
@ -487,12 +497,10 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev)
|
|||
io.map = i;
|
||||
s->ops->set_io_map(s, &io);
|
||||
}
|
||||
c->state &= ~CONFIG_LOCKED;
|
||||
}
|
||||
|
||||
return CS_SUCCESS;
|
||||
} /* pcmcia_release_configuration */
|
||||
EXPORT_SYMBOL(pcmcia_release_configuration);
|
||||
|
||||
|
||||
/** pcmcia_release_io
|
||||
|
@ -503,25 +511,23 @@ EXPORT_SYMBOL(pcmcia_release_configuration);
|
|||
* don't bother checking the port ranges against the current socket
|
||||
* values.
|
||||
*/
|
||||
int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
|
||||
static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
|
||||
{
|
||||
struct pcmcia_socket *s = p_dev->socket;
|
||||
config_t *c = p_dev->function_config;
|
||||
|
||||
if (!(p_dev->state & CLIENT_IO_REQ))
|
||||
if (!p_dev->_io )
|
||||
return CS_BAD_HANDLE;
|
||||
p_dev->state &= ~CLIENT_IO_REQ;
|
||||
|
||||
if (!(p_dev->state & CLIENT_STALE)) {
|
||||
config_t *c = CONFIG(p_dev);
|
||||
if (c->state & CONFIG_LOCKED)
|
||||
return CS_CONFIGURATION_LOCKED;
|
||||
if ((c->io.BasePort1 != req->BasePort1) ||
|
||||
(c->io.NumPorts1 != req->NumPorts1) ||
|
||||
(c->io.BasePort2 != req->BasePort2) ||
|
||||
(c->io.NumPorts2 != req->NumPorts2))
|
||||
return CS_BAD_ARGS;
|
||||
c->state &= ~CONFIG_IO_REQ;
|
||||
}
|
||||
p_dev->_io = 0;
|
||||
|
||||
if ((c->io.BasePort1 != req->BasePort1) ||
|
||||
(c->io.NumPorts1 != req->NumPorts1) ||
|
||||
(c->io.BasePort2 != req->BasePort2) ||
|
||||
(c->io.NumPorts2 != req->NumPorts2))
|
||||
return CS_BAD_ARGS;
|
||||
|
||||
c->state &= ~CONFIG_IO_REQ;
|
||||
|
||||
release_io_space(s, req->BasePort1, req->NumPorts1);
|
||||
if (req->NumPorts2)
|
||||
|
@ -529,28 +535,26 @@ int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
|
|||
|
||||
return CS_SUCCESS;
|
||||
} /* pcmcia_release_io */
|
||||
EXPORT_SYMBOL(pcmcia_release_io);
|
||||
|
||||
|
||||
int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
|
||||
static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
|
||||
{
|
||||
struct pcmcia_socket *s = p_dev->socket;
|
||||
if (!(p_dev->state & CLIENT_IRQ_REQ))
|
||||
return CS_BAD_HANDLE;
|
||||
p_dev->state &= ~CLIENT_IRQ_REQ;
|
||||
config_t *c= p_dev->function_config;
|
||||
|
||||
if (!(p_dev->state & CLIENT_STALE)) {
|
||||
config_t *c = CONFIG(p_dev);
|
||||
if (c->state & CONFIG_LOCKED)
|
||||
return CS_CONFIGURATION_LOCKED;
|
||||
if (c->irq.Attributes != req->Attributes)
|
||||
return CS_BAD_ATTRIBUTE;
|
||||
if (s->irq.AssignedIRQ != req->AssignedIRQ)
|
||||
return CS_BAD_IRQ;
|
||||
if (--s->irq.Config == 0) {
|
||||
c->state &= ~CONFIG_IRQ_REQ;
|
||||
s->irq.AssignedIRQ = 0;
|
||||
}
|
||||
if (!p_dev->_irq)
|
||||
return CS_BAD_HANDLE;
|
||||
p_dev->_irq = 0;
|
||||
|
||||
if (c->state & CONFIG_LOCKED)
|
||||
return CS_CONFIGURATION_LOCKED;
|
||||
if (c->irq.Attributes != req->Attributes)
|
||||
return CS_BAD_ATTRIBUTE;
|
||||
if (s->irq.AssignedIRQ != req->AssignedIRQ)
|
||||
return CS_BAD_IRQ;
|
||||
if (--s->irq.Config == 0) {
|
||||
c->state &= ~CONFIG_IRQ_REQ;
|
||||
s->irq.AssignedIRQ = 0;
|
||||
}
|
||||
|
||||
if (req->Attributes & IRQ_HANDLE_PRESENT) {
|
||||
|
@ -563,7 +567,6 @@ int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
|
|||
|
||||
return CS_SUCCESS;
|
||||
} /* pcmcia_release_irq */
|
||||
EXPORT_SYMBOL(pcmcia_release_irq);
|
||||
|
||||
|
||||
int pcmcia_release_window(window_handle_t win)
|
||||
|
@ -573,7 +576,7 @@ int pcmcia_release_window(window_handle_t win)
|
|||
if ((win == NULL) || (win->magic != WINDOW_MAGIC))
|
||||
return CS_BAD_HANDLE;
|
||||
s = win->sock;
|
||||
if (!(win->handle->state & CLIENT_WIN_REQ(win->index)))
|
||||
if (!(win->handle->_win & CLIENT_WIN_REQ(win->index)))
|
||||
return CS_BAD_HANDLE;
|
||||
|
||||
/* Shut down memory window */
|
||||
|
@ -587,7 +590,7 @@ int pcmcia_release_window(window_handle_t win)
|
|||
kfree(win->ctl.res);
|
||||
win->ctl.res = NULL;
|
||||
}
|
||||
win->handle->state &= ~CLIENT_WIN_REQ(win->index);
|
||||
win->handle->_win &= ~CLIENT_WIN_REQ(win->index);
|
||||
|
||||
win->magic = 0;
|
||||
|
||||
|
@ -610,16 +613,12 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
|
|||
|
||||
if (req->IntType & INT_CARDBUS)
|
||||
return CS_UNSUPPORTED_MODE;
|
||||
c = CONFIG(p_dev);
|
||||
c = p_dev->function_config;
|
||||
if (c->state & CONFIG_LOCKED)
|
||||
return CS_CONFIGURATION_LOCKED;
|
||||
|
||||
/* Do power control. We don't allow changes in Vcc. */
|
||||
if (s->socket.Vcc != req->Vcc)
|
||||
return CS_BAD_VCC;
|
||||
if (req->Vpp1 != req->Vpp2)
|
||||
return CS_BAD_VPP;
|
||||
s->socket.Vpp = req->Vpp1;
|
||||
s->socket.Vpp = req->Vpp;
|
||||
if (s->ops->set_socket(s, &s->socket))
|
||||
return CS_BAD_VPP;
|
||||
|
||||
|
@ -643,7 +642,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
|
|||
|
||||
/* Set up CIS configuration registers */
|
||||
base = c->ConfigBase = req->ConfigBase;
|
||||
c->Present = c->CardValues = req->Present;
|
||||
c->CardValues = req->Present;
|
||||
if (req->Present & PRESENT_COPY) {
|
||||
c->Copy = req->Copy;
|
||||
pcmcia_write_cis_mem(s, 1, (base + CISREG_SCR)>>1, 1, &c->Copy);
|
||||
|
@ -690,10 +689,10 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
|
|||
if (c->state & CONFIG_IO_REQ) {
|
||||
iomap.speed = io_speed;
|
||||
for (i = 0; i < MAX_IO_WIN; i++)
|
||||
if (s->io[i].NumPorts != 0) {
|
||||
if (s->io[i].res) {
|
||||
iomap.map = i;
|
||||
iomap.flags = MAP_ACTIVE;
|
||||
switch (s->io[i].Attributes & IO_DATA_PATH_WIDTH) {
|
||||
switch (s->io[i].res->flags & IO_DATA_PATH_WIDTH) {
|
||||
case IO_DATA_PATH_WIDTH_16:
|
||||
iomap.flags |= MAP_16BIT; break;
|
||||
case IO_DATA_PATH_WIDTH_AUTO:
|
||||
|
@ -701,15 +700,15 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
iomap.start = s->io[i].BasePort;
|
||||
iomap.stop = iomap.start + s->io[i].NumPorts - 1;
|
||||
iomap.start = s->io[i].res->start;
|
||||
iomap.stop = s->io[i].res->end;
|
||||
s->ops->set_io_map(s, &iomap);
|
||||
s->io[i].Config++;
|
||||
}
|
||||
}
|
||||
|
||||
c->state |= CONFIG_LOCKED;
|
||||
p_dev->state |= CLIENT_CONFIG_LOCKED;
|
||||
p_dev->_locked = 1;
|
||||
return CS_SUCCESS;
|
||||
} /* pcmcia_request_configuration */
|
||||
EXPORT_SYMBOL(pcmcia_request_configuration);
|
||||
|
@ -730,7 +729,7 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req)
|
|||
|
||||
if (!req)
|
||||
return CS_UNSUPPORTED_MODE;
|
||||
c = CONFIG(p_dev);
|
||||
c = p_dev->function_config;
|
||||
if (c->state & CONFIG_LOCKED)
|
||||
return CS_CONFIGURATION_LOCKED;
|
||||
if (c->state & CONFIG_IO_REQ)
|
||||
|
@ -755,7 +754,7 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req)
|
|||
|
||||
c->io = *req;
|
||||
c->state |= CONFIG_IO_REQ;
|
||||
p_dev->state |= CLIENT_IO_REQ;
|
||||
p_dev->_io = 1;
|
||||
return CS_SUCCESS;
|
||||
} /* pcmcia_request_io */
|
||||
EXPORT_SYMBOL(pcmcia_request_io);
|
||||
|
@ -786,7 +785,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
|
|||
|
||||
if (!(s->state & SOCKET_PRESENT))
|
||||
return CS_NO_CARD;
|
||||
c = CONFIG(p_dev);
|
||||
c = p_dev->function_config;
|
||||
if (c->state & CONFIG_LOCKED)
|
||||
return CS_CONFIGURATION_LOCKED;
|
||||
if (c->state & CONFIG_IRQ_REQ)
|
||||
|
@ -851,7 +850,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
|
|||
s->irq.Config++;
|
||||
|
||||
c->state |= CONFIG_IRQ_REQ;
|
||||
p_dev->state |= CLIENT_IRQ_REQ;
|
||||
p_dev->_irq = 1;
|
||||
|
||||
#ifdef CONFIG_PCMCIA_PROBE
|
||||
pcmcia_used_irq[irq]++;
|
||||
|
@ -911,7 +910,7 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h
|
|||
if (!win->ctl.res)
|
||||
return CS_IN_USE;
|
||||
}
|
||||
(*p_dev)->state |= CLIENT_WIN_REQ(w);
|
||||
(*p_dev)->_win |= CLIENT_WIN_REQ(w);
|
||||
|
||||
/* Configure the socket controller */
|
||||
win->ctl.map = w+1;
|
||||
|
@ -941,3 +940,14 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h
|
|||
return CS_SUCCESS;
|
||||
} /* pcmcia_request_window */
|
||||
EXPORT_SYMBOL(pcmcia_request_window);
|
||||
|
||||
void pcmcia_disable_device(struct pcmcia_device *p_dev) {
|
||||
pcmcia_release_configuration(p_dev);
|
||||
pcmcia_release_io(p_dev, &p_dev->io);
|
||||
pcmcia_release_irq(p_dev, &p_dev->irq);
|
||||
if (&p_dev->win)
|
||||
pcmcia_release_window(p_dev->win);
|
||||
|
||||
p_dev->dev_node = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(pcmcia_disable_device);
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
* (C) 1999 David A. Hinds
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
|
@ -22,6 +21,8 @@
|
|||
#include "cs_internal.h"
|
||||
|
||||
|
||||
#ifdef CONFIG_PCMCIA_IOCTL
|
||||
|
||||
#ifdef CONFIG_PCMCIA_PROBE
|
||||
|
||||
static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
|
||||
|
@ -98,6 +99,8 @@ int pcmcia_adjust_resource_info(adjust_t *adj)
|
|||
}
|
||||
EXPORT_SYMBOL(pcmcia_adjust_resource_info);
|
||||
|
||||
#endif
|
||||
|
||||
int pcmcia_validate_mem(struct pcmcia_socket *s)
|
||||
{
|
||||
if (s->resource_ops->validate_mem)
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
* (C) 1999 David A. Hinds
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/init.h>
|
||||
|
@ -61,7 +60,7 @@ struct socket_data {
|
|||
unsigned int rsrc_mem_probe;
|
||||
};
|
||||
|
||||
static DECLARE_MUTEX(rsrc_sem);
|
||||
static DEFINE_MUTEX(rsrc_mutex);
|
||||
#define MEM_PROBE_LOW (1 << 0)
|
||||
#define MEM_PROBE_HIGH (1 << 1)
|
||||
|
||||
|
@ -484,7 +483,7 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
|
|||
|
||||
|
||||
/*
|
||||
* Locking note: Must be called with skt_sem held!
|
||||
* Locking note: Must be called with skt_mutex held!
|
||||
*/
|
||||
static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
|
||||
{
|
||||
|
@ -495,7 +494,7 @@ static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
|
|||
if (!probe_mem)
|
||||
return 0;
|
||||
|
||||
down(&rsrc_sem);
|
||||
mutex_lock(&rsrc_mutex);
|
||||
|
||||
if (s->features & SS_CAP_PAGE_REGS)
|
||||
probe_mask = MEM_PROBE_HIGH;
|
||||
|
@ -507,7 +506,7 @@ static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
|
|||
s_data->rsrc_mem_probe |= probe_mask;
|
||||
}
|
||||
|
||||
up(&rsrc_sem);
|
||||
mutex_unlock(&rsrc_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -585,7 +584,7 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star
|
|||
struct socket_data *s_data = s->resource_data;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
down(&rsrc_sem);
|
||||
mutex_lock(&rsrc_mutex);
|
||||
for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
|
||||
unsigned long start = m->base;
|
||||
unsigned long end = m->base + m->num - 1;
|
||||
|
@ -596,7 +595,7 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star
|
|||
ret = adjust_resource(res, r_start, r_end - r_start + 1);
|
||||
break;
|
||||
}
|
||||
up(&rsrc_sem);
|
||||
mutex_unlock(&rsrc_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -630,7 +629,7 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num,
|
|||
data.offset = base & data.mask;
|
||||
data.map = &s_data->io_db;
|
||||
|
||||
down(&rsrc_sem);
|
||||
mutex_lock(&rsrc_mutex);
|
||||
#ifdef CONFIG_PCI
|
||||
if (s->cb_dev) {
|
||||
ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
|
||||
|
@ -639,7 +638,7 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num,
|
|||
#endif
|
||||
ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
|
||||
1, pcmcia_align, &data);
|
||||
up(&rsrc_sem);
|
||||
mutex_unlock(&rsrc_mutex);
|
||||
|
||||
if (ret != 0) {
|
||||
kfree(res);
|
||||
|
@ -672,7 +671,7 @@ static struct resource * nonstatic_find_mem_region(u_long base, u_long num,
|
|||
min = 0x100000UL + base;
|
||||
}
|
||||
|
||||
down(&rsrc_sem);
|
||||
mutex_lock(&rsrc_mutex);
|
||||
#ifdef CONFIG_PCI
|
||||
if (s->cb_dev) {
|
||||
ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num,
|
||||
|
@ -682,7 +681,7 @@ static struct resource * nonstatic_find_mem_region(u_long base, u_long num,
|
|||
#endif
|
||||
ret = allocate_resource(&iomem_resource, res, num, min,
|
||||
max, 1, pcmcia_align, &data);
|
||||
up(&rsrc_sem);
|
||||
mutex_unlock(&rsrc_mutex);
|
||||
if (ret == 0 || low)
|
||||
break;
|
||||
low = 1;
|
||||
|
@ -705,7 +704,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned
|
|||
if (end < start)
|
||||
return -EINVAL;
|
||||
|
||||
down(&rsrc_sem);
|
||||
mutex_lock(&rsrc_mutex);
|
||||
switch (action) {
|
||||
case ADD_MANAGED_RESOURCE:
|
||||
ret = add_interval(&data->mem_db, start, size);
|
||||
|
@ -723,7 +722,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned
|
|||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
up(&rsrc_sem);
|
||||
mutex_unlock(&rsrc_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -741,7 +740,7 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long
|
|||
if (end > IO_SPACE_LIMIT)
|
||||
return -EINVAL;
|
||||
|
||||
down(&rsrc_sem);
|
||||
mutex_lock(&rsrc_mutex);
|
||||
switch (action) {
|
||||
case ADD_MANAGED_RESOURCE:
|
||||
if (add_interval(&data->io_db, start, size) != 0) {
|
||||
|
@ -760,7 +759,7 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long
|
|||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
up(&rsrc_sem);
|
||||
mutex_unlock(&rsrc_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -867,7 +866,7 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s)
|
|||
struct socket_data *data = s->resource_data;
|
||||
struct resource_map *p, *q;
|
||||
|
||||
down(&rsrc_sem);
|
||||
mutex_lock(&rsrc_mutex);
|
||||
for (p = data->mem_db.next; p != &data->mem_db; p = q) {
|
||||
q = p->next;
|
||||
kfree(p);
|
||||
|
@ -876,7 +875,7 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s)
|
|||
q = p->next;
|
||||
kfree(p);
|
||||
}
|
||||
up(&rsrc_sem);
|
||||
mutex_unlock(&rsrc_mutex);
|
||||
}
|
||||
|
||||
|
||||
|
@ -901,7 +900,7 @@ static ssize_t show_io_db(struct class_device *class_dev, char *buf)
|
|||
struct resource_map *p;
|
||||
ssize_t ret = 0;
|
||||
|
||||
down(&rsrc_sem);
|
||||
mutex_lock(&rsrc_mutex);
|
||||
data = s->resource_data;
|
||||
|
||||
for (p = data->io_db.next; p != &data->io_db; p = p->next) {
|
||||
|
@ -913,7 +912,7 @@ static ssize_t show_io_db(struct class_device *class_dev, char *buf)
|
|||
((unsigned long) p->base + p->num - 1));
|
||||
}
|
||||
|
||||
up(&rsrc_sem);
|
||||
mutex_unlock(&rsrc_mutex);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
@ -953,7 +952,7 @@ static ssize_t show_mem_db(struct class_device *class_dev, char *buf)
|
|||
struct resource_map *p;
|
||||
ssize_t ret = 0;
|
||||
|
||||
down(&rsrc_sem);
|
||||
mutex_lock(&rsrc_mutex);
|
||||
data = s->resource_data;
|
||||
|
||||
for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
|
||||
|
@ -965,7 +964,7 @@ static ssize_t show_mem_db(struct class_device *class_dev, char *buf)
|
|||
((unsigned long) p->base + p->num - 1));
|
||||
}
|
||||
|
||||
up(&rsrc_sem);
|
||||
mutex_unlock(&rsrc_mutex);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* Based off the Assabet.
|
||||
*
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include <linux/moduleparam.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/config.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/errno.h>
|
||||
|
@ -25,6 +24,7 @@
|
|||
#include <linux/pm.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
|
@ -183,7 +183,7 @@ static ssize_t pccard_store_resource(struct class_device *dev, const char *buf,
|
|||
s->resource_setup_done = 1;
|
||||
spin_unlock_irqrestore(&s->lock, flags);
|
||||
|
||||
down(&s->skt_sem);
|
||||
mutex_lock(&s->skt_mutex);
|
||||
if ((s->callback) &&
|
||||
(s->state & SOCKET_PRESENT) &&
|
||||
!(s->state & SOCKET_CARDBUS)) {
|
||||
|
@ -192,7 +192,7 @@ static ssize_t pccard_store_resource(struct class_device *dev, const char *buf,
|
|||
module_put(s->callback->owner);
|
||||
}
|
||||
}
|
||||
up(&s->skt_sem);
|
||||
mutex_unlock(&s->skt_mutex);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
@ -322,7 +322,7 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, siz
|
|||
kfree(cis);
|
||||
|
||||
if (!ret) {
|
||||
down(&s->skt_sem);
|
||||
mutex_lock(&s->skt_mutex);
|
||||
if ((s->callback) && (s->state & SOCKET_PRESENT) &&
|
||||
!(s->state & SOCKET_CARDBUS)) {
|
||||
if (try_module_get(s->callback->owner)) {
|
||||
|
@ -330,7 +330,7 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, siz
|
|||
module_put(s->callback->owner);
|
||||
}
|
||||
}
|
||||
up(&s->skt_sem);
|
||||
mutex_unlock(&s->skt_mutex);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#ifndef _LINUX_TI113X_H
|
||||
#define _LINUX_TI113X_H
|
||||
|
||||
#include <linux/config.h>
|
||||
|
||||
/* Register definitions for TI 113X PCI-to-CardBus bridges */
|
||||
|
||||
|
|
|
@ -89,29 +89,29 @@ MODULE_LICENSE("Dual MPL/GPL");
|
|||
/*====================================================================*/
|
||||
|
||||
typedef struct scsi_info_t {
|
||||
dev_link_t link;
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
struct Scsi_Host *host;
|
||||
} scsi_info_t;
|
||||
|
||||
static void aha152x_release_cs(dev_link_t *link);
|
||||
static void aha152x_release_cs(struct pcmcia_device *link);
|
||||
static void aha152x_detach(struct pcmcia_device *p_dev);
|
||||
static void aha152x_config_cs(dev_link_t *link);
|
||||
static int aha152x_config_cs(struct pcmcia_device *link);
|
||||
|
||||
static dev_link_t *dev_list;
|
||||
static struct pcmcia_device *dev_list;
|
||||
|
||||
static int aha152x_attach(struct pcmcia_device *p_dev)
|
||||
static int aha152x_probe(struct pcmcia_device *link)
|
||||
{
|
||||
scsi_info_t *info;
|
||||
dev_link_t *link;
|
||||
|
||||
|
||||
DEBUG(0, "aha152x_attach()\n");
|
||||
|
||||
/* Create new SCSI device */
|
||||
info = kmalloc(sizeof(*info), GFP_KERNEL);
|
||||
if (!info) return -ENOMEM;
|
||||
memset(info, 0, sizeof(*info));
|
||||
link = &info->link; link->priv = info;
|
||||
info->p_dev = link;
|
||||
link->priv = info;
|
||||
|
||||
link->io.NumPorts1 = 0x20;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
|
@ -119,41 +119,22 @@ static int aha152x_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->conf.Present = PRESENT_OPTION;
|
||||
|
||||
link->handle = p_dev;
|
||||
p_dev->instance = link;
|
||||
|
||||
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
|
||||
aha152x_config_cs(link);
|
||||
|
||||
return 0;
|
||||
return aha152x_config_cs(link);
|
||||
} /* aha152x_attach */
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
static void aha152x_detach(struct pcmcia_device *p_dev)
|
||||
static void aha152x_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
dev_link_t **linkp;
|
||||
|
||||
DEBUG(0, "aha152x_detach(0x%p)\n", link);
|
||||
|
||||
/* Locate device structure */
|
||||
for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
|
||||
if (*linkp == link) break;
|
||||
if (*linkp == NULL)
|
||||
return;
|
||||
|
||||
if (link->state & DEV_CONFIG)
|
||||
aha152x_release_cs(link);
|
||||
aha152x_release_cs(link);
|
||||
|
||||
/* Unlink device structure, free bits */
|
||||
*linkp = link->next;
|
||||
kfree(link->priv);
|
||||
|
||||
} /* aha152x_detach */
|
||||
|
||||
/*====================================================================*/
|
||||
|
@ -161,9 +142,8 @@ static void aha152x_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 aha152x_config_cs(dev_link_t *link)
|
||||
static int aha152x_config_cs(struct pcmcia_device *link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
scsi_info_t *info = link->priv;
|
||||
struct aha152x_setup s;
|
||||
tuple_t tuple;
|
||||
|
@ -178,19 +158,16 @@ static void aha152x_config_cs(dev_link_t *link)
|
|||
tuple.TupleData = tuple_data;
|
||||
tuple.TupleDataMax = 64;
|
||||
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;
|
||||
|
||||
/* Configure card */
|
||||
link->state |= DEV_CONFIG;
|
||||
|
||||
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) {
|
||||
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;
|
||||
/* For New Media T&J, look for a SCSI window */
|
||||
if (parse.cftable_entry.io.win[0].len >= 0x20)
|
||||
|
@ -201,15 +178,15 @@ static void aha152x_config_cs(dev_link_t *link)
|
|||
if ((parse.cftable_entry.io.nwin > 0) &&
|
||||
(link->io.BasePort1 < 0xffff)) {
|
||||
link->conf.ConfigIndex = parse.cftable_entry.index;
|
||||
i = pcmcia_request_io(handle, &link->io);
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
if (i == CS_SUCCESS) break;
|
||||
}
|
||||
next_entry:
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
/* Set configuration options for the aha152x driver */
|
||||
memset(&s, 0, sizeof(s));
|
||||
|
@ -231,53 +208,30 @@ static void aha152x_config_cs(dev_link_t *link)
|
|||
}
|
||||
|
||||
sprintf(info->node.dev_name, "scsi%d", host->host_no);
|
||||
link->dev = &info->node;
|
||||
link->dev_node = &info->node;
|
||||
info->host = host;
|
||||
|
||||
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);
|
||||
aha152x_release_cs(link);
|
||||
return;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void aha152x_release_cs(dev_link_t *link)
|
||||
static void aha152x_release_cs(struct pcmcia_device *link)
|
||||
{
|
||||
scsi_info_t *info = link->priv;
|
||||
|
||||
aha152x_release(info->host);
|
||||
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);
|
||||
}
|
||||
|
||||
static int aha152x_suspend(struct pcmcia_device *dev)
|
||||
static int aha152x_resume(struct pcmcia_device *link)
|
||||
{
|
||||
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 aha152x_resume(struct pcmcia_device *dev)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(dev);
|
||||
scsi_info_t *info = link->priv;
|
||||
|
||||
link->state &= ~DEV_SUSPEND;
|
||||
if (link->state & DEV_CONFIG) {
|
||||
pcmcia_request_configuration(link->handle, &link->conf);
|
||||
aha152x_host_reset_host(info->host);
|
||||
}
|
||||
aha152x_host_reset_host(info->host);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -297,10 +251,9 @@ static struct pcmcia_driver aha152x_cs_driver = {
|
|||
.drv = {
|
||||
.name = "aha152x_cs",
|
||||
},
|
||||
.probe = aha152x_attach,
|
||||
.probe = aha152x_probe,
|
||||
.remove = aha152x_detach,
|
||||
.id_table = aha152x_ids,
|
||||
.suspend = aha152x_suspend,
|
||||
.resume = aha152x_resume,
|
||||
};
|
||||
|
||||
|
@ -317,4 +270,3 @@ static void __exit exit_aha152x_cs(void)
|
|||
|
||||
module_init(init_aha152x_cs);
|
||||
module_exit(exit_aha152x_cs);
|
||||
|
||||
|
|
|
@ -73,57 +73,48 @@ static char *version =
|
|||
/*====================================================================*/
|
||||
|
||||
typedef struct scsi_info_t {
|
||||
dev_link_t link;
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
struct Scsi_Host *host;
|
||||
} scsi_info_t;
|
||||
|
||||
|
||||
static void fdomain_release(dev_link_t *link);
|
||||
static void fdomain_release(struct pcmcia_device *link);
|
||||
static void fdomain_detach(struct pcmcia_device *p_dev);
|
||||
static void fdomain_config(dev_link_t *link);
|
||||
static int fdomain_config(struct pcmcia_device *link);
|
||||
|
||||
static int fdomain_attach(struct pcmcia_device *p_dev)
|
||||
static int fdomain_probe(struct pcmcia_device *link)
|
||||
{
|
||||
scsi_info_t *info;
|
||||
dev_link_t *link;
|
||||
scsi_info_t *info;
|
||||
|
||||
DEBUG(0, "fdomain_attach()\n");
|
||||
DEBUG(0, "fdomain_attach()\n");
|
||||
|
||||
/* Create new SCSI device */
|
||||
info = kmalloc(sizeof(*info), GFP_KERNEL);
|
||||
if (!info) return -ENOMEM;
|
||||
memset(info, 0, sizeof(*info));
|
||||
link = &info->link; link->priv = info;
|
||||
link->io.NumPorts1 = 0x10;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
link->io.IOAddrLines = 10;
|
||||
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->conf.Present = PRESENT_OPTION;
|
||||
/* Create new SCSI device */
|
||||
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
link->handle = p_dev;
|
||||
p_dev->instance = link;
|
||||
info->p_dev = link;
|
||||
link->priv = info;
|
||||
link->io.NumPorts1 = 0x10;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
link->io.IOAddrLines = 10;
|
||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
link->conf.Present = PRESENT_OPTION;
|
||||
|
||||
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
|
||||
fdomain_config(link);
|
||||
|
||||
return 0;
|
||||
return fdomain_config(link);
|
||||
} /* fdomain_attach */
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
static void fdomain_detach(struct pcmcia_device *p_dev)
|
||||
static void fdomain_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
|
||||
DEBUG(0, "fdomain_detach(0x%p)\n", link);
|
||||
|
||||
if (link->state & DEV_CONFIG)
|
||||
fdomain_release(link);
|
||||
fdomain_release(link);
|
||||
|
||||
kfree(link->priv);
|
||||
} /* fdomain_detach */
|
||||
|
@ -133,9 +124,8 @@ static void fdomain_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 fdomain_config(dev_link_t *link)
|
||||
static int fdomain_config(struct pcmcia_device *link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
scsi_info_t *info = link->priv;
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
|
@ -150,103 +140,75 @@ static void fdomain_config(dev_link_t *link)
|
|||
tuple.TupleData = tuple_data;
|
||||
tuple.TupleDataMax = 64;
|
||||
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;
|
||||
|
||||
/* Configure card */
|
||||
link->state |= DEV_CONFIG;
|
||||
|
||||
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) {
|
||||
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;
|
||||
link->conf.ConfigIndex = parse.cftable_entry.index;
|
||||
link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
|
||||
i = pcmcia_request_io(handle, &link->io);
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
if (i == CS_SUCCESS) break;
|
||||
next_entry:
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
/* A bad hack... */
|
||||
release_region(link->io.BasePort1, link->io.NumPorts1);
|
||||
|
||||
/* Set configuration options for the fdomain driver */
|
||||
sprintf(str, "%d,%d", link->io.BasePort1, link->irq.AssignedIRQ);
|
||||
fdomain_setup(str);
|
||||
|
||||
|
||||
host = __fdomain_16x0_detect(&fdomain_driver_template);
|
||||
if (!host) {
|
||||
printk(KERN_INFO "fdomain_cs: no SCSI devices found\n");
|
||||
goto cs_failed;
|
||||
}
|
||||
|
||||
scsi_add_host(host, NULL); /* XXX handle failure */
|
||||
|
||||
if (scsi_add_host(host, NULL))
|
||||
goto cs_failed;
|
||||
scsi_scan_host(host);
|
||||
|
||||
sprintf(info->node.dev_name, "scsi%d", host->host_no);
|
||||
link->dev = &info->node;
|
||||
link->dev_node = &info->node;
|
||||
info->host = host;
|
||||
|
||||
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);
|
||||
fdomain_release(link);
|
||||
return;
|
||||
|
||||
return -ENODEV;
|
||||
} /* fdomain_config */
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
static void fdomain_release(dev_link_t *link)
|
||||
static void fdomain_release(struct pcmcia_device *link)
|
||||
{
|
||||
scsi_info_t *info = link->priv;
|
||||
scsi_info_t *info = link->priv;
|
||||
|
||||
DEBUG(0, "fdomain_release(0x%p)\n", link);
|
||||
DEBUG(0, "fdomain_release(0x%p)\n", link);
|
||||
|
||||
scsi_remove_host(info->host);
|
||||
link->dev = NULL;
|
||||
|
||||
pcmcia_release_configuration(link->handle);
|
||||
pcmcia_release_io(link->handle, &link->io);
|
||||
pcmcia_release_irq(link->handle, &link->irq);
|
||||
|
||||
scsi_unregister(info->host);
|
||||
|
||||
link->state &= ~DEV_CONFIG;
|
||||
scsi_remove_host(info->host);
|
||||
pcmcia_disable_device(link);
|
||||
scsi_unregister(info->host);
|
||||
}
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
static int fdomain_suspend(struct pcmcia_device *dev)
|
||||
static int fdomain_resume(struct pcmcia_device *link)
|
||||
{
|
||||
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 fdomain_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);
|
||||
fdomain_16x0_bus_reset(NULL);
|
||||
}
|
||||
fdomain_16x0_bus_reset(NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -264,10 +226,9 @@ static struct pcmcia_driver fdomain_cs_driver = {
|
|||
.drv = {
|
||||
.name = "fdomain_cs",
|
||||
},
|
||||
.probe = fdomain_attach,
|
||||
.probe = fdomain_probe,
|
||||
.remove = fdomain_detach,
|
||||
.id_table = fdomain_ids,
|
||||
.suspend = fdomain_suspend,
|
||||
.resume = fdomain_resume,
|
||||
};
|
||||
|
||||
|
|
|
@ -1593,11 +1593,11 @@ static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)
|
|||
configure the card at this point -- we wait until we receive a
|
||||
card insertion event.
|
||||
======================================================================*/
|
||||
static int nsp_cs_attach(struct pcmcia_device *p_dev)
|
||||
static int nsp_cs_probe(struct pcmcia_device *link)
|
||||
{
|
||||
scsi_info_t *info;
|
||||
dev_link_t *link;
|
||||
nsp_hw_data *data = &nsp_data_base;
|
||||
int ret;
|
||||
|
||||
nsp_dbg(NSP_DEBUG_INIT, "in");
|
||||
|
||||
|
@ -1605,7 +1605,7 @@ static int nsp_cs_attach(struct pcmcia_device *p_dev)
|
|||
info = kmalloc(sizeof(*info), GFP_KERNEL);
|
||||
if (info == NULL) { return -ENOMEM; }
|
||||
memset(info, 0, sizeof(*info));
|
||||
link = &info->link;
|
||||
info->p_dev = link;
|
||||
link->priv = info;
|
||||
data->ScsiInfo = info;
|
||||
|
||||
|
@ -1627,18 +1627,13 @@ static int nsp_cs_attach(struct pcmcia_device *p_dev)
|
|||
|
||||
/* General socket configuration */
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.Vcc = 50;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
link->conf.Present = PRESENT_OPTION;
|
||||
|
||||
link->handle = p_dev;
|
||||
p_dev->instance = link;
|
||||
|
||||
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
|
||||
nsp_cs_config(link);
|
||||
ret = nsp_cs_config(link);
|
||||
|
||||
nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
|
||||
return 0;
|
||||
return ret;
|
||||
} /* nsp_cs_attach */
|
||||
|
||||
|
||||
|
@ -1648,16 +1643,12 @@ static int nsp_cs_attach(struct pcmcia_device *p_dev)
|
|||
structures are freed. Otherwise, the structures will be freed
|
||||
when the device is released.
|
||||
======================================================================*/
|
||||
static void nsp_cs_detach(struct pcmcia_device *p_dev)
|
||||
static void nsp_cs_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
|
||||
nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
|
||||
|
||||
if (link->state & DEV_CONFIG) {
|
||||
((scsi_info_t *)link->priv)->stop = 1;
|
||||
nsp_cs_release(link);
|
||||
}
|
||||
((scsi_info_t *)link->priv)->stop = 1;
|
||||
nsp_cs_release(link);
|
||||
|
||||
kfree(link->priv);
|
||||
link->priv = NULL;
|
||||
|
@ -1672,9 +1663,9 @@ static void nsp_cs_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 nsp_cs_config(dev_link_t *link)
|
||||
static int nsp_cs_config(struct pcmcia_device *link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
int ret;
|
||||
scsi_info_t *info = link->priv;
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
|
@ -1698,26 +1689,22 @@ static void nsp_cs_config(dev_link_t *link)
|
|||
tuple.TupleData = tuple_data;
|
||||
tuple.TupleDataMax = sizeof(tuple_data);
|
||||
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));
|
||||
|
||||
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 *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; }
|
||||
|
@ -1743,10 +1730,10 @@ static void nsp_cs_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;
|
||||
}
|
||||
|
||||
|
@ -1773,7 +1760,7 @@ static void nsp_cs_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;
|
||||
}
|
||||
|
||||
|
@ -1788,7 +1775,7 @@ static void nsp_cs_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)
|
||||
|
@ -1802,17 +1789,14 @@ static void nsp_cs_config(dev_link_t *link)
|
|||
|
||||
next_entry:
|
||||
nsp_dbg(NSP_DEBUG_INIT, "next");
|
||||
|
||||
if (link->io.NumPorts1) {
|
||||
pcmcia_release_io(link->handle, &link->io);
|
||||
}
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
|
||||
pcmcia_disable_device(link);
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
|
||||
if (free_ports) {
|
||||
if (link->io.BasePort1) {
|
||||
|
@ -1854,16 +1838,19 @@ static void nsp_cs_config(dev_link_t *link)
|
|||
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
|
||||
scsi_add_host (host, NULL);
|
||||
ret = scsi_add_host (host, NULL);
|
||||
if (ret)
|
||||
goto cs_failed;
|
||||
|
||||
scsi_scan_host(host);
|
||||
|
||||
snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no);
|
||||
link->dev = &info->node;
|
||||
link->dev_node = &info->node;
|
||||
info->host = host;
|
||||
|
||||
#else
|
||||
nsp_dbg(NSP_DEBUG_INIT, "GET_SCSI_INFO");
|
||||
tail = &link->dev;
|
||||
tail = &link->dev_node;
|
||||
info->ndev = 0;
|
||||
|
||||
nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
|
||||
|
@ -1908,11 +1895,10 @@ static void nsp_cs_config(dev_link_t *link)
|
|||
#endif
|
||||
|
||||
/* Finally, report what we've done */
|
||||
printk(KERN_INFO "nsp_cs: index 0x%02x: Vcc %d.%d",
|
||||
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 "nsp_cs: index 0x%02x: ",
|
||||
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);
|
||||
|
@ -1929,15 +1915,14 @@ static void nsp_cs_config(dev_link_t *link)
|
|||
req.Base+req.Size-1);
|
||||
printk("\n");
|
||||
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
return;
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
nsp_dbg(NSP_DEBUG_INIT, "config fail");
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
cs_error(link, last_fn, last_ret);
|
||||
nsp_cs_release(link);
|
||||
|
||||
return;
|
||||
return -ENODEV;
|
||||
} /* nsp_cs_config */
|
||||
#undef CS_CHECK
|
||||
|
||||
|
@ -1947,7 +1932,7 @@ static void nsp_cs_config(dev_link_t *link)
|
|||
device, and release the PCMCIA configuration. If the device is
|
||||
still open, this will be postponed until it is closed.
|
||||
======================================================================*/
|
||||
static void nsp_cs_release(dev_link_t *link)
|
||||
static void nsp_cs_release(struct pcmcia_device *link)
|
||||
{
|
||||
scsi_info_t *info = link->priv;
|
||||
nsp_hw_data *data = NULL;
|
||||
|
@ -1968,22 +1953,15 @@ static void nsp_cs_release(dev_link_t *link)
|
|||
#else
|
||||
scsi_unregister_host(&nsp_driver_template);
|
||||
#endif
|
||||
link->dev = NULL;
|
||||
link->dev_node = NULL;
|
||||
|
||||
if (link->win) {
|
||||
if (data != NULL) {
|
||||
iounmap((void *)(data->MmioAddress));
|
||||
}
|
||||
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);
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
|
||||
if (info->host != NULL) {
|
||||
scsi_host_put(info->host);
|
||||
|
@ -1991,14 +1969,11 @@ static void nsp_cs_release(dev_link_t *link)
|
|||
#endif
|
||||
} /* nsp_cs_release */
|
||||
|
||||
static int nsp_cs_suspend(struct pcmcia_device *dev)
|
||||
static int nsp_cs_suspend(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(dev);
|
||||
scsi_info_t *info = link->priv;
|
||||
nsp_hw_data *data;
|
||||
|
||||
link->state |= DEV_SUSPEND;
|
||||
|
||||
nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
|
||||
|
||||
if (info->host != NULL) {
|
||||
|
@ -2011,25 +1986,16 @@ static int nsp_cs_suspend(struct pcmcia_device *dev)
|
|||
|
||||
info->stop = 1;
|
||||
|
||||
if (link->state & DEV_CONFIG)
|
||||
pcmcia_release_configuration(link->handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nsp_cs_resume(struct pcmcia_device *dev)
|
||||
static int nsp_cs_resume(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(dev);
|
||||
scsi_info_t *info = link->priv;
|
||||
nsp_hw_data *data;
|
||||
|
||||
nsp_dbg(NSP_DEBUG_INIT, "event: resume");
|
||||
|
||||
link->state &= ~DEV_SUSPEND;
|
||||
|
||||
if (link->state & DEV_CONFIG)
|
||||
pcmcia_request_configuration(link->handle, &link->conf);
|
||||
|
||||
info->stop = 0;
|
||||
|
||||
if (info->host != NULL) {
|
||||
|
@ -2065,7 +2031,7 @@ static struct pcmcia_driver nsp_driver = {
|
|||
.drv = {
|
||||
.name = "nsp_cs",
|
||||
},
|
||||
.probe = nsp_cs_attach,
|
||||
.probe = nsp_cs_probe,
|
||||
.remove = nsp_cs_detach,
|
||||
.id_table = nsp_cs_ids,
|
||||
.suspend = nsp_cs_suspend,
|
||||
|
@ -2098,19 +2064,7 @@ static int __init nsp_cs_init(void)
|
|||
static void __exit nsp_cs_exit(void)
|
||||
{
|
||||
nsp_msg(KERN_INFO, "unloading...");
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
|
||||
pcmcia_unregister_driver(&nsp_driver);
|
||||
#else
|
||||
unregister_pcmcia_driver(&dev_info);
|
||||
/* XXX: this really needs to move into generic code.. */
|
||||
while (dev_list != NULL) {
|
||||
if (dev_list->state & DEV_CONFIG) {
|
||||
nsp_cs_release(dev_list);
|
||||
}
|
||||
nsp_cs_detach(dev_list);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -225,7 +225,7 @@
|
|||
/*====================================================================*/
|
||||
|
||||
typedef struct scsi_info_t {
|
||||
dev_link_t link;
|
||||
struct pcmcia_device *p_dev;
|
||||
struct Scsi_Host *host;
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
|
||||
dev_node_t node;
|
||||
|
@ -297,8 +297,8 @@ typedef struct _nsp_hw_data {
|
|||
|
||||
/* Card service functions */
|
||||
static void nsp_cs_detach (struct pcmcia_device *p_dev);
|
||||
static void nsp_cs_release(dev_link_t *link);
|
||||
static void nsp_cs_config (dev_link_t *link);
|
||||
static void nsp_cs_release(struct pcmcia_device *link);
|
||||
static int nsp_cs_config (struct pcmcia_device *link);
|
||||
|
||||
/* Linux SCSI subsystem specific functions */
|
||||
static struct Scsi_Host *nsp_detect (struct scsi_host_template *sht);
|
||||
|
@ -450,7 +450,7 @@ static inline struct Scsi_Host *scsi_host_hn_get(unsigned short hostno)
|
|||
return host;
|
||||
}
|
||||
|
||||
static void cs_error(client_handle_t handle, int func, int ret)
|
||||
static void cs_error(struct pcmcia_device *handle, int func, int ret)
|
||||
{
|
||||
error_info_t err = { func, ret };
|
||||
pcmcia_report_error(handle, &err);
|
||||
|
|
|
@ -91,18 +91,18 @@ static struct scsi_host_template qlogicfas_driver_template = {
|
|||
/*====================================================================*/
|
||||
|
||||
typedef struct scsi_info_t {
|
||||
dev_link_t link;
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
struct Scsi_Host *host;
|
||||
unsigned short manf_id;
|
||||
} scsi_info_t;
|
||||
|
||||
static void qlogic_release(dev_link_t *link);
|
||||
static void qlogic_release(struct pcmcia_device *link);
|
||||
static void qlogic_detach(struct pcmcia_device *p_dev);
|
||||
static void qlogic_config(dev_link_t * link);
|
||||
static int qlogic_config(struct pcmcia_device * link);
|
||||
|
||||
static struct Scsi_Host *qlogic_detect(struct scsi_host_template *host,
|
||||
dev_link_t *link, int qbase, int qlirq)
|
||||
struct pcmcia_device *link, int qbase, int qlirq)
|
||||
{
|
||||
int qltyp; /* type of chip */
|
||||
int qinitid;
|
||||
|
@ -156,10 +156,9 @@ static struct Scsi_Host *qlogic_detect(struct scsi_host_template *host,
|
|||
err:
|
||||
return NULL;
|
||||
}
|
||||
static int qlogic_attach(struct pcmcia_device *p_dev)
|
||||
static int qlogic_probe(struct pcmcia_device *link)
|
||||
{
|
||||
scsi_info_t *info;
|
||||
dev_link_t *link;
|
||||
|
||||
DEBUG(0, "qlogic_attach()\n");
|
||||
|
||||
|
@ -168,7 +167,7 @@ static int qlogic_attach(struct pcmcia_device *p_dev)
|
|||
if (!info)
|
||||
return -ENOMEM;
|
||||
memset(info, 0, sizeof(*info));
|
||||
link = &info->link;
|
||||
info->p_dev = link;
|
||||
link->priv = info;
|
||||
link->io.NumPorts1 = 16;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
|
@ -176,30 +175,19 @@ static int qlogic_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->conf.Present = PRESENT_OPTION;
|
||||
|
||||
link->handle = p_dev;
|
||||
p_dev->instance = link;
|
||||
|
||||
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
|
||||
qlogic_config(link);
|
||||
|
||||
return 0;
|
||||
return qlogic_config(link);
|
||||
} /* qlogic_attach */
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
static void qlogic_detach(struct pcmcia_device *p_dev)
|
||||
static void qlogic_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
|
||||
DEBUG(0, "qlogic_detach(0x%p)\n", link);
|
||||
|
||||
if (link->state & DEV_CONFIG)
|
||||
qlogic_release(link);
|
||||
|
||||
qlogic_release(link);
|
||||
kfree(link->priv);
|
||||
|
||||
} /* qlogic_detach */
|
||||
|
@ -209,9 +197,8 @@ static void qlogic_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 qlogic_config(dev_link_t * link)
|
||||
static int qlogic_config(struct pcmcia_device * link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
scsi_info_t *info = link->priv;
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
|
@ -225,38 +212,35 @@ static void qlogic_config(dev_link_t * link)
|
|||
tuple.TupleDataMax = 64;
|
||||
tuple.TupleOffset = 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, &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;
|
||||
|
||||
tuple.DesiredTuple = CISTPL_MANFID;
|
||||
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))
|
||||
info->manf_id = le16_to_cpu(tuple.TupleData[0]);
|
||||
|
||||
/* Configure card */
|
||||
link->state |= DEV_CONFIG;
|
||||
|
||||
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) {
|
||||
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;
|
||||
link->conf.ConfigIndex = parse.cftable_entry.index;
|
||||
link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
|
||||
link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
|
||||
if (link->io.BasePort1 != 0) {
|
||||
i = pcmcia_request_io(handle, &link->io);
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
if (i == CS_SUCCESS)
|
||||
break;
|
||||
}
|
||||
next_entry:
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) {
|
||||
/* set ATAcmd */
|
||||
|
@ -275,82 +259,54 @@ static void qlogic_config(dev_link_t * link)
|
|||
|
||||
if (!host) {
|
||||
printk(KERN_INFO "%s: no SCSI devices found\n", qlogic_name);
|
||||
goto out;
|
||||
goto cs_failed;
|
||||
}
|
||||
|
||||
sprintf(info->node.dev_name, "scsi%d", host->host_no);
|
||||
link->dev = &info->node;
|
||||
link->dev_node = &info->node;
|
||||
info->host = host;
|
||||
|
||||
out:
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
return;
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
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;
|
||||
return;
|
||||
cs_error(link, last_fn, last_ret);
|
||||
pcmcia_disable_device(link);
|
||||
return -ENODEV;
|
||||
|
||||
} /* qlogic_config */
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
static void qlogic_release(dev_link_t *link)
|
||||
static void qlogic_release(struct pcmcia_device *link)
|
||||
{
|
||||
scsi_info_t *info = link->priv;
|
||||
|
||||
DEBUG(0, "qlogic_release(0x%p)\n", link);
|
||||
|
||||
scsi_remove_host(info->host);
|
||||
link->dev = NULL;
|
||||
|
||||
free_irq(link->irq.AssignedIRQ, info->host);
|
||||
|
||||
pcmcia_release_configuration(link->handle);
|
||||
pcmcia_release_io(link->handle, &link->io);
|
||||
pcmcia_release_irq(link->handle, &link->irq);
|
||||
pcmcia_disable_device(link);
|
||||
|
||||
scsi_host_put(info->host);
|
||||
|
||||
link->state &= ~DEV_CONFIG;
|
||||
}
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
static int qlogic_suspend(struct pcmcia_device *dev)
|
||||
static int qlogic_resume(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(dev);
|
||||
scsi_info_t *info = link->priv;
|
||||
|
||||
link->state |= DEV_SUSPEND;
|
||||
if (link->state & DEV_CONFIG)
|
||||
pcmcia_release_configuration(link->handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qlogic_resume(struct pcmcia_device *dev)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(dev);
|
||||
|
||||
link->state &= ~DEV_SUSPEND;
|
||||
if (link->state & DEV_CONFIG) {
|
||||
scsi_info_t *info = link->priv;
|
||||
|
||||
pcmcia_request_configuration(link->handle, &link->conf);
|
||||
if ((info->manf_id == MANFID_MACNICA) ||
|
||||
(info->manf_id == MANFID_PIONEER) ||
|
||||
(info->manf_id == 0x0098)) {
|
||||
outb(0x80, link->io.BasePort1 + 0xd);
|
||||
outb(0x24, link->io.BasePort1 + 0x9);
|
||||
outb(0x04, link->io.BasePort1 + 0xd);
|
||||
}
|
||||
/* Ugggglllyyyy!!! */
|
||||
qlogicfas408_bus_reset(NULL);
|
||||
pcmcia_request_configuration(link, &link->conf);
|
||||
if ((info->manf_id == MANFID_MACNICA) ||
|
||||
(info->manf_id == MANFID_PIONEER) ||
|
||||
(info->manf_id == 0x0098)) {
|
||||
outb(0x80, link->io.BasePort1 + 0xd);
|
||||
outb(0x24, link->io.BasePort1 + 0x9);
|
||||
outb(0x04, link->io.BasePort1 + 0xd);
|
||||
}
|
||||
/* Ugggglllyyyy!!! */
|
||||
qlogicfas408_bus_reset(NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -382,10 +338,9 @@ static struct pcmcia_driver qlogic_cs_driver = {
|
|||
.drv = {
|
||||
.name = "qlogic_cs",
|
||||
},
|
||||
.probe = qlogic_attach,
|
||||
.probe = qlogic_probe,
|
||||
.remove = qlogic_detach,
|
||||
.id_table = qlogic_ids,
|
||||
.suspend = qlogic_suspend,
|
||||
.resume = qlogic_resume,
|
||||
};
|
||||
|
||||
|
|
|
@ -202,7 +202,7 @@ static char *version =
|
|||
/* ================================================================== */
|
||||
|
||||
struct scsi_info_t {
|
||||
dev_link_t link;
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
struct Scsi_Host *host;
|
||||
unsigned short manf_id;
|
||||
|
@ -527,7 +527,7 @@ SYM53C500_intr(int irq, void *dev_id, struct pt_regs *regs)
|
|||
}
|
||||
|
||||
static void
|
||||
SYM53C500_release(dev_link_t *link)
|
||||
SYM53C500_release(struct pcmcia_device *link)
|
||||
{
|
||||
struct scsi_info_t *info = link->priv;
|
||||
struct Scsi_Host *shost = info->host;
|
||||
|
@ -550,13 +550,7 @@ SYM53C500_release(dev_link_t *link)
|
|||
if (shost->io_port && shost->n_io_port)
|
||||
release_region(shost->io_port, shost->n_io_port);
|
||||
|
||||
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);
|
||||
|
||||
scsi_host_put(shost);
|
||||
} /* SYM53C500_release */
|
||||
|
@ -713,10 +707,9 @@ static struct scsi_host_template sym53c500_driver_template = {
|
|||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static void
|
||||
SYM53C500_config(dev_link_t *link)
|
||||
static int
|
||||
SYM53C500_config(struct pcmcia_device *link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
struct scsi_info_t *info = link->priv;
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
|
@ -733,40 +726,37 @@ SYM53C500_config(dev_link_t *link)
|
|||
tuple.TupleDataMax = 64;
|
||||
tuple.TupleOffset = 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, &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;
|
||||
|
||||
tuple.DesiredTuple = CISTPL_MANFID;
|
||||
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))
|
||||
info->manf_id = le16_to_cpu(tuple.TupleData[0]);
|
||||
|
||||
/* Configure card */
|
||||
link->state |= DEV_CONFIG;
|
||||
|
||||
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) {
|
||||
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;
|
||||
link->conf.ConfigIndex = parse.cftable_entry.index;
|
||||
link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
|
||||
link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
|
||||
|
||||
if (link->io.BasePort1 != 0) {
|
||||
i = pcmcia_request_io(handle, &link->io);
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
if (i == CS_SUCCESS)
|
||||
break;
|
||||
}
|
||||
next_entry:
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
/*
|
||||
* That's the trouble with copying liberally from another driver.
|
||||
|
@ -835,7 +825,7 @@ SYM53C500_config(dev_link_t *link)
|
|||
data->fast_pio = USE_FAST_PIO;
|
||||
|
||||
sprintf(info->node.dev_name, "scsi%d", host->host_no);
|
||||
link->dev = &info->node;
|
||||
link->dev_node = &info->node;
|
||||
info->host = host;
|
||||
|
||||
if (scsi_add_host(host, NULL))
|
||||
|
@ -843,7 +833,7 @@ SYM53C500_config(dev_link_t *link)
|
|||
|
||||
scsi_scan_host(host);
|
||||
|
||||
goto out; /* SUCCESS */
|
||||
return 0;
|
||||
|
||||
err_free_irq:
|
||||
free_irq(irq_level, host);
|
||||
|
@ -852,74 +842,50 @@ SYM53C500_config(dev_link_t *link)
|
|||
err_release:
|
||||
release_region(port_base, 0x10);
|
||||
printk(KERN_INFO "sym53c500_cs: no SCSI devices found\n");
|
||||
|
||||
out:
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
return;
|
||||
return -ENODEV;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
cs_error(link, last_fn, last_ret);
|
||||
SYM53C500_release(link);
|
||||
return;
|
||||
return -ENODEV;
|
||||
} /* SYM53C500_config */
|
||||
|
||||
static int sym53c500_suspend(struct pcmcia_device *dev)
|
||||
static int sym53c500_resume(struct pcmcia_device *link)
|
||||
{
|
||||
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 sym53c500_resume(struct pcmcia_device *dev)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(dev);
|
||||
struct scsi_info_t *info = link->priv;
|
||||
|
||||
link->state &= ~DEV_SUSPEND;
|
||||
if (link->state & DEV_CONFIG) {
|
||||
pcmcia_request_configuration(link->handle, &link->conf);
|
||||
|
||||
/* See earlier comment about manufacturer IDs. */
|
||||
if ((info->manf_id == MANFID_MACNICA) ||
|
||||
(info->manf_id == MANFID_PIONEER) ||
|
||||
(info->manf_id == 0x0098)) {
|
||||
outb(0x80, link->io.BasePort1 + 0xd);
|
||||
outb(0x24, link->io.BasePort1 + 0x9);
|
||||
outb(0x04, link->io.BasePort1 + 0xd);
|
||||
}
|
||||
/*
|
||||
* If things don't work after a "resume",
|
||||
* this is a good place to start looking.
|
||||
*/
|
||||
SYM53C500_int_host_reset(link->io.BasePort1);
|
||||
/* See earlier comment about manufacturer IDs. */
|
||||
if ((info->manf_id == MANFID_MACNICA) ||
|
||||
(info->manf_id == MANFID_PIONEER) ||
|
||||
(info->manf_id == 0x0098)) {
|
||||
outb(0x80, link->io.BasePort1 + 0xd);
|
||||
outb(0x24, link->io.BasePort1 + 0x9);
|
||||
outb(0x04, link->io.BasePort1 + 0xd);
|
||||
}
|
||||
/*
|
||||
* If things don't work after a "resume",
|
||||
* this is a good place to start looking.
|
||||
*/
|
||||
SYM53C500_int_host_reset(link->io.BasePort1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
SYM53C500_detach(struct pcmcia_device *p_dev)
|
||||
SYM53C500_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
|
||||
DEBUG(0, "SYM53C500_detach(0x%p)\n", link);
|
||||
|
||||
if (link->state & DEV_CONFIG)
|
||||
SYM53C500_release(link);
|
||||
SYM53C500_release(link);
|
||||
|
||||
kfree(link->priv);
|
||||
link->priv = NULL;
|
||||
} /* SYM53C500_detach */
|
||||
|
||||
static int
|
||||
SYM53C500_attach(struct pcmcia_device *p_dev)
|
||||
SYM53C500_probe(struct pcmcia_device *link)
|
||||
{
|
||||
struct scsi_info_t *info;
|
||||
dev_link_t *link;
|
||||
|
||||
DEBUG(0, "SYM53C500_attach()\n");
|
||||
|
||||
|
@ -928,7 +894,7 @@ SYM53C500_attach(struct pcmcia_device *p_dev)
|
|||
if (!info)
|
||||
return -ENOMEM;
|
||||
memset(info, 0, sizeof(*info));
|
||||
link = &info->link;
|
||||
info->p_dev = link;
|
||||
link->priv = info;
|
||||
link->io.NumPorts1 = 16;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
|
@ -936,17 +902,10 @@ SYM53C500_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->conf.Present = PRESENT_OPTION;
|
||||
|
||||
link->handle = p_dev;
|
||||
p_dev->instance = link;
|
||||
|
||||
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
|
||||
SYM53C500_config(link);
|
||||
|
||||
return 0;
|
||||
return SYM53C500_config(link);
|
||||
} /* SYM53C500_attach */
|
||||
|
||||
MODULE_AUTHOR("Bob Tracy <rct@frus.com>");
|
||||
|
@ -966,10 +925,9 @@ static struct pcmcia_driver sym53c500_cs_driver = {
|
|||
.drv = {
|
||||
.name = "sym53c500_cs",
|
||||
},
|
||||
.probe = SYM53C500_attach,
|
||||
.probe = SYM53C500_probe,
|
||||
.remove = SYM53C500_detach,
|
||||
.id_table = sym53c500_ids,
|
||||
.suspend = sym53c500_suspend,
|
||||
.resume = sym53c500_resume,
|
||||
};
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <linux/string.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/major.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/system.h>
|
||||
|
@ -97,11 +98,13 @@ static const struct multi_id multi_id[] = {
|
|||
#define MULTI_COUNT (sizeof(multi_id)/sizeof(struct multi_id))
|
||||
|
||||
struct serial_info {
|
||||
dev_link_t link;
|
||||
struct pcmcia_device *p_dev;
|
||||
int ndev;
|
||||
int multi;
|
||||
int slave;
|
||||
int manfid;
|
||||
int prodid;
|
||||
int c950ctrl;
|
||||
dev_node_t node[4];
|
||||
int line[4];
|
||||
};
|
||||
|
@ -113,9 +116,36 @@ struct serial_cfg_mem {
|
|||
};
|
||||
|
||||
|
||||
static void serial_config(dev_link_t * link);
|
||||
static int serial_config(struct pcmcia_device * link);
|
||||
|
||||
|
||||
static void wakeup_card(struct serial_info *info)
|
||||
{
|
||||
int ctrl = info->c950ctrl;
|
||||
|
||||
if (info->manfid == MANFID_OXSEMI) {
|
||||
outb(12, ctrl + 1);
|
||||
} else if (info->manfid == MANFID_POSSIO && info->prodid == PRODID_POSSIO_GCC) {
|
||||
/* request_region? oxsemi branch does no request_region too... */
|
||||
/* This sequence is needed to properly initialize MC45 attached to OXCF950.
|
||||
* I tried decreasing these msleep()s, but it worked properly (survived
|
||||
* 1000 stop/start operations) with these timeouts (or bigger). */
|
||||
outb(0xA, ctrl + 1);
|
||||
msleep(100);
|
||||
outb(0xE, ctrl + 1);
|
||||
msleep(300);
|
||||
outb(0xC, ctrl + 1);
|
||||
msleep(100);
|
||||
outb(0xE, ctrl + 1);
|
||||
msleep(200);
|
||||
outb(0xF, ctrl + 1);
|
||||
msleep(100);
|
||||
outb(0xE, ctrl + 1);
|
||||
msleep(100);
|
||||
outb(0xC, ctrl + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
|
||||
After a card is removed, serial_remove() will unregister
|
||||
|
@ -123,67 +153,45 @@ static void serial_config(dev_link_t * link);
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static void serial_remove(dev_link_t *link)
|
||||
static void serial_remove(struct pcmcia_device *link)
|
||||
{
|
||||
struct serial_info *info = link->priv;
|
||||
int i;
|
||||
|
||||
link->state &= ~DEV_PRESENT;
|
||||
|
||||
DEBUG(0, "serial_release(0x%p)\n", link);
|
||||
|
||||
/*
|
||||
* Recheck to see if the device is still configured.
|
||||
*/
|
||||
if (info->link.state & DEV_CONFIG) {
|
||||
for (i = 0; i < info->ndev; i++)
|
||||
serial8250_unregister_port(info->line[i]);
|
||||
for (i = 0; i < info->ndev; i++)
|
||||
serial8250_unregister_port(info->line[i]);
|
||||
|
||||
info->link.dev = NULL;
|
||||
info->p_dev->dev_node = NULL;
|
||||
|
||||
if (!info->slave) {
|
||||
pcmcia_release_configuration(info->link.handle);
|
||||
pcmcia_release_io(info->link.handle, &info->link.io);
|
||||
pcmcia_release_irq(info->link.handle, &info->link.irq);
|
||||
}
|
||||
|
||||
info->link.state &= ~DEV_CONFIG;
|
||||
}
|
||||
if (!info->slave)
|
||||
pcmcia_disable_device(link);
|
||||
}
|
||||
|
||||
static int serial_suspend(struct pcmcia_device *dev)
|
||||
static int serial_suspend(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(dev);
|
||||
link->state |= DEV_SUSPEND;
|
||||
struct serial_info *info = link->priv;
|
||||
int i;
|
||||
|
||||
if (link->state & DEV_CONFIG) {
|
||||
struct serial_info *info = link->priv;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < info->ndev; i++)
|
||||
serial8250_suspend_port(info->line[i]);
|
||||
|
||||
if (!info->slave)
|
||||
pcmcia_release_configuration(link->handle);
|
||||
}
|
||||
for (i = 0; i < info->ndev; i++)
|
||||
serial8250_suspend_port(info->line[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int serial_resume(struct pcmcia_device *dev)
|
||||
static int serial_resume(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(dev);
|
||||
link->state &= ~DEV_SUSPEND;
|
||||
|
||||
if (DEV_OK(link)) {
|
||||
if (pcmcia_dev_present(link)) {
|
||||
struct serial_info *info = link->priv;
|
||||
int i;
|
||||
|
||||
if (!info->slave)
|
||||
pcmcia_request_configuration(link->handle, &link->conf);
|
||||
|
||||
for (i = 0; i < info->ndev; i++)
|
||||
serial8250_resume_port(info->line[i]);
|
||||
wakeup_card(info);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -197,10 +205,9 @@ static int serial_resume(struct pcmcia_device *dev)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static int serial_probe(struct pcmcia_device *p_dev)
|
||||
static int serial_probe(struct pcmcia_device *link)
|
||||
{
|
||||
struct serial_info *info;
|
||||
dev_link_t *link;
|
||||
|
||||
DEBUG(0, "serial_attach()\n");
|
||||
|
||||
|
@ -209,7 +216,7 @@ static int serial_probe(struct pcmcia_device *p_dev)
|
|||
if (!info)
|
||||
return -ENOMEM;
|
||||
memset(info, 0, sizeof (*info));
|
||||
link = &info->link;
|
||||
info->p_dev = link;
|
||||
link->priv = info;
|
||||
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
|
@ -223,12 +230,7 @@ static int serial_probe(struct pcmcia_device *p_dev)
|
|||
}
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
link->handle = p_dev;
|
||||
p_dev->instance = link;
|
||||
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
|
||||
serial_config(link);
|
||||
|
||||
return 0;
|
||||
return serial_config(link);
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
|
@ -240,9 +242,8 @@ static int serial_probe(struct pcmcia_device *p_dev)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static void serial_detach(struct pcmcia_device *p_dev)
|
||||
static void serial_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct serial_info *info = link->priv;
|
||||
|
||||
DEBUG(0, "serial_detach(0x%p)\n", link);
|
||||
|
@ -263,7 +264,7 @@ static void serial_detach(struct pcmcia_device *p_dev)
|
|||
|
||||
/*====================================================================*/
|
||||
|
||||
static int setup_serial(client_handle_t handle, struct serial_info * info,
|
||||
static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
|
||||
kio_addr_t iobase, int irq)
|
||||
{
|
||||
struct uart_port port;
|
||||
|
@ -298,7 +299,7 @@ static int setup_serial(client_handle_t handle, struct serial_info * info,
|
|||
/*====================================================================*/
|
||||
|
||||
static int
|
||||
first_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse)
|
||||
first_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse)
|
||||
{
|
||||
int i;
|
||||
i = pcmcia_get_first_tuple(handle, tuple);
|
||||
|
@ -311,7 +312,7 @@ first_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse)
|
|||
}
|
||||
|
||||
static int
|
||||
next_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse)
|
||||
next_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse)
|
||||
{
|
||||
int i;
|
||||
i = pcmcia_get_next_tuple(handle, tuple);
|
||||
|
@ -325,11 +326,10 @@ next_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse)
|
|||
|
||||
/*====================================================================*/
|
||||
|
||||
static int simple_config(dev_link_t *link)
|
||||
static int simple_config(struct pcmcia_device *link)
|
||||
{
|
||||
static const kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
|
||||
static const int size_table[2] = { 8, 16 };
|
||||
client_handle_t handle = link->handle;
|
||||
struct serial_info *info = link->priv;
|
||||
struct serial_cfg_mem *cfg_mem;
|
||||
tuple_t *tuple;
|
||||
|
@ -350,7 +350,7 @@ static int simple_config(dev_link_t *link)
|
|||
buf = cfg_mem->buf;
|
||||
|
||||
/* If the card is already configured, look up the port and irq */
|
||||
i = pcmcia_get_configuration_info(handle, &config);
|
||||
i = pcmcia_get_configuration_info(link, &config);
|
||||
if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) {
|
||||
kio_addr_t port = 0;
|
||||
if ((config.BasePort2 != 0) && (config.NumPorts2 == 8)) {
|
||||
|
@ -363,10 +363,9 @@ static int simple_config(dev_link_t *link)
|
|||
}
|
||||
if (info->slave) {
|
||||
kfree(cfg_mem);
|
||||
return setup_serial(handle, info, port, config.AssignedIRQ);
|
||||
return setup_serial(link, info, port, config.AssignedIRQ);
|
||||
}
|
||||
}
|
||||
link->conf.Vcc = config.Vcc;
|
||||
|
||||
/* First pass: look for a config entry that looks normal. */
|
||||
tuple->TupleData = (cisdata_t *) buf;
|
||||
|
@ -377,12 +376,12 @@ static int simple_config(dev_link_t *link)
|
|||
/* Two tries: without IO aliases, then with aliases */
|
||||
for (s = 0; s < 2; s++) {
|
||||
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 =
|
||||
link->conf.Vpp =
|
||||
cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
|
||||
if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[s]) &&
|
||||
(cf->io.win[0].base != 0)) {
|
||||
|
@ -390,19 +389,19 @@ static int simple_config(dev_link_t *link)
|
|||
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)) {
|
||||
|
@ -410,50 +409,48 @@ static int simple_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) {
|
||||
printk(KERN_NOTICE
|
||||
"serial_cs: no usable port range found, giving up\n");
|
||||
cs_error(link->handle, RequestIO, i);
|
||||
cs_error(link, RequestIO, i);
|
||||
kfree(cfg_mem);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
if (info->multi && (info->manfid == MANFID_3COM))
|
||||
link->conf.ConfigIndex &= ~(0x08);
|
||||
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);
|
||||
kfree(cfg_mem);
|
||||
return -1;
|
||||
}
|
||||
kfree(cfg_mem);
|
||||
return setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ);
|
||||
return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
|
||||
}
|
||||
|
||||
static int multi_config(dev_link_t * link)
|
||||
static int multi_config(struct pcmcia_device * link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
struct serial_info *info = link->priv;
|
||||
struct serial_cfg_mem *cfg_mem;
|
||||
tuple_t *tuple;
|
||||
u_char *buf;
|
||||
cisparse_t *parse;
|
||||
cistpl_cftable_entry_t *cf;
|
||||
config_info_t config;
|
||||
int i, rc, base2 = 0;
|
||||
|
||||
cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL);
|
||||
|
@ -464,14 +461,6 @@ static int multi_config(dev_link_t * link)
|
|||
cf = &parse->cftable_entry;
|
||||
buf = cfg_mem->buf;
|
||||
|
||||
i = pcmcia_get_configuration_info(handle, &config);
|
||||
if (i != CS_SUCCESS) {
|
||||
cs_error(handle, GetConfigurationInfo, i);
|
||||
rc = -1;
|
||||
goto free_cfg_mem;
|
||||
}
|
||||
link->conf.Vcc = config.Vcc;
|
||||
|
||||
tuple->TupleData = (cisdata_t *) buf;
|
||||
tuple->TupleOffset = 0;
|
||||
tuple->TupleDataMax = 255;
|
||||
|
@ -480,7 +469,7 @@ static int multi_config(dev_link_t * link)
|
|||
|
||||
/* First, look for a generic full-sized window */
|
||||
link->io.NumPorts1 = info->multi * 8;
|
||||
i = first_tuple(handle, tuple, parse);
|
||||
i = first_tuple(link, tuple, parse);
|
||||
while (i != CS_NO_MORE_ITEMS) {
|
||||
/* The quad port cards have bad CIS's, so just look for a
|
||||
window larger than 8 ports and assume it will be right */
|
||||
|
@ -490,19 +479,19 @@ static int multi_config(dev_link_t * link)
|
|||
link->io.BasePort1 = cf->io.win[0].base;
|
||||
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);
|
||||
base2 = link->io.BasePort1 + 8;
|
||||
if (i == CS_SUCCESS)
|
||||
break;
|
||||
}
|
||||
i = next_tuple(handle, tuple, parse);
|
||||
i = next_tuple(link, tuple, parse);
|
||||
}
|
||||
|
||||
/* If that didn't work, look for two windows */
|
||||
if (i != CS_SUCCESS) {
|
||||
link->io.NumPorts1 = link->io.NumPorts2 = 8;
|
||||
info->multi = 2;
|
||||
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 == 2)) {
|
||||
link->conf.ConfigIndex = cf->index;
|
||||
|
@ -510,26 +499,26 @@ static int multi_config(dev_link_t * link)
|
|||
link->io.BasePort2 = cf->io.win[1].base;
|
||||
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);
|
||||
base2 = link->io.BasePort2;
|
||||
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);
|
||||
rc = -1;
|
||||
goto free_cfg_mem;
|
||||
}
|
||||
|
||||
i = pcmcia_request_irq(link->handle, &link->irq);
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != CS_SUCCESS) {
|
||||
printk(KERN_NOTICE
|
||||
"serial_cs: no usable port range found, giving up\n");
|
||||
cs_error(link->handle, RequestIRQ, i);
|
||||
cs_error(link, RequestIRQ, i);
|
||||
link->irq.AssignedIRQ = 0;
|
||||
}
|
||||
/* Socket Dual IO: this enables irq's for second port */
|
||||
|
@ -537,35 +526,43 @@ static int multi_config(dev_link_t * link)
|
|||
link->conf.Present |= PRESENT_EXT_STATUS;
|
||||
link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
|
||||
}
|
||||
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);
|
||||
rc = -1;
|
||||
goto free_cfg_mem;
|
||||
}
|
||||
|
||||
/* The Oxford Semiconductor OXCF950 cards are in fact single-port:
|
||||
8 registers are for the UART, the others are extra registers */
|
||||
if (info->manfid == MANFID_OXSEMI) {
|
||||
* 8 registers are for the UART, the others are extra registers.
|
||||
* Siemen's MC45 PCMCIA (Possio's GCC) is OXCF950 based too.
|
||||
*/
|
||||
if (info->manfid == MANFID_OXSEMI || (info->manfid == MANFID_POSSIO &&
|
||||
info->prodid == PRODID_POSSIO_GCC)) {
|
||||
int err;
|
||||
|
||||
if (cf->index == 1 || cf->index == 3) {
|
||||
setup_serial(handle, info, base2, link->irq.AssignedIRQ);
|
||||
outb(12, link->io.BasePort1 + 1);
|
||||
err = setup_serial(link, info, base2,
|
||||
link->irq.AssignedIRQ);
|
||||
base2 = link->io.BasePort1;
|
||||
} else {
|
||||
setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ);
|
||||
outb(12, base2 + 1);
|
||||
err = setup_serial(link, info, link->io.BasePort1,
|
||||
link->irq.AssignedIRQ);
|
||||
}
|
||||
info->c950ctrl = base2;
|
||||
wakeup_card(info);
|
||||
rc = 0;
|
||||
goto free_cfg_mem;
|
||||
}
|
||||
|
||||
setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ);
|
||||
setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
|
||||
/* The Nokia cards are not really multiport cards */
|
||||
if (info->manfid == MANFID_NOKIA) {
|
||||
rc = 0;
|
||||
goto free_cfg_mem;
|
||||
}
|
||||
for (i = 0; i < info->multi - 1; i++)
|
||||
setup_serial(handle, info, base2 + (8 * i),
|
||||
setup_serial(link, info, base2 + (8 * i),
|
||||
link->irq.AssignedIRQ);
|
||||
rc = 0;
|
||||
free_cfg_mem:
|
||||
|
@ -581,9 +578,8 @@ static int multi_config(dev_link_t * link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
void serial_config(dev_link_t * link)
|
||||
static int serial_config(struct pcmcia_device * link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
struct serial_info *info = link->priv;
|
||||
struct serial_cfg_mem *cfg_mem;
|
||||
tuple_t *tuple;
|
||||
|
@ -609,7 +605,7 @@ void serial_config(dev_link_t * link)
|
|||
tuple->Attributes = 0;
|
||||
/* 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;
|
||||
|
@ -617,18 +613,16 @@ void serial_config(dev_link_t * link)
|
|||
link->conf.ConfigBase = parse->config.base;
|
||||
link->conf.Present = parse->config.rmask[0];
|
||||
|
||||
/* Configure card */
|
||||
link->state |= DEV_CONFIG;
|
||||
|
||||
/* Is this a compliant multifunction card? */
|
||||
tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
|
||||
tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
|
||||
info->multi = (first_tuple(handle, tuple, parse) == CS_SUCCESS);
|
||||
info->multi = (first_tuple(link, tuple, parse) == CS_SUCCESS);
|
||||
|
||||
/* Is this a multiport card? */
|
||||
tuple->DesiredTuple = CISTPL_MANFID;
|
||||
if (first_tuple(handle, tuple, parse) == CS_SUCCESS) {
|
||||
if (first_tuple(link, tuple, parse) == CS_SUCCESS) {
|
||||
info->manfid = parse->manfid.manf;
|
||||
info->prodid = le16_to_cpu(buf[1]);
|
||||
for (i = 0; i < MULTI_COUNT; i++)
|
||||
if ((info->manfid == multi_id[i].manfid) &&
|
||||
(parse->manfid.card == multi_id[i].prodid))
|
||||
|
@ -641,11 +635,11 @@ void serial_config(dev_link_t * link)
|
|||
multifunction cards that ask for appropriate IO port ranges */
|
||||
tuple->DesiredTuple = CISTPL_FUNCID;
|
||||
if ((info->multi == 0) &&
|
||||
((first_tuple(handle, tuple, parse) != CS_SUCCESS) ||
|
||||
((first_tuple(link, tuple, parse) != CS_SUCCESS) ||
|
||||
(parse->funcid.func == CISTPL_FUNCID_MULTI) ||
|
||||
(parse->funcid.func == CISTPL_FUNCID_SERIAL))) {
|
||||
tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
if (first_tuple(handle, tuple, parse) == CS_SUCCESS) {
|
||||
if (first_tuple(link, tuple, parse) == CS_SUCCESS) {
|
||||
if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
|
||||
info->multi = cf->io.win[0].len >> 3;
|
||||
if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
|
||||
|
@ -664,31 +658,30 @@ void serial_config(dev_link_t * link)
|
|||
|
||||
if (info->manfid == MANFID_IBM) {
|
||||
conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
|
||||
last_ret = pcmcia_access_configuration_register(link->handle, ®);
|
||||
last_ret = pcmcia_access_configuration_register(link, ®);
|
||||
if (last_ret) {
|
||||
last_fn = AccessConfigurationRegister;
|
||||
goto cs_failed;
|
||||
}
|
||||
reg.Action = CS_WRITE;
|
||||
reg.Value = reg.Value | 1;
|
||||
last_ret = pcmcia_access_configuration_register(link->handle, ®);
|
||||
last_ret = pcmcia_access_configuration_register(link, ®);
|
||||
if (last_ret) {
|
||||
last_fn = AccessConfigurationRegister;
|
||||
goto cs_failed;
|
||||
}
|
||||
}
|
||||
|
||||
link->dev = &info->node[0];
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
link->dev_node = &info->node[0];
|
||||
kfree(cfg_mem);
|
||||
return;
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
serial_remove(link);
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
kfree(cfg_mem);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static struct pcmcia_device_id serial_ids[] = {
|
||||
|
@ -739,6 +732,7 @@ static struct pcmcia_device_id serial_ids[] = {
|
|||
PCMCIA_MFC_DEVICE_PROD_ID1(1, "Motorola MARQUIS", 0xf03e4e77),
|
||||
PCMCIA_MFC_DEVICE_PROD_ID2(1, "FAX/Modem/Ethernet Combo Card ", 0x1ed59302),
|
||||
PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0301),
|
||||
PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x0276),
|
||||
PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0039),
|
||||
PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0006),
|
||||
PCMCIA_DEVICE_MANF_CARD(0x0105, 0x410a),
|
||||
|
@ -757,6 +751,7 @@ static struct pcmcia_device_id serial_ids[] = {
|
|||
PCMCIA_DEVICE_PROD_ID14("MEGAHERTZ", "PCMCIA MODEM", 0xf510db04, 0xbd6c43ef),
|
||||
PCMCIA_DEVICE_PROD_ID124("TOSHIBA", "T144PF", "PCMCIA MODEM", 0xb4585a1a, 0x7271409c, 0xbd6c43ef),
|
||||
PCMCIA_DEVICE_PROD_ID123("FUJITSU", "FC14F ", "MBH10213", 0x6ee5a3d8, 0x30ead12b, 0xb00f05a0),
|
||||
PCMCIA_DEVICE_PROD_ID123("Novatel Wireless", "Merlin UMTS Modem", "U630", 0x32607776, 0xd9e73b13, 0xe87332e),
|
||||
PCMCIA_DEVICE_PROD_ID13("MEGAHERTZ", "V.34 PCMCIA MODEM", 0xf510db04, 0xbb2cce4a),
|
||||
PCMCIA_DEVICE_PROD_ID12("Brain Boxes", "Bluetooth PC Card", 0xee138382, 0xd4ce9b02),
|
||||
PCMCIA_DEVICE_PROD_ID12("CIRRUS LOGIC", "FAX MODEM", 0xe625f451, 0xcecd6dfa),
|
||||
|
|
|
@ -35,73 +35,52 @@ typedef struct ixj_info_t {
|
|||
} ixj_info_t;
|
||||
|
||||
static void ixj_detach(struct pcmcia_device *p_dev);
|
||||
static void ixj_config(dev_link_t * link);
|
||||
static void ixj_cs_release(dev_link_t * link);
|
||||
static int ixj_config(struct pcmcia_device * link);
|
||||
static void ixj_cs_release(struct pcmcia_device * link);
|
||||
|
||||
static int ixj_attach(struct pcmcia_device *p_dev)
|
||||
static int ixj_probe(struct pcmcia_device *p_dev)
|
||||
{
|
||||
dev_link_t *link;
|
||||
|
||||
DEBUG(0, "ixj_attach()\n");
|
||||
/* Create new ixj device */
|
||||
link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
|
||||
if (!link)
|
||||
return -ENOMEM;
|
||||
memset(link, 0, sizeof(struct dev_link_t));
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
||||
link->io.IOAddrLines = 3;
|
||||
link->conf.Vcc = 50;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
link->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL);
|
||||
if (!link->priv) {
|
||||
kfree(link);
|
||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
||||
p_dev->io.IOAddrLines = 3;
|
||||
p_dev->conf.IntType = INT_MEMORY_AND_IO;
|
||||
p_dev->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL);
|
||||
if (!p_dev->priv) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(link->priv, 0, sizeof(struct ixj_info_t));
|
||||
memset(p_dev->priv, 0, sizeof(struct ixj_info_t));
|
||||
|
||||
link->handle = p_dev;
|
||||
p_dev->instance = link;
|
||||
|
||||
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
|
||||
ixj_config(link);
|
||||
|
||||
return 0;
|
||||
return ixj_config(p_dev);
|
||||
}
|
||||
|
||||
static void ixj_detach(struct pcmcia_device *p_dev)
|
||||
static void ixj_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
|
||||
DEBUG(0, "ixj_detach(0x%p)\n", link);
|
||||
|
||||
link->state &= ~DEV_RELEASE_PENDING;
|
||||
if (link->state & DEV_CONFIG)
|
||||
ixj_cs_release(link);
|
||||
ixj_cs_release(link);
|
||||
|
||||
kfree(link->priv);
|
||||
kfree(link);
|
||||
}
|
||||
|
||||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static void ixj_get_serial(dev_link_t * link, IXJ * j)
|
||||
static void ixj_get_serial(struct pcmcia_device * link, IXJ * j)
|
||||
{
|
||||
client_handle_t handle;
|
||||
tuple_t tuple;
|
||||
u_short buf[128];
|
||||
char *str;
|
||||
int last_ret, last_fn, i, place;
|
||||
handle = link->handle;
|
||||
DEBUG(0, "ixj_get_serial(0x%p)\n", link);
|
||||
tuple.TupleData = (cisdata_t *) buf;
|
||||
tuple.TupleOffset = 0;
|
||||
tuple.TupleDataMax = 80;
|
||||
tuple.Attributes = 0;
|
||||
tuple.DesiredTuple = CISTPL_VERS_1;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
|
||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
|
||||
str = (char *) buf;
|
||||
printk("PCMCIA Version %d.%d\n", str[0], str[1]);
|
||||
str += 2;
|
||||
|
@ -149,22 +128,19 @@ static void ixj_get_serial(dev_link_t * link, IXJ * j)
|
|||
return;
|
||||
}
|
||||
|
||||
static void ixj_config(dev_link_t * link)
|
||||
static int ixj_config(struct pcmcia_device * link)
|
||||
{
|
||||
IXJ *j;
|
||||
client_handle_t handle;
|
||||
ixj_info_t *info;
|
||||
tuple_t tuple;
|
||||
u_short buf[128];
|
||||
cisparse_t parse;
|
||||
config_info_t conf;
|
||||
cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
|
||||
cistpl_cftable_entry_t dflt =
|
||||
{
|
||||
0
|
||||
};
|
||||
int last_ret, last_fn;
|
||||
handle = link->handle;
|
||||
info = link->priv;
|
||||
DEBUG(0, "ixj_config(0x%p)\n", link);
|
||||
tuple.TupleData = (cisdata_t *) buf;
|
||||
|
@ -172,19 +148,17 @@ static void ixj_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, &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];
|
||||
link->state |= DEV_CONFIG;
|
||||
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
|
||||
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 ||
|
||||
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->io.nwin > 0) || (dflt.io.nwin > 0)) {
|
||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
|
||||
|
@ -195,7 +169,7 @@ static void ixj_config(dev_link_t * link)
|
|||
link->io.BasePort2 = io->win[1].base;
|
||||
link->io.NumPorts2 = io->win[1].len;
|
||||
}
|
||||
if (pcmcia_request_io(link->handle, &link->io) != 0)
|
||||
if (pcmcia_request_io(link, &link->io) != 0)
|
||||
goto next_entry;
|
||||
/* If we've got this far, we're done */
|
||||
break;
|
||||
|
@ -203,10 +177,10 @@ static void ixj_config(dev_link_t * link)
|
|||
next_entry:
|
||||
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
|
||||
dflt = *cfg;
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
|
||||
}
|
||||
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
|
||||
/*
|
||||
* Register the card with the core.
|
||||
|
@ -215,46 +189,21 @@ static void ixj_config(dev_link_t * link)
|
|||
|
||||
info->ndev = 1;
|
||||
info->node.major = PHONE_MAJOR;
|
||||
link->dev = &info->node;
|
||||
link->dev_node = &info->node;
|
||||
ixj_get_serial(link, j);
|
||||
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);
|
||||
ixj_cs_release(link);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void ixj_cs_release(dev_link_t *link)
|
||||
static void ixj_cs_release(struct pcmcia_device *link)
|
||||
{
|
||||
ixj_info_t *info = link->priv;
|
||||
DEBUG(0, "ixj_cs_release(0x%p)\n", link);
|
||||
info->ndev = 0;
|
||||
link->dev = NULL;
|
||||
pcmcia_release_configuration(link->handle);
|
||||
pcmcia_release_io(link->handle, &link->io);
|
||||
link->state &= ~DEV_CONFIG;
|
||||
}
|
||||
|
||||
static int ixj_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 ixj_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 ixj_ids[] = {
|
||||
|
@ -268,11 +217,9 @@ static struct pcmcia_driver ixj_driver = {
|
|||
.drv = {
|
||||
.name = "ixj_cs",
|
||||
},
|
||||
.probe = ixj_attach,
|
||||
.probe = ixj_probe,
|
||||
.remove = ixj_detach,
|
||||
.id_table = ixj_ids,
|
||||
.suspend = ixj_suspend,
|
||||
.resume = ixj_resume,
|
||||
};
|
||||
|
||||
static int __init ixj_pcmcia_init(void)
|
||||
|
|
|
@ -67,11 +67,11 @@ module_param(pc_debug, int, 0644);
|
|||
static const char driver_name[DEV_NAME_LEN] = "sl811_cs";
|
||||
|
||||
typedef struct local_info_t {
|
||||
dev_link_t link;
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
} local_info_t;
|
||||
|
||||
static void sl811_cs_release(dev_link_t * link);
|
||||
static void sl811_cs_release(struct pcmcia_device * link);
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
|
@ -138,41 +138,27 @@ static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq)
|
|||
|
||||
/*====================================================================*/
|
||||
|
||||
static void sl811_cs_detach(struct pcmcia_device *p_dev)
|
||||
static void sl811_cs_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
|
||||
DBG(0, "sl811_cs_detach(0x%p)\n", link);
|
||||
|
||||
link->state &= ~DEV_PRESENT;
|
||||
if (link->state & DEV_CONFIG)
|
||||
sl811_cs_release(link);
|
||||
sl811_cs_release(link);
|
||||
|
||||
/* This points to the parent local_info_t struct */
|
||||
kfree(link->priv);
|
||||
}
|
||||
|
||||
static void sl811_cs_release(dev_link_t * link)
|
||||
static void sl811_cs_release(struct pcmcia_device * link)
|
||||
{
|
||||
|
||||
DBG(0, "sl811_cs_release(0x%p)\n", link);
|
||||
|
||||
/* Unlink the device chain */
|
||||
link->dev = NULL;
|
||||
|
||||
pcmcia_disable_device(link);
|
||||
platform_device_unregister(&platform_dev);
|
||||
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;
|
||||
}
|
||||
|
||||
static void sl811_cs_config(dev_link_t *link)
|
||||
static int sl811_cs_config(struct pcmcia_device *link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
struct device *parent = &handle_to_dev(handle);
|
||||
struct device *parent = &handle_to_dev(link);
|
||||
local_info_t *dev = link->priv;
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
|
@ -188,27 +174,23 @@ static void sl811_cs_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;
|
||||
pcmcia_get_configuration_info(link, &conf));
|
||||
|
||||
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 *cfg = &(parse.cftable_entry);
|
||||
|
||||
if (pcmcia_get_tuple_data(handle, &tuple) != 0
|
||||
|| pcmcia_parse_tuple(handle, &tuple, &parse)
|
||||
if (pcmcia_get_tuple_data(link, &tuple) != 0
|
||||
|| pcmcia_parse_tuple(link, &tuple, &parse)
|
||||
!= 0)
|
||||
goto next_entry;
|
||||
|
||||
|
@ -234,10 +216,10 @@ static void sl811_cs_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;
|
||||
|
||||
/* we need an interrupt */
|
||||
|
@ -254,15 +236,14 @@ static void sl811_cs_config(dev_link_t *link)
|
|||
link->io.BasePort1 = io->win[0].base;
|
||||
link->io.NumPorts1 = io->win[0].len;
|
||||
|
||||
if (pcmcia_request_io(link->handle, &link->io) != 0)
|
||||
if (pcmcia_request_io(link, &link->io) != 0)
|
||||
goto next_entry;
|
||||
}
|
||||
break;
|
||||
|
||||
next_entry:
|
||||
if (link->io.NumPorts1)
|
||||
pcmcia_release_io(link->handle, &link->io);
|
||||
last_ret = pcmcia_get_next_tuple(handle, &tuple);
|
||||
pcmcia_disable_device(link);
|
||||
last_ret = pcmcia_get_next_tuple(link, &tuple);
|
||||
}
|
||||
|
||||
/* require an IRQ and two registers */
|
||||
|
@ -270,71 +251,46 @@ static void sl811_cs_config(dev_link_t *link)
|
|||
goto cs_failed;
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
||||
CS_CHECK(RequestIRQ,
|
||||
pcmcia_request_irq(link->handle, &link->irq));
|
||||
pcmcia_request_irq(link, &link->irq));
|
||||
else
|
||||
goto cs_failed;
|
||||
|
||||
CS_CHECK(RequestConfiguration,
|
||||
pcmcia_request_configuration(link->handle, &link->conf));
|
||||
pcmcia_request_configuration(link, &link->conf));
|
||||
|
||||
sprintf(dev->node.dev_name, driver_name);
|
||||
dev->node.major = dev->node.minor = 0;
|
||||
link->dev = &dev->node;
|
||||
link->dev_node = &dev->node;
|
||||
|
||||
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);
|
||||
printk(", irq %d", link->irq.AssignedIRQ);
|
||||
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
|
||||
link->io.BasePort1+link->io.NumPorts1-1);
|
||||
printk("\n");
|
||||
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
|
||||
if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ)
|
||||
< 0) {
|
||||
cs_failed:
|
||||
printk("sl811_cs_config failed\n");
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
cs_error(link, last_fn, last_ret);
|
||||
sl811_cs_release(link);
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
static int sl811_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 sl811_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 int sl811_cs_attach(struct pcmcia_device *p_dev)
|
||||
static int sl811_cs_probe(struct pcmcia_device *link)
|
||||
{
|
||||
local_info_t *local;
|
||||
dev_link_t *link;
|
||||
|
||||
local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
|
||||
if (!local)
|
||||
return -ENOMEM;
|
||||
memset(local, 0, sizeof(local_info_t));
|
||||
link = &local->link;
|
||||
local->p_dev = link;
|
||||
link->priv = local;
|
||||
|
||||
/* Initialize */
|
||||
|
@ -343,16 +299,9 @@ static int sl811_cs_attach(struct pcmcia_device *p_dev)
|
|||
link->irq.Handler = NULL;
|
||||
|
||||
link->conf.Attributes = 0;
|
||||
link->conf.Vcc = 33;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
link->handle = p_dev;
|
||||
p_dev->instance = link;
|
||||
|
||||
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
|
||||
sl811_cs_config(link);
|
||||
|
||||
return 0;
|
||||
return sl811_cs_config(link);
|
||||
}
|
||||
|
||||
static struct pcmcia_device_id sl811_ids[] = {
|
||||
|
@ -366,11 +315,9 @@ static struct pcmcia_driver sl811_cs_driver = {
|
|||
.drv = {
|
||||
.name = (char *)driver_name,
|
||||
},
|
||||
.probe = sl811_cs_attach,
|
||||
.probe = sl811_cs_probe,
|
||||
.remove = sl811_cs_detach,
|
||||
.id_table = sl811_ids,
|
||||
.suspend = sl811_suspend,
|
||||
.resume = sl811_resume,
|
||||
};
|
||||
|
||||
/*====================================================================*/
|
||||
|
|
|
@ -65,6 +65,9 @@
|
|||
/* SmartMedia */
|
||||
#define AT91_SMARTMEDIA_BASE 0x40000000 /* NCS3: Smartmedia physical base address */
|
||||
|
||||
/* Compact Flash */
|
||||
#define AT91_CF_BASE 0x50000000 /* NCS4-NCS6: Compact Flash physical base address */
|
||||
|
||||
/* Multi-Master Memory controller */
|
||||
#define AT91_UHP_BASE 0x00300000 /* USB Host controller */
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ typedef struct region_info_t {
|
|||
#define REGION_BAR_MASK 0xe000
|
||||
#define REGION_BAR_SHIFT 13
|
||||
|
||||
int pcmcia_get_first_region(client_handle_t handle, region_info_t *rgn);
|
||||
int pcmcia_get_next_region(client_handle_t handle, region_info_t *rgn);
|
||||
int pcmcia_get_first_region(struct pcmcia_device *handle, region_info_t *rgn);
|
||||
int pcmcia_get_next_region(struct pcmcia_device *handle, region_info_t *rgn);
|
||||
|
||||
#endif /* _LINUX_BULKMEM_H */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* ciscode.h -- Definitions for bulk memory services
|
||||
* ciscode.h
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
@ -122,4 +122,7 @@
|
|||
|
||||
#define MANFID_XIRCOM 0x0105
|
||||
|
||||
#define MANFID_POSSIO 0x030c
|
||||
#define PRODID_POSSIO_GCC 0x0003
|
||||
|
||||
#endif /* _LINUX_CISCODE_H */
|
||||
|
|
|
@ -586,12 +586,7 @@ typedef struct cisdump_t {
|
|||
cisdata_t Data[CISTPL_MAX_CIS_SIZE];
|
||||
} cisdump_t;
|
||||
|
||||
int pcmcia_get_first_tuple(client_handle_t handle, tuple_t *tuple);
|
||||
int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple);
|
||||
int pcmcia_get_tuple_data(client_handle_t handle, tuple_t *tuple);
|
||||
int pcmcia_parse_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse);
|
||||
|
||||
int pcmcia_validate_cis(client_handle_t handle, cisinfo_t *info);
|
||||
int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis);
|
||||
|
||||
/* don't use outside of PCMCIA core yet */
|
||||
|
@ -602,4 +597,20 @@ int pccard_parse_tuple(tuple_t *tuple, cisparse_t *parse);
|
|||
|
||||
int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, cisinfo_t *info);
|
||||
|
||||
/* ... but use these wrappers instead */
|
||||
#define pcmcia_get_first_tuple(p_dev, tuple) \
|
||||
pccard_get_first_tuple(p_dev->socket, p_dev->func, tuple)
|
||||
|
||||
#define pcmcia_get_next_tuple(p_dev, tuple) \
|
||||
pccard_get_next_tuple(p_dev->socket, p_dev->func, tuple)
|
||||
|
||||
#define pcmcia_get_tuple_data(p_dev, tuple) \
|
||||
pccard_get_tuple_data(p_dev->socket, tuple)
|
||||
|
||||
#define pcmcia_parse_tuple(p_dev, tuple, parse) \
|
||||
pccard_parse_tuple(tuple, parse)
|
||||
|
||||
#define pcmcia_validate_cis(p_dev, info) \
|
||||
pccard_validate_cis(p_dev->socket, p_dev->func, info)
|
||||
|
||||
#endif /* LINUX_CISTPL_H */
|
||||
|
|
|
@ -109,17 +109,6 @@ typedef struct client_req_t {
|
|||
|
||||
#define CLIENT_THIS_SOCKET 0x01
|
||||
|
||||
/* For RegisterClient */
|
||||
typedef struct client_reg_t {
|
||||
dev_info_t *dev_info;
|
||||
u_int Attributes; /* UNUSED */
|
||||
u_int EventMask;
|
||||
int (*event_handler)(event_t event, int priority,
|
||||
event_callback_args_t *);
|
||||
event_callback_args_t event_callback_args;
|
||||
u_int Version;
|
||||
} client_reg_t;
|
||||
|
||||
/* ModifyConfiguration */
|
||||
typedef struct modconf_t {
|
||||
u_int Attributes;
|
||||
|
@ -127,15 +116,16 @@ typedef struct modconf_t {
|
|||
} modconf_t;
|
||||
|
||||
/* Attributes for ModifyConfiguration */
|
||||
#define CONF_IRQ_CHANGE_VALID 0x100
|
||||
#define CONF_VCC_CHANGE_VALID 0x200
|
||||
#define CONF_VPP1_CHANGE_VALID 0x400
|
||||
#define CONF_VPP2_CHANGE_VALID 0x800
|
||||
#define CONF_IRQ_CHANGE_VALID 0x0100
|
||||
#define CONF_VCC_CHANGE_VALID 0x0200
|
||||
#define CONF_VPP1_CHANGE_VALID 0x0400
|
||||
#define CONF_VPP2_CHANGE_VALID 0x0800
|
||||
#define CONF_IO_CHANGE_WIDTH 0x1000
|
||||
|
||||
/* For RequestConfiguration */
|
||||
typedef struct config_req_t {
|
||||
u_int Attributes;
|
||||
u_int Vcc, Vpp1, Vpp2;
|
||||
u_int Vpp; /* both Vpp1 and Vpp2 */
|
||||
u_int IntType;
|
||||
u_int ConfigBase;
|
||||
u_char Status, Pin, Copy, ExtStatus;
|
||||
|
@ -389,23 +379,27 @@ int pcmcia_get_status(struct pcmcia_device *p_dev, cs_status_t *status);
|
|||
int pcmcia_get_mem_page(window_handle_t win, memreq_t *req);
|
||||
int pcmcia_map_mem_page(window_handle_t win, memreq_t *req);
|
||||
int pcmcia_modify_configuration(struct pcmcia_device *p_dev, modconf_t *mod);
|
||||
int pcmcia_release_configuration(struct pcmcia_device *p_dev);
|
||||
int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req);
|
||||
int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req);
|
||||
int pcmcia_release_window(window_handle_t win);
|
||||
int pcmcia_request_configuration(struct pcmcia_device *p_dev, config_req_t *req);
|
||||
int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req);
|
||||
int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req);
|
||||
int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_handle_t *wh);
|
||||
int pcmcia_reset_card(struct pcmcia_device *p_dev, client_req_t *req);
|
||||
int pcmcia_suspend_card(struct pcmcia_socket *skt);
|
||||
int pcmcia_resume_card(struct pcmcia_socket *skt);
|
||||
int pcmcia_eject_card(struct pcmcia_socket *skt);
|
||||
int pcmcia_insert_card(struct pcmcia_socket *skt);
|
||||
int pccard_reset_card(struct pcmcia_socket *skt);
|
||||
|
||||
struct pcmcia_device * pcmcia_dev_present(struct pcmcia_device *p_dev);
|
||||
void pcmcia_disable_device(struct pcmcia_device *p_dev);
|
||||
|
||||
struct pcmcia_socket * pcmcia_get_socket(struct pcmcia_socket *skt);
|
||||
void pcmcia_put_socket(struct pcmcia_socket *skt);
|
||||
|
||||
/* compatibility functions */
|
||||
#define pcmcia_reset_card(p_dev, req) \
|
||||
pccard_reset_card(p_dev->socket)
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _LINUX_CS_H */
|
||||
|
|
|
@ -39,7 +39,7 @@ typedef struct win_info_t {
|
|||
typedef struct bind_info_t {
|
||||
dev_info_t dev_info;
|
||||
u_char function;
|
||||
struct dev_link_t *instance;
|
||||
struct pcmcia_device *instance;
|
||||
char name[DEV_NAME_LEN];
|
||||
u_short major, minor;
|
||||
void *next;
|
||||
|
@ -96,6 +96,7 @@ typedef union ds_ioctl_arg_t {
|
|||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/device.h>
|
||||
#include <pcmcia/ss.h>
|
||||
|
||||
typedef struct dev_node_t {
|
||||
char dev_name[DEV_NAME_LEN];
|
||||
|
@ -103,34 +104,9 @@ typedef struct dev_node_t {
|
|||
struct dev_node_t *next;
|
||||
} dev_node_t;
|
||||
|
||||
typedef struct dev_link_t {
|
||||
dev_node_t *dev;
|
||||
u_int state, open;
|
||||
wait_queue_head_t pending;
|
||||
client_handle_t handle;
|
||||
io_req_t io;
|
||||
irq_req_t irq;
|
||||
config_req_t conf;
|
||||
window_handle_t win;
|
||||
void *priv;
|
||||
struct dev_link_t *next;
|
||||
} dev_link_t;
|
||||
|
||||
/* Flags for device state */
|
||||
#define DEV_PRESENT 0x01
|
||||
#define DEV_CONFIG 0x02
|
||||
#define DEV_STALE_CONFIG 0x04 /* release on close */
|
||||
#define DEV_STALE_LINK 0x08 /* detach on release */
|
||||
#define DEV_CONFIG_PENDING 0x10
|
||||
#define DEV_RELEASE_PENDING 0x20
|
||||
#define DEV_SUSPEND 0x40
|
||||
#define DEV_BUSY 0x80
|
||||
|
||||
#define DEV_OK(l) \
|
||||
((l) && ((l->state & ~DEV_BUSY) == (DEV_CONFIG|DEV_PRESENT)))
|
||||
|
||||
|
||||
struct pcmcia_socket;
|
||||
struct config_t;
|
||||
|
||||
struct pcmcia_driver {
|
||||
int (*probe) (struct pcmcia_device *dev);
|
||||
|
@ -148,6 +124,7 @@ struct pcmcia_driver {
|
|||
int pcmcia_register_driver(struct pcmcia_driver *driver);
|
||||
void pcmcia_unregister_driver(struct pcmcia_driver *driver);
|
||||
|
||||
|
||||
struct pcmcia_device {
|
||||
/* the socket and the device_no [for multifunction devices]
|
||||
uniquely define a pcmcia_device */
|
||||
|
@ -160,21 +137,40 @@ struct pcmcia_device {
|
|||
/* the hardware "function" device; certain subdevices can
|
||||
* share one hardware "function" device. */
|
||||
u8 func;
|
||||
struct config_t* function_config;
|
||||
|
||||
struct list_head socket_device_list;
|
||||
|
||||
/* deprecated, a cleaned up version will be moved into this
|
||||
struct soon */
|
||||
dev_link_t *instance;
|
||||
u_int state;
|
||||
/* deprecated, will be cleaned up soon */
|
||||
dev_node_t *dev_node;
|
||||
u_int open;
|
||||
io_req_t io;
|
||||
irq_req_t irq;
|
||||
config_req_t conf;
|
||||
window_handle_t win;
|
||||
|
||||
/* Is the device suspended, or in the process of
|
||||
* being removed? */
|
||||
u16 suspended:1;
|
||||
u16 _removed:1;
|
||||
|
||||
/* Flags whether io, irq, win configurations were
|
||||
* requested, and whether the configuration is "locked" */
|
||||
u16 _irq:1;
|
||||
u16 _io:1;
|
||||
u16 _win:4;
|
||||
u16 _locked:1;
|
||||
|
||||
/* Flag whether a "fuzzy" func_id based match is
|
||||
* allowed. */
|
||||
u16 allow_func_id_match:1;
|
||||
|
||||
/* information about this device */
|
||||
u8 has_manf_id:1;
|
||||
u8 has_card_id:1;
|
||||
u8 has_func_id:1;
|
||||
u16 has_manf_id:1;
|
||||
u16 has_card_id:1;
|
||||
u16 has_func_id:1;
|
||||
|
||||
u8 allow_func_id_match:1;
|
||||
u8 reserved:4;
|
||||
u16 reserved:3;
|
||||
|
||||
u8 func_id;
|
||||
u16 manf_id;
|
||||
|
@ -182,22 +178,24 @@ struct pcmcia_device {
|
|||
|
||||
char * prod_id[4];
|
||||
|
||||
struct device dev;
|
||||
|
||||
#ifdef CONFIG_PCMCIA_IOCTL
|
||||
/* device driver wanted by cardmgr */
|
||||
struct pcmcia_driver * cardmgr;
|
||||
#endif
|
||||
|
||||
struct device dev;
|
||||
/* data private to drivers */
|
||||
void *priv;
|
||||
};
|
||||
|
||||
#define to_pcmcia_dev(n) container_of(n, struct pcmcia_device, dev)
|
||||
#define to_pcmcia_drv(n) container_of(n, struct pcmcia_driver, drv)
|
||||
|
||||
#define handle_to_pdev(handle) (handle)
|
||||
#define handle_to_dev(handle) (handle->dev)
|
||||
|
||||
#define dev_to_instance(dev) (dev->instance)
|
||||
|
||||
/* error reporting */
|
||||
void cs_error(client_handle_t handle, int func, int ret);
|
||||
void cs_error(struct pcmcia_device *handle, int func, int ret);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _LINUX_DS_H */
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <linux/config.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/sched.h> /* task_struct, completion */
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include <pcmcia/cs_types.h>
|
||||
#include <pcmcia/cs.h>
|
||||
|
@ -146,14 +147,15 @@ extern struct pccard_resource_ops pccard_static_ops;
|
|||
/* !SS_CAP_STATIC_MAP */
|
||||
extern struct pccard_resource_ops pccard_nonstatic_ops;
|
||||
|
||||
/* static mem, dynamic IO sockets */
|
||||
extern struct pccard_resource_ops pccard_iodyn_ops;
|
||||
|
||||
/*
|
||||
* Calls to set up low-level "Socket Services" drivers
|
||||
*/
|
||||
struct pcmcia_socket;
|
||||
|
||||
typedef struct io_window_t {
|
||||
u_int Attributes;
|
||||
kio_addr_t BasePort, NumPorts;
|
||||
kio_addr_t InUse, Config;
|
||||
struct resource *res;
|
||||
} io_window_t;
|
||||
|
@ -162,7 +164,7 @@ typedef struct io_window_t {
|
|||
typedef struct window_t {
|
||||
u_short magic;
|
||||
u_short index;
|
||||
client_handle_t handle;
|
||||
struct pcmcia_device *handle;
|
||||
struct pcmcia_socket *sock;
|
||||
pccard_mem_map ctl;
|
||||
} window_t;
|
||||
|
@ -186,7 +188,6 @@ struct pcmcia_socket {
|
|||
u_short lock_count;
|
||||
pccard_mem_map cis_mem;
|
||||
void __iomem *cis_virt;
|
||||
struct config_t *config;
|
||||
struct {
|
||||
u_int AssignedIRQ;
|
||||
u_int Config;
|
||||
|
@ -241,7 +242,7 @@ struct pcmcia_socket {
|
|||
#endif
|
||||
|
||||
/* state thread */
|
||||
struct semaphore skt_sem; /* protects socket h/w state */
|
||||
struct mutex skt_mutex; /* protects socket h/w state */
|
||||
|
||||
struct task_struct *thread;
|
||||
struct completion thread_done;
|
||||
|
|
|
@ -57,18 +57,12 @@ static struct snd_card *card_list[SNDRV_CARDS];
|
|||
/*
|
||||
* prototypes
|
||||
*/
|
||||
static void pdacf_config(dev_link_t *link);
|
||||
static int pdacf_config(struct pcmcia_device *link);
|
||||
static void snd_pdacf_detach(struct pcmcia_device *p_dev);
|
||||
|
||||
static void pdacf_release(dev_link_t *link)
|
||||
static void pdacf_release(struct pcmcia_device *link)
|
||||
{
|
||||
if (link->state & DEV_CONFIG) {
|
||||
/* release cs resources */
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -76,7 +70,7 @@ static void pdacf_release(dev_link_t *link)
|
|||
*/
|
||||
static int snd_pdacf_free(struct snd_pdacf *pdacf)
|
||||
{
|
||||
dev_link_t *link = &pdacf->link;
|
||||
struct pcmcia_device *link = pdacf->p_dev;
|
||||
|
||||
pdacf_release(link);
|
||||
|
||||
|
@ -96,10 +90,9 @@ static int snd_pdacf_dev_free(struct snd_device *device)
|
|||
/*
|
||||
* snd_pdacf_attach - attach callback for cs
|
||||
*/
|
||||
static int snd_pdacf_attach(struct pcmcia_device *p_dev)
|
||||
static int snd_pdacf_probe(struct pcmcia_device *link)
|
||||
{
|
||||
int i;
|
||||
dev_link_t *link; /* Info for cardmgr */
|
||||
struct snd_pdacf *pdacf;
|
||||
struct snd_card *card;
|
||||
static struct snd_device_ops ops = {
|
||||
|
@ -139,7 +132,7 @@ static int snd_pdacf_attach(struct pcmcia_device *p_dev)
|
|||
pdacf->index = i;
|
||||
card_list[i] = card;
|
||||
|
||||
link = &pdacf->link;
|
||||
pdacf->p_dev = link;
|
||||
link->priv = pdacf;
|
||||
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
|
@ -156,13 +149,7 @@ static int snd_pdacf_attach(struct pcmcia_device *p_dev)
|
|||
link->conf.ConfigIndex = 1;
|
||||
link->conf.Present = PRESENT_OPTION;
|
||||
|
||||
/* Chain drivers */
|
||||
link->next = NULL;
|
||||
|
||||
link->handle = p_dev;
|
||||
pdacf_config(link);
|
||||
|
||||
return 0;
|
||||
return pdacf_config(link);
|
||||
}
|
||||
|
||||
|
||||
|
@ -209,9 +196,8 @@ static int snd_pdacf_assign_resources(struct snd_pdacf *pdacf, int port, int irq
|
|||
/*
|
||||
* snd_pdacf_detach - detach callback for cs
|
||||
*/
|
||||
static void snd_pdacf_detach(struct pcmcia_device *p_dev)
|
||||
static void snd_pdacf_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct snd_pdacf *chip = link->priv;
|
||||
|
||||
snd_printdd(KERN_DEBUG "pdacf_detach called\n");
|
||||
|
@ -230,13 +216,11 @@ static void snd_pdacf_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 pdacf_config(dev_link_t *link)
|
||||
static int pdacf_config(struct pcmcia_device *link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
struct snd_pdacf *pdacf = link->priv;
|
||||
tuple_t tuple;
|
||||
cisparse_t *parse = NULL;
|
||||
config_info_t conf;
|
||||
u_short buf[32];
|
||||
int last_fn, last_ret;
|
||||
|
||||
|
@ -244,7 +228,7 @@ static void pdacf_config(dev_link_t *link)
|
|||
parse = kmalloc(sizeof(*parse), GFP_KERNEL);
|
||||
if (! parse) {
|
||||
snd_printk(KERN_ERR "pdacf_config: cannot allocate\n");
|
||||
return;
|
||||
return -ENOMEM;
|
||||
}
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
tuple.Attributes = 0;
|
||||
|
@ -252,71 +236,51 @@ static void pdacf_config(dev_link_t *link)
|
|||
tuple.TupleDataMax = sizeof(buf);
|
||||
tuple.TupleOffset = 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, 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.ConfigIndex = 0x5;
|
||||
kfree(parse);
|
||||
|
||||
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
|
||||
link->conf.Vcc = conf.Vcc;
|
||||
|
||||
/* Configure card */
|
||||
link->state |= DEV_CONFIG;
|
||||
|
||||
CS_CHECK(RequestIO, pcmcia_request_io(handle, &link->io));
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
|
||||
CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
|
||||
if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq.AssignedIRQ) < 0)
|
||||
goto failed;
|
||||
|
||||
link->dev = &pdacf->node;
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
return;
|
||||
link->dev_node = &pdacf->node;
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
pcmcia_release_configuration(link->handle);
|
||||
pcmcia_release_io(link->handle, &link->io);
|
||||
pcmcia_release_irq(link->handle, &link->irq);
|
||||
pcmcia_disable_device(link);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
static int pdacf_suspend(struct pcmcia_device *dev)
|
||||
static int pdacf_suspend(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(dev);
|
||||
struct snd_pdacf *chip = link->priv;
|
||||
|
||||
snd_printdd(KERN_DEBUG "SUSPEND\n");
|
||||
link->state |= DEV_SUSPEND;
|
||||
if (chip) {
|
||||
snd_printdd(KERN_DEBUG "snd_pdacf_suspend calling\n");
|
||||
snd_pdacf_suspend(chip, PMSG_SUSPEND);
|
||||
}
|
||||
|
||||
snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n");
|
||||
if (link->state & DEV_CONFIG)
|
||||
pcmcia_release_configuration(link->handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pdacf_resume(struct pcmcia_device *dev)
|
||||
static int pdacf_resume(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(dev);
|
||||
struct snd_pdacf *chip = link->priv;
|
||||
|
||||
snd_printdd(KERN_DEBUG "RESUME\n");
|
||||
link->state &= ~DEV_SUSPEND;
|
||||
|
||||
snd_printdd(KERN_DEBUG "CARD_RESET\n");
|
||||
if (DEV_OK(link)) {
|
||||
snd_printdd(KERN_DEBUG "requestconfig...\n");
|
||||
pcmcia_request_configuration(link->handle, &link->conf);
|
||||
if (pcmcia_dev_present(link)) {
|
||||
if (chip) {
|
||||
snd_printdd(KERN_DEBUG "calling snd_pdacf_resume\n");
|
||||
snd_pdacf_resume(chip);
|
||||
|
@ -343,7 +307,7 @@ static struct pcmcia_driver pdacf_cs_driver = {
|
|||
.drv = {
|
||||
.name = "snd-pdaudiocf",
|
||||
},
|
||||
.probe = snd_pdacf_attach,
|
||||
.probe = snd_pdacf_probe,
|
||||
.remove = snd_pdacf_detach,
|
||||
.id_table = snd_pdacf_ids,
|
||||
#ifdef CONFIG_PM
|
||||
|
|
|
@ -116,7 +116,7 @@ struct snd_pdacf {
|
|||
void *pcm_area;
|
||||
|
||||
/* pcmcia stuff */
|
||||
dev_link_t link;
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
};
|
||||
|
||||
|
|
|
@ -59,15 +59,9 @@ static unsigned int card_alloc;
|
|||
|
||||
/*
|
||||
*/
|
||||
static void vxpocket_release(dev_link_t *link)
|
||||
static void vxpocket_release(struct pcmcia_device *link)
|
||||
{
|
||||
if (link->state & DEV_CONFIG) {
|
||||
/* release cs resources */
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -132,9 +126,9 @@ static struct snd_vx_hardware vxp440_hw = {
|
|||
/*
|
||||
* create vxpocket instance
|
||||
*/
|
||||
static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl)
|
||||
static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl,
|
||||
struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link; /* Info for cardmgr */
|
||||
struct vx_core *chip;
|
||||
struct snd_vxpocket *vxp;
|
||||
static struct snd_device_ops ops = {
|
||||
|
@ -154,7 +148,7 @@ static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl)
|
|||
|
||||
vxp = (struct snd_vxpocket *)chip;
|
||||
|
||||
link = &vxp->link;
|
||||
vxp->p_dev = link;
|
||||
link->priv = chip;
|
||||
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
|
@ -167,7 +161,6 @@ static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl)
|
|||
link->irq.Instance = chip;
|
||||
|
||||
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;
|
||||
|
@ -215,9 +208,8 @@ static int snd_vxpocket_assign_resources(struct vx_core *chip, int port, int irq
|
|||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static void vxpocket_config(dev_link_t *link)
|
||||
static int vxpocket_config(struct pcmcia_device *link)
|
||||
{
|
||||
client_handle_t handle = link->handle;
|
||||
struct vx_core *chip = link->priv;
|
||||
struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
|
||||
tuple_t tuple;
|
||||
|
@ -229,24 +221,24 @@ static void vxpocket_config(dev_link_t *link)
|
|||
parse = kmalloc(sizeof(*parse), GFP_KERNEL);
|
||||
if (! parse) {
|
||||
snd_printk(KERN_ERR "vx: cannot allocate\n");
|
||||
return;
|
||||
return -ENOMEM;
|
||||
}
|
||||
tuple.Attributes = 0;
|
||||
tuple.TupleData = (cisdata_t *)buf;
|
||||
tuple.TupleDataMax = sizeof(buf);
|
||||
tuple.TupleOffset = 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, 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];
|
||||
|
||||
/* redefine hardware record according to the VERSION1 string */
|
||||
tuple.DesiredTuple = CISTPL_VERS_1;
|
||||
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));
|
||||
if (! strcmp(parse->version_1.str + parse->version_1.ofs[1], "VX-POCKET")) {
|
||||
snd_printdd("VX-pocket is detected\n");
|
||||
} else {
|
||||
|
@ -257,67 +249,50 @@ static void vxpocket_config(dev_link_t *link)
|
|||
strcpy(chip->card->driver, vxp440_hw.name);
|
||||
}
|
||||
|
||||
/* Configure card */
|
||||
link->state |= DEV_CONFIG;
|
||||
CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
|
||||
CS_CHECK(RequestIO, pcmcia_request_io(handle, &link->io));
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
|
||||
|
||||
chip->dev = &handle_to_dev(link->handle);
|
||||
chip->dev = &handle_to_dev(link);
|
||||
snd_card_set_dev(chip->card, chip->dev);
|
||||
|
||||
if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0)
|
||||
goto failed;
|
||||
|
||||
link->dev = &vxp->node;
|
||||
link->state &= ~DEV_CONFIG_PENDING;
|
||||
link->dev_node = &vxp->node;
|
||||
kfree(parse);
|
||||
return;
|
||||
return 9;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link->handle, last_fn, last_ret);
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
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);
|
||||
kfree(parse);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
static int vxp_suspend(struct pcmcia_device *dev)
|
||||
static int vxp_suspend(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(dev);
|
||||
struct vx_core *chip = link->priv;
|
||||
|
||||
snd_printdd(KERN_DEBUG "SUSPEND\n");
|
||||
link->state |= DEV_SUSPEND;
|
||||
if (chip) {
|
||||
snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n");
|
||||
snd_vx_suspend(chip, PMSG_SUSPEND);
|
||||
}
|
||||
snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n");
|
||||
if (link->state & DEV_CONFIG)
|
||||
pcmcia_release_configuration(link->handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vxp_resume(struct pcmcia_device *dev)
|
||||
static int vxp_resume(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(dev);
|
||||
struct vx_core *chip = link->priv;
|
||||
|
||||
snd_printdd(KERN_DEBUG "RESUME\n");
|
||||
link->state &= ~DEV_SUSPEND;
|
||||
|
||||
snd_printdd(KERN_DEBUG "CARD_RESET\n");
|
||||
if (DEV_OK(link)) {
|
||||
if (pcmcia_dev_present(link)) {
|
||||
//struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
|
||||
snd_printdd(KERN_DEBUG "requestconfig...\n");
|
||||
pcmcia_request_configuration(link->handle, &link->conf);
|
||||
if (chip) {
|
||||
snd_printdd(KERN_DEBUG "calling snd_vx_resume\n");
|
||||
snd_vx_resume(chip);
|
||||
|
@ -333,7 +308,7 @@ static int vxp_resume(struct pcmcia_device *dev)
|
|||
|
||||
/*
|
||||
*/
|
||||
static int vxpocket_attach(struct pcmcia_device *p_dev)
|
||||
static int vxpocket_probe(struct pcmcia_device *p_dev)
|
||||
{
|
||||
struct snd_card *card;
|
||||
struct snd_vxpocket *vxp;
|
||||
|
@ -358,7 +333,7 @@ static int vxpocket_attach(struct pcmcia_device *p_dev)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
vxp = snd_vxpocket_new(card, ibl[i]);
|
||||
vxp = snd_vxpocket_new(card, ibl[i], p_dev);
|
||||
if (! vxp) {
|
||||
snd_card_free(card);
|
||||
return -ENODEV;
|
||||
|
@ -368,20 +343,13 @@ static int vxpocket_attach(struct pcmcia_device *p_dev)
|
|||
vxp->index = i;
|
||||
card_alloc |= 1 << i;
|
||||
|
||||
/* Chain drivers */
|
||||
vxp->link.next = NULL;
|
||||
vxp->p_dev = p_dev;
|
||||
|
||||
vxp->link.handle = p_dev;
|
||||
vxp->link.state |= DEV_PRESENT | DEV_CONFIG_PENDING;
|
||||
p_dev->instance = &vxp->link;
|
||||
vxpocket_config(&vxp->link);
|
||||
|
||||
return 0;
|
||||
return vxpocket_config(p_dev);
|
||||
}
|
||||
|
||||
static void vxpocket_detach(struct pcmcia_device *p_dev)
|
||||
static void vxpocket_detach(struct pcmcia_device *link)
|
||||
{
|
||||
dev_link_t *link = dev_to_instance(p_dev);
|
||||
struct snd_vxpocket *vxp;
|
||||
struct vx_core *chip;
|
||||
|
||||
|
@ -413,7 +381,7 @@ static struct pcmcia_driver vxp_cs_driver = {
|
|||
.drv = {
|
||||
.name = "snd-vxpocket",
|
||||
},
|
||||
.probe = vxpocket_attach,
|
||||
.probe = vxpocket_probe,
|
||||
.remove = vxpocket_detach,
|
||||
.id_table = vxp_ids,
|
||||
#ifdef CONFIG_PM
|
||||
|
|
|
@ -42,7 +42,7 @@ struct snd_vxpocket {
|
|||
int index; /* card index */
|
||||
|
||||
/* pcmcia stuff */
|
||||
dev_link_t link;
|
||||
struct pcmcia_device *p_dev;
|
||||
dev_node_t node;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue