Commit 340fc58c authored by Linus Torvalds's avatar Linus Torvalds

Merge

parents da2def39 0848d6f4
......@@ -36,7 +36,7 @@ obj-$(CONFIG_FUSION) += message/
obj-$(CONFIG_IEEE1394) += ieee1394/
obj-y += cdrom/
obj-$(CONFIG_MTD) += mtd/
obj-$(CONFIG_PCMCIA) += pcmcia/
obj-$(CONFIG_PCCARD) += pcmcia/
obj-$(CONFIG_DIO) += dio/
obj-$(CONFIG_SBUS) += sbus/
obj-$(CONFIG_ZORRO) += zorro/
......
......@@ -5,30 +5,24 @@
# by the integrated kernel driver.
#
menu "PCMCIA/CardBus support"
menu "PCCARD (PCMCIA/CardBus) support"
depends on HOTPLUG
config PCMCIA
tristate "PCMCIA/CardBus support"
config PCCARD
tristate "PCCard (PCMCIA/CardBus) support"
---help---
Say Y here if you want to attach PCMCIA- or PC-cards to your Linux
computer. These are credit-card size devices such as network cards,
modems or hard drives often used with laptops computers. There are
actually two varieties of these cards: the older 16 bit PCMCIA cards
and the newer 32 bit CardBus cards. If you want to use CardBus
cards, you need to say Y here and also to "CardBus support" below.
To use your PC-cards, you will need supporting software from David
Hinds' pcmcia-cs package (see the file <file:Documentation/Changes>
for location). Please also read the PCMCIA-HOWTO, available from
<http://www.tldp.org/docs.html#howto>.
and the newer 32 bit CardBus cards.
To compile this driver as modules, choose M here: the
modules will be called pcmcia_core and ds.
module will be called pcmcia_core.
config PCMCIA_DEBUG
bool "Enable PCMCIA debugging"
depends on PCMCIA != n
bool "Enable PCCARD debugging"
depends on PCCARD != n
help
Say Y here to enable PCMCIA subsystem debugging. You
will need to choose the debugging level either via the
......@@ -45,29 +39,69 @@ config PCMCIA_DEBUG
In all the above examples, N is the debugging verbosity
level.
config YENTA
tristate "CardBus yenta-compatible bridge support"
depends on PCMCIA && PCI
config PCMCIA_OBSOLETE
bool "Enable obsolete PCCARD code"
depends on PCCARD != n
help
Say Y here to enable some code found in the PCCARD subsystem
which has no in-kernel usage, but might be needed for certain
external PCMCIA drivers. If you do need to say Y here so that
one such driver compiles and/or works correctly, please report
this to linux-pcmcia <at> lists.infradead.org
If unsure, say N
config PCMCIA
tristate "16-bit PCMCIA support"
depends on PCCARD
default y
---help---
This option enables support for 16-bit PCMCIA cards. Most older
PC-cards are such 16-bit PCMCIA cards, so unless you know you're
only using 32-bit CardBus cards, say Y or M here.
To use 16-bit PCMCIA cards, you will need supporting software from
David Hinds' pcmcia-cs package (see the file <file:Documentation/Changes>
for location). Please also read the PCMCIA-HOWTO, available from
<http://www.tldp.org/docs.html#howto>.
To compile this driver as modules, choose M here: the
module will be called pcmcia.
If unsure, say Y.
config CARDBUS
bool "32-bit CardBus support"
depends on PCCARD && PCI
default y
---help---
CardBus is a bus mastering architecture for PC-cards, which allows
for 32 bit PC-cards (the original PCMCIA standard specifies only
a 16 bit wide bus). Many newer PC-cards are actually CardBus cards.
This option enables support for CardBus PC Cards, as well as support
for CardBus host bridges. Virtually all modern PCMCIA bridges are
CardBus compatible. A "bridge" is the hardware inside your computer
that PCMCIA cards are plugged into.
To use your PC-cards, you will need supporting software from David
Hinds' pcmcia-cs package (see the file <file:Documentation/Changes>
for location).
To use 32 bit PC-cards, you also need a CardBus compatible host
bridge. Virtually all modern PCMCIA bridges do this, and most of
them are "yenta-compatible", so say Y or M there, too.
If unsure, say Y.
config CARDBUS
bool
depends on YENTA
default y if YENTA
comment "PC-card bridges"
config YENTA
tristate "CardBus yenta-compatible bridge support"
depends on PCCARD && PCI
#fixme: remove dependendcy on CARDBUS
depends on CARDBUS
---help---
This option enables support for CardBus host bridges. Virtually
all modern PCMCIA bridges are CardBus compatible. A "bridge" is
the hardware inside your computer that PCMCIA cards are plugged
into.
To compile this driver as modules, choose M here: the
module will be called yenta_socket.
If unsure, say Y.
config PD6729
tristate "Cirrus PD6729 compatible bridge support"
......
......@@ -6,7 +6,16 @@ ifeq ($(CONFIG_PCMCIA_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG
endif
obj-$(CONFIG_PCMCIA) += pcmcia_core.o ds.o
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 bulkmem.o pcmcia_compat.o
obj-$(CONFIG_PCMCIA) += pcmcia.o
# socket drivers
obj-$(CONFIG_YENTA) += yenta_socket.o
obj-$(CONFIG_PD6729) += pd6729.o
......@@ -20,9 +29,6 @@ obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_core.o pxa2xx_cs.o
obj-$(CONFIG_M32R_PCC) += m32r_pcc.o
obj-$(CONFIG_M32R_CFC) += m32r_cfc.o
pcmcia_core-y += cistpl.o rsrc_mgr.o bulkmem.o cs.o socket_sysfs.o
pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o
sa11xx_core-y += soc_common.o sa11xx_base.o
pxa2xx_core-y += soc_common.o pxa2xx_base.o
......
This diff is collapsed.
......@@ -376,12 +376,8 @@ int verify_cis_cache(struct pcmcia_socket *s)
======================================================================*/
int pcmcia_replace_cis(client_handle_t handle, cisdump_t *cis)
int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis)
{
struct pcmcia_socket *s;
if (CHECK_HANDLE(handle))
return CS_BAD_HANDLE;
s = SOCKET(handle);
if (s->fake_cis != NULL) {
kfree(s->fake_cis);
s->fake_cis = NULL;
......@@ -414,14 +410,12 @@ typedef struct tuple_flags {
#define MFC_FN(f) (((tuple_flags *)(&(f)))->mfc_fn)
#define SPACE(f) (((tuple_flags *)(&(f)))->space)
int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple);
int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int func, tuple_t *tuple);
int pcmcia_get_first_tuple(client_handle_t handle, tuple_t *tuple)
int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple)
{
struct pcmcia_socket *s;
if (CHECK_HANDLE(handle))
if (!s)
return CS_BAD_HANDLE;
s = SOCKET(handle);
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
tuple->TupleLink = tuple->Flags = 0;
......@@ -443,16 +437,17 @@ int pcmcia_get_first_tuple(client_handle_t handle, tuple_t *tuple)
!(tuple->Attributes & TUPLE_RETURN_COMMON)) {
cisdata_t req = tuple->DesiredTuple;
tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
if (pcmcia_get_next_tuple(handle, tuple) == CS_SUCCESS) {
if (pccard_get_next_tuple(s, function, tuple) == CS_SUCCESS) {
tuple->DesiredTuple = CISTPL_LINKTARGET;
if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
if (pccard_get_next_tuple(s, function, tuple) != CS_SUCCESS)
return CS_NO_MORE_ITEMS;
} else
tuple->CISOffset = tuple->TupleLink = 0;
tuple->DesiredTuple = req;
}
return pcmcia_get_next_tuple(handle, tuple);
return pccard_get_next_tuple(s, function, tuple);
}
EXPORT_SYMBOL(pccard_get_first_tuple);
static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
{
......@@ -494,15 +489,13 @@ static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
return -1;
}
int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple)
int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple)
{
struct pcmcia_socket *s;
u_char link[2], tmp;
int ofs, i, attr;
if (CHECK_HANDLE(handle))
if (!s)
return CS_BAD_HANDLE;
s = SOCKET(handle);
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
......@@ -554,14 +547,14 @@ int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple)
case CISTPL_LONGLINK_MFC:
tuple->LinkOffset = ofs + 3;
LINK_SPACE(tuple->Flags) = attr;
if (handle->Function == BIND_FN_ALL) {
if (function == BIND_FN_ALL) {
/* Follow all the MFC links */
read_cis_cache(s, attr, ofs+2, 1, &tmp);
MFC_FN(tuple->Flags) = tmp;
} else {
/* Follow exactly one of the links */
MFC_FN(tuple->Flags) = 1;
tuple->LinkOffset += handle->Function * 5;
tuple->LinkOffset += function * 5;
}
break;
case CISTPL_NO_LINK:
......@@ -589,21 +582,19 @@ int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple)
tuple->CISOffset = ofs + 2;
return CS_SUCCESS;
}
EXPORT_SYMBOL(pccard_get_next_tuple);
/*====================================================================*/
#define _MIN(a, b) (((a) < (b)) ? (a) : (b))
int pcmcia_get_tuple_data(client_handle_t handle, tuple_t *tuple)
int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple)
{
struct pcmcia_socket *s;
u_int len;
if (CHECK_HANDLE(handle))
if (!s)
return CS_BAD_HANDLE;
s = SOCKET(handle);
if (tuple->TupleLink < tuple->TupleOffset)
return CS_NO_MORE_ITEMS;
len = tuple->TupleLink - tuple->TupleOffset;
......@@ -615,6 +606,8 @@ int pcmcia_get_tuple_data(client_handle_t handle, tuple_t *tuple)
_MIN(len, tuple->TupleDataMax), tuple->TupleData);
return CS_SUCCESS;
}
EXPORT_SYMBOL(pccard_get_tuple_data);
/*======================================================================
......@@ -1320,7 +1313,7 @@ static int parse_format(tuple_t *tuple, cistpl_format_t *fmt)
/*====================================================================*/
int pcmcia_parse_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
int pccard_parse_tuple(tuple_t *tuple, cisparse_t *parse)
{
int ret = CS_SUCCESS;
......@@ -1401,6 +1394,7 @@ int pcmcia_parse_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse
}
return ret;
}
EXPORT_SYMBOL(pccard_parse_tuple);
/*======================================================================
......@@ -1408,7 +1402,7 @@ int pcmcia_parse_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse
======================================================================*/
int read_tuple(client_handle_t handle, cisdata_t code, void *parse)
int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse)
{
tuple_t tuple;
cisdata_t *buf;
......@@ -1419,18 +1413,19 @@ int read_tuple(client_handle_t handle, cisdata_t code, void *parse)
return CS_OUT_OF_RESOURCE;
tuple.DesiredTuple = code;
tuple.Attributes = TUPLE_RETURN_COMMON;
ret = pcmcia_get_first_tuple(handle, &tuple);
ret = pccard_get_first_tuple(s, function, &tuple);
if (ret != CS_SUCCESS) goto done;
tuple.TupleData = buf;
tuple.TupleOffset = 0;
tuple.TupleDataMax = 255;
ret = pcmcia_get_tuple_data(handle, &tuple);
ret = pccard_get_tuple_data(s, &tuple);
if (ret != CS_SUCCESS) goto done;
ret = pcmcia_parse_tuple(handle, &tuple, parse);
ret = pccard_parse_tuple(&tuple, parse);
done:
kfree(buf);
return ret;
}
EXPORT_SYMBOL(pccard_read_tuple);
/*======================================================================
......@@ -1442,14 +1437,15 @@ int read_tuple(client_handle_t handle, cisdata_t code, void *parse)
======================================================================*/
int pcmcia_validate_cis(client_handle_t handle, cisinfo_t *info)
int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, cisinfo_t *info)
{
tuple_t *tuple;
cisparse_t *p;
int ret, reserved, dev_ok = 0, ident_ok = 0;
if (CHECK_HANDLE(handle))
if (!s)
return CS_BAD_HANDLE;
tuple = kmalloc(sizeof(*tuple), GFP_KERNEL);
if (tuple == NULL)
return CS_OUT_OF_RESOURCE;
......@@ -1462,30 +1458,30 @@ int pcmcia_validate_cis(client_handle_t handle, cisinfo_t *info)
info->Chains = reserved = 0;
tuple->DesiredTuple = RETURN_FIRST_TUPLE;
tuple->Attributes = TUPLE_RETURN_COMMON;
ret = pcmcia_get_first_tuple(handle, tuple);
ret = pccard_get_first_tuple(s, function, tuple);
if (ret != CS_SUCCESS)
goto done;
/* First tuple should be DEVICE; we should really have either that
or a CFTABLE_ENTRY of some sort */
if ((tuple->TupleCode == CISTPL_DEVICE) ||
(read_tuple(handle, CISTPL_CFTABLE_ENTRY, p) == CS_SUCCESS) ||
(read_tuple(handle, CISTPL_CFTABLE_ENTRY_CB, p) == CS_SUCCESS))
(pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY, p) == CS_SUCCESS) ||
(pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY_CB, p) == CS_SUCCESS))
dev_ok++;
/* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
tuple, for card identification. Certain old D-Link and Linksys
cards have only a broken VERS_2 tuple; hence the bogus test. */
if ((read_tuple(handle, CISTPL_MANFID, p) == CS_SUCCESS) ||
(read_tuple(handle, CISTPL_VERS_1, p) == CS_SUCCESS) ||
(read_tuple(handle, CISTPL_VERS_2, p) != CS_NO_MORE_ITEMS))
if ((pccard_read_tuple(s, function, CISTPL_MANFID, p) == CS_SUCCESS) ||
(pccard_read_tuple(s, function, CISTPL_VERS_1, p) == CS_SUCCESS) ||
(pccard_read_tuple(s, function, CISTPL_VERS_2, p) != CS_NO_MORE_ITEMS))
ident_ok++;
if (!dev_ok && !ident_ok)
goto done;
for (info->Chains = 1; info->Chains < MAX_TUPLES; info->Chains++) {
ret = pcmcia_get_next_tuple(handle, tuple);
ret = pccard_get_next_tuple(s, function, tuple);
if (ret != CS_SUCCESS) break;
if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) ||
((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) ||
......@@ -1501,4 +1497,4 @@ int pcmcia_validate_cis(client_handle_t handle, cisinfo_t *info)
kfree(p);
return CS_SUCCESS;
}
EXPORT_SYMBOL(pccard_validate_cis);
This diff is collapsed.
......@@ -21,14 +21,6 @@
#include <linux/config.h>
#define ERASEQ_MAGIC 0xFA67
typedef struct eraseq_t {
u_short eraseq_magic;
client_handle_t handle;
int count;
eraseq_entry_t *entry;
} eraseq_t;
#define CLIENT_MAGIC 0x51E6
typedef struct client_t {
u_short client_magic;
......@@ -42,9 +34,6 @@ typedef struct client_t {
event_callback_args_t *);
event_callback_args_t event_callback_args;
struct client_t *next;
u_int mtd_count;
wait_queue_head_t mtd_req;
erase_busy_t erase_busy;
} client_t;
/* Flags in client state */
......@@ -157,27 +146,7 @@ void write_cis_mem(struct pcmcia_socket *s, int attr,
void release_cis_mem(struct pcmcia_socket *s);
void destroy_cis_cache(struct pcmcia_socket *s);
int verify_cis_cache(struct pcmcia_socket *s);
void preload_cis_cache(struct pcmcia_socket *s);
int get_first_tuple(client_handle_t handle, tuple_t *tuple);
int get_next_tuple(client_handle_t handle, tuple_t *tuple);
int get_tuple_data(client_handle_t handle, tuple_t *tuple);
int parse_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse);
int validate_cis(client_handle_t handle, cisinfo_t *info);
int replace_cis(client_handle_t handle, cisdump_t *cis);
int read_tuple(client_handle_t handle, cisdata_t code, void *parse);
/* In bulkmem.c */
int get_first_region(client_handle_t handle, region_info_t *rgn);
int get_next_region(client_handle_t handle, region_info_t *rgn);
int register_mtd(client_handle_t handle, mtd_reg_t *reg);
int register_erase_queue(client_handle_t *handle, eraseq_hdr_t *header);
int deregister_erase_queue(eraseq_handle_t eraseq);
int check_erase_queue(eraseq_handle_t eraseq);
int open_memory(client_handle_t *handle, open_mem_t *open);
int close_memory(memory_handle_t handle);
int read_memory(memory_handle_t handle, mem_op_t *req, caddr_t buf);
int write_memory(memory_handle_t handle, mem_op_t *req, caddr_t buf);
int copy_memory(memory_handle_t handle, copy_op_t *req);
int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse);
/* In rsrc_mgr */
void pcmcia_validate_mem(struct pcmcia_socket *s);
......@@ -198,6 +167,11 @@ extern struct class_interface pccard_sysfs_interface;
/* In cs.c */
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_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);
#define cs_socket_name(skt) ((skt)->dev.class_id)
......
......@@ -75,7 +75,7 @@ MODULE_DESCRIPTION("PCMCIA Driver Services");
MODULE_LICENSE("Dual MPL/GPL");
#ifdef DEBUG
static int pc_debug;
int pc_debug;
module_param(pc_debug, int, 0644);
......@@ -167,9 +167,6 @@ static int pcmcia_bind_device(bind_req_t *req)
client->Socket = s;
client->Function = req->Function;
client->state = CLIENT_UNBOUND;
client->erase_busy.next = &client->erase_busy;
client->erase_busy.prev = &client->erase_busy;
init_waitqueue_head(&client->mtd_req);
client->next = s->clients;
s->clients = client;
ds_dbg(1, "%s: bind_device(): client 0x%p, dev %s\n",
......@@ -630,6 +627,8 @@ static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
/*====================================================================*/
extern struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s);
static int get_device_info(struct pcmcia_bus_socket *s, bind_info_t *bind_info, int first)
{
socket_bind_t *b;
......@@ -643,7 +642,7 @@ static int get_device_info(struct pcmcia_bus_socket *s, bind_info_t *bind_info,
{
struct pci_bus *bus;
bus = pcmcia_lookup_bus(s->handle);
bus = pcmcia_lookup_bus(s->parent);
if (bus) {
struct list_head *list;
struct pci_dev *dev = NULL;
......@@ -885,6 +884,10 @@ static u_int ds_poll(struct file *file, poll_table *wait)
/*====================================================================*/
extern int pcmcia_adjust_resource_info(adjust_t *adj);
extern int pccard_get_next_region(struct pcmcia_socket *s, region_info_t *rgn);
extern int pccard_get_first_region(struct pcmcia_socket *s, region_info_t *rgn);
static int ds_ioctl(struct inode * inode, struct file * file,
u_int cmd, u_long arg)
{
......@@ -933,39 +936,47 @@ static int ds_ioctl(struct inode * inode, struct file * file,
switch (cmd) {
case DS_ADJUST_RESOURCE_INFO:
ret = pcmcia_adjust_resource_info(s->handle, &buf.adjust);
ret = pcmcia_adjust_resource_info(&buf.adjust);
break;
case DS_GET_CARD_SERVICES_INFO:
ret = pcmcia_get_card_services_info(&buf.servinfo);
break;
case DS_GET_CONFIGURATION_INFO:
ret = pcmcia_get_configuration_info(s->handle, &buf.config);
if (buf.config.Function &&
(buf.config.Function >= s->parent->functions))
ret = CS_BAD_ARGS;
else
ret = pccard_get_configuration_info(s->parent, buf.config.Function, &buf.config);
break;
case DS_GET_FIRST_TUPLE:
pcmcia_validate_mem(s->parent);
ret = pcmcia_get_first_tuple(s->handle, &buf.tuple);
ret = pccard_get_first_tuple(s->parent, BIND_FN_ALL, &buf.tuple);
break;
case DS_GET_NEXT_TUPLE:
ret = pcmcia_get_next_tuple(s->handle, &buf.tuple);
ret = pccard_get_next_tuple(s->parent, BIND_FN_ALL, &buf.tuple);
break;
case DS_GET_TUPLE_DATA:
buf.tuple.TupleData = buf.tuple_parse.data;
buf.tuple.TupleDataMax = sizeof(buf.tuple_parse.data);
ret = pcmcia_get_tuple_data(s->handle, &buf.tuple);
ret = pccard_get_tuple_data(s->parent, &buf.tuple);
break;
case DS_PARSE_TUPLE:
buf.tuple.TupleData = buf.tuple_parse.data;
ret = pcmcia_parse_tuple(s->handle, &buf.tuple, &buf.tuple_parse.parse);
ret = pccard_parse_tuple(&buf.tuple, &buf.tuple_parse.parse);
break;
case DS_RESET_CARD:
ret = pcmcia_reset_card(s->handle, NULL);
ret = pccard_reset_card(s->parent);
break;
case DS_GET_STATUS:
ret = pcmcia_get_status(s->handle, &buf.status);
if (buf.status.Function &&
(buf.status.Function >= s->parent->functions))
ret = CS_BAD_ARGS;
else
ret = pccard_get_status(s->parent, buf.status.Function, &buf.status);
break;
case DS_VALIDATE_CIS:
pcmcia_validate_mem(s->parent);
ret = pcmcia_validate_cis(s->handle, &buf.cisinfo);
ret = pccard_validate_cis(s->parent, BIND_FN_ALL, &buf.cisinfo);
break;
case DS_SUSPEND_CARD:
ret = pcmcia_suspend_card(s->parent);
......@@ -982,27 +993,30 @@ static int ds_ioctl(struct inode * inode, struct file * file,
case DS_ACCESS_CONFIGURATION_REGISTER:
if ((buf.conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN))
return -EPERM;
ret = pcmcia_access_configuration_register(s->handle, &buf.conf_reg);
if (buf.conf_reg.Function &&
(buf.conf_reg.Function >= s->parent->functions))
ret = CS_BAD_ARGS;
else
ret = pccard_access_configuration_register(s->parent, buf.conf_reg.Function, &buf.conf_reg);
break;
case DS_GET_FIRST_REGION:
ret = pcmcia_get_first_region(s->handle, &buf.region);
ret = pccard_get_first_region(s->parent, &buf.region);
break;
case DS_GET_NEXT_REGION:
ret = pcmcia_get_next_region(s->handle, &buf.region);
ret = pccard_get_next_region(s->parent, &buf.region);
break;
case DS_GET_FIRST_WINDOW:
buf.win_info.handle = (window_handle_t)s->handle;
ret = pcmcia_get_first_window(&buf.win_info.handle, &buf.win_info.window);
ret = pcmcia_get_window(s->parent, &buf.win_info.handle, 0, &buf.win_info.window);
break;
case DS_GET_NEXT_WINDOW:
ret = pcmcia_get_next_window(&buf.win_info.handle, &buf.win_info.window);
ret = pcmcia_get_window(s->parent, &buf.win_info.handle, buf.win_info.handle->index + 1, &buf.win_info.window);
break;
case DS_GET_MEM_PAGE:
ret = pcmcia_get_mem_page(buf.win_info.handle,
&buf.win_info.map);
break;
case DS_REPLACE_CIS:
ret = pcmcia_replace_cis(s->handle, &buf.cisdump);
ret = pcmcia_replace_cis(s->parent, &buf.cisdump);
break;
case DS_BIND_REQUEST:
if (!capable(CAP_SYS_ADMIN)) return -EPERM;
......@@ -1244,3 +1258,5 @@ static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info)
return cmp.drv;
return NULL;
}
MODULE_ALIAS("ds");
/*
* 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/version.h>
#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(client_handle_t handle, tuple_t *tuple)
{
struct pcmcia_socket *s;
if (CHECK_HANDLE(handle))
return CS_BAD_HANDLE;
s = SOCKET(handle);
return pccard_get_first_tuple(s, handle->Function, tuple);
}
EXPORT_SYMBOL(pcmcia_get_first_tuple);
int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple)
{
struct pcmcia_socket *s;
if (CHECK_HANDLE(handle))
return CS_BAD_HANDLE;
s = SOCKET(handle);
return pccard_get_next_tuple(s, handle->Function, tuple);
}
EXPORT_SYMBOL(pcmcia_get_next_tuple);
int pcmcia_get_tuple_data(client_handle_t handle, tuple_t *tuple)
{
struct pcmcia_socket *s;
if (CHECK_HANDLE(handle))
return CS_BAD_HANDLE;
s = SOCKET(handle);
return pccard_get_tuple_data(s, tuple);
}
EXPORT_SYMBOL(pcmcia_get_tuple_data);
int pcmcia_parse_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
{
return pccard_parse_tuple(tuple, parse);
}
EXPORT_SYMBOL(pcmcia_parse_tuple);
int pcmcia_validate_cis(client_handle_t handle, cisinfo_t *info)
{
struct pcmcia_socket *s;
if (CHECK_HANDLE(handle))
return CS_BAD_HANDLE;
s = SOCKET(handle);
return pccard_validate_cis(s, handle->Function, info);
}
EXPORT_SYMBOL(pcmcia_validate_cis);
int pcmcia_get_configuration_info(client_handle_t handle,
config_info_t *config)
{
struct pcmcia_socket *s;
if ((CHECK_HANDLE(handle)) || !config)
return CS_BAD_HANDLE;
s = SOCKET(handle);
if (!s)
return CS_BAD_HANDLE;
return pccard_get_configuration_info(s, handle->Function, config);
}
EXPORT_SYMBOL(pcmcia_get_configuration_info);
int pcmcia_reset_card(client_handle_t handle, client_req_t *req)
{
struct pcmcia_socket *skt;
if (CHECK_HANDLE(handle))
return CS_BAD_HANDLE;
skt = SOCKET(handle);
if (!skt)
return CS_BAD_HANDLE;
return pccard_reset_card(skt);
}
EXPORT_SYMBOL(pcmcia_reset_card);
int pcmcia_get_status(client_handle_t handle, cs_status_t *status)
{
struct pcmcia_socket *s;
if (CHECK_HANDLE(handle))
return CS_BAD_HANDLE;
s = SOCKET(handle);
return pccard_get_status(s, handle->Function, status);
}
EXPORT_SYMBOL(pcmcia_get_status);
int pcmcia_access_configuration_register(client_handle_t handle,
conf_reg_t *reg)
{
struct pcmcia_socket *s;
if (CHECK_HANDLE(handle))
return CS_BAD_HANDLE;
s = SOCKET(handle);
return pccard_access_configuration_register(s, handle->Function, reg);
}
EXPORT_SYMBOL(pcmcia_access_configuration_register);
#ifdef CONFIG_PCMCIA_OBSOLETE
int pcmcia_get_first_window(window_handle_t *win, win_req_t *req)
{
if ((win == NULL) || ((*win)->magic != WINDOW_MAGIC))
return CS_BAD_HANDLE;
return pcmcia_get_window(((client_handle_t)*win)->Socket, win, 0, req);
}
EXPORT_SYMBOL(pcmcia_get_first_window);
int pcmcia_get_next_window(window_handle_t *win, win_req_t *req)
{
if ((win == NULL) || ((*win)->magic != WINDOW_MAGIC))
return CS_BAD_HANDLE;
return pcmcia_get_window((*win)->sock, win, (*win)->index+1, req);
}
EXPORT_SYMBOL(pcmcia_get_next_window);
#endif
......@@ -307,7 +307,7 @@ static int readable(struct pcmcia_socket *s, struct resource *res, cisinfo_t *in
s->cis_mem.res = res;
s->cis_virt = ioremap(res->start, s->map_size);
if (s->cis_virt) {
ret = pcmcia_validate_cis(s->clients, info);
ret = pccard_validate_cis(s, BIND_FN_ALL, info);
/* invalidate mapping and CIS cache */
iounmap(s->cis_virt);
s->cis_virt = NULL;
......@@ -973,11 +973,8 @@ static int adjust_irq(adjust_t *adj)
/*====================================================================*/
int pcmcia_adjust_resource_info(client_handle_t handle, adjust_t *adj)
int pcmcia_adjust_resource_info(adjust_t *adj)
{
if (CHECK_HANDLE(handle))
return CS_BAD_HANDLE;
switch (adj->Resource) {
case RES_MEMORY_RANGE:
return adjust_memory(adj);
......@@ -991,6 +988,7 @@ int pcmcia_adjust_resource_info(client_handle_t handle, adjust_t *adj)
}
return CS_UNSUPPORTED_FUNCTION;
}
EXPORT_SYMBOL(pcmcia_adjust_resource_info);
/*====================================================================*/
......
......@@ -53,155 +53,7 @@ typedef struct region_info_t {
#define REGION_BAR_MASK 0xe000
#define REGION_BAR_SHIFT 13
/* For OpenMemory */
typedef struct open_mem_t {
u_int Attributes;
u_int Offset;
} open_mem_t;
/* Attributes for OpenMemory */
#define MEMORY_TYPE 0x0001
#define MEMORY_TYPE_CM 0x0000
#define MEMORY_TYPE_AM 0x0001
#define MEMORY_EXCLUSIVE 0x0002
#define MEMORY_PREFETCH 0x0008
#define MEMORY_CACHEABLE 0x0010
#define MEMORY_BAR_MASK 0xe000
#define MEMORY_BAR_SHIFT 13
typedef struct eraseq_entry_t {
memory_handle_t Handle;
u_char State;
u_int Size;
u_int Offset;
void *Optional;
} eraseq_entry_t;
typedef struct eraseq_hdr_t {
int QueueEntryCnt;
eraseq_entry_t *QueueEntryArray;
} eraseq_hdr_t;
#define ERASE_QUEUED 0x00
#define ERASE_IN_PROGRESS(n) (((n) > 0) && ((n) < 0x80))
#define ERASE_IDLE 0xff
#define ERASE_PASSED 0xe0
#define ERASE_FAILED 0xe1
#define ERASE_MISSING 0x80
#define ERASE_MEDIA_WRPROT 0x84
#define ERASE_NOT_ERASABLE 0x85
#define ERASE_BAD_OFFSET 0xc1
#define ERASE_BAD_TECH 0xc2
#define ERASE_BAD_SOCKET 0xc3
#define ERASE_BAD_VCC 0xc4
#define ERASE_BAD_VPP 0xc5
#define ERASE_BAD_SIZE 0xc6
/* For CopyMemory */
typedef struct copy_op_t {
u_int Attributes;
u_int SourceOffset;
u_int DestOffset;
u_int Count;
} copy_op_t;
/* For ReadMemory and WriteMemory */
typedef struct mem_op_t {
u_int Attributes;
u_int Offset;
u_int Count;
} mem_op_t;
#define MEM_OP_BUFFER 0x01
#define MEM_OP_BUFFER_USER 0x00
#define MEM_OP_BUFFER_KERNEL 0x01
#define MEM_OP_DISABLE_ERASE 0x02
#define MEM_OP_VERIFY 0x04
/* For RegisterMTD */
typedef struct mtd_reg_t {
u_int Attributes;
u_int Offset;
u_long MediaID;
} mtd_reg_t;
/*
* Definitions for MTD requests
*/
typedef struct mtd_request_t {
u_int SrcCardOffset;
u_int DestCardOffset;
u_int TransferLength;
u_int Function;
u_long MediaID;
u_int Status;
u_int Timeout;
} mtd_request_t;
/* Fields in MTD Function */
#define MTD_REQ_ACTION 0x003
#define MTD_REQ_ERASE 0x000
#define MTD_REQ_READ 0x001
#define MTD_REQ_WRITE 0x002
#define MTD_REQ_COPY 0x003
#define MTD_REQ_NOERASE 0x004
#define MTD_REQ_VERIFY 0x008
#define MTD_REQ_READY 0x010
#define MTD_REQ_TIMEOUT 0x020
#define MTD_REQ_LAST 0x040
#define MTD_REQ_FIRST 0x080
#define MTD_REQ_KERNEL 0x100
/* Status codes */
#define MTD_WAITREQ 0x00
#define MTD_WAITTIMER 0x01
#define MTD_WAITRDY 0x02
#define MTD_WAITPOWER 0x03
/*
* Definitions for MTD helper functions
*/
/* For MTDModifyWindow */
typedef struct mtd_mod_win_t {
u_int Attributes;
u_int AccessSpeed;
u_int CardOffset;
} mtd_mod_win_t;
/* For MTDSetVpp */
typedef struct mtd_vpp_req_t {
u_char Vpp1, Vpp2;
} mtd_vpp_req_t;
/* For MTDRDYMask */
typedef struct mtd_rdy_req_t {
u_int Mask;
} mtd_rdy_req_t;
enum mtd_helper {
MTDRequestWindow, MTDModifyWindow, MTDReleaseWindow,
MTDSetVpp, MTDRDYMask
};
#ifdef IN_CARD_SERVICES
extern int MTDHelperEntry(int func, void *a1, void *a2);
#else
extern int MTDHelperEntry(int func, ...);
#endif
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_register_mtd(client_handle_t handle, mtd_reg_t *reg);
int pcmcia_register_erase_queue(client_handle_t *handle, eraseq_hdr_t *header, eraseq_handle_t *e);
int pcmcia_deregister_erase_queue(eraseq_handle_t eraseq);
int pcmcia_check_erase_queue(eraseq_handle_t eraseq);
int pcmcia_open_memory(client_handle_t *handle, open_mem_t *open, memory_handle_t *m);
int pcmcia_close_memory(memory_handle_t handle);
int pcmcia_read_memory(memory_handle_t handle, mem_op_t *req, caddr_t buf);
int pcmcia_write_memory(memory_handle_t handle, mem_op_t *req, caddr_t buf);
int pcmcia_copy_memory(memory_handle_t handle, copy_op_t *req);
#endif /* _LINUX_BULKMEM_H */
......@@ -607,6 +607,14 @@ 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(client_handle_t handle, cisdump_t *cis);
int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis);
/* don't use outside of PCMCIA core yet */
int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int func, tuple_t *tuple);
int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple);
int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple);
int pccard_parse_tuple(tuple_t *tuple, cisparse_t *parse);
int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, cisinfo_t *info);
#endif /* LINUX_CISTPL_H */
......@@ -348,7 +348,6 @@ typedef struct mtd_bind_t {
#define CS_EVENT_RESET_PHYSICAL 0x000200
#define CS_EVENT_CARD_RESET 0x000400
#define CS_EVENT_REGISTRATION_COMPLETE 0x000800
#define CS_EVENT_RESET_COMPLETE 0x001000
#define CS_EVENT_PM_SUSPEND 0x002000
#define CS_EVENT_PM_RESUME 0x004000
#define CS_EVENT_INSERTION_REQUEST 0x008000
......@@ -425,16 +424,12 @@ int pcmcia_access_configuration_register(client_handle_t handle, conf_reg_t *reg
int pcmcia_deregister_client(client_handle_t handle);
int pcmcia_get_configuration_info(client_handle_t handle, config_info_t *config);
int pcmcia_get_card_services_info(servinfo_t *info);
int pcmcia_get_first_client(client_handle_t *handle, client_req_t *req);
int pcmcia_get_next_client(client_handle_t *handle, client_req_t *req);
int pcmcia_get_window(window_handle_t *handle, int idx, win_req_t *req);
int pcmcia_get_first_window(window_handle_t *win, win_req_t *req);
int pcmcia_get_next_window(window_handle_t *win, win_req_t *req);
int pcmcia_get_status(client_handle_t handle, 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(client_handle_t handle, modconf_t *mod);
int pcmcia_modify_window(window_handle_t win, modwin_t *req);
int pcmcia_register_client(client_handle_t *handle, client_reg_t *req);
int pcmcia_release_configuration(client_handle_t handle);
int pcmcia_release_io(client_handle_t handle, io_req_t *req);
......@@ -449,12 +444,14 @@ 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 pcmcia_set_event_mask(client_handle_t handle, eventmask_t *mask);
int pcmcia_report_error(client_handle_t handle, error_info_t *err);
struct pci_bus *pcmcia_lookup_bus(client_handle_t handle);
/* rsrc_mgr.c */
int pcmcia_adjust_resource_info(client_handle_t handle, adjust_t *adj);
#ifdef CONFIG_PCMCIA_OBSOLETE
int pcmcia_get_first_client(client_handle_t *handle, client_req_t *req);
int pcmcia_get_next_client(client_handle_t *handle, client_req_t *req);
int pcmcia_modify_window(window_handle_t win, modwin_t *req);
int pcmcia_set_event_mask(client_handle_t handle, eventmask_t *mask);
#endif
#endif /* __KERNEL__ */
......
......@@ -56,9 +56,6 @@ typedef struct window_t *window_handle_t;
struct region_t;
typedef struct region_t *memory_handle_t;
struct eraseq_t;
typedef struct eraseq_t *eraseq_handle_t;
#ifndef DEV_NAME_LEN
#define DEV_NAME_LEN 32
#endif
......
/*
* ftl.h 1.8 2000/06/12 21:55:40
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License
* at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and
* limitations under the License.
*
* 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.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the MPL or the GPL.
*/
#ifndef _LINUX_FTL_H
#define _LINUX_FTL_H
typedef struct erase_unit_header_t {
u_char LinkTargetTuple[5];
u_char DataOrgTuple[10];
u_char NumTransferUnits;
u_int EraseCount;
u_short LogicalEUN;
u_char BlockSize;
u_char EraseUnitSize;
u_short FirstPhysicalEUN;
u_short NumEraseUnits;
u_int FormattedSize;
u_int FirstVMAddress;
u_short NumVMPages;
u_char Flags;
u_char Code;
u_int SerialNumber;
u_int AltEUHOffset;
u_int BAMOffset;
u_char Reserved[12];
u_char EndTuple[2];
} erase_unit_header_t;
/* Flags in erase_unit_header_t */
#define HIDDEN_AREA 0x01
#define REVERSE_POLARITY 0x02
#define DOUBLE_BAI 0x04
/* Definitions for block allocation information */
#define BLOCK_FREE(b) ((b) == 0xffffffff)
#define BLOCK_DELETED(b) (((b) == 0) || ((b) == 0xfffffffe))
#define BLOCK_TYPE(b) ((b) & 0x7f)
#define BLOCK_ADDRESS(b) ((b) & ~0x7f)
#define BLOCK_NUMBER(b) ((b) >> 9)
#define BLOCK_CONTROL 0x30
#define BLOCK_DATA 0x40
#define BLOCK_REPLACEMENT 0x60
#define BLOCK_BAD 0x70
#endif /* _LINUX_FTL_H */
/*
* memory.h 1.7 2000/06/12 21:55:40
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License
* at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and
* limitations under the License.
*
* 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.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the MPL or the GPL.
*/
#ifndef _LINUX_MEMORY_H
#define _LINUX_MEMORY_H
typedef struct erase_info_t {
u_long Offset;
u_long Size;
} erase_info_t;
#define MEMGETINFO _IOR('M', 1, region_info_t)
#define MEMERASE _IOW('M', 2, erase_info_t)
#endif /* _LINUX_MEMORY_H */
......@@ -135,13 +135,6 @@ struct pccard_operations {
*/
struct pcmcia_socket;
typedef struct erase_busy_t {
eraseq_entry_t *erase;
client_handle_t client;
struct timer_list timeout;
struct erase_busy_t *prev, *next;
} erase_busy_t;
typedef struct io_window_t {
u_int Attributes;
ioaddr_t BasePort, NumPorts;
......@@ -185,7 +178,6 @@ struct pcmcia_socket {
io_window_t io[MAX_IO_WIN];
window_t win[MAX_WIN];
struct region_t *c_region, *a_region;
erase_busy_t erase_busy;
struct list_head cis_cache;
u_int fake_cis_len;
char *fake_cis;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment