Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 30 Mar 2009 22:18:38 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r190581 - in head/sys: . amd64/include/xen arm/arm cddl/dev/dtnfsclient contrib/pf dev/ata dev/ata/chipsets dev/cxgb dev/sound/usb dev/usb dev/usb/bluetooth dev/usb/controller dev/usb/i...
Message-ID:  <200903302218.n2UMIc6t080193@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Mon Mar 30 22:18:38 2009
New Revision: 190581
URL: http://svn.freebsd.org/changeset/base/190581

Log:
  Integrate user/mav/ata branch:
  
  Add ch_suspend/ch_resume methods for PCI controllers and implement them
  for AHCI. Refactor AHCI channel initialization according to it.
  
  Fix Port Multipliers operation. It is far from perfect yet, but works now.
  Tested with JMicron JMB363 AHCI + SiI 3726 PMP pair.
  Previous version was also tested with SiI 4726 PMP.
  
  Hardware sponsored by: Vitsch Electronics / VEHosting.nl

Modified:
  head/sys/   (props changed)
  head/sys/amd64/include/xen/   (props changed)
  head/sys/arm/arm/cpufunc_asm_sheeva.S   (props changed)
  head/sys/cddl/dev/dtnfsclient/   (props changed)
  head/sys/contrib/pf/   (props changed)
  head/sys/dev/ata/ata-pci.c
  head/sys/dev/ata/ata-pci.h
  head/sys/dev/ata/ata-sata.c
  head/sys/dev/ata/ata-usb.c   (props changed)
  head/sys/dev/ata/chipsets/ata-ahci.c
  head/sys/dev/ata/chipsets/ata-intel.c
  head/sys/dev/ata/chipsets/ata-jmicron.c
  head/sys/dev/ata/chipsets/ata-marvell.c
  head/sys/dev/ata/chipsets/ata-nvidia.c
  head/sys/dev/ata/chipsets/ata-promise.c
  head/sys/dev/ata/chipsets/ata-siliconimage.c
  head/sys/dev/ata/chipsets/ata-sis.c
  head/sys/dev/ata/chipsets/ata-via.c
  head/sys/dev/cxgb/   (props changed)
  head/sys/dev/sound/usb/uaudio.c   (props changed)
  head/sys/dev/sound/usb/uaudio.h   (props changed)
  head/sys/dev/sound/usb/uaudio_pcm.c   (props changed)
  head/sys/dev/sound/usb/uaudioreg.h   (props changed)
  head/sys/dev/usb/README.TXT   (props changed)
  head/sys/dev/usb/bluetooth/TODO.TXT   (props changed)
  head/sys/dev/usb/bluetooth/ng_ubt.c   (props changed)
  head/sys/dev/usb/bluetooth/ng_ubt_var.h   (props changed)
  head/sys/dev/usb/bluetooth/ubtbcmfw.c   (props changed)
  head/sys/dev/usb/controller/at91dci.c   (props changed)
  head/sys/dev/usb/controller/at91dci.h   (props changed)
  head/sys/dev/usb/controller/at91dci_atmelarm.c   (props changed)
  head/sys/dev/usb/controller/atmegadci.c   (props changed)
  head/sys/dev/usb/controller/atmegadci.h   (props changed)
  head/sys/dev/usb/controller/atmegadci_atmelarm.c   (props changed)
  head/sys/dev/usb/controller/ehci.c   (props changed)
  head/sys/dev/usb/controller/ehci.h   (props changed)
  head/sys/dev/usb/controller/ehci_ixp4xx.c   (props changed)
  head/sys/dev/usb/controller/ehci_mbus.c   (props changed)
  head/sys/dev/usb/controller/ehci_pci.c   (props changed)
  head/sys/dev/usb/controller/musb_otg.c   (props changed)
  head/sys/dev/usb/controller/musb_otg.h   (props changed)
  head/sys/dev/usb/controller/musb_otg_atmelarm.c   (props changed)
  head/sys/dev/usb/controller/ohci.c   (props changed)
  head/sys/dev/usb/controller/ohci.h   (props changed)
  head/sys/dev/usb/controller/ohci_atmelarm.c   (props changed)
  head/sys/dev/usb/controller/ohci_pci.c   (props changed)
  head/sys/dev/usb/controller/uhci.c   (props changed)
  head/sys/dev/usb/controller/uhci.h   (props changed)
  head/sys/dev/usb/controller/uhci_pci.c   (props changed)
  head/sys/dev/usb/controller/usb_controller.c   (props changed)
  head/sys/dev/usb/controller/uss820dci.c   (props changed)
  head/sys/dev/usb/controller/uss820dci.h   (props changed)
  head/sys/dev/usb/controller/uss820dci_atmelarm.c   (props changed)
  head/sys/dev/usb/input/uhid.c   (props changed)
  head/sys/dev/usb/input/ukbd.c   (props changed)
  head/sys/dev/usb/input/ums.c   (props changed)
  head/sys/dev/usb/input/usb_rdesc.h   (props changed)
  head/sys/dev/usb/misc/udbp.c   (props changed)
  head/sys/dev/usb/misc/udbp.h   (props changed)
  head/sys/dev/usb/misc/ufm.c   (props changed)
  head/sys/dev/usb/net/if_aue.c   (props changed)
  head/sys/dev/usb/net/if_auereg.h   (props changed)
  head/sys/dev/usb/net/if_axe.c   (props changed)
  head/sys/dev/usb/net/if_axereg.h   (props changed)
  head/sys/dev/usb/net/if_cdce.c   (props changed)
  head/sys/dev/usb/net/if_cdcereg.h   (props changed)
  head/sys/dev/usb/net/if_cue.c   (props changed)
  head/sys/dev/usb/net/if_cuereg.h   (props changed)
  head/sys/dev/usb/net/if_kue.c   (props changed)
  head/sys/dev/usb/net/if_kuefw.h   (props changed)
  head/sys/dev/usb/net/if_kuereg.h   (props changed)
  head/sys/dev/usb/net/if_rue.c   (props changed)
  head/sys/dev/usb/net/if_ruereg.h   (props changed)
  head/sys/dev/usb/net/if_udav.c   (props changed)
  head/sys/dev/usb/net/if_udavreg.h   (props changed)
  head/sys/dev/usb/net/usb_ethernet.c   (props changed)
  head/sys/dev/usb/net/usb_ethernet.h   (props changed)
  head/sys/dev/usb/quirk/usb_quirk.c   (props changed)
  head/sys/dev/usb/quirk/usb_quirk.h   (props changed)
  head/sys/dev/usb/serial/u3g.c   (props changed)
  head/sys/dev/usb/serial/uark.c   (props changed)
  head/sys/dev/usb/serial/ubsa.c   (props changed)
  head/sys/dev/usb/serial/ubser.c   (props changed)
  head/sys/dev/usb/serial/uchcom.c   (props changed)
  head/sys/dev/usb/serial/ucycom.c   (props changed)
  head/sys/dev/usb/serial/ufoma.c   (props changed)
  head/sys/dev/usb/serial/uftdi.c   (props changed)
  head/sys/dev/usb/serial/uftdi_reg.h   (props changed)
  head/sys/dev/usb/serial/ugensa.c   (props changed)
  head/sys/dev/usb/serial/uipaq.c   (props changed)
  head/sys/dev/usb/serial/ulpt.c   (props changed)
  head/sys/dev/usb/serial/umct.c   (props changed)
  head/sys/dev/usb/serial/umodem.c   (props changed)
  head/sys/dev/usb/serial/umoscom.c   (props changed)
  head/sys/dev/usb/serial/uplcom.c   (props changed)
  head/sys/dev/usb/serial/usb_serial.c   (props changed)
  head/sys/dev/usb/serial/usb_serial.h   (props changed)
  head/sys/dev/usb/serial/uslcom.c   (props changed)
  head/sys/dev/usb/serial/uvisor.c   (props changed)
  head/sys/dev/usb/serial/uvscom.c   (props changed)
  head/sys/dev/usb/storage/rio500_usb.h   (props changed)
  head/sys/dev/usb/storage/umass.c   (props changed)
  head/sys/dev/usb/storage/urio.c   (props changed)
  head/sys/dev/usb/storage/ustorage_fs.c   (props changed)
  head/sys/dev/usb/template/usb_template.c   (props changed)
  head/sys/dev/usb/template/usb_template.h   (props changed)
  head/sys/dev/usb/template/usb_template_cdce.c   (props changed)
  head/sys/dev/usb/template/usb_template_msc.c   (props changed)
  head/sys/dev/usb/template/usb_template_mtp.c   (props changed)
  head/sys/dev/usb/ufm_ioctl.h   (props changed)
  head/sys/dev/usb/usb.h   (props changed)
  head/sys/dev/usb/usb_bus.h   (props changed)
  head/sys/dev/usb/usb_busdma.c   (props changed)
  head/sys/dev/usb/usb_busdma.h   (props changed)
  head/sys/dev/usb/usb_cdc.h   (props changed)
  head/sys/dev/usb/usb_compat_linux.c   (props changed)
  head/sys/dev/usb/usb_compat_linux.h   (props changed)
  head/sys/dev/usb/usb_controller.h   (props changed)
  head/sys/dev/usb/usb_core.c   (props changed)
  head/sys/dev/usb/usb_core.h   (props changed)
  head/sys/dev/usb/usb_debug.c   (props changed)
  head/sys/dev/usb/usb_debug.h   (props changed)
  head/sys/dev/usb/usb_defs.h   (props changed)
  head/sys/dev/usb/usb_dev.c   (props changed)
  head/sys/dev/usb/usb_dev.h   (props changed)
  head/sys/dev/usb/usb_device.c   (props changed)
  head/sys/dev/usb/usb_device.h   (props changed)
  head/sys/dev/usb/usb_dynamic.c   (props changed)
  head/sys/dev/usb/usb_dynamic.h   (props changed)
  head/sys/dev/usb/usb_endian.h   (props changed)
  head/sys/dev/usb/usb_error.c   (props changed)
  head/sys/dev/usb/usb_error.h   (props changed)
  head/sys/dev/usb/usb_generic.c   (props changed)
  head/sys/dev/usb/usb_generic.h   (props changed)
  head/sys/dev/usb/usb_handle_request.c   (props changed)
  head/sys/dev/usb/usb_handle_request.h   (props changed)
  head/sys/dev/usb/usb_hid.c   (props changed)
  head/sys/dev/usb/usb_hid.h   (props changed)
  head/sys/dev/usb/usb_hub.c   (props changed)
  head/sys/dev/usb/usb_hub.h   (props changed)
  head/sys/dev/usb/usb_if.m   (props changed)
  head/sys/dev/usb/usb_ioctl.h   (props changed)
  head/sys/dev/usb/usb_lookup.c   (props changed)
  head/sys/dev/usb/usb_lookup.h   (props changed)
  head/sys/dev/usb/usb_mbuf.c   (props changed)
  head/sys/dev/usb/usb_mbuf.h   (props changed)
  head/sys/dev/usb/usb_mfunc.h   (props changed)
  head/sys/dev/usb/usb_msctest.c   (props changed)
  head/sys/dev/usb/usb_msctest.h   (props changed)
  head/sys/dev/usb/usb_parse.c   (props changed)
  head/sys/dev/usb/usb_parse.h   (props changed)
  head/sys/dev/usb/usb_pci.h   (props changed)
  head/sys/dev/usb/usb_process.c   (props changed)
  head/sys/dev/usb/usb_process.h   (props changed)
  head/sys/dev/usb/usb_request.c   (props changed)
  head/sys/dev/usb/usb_request.h   (props changed)
  head/sys/dev/usb/usb_revision.h   (props changed)
  head/sys/dev/usb/usb_sw_transfer.c   (props changed)
  head/sys/dev/usb/usb_sw_transfer.h   (props changed)
  head/sys/dev/usb/usb_transfer.c   (props changed)
  head/sys/dev/usb/usb_transfer.h   (props changed)
  head/sys/dev/usb/usb_util.c   (props changed)
  head/sys/dev/usb/usb_util.h   (props changed)
  head/sys/dev/usb/usbdevs   (props changed)
  head/sys/dev/usb/usbhid.h   (props changed)
  head/sys/dev/usb/wlan/if_rum.c   (props changed)
  head/sys/dev/usb/wlan/if_rumfw.h   (props changed)
  head/sys/dev/usb/wlan/if_rumreg.h   (props changed)
  head/sys/dev/usb/wlan/if_rumvar.h   (props changed)
  head/sys/dev/usb/wlan/if_ural.c   (props changed)
  head/sys/dev/usb/wlan/if_uralreg.h   (props changed)
  head/sys/dev/usb/wlan/if_uralvar.h   (props changed)
  head/sys/dev/usb/wlan/if_zyd.c   (props changed)
  head/sys/dev/usb/wlan/if_zydfw.h   (props changed)
  head/sys/dev/usb/wlan/if_zydreg.h   (props changed)
  head/sys/dev/usb/wlan/usb_wlan.h   (props changed)
  head/sys/dev/xen/netfront/   (props changed)
  head/sys/dev/xen/xenpci/   (props changed)
  head/sys/legacy/dev/ata/ata-usb.c   (props changed)
  head/sys/legacy/dev/sound/usb/uaudio.c   (props changed)
  head/sys/legacy/dev/sound/usb/uaudio.h   (props changed)
  head/sys/legacy/dev/sound/usb/uaudio_pcm.c   (props changed)
  head/sys/legacy/dev/sound/usb/uaudioreg.h   (props changed)
  head/sys/legacy/dev/usb/   (props changed)
  head/sys/legacy/dev/usb/ehci_ixp4xx.c   (props changed)
  head/sys/mips/mips/elf64_machdep.c   (props changed)
  head/sys/modules/dtrace/dtnfsclient/   (props changed)
  head/sys/modules/ip6_mroute_mod/   (props changed)
  head/sys/modules/ipmi/ipmi_linux/   (props changed)
  head/sys/xen/evtchn.h   (props changed)
  head/sys/xen/hypervisor.h   (props changed)
  head/sys/xen/xen_intr.h   (props changed)

Modified: head/sys/dev/ata/ata-pci.c
==============================================================================
--- head/sys/dev/ata/ata-pci.c	Mon Mar 30 21:54:39 2009	(r190580)
+++ head/sys/dev/ata/ata-pci.c	Mon Mar 30 22:18:38 2009	(r190581)
@@ -584,22 +584,35 @@ ata_pcichannel_detach(device_t dev)
 static int
 ata_pcichannel_suspend(device_t dev)
 {
+    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
     struct ata_channel *ch = device_get_softc(dev);
+    int error;
 
     if (!ch->attached)
 	return (0);
 
-    return ata_suspend(dev);
+    if ((error = ata_suspend(dev)))
+	return (error);
+
+    if (ctlr->ch_suspend != NULL && (error = ctlr->ch_suspend(dev)))
+	return (error);
+
+    return (0);
 }
 
 static int
 ata_pcichannel_resume(device_t dev)
 {
+    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
     struct ata_channel *ch = device_get_softc(dev);
+    int error;
 
     if (!ch->attached)
 	return (0);
 
+    if (ctlr->ch_resume != NULL && (error = ctlr->ch_resume(dev)))
+	return (error);
+
     return ata_resume(dev);
 }
 

Modified: head/sys/dev/ata/ata-pci.h
==============================================================================
--- head/sys/dev/ata/ata-pci.h	Mon Mar 30 21:54:39 2009	(r190580)
+++ head/sys/dev/ata/ata-pci.h	Mon Mar 30 22:18:38 2009	(r190581)
@@ -57,6 +57,8 @@ struct ata_pci_controller {
     int                 (*resume)(device_t);
     int                 (*ch_attach)(device_t);
     int                 (*ch_detach)(device_t);
+    int                 (*ch_suspend)(device_t);
+    int                 (*ch_resume)(device_t);
     int                 (*locking)(device_t, int);
     void                (*reset)(device_t);
     void                (*setmode)(device_t, int);
@@ -443,7 +445,9 @@ int ata_mode2idx(int mode);
 
 /* global prototypes ata-sata.c */
 void ata_sata_phy_check_events(device_t dev);
-int ata_sata_phy_reset(device_t dev);
+int ata_sata_scr_read(struct ata_channel *ch, int port, int reg, uint32_t *val);
+int ata_sata_scr_write(struct ata_channel *ch, int port, int reg, uint32_t val);
+int ata_sata_phy_reset(device_t dev, int port, int quick);
 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);
@@ -452,6 +456,8 @@ void ata_pm_identify(device_t dev);
 int ata_ahci_chipinit(device_t);
 int ata_ahci_ch_attach(device_t dev);
 int ata_ahci_ch_detach(device_t dev);
+int ata_ahci_ch_suspend(device_t dev);
+int ata_ahci_ch_resume(device_t dev);
 void ata_ahci_reset(device_t dev);
 int ata_marvell_edma_chipinit(device_t);
 int ata_sii_chipinit(device_t);

Modified: head/sys/dev/ata/ata-sata.c
==============================================================================
--- head/sys/dev/ata/ata-sata.c	Mon Mar 30 21:54:39 2009	(r190580)
+++ head/sys/dev/ata/ata-sata.c	Mon Mar 30 22:18:38 2009	(r190581)
@@ -73,59 +73,141 @@ ata_sata_phy_check_events(device_t dev)
     }
 }
 
+int
+ata_sata_scr_read(struct ata_channel *ch, int port, int reg, uint32_t *val)
+{
+    int r;
+
+    if (port < 0) {
+	*val = ATA_IDX_INL(ch, reg);
+	return (0);
+    } else {
+	switch (reg) {
+	    case ATA_SSTATUS:
+		r = 0;
+		break;
+	    case ATA_SERROR:
+		r = 1;
+		break;
+	    case ATA_SCONTROL:
+		r = 2;
+		break;
+	    default:
+		return (EINVAL);
+	}
+	return (ch->hw.pm_read(ch->dev, port, r, val));
+    }
+}
+
+int
+ata_sata_scr_write(struct ata_channel *ch, int port, int reg, uint32_t val)
+{
+    int r;
+
+    if (port < 0) {
+	ATA_IDX_OUTL(ch, reg, val);
+	return (0);
+    } else {
+	switch (reg) {
+	    case ATA_SERROR:
+		r = 1;
+		break;
+	    case ATA_SCONTROL:
+		r = 2;
+		break;
+	    default:
+		return (EINVAL);
+	}
+	return (ch->hw.pm_write(ch->dev, port, r, val));
+    }
+}
+
 static int
-ata_sata_connect(struct ata_channel *ch)
+ata_sata_connect(struct ata_channel *ch, int port)
 {
     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 (ata_sata_scr_read(ch, port, ATA_SSTATUS, &status))
+	    return (0);
 	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);
+	if (bootverbose) {
+	    if (port < 0) {
+		device_printf(ch->dev, "SATA connect timeout status=%08x\n",
+		    status);
+	    } else {
+		device_printf(ch->dev, "p%d: SATA connect timeout status=%08x\n",
+		    port, status);
+	    }
+	}
 	return 0;
     }
-    if (bootverbose)
-	device_printf(ch->dev, "SATA connect time=%dms\n", timeout * 10);
+    if (bootverbose) {
+	if (port < 0) {
+	    device_printf(ch->dev, "SATA connect time=%dms status=%08x\n",
+		timeout * 10, status);
+	} else {
+	    device_printf(ch->dev, "p%d: SATA connect time=%dms status=%08x\n",
+		port, timeout * 10, status);
+	}
+    }
 
     /* clear SATA error register */
-    ATA_IDX_OUTL(ch, ATA_SERROR, ATA_IDX_INL(ch, ATA_SERROR));
+    ata_sata_scr_write(ch, port, ATA_SERROR, 0xffffffff);
 
     return 1;
 }
 
 int
-ata_sata_phy_reset(device_t dev)
+ata_sata_phy_reset(device_t dev, int port, int quick)
 {
     struct ata_channel *ch = device_get_softc(dev);
     int loop, retry;
+    uint32_t val;
 
-    if ((ATA_IDX_INL(ch, ATA_SCONTROL) & ATA_SC_DET_MASK) == ATA_SC_DET_IDLE)
-	return ata_sata_connect(ch);
+    if (quick) {
+	if (ata_sata_scr_read(ch, port, ATA_SCONTROL, &val))
+	    return (0);
+	if ((val & ATA_SC_DET_MASK) == ATA_SC_DET_IDLE)
+	    return ata_sata_connect(ch, port);
+    }
 
+    if (bootverbose) {
+	if (port < 0) {
+	    device_printf(dev, "hardware reset ...\n");
+	} else {
+	    device_printf(dev, "p%d: hardware reset ...\n", port);
+	}
+    }
     for (retry = 0; retry < 10; retry++) {
 	for (loop = 0; loop < 10; loop++) {
-	    ATA_IDX_OUTL(ch, ATA_SCONTROL, ATA_SC_DET_RESET);
+	    if (ata_sata_scr_write(ch, port, ATA_SCONTROL, ATA_SC_DET_RESET))
+		return (0);
 	    ata_udelay(100);
-	    if ((ATA_IDX_INL(ch, ATA_SCONTROL) & ATA_SC_DET_MASK) == 
-		ATA_SC_DET_RESET)
+	    if (ata_sata_scr_read(ch, port, ATA_SCONTROL, &val))
+		return (0);
+	    if ((val & 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);
+	    if (ata_sata_scr_write(ch, port, ATA_SCONTROL,
+					ATA_SC_DET_IDLE |
+					ATA_SC_IPM_DIS_PARTIAL |
+					ATA_SC_IPM_DIS_SLUMBER))
+		return (0);
 	    ata_udelay(100);
-	    if ((ATA_IDX_INL(ch, ATA_SCONTROL) & ATA_SC_DET_MASK) == 0)
-		return ata_sata_connect(ch);
+	    if (ata_sata_scr_read(ch, port, ATA_SCONTROL, &val))
+		return (0);
+	    if ((val & ATA_SC_DET_MASK) == 0)
+		return ata_sata_connect(ch, port);
 	}
     }
     return 0;
@@ -237,14 +319,27 @@ ata_pm_identify(device_t dev)
     /* chip specific quirks */
     switch (pm_chipid) {
     case 0x37261095:
-	/* Some of these bogusly reports 6 ports */
+	/* This PM declares 6 ports, while only 5 of them are real.
+	 * Port 5 is enclosure management bridge port, which has implementation
+	 * problems, causing probe faults. Hide it for now. */
+	device_printf(dev, "SiI 3726 (rev=%x) Port Multiplier with %d (5) ports\n",
+		      pm_revision, pm_ports);
 	pm_ports = 5;
-	device_printf(dev, "SiI 3726 r%x Portmultiplier with %d ports\n",
+	break;
+
+    case 0x47261095:
+	/* This PM declares 7 ports, while only 5 of them are real.
+	 * Port 5 is some fake "Config  Disk" with 640 sectors size,
+	 * port 6 is enclosure management bridge port.
+	 * Both fake ports has implementation problems, causing
+	 * probe faults. Hide them for now. */
+	device_printf(dev, "SiI 4726 (rev=%x) Port Multiplier with %d (5) ports\n",
 		      pm_revision, pm_ports);
+	pm_ports = 5;
 	break;
 
     default:
-	device_printf(dev, "Portmultiplier (id=%08x rev=%x) with %d ports\n",
+	device_printf(dev, "Port Multiplier (id=%08x rev=%x) with %d ports\n",
 		      pm_chipid, pm_revision, pm_ports);
     }
 
@@ -253,41 +348,17 @@ ata_pm_identify(device_t dev)
 
     /* reset all ports and register if anything connected */
     for (port=0; port < pm_ports; port++) {
-	u_int32_t signature, status;
-	int timeout;
+	u_int32_t signature;
 
-	if (ch->hw.pm_write(dev, port, 2, ATA_SC_DET_RESET)) {
-	    device_printf(dev, "p%d: writing ATA_SC_DET_RESET failed\n", port);
+	if (!ata_sata_phy_reset(dev, port, 1))
 	    continue;
-	}
-
-	ata_udelay(5000);
-
-	if (ch->hw.pm_write(dev, port, 2, ATA_SC_DET_IDLE)) {
-	    device_printf(dev, "p%d: writing ATA_SC_DET_idle failed\n", port);
-	    continue;
-	}
-
-	ata_udelay(5000);
-
-	/* wait up to 1 second for "connect well" */
-	for (timeout = 0; timeout < 100 ; timeout++) {
-	    ch->hw.pm_read(dev, port, 0, &status);
-	    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(dev, "p%d: connect status=%08x\n", port, status);
-	    continue;
-	}
-	if (bootverbose)
-	    device_printf(dev, "p%d: connect time %dms\n", port, timeout * 10);
 
-	/* clear SERROR register */
-	ch->hw.pm_write(dev, port, 1, 0xffffffff);
+	/*
+	 * XXX: I have no idea how to properly wait for PMP port hardreset
+	 * completion. Without this delay soft reset does not completes
+	 * successfully.
+	 */
+	DELAY(1000000);
 
 	signature = ch->hw.softreset(dev, port);
 

Modified: head/sys/dev/ata/chipsets/ata-ahci.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-ahci.c	Mon Mar 30 21:54:39 2009	(r190580)
+++ head/sys/dev/ata/chipsets/ata-ahci.c	Mon Mar 30 22:18:38 2009	(r190581)
@@ -59,10 +59,16 @@ static int ata_ahci_begin_transaction(st
 static int ata_ahci_end_transaction(struct ata_request *request);
 static int ata_ahci_pm_read(device_t dev, int port, int reg, u_int32_t *result);
 static int ata_ahci_pm_write(device_t dev, int port, int reg, u_int32_t result);
+static int ata_ahci_hardreset(device_t dev, int port, uint32_t *signature);
 static u_int32_t ata_ahci_softreset(device_t dev, int port);
 static void ata_ahci_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error);
 static int ata_ahci_setup_fis(struct ata_ahci_cmd_tab *ctp, struct ata_request *equest);
 static void ata_ahci_dmainit(device_t dev);
+static void ata_ahci_start(device_t dev);
+static void ata_ahci_stop(device_t dev);
+static void ata_ahci_clo(device_t dev);
+static void ata_ahci_start_fr(device_t dev);
+static void ata_ahci_stop_fr(device_t dev);
 
 /*
  * AHCI v1.x compliant SATA chipset support functions
@@ -131,6 +137,8 @@ ata_ahci_chipinit(device_t dev)
     ctlr->reset = ata_ahci_reset;
     ctlr->ch_attach = ata_ahci_ch_attach;
     ctlr->ch_detach = ata_ahci_ch_detach;
+    ctlr->ch_suspend = ata_ahci_ch_suspend;
+    ctlr->ch_resume = ata_ahci_ch_resume;
     ctlr->setmode = ata_sata_setmode;
     ctlr->suspend = ata_ahci_suspend;
     ctlr->resume = ata_ahci_ctlr_reset;
@@ -192,7 +200,6 @@ ata_ahci_suspend(device_t dev)
     return 0;
 }
 
-
 int
 ata_ahci_ch_attach(device_t dev)
 {
@@ -220,12 +227,22 @@ ata_ahci_ch_attach(device_t dev)
     ch->hw.pm_read = ata_ahci_pm_read;
     ch->hw.pm_write = ata_ahci_pm_write;
 
+    ata_ahci_ch_resume(dev);
     return 0;
 }
 
 int
 ata_ahci_ch_detach(device_t dev)
 {
+
+    ata_ahci_ch_suspend(dev);
+    ata_dmafini(dev);
+    return (0);
+}
+
+int
+ata_ahci_ch_suspend(device_t dev)
+{
     struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
     struct ata_channel *ch = device_get_softc(dev);
     int offset = ch->unit << 7;
@@ -233,6 +250,8 @@ ata_ahci_ch_detach(device_t dev)
     /* Disable port interrupts. */
     ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_IE + offset, 0);
     /* Reset command register. */
+    ata_ahci_stop(dev);
+    ata_ahci_stop_fr(dev);
     ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CMD + offset, 0);
 
     /* Allow everything including partial and slumber modes. */
@@ -243,7 +262,35 @@ ata_ahci_ch_detach(device_t dev)
     /* Disable PHY. */
     ATA_IDX_OUTL(ch, ATA_SCONTROL, ATA_SC_DET_DISABLE);
 
-    ata_dmafini(dev);
+    return (0);
+}
+
+int
+ata_ahci_ch_resume(device_t dev)
+{
+    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+    struct ata_channel *ch = device_get_softc(dev);
+    uint64_t work;
+    int offset = ch->unit << 7;
+
+    /* Disable port interrupts */
+    ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_IE + offset, 0);
+
+    /* setup work areas */
+    work = ch->dma.work_bus + ATA_AHCI_CL_OFFSET;
+    ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CLB + offset, work & 0xffffffff);
+    ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CLBU + offset, work >> 32);
+
+    work = ch->dma.work_bus + ATA_AHCI_FB_OFFSET;
+    ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_FB + offset, work & 0xffffffff); 
+    ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_FBU + offset, work >> 32);
+
+    /* activate the channel and power/spin up device */
+    ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CMD + offset,
+	     (ATA_AHCI_P_CMD_ACTIVE | ATA_AHCI_P_CMD_POD | ATA_AHCI_P_CMD_SUD));
+    ata_ahci_start_fr(dev);
+    ata_ahci_start(dev);
+
     return (0);
 }
 
@@ -366,9 +413,6 @@ ata_ahci_begin_transaction(struct ata_re
 		 ATA_INL(ctlr->r_res2, ATA_AHCI_P_CMD + offset) &
 		 ~ATA_AHCI_P_CMD_ATAPI);
 
-    /* set PM port to address */
-    //ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_FBS + offset, (port << 8) | 0x00000001);
-
     /* issue command to controller */
     ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CI + offset, (1 << request->tag));
     
@@ -465,9 +509,6 @@ ata_ahci_issue_cmd(device_t dev, u_int16
     clp->bytecount = 0;
     clp->cmd_table_phys = htole64(ch->dma.work_bus + ATA_AHCI_CT_OFFSET);
 
-    /* set PM port */
-    //ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_FBS + offset, (port << 8) | 0x00000001);
-
     /* issue command to controller */
     ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CI + offset, 1);
 
@@ -480,7 +521,7 @@ ata_ahci_issue_cmd(device_t dev, u_int16
 
     /* clear interrupts */
     ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_IS + offset,
-	     ATA_INL(ctlr->r_res2, ATA_AHCI_P_IS + offset));
+	    ATA_INL(ctlr->r_res2, ATA_AHCI_P_IS + offset));
 
     if (timeout && (count >= timeout)) {
 	if (bootverbose) {
@@ -559,7 +600,7 @@ ata_ahci_stop(device_t dev)
     /* kill off all activity on this channel */
     cmd = ATA_INL(ctlr->r_res2, ATA_AHCI_P_CMD + offset);
     ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CMD + offset,
-	     cmd & ~(ATA_AHCI_P_CMD_FRE | ATA_AHCI_P_CMD_ST));
+	     cmd & ~ATA_AHCI_P_CMD_ST);
 
     /* XXX SOS this is not entirely wrong */
     timeout = 0;
@@ -617,10 +658,47 @@ ata_ahci_start(device_t dev)
     /* start operations on this channel */
     cmd = ATA_INL(ctlr->r_res2, ATA_AHCI_P_CMD + offset);
     ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CMD + offset,
-	     cmd | (ATA_AHCI_P_CMD_FRE | ATA_AHCI_P_CMD_ST) |
+	     cmd | ATA_AHCI_P_CMD_ST |
 	     (ch->devices & ATA_PORTMULTIPLIER ? ATA_AHCI_P_CMD_PMA : 0));
 }
 
+static void
+ata_ahci_stop_fr(device_t dev)
+{
+    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+    struct ata_channel *ch = device_get_softc(dev);
+    u_int32_t cmd;
+    int offset = ch->unit << 7;
+    int timeout;
+
+    /* kill off all activity on this channel */
+    cmd = ATA_INL(ctlr->r_res2, ATA_AHCI_P_CMD + offset);
+    ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CMD + offset, cmd & ~ATA_AHCI_P_CMD_FRE);
+
+    timeout = 0;
+    do {
+	DELAY(1000);
+	if (timeout++ > 1000) {
+	    device_printf(dev, "stopping AHCI FR engine failed\n");
+	    break;
+	}
+    }
+    while (ATA_INL(ctlr->r_res2, ATA_AHCI_P_CMD + offset) & ATA_AHCI_P_CMD_FR);
+}
+
+static void
+ata_ahci_start_fr(device_t dev)
+{
+    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+    struct ata_channel *ch = device_get_softc(dev);
+    u_int32_t cmd;
+    int offset = ch->unit << 7;
+
+    /* start FIS reception on this channel */
+    cmd = ATA_INL(ctlr->r_res2, ATA_AHCI_P_CMD + offset);
+    ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CMD + offset, cmd | ATA_AHCI_P_CMD_FRE);
+}
+
 static int
 ata_ahci_wait_ready(device_t dev, int t)
 {
@@ -628,13 +706,14 @@ ata_ahci_wait_ready(device_t dev, int t)
     struct ata_channel *ch = device_get_softc(dev);
     int offset = ch->unit << 7;
     int timeout = 0;
+    uint32_t val;
 
-    while (ATA_INL(ctlr->r_res2, ATA_AHCI_P_TFD + offset) &
+    while ((val = ATA_INL(ctlr->r_res2, ATA_AHCI_P_TFD + offset)) &
 	(ATA_S_BUSY | ATA_S_DRQ)) {
 	    DELAY(1000);
 	    if (timeout++ > t) {
-		device_printf(dev, "port is not ready (timeout %dms)\n", t);
-		return (-1);
+		device_printf(dev, "port is not ready (timeout %dms) tfd = %08x\n", t, val);
+		return (EBUSY);
 	    }
     } 
     if (bootverbose)
@@ -642,6 +721,28 @@ ata_ahci_wait_ready(device_t dev, int t)
     return (0);
 }
 
+static int
+ata_ahci_hardreset(device_t dev, int port, uint32_t *signature)
+{
+    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+    struct ata_channel *ch = device_get_softc(dev);
+    int offset = ch->unit << 7;
+
+    *signature = 0xffffffff;
+    ata_ahci_stop(dev);
+    /* Reset port */
+    if (!ata_sata_phy_reset(dev, port, 0))
+	return (ENOENT);
+    /* Wait for clearing busy status. */
+    if (ata_ahci_wait_ready(dev, 10000)) {
+	device_printf(dev, "hardware reset timeout\n");
+	return (EBUSY);
+    }
+    *signature = ATA_INL(ctlr->r_res2, ATA_AHCI_P_SIG + offset);
+    ata_ahci_start(dev);
+    return (0);
+}
+
 static u_int32_t
 ata_ahci_softreset(device_t dev, int port)
 {
@@ -679,9 +780,9 @@ ata_ahci_softreset(device_t dev, int por
     ctp->cfis[1] = port & 0x0f;
     //ctp->cfis[7] = ATA_D_LBA | ATA_D_IBM;
     ctp->cfis[15] = ATA_A_4BIT;
-    ata_ahci_issue_cmd(dev, 0, 1000);
+    ata_ahci_issue_cmd(dev, 0, 3000);
 
-    if (ata_ahci_wait_ready(dev, 1000)) {
+    if (ata_ahci_wait_ready(dev, 0)) {
 	device_printf(dev, "software reset clear timeout\n");
 	return (-1);
     }
@@ -694,7 +795,6 @@ ata_ahci_reset(device_t dev)
 {
     struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
     struct ata_channel *ch = device_get_softc(dev);
-    u_int64_t work;
     u_int32_t signature;
     int offset = ch->unit << 7;
 
@@ -704,25 +804,7 @@ ata_ahci_reset(device_t dev)
     /* Disable port interrupts */
     ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_IE + offset, 0);
 
-    /* setup work areas */
-    work = ch->dma.work_bus + ATA_AHCI_CL_OFFSET;
-    ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CLB + offset, work & 0xffffffff);
-    ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CLBU + offset, work >> 32);
-
-    work = ch->dma.work_bus + ATA_AHCI_FB_OFFSET;
-    ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_FB + offset, work & 0xffffffff); 
-    ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_FBU + offset, work >> 32);
-
-    /* activate the channel and power/spin up device */
-    ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CMD + offset,
-	     (ATA_AHCI_P_CMD_ACTIVE | ATA_AHCI_P_CMD_POD | ATA_AHCI_P_CMD_SUD));
-
-    ata_ahci_stop(dev);
-
-    /* enable FIS based switching */
-    //ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_FBS + offset, 0x00000003);
-
-    if (!ata_sata_phy_reset(dev)) {
+    if (ata_ahci_hardreset(dev, -1, &signature)) {
 	if (bootverbose)
 	    device_printf(dev, "AHCI reset done: phy reset found no device\n");
 	ch->devices = 0;
@@ -733,8 +815,6 @@ ata_ahci_reset(device_t dev)
 	return;
     }
 
-    ata_ahci_start(dev);
-
     /* enable wanted port interrupts */
     ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_IE + offset,
 	     (ATA_AHCI_P_IX_CPD | ATA_AHCI_P_IX_TFE | ATA_AHCI_P_IX_HBF |
@@ -743,9 +823,6 @@ ata_ahci_reset(device_t dev)
 	      ATA_AHCI_P_IX_UF | ATA_AHCI_P_IX_SDB | ATA_AHCI_P_IX_DS |
 	      ATA_AHCI_P_IX_PS | ATA_AHCI_P_IX_DHR));
 
-    /* Wait for initial TFD from device. */
-    ata_ahci_wait_ready(dev, 10000);
-
     /* only probe for PortMultiplier if HW has support */
     if (ATA_INL(ctlr->r_res2, ATA_AHCI_CAP) & ATA_AHCI_CAP_SPM) {
 	signature = ata_ahci_softreset(dev, ATA_PM);

Modified: head/sys/dev/ata/chipsets/ata-intel.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-intel.c	Mon Mar 30 21:54:39 2009	(r190580)
+++ head/sys/dev/ata/chipsets/ata-intel.c	Mon Mar 30 22:18:38 2009	(r190581)
@@ -517,7 +517,7 @@ ata_intel_31244_tf_write(struct ata_requ
 static void
 ata_intel_31244_reset(device_t dev)
 {
-    if (ata_sata_phy_reset(dev))
+    if (ata_sata_phy_reset(dev, -1, 1))
 	ata_generic_reset(dev);
 }
 

Modified: head/sys/dev/ata/chipsets/ata-jmicron.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-jmicron.c	Mon Mar 30 21:54:39 2009	(r190580)
+++ head/sys/dev/ata/chipsets/ata-jmicron.c	Mon Mar 30 22:18:38 2009	(r190581)
@@ -55,6 +55,8 @@ __FBSDID("$FreeBSD$");
 static int ata_jmicron_chipinit(device_t dev);
 static int ata_jmicron_ch_attach(device_t dev);
 static int ata_jmicron_ch_detach(device_t dev);
+static int ata_jmicron_ch_suspend(device_t dev);
+static int ata_jmicron_ch_resume(device_t dev);
 static void ata_jmicron_reset(device_t dev);
 static void ata_jmicron_setmode(device_t dev, int mode);
 
@@ -127,6 +129,8 @@ ata_jmicron_chipinit(device_t dev)
 
 	ctlr->ch_attach = ata_jmicron_ch_attach;
 	ctlr->ch_detach = ata_jmicron_ch_detach;
+	ctlr->ch_suspend = ata_jmicron_ch_suspend;
+	ctlr->ch_resume = ata_jmicron_ch_resume;
 	ctlr->reset = ata_jmicron_reset;
 	ctlr->setmode = ata_jmicron_setmode;
 
@@ -173,6 +177,30 @@ ata_jmicron_ch_detach(device_t dev)
     return (error);
 }
 
+static int
+ata_jmicron_ch_suspend(device_t dev)
+{
+    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+    struct ata_channel *ch = device_get_softc(dev);
+    int error = 0;
+
+    if (ch->unit < ctlr->chip->cfg1)
+	error = ata_ahci_ch_suspend(dev);
+    return error;
+}
+
+static int
+ata_jmicron_ch_resume(device_t dev)
+{
+    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+    struct ata_channel *ch = device_get_softc(dev);
+    int error = 0;
+
+    if (ch->unit < ctlr->chip->cfg1)
+	error = ata_ahci_ch_resume(dev);
+    return (error);
+}
+
 static void
 ata_jmicron_reset(device_t dev)
 {

Modified: head/sys/dev/ata/chipsets/ata-marvell.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-marvell.c	Mon Mar 30 21:54:39 2009	(r190580)
+++ head/sys/dev/ata/chipsets/ata-marvell.c	Mon Mar 30 22:18:38 2009	(r190581)
@@ -503,7 +503,7 @@ ata_marvell_edma_reset(device_t dev)
     ATA_OUTL(ctlr->r_res1, 0x0200c + ATA_MV_EDMA_BASE(ch), ~0x0);
 
     /* enable channel and test for devices */
-    if (ata_sata_phy_reset(dev))
+    if (ata_sata_phy_reset(dev, -1, 1))
 	ata_generic_reset(dev);
 
     /* enable EDMA machinery */

Modified: head/sys/dev/ata/chipsets/ata-nvidia.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-nvidia.c	Mon Mar 30 21:54:39 2009	(r190580)
+++ head/sys/dev/ata/chipsets/ata-nvidia.c	Mon Mar 30 22:18:38 2009	(r190581)
@@ -249,7 +249,7 @@ ata_nvidia_status(device_t dev)
 static void
 ata_nvidia_reset(device_t dev)
 {
-    if (ata_sata_phy_reset(dev))
+    if (ata_sata_phy_reset(dev, -1, 1))
 	ata_generic_reset(dev);
 }
 

Modified: head/sys/dev/ata/chipsets/ata-promise.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-promise.c	Mon Mar 30 21:54:39 2009	(r190580)
+++ head/sys/dev/ata/chipsets/ata-promise.c	Mon Mar 30 22:18:38 2009	(r190581)
@@ -769,7 +769,7 @@ ata_promise_mio_reset(device_t dev)
 	if ((ctlr->chip->cfg2 == PR_SATA) ||
 	    ((ctlr->chip->cfg2 == PR_CMBO) && (ch->unit < 2))) {
 
-	    if (ata_sata_phy_reset(dev))
+	    if (ata_sata_phy_reset(dev, -1, 1))
 		ata_generic_reset(dev);
 
 	    /* reset and enable plug/unplug intr */
@@ -805,7 +805,7 @@ ata_promise_mio_reset(device_t dev)
 		     (ATA_INL(ctlr->r_res2, 0x414 + (ch->unit << 8)) &
 		     ~0x00000003) | 0x00000001);
 
-	    if (ata_sata_phy_reset(dev)) {
+	    if (ata_sata_phy_reset(dev, -1, 1)) {
 		u_int32_t signature = ch->hw.softreset(dev, ATA_PM);
 
 		if (1 | bootverbose)

Modified: head/sys/dev/ata/chipsets/ata-siliconimage.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-siliconimage.c	Mon Mar 30 21:54:39 2009	(r190580)
+++ head/sys/dev/ata/chipsets/ata-siliconimage.c	Mon Mar 30 22:18:38 2009	(r190581)
@@ -380,7 +380,7 @@ ata_sii_status(device_t dev)
 static void
 ata_sii_reset(device_t dev)
 {
-    if (ata_sata_phy_reset(dev))
+    if (ata_sata_phy_reset(dev, -1, 1))
 	ata_generic_reset(dev);
 }
 
@@ -832,7 +832,7 @@ ata_siiprb_reset(device_t dev)
     }
 
     /* reset phy */
-    if (!ata_sata_phy_reset(dev)) {
+    if (!ata_sata_phy_reset(dev, -1, 1)) {
 	if (bootverbose)
 	    device_printf(dev, "phy reset found no device\n");
 	ch->devices = 0;

Modified: head/sys/dev/ata/chipsets/ata-sis.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-sis.c	Mon Mar 30 21:54:39 2009	(r190580)
+++ head/sys/dev/ata/chipsets/ata-sis.c	Mon Mar 30 22:18:38 2009	(r190581)
@@ -226,7 +226,7 @@ ata_sis_ch_attach(device_t dev)
 static void
 ata_sis_reset(device_t dev)
 {
-    if (ata_sata_phy_reset(dev))
+    if (ata_sata_phy_reset(dev, -1, 1))
 	ata_generic_reset(dev);
 }
 

Modified: head/sys/dev/ata/chipsets/ata-via.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-via.c	Mon Mar 30 21:54:39 2009	(r190580)
+++ head/sys/dev/ata/chipsets/ata-via.c	Mon Mar 30 22:18:38 2009	(r190581)
@@ -269,7 +269,7 @@ ata_via_reset(device_t dev)
     if ((ctlr->chip->cfg2 & VIABAR) && (ch->unit > 1))
         ata_generic_reset(dev);
     else
-	if (ata_sata_phy_reset(dev))
+	if (ata_sata_phy_reset(dev, -1, 1))
 	    ata_generic_reset(dev);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200903302218.n2UMIc6t080193>