|
@@ -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);
|