aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2008-07-29 02:38:30 -0400
committerDominik Brodowski <linux@dominikbrodowski.net>2008-08-22 18:46:35 -0400
commita804b574e6c7236222593046fc2b1b8bd0298fce (patch)
tree63e8e0805e61337be328a2e25c439317bd96914a
parent6e86841d05f371b5b9b86ce76c02aaee83352298 (diff)
pcmcia: add pcmcia_loop_config() helper
By calling pcmcia_loop_config(), a pcmcia 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. Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
-rw-r--r--Documentation/pcmcia/driver-changes.txt6
-rw-r--r--drivers/pcmcia/pcmcia_resource.c62
-rw-r--r--include/pcmcia/cistpl.h6
3 files changed, 74 insertions, 0 deletions
diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt
index 96f155e68750..059934363caf 100644
--- a/Documentation/pcmcia/driver-changes.txt
+++ b/Documentation/pcmcia/driver-changes.txt
@@ -1,5 +1,11 @@
1This file details changes in 2.6 which affect PCMCIA card driver authors: 1This file details changes in 2.6 which affect PCMCIA card driver authors:
2 2
3* New configuration loop helper (as of 2.6.28)
4 By calling pcmcia_loop_config(), a driver can iterate over all available
5 configuration options. During a driver's probe() phase, one doesn't need
6 to use pcmcia_get_{first,next}_tuple, pcmcia_get_tuple_data and
7 pcmcia_parse_tuple directly in most if not all cases.
8
3* New release helper (as of 2.6.17) 9* New release helper (as of 2.6.17)
4 Instead of calling pcmcia_release_{configuration,io,irq,win}, all that's 10 Instead of calling pcmcia_release_{configuration,io,irq,win}, all that's
5 necessary now is calling pcmcia_disable_device. As there is no valid 11 necessary now is calling pcmcia_disable_device. As there is no valid
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index 4884a18cf9e6..9f054bc847f2 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -909,3 +909,65 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev) {
909 pcmcia_release_window(p_dev->win); 909 pcmcia_release_window(p_dev->win);
910} 910}
911EXPORT_SYMBOL(pcmcia_disable_device); 911EXPORT_SYMBOL(pcmcia_disable_device);
912
913
914struct pcmcia_cfg_mem {
915 tuple_t tuple;
916 cisparse_t parse;
917 u8 buf[256];
918};
919
920/**
921 * pcmcia_loop_config() - loop over configuration options
922 * @p_dev: the struct pcmcia_device which we need to loop for.
923 * @conf_check: function to call for each configuration option.
924 * It gets passed the struct pcmcia_device, the CIS data
925 * describing the configuration option, and private data
926 * being passed to pcmcia_loop_config()
927 * @priv_data: private data to be passed to the conf_check function.
928 *
929 * pcmcia_loop_config() loops over all configuration options, and calls
930 * the driver-specific conf_check() for each one, checking whether
931 * it is a valid one.
932 */
933int pcmcia_loop_config(struct pcmcia_device *p_dev,
934 int (*conf_check) (struct pcmcia_device *p_dev,
935 cistpl_cftable_entry_t *cfg,
936 void *priv_data),
937 void *priv_data)
938{
939 struct pcmcia_cfg_mem *cfg_mem;
940 tuple_t *tuple;
941 int ret = -ENODEV;
942
943 cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL);
944 if (cfg_mem == NULL)
945 return -ENOMEM;
946
947 tuple = &cfg_mem->tuple;
948 tuple->TupleData = cfg_mem->buf;
949 tuple->TupleDataMax = 255;
950 tuple->TupleOffset = 0;
951 tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
952 tuple->Attributes = 0;
953
954 ret = pcmcia_get_first_tuple(p_dev, tuple);
955 while (!ret) {
956 if (pcmcia_get_tuple_data(p_dev, tuple))
957 goto next_entry;
958
959 if (pcmcia_parse_tuple(p_dev, tuple, &cfg_mem->parse))
960 goto next_entry;
961
962 ret = conf_check(p_dev, &cfg_mem->parse.cftable_entry,
963 priv_data);
964 if (!ret)
965 break;
966
967next_entry:
968 ret = pcmcia_get_next_tuple(p_dev, tuple);
969 }
970
971 return ret;
972}
973EXPORT_SYMBOL(pcmcia_loop_config);
diff --git a/include/pcmcia/cistpl.h b/include/pcmcia/cistpl.h
index e2e10c1e9a06..b2eb914a18df 100644
--- a/include/pcmcia/cistpl.h
+++ b/include/pcmcia/cistpl.h
@@ -613,4 +613,10 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned
613#define pcmcia_validate_cis(p_dev, info) \ 613#define pcmcia_validate_cis(p_dev, info) \
614 pccard_validate_cis(p_dev->socket, p_dev->func, info) 614 pccard_validate_cis(p_dev->socket, p_dev->func, info)
615 615
616int pcmcia_loop_config(struct pcmcia_device *p_dev,
617 int (*conf_check) (struct pcmcia_device *p_dev,
618 cistpl_cftable_entry_t *cf,
619 void *priv_data),
620 void *priv_data);
621
616#endif /* LINUX_CISTPL_H */ 622#endif /* LINUX_CISTPL_H */