20 May, 2008

3 commits

  • PMP notification during reset can make some controllers fail reset
    processing and needs to be turned off during resets. PMP attach and
    full-revalidation path did this via sata_pmp_configure() but the quick
    revalidation wasn't. Move the notification disable code right above
    fan-out port recovery so that it's always turned off.

    This fixes obscure reset failures.

    Signed-off-by: Tejun Heo
    Signed-off-by: Jeff Garzik

    Tejun Heo
     
  • This timeout was set low because previously PMP register access was
    done via polling and register access timeouts could stack up. This is
    no longer the case. One timeout will make all following accesses fail
    immediately.

    In rare cases both marvell and SIMG PMPs need almost a second. Bump
    it to 3s.

    While at it, rename it to SATA_PMP_RW_TIMEOUT. It's not specific to
    SCR access.

    Signed-off-by: Tejun Heo
    Signed-off-by: Jeff Garzik

    Tejun Heo
     
  • Previously reset freeze/thaw handling lived outside of ata_eh_reset()
    mainly because the original PMP reset code needed the port frozen
    while resetting all the fan-out ports, which is no longer the case.

    This patch moves freeze/thaw handling into ata_eh_reset().
    @prereset() and @postreset() are now called w/o freezing the port
    although @prereset() an be called frozen if the port is frozen prior
    to entering ata_eh_reset().

    This makes code simpler and will help removing hotplug event related
    races.

    Signed-off-by: Tejun Heo
    Signed-off-by: Jeff Garzik

    Tejun Heo
     

18 Apr, 2008

10 commits

  • Implement helpers to test whether PMP is supported, attached and
    determine pmp number to use when issuing SRST to a link. While at it,
    move ata_is_host_link() so that it's together with the two new PMP
    helpers.

    This change simplifies LLDs and helps making PMP support optional.

    Signed-off-by: Tejun Heo

    Tejun Heo
     
  • Most of PMP support code is already in libata-pmp.c. All that are in
    libata-core.c are sata_pmp_port_ops and EXPORTs. Move them to
    libata-pmp.c. Also, collect PMP related prototypes and declarations
    in header files and move them right above of SFF stuff.

    This change is to make PMP support optional.

    Signed-off-by: Tejun Heo

    Tejun Heo
     
  • If PMP fan-out reset fails and SCR isn't accessible, PMP should be
    reset. This used to be tested by sata_pmp_std_hardreset() and
    communicated to EH by -ERESTART. However, this logic is generic and
    doesn't really have much to do with specific hardreset implementation.

    This patch moves SCR access failure detection logic to ata_eh_reset()
    where it belongs. As this makes sata_pmp_std_hardreset() identical to
    sata_std_hardreset(), the function is killed and replaced with the
    standard method.

    Signed-off-by: Tejun Heo

    Tejun Heo
     
  • SError used to be cleared in ->postreset. This has small hotplug race
    condition. If a device is plugged in after reset is complete but
    postreset hasn't run yet, its hotplug event gets lost when SError is
    cleared. This patch makes sata_link_resume() clear SError. This
    kills the race condition and makes a lot of sense as some PMP and host
    PHYs don't work properly without SError cleared.

    This change makes sata_pmp_std_{pre|post}_reset()'s unnecessary as
    they become identical to ata_std counterparts. It also simplifies
    sata_pmp_hardreset() and ahci_vt8251_hardreset().

    Signed-off-by: Tejun Heo

    Tejun Heo
     
  • sata_sff_hardreset() contains link readiness wait logic which isn't
    SFF specific. Move that part into sata_link_hardreset(), which now
    takes two more parameters - @online and @check_ready. Both are
    optional. The former is out parameter for link onlineness after
    reset. The latter is used to wait for link readiness after hardreset.

    Users of sata_link_hardreset() is updated to use new funtionality and
    ahci_hardreset() is updated to use sata_link_hardreset() instead of
    sata_sff_hardreset(). This doesn't really cause any behavior change.

    Signed-off-by: Tejun Heo

    Tejun Heo
     
  • Currently reset methods are not specified directly in the
    ata_port_operations table. If a LLD wants to use custom reset
    methods, it should construct and use a error_handler which uses those
    reset methods. It's done this way for two reasons.

    First, the ops table already contained too many methods and adding
    four more of them would noticeably increase the amount of necessary
    boilerplate code all over low level drivers.

    Second, as ->error_handler uses those reset methods, it can get
    confusing. ie. By overriding ->error_handler, those reset ops can be
    made useless making layering a bit hazy.

    Now that ops table uses inheritance, the first problem doesn't exist
    anymore. The second isn't completely solved but is relieved by
    providing default values - most drivers can just override what it has
    implemented and don't have to concern itself about higher level
    callbacks. In fact, there currently is no driver which actually
    modifies error handling behavior. Drivers which override
    ->error_handler just wraps the standard error handler only to prepare
    the controller for EH. I don't think making ops layering strict has
    any noticeable benefit.

    This patch makes ->prereset, ->softreset, ->hardreset, ->postreset and
    their PMP counterparts propoer ops. Default ops are provided in the
    base ops tables and drivers are converted to override individual reset
    methods instead of creating custom error_handler.

    * ata_std_error_handler() doesn't use sata_std_hardreset() if SCRs
    aren't accessible. sata_promise doesn't need to use separate
    error_handlers for PATA and SATA anymore.

    * softreset is broken for sata_inic162x and sata_sx4. As libata now
    always prefers hardreset, this doesn't really matter but the ops are
    forced to NULL using ATA_OP_NULL for documentation purpose.

    * pata_hpt374 needs to use different prereset for the first and second
    PCI functions. This used to be done by branching from
    hpt374_error_handler(). The proper way to do this is to use
    separate ops and port_info tables for each function. Converted.

    Signed-off-by: Tejun Heo

    Tejun Heo
     
  • ata_ehi_schedule_probe() was created to hide details of link-resuming
    reset magic. Now that all the softreset workarounds are gone,
    scheduling probe is very simple - set probe_mask and request RESET.
    Kill ata_ehi_schedule_probe() and open code it. This also increases
    consistency as ata_ehi_schedule_probe() couldn't cover individual
    device probings so they were open-coded even when the helper existed.

    While at it, define ATA_ALL_DEVICES as mask of all possible devices on
    a link and always use it when requesting probe on link level for
    simplicity and consistency. Setting extra bits in the probe_mask
    doesn't hurt anybody.

    Signed-off-by: Tejun Heo

    Tejun Heo
     
  • ATA_EHI_RESUME_LINK has two functions - promote reset to hardreset if
    ATA_LFLAG_HRST_TO_RESUME is set and preventing EH from shortcutting
    reset action when probing is requested. The former is gone now and
    the latter can easily be achieved by making EH to perform at least one
    reset if reset is requested, which also makes more sense than
    depending on RESUME_LINK flag.

    As ATA_EHI_RESUME_LINK was the only EHI reset modifier, this also
    kills reset modifier handling.

    Signed-off-by: Tejun Heo

    Tejun Heo
     
  • Now that hardreset is the preferred method of resetting, there's no
    need for ATA_LFLAG_HRST_TO_RESUME flag. Kill it.

    Signed-off-by: Tejun Heo

    Tejun Heo
     
  • When both soft and hard resets are available, libata preferred
    softreset till now. The logic behind it was to be softer to devices;
    however, this doesn't really help much. Rationales for the change:

    * BIOS may freeze lock certain things during boot and softreset can't
    unlock those. This by itself is okay but during operation PHY event
    or other error conditions can trigger hardreset and the device may
    end up with different configuration.

    For example, after a hardreset, previously unlockable HPA can be
    unlocked resulting in different device size and thus revalidation
    failure. Similar condition can occur during or after resume.

    * Certain ATAPI devices require hardreset to recover after certain
    error conditions. On PATA, this is done by issuing the DEVICE RESET
    command. On SATA, COMRESET has equivalent effect. The problem is
    that DEVICE RESET needs its own execution protocol.

    For SFF controllers with bare TF access, it can be easily
    implemented but more advanced controllers (e.g. ahci and sata_sil24)
    require specialized implementations. Simply using hardreset solves
    the problem nicely.

    * COMRESET initialization sequence is the norm in SATA land and many
    SATA devices don't work properly if only SRST is used. For example,
    some PMPs behave this way and libata works around by always issuing
    hardreset if the host supports PMP.

    Like the above example, libata has developed a number of mechanisms
    aiming to promote softreset to hardreset if softreset is not going
    to work. This approach is time consuming and error prone.

    Also, note that, dependingon how you read the specs, it could be
    argued that PMP fan-out ports require COMRESET to start operation.
    In fact, all the PMPs on the market except one don't work properly
    if COMRESET is not issued to fan-out ports after PMP reset.

    * COMRESET is an integral part of SATA connection and any working
    device should be able to handle COMRESET properly. After all, it's
    the way to signal hardreset during reboot. This is the most used
    and recommended (at least by the ahci spec) method of resetting
    devices.

    So, this patch makes libata prefer hardreset over softreset by making
    the following changes.

    * Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever
    ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is
    now only used to tell prereset whether soft or hard reset will be
    issued.

    * Strip out now unneeded promote-to-hardreset logics from
    ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and
    other places.

    Signed-off-by: Tejun Heo

    Tejun Heo
     

24 Feb, 2008

1 commit

  • >> Mark Lord wrote:
    >>> Tejun, I've added PMP to sata_mv, and am now trying to get it
    >>> to work with a Marvell PM attached.
    >>>
    >>> And the behaviour I see is very bizarre.
    >>>
    >>> After hard+soft resets, the PM signature is found,
    >>> and libata interrogates the PM registers.
    >>>
    >>> It successfully reads register 0, and then register 1.
    >>> But all subsequent registers read out (incorrectly) as zeros.
    ...

    This behavior has been confirmed by Marvell with a SATA analyzer.
    The Marvell port-multiplier apparently likes to see clean HOB
    information when accessing PMP registers.

    Since sata_mv uses PIO shadow register access, this doesn't happen
    automatically, as it might in a more purely FIS-based driver (eg. ahci).

    One way to fix this is to flag these commands with ATA_TFLAG_LBA48,
    forcing libata to write out the HOB fields with known (zero) values.

    Signed-off-by: Saeed Bishara
    Acked-by: Mark Lord
    Signed-off-by: Jeff Garzik

    Mark Lord
     

11 Jan, 2008

1 commit


13 Oct, 2007

4 commits

  • PMP registers used to be accessed with dedicated accessors ->pmp_read
    and ->pmp_write. During reset, those callbacks are called with the
    port frozen so they should be able to run without depending on
    interrupt delivery. To achieve this, they were implemented polling.

    However, as resetting the host port makes the PMP to isolate fan-out
    ports until SError.X is cleared, resetting fan-out ports while port is
    frozen doesn't buy much additional safety.

    This patch updates libata PMP support such that PMP registers are
    accessed using regular ata_exec_internal() mechanism and kills
    ->pmp_read/write() callbacks. The following changes are made.

    * PMP access helpers - sata_pmp_read_init_tf(), sata_pmp_read_val(),
    sata_pmp_write_init_tf() are folded into sata_pmp_read/write() which
    are now standalone PMP register access functions.

    * sata_pmp_read/write() returns err_mask instead of rc. This is
    consistent with other functions which issue internal commands and
    allows more detailed error reporting.

    * ahci interrupt handler is modified to ignore BAD_PMP and
    spurious/illegal completion IRQs while reset is in progress. These
    conditions are expected during reset.

    Signed-off-by: Tejun Heo
    Signed-off-by: Jeff Garzik

    Tejun Heo
     
  • Implement sata_pmp_qc_defer_cmd_switch() - standard qc_defer for
    command switching PMP support.

    Signed-off-by: Tejun Heo
    Signed-off-by: Jeff Garzik

    Tejun Heo
     
  • Extend ata_acpi_associate_sata_port() such that it can handle PMP and
    call it when PMP is attached and detached.

    Build breakage when !CONFIG_ATA_ACPI was spotted and fixed by Petr
    Vandrovec.

    Signed-off-by: Tejun Heo
    Cc: Petr Vandrovec
    Signed-off-by: Jeff Garzik

    Tejun Heo
     
  • Implement Port Multiplier support. To support PMP, a LLDD has to
    supply ops->pmp_read() and pmp_write(). If non-null, ->pmp_attach and
    ->pmp_detach are called on PMP attach and detach, respectively.

    ->pmp_read/write() can be called while the port is frozen, so they
    must be implemented by polling. This patch supplies several helpers
    to ease ->pmp_read/write() implementation.

    Also, irq_handler and error_handler must be PMP aware. Most of PMP
    aware EH can be done by calling ata_pmp_do_eh() with appropriate
    methods. PMP EH uses separate set of reset methods and this patch
    implements standard prereset, hardreset and postreset methods.

    This patch only implements PMP support. The next patch will integrate
    PMP into the reset of libata and thus enable PMP support.

    Signed-off-by: Tejun Heo
    Signed-off-by: Jeff Garzik

    Tejun Heo