// SPDX-License-Identifier: GPL-2.0 /* * IPWireless 3G PCMCIA Network Driver * * Original code * by Stephen Blackheath <stephen@blacksapphire.com>, * Ben Martel <benm@symmetric.co.nz> * * Copyrighted as follows: * Copyright (C) 2004 by Symmetric Systems Ltd (NZ) * * Various driver changes and rewrites, port to new kernels * Copyright (C) 2006-2007 Jiri Kosina * * Misc code cleanups and updates * Copyright (C) 2007 David Sterba
*/
ipw->common_memory = ioremap(p_dev->resource[2]->start,
resource_size(p_dev->resource[2])); if (!ipw->common_memory) {
ret = -ENOMEM; goto exit1;
} if (!request_mem_region(p_dev->resource[2]->start,
resource_size(p_dev->resource[2]),
IPWIRELESS_PCCARD_NAME)) {
ret = -EBUSY; goto exit2;
}
p_dev->resource[3]->flags |= WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM |
WIN_ENABLE;
p_dev->resource[3]->end = 0; /* this used to be 0x1000 */
ret = pcmcia_request_window(p_dev, p_dev->resource[3], 0); if (ret != 0) goto exit3;
ret = pcmcia_map_mem_page(p_dev, p_dev->resource[3], 0); if (ret != 0) goto exit3;
ipw->attr_memory = ioremap(p_dev->resource[3]->start,
resource_size(p_dev->resource[3])); if (!ipw->attr_memory) {
ret = -ENOMEM; goto exit3;
} if (!request_mem_region(p_dev->resource[3]->start,
resource_size(p_dev->resource[3]),
IPWIRELESS_PCCARD_NAME)) {
ret = -EBUSY; goto exit4;
}
ipw->network = ipwireless_network_create(ipw->hardware); if (!ipw->network) gotoexit;
ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network); if (!ipw->tty) gotoexit;
ipwireless_init_hardware_v2_v3(ipw->hardware);
/* * Do the RequestConfiguration last, because it enables interrupts. * Then we don't get any interrupts before we're ready for them.
*/
ret = pcmcia_enable_device(link); if (ret != 0) gotoexit;
return 0;
exit: if (ipw->common_memory) {
release_mem_region(link->resource[2]->start,
resource_size(link->resource[2]));
iounmap(ipw->common_memory);
} if (ipw->attr_memory) {
release_mem_region(link->resource[3]->start,
resource_size(link->resource[3]));
iounmap(ipw->attr_memory);
}
pcmcia_disable_device(link); return -1;
}
/* * ipwireless_attach() creates an "instance" of the driver, allocating * local data structures for one device (one interface). The device * is registered with Card Services. * * The pcmcia_device structure is initialized, but we don't actually * configure the card at this point -- we wait until we receive a * card insertion event.
*/ staticint ipwireless_attach(struct pcmcia_device *link)
{ struct ipw_dev *ipw; int ret;
ipw = kzalloc(sizeof(struct ipw_dev), GFP_KERNEL); if (!ipw) return -ENOMEM;
ipw->link = link;
link->priv = ipw;
ipw->hardware = ipwireless_hardware_create(); if (!ipw->hardware) {
kfree(ipw); return -ENOMEM;
} /* RegisterClient will call config_ipwireless */
ret = config_ipwireless(ipw);
if (ret != 0) {
ipwireless_detach(link); return ret;
}
return 0;
}
/* * This deletes a driver "instance". The device is de-registered with * Card Services. If it has been released, all local data structures * are freed. Otherwise, the structures will be freed when the device * is released.
*/ staticvoid ipwireless_detach(struct pcmcia_device *link)
{ struct ipw_dev *ipw = link->priv;
release_ipwireless(ipw);
if (ipw->tty != NULL)
ipwireless_tty_free(ipw->tty); if (ipw->network != NULL)
ipwireless_network_free(ipw->network); if (ipw->hardware != NULL)
ipwireless_hardware_free(ipw->hardware);
kfree(ipw);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.