diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2008-07-29 02:38:30 -0400 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2008-08-22 18:46:35 -0400 |
commit | a804b574e6c7236222593046fc2b1b8bd0298fce (patch) | |
tree | 63e8e0805e61337be328a2e25c439317bd96914a /drivers/pcmcia/pcmcia_resource.c | |
parent | 6e86841d05f371b5b9b86ce76c02aaee83352298 (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>
Diffstat (limited to 'drivers/pcmcia/pcmcia_resource.c')
-rw-r--r-- | drivers/pcmcia/pcmcia_resource.c | 62 |
1 files changed, 62 insertions, 0 deletions
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 | } |
911 | EXPORT_SYMBOL(pcmcia_disable_device); | 911 | EXPORT_SYMBOL(pcmcia_disable_device); |
912 | |||
913 | |||
914 | struct 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 | */ | ||
933 | int 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 | |||
967 | next_entry: | ||
968 | ret = pcmcia_get_next_tuple(p_dev, tuple); | ||
969 | } | ||
970 | |||
971 | return ret; | ||
972 | } | ||
973 | EXPORT_SYMBOL(pcmcia_loop_config); | ||