1 /* $NetBSD: pcmcia.c,v 1.92 2009/05/12 13:18:04 cegger Exp $ */
4 * Copyright (c) 2004 Charles M. Hannum. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Charles M. Hannum.
17 * 4. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
22 * Copyright (c) 1997 Marc Horowitz. All rights reserved.
24 * Redistribution and use in source and binary forms, with or without
25 * modification, are permitted provided that the following conditions
27 * 1. Redistributions of source code must retain the above copyright
28 * notice, this list of conditions and the following disclaimer.
29 * 2. Redistributions in binary form must reproduce the above copyright
30 * notice, this list of conditions and the following disclaimer in the
31 * documentation and/or other materials provided with the distribution.
32 * 3. All advertising materials mentioning features or use of this software
33 * must display the following acknowledgement:
34 * This product includes software developed by Marc Horowitz.
35 * 4. The name of the author may not be used to endorse or promote products
36 * derived from this software without specific prior written permission.
38 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
42 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
47 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 #include <sys/cdefs.h>
51 __KERNEL_RCSID(0, "$NetBSD: pcmcia.c,v 1.92 2009/05/12 13:18:04 cegger Exp $");
53 #include "opt_pcmciaverbose.h"
55 #include <sys/param.h>
56 #include <sys/systm.h>
57 #include <sys/device.h>
61 #include <dev/pcmcia/pcmciareg.h>
62 #include <dev/pcmcia/pcmciachip.h>
63 #include <dev/pcmcia/pcmciavar.h>
64 #ifdef IT8368E_LEGACY_MODE /* XXX -uch */
65 #include <arch/hpcmips/dev/it8368var.h>
72 #define DPRINTF(arg) if (pcmcia_debug) printf arg
78 int pcmcia_verbose
= 1;
80 int pcmcia_verbose
= 0;
83 int pcmcia_match(device_t
, cfdata_t
, void *);
84 void pcmcia_attach(device_t
, device_t
, void *);
85 int pcmcia_detach(device_t
, int);
86 int pcmcia_rescan(device_t
, const char *, const int *);
87 void pcmcia_childdetached(device_t
, device_t
);
88 int pcmcia_print(void *, const char *);
90 CFATTACH_DECL3_NEW(pcmcia
, sizeof(struct pcmcia_softc
),
91 pcmcia_match
, pcmcia_attach
, pcmcia_detach
, NULL
,
92 pcmcia_rescan
, pcmcia_childdetached
, DVF_DETACH_SHUTDOWN
);
95 pcmcia_ccr_read(struct pcmcia_function
*pf
, int ccr
)
98 return (bus_space_read_1(pf
->pf_ccrt
, pf
->pf_ccrh
,
99 pf
->pf_ccr_offset
+ ccr
* 2));
103 pcmcia_ccr_write(struct pcmcia_function
*pf
, int ccr
, int val
)
106 if (pf
->ccr_mask
& (1 << ccr
)) {
107 bus_space_write_1(pf
->pf_ccrt
, pf
->pf_ccrh
,
108 pf
->pf_ccr_offset
+ ccr
* 2, val
);
113 pcmcia_match(device_t parent
, cfdata_t match
, void *aux
)
115 struct pcmciabus_attach_args
*paa
= aux
;
117 if (strcmp(paa
->paa_busname
, match
->cf_name
)) {
120 /* if the autoconfiguration got this far, there's a socket here */
125 pcmcia_attach(device_t parent
, device_t self
, void *aux
)
127 struct pcmciabus_attach_args
*paa
= aux
;
128 struct pcmcia_softc
*sc
= device_private(self
);
136 sc
->iobase
= paa
->iobase
;
137 sc
->iosize
= paa
->iosize
;
141 if (!pmf_device_register(self
, NULL
, NULL
))
142 aprint_error_dev(self
, "couldn't establish power handler\n");
146 pcmcia_detach(device_t self
, int flags
)
150 if ((rc
= config_detach_children(self
, flags
)) != 0)
153 pmf_device_deregister(self
);
158 pcmcia_card_attach(device_t dev
)
160 struct pcmcia_softc
*sc
= device_private(dev
);
161 struct pcmcia_function
*pf
;
163 static const int wildcard
[PCMCIACF_NLOCS
] = {
164 PCMCIACF_FUNCTION_DEFAULT
168 * this is here so that when socket_enable calls gettype, trt happens
170 SIMPLEQ_FIRST(&sc
->card
.pf_head
) = NULL
;
172 pcmcia_socket_enable(dev
);
175 pcmcia_check_cis_quirks(sc
);
177 #if 1 /* XXX remove this, done below ??? */
179 * bail now if the card has no functions, or if there was an error in
182 if (sc
->card
.error
||
183 SIMPLEQ_EMPTY(&sc
->card
.pf_head
)) {
184 printf("%s: card appears to have bogus CIS\n",
185 device_xname(sc
->dev
));
192 pcmcia_print_cis(sc
);
194 SIMPLEQ_FOREACH(pf
, &sc
->card
.pf_head
, pf_list
) {
195 if (SIMPLEQ_EMPTY(&pf
->cfe_head
))
199 if (pf
->child
!= NULL
) {
200 printf("%s: %s still attached to function %d!\n",
201 device_xname(sc
->dev
), device_xname(pf
->child
),
203 panic("pcmcia_card_attach");
212 error
= pcmcia_rescan(dev
, "pcmcia", wildcard
);
214 pcmcia_socket_disable(dev
);
219 pcmcia_rescan(device_t self
, const char *ifattr
,
222 struct pcmcia_softc
*sc
= device_private(self
);
223 struct pcmcia_function
*pf
;
224 struct pcmcia_attach_args paa
;
225 int locs
[PCMCIACF_NLOCS
];
227 if (sc
->card
.error
||
228 SIMPLEQ_EMPTY(&sc
->card
.pf_head
)) {
229 /* XXX silently ignore if no card present? */
233 SIMPLEQ_FOREACH(pf
, &sc
->card
.pf_head
, pf_list
) {
234 if (SIMPLEQ_EMPTY(&pf
->cfe_head
))
237 if ((locators
[PCMCIACF_FUNCTION
] != PCMCIACF_FUNCTION_DEFAULT
)
238 && (locators
[PCMCIACF_FUNCTION
] != pf
->number
))
244 locs
[PCMCIACF_FUNCTION
] = pf
->number
;
246 paa
.manufacturer
= sc
->card
.manufacturer
;
247 paa
.product
= sc
->card
.product
;
248 paa
.card
= &sc
->card
;
251 pf
->child
= config_found_sm_loc(self
, "pcmcia", locs
, &paa
,
260 pcmcia_card_detach(device_t dev
, int flags
)
261 /* flags: DETACH_* flags */
263 struct pcmcia_softc
*sc
= device_private(dev
);
264 struct pcmcia_function
*pf
;
268 * We are running on either the PCMCIA socket's event thread
269 * or in user context detaching a device by user request.
271 SIMPLEQ_FOREACH(pf
, &sc
->card
.pf_head
, pf_list
) {
272 pf
->pf_flags
|= PFF_DETACHED
;
273 if (SIMPLEQ_EMPTY(&pf
->cfe_head
))
275 if (pf
->child
== NULL
)
277 DPRINTF(("%s: detaching %s (function %d)\n",
278 device_xname(sc
->dev
), device_xname(pf
->child
), pf
->number
));
279 if ((error
= config_detach(pf
->child
, flags
)) != 0) {
280 printf("%s: error %d detaching %s (function %d)\n",
281 device_xname(sc
->dev
), error
, device_xname(pf
->child
),
286 if (sc
->sc_enabled_count
!= 0) {
288 printf("pcmcia_card_detach: enabled_count should be 0 here??\n");
290 pcmcia_chip_socket_disable(sc
->pct
, sc
->pch
);
291 sc
->sc_enabled_count
= 0;
296 pcmcia_childdetached(device_t self
, device_t child
)
298 struct pcmcia_softc
*sc
= device_private(self
);
299 struct pcmcia_function
*pf
;
301 SIMPLEQ_FOREACH(pf
, &sc
->card
.pf_head
, pf_list
) {
302 if (SIMPLEQ_EMPTY(&pf
->cfe_head
))
304 if (pf
->child
== child
) {
305 KASSERT(device_locator(child
, PCMCIACF_FUNCTION
)
312 aprint_error_dev(self
, "pcmcia_childdetached: %s not found\n",
313 device_xname(child
));
317 pcmcia_card_deactivate(device_t dev
)
319 struct pcmcia_softc
*sc
= device_private(dev
);
320 struct pcmcia_function
*pf
;
323 * We're in the chip's card removal interrupt handler.
324 * Deactivate the child driver. The PCMCIA socket's
325 * event thread will run later to finish the detach.
327 SIMPLEQ_FOREACH(pf
, &sc
->card
.pf_head
, pf_list
) {
328 if (SIMPLEQ_EMPTY(&pf
->cfe_head
))
330 if (pf
->child
== NULL
)
332 DPRINTF(("%s: deactivating %s (function %d)\n",
333 device_xname(sc
->dev
), device_xname(pf
->child
), pf
->number
));
334 config_deactivate(pf
->child
);
339 pcmcia_print(void *arg
, const char *pnp
)
341 struct pcmcia_attach_args
*pa
= arg
;
342 struct pcmcia_softc
*sc
= pa
->pf
->sc
;
343 struct pcmcia_card
*card
= &sc
->card
;
347 aprint_normal("%s", pnp
);
349 pcmcia_devinfo(card
, !!pnp
, devinfo
, sizeof(devinfo
));
351 aprint_normal(" function %d: %s\n", pa
->pf
->number
, devinfo
);
357 pcmcia_devinfo(struct pcmcia_card
*card
, int showhex
, char *cp
, size_t cplen
)
367 for (i
= 0; i
< 4 && card
->cis1_info
[i
] != NULL
&& cplen
> 1; i
++) {
368 n
= snprintf(cp
, cplen
, "%s%s", i
? ", " : "",
382 if (showhex
&& cplen
> 1)
383 snprintf(cp
, cplen
, " (manufacturer 0x%04x, product 0x%04x)",
384 card
->manufacturer
, card
->product
);
388 pcmcia_product_lookup(struct pcmcia_attach_args
*pa
, const void *tab
, size_t nent
, size_t ent_size
, pcmcia_product_match_fn matchfn
)
390 const struct pcmcia_product
*pp
;
395 if (sizeof *pp
> ent_size
)
396 panic("pcmcia_product_lookup: bogus ent_size %ld",
400 for (pp
= tab
, n
= nent
; n
; pp
= (const struct pcmcia_product
*)
401 ((const char *)pp
+ ent_size
), n
--) {
402 /* see if it matches vendor/product */
404 if ((pp
->pp_vendor
!= PCMCIA_VENDOR_INVALID
&&
405 pp
->pp_vendor
== pa
->manufacturer
) &&
406 (pp
->pp_product
!= PCMCIA_PRODUCT_INVALID
&&
407 pp
->pp_product
== pa
->product
))
409 if ((pp
->pp_cisinfo
[0] && pa
->card
->cis1_info
[0] &&
410 !strcmp(pp
->pp_cisinfo
[0], pa
->card
->cis1_info
[0])) &&
411 (pp
->pp_cisinfo
[1] && pa
->card
->cis1_info
[1] &&
412 !strcmp(pp
->pp_cisinfo
[1], pa
->card
->cis1_info
[1])) &&
413 (!pp
->pp_cisinfo
[2] || (pa
->card
->cis1_info
[2] &&
414 !strcmp(pp
->pp_cisinfo
[2], pa
->card
->cis1_info
[2]))) &&
415 (!pp
->pp_cisinfo
[3] || (pa
->card
->cis1_info
[3] &&
416 !strcmp(pp
->pp_cisinfo
[3], pa
->card
->cis1_info
[3]))))
419 /* if a separate match function is given, let it override */
421 matches
= (*matchfn
)(pa
, pp
, matches
);
430 pcmcia_socket_settype(device_t dev
, int type
)
432 struct pcmcia_softc
*sc
= device_private(dev
);
434 pcmcia_chip_socket_settype(sc
->pct
, sc
->pch
, type
);
438 * Initialize a PCMCIA function. May be called as long as the function is
442 pcmcia_function_init(struct pcmcia_function
*pf
, struct pcmcia_config_entry
*cfe
)
444 if (pf
->pf_flags
& PFF_ENABLED
)
445 panic("pcmcia_function_init: function is enabled");
447 /* Remember which configuration entry we are using. */
452 pcmcia_socket_enable(device_t dev
)
454 struct pcmcia_softc
*sc
= device_private(dev
);
456 if (sc
->sc_enabled_count
++ == 0)
457 pcmcia_chip_socket_enable(sc
->pct
, sc
->pch
);
458 DPRINTF(("%s: ++enabled_count = %d\n", device_xname(sc
->dev
),
459 sc
->sc_enabled_count
));
463 pcmcia_socket_disable(device_t dev
)
465 struct pcmcia_softc
*sc
= device_private(dev
);
467 if (--sc
->sc_enabled_count
== 0)
468 pcmcia_chip_socket_disable(sc
->pct
, sc
->pch
);
469 DPRINTF(("%s: --enabled_count = %d\n", device_xname(sc
->dev
),
470 sc
->sc_enabled_count
));
473 /* Enable a PCMCIA function */
475 pcmcia_function_enable(struct pcmcia_function
*pf
)
477 struct pcmcia_softc
*sc
= pf
->sc
;
478 struct pcmcia_function
*tmp
;
483 panic("pcmcia_function_enable: function not initialized");
486 * Increase the reference count on the socket, enabling power, if
489 pcmcia_socket_enable(sc
->dev
);
490 pcmcia_socket_settype(sc
->dev
, pf
->cfe
->iftype
);
492 if (pf
->pf_flags
& PFF_ENABLED
) {
494 * Don't do anything if we're already enabled.
500 * it's possible for different functions' CCRs to be in the same
501 * underlying page. Check for that.
504 SIMPLEQ_FOREACH(tmp
, &sc
->card
.pf_head
, pf_list
) {
505 if ((tmp
->pf_flags
& PFF_ENABLED
) &&
506 (pf
->ccr_base
>= (tmp
->ccr_base
- tmp
->pf_ccr_offset
)) &&
507 ((pf
->ccr_base
+ PCMCIA_CCR_SIZE
) <=
508 (tmp
->ccr_base
- tmp
->pf_ccr_offset
+
509 tmp
->pf_ccr_realsize
))) {
510 pf
->pf_ccrt
= tmp
->pf_ccrt
;
511 pf
->pf_ccrh
= tmp
->pf_ccrh
;
512 pf
->pf_ccr_realsize
= tmp
->pf_ccr_realsize
;
515 * pf->pf_ccr_offset = (tmp->pf_ccr_offset -
516 * tmp->ccr_base) + pf->ccr_base;
519 (tmp
->pf_ccr_offset
+ pf
->ccr_base
) -
521 pf
->pf_ccr_window
= tmp
->pf_ccr_window
;
527 error
= pcmcia_mem_alloc(pf
, PCMCIA_CCR_SIZE
, &pf
->pf_pcmh
);
531 error
= pcmcia_mem_map(pf
, PCMCIA_MEM_ATTR
, pf
->ccr_base
,
532 PCMCIA_CCR_SIZE
, &pf
->pf_pcmh
, &pf
->pf_ccr_offset
,
535 pcmcia_mem_free(pf
, &pf
->pf_pcmh
);
540 if (pcmcia_mfc(sc
) || 1) {
541 pcmcia_ccr_write(pf
, PCMCIA_CCR_IOBASE0
,
542 (pf
->pf_mfc_iobase
>> 0) & 0xff);
543 pcmcia_ccr_write(pf
, PCMCIA_CCR_IOBASE1
,
544 (pf
->pf_mfc_iobase
>> 8) & 0xff);
545 pcmcia_ccr_write(pf
, PCMCIA_CCR_IOBASE2
,
546 (pf
->pf_mfc_iobase
>> 16) & 0xff);
547 pcmcia_ccr_write(pf
, PCMCIA_CCR_IOBASE3
,
548 (pf
->pf_mfc_iobase
>> 24) & 0xff);
549 pcmcia_ccr_write(pf
, PCMCIA_CCR_IOLIMIT
,
550 pf
->pf_mfc_iomax
- pf
->pf_mfc_iobase
);
554 if (pf
->cfe
->flags
& PCMCIA_CFE_AUDIO
)
555 reg
|= PCMCIA_CCR_STATUS_AUDIO
;
556 pcmcia_ccr_write(pf
, PCMCIA_CCR_STATUS
, reg
);
558 pcmcia_ccr_write(pf
, PCMCIA_CCR_SOCKETCOPY
, 0);
560 reg
= (pf
->cfe
->number
& PCMCIA_CCR_OPTION_CFINDEX
);
561 reg
|= PCMCIA_CCR_OPTION_LEVIREQ
;
562 if (pcmcia_mfc(sc
)) {
563 reg
|= (PCMCIA_CCR_OPTION_FUNC_ENABLE
|
564 PCMCIA_CCR_OPTION_ADDR_DECODE
);
566 reg
|= PCMCIA_CCR_OPTION_IREQ_ENABLE
;
569 pcmcia_ccr_write(pf
, PCMCIA_CCR_OPTION
, reg
);
573 SIMPLEQ_FOREACH(tmp
, &sc
->card
.pf_head
, pf_list
) {
574 printf("%s: function %d CCR at %d offset %lx: "
575 "%x %x %x %x, %x %x %x %x, %x\n",
576 device_xname(tmp
->sc
->dev
), tmp
->number
,
578 (unsigned long) tmp
->pf_ccr_offset
,
579 pcmcia_ccr_read(tmp
, 0),
580 pcmcia_ccr_read(tmp
, 1),
581 pcmcia_ccr_read(tmp
, 2),
582 pcmcia_ccr_read(tmp
, 3),
584 pcmcia_ccr_read(tmp
, 5),
585 pcmcia_ccr_read(tmp
, 6),
586 pcmcia_ccr_read(tmp
, 7),
587 pcmcia_ccr_read(tmp
, 8),
589 pcmcia_ccr_read(tmp
, 9));
594 #ifdef IT8368E_LEGACY_MODE
595 /* return to I/O mode */
596 it8368_mode(pf
, IT8368_IO_MODE
, IT8368_WIDTH_16
);
599 pf
->pf_flags
|= PFF_ENABLED
;
604 * Decrement the reference count, and power down the socket, if
607 printf("%s: couldn't map the CCR\n", device_xname(pf
->child
));
608 pcmcia_socket_disable(sc
->dev
);
613 /* Disable PCMCIA function. */
615 pcmcia_function_disable(struct pcmcia_function
*pf
)
617 struct pcmcia_softc
*sc
= pf
->sc
;
618 struct pcmcia_function
*tmp
;
622 panic("pcmcia_function_enable: function not initialized");
624 if ((pf
->pf_flags
& PFF_ENABLED
) == 0) {
626 * Don't do anything but decrement if we're already disabled.
631 if (pcmcia_mfc(sc
) &&
632 (pf
->pf_flags
& PFF_DETACHED
) == 0) {
633 reg
= pcmcia_ccr_read(pf
, PCMCIA_CCR_OPTION
);
634 reg
&= ~(PCMCIA_CCR_OPTION_FUNC_ENABLE
|
635 PCMCIA_CCR_OPTION_ADDR_DECODE
|
636 PCMCIA_CCR_OPTION_IREQ_ENABLE
);
637 pcmcia_ccr_write(pf
, PCMCIA_CCR_OPTION
, reg
);
641 * it's possible for different functions' CCRs to be in the same
642 * underlying page. Check for that. Note we mark us as disabled
643 * first to avoid matching ourself.
646 pf
->pf_flags
&= ~PFF_ENABLED
;
647 SIMPLEQ_FOREACH(tmp
, &sc
->card
.pf_head
, pf_list
) {
648 if ((tmp
->pf_flags
& PFF_ENABLED
) &&
649 (pf
->ccr_base
>= (tmp
->ccr_base
- tmp
->pf_ccr_offset
)) &&
650 ((pf
->ccr_base
+ PCMCIA_CCR_SIZE
) <=
651 (tmp
->ccr_base
- tmp
->pf_ccr_offset
+ tmp
->pf_ccr_realsize
)))
655 /* Not used by anyone else; unmap the CCR. */
657 pcmcia_mem_unmap(pf
, pf
->pf_ccr_window
);
658 pcmcia_mem_free(pf
, &pf
->pf_pcmh
);
663 * Decrement the reference count, and power down the socket, if
666 pcmcia_socket_disable(sc
->dev
);
670 pcmcia_io_map(struct pcmcia_function
*pf
, int width
, struct pcmcia_io_handle
*pcihp
, int *windowp
)
672 struct pcmcia_softc
*sc
= pf
->sc
;
675 if (pf
->pf_flags
& PFF_ENABLED
)
676 printf("pcmcia_io_map: function is enabled!\n");
678 error
= pcmcia_chip_io_map(sc
->pct
, sc
->pch
,
679 width
, 0, pcihp
->size
, pcihp
, windowp
);
684 * XXX in the multifunction multi-iospace-per-function case, this
685 * needs to cooperate with io_alloc to make sure that the spaces
686 * don't overlap, and that the ccr's are set correctly
689 if (pcmcia_mfc(sc
) || 1) {
690 bus_addr_t iobase
= pcihp
->addr
;
691 bus_addr_t iomax
= pcihp
->addr
+ pcihp
->size
- 1;
693 DPRINTF(("window iobase %lx iomax %lx\n", (long)iobase
,
695 if (pf
->pf_mfc_iobase
== 0) {
696 pf
->pf_mfc_iobase
= iobase
;
697 pf
->pf_mfc_iomax
= iomax
;
699 if (iobase
< pf
->pf_mfc_iobase
)
700 pf
->pf_mfc_iobase
= iobase
;
701 if (iomax
> pf
->pf_mfc_iomax
)
702 pf
->pf_mfc_iomax
= iomax
;
704 DPRINTF(("function iobase %lx iomax %lx\n",
705 (long)pf
->pf_mfc_iobase
, (long)pf
->pf_mfc_iomax
));
712 pcmcia_io_unmap(struct pcmcia_function
*pf
, int window
)
714 struct pcmcia_softc
*sc
= pf
->sc
;
716 if (pf
->pf_flags
& PFF_ENABLED
)
717 printf("pcmcia_io_unmap: function is enabled!\n");
719 pcmcia_chip_io_unmap(sc
->pct
, sc
->pch
, window
);
723 pcmcia_intr_establish(struct pcmcia_function
*pf
, int ipl
,
724 int (*ih_fct
)(void *), void *ih_arg
)
727 if (pf
->pf_flags
& PFF_ENABLED
)
728 printf("pcmcia_intr_establish: function is enabled!\n");
730 panic("pcmcia_intr_establish: already done\n");
732 pf
->pf_ih
= pcmcia_chip_intr_establish(pf
->sc
->pct
, pf
->sc
->pch
,
733 pf
, ipl
, ih_fct
, ih_arg
);
735 aprint_error_dev(pf
->child
, "interrupt establish failed\n");
740 pcmcia_intr_disestablish(struct pcmcia_function
*pf
, void *ih
)
743 if (pf
->pf_flags
& PFF_ENABLED
)
744 printf("pcmcia_intr_disestablish: function is enabled!\n");
746 panic("pcmcia_intr_distestablish: already done\n");
748 pcmcia_chip_intr_disestablish(pf
->sc
->pct
, pf
->sc
->pch
, ih
);
753 pcmcia_config_alloc(struct pcmcia_function
*pf
, struct pcmcia_config_entry
*cfe
)
758 for (n
= 0; n
< cfe
->num_iospace
; n
++) {
759 bus_addr_t start
= cfe
->iospace
[n
].start
;
760 bus_size_t length
= cfe
->iospace
[n
].length
;
761 bus_size_t align
= cfe
->iomask
? (1 << cfe
->iomask
) :
763 bus_size_t skew
= start
& (align
- 1);
765 if ((start
- skew
) == 0 && align
< 0x400) {
767 printf("Drats! I need a skew!\n");
771 DPRINTF(("pcmcia_config_alloc: io %d start=%lx length=%lx align=%lx skew=%lx\n",
772 n
, (long)start
, (long)length
, (long)align
, (long)skew
));
774 error
= pcmcia_io_alloc(pf
, start
, length
, align
,
775 &cfe
->iospace
[n
].handle
);
779 if (n
< cfe
->num_iospace
) {
780 for (m
= 0; m
< n
; m
++)
781 pcmcia_io_free(pf
, &cfe
->iospace
[m
].handle
);
785 for (n
= 0; n
< cfe
->num_memspace
; n
++) {
786 bus_size_t length
= cfe
->memspace
[n
].length
;
788 DPRINTF(("pcmcia_config_alloc: mem %d length %lx\n", n
,
791 error
= pcmcia_mem_alloc(pf
, length
, &cfe
->memspace
[n
].handle
);
795 if (n
< cfe
->num_memspace
) {
796 for (m
= 0; m
< cfe
->num_iospace
; m
++)
797 pcmcia_io_free(pf
, &cfe
->iospace
[m
].handle
);
798 for (m
= 0; m
< n
; m
++)
799 pcmcia_mem_free(pf
, &cfe
->memspace
[m
].handle
);
803 /* This one's good! */
808 pcmcia_config_free(struct pcmcia_function
*pf
)
810 struct pcmcia_config_entry
*cfe
= pf
->cfe
;
813 for (m
= 0; m
< cfe
->num_iospace
; m
++)
814 pcmcia_io_free(pf
, &cfe
->iospace
[m
].handle
);
815 for (m
= 0; m
< cfe
->num_memspace
; m
++)
816 pcmcia_mem_free(pf
, &cfe
->memspace
[m
].handle
);
820 pcmcia_config_map(struct pcmcia_function
*pf
)
822 struct pcmcia_config_entry
*cfe
= pf
->cfe
;
826 for (n
= 0; n
< cfe
->num_iospace
; n
++) {
829 if (cfe
->flags
& PCMCIA_CFE_IO16
)
830 width
= PCMCIA_WIDTH_AUTO
;
832 width
= PCMCIA_WIDTH_IO8
;
833 error
= pcmcia_io_map(pf
, width
, &cfe
->iospace
[n
].handle
,
834 &cfe
->iospace
[n
].window
);
838 if (n
< cfe
->num_iospace
) {
839 for (m
= 0; m
< n
; m
++)
840 pcmcia_io_unmap(pf
, cfe
->iospace
[m
].window
);
844 for (n
= 0; n
< cfe
->num_memspace
; n
++) {
845 bus_size_t length
= cfe
->memspace
[n
].length
;
848 DPRINTF(("pcmcia_config_alloc: mem %d length %lx\n", n
,
852 width
= PCMCIA_WIDTH_MEM8
|PCMCIA_MEM_COMMON
;
853 error
= pcmcia_mem_map(pf
, width
, 0, length
,
854 &cfe
->memspace
[n
].handle
, &cfe
->memspace
[n
].offset
,
855 &cfe
->memspace
[n
].window
);
859 if (n
< cfe
->num_memspace
) {
860 for (m
= 0; m
< cfe
->num_iospace
; m
++)
861 pcmcia_io_unmap(pf
, cfe
->iospace
[m
].window
);
862 for (m
= 0; m
< n
; m
++)
863 pcmcia_mem_unmap(pf
, cfe
->memspace
[m
].window
);
867 /* This one's good! */
872 pcmcia_config_unmap(struct pcmcia_function
*pf
)
874 struct pcmcia_config_entry
*cfe
= pf
->cfe
;
877 for (m
= 0; m
< cfe
->num_iospace
; m
++)
878 pcmcia_io_unmap(pf
, cfe
->iospace
[m
].window
);
879 for (m
= 0; m
< cfe
->num_memspace
; m
++)
880 pcmcia_mem_unmap(pf
, cfe
->memspace
[m
].window
);
884 pcmcia_function_configure(struct pcmcia_function
*pf
,
885 int (*validator
)(struct pcmcia_config_entry
*))
887 struct pcmcia_config_entry
*cfe
;
890 SIMPLEQ_FOREACH(cfe
, &pf
->cfe_head
, cfe_list
) {
891 error
= validator(cfe
);
894 error
= pcmcia_config_alloc(pf
, cfe
);
899 DPRINTF(("pcmcia_function_configure: no config entry found, error=%d\n",
904 /* Remember which configuration entry we are using. */
907 error
= pcmcia_config_map(pf
);
909 DPRINTF(("pcmcia_function_configure: map failed, error=%d\n",
918 pcmcia_function_unconfigure(struct pcmcia_function
*pf
)
921 pcmcia_config_unmap(pf
);
922 pcmcia_config_free(pf
);