Skip to content

Commit

Permalink
pcmcia: move cistpl.c into pcmcia module
Browse files Browse the repository at this point in the history
As PCMCIA is the only real user of CIS access functions, include
cistpl.c in the PCMCIA module, not in the PCMCIA & CardBus core
module.

Tested-by: Wolfram Sang <w.sang@pengutronix.de>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
  • Loading branch information
Dominik Brodowski committed Feb 17, 2010
1 parent 4e8804f commit 6e7b51a
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 187 deletions.
4 changes: 2 additions & 2 deletions drivers/pcmcia/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
# Makefile for the kernel pcmcia subsystem (c/o David Hinds)
#

pcmcia_core-y += cs.o cistpl.o rsrc_mgr.o socket_sysfs.o
pcmcia_core-y += cs.o rsrc_mgr.o socket_sysfs.o
pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o
obj-$(CONFIG_PCCARD) += pcmcia_core.o

pcmcia-y += ds.o pcmcia_resource.o
pcmcia-y += ds.o pcmcia_resource.o cistpl.o
pcmcia-$(CONFIG_PCMCIA_IOCTL) += pcmcia_ioctl.o
obj-$(CONFIG_PCMCIA) += pcmcia.o

Expand Down
158 changes: 146 additions & 12 deletions drivers/pcmcia/cistpl.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ void release_cis_mem(struct pcmcia_socket *s)
s->cis_virt = NULL;
}
}
EXPORT_SYMBOL(release_cis_mem);

/*
* Map the card memory at "card_offset" into virtual space.
Expand Down Expand Up @@ -195,7 +194,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
*(u_char *)(ptr+2), *(u_char *)(ptr+3));
return 0;
}
EXPORT_SYMBOL(pcmcia_read_cis_mem);


void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
Expand Down Expand Up @@ -254,7 +252,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
}
}
}
EXPORT_SYMBOL(pcmcia_write_cis_mem);


/*======================================================================
Expand Down Expand Up @@ -335,7 +332,6 @@ void destroy_cis_cache(struct pcmcia_socket *s)
kfree(cis);
}
}
EXPORT_SYMBOL(destroy_cis_cache);

/*======================================================================
Expand Down Expand Up @@ -374,7 +370,6 @@ int verify_cis_cache(struct pcmcia_socket *s)
kfree(buf);
return 0;
}
EXPORT_SYMBOL(verify_cis_cache);

/*======================================================================
Expand All @@ -400,7 +395,6 @@ int pcmcia_replace_cis(struct pcmcia_socket *s,
memcpy(s->fake_cis, data, len);
return 0;
}
EXPORT_SYMBOL(pcmcia_replace_cis);

/*======================================================================
Expand Down Expand Up @@ -446,7 +440,6 @@ int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, 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)
{
Expand Down Expand Up @@ -582,7 +575,6 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
tuple->CISOffset = ofs + 2;
return 0;
}
EXPORT_SYMBOL(pccard_get_next_tuple);

/*====================================================================*/

Expand All @@ -606,7 +598,6 @@ int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple)
_MIN(len, tuple->TupleDataMax), tuple->TupleData);
return 0;
}
EXPORT_SYMBOL(pccard_get_tuple_data);


/*======================================================================
Expand Down Expand Up @@ -1379,7 +1370,6 @@ int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t
kfree(buf);
return ret;
}
EXPORT_SYMBOL(pccard_read_tuple);


/**
Expand Down Expand Up @@ -1439,7 +1429,6 @@ int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
kfree(buf);
return ret;
}
EXPORT_SYMBOL(pccard_loop_tuple);


/**
Expand Down Expand Up @@ -1533,4 +1522,149 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
kfree(p);
return ret;
}
EXPORT_SYMBOL(pccard_validate_cis);


#define to_socket(_dev) container_of(_dev, struct pcmcia_socket, dev)

static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf,
loff_t off, size_t count)
{
tuple_t tuple;
int status, i;
loff_t pointer = 0;
ssize_t ret = 0;
u_char *tuplebuffer;
u_char *tempbuffer;

tuplebuffer = kmalloc(sizeof(u_char) * 256, GFP_KERNEL);
if (!tuplebuffer)
return -ENOMEM;

tempbuffer = kmalloc(sizeof(u_char) * 258, GFP_KERNEL);
if (!tempbuffer) {
ret = -ENOMEM;
goto free_tuple;
}

memset(&tuple, 0, sizeof(tuple_t));

tuple.Attributes = TUPLE_RETURN_LINK | TUPLE_RETURN_COMMON;
tuple.DesiredTuple = RETURN_FIRST_TUPLE;
tuple.TupleOffset = 0;

status = pccard_get_first_tuple(s, BIND_FN_ALL, &tuple);
while (!status) {
tuple.TupleData = tuplebuffer;
tuple.TupleDataMax = 255;
memset(tuplebuffer, 0, sizeof(u_char) * 255);

status = pccard_get_tuple_data(s, &tuple);
if (status)
break;

if (off < (pointer + 2 + tuple.TupleDataLen)) {
tempbuffer[0] = tuple.TupleCode & 0xff;
tempbuffer[1] = tuple.TupleLink & 0xff;
for (i = 0; i < tuple.TupleDataLen; i++)
tempbuffer[i + 2] = tuplebuffer[i] & 0xff;

for (i = 0; i < (2 + tuple.TupleDataLen); i++) {
if (((i + pointer) >= off) &&
(i + pointer) < (off + count)) {
buf[ret] = tempbuffer[i];
ret++;
}
}
}

pointer += 2 + tuple.TupleDataLen;

if (pointer >= (off + count))
break;

if (tuple.TupleCode == CISTPL_END)
break;
status = pccard_get_next_tuple(s, BIND_FN_ALL, &tuple);
}

kfree(tempbuffer);
free_tuple:
kfree(tuplebuffer);

return ret;
}


static ssize_t pccard_show_cis(struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
unsigned int size = 0x200;

if (off >= size)
count = 0;
else {
struct pcmcia_socket *s;
unsigned int chains;

if (off + count > size)
count = size - off;

s = to_socket(container_of(kobj, struct device, kobj));

if (!(s->state & SOCKET_PRESENT))
return -ENODEV;
if (pccard_validate_cis(s, &chains))
return -EIO;
if (!chains)
return -ENODATA;

count = pccard_extract_cis(s, buf, off, count);
}

return count;
}


static ssize_t pccard_store_cis(struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
struct pcmcia_socket *s;
int error;

s = to_socket(container_of(kobj, struct device, kobj));

if (off)
return -EINVAL;

if (count >= CISTPL_MAX_CIS_SIZE)
return -EINVAL;

if (!(s->state & SOCKET_PRESENT))
return -ENODEV;

error = pcmcia_replace_cis(s, buf, count);
if (error)
return -EIO;

mutex_lock(&s->skt_mutex);
if ((s->callback) && (s->state & SOCKET_PRESENT) &&
!(s->state & SOCKET_CARDBUS)) {
if (try_module_get(s->callback->owner)) {
s->callback->requery(s, 1);
module_put(s->callback->owner);
}
}
mutex_unlock(&s->skt_mutex);

return count;
}


struct bin_attribute pccard_cis_attr = {
.attr = { .name = "cis", .mode = S_IRUGO | S_IWUSR },
.size = 0x200,
.read = pccard_show_cis,
.write = pccard_store_cis,
};
44 changes: 21 additions & 23 deletions drivers/pcmcia/cs_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,18 +92,13 @@ struct pccard_resource_ops {
* Stuff internal to module "pcmcia_core":
*/

/* cistpl.c */
int verify_cis_cache(struct pcmcia_socket *s);

/* socket_sysfs.c */
extern int pccard_sysfs_add_socket(struct device *dev);
extern void pccard_sysfs_remove_socket(struct device *dev);

/* cardbus.c */
int cb_alloc(struct pcmcia_socket *s);
void cb_free(struct pcmcia_socket *s);
int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len,
void *ptr);



Expand All @@ -116,6 +111,7 @@ struct pcmcia_callback{
int (*event) (struct pcmcia_socket *s,
event_t event, int priority);
void (*requery) (struct pcmcia_socket *s, int new_cis);
int (*validate) (struct pcmcia_socket *s, unsigned int *i);
int (*suspend) (struct pcmcia_socket *s);
int (*resume) (struct pcmcia_socket *s);
};
Expand All @@ -137,7 +133,26 @@ int pcmcia_insert_card(struct pcmcia_socket *skt);
struct pcmcia_socket *pcmcia_get_socket(struct pcmcia_socket *skt);
void pcmcia_put_socket(struct pcmcia_socket *skt);

/* rsrc_mgr.c */
int pcmcia_validate_mem(struct pcmcia_socket *s);
struct resource *pcmcia_find_mem_region(u_long base,
u_long num,
u_long align,
int low,
struct pcmcia_socket *s);

/*
* Stuff internal to module "pcmcia".
*/
/* ds.c */
extern struct bus_type pcmcia_bus_type;

/* pcmcia_resource.c */
extern int pcmcia_release_configuration(struct pcmcia_device *p_dev);

/* cistpl.c */
extern struct bin_attribute pccard_cis_attr;

int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr,
u_int addr, u_int len, void *ptr);
void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr,
Expand All @@ -149,8 +164,8 @@ int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function,
int pcmcia_replace_cis(struct pcmcia_socket *s,
const u8 *data, const size_t len);
int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *count);
int verify_cis_cache(struct pcmcia_socket *s);

/* loop over CIS entries */
int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
cisdata_t code, cisparse_t *parse, void *priv_data,
int (*loop_tuple) (tuple_t *tuple,
Expand All @@ -166,23 +181,6 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function,
int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple);


/* rsrc_mgr.c */
int pcmcia_validate_mem(struct pcmcia_socket *s);
struct resource *pcmcia_find_mem_region(u_long base,
u_long num,
u_long align,
int low,
struct pcmcia_socket *s);

/*
* Stuff internal to module "pcmcia".
*/
/* ds.c */
extern struct bus_type pcmcia_bus_type;

/* pcmcia_resource.c */
extern int pcmcia_release_configuration(struct pcmcia_device *p_dev);

#ifdef CONFIG_PCMCIA_IOCTL
/* ds.c */
extern spinlock_t pcmcia_dev_list_lock;
Expand Down
10 changes: 10 additions & 0 deletions drivers/pcmcia/ds.c
Original file line number Diff line number Diff line change
Expand Up @@ -1313,6 +1313,7 @@ static struct pcmcia_callback pcmcia_bus_callback = {
.owner = THIS_MODULE,
.event = ds_event,
.requery = pcmcia_bus_rescan,
.validate = pccard_validate_cis,
.suspend = pcmcia_bus_suspend,
.resume = pcmcia_bus_resume,
};
Expand All @@ -1336,6 +1337,13 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev,
*/
msleep(250);

ret = sysfs_create_bin_file(&dev->kobj, &pccard_cis_attr);
if (ret) {
dev_printk(KERN_ERR, dev, "PCMCIA registration failed\n");
pcmcia_put_socket(socket);
return ret;
}

#ifdef CONFIG_PCMCIA_IOCTL
init_waitqueue_head(&socket->queue);
#endif
Expand Down Expand Up @@ -1371,6 +1379,8 @@ static void pcmcia_bus_remove_socket(struct device *dev,
release_cis_mem(socket);
mutex_unlock(&socket->skt_mutex);

sysfs_remove_bin_file(&dev->kobj, &pccard_cis_attr);

pcmcia_put_socket(socket);

return;
Expand Down
4 changes: 3 additions & 1 deletion drivers/pcmcia/rsrc_nonstatic.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,9 @@ static int readable(struct pcmcia_socket *s, struct resource *res,
s->cis_mem.res = res;
s->cis_virt = ioremap(res->start, s->map_size);
if (s->cis_virt) {
ret = pccard_validate_cis(s, count);
/* as we're only called from pcmcia.c, we're safe */
if (s->callback->validate)
ret = s->callback->validate(s, count);
/* invalidate mapping */
iounmap(s->cis_virt);
s->cis_virt = NULL;
Expand Down
Loading

0 comments on commit 6e7b51a

Please sign in to comment.