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 | |
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>
-rw-r--r-- | Documentation/pcmcia/driver-changes.txt | 6 | ||||
-rw-r--r-- | drivers/pcmcia/pcmcia_resource.c | 62 | ||||
-rw-r--r-- | include/pcmcia/cistpl.h | 6 |
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 @@ | |||
1 | This file details changes in 2.6 which affect PCMCIA card driver authors: | 1 | This 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 | } |
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); | ||
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 | ||
616 | int 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 */ |