Home | History | Annotate | Line # | Download | only in pci
jmide.c revision 1.18
      1  1.18    bouyer /*	$NetBSD: jmide.c,v 1.18 2012/07/31 15:50:36 bouyer Exp $	*/
      2   1.1    bouyer 
      3   1.1    bouyer /*
      4   1.1    bouyer  * Copyright (c) 2007 Manuel Bouyer.
      5   1.1    bouyer  *
      6   1.1    bouyer  * Redistribution and use in source and binary forms, with or without
      7   1.1    bouyer  * modification, are permitted provided that the following conditions
      8   1.1    bouyer  * are met:
      9   1.1    bouyer  * 1. Redistributions of source code must retain the above copyright
     10   1.1    bouyer  *    notice, this list of conditions and the following disclaimer.
     11   1.1    bouyer  * 2. Redistributions in binary form must reproduce the above copyright
     12   1.1    bouyer  *    notice, this list of conditions and the following disclaimer in the
     13   1.1    bouyer  *    documentation and/or other materials provided with the distribution.
     14   1.1    bouyer  *
     15   1.1    bouyer  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16   1.1    bouyer  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     17   1.1    bouyer  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     18   1.1    bouyer  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     19   1.1    bouyer  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     20   1.1    bouyer  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     21   1.1    bouyer  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     22   1.1    bouyer  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23   1.1    bouyer  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     24   1.1    bouyer  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25   1.1    bouyer  */
     26   1.1    bouyer 
     27   1.1    bouyer #include <sys/cdefs.h>
     28  1.18    bouyer __KERNEL_RCSID(0, "$NetBSD: jmide.c,v 1.18 2012/07/31 15:50:36 bouyer Exp $");
     29   1.1    bouyer 
     30   1.1    bouyer #include <sys/param.h>
     31   1.1    bouyer #include <sys/systm.h>
     32   1.1    bouyer #include <sys/malloc.h>
     33   1.1    bouyer 
     34   1.1    bouyer #include <dev/pci/pcivar.h>
     35   1.1    bouyer #include <dev/pci/pcidevs.h>
     36   1.1    bouyer #include <dev/pci/pciidereg.h>
     37   1.1    bouyer #include <dev/pci/pciidevar.h>
     38   1.1    bouyer 
     39   1.1    bouyer #include <dev/pci/jmide_reg.h>
     40   1.1    bouyer 
     41   1.1    bouyer #include <dev/ic/ahcisatavar.h>
     42   1.1    bouyer 
     43   1.1    bouyer #include "jmide.h"
     44   1.1    bouyer 
     45   1.1    bouyer static const struct jmide_product *jmide_lookup(pcireg_t);
     46   1.1    bouyer 
     47   1.4      cube static int  jmide_match(device_t, cfdata_t, void *);
     48   1.4      cube static void jmide_attach(device_t, device_t, void *);
     49   1.1    bouyer static int  jmide_intr(void *);
     50   1.1    bouyer 
     51  1.10    dyoung static void jmpata_chip_map(struct pciide_softc*, const struct pci_attach_args*);
     52   1.1    bouyer static void jmpata_setup_channel(struct ata_channel*);
     53   1.1    bouyer 
     54   1.1    bouyer static int  jmahci_print(void *, const char *);
     55   1.1    bouyer 
     56   1.1    bouyer struct jmide_product {
     57   1.1    bouyer 	u_int32_t jm_product;
     58   1.1    bouyer 	int jm_npata;
     59   1.1    bouyer 	int jm_nsata;
     60   1.1    bouyer };
     61   1.1    bouyer 
     62   1.1    bouyer static const struct jmide_product jm_products[] =  {
     63   1.1    bouyer 	{ PCI_PRODUCT_JMICRON_JMB360,
     64   1.1    bouyer 	  0,
     65   1.1    bouyer 	  1
     66   1.1    bouyer 	},
     67   1.1    bouyer 	{ PCI_PRODUCT_JMICRON_JMB361,
     68   1.1    bouyer 	  1,
     69   1.1    bouyer 	  1
     70   1.1    bouyer 	},
     71  1.13  pgoyette 	{ PCI_PRODUCT_JMICRON_JMB362,
     72  1.13  pgoyette 	  0,
     73  1.13  pgoyette 	  2
     74  1.13  pgoyette 	},
     75   1.1    bouyer 	{ PCI_PRODUCT_JMICRON_JMB363,
     76   1.1    bouyer 	  1,
     77   1.1    bouyer 	  2
     78   1.1    bouyer 	},
     79   1.1    bouyer 	{ PCI_PRODUCT_JMICRON_JMB365,
     80   1.1    bouyer 	  2,
     81   1.1    bouyer 	  1
     82   1.1    bouyer 	},
     83   1.1    bouyer 	{ PCI_PRODUCT_JMICRON_JMB366,
     84   1.1    bouyer 	  2,
     85   1.1    bouyer 	  2
     86   1.1    bouyer 	},
     87   1.1    bouyer 	{ PCI_PRODUCT_JMICRON_JMB368,
     88   1.1    bouyer 	  1,
     89   1.1    bouyer 	  0
     90   1.1    bouyer 	},
     91   1.1    bouyer 	{ 0,
     92   1.1    bouyer 	  0,
     93   1.1    bouyer 	  0
     94   1.1    bouyer 	}
     95   1.1    bouyer };
     96   1.1    bouyer 
     97   1.1    bouyer typedef enum {
     98   1.1    bouyer 	TYPE_INVALID = 0,
     99   1.1    bouyer 	TYPE_PATA,
    100   1.1    bouyer 	TYPE_SATA,
    101   1.1    bouyer 	TYPE_NONE
    102   1.1    bouyer } jmchan_t;
    103   1.1    bouyer 
    104   1.1    bouyer struct jmide_softc {
    105   1.1    bouyer 	struct pciide_softc sc_pciide;
    106   1.6    bouyer 	device_t sc_ahci;
    107   1.1    bouyer 	int sc_npata;
    108   1.1    bouyer 	int sc_nsata;
    109   1.1    bouyer 	jmchan_t sc_chan_type[PCIIDE_NUM_CHANNELS];
    110   1.1    bouyer 	int sc_chan_swap;
    111   1.1    bouyer };
    112   1.1    bouyer 
    113   1.2    bouyer struct jmahci_attach_args {
    114  1.10    dyoung 	const struct pci_attach_args *jma_pa;
    115   1.2    bouyer 	bus_space_tag_t jma_ahcit;
    116   1.2    bouyer 	bus_space_handle_t jma_ahcih;
    117   1.2    bouyer };
    118   1.2    bouyer 
    119   1.4      cube #define JM_NAME(sc) (device_xname(sc->sc_pciide.sc_wdcdev.sc_atac.atac_dev))
    120   1.1    bouyer 
    121   1.4      cube CFATTACH_DECL_NEW(jmide, sizeof(struct jmide_softc),
    122   1.1    bouyer     jmide_match, jmide_attach, NULL, NULL);
    123   1.1    bouyer 
    124   1.1    bouyer static const struct jmide_product *
    125   1.1    bouyer jmide_lookup(pcireg_t id) {
    126   1.1    bouyer 	const struct jmide_product *jp;
    127   1.1    bouyer 
    128   1.1    bouyer 	for (jp = jm_products; jp->jm_product != 0; jp++) {
    129   1.1    bouyer 		if (jp->jm_product == PCI_PRODUCT(id))
    130   1.1    bouyer 			return jp;
    131   1.1    bouyer 	}
    132   1.1    bouyer 	return NULL;
    133   1.1    bouyer }
    134   1.1    bouyer 
    135   1.1    bouyer static int
    136   1.4      cube jmide_match(device_t parent, cfdata_t match, void *aux)
    137   1.1    bouyer {
    138   1.1    bouyer 	struct pci_attach_args *pa = aux;
    139   1.1    bouyer 
    140   1.1    bouyer 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_JMICRON) {
    141   1.1    bouyer 		if (jmide_lookup(pa->pa_id))
    142  1.11  jakllsch 			return (4); /* higher than ahcisata */
    143   1.1    bouyer 	}
    144   1.1    bouyer 	return (0);
    145   1.1    bouyer }
    146   1.1    bouyer 
    147   1.1    bouyer static void
    148   1.4      cube jmide_attach(device_t parent, device_t self, void *aux)
    149   1.1    bouyer {
    150   1.1    bouyer 	struct pci_attach_args *pa = aux;
    151   1.4      cube 	struct jmide_softc *sc = device_private(self);
    152   1.1    bouyer 	const struct jmide_product *jp;
    153   1.1    bouyer 	const char *intrstr;
    154   1.1    bouyer         pci_intr_handle_t intrhandle;
    155   1.1    bouyer 	u_int32_t pcictrl0 = pci_conf_read(pa->pa_pc, pa->pa_tag,
    156   1.1    bouyer 	    PCI_JM_CONTROL0);
    157   1.1    bouyer 	u_int32_t pcictrl1 = pci_conf_read(pa->pa_pc, pa->pa_tag,
    158   1.1    bouyer 	    PCI_JM_CONTROL1);
    159   1.1    bouyer 	struct pciide_product_desc *pp;
    160   1.2    bouyer 	int ahci_used = 0;
    161   1.1    bouyer 
    162   1.4      cube 	sc->sc_pciide.sc_wdcdev.sc_atac.atac_dev = self;
    163   1.4      cube 
    164   1.1    bouyer 	jp = jmide_lookup(pa->pa_id);
    165   1.1    bouyer 	if (jp == NULL) {
    166   1.1    bouyer 		printf("jmide_attach: WTF?\n");
    167   1.1    bouyer 		return;
    168   1.1    bouyer 	}
    169   1.1    bouyer 	sc->sc_npata = jp->jm_npata;
    170   1.1    bouyer 	sc->sc_nsata = jp->jm_nsata;
    171   1.1    bouyer 
    172  1.12  drochner         pci_aprint_devinfo(pa, "JMICRON PATA/SATA disk controller");
    173   1.1    bouyer 
    174   1.1    bouyer 	aprint_normal("%s: ", JM_NAME(sc));
    175   1.1    bouyer 	if (sc->sc_npata)
    176   1.1    bouyer 		aprint_normal("%d PATA port%s", sc->sc_npata,
    177   1.1    bouyer 		    (sc->sc_npata > 1) ? "s" : "");
    178   1.1    bouyer 	if (sc->sc_nsata)
    179   1.1    bouyer 		aprint_normal("%s%d SATA port%s", sc->sc_npata ? ", " : "",
    180   1.1    bouyer 		    sc->sc_nsata, (sc->sc_nsata > 1) ? "s" : "");
    181   1.1    bouyer 	aprint_normal("\n");
    182   1.1    bouyer 
    183   1.1    bouyer 	if (pci_intr_map(pa, &intrhandle) != 0) {
    184   1.1    bouyer                 aprint_error("%s: couldn't map interrupt\n", JM_NAME(sc));
    185   1.1    bouyer                 return;
    186   1.1    bouyer         }
    187   1.1    bouyer         intrstr = pci_intr_string(pa->pa_pc, intrhandle);
    188   1.1    bouyer         sc->sc_pciide.sc_pci_ih = pci_intr_establish(pa->pa_pc, intrhandle,
    189   1.1    bouyer 	    IPL_BIO, jmide_intr, sc);
    190   1.1    bouyer         if (sc->sc_pciide.sc_pci_ih == NULL) {
    191   1.1    bouyer                 aprint_error("%s: couldn't establish interrupt", JM_NAME(sc));
    192   1.1    bouyer                 return;
    193   1.1    bouyer         }
    194   1.1    bouyer         aprint_normal("%s: interrupting at %s\n", JM_NAME(sc),
    195   1.1    bouyer             intrstr ? intrstr : "unknown interrupt");
    196   1.1    bouyer 
    197   1.1    bouyer 	if (pcictrl0 & JM_CONTROL0_AHCI_EN) {
    198   1.2    bouyer 		bus_size_t size;
    199   1.2    bouyer 		struct jmahci_attach_args jma;
    200   1.2    bouyer 		u_int32_t saved_pcictrl0;
    201   1.1    bouyer 		/*
    202   1.1    bouyer 		 * ahci controller enabled; disable sata on pciide and
    203   1.1    bouyer 		 * enable on ahci
    204   1.1    bouyer 		 */
    205   1.2    bouyer 		saved_pcictrl0 = pcictrl0;
    206   1.1    bouyer 		pcictrl0 |= JM_CONTROL0_SATA0_AHCI | JM_CONTROL0_SATA1_AHCI;
    207   1.1    bouyer 		pcictrl0 &= ~(JM_CONTROL0_SATA0_IDE | JM_CONTROL0_SATA1_IDE);
    208   1.1    bouyer 		pci_conf_write(pa->pa_pc, pa->pa_tag,
    209   1.1    bouyer 		    PCI_JM_CONTROL0, pcictrl0);
    210   1.1    bouyer 		/* attach ahci controller if on the right function */
    211   1.1    bouyer 		if ((pa->pa_function == 0 &&
    212   1.1    bouyer 		      (pcictrl0 & JM_CONTROL0_AHCI_F1) == 0) ||
    213   1.1    bouyer 	    	    (pa->pa_function == 1 &&
    214   1.1    bouyer 		      (pcictrl0 & JM_CONTROL0_AHCI_F1) != 0)) {
    215   1.2    bouyer 			jma.jma_pa = pa;
    216   1.2    bouyer 			/* map registers */
    217   1.2    bouyer 			if (pci_mapreg_map(pa, AHCI_PCI_ABAR,
    218   1.2    bouyer 			    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
    219   1.2    bouyer 			    &jma.jma_ahcit, &jma.jma_ahcih, NULL, &size) != 0) {
    220   1.2    bouyer 				aprint_error("%s: can't map ahci registers\n",
    221   1.2    bouyer 				    JM_NAME(sc));
    222   1.2    bouyer 			} else {
    223   1.2    bouyer 				sc->sc_ahci = config_found_ia(
    224   1.4      cube 				    sc->sc_pciide.sc_wdcdev.sc_atac.atac_dev,
    225   1.2    bouyer 				    "jmide_hl", &jma, jmahci_print);
    226   1.2    bouyer 			}
    227   1.2    bouyer 			/*
    228   1.2    bouyer 			 * if we couldn't attach an ahci, try to fall back
    229   1.2    bouyer 			 * to pciide. Note that this will not work if IDE
    230   1.2    bouyer 			 * is on function 0 and AHCI on function 1.
    231   1.2    bouyer 			 */
    232   1.2    bouyer 			if (sc->sc_ahci == NULL) {
    233   1.2    bouyer 				pcictrl0 = saved_pcictrl0 &
    234   1.2    bouyer 				    ~(JM_CONTROL0_SATA0_AHCI |
    235   1.2    bouyer 				      JM_CONTROL0_SATA1_AHCI |
    236   1.2    bouyer 				      JM_CONTROL0_AHCI_EN);
    237   1.2    bouyer 				pcictrl0 |= JM_CONTROL0_SATA1_IDE |
    238   1.2    bouyer 					JM_CONTROL0_SATA0_IDE;
    239   1.2    bouyer 				pci_conf_write(pa->pa_pc, pa->pa_tag,
    240   1.2    bouyer 				    PCI_JM_CONTROL0, pcictrl0);
    241   1.2    bouyer 			} else
    242   1.2    bouyer 				ahci_used = 1;
    243   1.1    bouyer 		}
    244   1.1    bouyer 	}
    245   1.1    bouyer 	sc->sc_chan_swap = ((pcictrl0 & JM_CONTROL0_PCIIDE_CS) != 0);
    246   1.1    bouyer 	/* compute the type of internal primary channel */
    247   1.2    bouyer 	if (pcictrl1 & JM_CONTROL1_PATA1_PRI) {
    248   1.2    bouyer 		if (sc->sc_npata > 1)
    249   1.1    bouyer 			sc->sc_chan_type[sc->sc_chan_swap ? 1 : 0] = TYPE_PATA;
    250   1.1    bouyer 		else
    251   1.1    bouyer 			sc->sc_chan_type[sc->sc_chan_swap ? 1 : 0] = TYPE_NONE;
    252   1.2    bouyer 	} else if (ahci_used == 0 && sc->sc_nsata > 0)
    253   1.2    bouyer 		sc->sc_chan_type[sc->sc_chan_swap ? 1 : 0] = TYPE_SATA;
    254   1.2    bouyer 	else
    255   1.2    bouyer 		sc->sc_chan_type[sc->sc_chan_swap ? 1 : 0] = TYPE_NONE;
    256   1.2    bouyer 	/* compute the type of internal secondary channel */
    257   1.2    bouyer 	if (sc->sc_nsata > 1 && ahci_used == 0 &&
    258   1.2    bouyer 	    (pcictrl0 & JM_CONTROL0_PCIIDE0_MS) == 0) {
    259   1.2    bouyer 		sc->sc_chan_type[sc->sc_chan_swap ? 0 : 1] = TYPE_SATA;
    260   1.1    bouyer 	} else {
    261   1.1    bouyer 		/* only a drive if first PATA enabled */
    262   1.1    bouyer 		if (sc->sc_npata > 0 && (pcictrl0 & JM_CONTROL0_PATA0_EN)
    263   1.1    bouyer 		    && (pcictrl0 &
    264   1.1    bouyer 		    (sc->sc_chan_swap ? JM_CONTROL0_PATA0_PRI: JM_CONTROL0_PATA0_SEC)))
    265   1.1    bouyer 			sc->sc_chan_type[sc->sc_chan_swap ? 0 : 1] = TYPE_PATA;
    266   1.1    bouyer 		else
    267   1.1    bouyer 			sc->sc_chan_type[sc->sc_chan_swap ? 0 : 1] = TYPE_NONE;
    268   1.1    bouyer 	}
    269   1.2    bouyer 
    270   1.1    bouyer 	if (sc->sc_chan_type[0] == TYPE_NONE &&
    271   1.1    bouyer 	    sc->sc_chan_type[1] == TYPE_NONE)
    272   1.1    bouyer 		return;
    273   1.1    bouyer 	if (pa->pa_function == 0 && (pcictrl0 & JM_CONTROL0_PCIIDE_F1))
    274   1.1    bouyer 		return;
    275   1.1    bouyer 	if (pa->pa_function == 1 && (pcictrl0 & JM_CONTROL0_PCIIDE_F1) == 0)
    276   1.1    bouyer 		return;
    277   1.1    bouyer 	pp = malloc(sizeof(struct pciide_product_desc), M_DEVBUF, M_NOWAIT);
    278   1.1    bouyer 	if (pp == NULL) {
    279   1.1    bouyer 		aprint_error("%s: can't malloc sc_pp\n", JM_NAME(sc));
    280   1.1    bouyer 		return;
    281   1.1    bouyer 	}
    282   1.1    bouyer 	aprint_normal("%s: PCI IDE interface used", JM_NAME(sc));
    283   1.1    bouyer 	pp->ide_product = 0;
    284   1.1    bouyer 	pp->ide_flags = 0;
    285   1.1    bouyer 	pp->ide_name = NULL;
    286   1.1    bouyer 	pp->chip_map = jmpata_chip_map;
    287   1.1    bouyer 	pciide_common_attach(&sc->sc_pciide, pa, pp);
    288   1.1    bouyer 
    289   1.1    bouyer }
    290   1.1    bouyer 
    291   1.1    bouyer static int
    292   1.1    bouyer jmide_intr(void *arg)
    293   1.1    bouyer {
    294   1.1    bouyer 	struct jmide_softc *sc = arg;
    295   1.1    bouyer 	int ret = 0;
    296   1.1    bouyer 
    297   1.1    bouyer #ifdef NJMAHCI
    298   1.1    bouyer 	if (sc->sc_ahci)
    299   1.6    bouyer 		ret |= ahci_intr(device_private(sc->sc_ahci));
    300   1.1    bouyer #endif
    301   1.1    bouyer 	if (sc->sc_npata)
    302   1.1    bouyer 		ret |= pciide_pci_intr(&sc->sc_pciide);
    303   1.1    bouyer 	return ret;
    304   1.1    bouyer }
    305   1.1    bouyer 
    306   1.1    bouyer static void
    307  1.10    dyoung jmpata_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa)
    308   1.1    bouyer {
    309   1.1    bouyer 	struct jmide_softc *jmidesc = (struct jmide_softc *)sc;
    310   1.1    bouyer 	int channel;
    311   1.1    bouyer 	pcireg_t interface;
    312   1.1    bouyer 	struct pciide_channel *cp;
    313   1.1    bouyer 
    314   1.1    bouyer 	if (pciide_chipen(sc, pa) == 0)
    315   1.1    bouyer 		return;
    316   1.1    bouyer 	aprint_verbose("%s: bus-master DMA support present", JM_NAME(jmidesc));
    317   1.1    bouyer 	pciide_mapreg_dma(sc, pa);
    318   1.1    bouyer 	aprint_verbose("\n");
    319   1.1    bouyer 	sc->sc_wdcdev.sc_atac.atac_cap = ATAC_CAP_DATA16 | ATAC_CAP_DATA32;
    320   1.1    bouyer 	if (sc->sc_dma_ok) {
    321   1.1    bouyer 		sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DMA | ATAC_CAP_UDMA;
    322   1.1    bouyer 		sc->sc_wdcdev.sc_atac.atac_udma_cap = 6;
    323   1.1    bouyer 	}
    324   1.1    bouyer 	sc->sc_wdcdev.sc_atac.atac_pio_cap = 4;
    325   1.1    bouyer 	sc->sc_wdcdev.sc_atac.atac_dma_cap = 2;
    326   1.1    bouyer 	sc->sc_wdcdev.sc_atac.atac_set_modes = jmpata_setup_channel;
    327   1.1    bouyer 	sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray;
    328   1.1    bouyer 	sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS;
    329  1.18    bouyer 	sc->sc_wdcdev.wdc_maxdrives = 2;
    330   1.1    bouyer 	wdc_allocate_regs(&sc->sc_wdcdev);
    331   1.1    bouyer 	/*
    332   1.1    bouyer          * can't rely on the PCI_CLASS_REG content if the chip was in raid
    333   1.1    bouyer          * mode. We have to fake interface
    334   1.1    bouyer          */
    335   1.1    bouyer 	interface = PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1);
    336   1.1    bouyer 	for (channel = 0; channel < sc->sc_wdcdev.sc_atac.atac_nchannels;
    337   1.1    bouyer 	    channel++) {
    338   1.1    bouyer 		cp = &sc->pciide_channels[channel];
    339   1.1    bouyer 		if (pciide_chansetup(sc, channel, interface) == 0)
    340   1.1    bouyer 			continue;
    341   1.1    bouyer 		aprint_normal("%s: %s channel is ", JM_NAME(jmidesc),
    342   1.1    bouyer 		    PCIIDE_CHANNEL_NAME(channel));
    343   1.1    bouyer 		switch(jmidesc->sc_chan_type[channel]) {
    344   1.1    bouyer 		case TYPE_PATA:
    345   1.1    bouyer 			aprint_normal("PATA");
    346   1.1    bouyer 			break;
    347   1.1    bouyer 		case TYPE_SATA:
    348   1.1    bouyer 			aprint_normal("SATA");
    349   1.1    bouyer 			break;
    350   1.1    bouyer 		case TYPE_NONE:
    351   1.1    bouyer 			aprint_normal("unused");
    352   1.1    bouyer 			break;
    353   1.1    bouyer 		default:
    354   1.1    bouyer 			aprint_normal("impossible");
    355   1.1    bouyer 			panic("jmide: wrong/uninitialised channel type");
    356   1.1    bouyer 		}
    357   1.1    bouyer 		aprint_normal("\n");
    358   1.1    bouyer 		if (jmidesc->sc_chan_type[channel] == TYPE_NONE) {
    359   1.1    bouyer 			cp->ata_channel.ch_flags |= ATACH_DISABLED;
    360   1.1    bouyer 			continue;
    361   1.1    bouyer 		}
    362   1.9  jakllsch 		pciide_mapchan(pa, cp, interface, pciide_pci_intr);
    363   1.1    bouyer 	}
    364   1.1    bouyer }
    365   1.1    bouyer 
    366   1.1    bouyer static void
    367   1.1    bouyer jmpata_setup_channel(struct ata_channel *chp)
    368   1.1    bouyer {
    369   1.1    bouyer 	struct ata_drive_datas *drvp;
    370   1.1    bouyer 	int drive, s;
    371   1.1    bouyer 	u_int32_t idedma_ctl;
    372   1.1    bouyer 	struct pciide_channel *cp = CHAN_TO_PCHAN(chp);
    373   1.1    bouyer 	struct pciide_softc *sc = CHAN_TO_PCIIDE(chp);
    374   1.1    bouyer 	struct jmide_softc *jmidesc = (struct jmide_softc *)sc;
    375   1.1    bouyer 	int ide80p;
    376   1.1    bouyer 
    377   1.1    bouyer 	/* setup DMA if needed */
    378   1.1    bouyer 	pciide_channel_dma_setup(cp);
    379   1.1    bouyer 
    380   1.1    bouyer 	idedma_ctl = 0;
    381   1.1    bouyer 
    382   1.1    bouyer 	/* cable type detect */
    383   1.1    bouyer 	ide80p = 1;
    384   1.1    bouyer 	if (chp->ch_channel == (jmidesc->sc_chan_swap ? 1 : 0)) {
    385   1.1    bouyer 		if (jmidesc->sc_chan_type[chp->ch_channel] == TYPE_PATA &&
    386   1.1    bouyer 		    (pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_JM_CONTROL1) &
    387   1.1    bouyer 		    JM_CONTROL1_PATA1_40P))
    388   1.1    bouyer 			ide80p = 0;
    389   1.1    bouyer 	} else {
    390   1.1    bouyer 		if (jmidesc->sc_chan_type[chp->ch_channel] == TYPE_PATA &&
    391   1.1    bouyer 		    (pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_JM_CONTROL0) &
    392   1.1    bouyer 		    JM_CONTROL0_PATA0_40P))
    393   1.1    bouyer 			ide80p = 0;
    394   1.1    bouyer 	}
    395   1.1    bouyer 
    396   1.1    bouyer 	for (drive = 0; drive < 2; drive++) {
    397   1.1    bouyer 		drvp = &chp->ch_drive[drive];
    398   1.1    bouyer 		/* If no drive, skip */
    399  1.18    bouyer 		if (drvp->drive_type == ATA_DRIVET_NONE)
    400   1.1    bouyer 			continue;
    401  1.18    bouyer 		if (drvp->drive_flags & ATA_DRIVE_UDMA) {
    402   1.1    bouyer 			/* use Ultra/DMA */
    403   1.1    bouyer 			s = splbio();
    404  1.18    bouyer 			drvp->drive_flags &= ~ATA_DRIVE_DMA;
    405   1.1    bouyer 			if (drvp->UDMA_mode > 2 && ide80p == 0)
    406   1.1    bouyer 				drvp->UDMA_mode = 2;
    407   1.1    bouyer 			splx(s);
    408   1.1    bouyer 			idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
    409  1.18    bouyer 		} else if (drvp->drive_flags & ATA_DRIVE_DMA) {
    410   1.1    bouyer 			idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
    411   1.1    bouyer 		}
    412   1.1    bouyer 	}
    413   1.1    bouyer 	/* nothing to do to setup modes, the controller snoop SET_FEATURE cmd */
    414   1.1    bouyer 	if (idedma_ctl != 0) {
    415   1.1    bouyer 		/* Add software bits in status register */
    416   1.1    bouyer 		bus_space_write_1(sc->sc_dma_iot, cp->dma_iohs[IDEDMA_CTL],
    417   1.1    bouyer 		    0, idedma_ctl);
    418   1.1    bouyer 	}
    419   1.1    bouyer }
    420   1.1    bouyer 
    421   1.1    bouyer static int
    422   1.1    bouyer jmahci_print(void *aux, const char *pnp)
    423   1.1    bouyer {
    424   1.1    bouyer         if (pnp)
    425   1.1    bouyer                 aprint_normal("ahcisata at %s", pnp);
    426   1.1    bouyer 
    427   1.1    bouyer         return (UNCONF);
    428   1.1    bouyer }
    429   1.1    bouyer 
    430   1.1    bouyer 
    431   1.1    bouyer #ifdef NJMAHCI
    432   1.5   xtraeme static int  jmahci_match(device_t, cfdata_t, void *);
    433   1.5   xtraeme static void jmahci_attach(device_t, device_t, void *);
    434   1.8  jakllsch static int  jmahci_detach(device_t, int);
    435   1.8  jakllsch static bool jmahci_resume(device_t, const pmf_qual_t *);
    436   1.1    bouyer 
    437   1.5   xtraeme CFATTACH_DECL_NEW(jmahci, sizeof(struct ahci_softc),
    438   1.8  jakllsch 	jmahci_match, jmahci_attach, jmahci_detach, NULL);
    439   1.1    bouyer 
    440   1.1    bouyer static int
    441   1.5   xtraeme jmahci_match(device_t parent, cfdata_t match, void *aux)
    442   1.1    bouyer {
    443   1.1    bouyer 	return 1;
    444   1.1    bouyer }
    445   1.1    bouyer 
    446   1.1    bouyer static void
    447   1.5   xtraeme jmahci_attach(device_t parent, device_t self, void *aux)
    448   1.1    bouyer {
    449   1.2    bouyer 	struct jmahci_attach_args *jma = aux;
    450  1.10    dyoung 	const struct pci_attach_args *pa = jma->jma_pa;
    451   1.5   xtraeme 	struct ahci_softc *sc = device_private(self);
    452   1.8  jakllsch 	uint32_t ahci_cap;
    453   1.1    bouyer 
    454   1.1    bouyer 	aprint_naive(": AHCI disk controller\n");
    455   1.1    bouyer 	aprint_normal("\n");
    456   1.2    bouyer 
    457   1.5   xtraeme 	sc->sc_atac.atac_dev = self;
    458   1.2    bouyer 	sc->sc_ahcit = jma->jma_ahcit;
    459   1.2    bouyer 	sc->sc_ahcih = jma->jma_ahcih;
    460   1.8  jakllsch 
    461   1.8  jakllsch 	ahci_cap = AHCI_READ(sc, AHCI_CAP);
    462   1.8  jakllsch 
    463   1.8  jakllsch 	if (pci_dma64_available(jma->jma_pa) && (ahci_cap & AHCI_CAP_64BIT))
    464   1.8  jakllsch 		sc->sc_dmat = jma->jma_pa->pa_dmat64;
    465   1.8  jakllsch 	else
    466   1.8  jakllsch 		sc->sc_dmat = jma->jma_pa->pa_dmat;
    467   1.3   xtraeme 
    468   1.3   xtraeme 	if (PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_RAID)
    469   1.3   xtraeme 		sc->sc_atac_capflags = ATAC_CAP_RAID;
    470   1.3   xtraeme 
    471   1.1    bouyer 	ahci_attach(sc);
    472   1.8  jakllsch 
    473   1.8  jakllsch 	if (!pmf_device_register(self, NULL, jmahci_resume))
    474   1.8  jakllsch 	    aprint_error_dev(self, "couldn't establish power handler\n");
    475   1.8  jakllsch }
    476   1.8  jakllsch 
    477   1.8  jakllsch static int
    478   1.8  jakllsch jmahci_detach(device_t dv, int flags)
    479   1.8  jakllsch {
    480   1.8  jakllsch 	struct ahci_softc *sc;
    481   1.8  jakllsch 	sc = device_private(dv);
    482   1.8  jakllsch 
    483   1.8  jakllsch 	int rv;
    484   1.8  jakllsch 
    485   1.8  jakllsch 	if ((rv = ahci_detach(sc, flags)))
    486   1.8  jakllsch 		return rv;
    487   1.8  jakllsch 
    488   1.8  jakllsch 	return 0;
    489   1.8  jakllsch }
    490   1.8  jakllsch 
    491   1.8  jakllsch static bool
    492   1.8  jakllsch jmahci_resume(device_t dv, const pmf_qual_t *qual)
    493   1.8  jakllsch {
    494   1.8  jakllsch 	struct ahci_softc *sc;
    495   1.8  jakllsch 	int s;
    496   1.8  jakllsch 
    497   1.8  jakllsch 	sc = device_private(dv);
    498   1.8  jakllsch 
    499   1.8  jakllsch 	s = splbio();
    500   1.8  jakllsch 	ahci_resume(sc);
    501   1.8  jakllsch 	splx(s);
    502   1.8  jakllsch 
    503   1.8  jakllsch 	return true;
    504   1.1    bouyer }
    505   1.1    bouyer #endif
    506