1 /* $NetBSD: jmide.c,v 1.6 2008/06/05 18:22:02 bouyer Exp $ */
4 * Copyright (c) 2007 Manuel Bouyer.
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.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <sys/cdefs.h>
28 __KERNEL_RCSID(0, "$NetBSD: jmide.c,v 1.6 2008/06/05 18:22:02 bouyer Exp $");
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/malloc.h>
34 #include <dev/pci/pcivar.h>
35 #include <dev/pci/pcidevs.h>
36 #include <dev/pci/pciidereg.h>
37 #include <dev/pci/pciidevar.h>
39 #include <dev/pci/jmide_reg.h>
41 #include <dev/ic/ahcisatavar.h>
45 static const struct jmide_product
*jmide_lookup(pcireg_t
);
47 static int jmide_match(device_t
, cfdata_t
, void *);
48 static void jmide_attach(device_t
, device_t
, void *);
49 static int jmide_intr(void *);
51 static void jmpata_chip_map(struct pciide_softc
*, struct pci_attach_args
*);
52 static void jmpata_setup_channel(struct ata_channel
*);
54 static int jmahci_print(void *, const char *);
56 struct jmide_product
{
62 static const struct jmide_product jm_products
[] = {
63 { PCI_PRODUCT_JMICRON_JMB360
,
67 { PCI_PRODUCT_JMICRON_JMB361
,
71 { PCI_PRODUCT_JMICRON_JMB363
,
75 { PCI_PRODUCT_JMICRON_JMB365
,
79 { PCI_PRODUCT_JMICRON_JMB366
,
83 { PCI_PRODUCT_JMICRON_JMB368
,
101 struct pciide_softc sc_pciide
;
105 jmchan_t sc_chan_type
[PCIIDE_NUM_CHANNELS
];
109 struct jmahci_attach_args
{
110 struct pci_attach_args
*jma_pa
;
111 bus_space_tag_t jma_ahcit
;
112 bus_space_handle_t jma_ahcih
;
115 #define JM_NAME(sc) (device_xname(sc->sc_pciide.sc_wdcdev.sc_atac.atac_dev))
117 CFATTACH_DECL_NEW(jmide
, sizeof(struct jmide_softc
),
118 jmide_match
, jmide_attach
, NULL
, NULL
);
120 static const struct jmide_product
*
121 jmide_lookup(pcireg_t id
) {
122 const struct jmide_product
*jp
;
124 for (jp
= jm_products
; jp
->jm_product
!= 0; jp
++) {
125 if (jp
->jm_product
== PCI_PRODUCT(id
))
132 jmide_match(device_t parent
, cfdata_t match
, void *aux
)
134 struct pci_attach_args
*pa
= aux
;
136 if (PCI_VENDOR(pa
->pa_id
) == PCI_VENDOR_JMICRON
) {
137 if (jmide_lookup(pa
->pa_id
))
138 return (4); /* highter than ahcisata */
144 jmide_attach(device_t parent
, device_t self
, void *aux
)
146 struct pci_attach_args
*pa
= aux
;
147 struct jmide_softc
*sc
= device_private(self
);
148 const struct jmide_product
*jp
;
151 pci_intr_handle_t intrhandle
;
152 u_int32_t pcictrl0
= pci_conf_read(pa
->pa_pc
, pa
->pa_tag
,
154 u_int32_t pcictrl1
= pci_conf_read(pa
->pa_pc
, pa
->pa_tag
,
156 struct pciide_product_desc
*pp
;
159 sc
->sc_pciide
.sc_wdcdev
.sc_atac
.atac_dev
= self
;
161 jp
= jmide_lookup(pa
->pa_id
);
163 printf("jmide_attach: WTF?\n");
166 sc
->sc_npata
= jp
->jm_npata
;
167 sc
->sc_nsata
= jp
->jm_nsata
;
169 pci_devinfo(pa
->pa_id
, pa
->pa_class
, 0, devinfo
, sizeof(devinfo
));
170 aprint_naive(": JMICRON PATA/SATA disk controller\n");
171 aprint_normal(": %s\n", devinfo
);
173 aprint_normal("%s: ", JM_NAME(sc
));
175 aprint_normal("%d PATA port%s", sc
->sc_npata
,
176 (sc
->sc_npata
> 1) ? "s" : "");
178 aprint_normal("%s%d SATA port%s", sc
->sc_npata
? ", " : "",
179 sc
->sc_nsata
, (sc
->sc_nsata
> 1) ? "s" : "");
182 if (pci_intr_map(pa
, &intrhandle
) != 0) {
183 aprint_error("%s: couldn't map interrupt\n", JM_NAME(sc
));
186 intrstr
= pci_intr_string(pa
->pa_pc
, intrhandle
);
187 sc
->sc_pciide
.sc_pci_ih
= pci_intr_establish(pa
->pa_pc
, intrhandle
,
188 IPL_BIO
, jmide_intr
, sc
);
189 if (sc
->sc_pciide
.sc_pci_ih
== NULL
) {
190 aprint_error("%s: couldn't establish interrupt", JM_NAME(sc
));
193 aprint_normal("%s: interrupting at %s\n", JM_NAME(sc
),
194 intrstr
? intrstr
: "unknown interrupt");
196 if (pcictrl0
& JM_CONTROL0_AHCI_EN
) {
198 struct jmahci_attach_args jma
;
199 u_int32_t saved_pcictrl0
;
201 * ahci controller enabled; disable sata on pciide and
204 saved_pcictrl0
= pcictrl0
;
205 pcictrl0
|= JM_CONTROL0_SATA0_AHCI
| JM_CONTROL0_SATA1_AHCI
;
206 pcictrl0
&= ~(JM_CONTROL0_SATA0_IDE
| JM_CONTROL0_SATA1_IDE
);
207 pci_conf_write(pa
->pa_pc
, pa
->pa_tag
,
208 PCI_JM_CONTROL0
, pcictrl0
);
209 /* attach ahci controller if on the right function */
210 if ((pa
->pa_function
== 0 &&
211 (pcictrl0
& JM_CONTROL0_AHCI_F1
) == 0) ||
212 (pa
->pa_function
== 1 &&
213 (pcictrl0
& JM_CONTROL0_AHCI_F1
) != 0)) {
216 if (pci_mapreg_map(pa
, AHCI_PCI_ABAR
,
217 PCI_MAPREG_TYPE_MEM
| PCI_MAPREG_MEM_TYPE_32BIT
, 0,
218 &jma
.jma_ahcit
, &jma
.jma_ahcih
, NULL
, &size
) != 0) {
219 aprint_error("%s: can't map ahci registers\n",
222 sc
->sc_ahci
= config_found_ia(
223 sc
->sc_pciide
.sc_wdcdev
.sc_atac
.atac_dev
,
224 "jmide_hl", &jma
, jmahci_print
);
227 * if we couldn't attach an ahci, try to fall back
228 * to pciide. Note that this will not work if IDE
229 * is on function 0 and AHCI on function 1.
231 if (sc
->sc_ahci
== NULL
) {
232 pcictrl0
= saved_pcictrl0
&
233 ~(JM_CONTROL0_SATA0_AHCI
|
234 JM_CONTROL0_SATA1_AHCI
|
235 JM_CONTROL0_AHCI_EN
);
236 pcictrl0
|= JM_CONTROL0_SATA1_IDE
|
237 JM_CONTROL0_SATA0_IDE
;
238 pci_conf_write(pa
->pa_pc
, pa
->pa_tag
,
239 PCI_JM_CONTROL0
, pcictrl0
);
244 sc
->sc_chan_swap
= ((pcictrl0
& JM_CONTROL0_PCIIDE_CS
) != 0);
245 /* compute the type of internal primary channel */
246 if (pcictrl1
& JM_CONTROL1_PATA1_PRI
) {
247 if (sc
->sc_npata
> 1)
248 sc
->sc_chan_type
[sc
->sc_chan_swap
? 1 : 0] = TYPE_PATA
;
250 sc
->sc_chan_type
[sc
->sc_chan_swap
? 1 : 0] = TYPE_NONE
;
251 } else if (ahci_used
== 0 && sc
->sc_nsata
> 0)
252 sc
->sc_chan_type
[sc
->sc_chan_swap
? 1 : 0] = TYPE_SATA
;
254 sc
->sc_chan_type
[sc
->sc_chan_swap
? 1 : 0] = TYPE_NONE
;
255 /* compute the type of internal secondary channel */
256 if (sc
->sc_nsata
> 1 && ahci_used
== 0 &&
257 (pcictrl0
& JM_CONTROL0_PCIIDE0_MS
) == 0) {
258 sc
->sc_chan_type
[sc
->sc_chan_swap
? 0 : 1] = TYPE_SATA
;
260 /* only a drive if first PATA enabled */
261 if (sc
->sc_npata
> 0 && (pcictrl0
& JM_CONTROL0_PATA0_EN
)
263 (sc
->sc_chan_swap
? JM_CONTROL0_PATA0_PRI
: JM_CONTROL0_PATA0_SEC
)))
264 sc
->sc_chan_type
[sc
->sc_chan_swap
? 0 : 1] = TYPE_PATA
;
266 sc
->sc_chan_type
[sc
->sc_chan_swap
? 0 : 1] = TYPE_NONE
;
269 if (sc
->sc_chan_type
[0] == TYPE_NONE
&&
270 sc
->sc_chan_type
[1] == TYPE_NONE
)
272 if (pa
->pa_function
== 0 && (pcictrl0
& JM_CONTROL0_PCIIDE_F1
))
274 if (pa
->pa_function
== 1 && (pcictrl0
& JM_CONTROL0_PCIIDE_F1
) == 0)
276 pp
= malloc(sizeof(struct pciide_product_desc
), M_DEVBUF
, M_NOWAIT
);
278 aprint_error("%s: can't malloc sc_pp\n", JM_NAME(sc
));
281 aprint_normal("%s: PCI IDE interface used", JM_NAME(sc
));
285 pp
->chip_map
= jmpata_chip_map
;
286 pciide_common_attach(&sc
->sc_pciide
, pa
, pp
);
291 jmide_intr(void *arg
)
293 struct jmide_softc
*sc
= arg
;
298 ret
|= ahci_intr(device_private(sc
->sc_ahci
));
301 ret
|= pciide_pci_intr(&sc
->sc_pciide
);
306 jmpata_chip_map(struct pciide_softc
*sc
, struct pci_attach_args
*pa
)
308 struct jmide_softc
*jmidesc
= (struct jmide_softc
*)sc
;
311 bus_size_t cmdsize
, ctlsize
;
312 struct pciide_channel
*cp
;
314 if (pciide_chipen(sc
, pa
) == 0)
316 aprint_verbose("%s: bus-master DMA support present", JM_NAME(jmidesc
));
317 pciide_mapreg_dma(sc
, pa
);
318 aprint_verbose("\n");
319 sc
->sc_wdcdev
.sc_atac
.atac_cap
= ATAC_CAP_DATA16
| ATAC_CAP_DATA32
;
321 sc
->sc_wdcdev
.sc_atac
.atac_cap
|= ATAC_CAP_DMA
| ATAC_CAP_UDMA
;
322 sc
->sc_wdcdev
.sc_atac
.atac_udma_cap
= 6;
324 sc
->sc_wdcdev
.sc_atac
.atac_pio_cap
= 4;
325 sc
->sc_wdcdev
.sc_atac
.atac_dma_cap
= 2;
326 sc
->sc_wdcdev
.sc_atac
.atac_set_modes
= jmpata_setup_channel
;
327 sc
->sc_wdcdev
.sc_atac
.atac_channels
= sc
->wdc_chanarray
;
328 sc
->sc_wdcdev
.sc_atac
.atac_nchannels
= PCIIDE_NUM_CHANNELS
;
329 wdc_allocate_regs(&sc
->sc_wdcdev
);
331 * can't rely on the PCI_CLASS_REG content if the chip was in raid
332 * mode. We have to fake interface
334 interface
= PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1);
335 for (channel
= 0; channel
< sc
->sc_wdcdev
.sc_atac
.atac_nchannels
;
337 cp
= &sc
->pciide_channels
[channel
];
338 if (pciide_chansetup(sc
, channel
, interface
) == 0)
340 aprint_normal("%s: %s channel is ", JM_NAME(jmidesc
),
341 PCIIDE_CHANNEL_NAME(channel
));
342 switch(jmidesc
->sc_chan_type
[channel
]) {
344 aprint_normal("PATA");
347 aprint_normal("SATA");
350 aprint_normal("unused");
353 aprint_normal("impossible");
354 panic("jmide: wrong/uninitialised channel type");
357 if (jmidesc
->sc_chan_type
[channel
] == TYPE_NONE
) {
358 cp
->ata_channel
.ch_flags
|= ATACH_DISABLED
;
361 pciide_mapchan(pa
, cp
, interface
, &cmdsize
, &ctlsize
,
367 jmpata_setup_channel(struct ata_channel
*chp
)
369 struct ata_drive_datas
*drvp
;
371 u_int32_t idedma_ctl
;
372 struct pciide_channel
*cp
= CHAN_TO_PCHAN(chp
);
373 struct pciide_softc
*sc
= CHAN_TO_PCIIDE(chp
);
374 struct jmide_softc
*jmidesc
= (struct jmide_softc
*)sc
;
377 /* setup DMA if needed */
378 pciide_channel_dma_setup(cp
);
382 /* cable type detect */
384 if (chp
->ch_channel
== (jmidesc
->sc_chan_swap
? 1 : 0)) {
385 if (jmidesc
->sc_chan_type
[chp
->ch_channel
] == TYPE_PATA
&&
386 (pci_conf_read(sc
->sc_pc
, sc
->sc_tag
, PCI_JM_CONTROL1
) &
387 JM_CONTROL1_PATA1_40P
))
390 if (jmidesc
->sc_chan_type
[chp
->ch_channel
] == TYPE_PATA
&&
391 (pci_conf_read(sc
->sc_pc
, sc
->sc_tag
, PCI_JM_CONTROL0
) &
392 JM_CONTROL0_PATA0_40P
))
396 for (drive
= 0; drive
< 2; drive
++) {
397 drvp
= &chp
->ch_drive
[drive
];
398 /* If no drive, skip */
399 if ((drvp
->drive_flags
& DRIVE
) == 0)
401 if (drvp
->drive_flags
& DRIVE_UDMA
) {
404 drvp
->drive_flags
&= ~DRIVE_DMA
;
405 if (drvp
->UDMA_mode
> 2 && ide80p
== 0)
408 idedma_ctl
|= IDEDMA_CTL_DRV_DMA(drive
);
409 } else if (drvp
->drive_flags
& DRIVE_DMA
) {
410 idedma_ctl
|= IDEDMA_CTL_DRV_DMA(drive
);
413 /* nothing to do to setup modes, the controller snoop SET_FEATURE cmd */
414 if (idedma_ctl
!= 0) {
415 /* Add software bits in status register */
416 bus_space_write_1(sc
->sc_dma_iot
, cp
->dma_iohs
[IDEDMA_CTL
],
422 jmahci_print(void *aux
, const char *pnp
)
425 aprint_normal("ahcisata at %s", pnp
);
432 static int jmahci_match(device_t
, cfdata_t
, void *);
433 static void jmahci_attach(device_t
, device_t
, void *);
435 CFATTACH_DECL_NEW(jmahci
, sizeof(struct ahci_softc
),
436 jmahci_match
, jmahci_attach
, NULL
, NULL
);
439 jmahci_match(device_t parent
, cfdata_t match
, void *aux
)
445 jmahci_attach(device_t parent
, device_t self
, void *aux
)
447 struct jmahci_attach_args
*jma
= aux
;
448 struct pci_attach_args
*pa
= jma
->jma_pa
;
449 struct ahci_softc
*sc
= device_private(self
);
451 aprint_naive(": AHCI disk controller\n");
454 sc
->sc_atac
.atac_dev
= self
;
455 sc
->sc_ahcit
= jma
->jma_ahcit
;
456 sc
->sc_ahcih
= jma
->jma_ahcih
;
457 sc
->sc_dmat
= jma
->jma_pa
->pa_dmat
;
459 if (PCI_SUBCLASS(pa
->pa_class
) == PCI_SUBCLASS_MASS_STORAGE_RAID
)
460 sc
->sc_atac_capflags
= ATAC_CAP_RAID
;