1 /* $NetBSD: if_cs_pcmcia.c,v 1.17 2009/05/12 13:18:04 cegger Exp $ */
4 * Copyright (c)2001 YAMAMOTO Takashi,
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: if_cs_pcmcia.c,v 1.17 2009/05/12 13:18:04 cegger Exp $");
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/device.h>
35 #include <sys/socket.h>
36 #include <sys/queue.h>
44 #include <net/if_ether.h>
45 #include <net/if_media.h>
50 #include <dev/pcmcia/pcmciareg.h>
51 #include <dev/pcmcia/pcmciavar.h>
52 #include <dev/pcmcia/pcmciadevs.h>
54 #include <dev/ic/cs89x0reg.h>
55 #include <dev/ic/cs89x0var.h>
57 struct cs_pcmcia_softc
;
59 static int cs_pcmcia_match(device_t
, cfdata_t
, void *);
60 static int cs_pcmcia_validate_config(struct pcmcia_config_entry
*);
61 static void cs_pcmcia_attach(device_t
, device_t
, void *);
62 static int cs_pcmcia_detach(device_t
, int);
63 static int cs_pcmcia_enable(struct cs_softc
*);
64 static void cs_pcmcia_disable(struct cs_softc
*);
66 struct cs_pcmcia_softc
{
67 struct cs_softc sc_cs
; /* real "cs" softc */
69 struct pcmcia_function
*sc_pf
;
72 #define CS_PCMCIA_ATTACHED 3
75 CFATTACH_DECL(cs_pcmcia
, sizeof(struct cs_pcmcia_softc
),
76 cs_pcmcia_match
, cs_pcmcia_attach
, cs_pcmcia_detach
, cs_activate
);
79 cs_pcmcia_match(device_t parent
, cfdata_t match
,
82 struct pcmcia_attach_args
*pa
= aux
;
84 if (pa
->manufacturer
== PCMCIA_VENDOR_IBM
&&
85 pa
->product
== PCMCIA_PRODUCT_IBM_ETHERJET
)
91 cs_pcmcia_validate_config(struct pcmcia_config_entry
*cfe
)
93 if (cfe
->iftype
!= PCMCIA_IFTYPE_IO
||
94 cfe
->num_memspace
!= 0 ||
95 cfe
->num_iospace
!= 1 ||
96 cfe
->iospace
[0].length
< CS8900_IOSIZE
)
102 cs_pcmcia_attach(device_t parent
, device_t self
, void *aux
)
104 struct cs_pcmcia_softc
*psc
= (void *)self
;
105 struct cs_softc
*sc
= (void *)&psc
->sc_cs
;
106 struct pcmcia_attach_args
*pa
= aux
;
107 struct pcmcia_config_entry
*cfe
;
108 struct pcmcia_function
*pf
;
111 pf
= psc
->sc_pf
= pa
->pf
;
113 error
= pcmcia_function_configure(pa
->pf
, cs_pcmcia_validate_config
);
115 aprint_error_dev(self
, "configure failed, error=%d\n",
121 sc
->sc_iot
= cfe
->iospace
[0].handle
.iot
;
122 sc
->sc_ioh
= cfe
->iospace
[0].handle
.ioh
;
124 #define CS_PCMCIA_HACK_FOR_CARDBUS
125 #ifdef CS_PCMCIA_HACK_FOR_CARDBUS
127 * XXX is there a generic way to know if it's a cardbus or not?
129 sc
->sc_cfgflags
|= CFGFLG_CARDBUS_HACK
;
132 error
= cs_pcmcia_enable(sc
);
136 sc
->sc_enable
= cs_pcmcia_enable
;
137 sc
->sc_disable
= cs_pcmcia_disable
;
140 error
= cs_attach(sc
, 0, 0, 0, 0);
144 cs_pcmcia_disable(sc
);
145 psc
->sc_state
= CS_PCMCIA_ATTACHED
;
149 cs_pcmcia_disable(sc
);
151 pcmcia_function_unconfigure(pf
);
155 cs_pcmcia_detach(device_t self
, int flags
)
157 struct cs_pcmcia_softc
*psc
= (void *)self
;
158 struct cs_softc
*sc
= &psc
->sc_cs
;
161 if (psc
->sc_state
!= CS_PCMCIA_ATTACHED
)
164 error
= cs_detach(sc
);
168 pcmcia_function_unconfigure(psc
->sc_pf
);
174 cs_pcmcia_enable(struct cs_softc
*sc
)
176 struct cs_pcmcia_softc
*psc
= (void *)sc
;
179 sc
->sc_ih
= pcmcia_intr_establish(psc
->sc_pf
, IPL_NET
, cs_intr
, sc
);
183 error
= pcmcia_function_enable(psc
->sc_pf
);
185 pcmcia_intr_disestablish(psc
->sc_pf
, sc
->sc_ih
);
193 cs_pcmcia_disable(struct cs_softc
*sc
)
195 struct cs_pcmcia_softc
*psc
= (void *)sc
;
197 pcmcia_function_disable(psc
->sc_pf
);
198 pcmcia_intr_disestablish(psc
->sc_pf
, sc
->sc_ih
);