diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2009-10-18 12:28:39 -0400 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2009-11-08 12:06:53 -0500 |
commit | aaa8cfdada648a6bae32f62df76cc60137a2b323 (patch) | |
tree | c610da3b895ed6fdcda058dc08962b0248624c98 /drivers | |
parent | 7d2e8d00b47b973c92db4df7444d5e6d3bb945f9 (diff) |
pcmcia: use pcmcia_loop_config in misc pcmcia drivers
Use pcmcia_loop_config() in a few drivers missed during the first
round. On fmvj18x_cs.c it -- strangely -- only requries us to set
conf.ConfigIndex, which is done by the core, so include an empty
loop function which returns 0 unconditionally.
CC: David S. Miller <davem@davemloft.net>
CC: David Sterba <dsterba@suse.cz>
CC: netdev@vger.kernel.org
CC: linux-wireless@vger.kernel.org
For the ipwireless part: Acked-by: Jiri Kosina <jkosina@suse.cz>
Acked-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/pcmcia/ipwireless/main.c | 103 | ||||
-rw-r--r-- | drivers/char/pcmcia/synclink_cs.c | 64 | ||||
-rw-r--r-- | drivers/net/pcmcia/fmvj18x_cs.c | 22 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/if_cs.c | 67 |
4 files changed, 88 insertions, 168 deletions
diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c index 5216fce0c62d..263a18f381b3 100644 --- a/drivers/char/pcmcia/ipwireless/main.c +++ b/drivers/char/pcmcia/ipwireless/main.c | |||
@@ -79,14 +79,32 @@ static void signalled_reboot_callback(void *callback_data) | |||
79 | schedule_work(&ipw->work_reboot); | 79 | schedule_work(&ipw->work_reboot); |
80 | } | 80 | } |
81 | 81 | ||
82 | static int ipwireless_ioprobe(struct pcmcia_device *p_dev, | ||
83 | cistpl_cftable_entry_t *cfg, | ||
84 | cistpl_cftable_entry_t *dflt, | ||
85 | unsigned int vcc, | ||
86 | void *priv_data) | ||
87 | { | ||
88 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
89 | p_dev->io.BasePort1 = cfg->io.win[0].base; | ||
90 | p_dev->io.NumPorts1 = cfg->io.win[0].len; | ||
91 | p_dev->io.IOAddrLines = 16; | ||
92 | |||
93 | p_dev->irq.IRQInfo1 = cfg->irq.IRQInfo1; | ||
94 | |||
95 | /* 0x40 causes it to generate level mode interrupts. */ | ||
96 | /* 0x04 enables IREQ pin. */ | ||
97 | p_dev->conf.ConfigIndex = cfg->index | 0x44; | ||
98 | return pcmcia_request_io(p_dev, &p_dev->io); | ||
99 | } | ||
100 | |||
82 | static int config_ipwireless(struct ipw_dev *ipw) | 101 | static int config_ipwireless(struct ipw_dev *ipw) |
83 | { | 102 | { |
84 | struct pcmcia_device *link = ipw->link; | 103 | struct pcmcia_device *link = ipw->link; |
85 | int ret; | 104 | int ret = 0; |
86 | tuple_t tuple; | 105 | tuple_t tuple; |
87 | unsigned short buf[64]; | 106 | unsigned short buf[64]; |
88 | cisparse_t parse; | 107 | cisparse_t parse; |
89 | unsigned short cor_value; | ||
90 | memreq_t memreq_attr_memory; | 108 | memreq_t memreq_attr_memory; |
91 | memreq_t memreq_common_memory; | 109 | memreq_t memreq_common_memory; |
92 | 110 | ||
@@ -97,103 +115,26 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
97 | tuple.TupleDataMax = sizeof(buf); | 115 | tuple.TupleDataMax = sizeof(buf); |
98 | tuple.TupleOffset = 0; | 116 | tuple.TupleOffset = 0; |
99 | 117 | ||
100 | tuple.DesiredTuple = RETURN_FIRST_TUPLE; | 118 | ret = pcmcia_loop_config(link, ipwireless_ioprobe, NULL); |
101 | |||
102 | ret = pcmcia_get_first_tuple(link, &tuple); | ||
103 | |||
104 | while (ret == 0) { | ||
105 | ret = pcmcia_get_tuple_data(link, &tuple); | ||
106 | |||
107 | if (ret != 0) { | ||
108 | cs_error(link, GetTupleData, ret); | ||
109 | goto exit0; | ||
110 | } | ||
111 | ret = pcmcia_get_next_tuple(link, &tuple); | ||
112 | } | ||
113 | |||
114 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | ||
115 | |||
116 | ret = pcmcia_get_first_tuple(link, &tuple); | ||
117 | |||
118 | if (ret != 0) { | ||
119 | cs_error(link, GetFirstTuple, ret); | ||
120 | goto exit0; | ||
121 | } | ||
122 | |||
123 | ret = pcmcia_get_tuple_data(link, &tuple); | ||
124 | |||
125 | if (ret != 0) { | ||
126 | cs_error(link, GetTupleData, ret); | ||
127 | goto exit0; | ||
128 | } | ||
129 | |||
130 | ret = pcmcia_parse_tuple(&tuple, &parse); | ||
131 | |||
132 | if (ret != 0) { | ||
133 | cs_error(link, ParseTuple, ret); | ||
134 | goto exit0; | ||
135 | } | ||
136 | |||
137 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
138 | link->io.BasePort1 = parse.cftable_entry.io.win[0].base; | ||
139 | link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; | ||
140 | link->io.IOAddrLines = 16; | ||
141 | |||
142 | link->irq.IRQInfo1 = parse.cftable_entry.irq.IRQInfo1; | ||
143 | |||
144 | /* 0x40 causes it to generate level mode interrupts. */ | ||
145 | /* 0x04 enables IREQ pin. */ | ||
146 | cor_value = parse.cftable_entry.index | 0x44; | ||
147 | link->conf.ConfigIndex = cor_value; | ||
148 | |||
149 | /* IRQ and I/O settings */ | ||
150 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
151 | |||
152 | ret = pcmcia_get_first_tuple(link, &tuple); | ||
153 | |||
154 | if (ret != 0) { | 119 | if (ret != 0) { |
155 | cs_error(link, GetFirstTuple, ret); | 120 | cs_error(link, RequestIO, ret); |
156 | goto exit0; | ||
157 | } | ||
158 | |||
159 | ret = pcmcia_get_tuple_data(link, &tuple); | ||
160 | |||
161 | if (ret != 0) { | ||
162 | cs_error(link, GetTupleData, ret); | ||
163 | goto exit0; | 121 | goto exit0; |
164 | } | 122 | } |
165 | 123 | ||
166 | ret = pcmcia_parse_tuple(&tuple, &parse); | ||
167 | |||
168 | if (ret != 0) { | ||
169 | cs_error(link, GetTupleData, ret); | ||
170 | goto exit0; | ||
171 | } | ||
172 | link->conf.Attributes = CONF_ENABLE_IRQ; | 124 | link->conf.Attributes = CONF_ENABLE_IRQ; |
173 | link->conf.ConfigBase = parse.config.base; | ||
174 | link->conf.Present = parse.config.rmask[0]; | ||
175 | link->conf.IntType = INT_MEMORY_AND_IO; | 125 | link->conf.IntType = INT_MEMORY_AND_IO; |
176 | 126 | ||
177 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT; | 127 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT; |
178 | link->irq.Handler = ipwireless_interrupt; | 128 | link->irq.Handler = ipwireless_interrupt; |
179 | link->irq.Instance = ipw->hardware; | 129 | link->irq.Instance = ipw->hardware; |
180 | 130 | ||
181 | ret = pcmcia_request_io(link, &link->io); | ||
182 | |||
183 | if (ret != 0) { | ||
184 | cs_error(link, RequestIO, ret); | ||
185 | goto exit0; | ||
186 | } | ||
187 | |||
188 | request_region(link->io.BasePort1, link->io.NumPorts1, | 131 | request_region(link->io.BasePort1, link->io.NumPorts1, |
189 | IPWIRELESS_PCCARD_NAME); | 132 | IPWIRELESS_PCCARD_NAME); |
190 | 133 | ||
191 | /* memory settings */ | 134 | /* memory settings */ |
192 | |||
193 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 135 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; |
194 | 136 | ||
195 | ret = pcmcia_get_first_tuple(link, &tuple); | 137 | ret = pcmcia_get_first_tuple(link, &tuple); |
196 | |||
197 | if (ret != 0) { | 138 | if (ret != 0) { |
198 | cs_error(link, GetFirstTuple, ret); | 139 | cs_error(link, GetFirstTuple, ret); |
199 | goto exit1; | 140 | goto exit1; |
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index caf6e4d19469..429b7313119b 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -575,55 +575,39 @@ static int mgslpc_probe(struct pcmcia_device *link) | |||
575 | #define CS_CHECK(fn, ret) \ | 575 | #define CS_CHECK(fn, ret) \ |
576 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | 576 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) |
577 | 577 | ||
578 | static int mgslpc_ioprobe(struct pcmcia_device *p_dev, | ||
579 | cistpl_cftable_entry_t *cfg, | ||
580 | cistpl_cftable_entry_t *dflt, | ||
581 | unsigned int vcc, | ||
582 | void *priv_data) | ||
583 | { | ||
584 | if (cfg->io.nwin > 0) { | ||
585 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
586 | if (!(cfg->io.flags & CISTPL_IO_8BIT)) | ||
587 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; | ||
588 | if (!(cfg->io.flags & CISTPL_IO_16BIT)) | ||
589 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | ||
590 | p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK; | ||
591 | p_dev->io.BasePort1 = cfg->io.win[0].base; | ||
592 | p_dev->io.NumPorts1 = cfg->io.win[0].len; | ||
593 | return pcmcia_request_io(p_dev, &p_dev->io); | ||
594 | } | ||
595 | return -ENODEV; | ||
596 | } | ||
597 | |||
578 | static int mgslpc_config(struct pcmcia_device *link) | 598 | static int mgslpc_config(struct pcmcia_device *link) |
579 | { | 599 | { |
580 | MGSLPC_INFO *info = link->priv; | 600 | MGSLPC_INFO *info = link->priv; |
581 | tuple_t tuple; | 601 | int last_fn = RequestIO; |
582 | cisparse_t parse; | 602 | int last_ret; |
583 | int last_fn, last_ret; | ||
584 | u_char buf[64]; | ||
585 | cistpl_cftable_entry_t dflt = { 0 }; | ||
586 | cistpl_cftable_entry_t *cfg; | ||
587 | 603 | ||
588 | if (debug_level >= DEBUG_LEVEL_INFO) | 604 | if (debug_level >= DEBUG_LEVEL_INFO) |
589 | printk("mgslpc_config(0x%p)\n", link); | 605 | printk("mgslpc_config(0x%p)\n", link); |
590 | 606 | ||
591 | tuple.Attributes = 0; | 607 | last_ret = pcmcia_loop_config(link, mgslpc_ioprobe, NULL); |
592 | tuple.TupleData = buf; | 608 | if (last_ret != 0) |
593 | tuple.TupleDataMax = sizeof(buf); | ||
594 | tuple.TupleOffset = 0; | ||
595 | |||
596 | /* get CIS configuration entry */ | ||
597 | |||
598 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | ||
599 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
600 | |||
601 | cfg = &(parse.cftable_entry); | ||
602 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
603 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse)); | ||
604 | |||
605 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; | ||
606 | if (cfg->index == 0) | ||
607 | goto cs_failed; | 609 | goto cs_failed; |
608 | 610 | ||
609 | link->conf.ConfigIndex = cfg->index; | ||
610 | link->conf.Attributes |= CONF_ENABLE_IRQ; | ||
611 | |||
612 | /* IO window settings */ | ||
613 | link->io.NumPorts1 = 0; | ||
614 | if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { | ||
615 | cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; | ||
616 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
617 | if (!(io->flags & CISTPL_IO_8BIT)) | ||
618 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; | ||
619 | if (!(io->flags & CISTPL_IO_16BIT)) | ||
620 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | ||
621 | link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; | ||
622 | link->io.BasePort1 = io->win[0].base; | ||
623 | link->io.NumPorts1 = io->win[0].len; | ||
624 | CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); | ||
625 | } | ||
626 | |||
627 | link->conf.Attributes = CONF_ENABLE_IRQ; | 611 | link->conf.Attributes = CONF_ENABLE_IRQ; |
628 | link->conf.IntType = INT_MEMORY_AND_IO; | 612 | link->conf.IntType = INT_MEMORY_AND_IO; |
629 | link->conf.ConfigIndex = 8; | 613 | link->conf.ConfigIndex = 8; |
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 7e01fbdb87e0..c7a2bbfaf821 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c | |||
@@ -341,14 +341,23 @@ static int ungermann_try_io_port(struct pcmcia_device *link) | |||
341 | return ret; /* RequestIO failed */ | 341 | return ret; /* RequestIO failed */ |
342 | } | 342 | } |
343 | 343 | ||
344 | static int fmvj18x_ioprobe(struct pcmcia_device *p_dev, | ||
345 | cistpl_cftable_entry_t *cfg, | ||
346 | cistpl_cftable_entry_t *dflt, | ||
347 | unsigned int vcc, | ||
348 | void *priv_data) | ||
349 | { | ||
350 | return 0; /* strange, but that's what the code did already before... */ | ||
351 | } | ||
352 | |||
353 | |||
344 | static int fmvj18x_config(struct pcmcia_device *link) | 354 | static int fmvj18x_config(struct pcmcia_device *link) |
345 | { | 355 | { |
346 | struct net_device *dev = link->priv; | 356 | struct net_device *dev = link->priv; |
347 | local_info_t *lp = netdev_priv(dev); | 357 | local_info_t *lp = netdev_priv(dev); |
348 | tuple_t tuple; | 358 | tuple_t tuple; |
349 | cisparse_t parse; | ||
350 | u_short buf[32]; | 359 | u_short buf[32]; |
351 | int i, last_fn = 0, last_ret = 0, ret; | 360 | int i, last_fn = RequestIO, last_ret = 0, ret; |
352 | unsigned int ioaddr; | 361 | unsigned int ioaddr; |
353 | cardtype_t cardtype; | 362 | cardtype_t cardtype; |
354 | char *card_name = "unknown"; | 363 | char *card_name = "unknown"; |
@@ -362,12 +371,11 @@ static int fmvj18x_config(struct pcmcia_device *link) | |||
362 | tuple.DesiredTuple = CISTPL_FUNCE; | 371 | tuple.DesiredTuple = CISTPL_FUNCE; |
363 | tuple.TupleOffset = 0; | 372 | tuple.TupleOffset = 0; |
364 | if (pcmcia_get_first_tuple(link, &tuple) == 0) { | 373 | if (pcmcia_get_first_tuple(link, &tuple) == 0) { |
374 | last_ret = pcmcia_loop_config(link, fmvj18x_ioprobe, NULL); | ||
375 | if (last_ret != 0) | ||
376 | goto cs_failed; | ||
377 | |||
365 | /* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */ | 378 | /* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */ |
366 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | ||
367 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
368 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
369 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse)); | ||
370 | link->conf.ConfigIndex = parse.cftable_entry.index; | ||
371 | switch (link->manf_id) { | 379 | switch (link->manf_id) { |
372 | case MANFID_TDK: | 380 | case MANFID_TDK: |
373 | cardtype = TDK; | 381 | cardtype = TDK; |
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index 62381768f2d5..cb40c386fc77 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c | |||
@@ -793,18 +793,37 @@ static void if_cs_release(struct pcmcia_device *p_dev) | |||
793 | * configure the card at this point -- we wait until we receive a card | 793 | * configure the card at this point -- we wait until we receive a card |
794 | * insertion event. | 794 | * insertion event. |
795 | */ | 795 | */ |
796 | |||
797 | static int if_cs_ioprobe(struct pcmcia_device *p_dev, | ||
798 | cistpl_cftable_entry_t *cfg, | ||
799 | cistpl_cftable_entry_t *dflt, | ||
800 | unsigned int vcc, | ||
801 | void *priv_data) | ||
802 | { | ||
803 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
804 | p_dev->io.BasePort1 = cfg->io.win[0].base; | ||
805 | p_dev->io.NumPorts1 = cfg->io.win[0].len; | ||
806 | |||
807 | /* Do we need to allocate an interrupt? */ | ||
808 | if (cfg->irq.IRQInfo1) | ||
809 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; | ||
810 | |||
811 | /* IO window settings */ | ||
812 | if (cfg->io.nwin != 1) { | ||
813 | lbs_pr_err("wrong CIS (check number of IO windows)\n"); | ||
814 | return -ENODEV; | ||
815 | } | ||
816 | |||
817 | /* This reserves IO space but doesn't actually enable it */ | ||
818 | return pcmcia_request_io(p_dev, &p_dev->io); | ||
819 | } | ||
820 | |||
796 | static int if_cs_probe(struct pcmcia_device *p_dev) | 821 | static int if_cs_probe(struct pcmcia_device *p_dev) |
797 | { | 822 | { |
798 | int ret = -ENOMEM; | 823 | int ret = -ENOMEM; |
799 | unsigned int prod_id; | 824 | unsigned int prod_id; |
800 | struct lbs_private *priv; | 825 | struct lbs_private *priv; |
801 | struct if_cs_card *card; | 826 | struct if_cs_card *card; |
802 | /* CIS parsing */ | ||
803 | tuple_t tuple; | ||
804 | cisparse_t parse; | ||
805 | cistpl_cftable_entry_t *cfg = &parse.cftable_entry; | ||
806 | cistpl_io_t *io = &cfg->io; | ||
807 | u_char buf[64]; | ||
808 | 827 | ||
809 | lbs_deb_enter(LBS_DEB_CS); | 828 | lbs_deb_enter(LBS_DEB_CS); |
810 | 829 | ||
@@ -823,43 +842,11 @@ static int if_cs_probe(struct pcmcia_device *p_dev) | |||
823 | p_dev->conf.Attributes = 0; | 842 | p_dev->conf.Attributes = 0; |
824 | p_dev->conf.IntType = INT_MEMORY_AND_IO; | 843 | p_dev->conf.IntType = INT_MEMORY_AND_IO; |
825 | 844 | ||
826 | tuple.Attributes = 0; | 845 | if (pcmcia_loop_config(p_dev, if_cs_ioprobe, NULL)) { |
827 | tuple.TupleData = buf; | 846 | lbs_pr_err("error in pcmcia_loop_config\n"); |
828 | tuple.TupleDataMax = sizeof(buf); | ||
829 | tuple.TupleOffset = 0; | ||
830 | |||
831 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | ||
832 | if ((ret = pcmcia_get_first_tuple(p_dev, &tuple)) != 0 || | ||
833 | (ret = pcmcia_get_tuple_data(p_dev, &tuple)) != 0 || | ||
834 | (ret = pcmcia_parse_tuple(&tuple, &parse)) != 0) | ||
835 | { | ||
836 | lbs_pr_err("error in pcmcia_get_first_tuple etc\n"); | ||
837 | goto out1; | ||
838 | } | ||
839 | |||
840 | p_dev->conf.ConfigIndex = cfg->index; | ||
841 | |||
842 | /* Do we need to allocate an interrupt? */ | ||
843 | if (cfg->irq.IRQInfo1) { | ||
844 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; | ||
845 | } | ||
846 | |||
847 | /* IO window settings */ | ||
848 | if (cfg->io.nwin != 1) { | ||
849 | lbs_pr_err("wrong CIS (check number of IO windows)\n"); | ||
850 | ret = -ENODEV; | ||
851 | goto out1; | 847 | goto out1; |
852 | } | 848 | } |
853 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
854 | p_dev->io.BasePort1 = io->win[0].base; | ||
855 | p_dev->io.NumPorts1 = io->win[0].len; | ||
856 | 849 | ||
857 | /* This reserves IO space but doesn't actually enable it */ | ||
858 | ret = pcmcia_request_io(p_dev, &p_dev->io); | ||
859 | if (ret) { | ||
860 | lbs_pr_err("error in pcmcia_request_io\n"); | ||
861 | goto out1; | ||
862 | } | ||
863 | 850 | ||
864 | /* | 851 | /* |
865 | * Allocate an interrupt line. Note that this does not assign | 852 | * Allocate an interrupt line. Note that this does not assign |