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...
Roman Divacky
rdivacky at FreeBSD.org
Tue Mar 31 00:20:44 PDT 2009
are you sure about the merge info?
On Mon, Mar 30, 2009 at 10:18:38PM +0000, Alexander Motin wrote:
> 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);
> }
>
More information about the svn-src-all
mailing list