Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 114112
b: refs/heads/master
c: a804b57
h: refs/heads/master
v: v3
  • Loading branch information
Dominik Brodowski committed Aug 22, 2008
1 parent e5de593 commit b830660
Show file tree
Hide file tree
Showing 12 changed files with 118 additions and 28 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 795659ef0ee175d47723f806e7a29427b171e61b
refs/heads/master: a804b574e6c7236222593046fc2b1b8bd0298fce
6 changes: 6 additions & 0 deletions trunk/Documentation/pcmcia/driver-changes.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
This file details changes in 2.6 which affect PCMCIA card driver authors:

* New configuration loop helper (as of 2.6.28)
By calling pcmcia_loop_config(), a driver can iterate over all available
configuration options. During a driver's probe() phase, one doesn't need
to use pcmcia_get_{first,next}_tuple, pcmcia_get_tuple_data and
pcmcia_parse_tuple directly in most if not all cases.

* 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
Expand Down
3 changes: 1 addition & 2 deletions trunk/drivers/ata/pata_pcmcia.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,6 @@ static struct pcmcia_device_id pcmcia_devices[] = {
PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
PCMCIA_DEVICE_MANF_CARD(0x0032, 0x2904),
PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), /* SanDisk CFA */
PCMCIA_DEVICE_MANF_CARD(0x004f, 0x0000), /* Kingston */
PCMCIA_DEVICE_MANF_CARD(0x0097, 0x1620), /* TI emulated */
PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */
PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
Expand All @@ -405,9 +404,9 @@ static struct pcmcia_device_id pcmcia_devices[] = {
PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591),
PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728),
PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e),
PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae),
PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178),
PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178),
PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF8GB", 0x2e6d1829, 0xacbe682e),
Expand Down
2 changes: 0 additions & 2 deletions trunk/drivers/ide/legacy/ide-cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,10 +404,8 @@ static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x000a, 0x0000), /* I-O Data CFA */
PCMCIA_DEVICE_MANF_CARD(0x001c, 0x0001), /* Mitsubishi CFA */
PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
PCMCIA_DEVICE_MANF_CARD(0x0032, 0x2904),
PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), /* SanDisk CFA */
PCMCIA_DEVICE_MANF_CARD(0x004f, 0x0000), /* Kingston */
PCMCIA_DEVICE_MANF_CARD(0x0097, 0x1620), /* TI emulated */
PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */
PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */
Expand Down
18 changes: 9 additions & 9 deletions trunk/drivers/pcmcia/cistpl.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,13 +265,13 @@ EXPORT_SYMBOL(pcmcia_write_cis_mem);
======================================================================*/

static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
size_t len, void *ptr)
u_int len, void *ptr)
{
struct cis_cache_entry *cis;
int ret;

if (s->fake_cis) {
if (s->fake_cis_len >= addr+len)
if (s->fake_cis_len > addr+len)
memcpy(ptr, s->fake_cis+addr, len);
else
memset(ptr, 0xff, len);
Expand Down Expand Up @@ -380,17 +380,17 @@ int verify_cis_cache(struct pcmcia_socket *s)
======================================================================*/

int pcmcia_replace_cis(struct pcmcia_socket *s,
const u8 *data, const size_t len)
int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis)
{
if (len > CISTPL_MAX_CIS_SIZE)
return CS_BAD_SIZE;
kfree(s->fake_cis);
s->fake_cis = kmalloc(len, GFP_KERNEL);
s->fake_cis = NULL;
if (cis->Length > CISTPL_MAX_CIS_SIZE)
return CS_BAD_SIZE;
s->fake_cis = kmalloc(cis->Length, GFP_KERNEL);
if (s->fake_cis == NULL)
return CS_OUT_OF_RESOURCE;
s->fake_cis_len = len;
memcpy(s->fake_cis, data, len);
s->fake_cis_len = cis->Length;
memcpy(s->fake_cis, cis->Data, cis->Length);
return CS_SUCCESS;
}
EXPORT_SYMBOL(pcmcia_replace_cis);
Expand Down
12 changes: 11 additions & 1 deletion trunk/drivers/pcmcia/ds.c
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,7 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
int ret = -ENOMEM;
int no_funcs;
int old_funcs;
cisdump_t *cis;
cistpl_longlink_mfc_t mfc;

if (!filename)
Expand All @@ -876,7 +877,16 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
goto release;
}

if (!pcmcia_replace_cis(s, fw->data, fw->size))
cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL);
if (!cis) {
ret = -ENOMEM;
goto release;
}

cis->Length = fw->size + 1;
memcpy(cis->Data, fw->data, fw->size);

if (!pcmcia_replace_cis(s, cis))
ret = 0;
else {
printk(KERN_ERR "pcmcia: CIS override failed\n");
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/pcmcia/pcmcia_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
&buf->win_info.map);
break;
case DS_REPLACE_CIS:
ret = pcmcia_replace_cis(s, buf->cisdump.Data, buf->cisdump.Length);
ret = pcmcia_replace_cis(s, &buf->cisdump);
break;
case DS_BIND_REQUEST:
if (!capable(CAP_SYS_ADMIN)) {
Expand Down
62 changes: 62 additions & 0 deletions trunk/drivers/pcmcia/pcmcia_resource.c
Original file line number Diff line number Diff line change
Expand Up @@ -909,3 +909,65 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev) {
pcmcia_release_window(p_dev->win);
}
EXPORT_SYMBOL(pcmcia_disable_device);


struct pcmcia_cfg_mem {
tuple_t tuple;
cisparse_t parse;
u8 buf[256];
};

/**
* pcmcia_loop_config() - loop over configuration options
* @p_dev: the struct pcmcia_device which we need to loop for.
* @conf_check: function to call for each configuration option.
* It gets passed the struct pcmcia_device, the CIS data
* describing the configuration option, and private data
* being passed to pcmcia_loop_config()
* @priv_data: private data to be passed to the conf_check function.
*
* pcmcia_loop_config() loops over all configuration options, and calls
* the driver-specific conf_check() for each one, checking whether
* it is a valid one.
*/
int pcmcia_loop_config(struct pcmcia_device *p_dev,
int (*conf_check) (struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
void *priv_data),
void *priv_data)
{
struct pcmcia_cfg_mem *cfg_mem;
tuple_t *tuple;
int ret = -ENODEV;

cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL);
if (cfg_mem == NULL)
return -ENOMEM;

tuple = &cfg_mem->tuple;
tuple->TupleData = cfg_mem->buf;
tuple->TupleDataMax = 255;
tuple->TupleOffset = 0;
tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
tuple->Attributes = 0;

ret = pcmcia_get_first_tuple(p_dev, tuple);
while (!ret) {
if (pcmcia_get_tuple_data(p_dev, tuple))
goto next_entry;

if (pcmcia_parse_tuple(p_dev, tuple, &cfg_mem->parse))
goto next_entry;

ret = conf_check(p_dev, &cfg_mem->parse.cftable_entry,
priv_data);
if (!ret)
break;

next_entry:
ret = pcmcia_get_next_tuple(p_dev, tuple);
}

return ret;
}
EXPORT_SYMBOL(pcmcia_loop_config);
13 changes: 11 additions & 2 deletions trunk/drivers/pcmcia/socket_sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,18 +316,27 @@ static ssize_t pccard_store_cis(struct kobject *kobj,
char *buf, loff_t off, size_t count)
{
struct pcmcia_socket *s = to_socket(container_of(kobj, struct device, kobj));
cisdump_t *cis;
int error;

if (off)
return -EINVAL;

if (count >= CISTPL_MAX_CIS_SIZE)
if (count >= 0x200)
return -EINVAL;

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

error = pcmcia_replace_cis(s, buf, count);
cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL);
if (!cis)
return -ENOMEM;

cis->Length = count + 1;
memcpy(cis->Data, buf, count);

error = pcmcia_replace_cis(s, cis);
kfree(cis);
if (error)
return -EIO;

Expand Down
16 changes: 14 additions & 2 deletions trunk/include/pcmcia/cistpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -580,8 +580,14 @@ typedef struct cisinfo_t {

#define CISTPL_MAX_CIS_SIZE 0x200

int pcmcia_replace_cis(struct pcmcia_socket *s,
const u8 *data, const size_t len);
/* For ReplaceCIS */
typedef struct cisdump_t {
u_int Length;
cisdata_t Data[CISTPL_MAX_CIS_SIZE];
} cisdump_t;


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);
Expand All @@ -607,4 +613,10 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned
#define pcmcia_validate_cis(p_dev, info) \
pccard_validate_cis(p_dev->socket, p_dev->func, info)

int pcmcia_loop_config(struct pcmcia_device *p_dev,
int (*conf_check) (struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
void *priv_data),
void *priv_data);

#endif /* LINUX_CISTPL_H */
6 changes: 0 additions & 6 deletions trunk/include/pcmcia/ds.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,6 @@ typedef struct region_info_t {
#define REGION_BAR_MASK 0xe000
#define REGION_BAR_SHIFT 13

/* For ReplaceCIS */
typedef struct cisdump_t {
u_int Length;
cisdata_t Data[CISTPL_MAX_CIS_SIZE];
} cisdump_t;

typedef union ds_ioctl_arg_t {
adjust_t adjust;
config_info_t config;
Expand Down
4 changes: 2 additions & 2 deletions trunk/include/pcmcia/ss.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,8 @@ struct pcmcia_socket {
io_window_t io[MAX_IO_WIN];
window_t win[MAX_WIN];
struct list_head cis_cache;
size_t fake_cis_len;
u8 *fake_cis;
u_int fake_cis_len;
char *fake_cis;

struct list_head socket_list;
struct completion socket_released;
Expand Down

0 comments on commit b830660

Please sign in to comment.