NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/53716: PCengines APU2 requires AHCI enabler



The following reply was made to PR kern/53716; it has been noted by GNATS.

From: clare%csel.org@localhost
To: gnats-bugs%NetBSD.org@localhost
Cc: matthew green <mrg%eterna.com.au@localhost>, kern-bug-people%netbsd.org@localhost,
 gnats-admin%netbsd.org@localhost, netbsd-bugs%netbsd.org@localhost
Subject: Re: kern/53716: PCengines APU2 requires AHCI enabler
Date: Sun, 11 Nov 2018 20:00:47 +0900

 I re-worked the patch as following:
 
 Index: sys/dev/ic/ahcisatavar.h
 ===================================================================
 RCS file: /export/cvsroot/netbsd/src/sys/dev/ic/ahcisatavar.h,v
 retrieving revision 1.17
 diff -u -r1.17 ahcisatavar.h
 --- sys/dev/ic/ahcisatavar.h	24 May 2015 22:30:05 -0000	1.17
 +++ sys/dev/ic/ahcisatavar.h	11 Nov 2018 05:30:32 -0000
 @@ -60,6 +60,7 @@
  #define AHCI_QUIRK_BADPMP	__BIT(2)  /* broken PMP support, ignore */
  #define AHCI_QUIRK_BADPMPRESET	__BIT(3)  /* broken PMP support for reset */
  #define AHCI_QUIRK_SKIP_RESET	__BIT(4)  /* skip drive reset sequence */
 +#define AHCI_PCI_QUIRK_FIXUP	__BIT(5)  /* interface needs fixup */
  
  	uint32_t sc_ahci_cap;	/* copy of AHCI_CAP */
  	int sc_ncmds; /* number of command slots */
 Index: sys/dev/pci/ahcisata_pci.c
 ===================================================================
 RCS file: /export/cvsroot/netbsd/src/sys/dev/pci/ahcisata_pci.c,v
 retrieving revision 1.38
 diff -u -r1.38 ahcisata_pci.c
 --- sys/dev/pci/ahcisata_pci.c	13 Oct 2016 17:11:09 -0000	1.38
 +++ sys/dev/pci/ahcisata_pci.c	11 Nov 2018 10:57:34 -0000
 @@ -194,6 +194,8 @@
  	    AHCI_PCI_QUIRK_FORCE },
  	{ PCI_VENDOR_ASMEDIA, PCI_PRODUCT_ASMEDIA_ASM1061_12,
  	    AHCI_PCI_QUIRK_FORCE },
 +	{ PCI_VENDOR_AMD, PCI_PRODUCT_AMD_HUDSON_SATA,
 +	    AHCI_PCI_QUIRK_FORCE | AHCI_PCI_QUIRK_FIXUP },
  };
  
  struct ahci_pci_softc {
 @@ -208,7 +210,7 @@
  static void ahci_pci_attach(device_t, device_t, void *);
  static int  ahci_pci_detach(device_t, int);
  static bool ahci_pci_resume(device_t, const pmf_qual_t *);
 -
 +static void ahci_pci_fixup_interface(device_t);
  
  CFATTACH_DECL_NEW(ahcisata_pci, sizeof(struct ahci_pci_softc),
      ahci_pci_match, ahci_pci_attach, ahci_pci_detach, NULL);
 @@ -273,7 +275,17 @@
  	pci_intr_handle_t intrhandle;
  	char intrbuf[PCI_INTRSTR_LEN];
  
 +	pci_aprint_devinfo(pa, "AHCI disk controller");
 +	
  	sc->sc_atac.atac_dev = self;
 +	sc->sc_ahci_quirks = ahci_pci_has_quirk(PCI_VENDOR(pa->pa_id),
 +					    PCI_PRODUCT(pa->pa_id));
 +
 +	psc->sc_pc = pa->pa_pc;
 +	psc->sc_pcitag = pa->pa_tag;
 +
 +	if (sc->sc_ahci_quirks & AHCI_PCI_QUIRK_FIXUP)
 +		ahci_pci_fixup_interface(self);
  
  	if (pci_mapreg_map(pa, AHCI_PCI_ABAR,
  	    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
 @@ -281,11 +293,7 @@
  		aprint_error_dev(self, "can't map ahci registers\n");
  		return;
  	}
 -	psc->sc_pc = pa->pa_pc;
 -	psc->sc_pcitag = pa->pa_tag;
  
 -	pci_aprint_devinfo(pa, "AHCI disk controller");
 -	
  	if (pci_intr_map(pa, &intrhandle) != 0) {
  		aprint_error_dev(self, "couldn't map interrupt\n");
  		return;
 @@ -302,8 +310,6 @@
  
  	sc->sc_dmat = pa->pa_dmat;
  
 -	sc->sc_ahci_quirks = ahci_pci_has_quirk(PCI_VENDOR(pa->pa_id),
 -					    PCI_PRODUCT(pa->pa_id));
  
  	ahci_cap_64bit = (AHCI_READ(sc, AHCI_CAP) & AHCI_CAP_64BIT) != 0;
  	ahci_bad_64bit = ((sc->sc_ahci_quirks & AHCI_PCI_QUIRK_BAD64) != 0);
 @@ -364,3 +370,58 @@
  
  	return true;
  }
 +
 +/*
 + * Switch devices in legacy IDE interface to native AHCI, if desired.
 + *
 + * In some devices, especially in PCengines APU2 series, the BIOS left
 + * AHCI devices in IDE/legacy mode to simplify their code and some
 + * unknown compatibility reasons.  Since we have no PCI-IDE DMA
 + * handler for the AMD Hudson SATA IDE controller, we should re-program
 + * interfacing mode and use it in native AHCI.
 + *
 + * see ftp://kolibrios.org/users/art_zh/doc/public/A50_RPR.pdf
 + * for register programming details.
 + */
 +static void
 +ahci_pci_fixup_interface(device_t dv)
 +{
 +	struct ahci_pci_softc *psc = device_private(dv);
 +	int cc;
 +	int reg;
 +
 +	/*
 +	 * check the interface mode in IDE/legacy
 +	 */
 +	cc = pci_conf_read(psc->sc_pc, psc->sc_pcitag, 0x08);
 +	if (!(PCI_CLASS(cc) == PCI_CLASS_MASS_STORAGE &&
 +	    PCI_SUBCLASS(cc) == PCI_SUBCLASS_MASS_STORAGE_IDE))
 +		return;
 +
 +	aprint_normal_dev(dv, "switch legacy IDE to native AHCI\n");
 +
 +	/*
 +	 * make subclass/interface register is writeable.
 +	 */
 +	reg = pci_conf_read(psc->sc_pc, psc->sc_pcitag, 0x40);
 +	reg |= 1;
 +	pci_conf_write(psc->sc_pc, psc->sc_pcitag, 0x40, reg);
 +
 +	/*
 +	 * rewrite subclass/interface register.
 +	 * this causes switch interface logic.
 +	 */
 +	reg = pci_conf_read(psc->sc_pc, psc->sc_pcitag, PCI_CLASS_REG);
 +	reg &= ~PCI_SUBCLASS(PCI_SUBCLASS_MASK);
 +	reg |=  PCI_SUBCLASS(PCI_SUBCLASS_MASS_STORAGE_SATA);
 +	reg &= ~PCI_INTERFACE(PCI_INTERFACE_MASK);
 +	reg |=  PCI_INTERFACE(PCI_INTERFACE_SATA_AHCI);
 +	pci_conf_write(psc->sc_pc, psc->sc_pcitag, PCI_CLASS_REG, reg);
 +
 +	/*
 +	 * make subclass/interface register is read-only.
 +	 */
 +	reg = pci_conf_read(psc->sc_pc, psc->sc_pcitag, 0x40);
 +	reg &= ~1;
 +	pci_conf_write(psc->sc_pc, psc->sc_pcitag, 0x40, reg);
 +}
 
 
 -- 
 Shinichi Doyashiki <clare%csel.org@localhost>
 


Home | Main Index | Thread Index | Old Index