svn commit: r183724 - in head/sys: conf dev/ata dev/ata/chipsets modules/ata modules/ata/ata modules/ata/atacore modules/ata/atadevel modules/ata/atapci modules/ata/atapci/chipsets modules/ata/atap...

Søren Schmidt sos at FreeBSD.org
Thu Oct 9 12:56:57 UTC 2008


Author: sos
Date: Thu Oct  9 12:56:57 2008
New Revision: 183724
URL: http://svn.freebsd.org/changeset/base/183724

Log:
  This is the roumored ATA modulerisation works, and it needs a little explanation.
  
  If you just config KERNEL as usual there should be no apparent changes, you'll get all chipset support code compiled in.
  
  However there is now a way to only compile in code for chipsets needed on a pr vendor basis. ATA now has the following "device" entries:
  
  atacore:	ATA core functionality, always needed for any ATA setup
  
  atacard:	CARDBUS support
  atacbus:	PC98 cbus support
  ataisa:		ISA bus support
  atapci:		PCI bus support only generic chipset support.
  
  ataahci:	AHCI support, also pulled in by some vendor modules.
  
  ataacard, ataacerlabs, ataadaptec, ataamd, ataati, atacenatek, atacypress, atacyrix, atahighpoint, ataintel, ataite, atajmicron, atamarvell, atamicron, atanational, atanetcell, atanvidia, atapromise, ataserverworks, atasiliconimage, atasis, atavia;	Vendor support, ie atavia for VIA chipsets
  
  atadisk:	ATA disk driver
  ataraid:	ATA softraid driver
  
  atapicd:	ATAPI cd/dvd driver
  atapifd:	ATAPI floppy/flashdisk driver
  atapist:	ATAPI tape driver
  
  atausb:		ATA<>USB bridge
  atapicam:	ATA<>CAM bridge
  
  This makes it possible to config a kernel with just VIA chipset support by having the following ATA lines in the kernel config file:
  
  device          atacore
  device          atapci
  device          atavia
  
  And then you need the atadisk, atapicd etc lines in there just as usual.
  
  If you use ATA as modules loaded at boot there is few changes except the rename of the "ata" module to "atacore", things looks just as usual.
  However under atapci you now have a whole bunch of vendor specific drivers, that you can kldload individually depending on you needs. Drivers have the same names as used in the kernel config explained above.

Added:
  head/sys/dev/ata/ata-sata.c   (contents, props changed)
  head/sys/dev/ata/chipsets/
  head/sys/dev/ata/chipsets/ata-acard.c   (contents, props changed)
  head/sys/dev/ata/chipsets/ata-acerlabs.c   (contents, props changed)
  head/sys/dev/ata/chipsets/ata-adaptec.c   (contents, props changed)
  head/sys/dev/ata/chipsets/ata-ahci.c   (contents, props changed)
  head/sys/dev/ata/chipsets/ata-amd.c   (contents, props changed)
  head/sys/dev/ata/chipsets/ata-ati.c   (contents, props changed)
  head/sys/dev/ata/chipsets/ata-cenatek.c   (contents, props changed)
  head/sys/dev/ata/chipsets/ata-cypress.c   (contents, props changed)
  head/sys/dev/ata/chipsets/ata-cyrix.c   (contents, props changed)
  head/sys/dev/ata/chipsets/ata-highpoint.c   (contents, props changed)
  head/sys/dev/ata/chipsets/ata-intel.c   (contents, props changed)
  head/sys/dev/ata/chipsets/ata-ite.c   (contents, props changed)
  head/sys/dev/ata/chipsets/ata-jmicron.c   (contents, props changed)
  head/sys/dev/ata/chipsets/ata-marvell.c   (contents, props changed)
  head/sys/dev/ata/chipsets/ata-micron.c   (contents, props changed)
  head/sys/dev/ata/chipsets/ata-national.c   (contents, props changed)
  head/sys/dev/ata/chipsets/ata-netcell.c   (contents, props changed)
  head/sys/dev/ata/chipsets/ata-nvidia.c   (contents, props changed)
  head/sys/dev/ata/chipsets/ata-promise.c   (contents, props changed)
  head/sys/dev/ata/chipsets/ata-serverworks.c   (contents, props changed)
  head/sys/dev/ata/chipsets/ata-siliconimage.c   (contents, props changed)
  head/sys/dev/ata/chipsets/ata-sis.c   (contents, props changed)
  head/sys/dev/ata/chipsets/ata-via.c   (contents, props changed)
  head/sys/modules/ata/atacore/
  head/sys/modules/ata/atacore/Makefile   (contents, props changed)
  head/sys/modules/ata/atadevel/
  head/sys/modules/ata/atadevel/Makefile   (contents, props changed)
  head/sys/modules/ata/atadevel/ata-devel.c   (contents, props changed)
  head/sys/modules/ata/atapci/Makefile.inc   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/
  head/sys/modules/ata/atapci/chipsets/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/Makefile.inc   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/ataacard/
  head/sys/modules/ata/atapci/chipsets/ataacard/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/ataacerlabs/
  head/sys/modules/ata/atapci/chipsets/ataacerlabs/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/ataadaptec/
  head/sys/modules/ata/atapci/chipsets/ataadaptec/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/ataahci/
  head/sys/modules/ata/atapci/chipsets/ataahci/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/ataamd/
  head/sys/modules/ata/atapci/chipsets/ataamd/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/ataati/
  head/sys/modules/ata/atapci/chipsets/ataati/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/atacenatek/
  head/sys/modules/ata/atapci/chipsets/atacenatek/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/atacypress/
  head/sys/modules/ata/atapci/chipsets/atacypress/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/atacyrix/
  head/sys/modules/ata/atapci/chipsets/atacyrix/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/atahighpoint/
  head/sys/modules/ata/atapci/chipsets/atahighpoint/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/ataintel/
  head/sys/modules/ata/atapci/chipsets/ataintel/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/ataite/
  head/sys/modules/ata/atapci/chipsets/ataite/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/atajmicron/
  head/sys/modules/ata/atapci/chipsets/atajmicron/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/atamarvell/
  head/sys/modules/ata/atapci/chipsets/atamarvell/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/atamicron/
  head/sys/modules/ata/atapci/chipsets/atamicron/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/atanational/
  head/sys/modules/ata/atapci/chipsets/atanational/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/atanetcell/
  head/sys/modules/ata/atapci/chipsets/atanetcell/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/atanvidia/
  head/sys/modules/ata/atapci/chipsets/atanvidia/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/atapromise/
  head/sys/modules/ata/atapci/chipsets/atapromise/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/ataserverworks/
  head/sys/modules/ata/atapci/chipsets/ataserverworks/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/atasiliconimage/
  head/sys/modules/ata/atapci/chipsets/atasiliconimage/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/atasis/
  head/sys/modules/ata/atapci/chipsets/atasis/Makefile   (contents, props changed)
  head/sys/modules/ata/atapci/chipsets/atavia/
  head/sys/modules/ata/atapci/chipsets/atavia/Makefile   (contents, props changed)
Deleted:
  head/sys/dev/ata/ata-chipset.c
  head/sys/modules/ata/ata/Makefile
Modified:
  head/sys/conf/files
  head/sys/dev/ata/ata-all.c
  head/sys/dev/ata/ata-all.h
  head/sys/dev/ata/ata-dma.c
  head/sys/dev/ata/ata-pci.c
  head/sys/dev/ata/ata-pci.h
  head/sys/modules/ata/Makefile
  head/sys/modules/ata/atapci/Makefile

Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files	Thu Oct  9 12:25:07 2008	(r183723)
+++ head/sys/conf/files	Thu Oct  9 12:56:57 2008	(r183724)
@@ -459,23 +459,49 @@ dev/an/if_an_isa.c		optional an isa
 dev/an/if_an_pccard.c		optional an pccard
 dev/an/if_an_pci.c		optional an pci
 dev/asr/asr.c			optional asr pci
-dev/ata/ata_if.m		optional ata
-dev/ata/ata-all.c		optional ata
-dev/ata/ata-card.c		optional ata pccard
-dev/ata/ata-cbus.c		optional ata pc98
-dev/ata/ata-chipset.c		optional ata pci
+#
+dev/ata/ata_if.m		optional ata | atacore
+dev/ata/ata-all.c		optional ata | atacore
+dev/ata/ata-lowlevel.c		optional ata | atacore
+dev/ata/ata-queue.c		optional ata | atacore
+dev/ata/ata-card.c		optional ata pccard | atapccard
+dev/ata/ata-cbus.c		optional ata pc98 | atapc98
+dev/ata/ata-isa.c		optional ata isa | ataisa
+dev/ata/ata-pci.c		optional ata pci | atapci
+dev/ata/ata-dma.c		optional ata pci | atapci
+dev/ata/ata-sata.c		optional ata pci | atapci
+dev/ata/chipsets/ata-ahci.c	optional ata pci | ataahci | ataacerlabs | \
+					 ataati | ataintel | atajmicron | atavia
+dev/ata/chipsets/ata-acard.c	optional ata pci | ataacard
+dev/ata/chipsets/ata-acerlabs.c	optional ata pci | ataacerlabs
+dev/ata/chipsets/ata-adaptec.c	optional ata pci | ataadaptec
+dev/ata/chipsets/ata-amd.c	optional ata pci | ataamd
+dev/ata/chipsets/ata-ati.c	optional ata pci | ataati
+dev/ata/chipsets/ata-cenatek.c	optional ata pci | atacenatek
+dev/ata/chipsets/ata-cypress.c	optional ata pci | atacypress
+dev/ata/chipsets/ata-cyrix.c	optional ata pci | atacyrix
+dev/ata/chipsets/ata-highpoint.c	optional ata pci | atahighpoint
+dev/ata/chipsets/ata-intel.c	optional ata pci | ataintel
+dev/ata/chipsets/ata-ite.c	optional ata pci | ataite
+dev/ata/chipsets/ata-jmicron.c	optional ata pci | atajmicron
+dev/ata/chipsets/ata-marvell.c	optional ata pci | atamarvell
+dev/ata/chipsets/ata-micron.c	optional ata pci | atamicron
+dev/ata/chipsets/ata-national.c	optional ata pci | atanational
+dev/ata/chipsets/ata-netcell.c	optional ata pci | atanetcell
+dev/ata/chipsets/ata-nvidia.c	optional ata pci | atanvidia
+dev/ata/chipsets/ata-promise.c	optional ata pci | atapromise
+dev/ata/chipsets/ata-serverworks.c	optional ata pci | ataserverworks
+dev/ata/chipsets/ata-siliconimage.c	optional ata pci | atasiliconimage
+dev/ata/chipsets/ata-sis.c	optional ata pci | atasis
+dev/ata/chipsets/ata-via.c	optional ata pci | atavia
 dev/ata/ata-disk.c		optional atadisk
-dev/ata/ata-dma.c		optional ata pci
-dev/ata/ata-isa.c		optional ata isa
-dev/ata/ata-lowlevel.c		optional ata
-dev/ata/ata-pci.c		optional ata pci
-dev/ata/ata-queue.c		optional ata
 dev/ata/ata-raid.c		optional ataraid
 dev/ata/ata-usb.c		optional atausb
-dev/ata/atapi-cam.c		optional atapicam
 dev/ata/atapi-cd.c		optional atapicd
 dev/ata/atapi-fd.c		optional atapifd
 dev/ata/atapi-tape.c		optional atapist
+dev/ata/atapi-cam.c		optional atapicam
+#
 dev/ath/ah_osdep.c optional ath_hal \
 	compile-with "${NORMAL_C} -I$S/dev/ath"
 dev/ath/ath_rate/amrr/amrr.c	optional ath_rate_amrr \

Modified: head/sys/dev/ata/ata-all.c
==============================================================================
--- head/sys/dev/ata/ata-all.c	Thu Oct  9 12:25:07 2008	(r183723)
+++ head/sys/dev/ata/ata-all.c	Thu Oct  9 12:56:57 2008	(r183724)
@@ -616,7 +616,6 @@ ata_getparam(struct ata_device *atadev, 
     if (!error && (isprint(atadev->param.model[0]) ||
 		   isprint(atadev->param.model[1]))) {
 	struct ata_params *atacap = &atadev->param;
-	char buffer[64];
 	int16_t *ptr;
 
 	for (ptr = (int16_t *)atacap;
@@ -648,6 +647,8 @@ ata_getparam(struct ata_device *atadev, 
 		   (atacap->hwres & ATA_CABLE_ID) ? "80":"40");
 
 	if (init) {
+	    char buffer[64];
+
 	    sprintf(buffer, "%.40s/%.8s", atacap->model, atacap->revision);
 	    device_set_desc_copy(atadev->dev, buffer);
 	    if ((atadev->param.config & ATA_PROTO_ATAPI) &&
@@ -677,8 +678,8 @@ int
 ata_identify(device_t dev)
 {
     struct ata_channel *ch = device_get_softc(dev);
-    struct ata_device *devices[ATA_PM];
-    device_t childdevs[ATA_PM];
+    struct ata_device *atadev;
+    device_t child;
     int i;
 
     if (bootverbose)
@@ -688,33 +689,26 @@ ata_identify(device_t dev)
 	if (ch->devices & (((ATA_ATA_MASTER | ATA_ATAPI_MASTER) << i))) {
 	    int unit = -1;
 
-	    if (!(devices[i] = malloc(sizeof(struct ata_device),
-				      M_ATA, M_NOWAIT | M_ZERO))) {
+	    if (!(atadev = malloc(sizeof(struct ata_device),
+				  M_ATA, M_NOWAIT | M_ZERO))) {
 		device_printf(dev, "out of memory\n");
 		return ENOMEM;
 	    }
-	    devices[i]->unit = i;
+	    atadev->unit = i;
 #ifdef ATA_STATIC_ID
 	    if (ch->devices & ((ATA_ATA_MASTER << i)))
 		unit = (device_get_unit(dev) << 1) + i;
 #endif
-	    if (!(childdevs[i] = ata_add_child(dev, devices[i], unit))) {
-		free(devices[i], M_ATA);
-		devices[i]=NULL;
-	    }
-	    else {
-		if (ata_getparam(devices[i], 1)) {
-		    device_delete_child(dev, childdevs[i]);
-		    free(devices[i], M_ATA);
-		    childdevs[i] = NULL;
-		    devices[i] = NULL;
+	    if ((child = ata_add_child(dev, atadev, unit))) {
+		if (ata_getparam(atadev, 1)) {
+		    device_delete_child(dev, child);
+		    free(atadev, M_ATA);
 		}
 	    }
+	    else
+		free(atadev, M_ATA);
 	}
-	devices[i] = NULL;
-	childdevs[i] = NULL;
     }
-
     bus_generic_probe(dev);
     bus_generic_attach(dev);
     return 0;
@@ -895,6 +889,16 @@ ata_mode2str(int mode)
 }
 
 int
+ata_atapi(device_t dev)
+{
+    struct ata_channel *ch = device_get_softc(device_get_parent(dev));
+    struct ata_device *atadev = device_get_softc(dev);
+
+    return ((atadev->unit == ATA_MASTER && ch->devices & ATA_ATAPI_MASTER) ||
+            (atadev->unit == ATA_SLAVE && ch->devices & ATA_ATAPI_SLAVE));
+}
+
+int
 ata_pmode(struct ata_params *ap)
 {
     if (ap->atavalid & ATA_FLAG_64_70) {

Modified: head/sys/dev/ata/ata-all.h
==============================================================================
--- head/sys/dev/ata/ata-all.h	Thu Oct  9 12:25:07 2008	(r183723)
+++ head/sys/dev/ata/ata-all.h	Thu Oct  9 12:56:57 2008	(r183724)
@@ -563,6 +563,7 @@ void ata_modify_if_48bit(struct ata_requ
 void ata_udelay(int interval);
 char *ata_unit2str(struct ata_device *atadev);
 char *ata_mode2str(int mode);
+int ata_atapi(device_t dev);
 int ata_pmode(struct ata_params *ap);
 int ata_wmode(struct ata_params *ap);
 int ata_umode(struct ata_params *ap);

Modified: head/sys/dev/ata/ata-dma.c
==============================================================================
--- head/sys/dev/ata/ata-dma.c	Thu Oct  9 12:25:07 2008	(r183723)
+++ head/sys/dev/ata/ata-dma.c	Thu Oct  9 12:56:57 2008	(r183724)
@@ -81,7 +81,7 @@ ata_dmainit(device_t dev)
     ch->dma.segsize = 63536;
     ch->dma.max_iosize = 128 * DEV_BSIZE;
     ch->dma.max_address = BUS_SPACE_MAXADDR_32BIT;
-    ch->dma.dma_slots = 2;
+    ch->dma.dma_slots = 6;
 
     if (bus_dma_tag_create(bus_get_dma_tag(dev), ch->dma.alignment, 0,
 			   ch->dma.max_address, BUS_SPACE_MAXADDR,

Modified: head/sys/dev/ata/ata-pci.c
==============================================================================
--- head/sys/dev/ata/ata-pci.c	Thu Oct  9 12:25:07 2008	(r183723)
+++ head/sys/dev/ata/ata-pci.c	Thu Oct  9 12:56:57 2008	(r183724)
@@ -54,140 +54,34 @@ static MALLOC_DEFINE(M_ATAPCI, "ata_pci"
 
 /* misc defines */
 #define IOMASK                  0xfffffffc
-#define ATA_PROBE_OK            -10
-
-int
-ata_legacy(device_t dev)
-{
-    return (((pci_read_config(dev, PCIR_PROGIF, 1)&PCIP_STORAGE_IDE_MASTERDEV)&&
-	     ((pci_read_config(dev, PCIR_PROGIF, 1) &
-	       (PCIP_STORAGE_IDE_MODEPRIM | PCIP_STORAGE_IDE_MODESEC)) !=
-	      (PCIP_STORAGE_IDE_MODEPRIM | PCIP_STORAGE_IDE_MODESEC))) ||
-	    (!pci_read_config(dev, PCIR_BAR(0), 4) &&
-	     !pci_read_config(dev, PCIR_BAR(1), 4) &&
-	     !pci_read_config(dev, PCIR_BAR(2), 4) &&
-	     !pci_read_config(dev, PCIR_BAR(3), 4) &&
-	     !pci_read_config(dev, PCIR_BAR(5), 4)));
-}
 
+/* local prototypes */
+static int ata_generic_chipinit(device_t dev);
+static void ata_generic_setmode(device_t dev, int mode);
+
+/*
+ * generic PCI ATA device probe
+ */
 int
 ata_pci_probe(device_t dev)
 {
+    struct ata_pci_controller *ctlr = device_get_softc(dev);
+    char buffer[64];
+
+    /* is this a storage class device ? */
     if (pci_get_class(dev) != PCIC_STORAGE)
 	return ENXIO;
 
-    /* if this is an AHCI chipset grab it */
-    if (pci_get_subclass(dev) == PCIS_STORAGE_SATA) {
-	if (!ata_ahci_ident(dev))
-	    return ATA_PROBE_OK;
-    }
-
-    /* run through the vendor specific drivers */
-    switch (pci_get_vendor(dev)) {
-    case ATA_ACARD_ID: 
-	if (!ata_acard_ident(dev))
-	    return ATA_PROBE_OK;
-	break;
-    case ATA_ACER_LABS_ID:
-	if (!ata_ali_ident(dev))
-	    return ATA_PROBE_OK;
-	break;
-    case ATA_AMD_ID:
-	if (!ata_amd_ident(dev))
-	    return ATA_PROBE_OK;
-	break;
-    case ATA_ADAPTEC_ID:
-	if (!ata_adaptec_ident(dev))
-	    return ATA_PROBE_OK;
-	break;
-    case ATA_ATI_ID:
-	if (!ata_ati_ident(dev))
-	    return ATA_PROBE_OK;
-	break;
-    case ATA_CYRIX_ID:
-	if (!ata_cyrix_ident(dev))
-	    return ATA_PROBE_OK;
-	break;
-    case ATA_CYPRESS_ID:
-	if (!ata_cypress_ident(dev))
-	    return ATA_PROBE_OK;
-	break;
-    case ATA_HIGHPOINT_ID: 
-	if (!ata_highpoint_ident(dev))
-	    return ATA_PROBE_OK;
-	break;
-    case ATA_INTEL_ID:
-	if (!ata_intel_ident(dev))
-	    return ATA_PROBE_OK;
-	break;
-    case ATA_ITE_ID:
-	if (!ata_ite_ident(dev))
-	    return ATA_PROBE_OK;
-	break;
-    case ATA_JMICRON_ID:
-	if (!ata_jmicron_ident(dev))
-	    return ATA_PROBE_OK;
-	break;
-    case ATA_MARVELL_ID:
-	if (!ata_marvell_ident(dev))
-	    return ATA_PROBE_OK;
-	break;
-    case ATA_NATIONAL_ID:
-	if (!ata_national_ident(dev))
-	    return ATA_PROBE_OK;
-	break;
-    case ATA_NETCELL_ID:
-	if (!ata_netcell_ident(dev))
-	    return ATA_PROBE_OK;
-	break;
-    case ATA_NVIDIA_ID:
-	if (!ata_nvidia_ident(dev))
-	    return ATA_PROBE_OK;
-	break;
-    case ATA_PROMISE_ID:
-	if (!ata_promise_ident(dev))
-	    return ATA_PROBE_OK;
-	break;
-    case ATA_SERVERWORKS_ID: 
-	if (!ata_serverworks_ident(dev))
-	    return ATA_PROBE_OK;
-	break;
-    case ATA_SILICON_IMAGE_ID:
-	if (!ata_sii_ident(dev))
-	    return ATA_PROBE_OK;
-	break;
-    case ATA_SIS_ID:
-	if (!ata_sis_ident(dev))
-	    return ATA_PROBE_OK;
-	break;
-    case ATA_VIA_ID: 
-	if (!ata_via_ident(dev))
-	    return ATA_PROBE_OK;
-	break;
-    case ATA_CENATEK_ID:
-	if (pci_get_devid(dev) == ATA_CENATEK_ROCKET) {
-	    ata_generic_ident(dev);
-	    device_set_desc(dev, "Cenatek Rocket Drive controller");
-	    return ATA_PROBE_OK;
-	}
-	break;
-    case ATA_MICRON_ID:
-	if (pci_get_devid(dev) == ATA_MICRON_RZ1000 ||
-	    pci_get_devid(dev) == ATA_MICRON_RZ1001) {
-	    ata_generic_ident(dev);
-	    device_set_desc(dev, 
-		"RZ 100? ATA controller !WARNING! data loss/corruption risk");
-	    return ATA_PROBE_OK;
-	}
-	break;
-    }
+    /* is this an IDE/ATA type device ? */
+    if (pci_get_subclass(dev) != PCIS_STORAGE_IDE)
+	return ENXIO;
+    
+    sprintf(buffer, "%s ATA controller", ata_pcivendor2str(dev));
+    device_set_desc_copy(dev, buffer);
+    ctlr->chipinit = ata_generic_chipinit;
 
-    /* unknown chipset, try generic DMA if it seems possible */
-    if (pci_get_subclass(dev) == PCIS_STORAGE_IDE) {
-	if (!ata_generic_ident(dev))
-	    return ATA_PROBE_OK;
-    }
-    return ENXIO;
+    /* we are a low priority handler */
+    return -100;
 }
 
 int
@@ -286,7 +180,6 @@ ata_pci_resume(device_t dev)
     return error;
 }
 
-
 struct resource *
 ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
 		       u_long start, u_long end, u_long count, u_int flags)
@@ -414,6 +307,28 @@ ata_pci_teardown_intr(device_t dev, devi
     }
 }
     
+static void
+ata_generic_setmode(device_t dev, int mode)
+{
+    struct ata_device *atadev = device_get_softc(dev);
+
+    mode = ata_limit_mode(dev, mode, ATA_UDMA2);
+    mode = ata_check_80pin(dev, mode);
+    if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
+	atadev->mode = mode;
+}
+
+static int
+ata_generic_chipinit(device_t dev)
+{
+    struct ata_pci_controller *ctlr = device_get_softc(dev);
+
+    if (ata_setup_interrupt(dev, ata_generic_intr))
+	return ENXIO;
+    ctlr->setmode = ata_generic_setmode;
+    return 0;
+}
+
 int
 ata_pci_allocate(device_t dev)
 {
@@ -545,35 +460,6 @@ ata_pci_dmainit(device_t dev)
     ch->dma.reset = ata_pci_dmareset;
 }
 
-char *
-ata_pcivendor2str(device_t dev)
-{
-    switch (pci_get_vendor(dev)) {
-    case ATA_ACARD_ID:          return "Acard";
-    case ATA_ACER_LABS_ID:      return "AcerLabs";
-    case ATA_AMD_ID:            return "AMD";
-    case ATA_ADAPTEC_ID:        return "Adaptec";
-    case ATA_ATI_ID:            return "ATI";
-    case ATA_CYRIX_ID:          return "Cyrix";
-    case ATA_CYPRESS_ID:        return "Cypress";
-    case ATA_HIGHPOINT_ID:      return "HighPoint";
-    case ATA_INTEL_ID:          return "Intel";
-    case ATA_ITE_ID:            return "ITE";
-    case ATA_JMICRON_ID:        return "JMicron";
-    case ATA_MARVELL_ID:        return "Marvell";
-    case ATA_NATIONAL_ID:       return "National";
-    case ATA_NETCELL_ID:        return "Netcell";
-    case ATA_NVIDIA_ID:         return "nVidia";
-    case ATA_PROMISE_ID:        return "Promise";
-    case ATA_SERVERWORKS_ID:    return "ServerWorks";
-    case ATA_SILICON_IMAGE_ID:  return "SiI";
-    case ATA_SIS_ID:            return "SiS";
-    case ATA_VIA_ID:            return "VIA";
-    case ATA_CENATEK_ID:        return "Cenatek";
-    case ATA_MICRON_ID:         return "Micron";
-    default:                    return "Generic";
-    }
-}
 
 static device_method_t ata_pci_methods[] = {
     /* device interface */
@@ -595,7 +481,7 @@ static device_method_t ata_pci_methods[]
     { 0, 0 }
 };
 
-devclass_t atapci_devclass;
+devclass_t ata_pci_devclass;
 
 static driver_t ata_pci_driver = {
     "atapci",
@@ -603,7 +489,7 @@ static driver_t ata_pci_driver = {
     sizeof(struct ata_pci_controller),
 };
 
-DRIVER_MODULE(atapci, pci, ata_pci_driver, atapci_devclass, 0, 0);
+DRIVER_MODULE(atapci, pci, ata_pci_driver, ata_pci_devclass, 0, 0);
 MODULE_VERSION(atapci, 1);
 MODULE_DEPEND(atapci, ata, 1, 1, 1);
 
@@ -728,3 +614,171 @@ driver_t ata_pcichannel_driver = {
 };
 
 DRIVER_MODULE(ata, atapci, ata_pcichannel_driver, ata_devclass, 0, 0);
+
+
+/*
+ * misc support fucntions
+ */
+int
+ata_legacy(device_t dev)
+{
+    return (((pci_read_config(dev, PCIR_PROGIF, 1)&PCIP_STORAGE_IDE_MASTERDEV)&&
+	     ((pci_read_config(dev, PCIR_PROGIF, 1) &
+	       (PCIP_STORAGE_IDE_MODEPRIM | PCIP_STORAGE_IDE_MODESEC)) !=
+	      (PCIP_STORAGE_IDE_MODEPRIM | PCIP_STORAGE_IDE_MODESEC))) ||
+	    (!pci_read_config(dev, PCIR_BAR(0), 4) &&
+	     !pci_read_config(dev, PCIR_BAR(1), 4) &&
+	     !pci_read_config(dev, PCIR_BAR(2), 4) &&
+	     !pci_read_config(dev, PCIR_BAR(3), 4) &&
+	     !pci_read_config(dev, PCIR_BAR(5), 4)));
+}
+
+void
+ata_generic_intr(void *data)
+{
+    struct ata_pci_controller *ctlr = data;
+    struct ata_channel *ch;
+    int unit;
+
+    for (unit = 0; unit < ctlr->channels; unit++) {
+	if ((ch = ctlr->interrupt[unit].argument))
+	    ctlr->interrupt[unit].function(ch);
+    }
+}
+
+int
+ata_setup_interrupt(device_t dev, void *intr_func)
+{
+    struct ata_pci_controller *ctlr = device_get_softc(dev);
+    int rid = ATA_IRQ_RID;
+
+    if (!ata_legacy(dev)) {
+	if (!(ctlr->r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+						   RF_SHAREABLE | RF_ACTIVE))) {
+	    device_printf(dev, "unable to map interrupt\n");
+	    return ENXIO;
+	}
+	if ((bus_setup_intr(dev, ctlr->r_irq, ATA_INTR_FLAGS, NULL,
+			    intr_func, ctlr, &ctlr->handle))) {
+	    /* SOS XXX release r_irq */
+	    device_printf(dev, "unable to setup interrupt\n");
+	    return ENXIO;
+	}
+    }
+    return 0;
+}
+
+void
+ata_set_desc(device_t dev)
+{
+    struct ata_pci_controller *ctlr = device_get_softc(dev);
+    char buffer[128];
+
+    sprintf(buffer, "%s %s %s controller",
+            ata_pcivendor2str(dev), ctlr->chip->text, 
+            ata_mode2str(ctlr->chip->max_dma));
+    device_set_desc_copy(dev, buffer);
+}
+
+struct ata_chip_id *
+ata_match_chip(device_t dev, struct ata_chip_id *index)
+{
+    while (index->chipid != 0) {
+	if (pci_get_devid(dev) == index->chipid &&
+	    pci_get_revid(dev) >= index->chiprev)
+	    return index;
+	index++;
+    }
+    return NULL;
+}
+
+struct ata_chip_id *
+ata_find_chip(device_t dev, struct ata_chip_id *index, int slot)
+{
+    device_t *children;
+    int nchildren, i;
+
+    if (device_get_children(device_get_parent(dev), &children, &nchildren))
+	return 0;
+
+    while (index->chipid != 0) {
+	for (i = 0; i < nchildren; i++) {
+	    if (((slot >= 0 && pci_get_slot(children[i]) == slot) || 
+		 (slot < 0 && pci_get_slot(children[i]) <= -slot)) &&
+		pci_get_devid(children[i]) == index->chipid &&
+		pci_get_revid(children[i]) >= index->chiprev) {
+		free(children, M_TEMP);
+		return index;
+	    }
+	}
+	index++;
+    }
+    free(children, M_TEMP);
+    return NULL;
+}
+
+void
+ata_print_cable(device_t dev, u_int8_t *who)
+{
+    device_printf(dev,
+                  "DMA limited to UDMA33, %s found non-ATA66 cable\n", who);
+}
+
+int
+ata_check_80pin(device_t dev, int mode)
+{
+    struct ata_device *atadev = device_get_softc(dev);
+
+    if (!ata_dma_check_80pin) {
+        if (bootverbose)
+            device_printf(dev, "Skipping 80pin cable check\n");
+        return mode;
+    }
+
+    if (mode > ATA_UDMA2 && !(atadev->param.hwres & ATA_CABLE_ID)) {
+        ata_print_cable(dev, "device");
+        mode = ATA_UDMA2;
+    }
+    return mode;
+}
+
+char *
+ata_pcivendor2str(device_t dev)
+{
+    switch (pci_get_vendor(dev)) {
+    case ATA_ACARD_ID:          return "Acard";
+    case ATA_ACER_LABS_ID:      return "AcerLabs";
+    case ATA_AMD_ID:            return "AMD";
+    case ATA_ADAPTEC_ID:        return "Adaptec";
+    case ATA_ATI_ID:            return "ATI";
+    case ATA_CYRIX_ID:          return "Cyrix";
+    case ATA_CYPRESS_ID:        return "Cypress";
+    case ATA_HIGHPOINT_ID:      return "HighPoint";
+    case ATA_INTEL_ID:          return "Intel";
+    case ATA_ITE_ID:            return "ITE";
+    case ATA_JMICRON_ID:        return "JMicron";
+    case ATA_MARVELL_ID:        return "Marvell";
+    case ATA_NATIONAL_ID:       return "National";
+    case ATA_NETCELL_ID:        return "Netcell";
+    case ATA_NVIDIA_ID:         return "nVidia";
+    case ATA_PROMISE_ID:        return "Promise";
+    case ATA_SERVERWORKS_ID:    return "ServerWorks";
+    case ATA_SILICON_IMAGE_ID:  return "SiI";
+    case ATA_SIS_ID:            return "SiS";
+    case ATA_VIA_ID:            return "VIA";
+    case ATA_CENATEK_ID:        return "Cenatek";
+    case ATA_MICRON_ID:         return "Micron";
+    default:                    return "Generic";
+    }
+}
+
+int
+ata_mode2idx(int mode)
+{
+    if ((mode & ATA_DMA_MASK) == ATA_UDMA0)
+	return (mode & ATA_MODE_MASK) + 8;
+    if ((mode & ATA_DMA_MASK) == ATA_WDMA0)
+	return (mode & ATA_MODE_MASK) + 5;
+    return (mode & ATA_MODE_MASK) - ATA_PIO0;
+}
+

Modified: head/sys/dev/ata/ata-pci.h
==============================================================================
--- head/sys/dev/ata/ata-pci.h	Thu Oct  9 12:25:07 2008	(r183723)
+++ head/sys/dev/ata/ata-pci.h	Thu Oct  9 12:56:57 2008	(r183724)
@@ -395,79 +395,6 @@ struct ata_connect_task {
 #define ATA_VIA6420             0x31491106
 #define ATA_VIA6421             0x32491106
 
-/* chipset setup related defines */
-#define AHCI            1
-#define ATPOLD          1
-
-#define ALIOLD          0x01
-#define ALINEW          0x02
-#define ALISATA         0x04
-
-#define ATIPATA		0x01
-#define ATISATA		0x02
-#define ATIAHCI		0x04
-
-#define HPT366          0
-#define HPT370          1
-#define HPT372          2
-#define HPT374          3
-#define HPTOLD          0x01
-
-#define MV50XX          50
-#define MV60XX          60
-#define MV61XX          61
-
-#define PROLD           0
-#define PRNEW           1
-#define PRTX            2
-#define PRMIO           3
-#define PRTX4           0x01
-#define PRSX4X          0x02
-#define PRSX6K          0x04
-#define PRPATA          0x08
-#define PRCMBO          0x10
-#define PRCMBO2         0x20
-#define PRSATA          0x40
-#define PRSATA2         0x80
-
-#define SWKS33          0
-#define SWKS66          1
-#define SWKS100         2
-#define SWKSMIO         3
-
-#define SIIMEMIO        1
-#define SIIPRBIO        2
-#define SIIINTR         0x01
-#define SIISETCLK       0x02
-#define SIIBUG          0x04
-#define SII4CH          0x08
-
-#define SIS_SOUTH       1
-#define SISSATA         2
-#define SIS133NEW       3
-#define SIS133OLD       4
-#define SIS100NEW       5
-#define SIS100OLD       6
-#define SIS66           7
-#define SIS33           8
-
-#define VIA33           0
-#define VIA66           1
-#define VIA100          2
-#define VIA133          3
-#define AMDNVIDIA       4
-
-#define AMDCABLE        0x0001
-#define AMDBUG          0x0002
-#define NVIDIA          0x0004
-#define NV4             0x0010
-#define NVQ             0x0020
-#define VIACLK          0x0100
-#define VIABUG          0x0200
-#define VIABAR          0x0400
-#define VIAAHCI         0x0800
-
-
 /* global prototypes ata-pci.c */
 int ata_pci_probe(device_t dev);
 int ata_pci_attach(device_t dev);
@@ -483,32 +410,62 @@ int ata_pci_status(device_t dev);
 void ata_pci_hw(device_t dev);
 void ata_pci_dmainit(device_t dev);
 char *ata_pcivendor2str(device_t dev);
-
-
-/* global prototypes ata-chipset.c */
-int ata_generic_ident(device_t);
-int ata_ahci_ident(device_t);
-int ata_acard_ident(device_t);
-int ata_ali_ident(device_t);
-int ata_amd_ident(device_t);
-int ata_adaptec_ident(device_t);
-int ata_ati_ident(device_t);
-int ata_cyrix_ident(device_t);
-int ata_cypress_ident(device_t);
-int ata_highpoint_ident(device_t);
-int ata_intel_ident(device_t);
-int ata_ite_ident(device_t);
-int ata_jmicron_ident(device_t);
-int ata_marvell_ident(device_t);
-int ata_national_ident(device_t);
-int ata_nvidia_ident(device_t);
-int ata_netcell_ident(device_t);
-int ata_promise_ident(device_t);
-int ata_serverworks_ident(device_t);
-int ata_sii_ident(device_t);
-int ata_sis_ident(device_t);
-int ata_via_ident(device_t);
 int ata_legacy(device_t);
+void ata_generic_intr(void *data);
+int ata_setup_interrupt(device_t dev, void *intr_func);
+void ata_set_desc(device_t dev);
+struct ata_chip_id *ata_match_chip(device_t dev, struct ata_chip_id *index);
+struct ata_chip_id *ata_find_chip(device_t dev, struct ata_chip_id *index, int slot);
+void ata_print_cable(device_t dev, u_int8_t *who);
+int ata_check_80pin(device_t dev, int mode);
+int ata_mode2idx(int mode);
+
+/* global prototypes ata-sata.c */
+void ata_sata_phy_event(void *context, int dummy);
+void ata_sata_phy_check_events(device_t dev);
+int ata_sata_phy_reset(device_t dev);
+void ata_sata_setmode(device_t dev, int mode);
+int ata_request2fis_h2d(struct ata_request *request, u_int8_t *fis);
+void ata_pm_identify(device_t dev);
+
+/* global prototypes from chipsets/ata-*.c */
+int ata_ahci_chipinit(device_t);
+int ata_ahci_allocate(device_t dev);
+void ata_ahci_reset(device_t dev);
+void ata_ahci_dmainit(device_t dev);
+int ata_marvell_edma_chipinit(device_t);
+int ata_sii_chipinit(device_t);
 
 /* global prototypes ata-dma.c */
 void ata_dmainit(device_t);
+
+/* externs */
+extern devclass_t ata_pci_devclass;
+
+/* macro for easy definition of all driver module stuff */
+#define ATA_DECLARE_DRIVER(dname) \
+static device_method_t __CONCAT(dname,_methods)[] = { \
+    DEVMETHOD(device_probe,     __CONCAT(dname,_probe)), \
+    DEVMETHOD(device_attach,    ata_pci_attach), \
+    DEVMETHOD(device_detach,    ata_pci_detach), \
+    DEVMETHOD(device_suspend,   bus_generic_suspend), \
+    DEVMETHOD(device_resume,    bus_generic_resume), \
+    DEVMETHOD(device_shutdown,  bus_generic_shutdown), \
+    DEVMETHOD(bus_alloc_resource,       ata_pci_alloc_resource), \
+    DEVMETHOD(bus_release_resource,     ata_pci_release_resource), \
+    DEVMETHOD(bus_activate_resource,    bus_generic_activate_resource), \
+    DEVMETHOD(bus_deactivate_resource,  bus_generic_deactivate_resource), \
+    DEVMETHOD(bus_setup_intr,           ata_pci_setup_intr), \
+    DEVMETHOD(bus_teardown_intr,        ata_pci_teardown_intr), \
+    { 0, 0 } \
+}; \
+static driver_t __CONCAT(dname,_driver) = { \
+        "atapci", \
+        __CONCAT(dname,_methods), \
+        sizeof(struct ata_pci_controller) \
+}; \
+DRIVER_MODULE(dname, pci, __CONCAT(dname,_driver), ata_pci_devclass, 0, 0); \
+MODULE_VERSION(dname, 1); \
+MODULE_DEPEND(dname, ata, 1, 1, 1); \
+MODULE_DEPEND(dname, atapci, 1, 1, 1);
+

Added: head/sys/dev/ata/ata-sata.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/ata/ata-sata.c	Thu Oct  9 12:56:57 2008	(r183724)
@@ -0,0 +1,357 @@
+/*-
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer,
+ *    without modification, immediately at the beginning of the file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_ata.h"
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/ata.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/malloc.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/sema.h>
+#include <sys/taskqueue.h>
+#include <vm/uma.h>
+#include <machine/stdarg.h>
+#include <machine/resource.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+#include <dev/ata/ata-all.h>
+#include <dev/ata/ata-pci.h>
+#include <ata_if.h>
+
+/*
+ * SATA support functions
+ */
+void
+ata_sata_phy_event(void *context, int dummy)
+{
+    struct ata_connect_task *tp = (struct ata_connect_task *)context;
+    struct ata_channel *ch = device_get_softc(tp->dev);
+    device_t *children;
+    int nchildren, i;
+
+    mtx_lock(&Giant);   /* newbus suckage it needs Giant */
+    if (tp->action == ATA_C_ATTACH) {
+	if (bootverbose)
+	    device_printf(tp->dev, "CONNECTED\n");
+	ATA_RESET(tp->dev);
+	ata_identify(tp->dev);
+    }
+    if (tp->action == ATA_C_DETACH) {
+	if (!device_get_children(tp->dev, &children, &nchildren)) {
+	    for (i = 0; i < nchildren; i++)
+		if (children[i])
+		    device_delete_child(tp->dev, children[i]);
+	    free(children, M_TEMP);
+	}    
+	mtx_lock(&ch->state_mtx);
+	ch->state = ATA_IDLE;
+	mtx_unlock(&ch->state_mtx);
+	if (bootverbose)
+	    device_printf(tp->dev, "DISCONNECTED\n");
+    }
+    mtx_unlock(&Giant); /* suckage code dealt with, release Giant */
+    free(tp, M_ATA);
+}
+
+void
+ata_sata_phy_check_events(device_t dev)
+{
+    struct ata_channel *ch = device_get_softc(dev);
+    u_int32_t error = ATA_IDX_INL(ch, ATA_SERROR);
+
+    /* clear error bits/interrupt */
+    ATA_IDX_OUTL(ch, ATA_SERROR, error);
+
+    /* do we have any events flagged ? */
+    if (error) {
+	struct ata_connect_task *tp;
+	u_int32_t status = ATA_IDX_INL(ch, ATA_SSTATUS);
+
+	/* if we have a connection event deal with it */
+	if ((error & ATA_SE_PHY_CHANGED) &&
+	    (tp = (struct ata_connect_task *)
+		  malloc(sizeof(struct ata_connect_task),
+			 M_ATA, M_NOWAIT | M_ZERO))) {
+
+	    if (((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN1) ||
+		((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN2)) {
+		if (bootverbose)
+		    device_printf(dev, "CONNECT requested\n");
+		tp->action = ATA_C_ATTACH;
+	    }
+	    else {
+		if (bootverbose)
+		    device_printf(dev, "DISCONNECT requested\n");
+		tp->action = ATA_C_DETACH;
+	    }
+	    tp->dev = dev;
+	    TASK_INIT(&tp->task, 0, ata_sata_phy_event, tp);
+	    taskqueue_enqueue(taskqueue_thread, &tp->task);
+	}
+    }
+}
+
+static int
+ata_sata_connect(struct ata_channel *ch)
+{
+    u_int32_t status;
+    int timeout;
+
+    /* wait up to 1 second for "connect well" */
+    for (timeout = 0; timeout < 100 ; timeout++) {
+	status = ATA_IDX_INL(ch, ATA_SSTATUS);
+	if ((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN1 ||
+	    (status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN2)
+	    break;
+	ata_udelay(10000);
+    }
+    if (timeout >= 100) {
+	if (bootverbose)
+	    device_printf(ch->dev, "SATA connect status=%08x\n", status);
+	return 0;
+    }
+    if (bootverbose)
+	device_printf(ch->dev, "SATA connect time=%dms\n", timeout * 10);
+
+    /* clear SATA error register */
+    ATA_IDX_OUTL(ch, ATA_SERROR, ATA_IDX_INL(ch, ATA_SERROR));
+
+    return 1;
+}
+
+int
+ata_sata_phy_reset(device_t dev)
+{
+    struct ata_channel *ch = device_get_softc(dev);
+    int loop, retry;
+
+    if ((ATA_IDX_INL(ch, ATA_SCONTROL) & ATA_SC_DET_MASK) == ATA_SC_DET_IDLE)
+	return ata_sata_connect(ch);
+
+    for (retry = 0; retry < 10; retry++) {
+	for (loop = 0; loop < 10; loop++) {
+	    ATA_IDX_OUTL(ch, ATA_SCONTROL, ATA_SC_DET_RESET);
+	    ata_udelay(100);
+	    if ((ATA_IDX_INL(ch, ATA_SCONTROL) & ATA_SC_DET_MASK) == 
+		ATA_SC_DET_RESET)
+		break;
+	}
+	ata_udelay(5000);
+	for (loop = 0; loop < 10; loop++) {
+	    ATA_IDX_OUTL(ch, ATA_SCONTROL, ATA_SC_DET_IDLE |
+					   ATA_SC_IPM_DIS_PARTIAL |
+					   ATA_SC_IPM_DIS_SLUMBER);
+	    ata_udelay(100);
+	    if ((ATA_IDX_INL(ch, ATA_SCONTROL) & ATA_SC_DET_MASK) == 0)
+		return ata_sata_connect(ch);
+	}
+    }
+    return 0;
+}
+
+void
+ata_sata_setmode(device_t dev, int mode)
+{
+    struct ata_device *atadev = device_get_softc(dev);
+
+    /*
+     * if we detect that the device isn't a real SATA device we limit 
+     * the transfer mode to UDMA5/ATA100.
+     * this works around the problems some devices has with the 
+     * Marvell 88SX8030 SATA->PATA converters and UDMA6/ATA133.
+     */
+    if (atadev->param.satacapabilities != 0x0000 &&
+	atadev->param.satacapabilities != 0xffff) {
+	struct ata_channel *ch = device_get_softc(device_get_parent(dev));
+
+	/* on some drives we need to set the transfer mode */
+	ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0,
+		       ata_limit_mode(dev, mode, ATA_UDMA6));
+
+	/* query SATA STATUS for the speed */
+        if (ch->r_io[ATA_SSTATUS].res && 
+	   ((ATA_IDX_INL(ch, ATA_SSTATUS) & ATA_SS_CONWELL_MASK) ==
+	    ATA_SS_CONWELL_GEN2))
+	    atadev->mode = ATA_SA300;
+	else 
+	    atadev->mode = ATA_SA150;
+    }
+    else {
+	mode = ata_limit_mode(dev, mode, ATA_UDMA5);
+	if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
+	    atadev->mode = mode;
+    }
+}
+
+int
+ata_request2fis_h2d(struct ata_request *request, u_int8_t *fis)
+{
+    struct ata_device *atadev = device_get_softc(request->dev);
+
+    if (request->flags & ATA_R_ATAPI) {
+	fis[0] = 0x27;  		/* host to device */
+	fis[1] = 0x80 | (atadev->unit & 0x0f);
+	fis[2] = ATA_PACKET_CMD;
+	if (request->flags & (ATA_R_READ | ATA_R_WRITE))

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list