Re: libata and software reset

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

 



On 10/19/22 18:32, John Garry wrote:
> On 18/10/2022 16:04, Niklas Cassel wrote:
>>> Hi guys,
>>>
>>> In the hisi_sas driver there are times in which we need to issue an ATA
>>> software reset. For this we use hisi_sas_softreset_ata_disk() ->
>>> sas_execute_ata_cmd() -> sas_execute_tmf(), which uses libsas "slow
>>> task"
>>> mechanism to issue the command.
>>>
>>> I would like if libata provided such a function to issue a software
>>> reset,
>>> such that we can send the command as an ATA queued command.
>>>
>>> The problem is that often when we would want to issue this software
>>> reset
>>> the associated ata port is frozen, like in ATA EH, and so we cannot
>>> issue
>>> ATA queued commands - internal or normal - at that time.
>>>
>>> Is there any way to solve this? Or I am just misunderstanding how and
>>> when
>>> ATA queued commands can and should be used?
>>>
>> Hello John,
> 
> Hi Niklas,
> 
>>
>> See the kdoc above __ata_port_freeze():
>> "This function is called when HSM violation or some other
>> condition disrupts normal operation of the port.  Frozen port
>> is not allowed to perform any operation until the port is
>> thawed, which usually follows a successful reset.
> 
> ok, I see.
> 
>>
>> ap->ops->freeze() callback can be used for freezing the port
>> hardware-wise (e.g. mask interrupt and stop DMA engine).  If a
>> port cannot be frozen hardware-wise, the interrupt handler
>> must ack and clear interrupts unconditionally while the port
>> is frozen."
>>
>>
>> ata_port_operations.qc_issue() is obviously an operation on the port,
>> so it makes sense that it is not allowed.
> 
> hmmm..ok, then.
> 
> 
>> Interrupts are also usually masked or disabled at this time, so we
>> won't get an IRQ with the completion.
> 
> Doesn't this policy really just depend on the host controller driver?
> 
>>
>> Perhaps one could argue that there could be an API to execute a polled
>> command. But if the port is in a bad state,
>  e.g. a HSM error (RDY bit
>> is not set), issuing a command would likely fail anyway, regardless if
>> using polling or IRQs.
>>
>>
>>> I assume that ata_port_operations.softreset callback requires a
>>> method to be
>>> able to issue the softreset directly from the driver, like
>>> ahci_softreset()
>>> -> ahci_do_softreset() -> ahci_exec_polled_cmd().
>> Yes, looking .softreset in a few ata drivers, they all seem issue the
>> softreset directly from the driver.
>> (e.g. ahci_do_softreset() calls ahci_exec_polled_cmd() which just always
>> uses bit 0 in PORT_CMD_ISSUE, so it ignores hw_tag.)
>>
>> But I don't think that I fully understand your problem.
>>
>> hisi_sas_softreset_ata_disk() -> sas_execute_ata_cmd() ->
>> sas_execute_tmf()
>> calls lldd_execute_task() (hisi_sas_queue_command()) and then calls
>> waits for completion.
>>
>> How is this different from e.g. the libahci case?
> 
> The difference really comes down to the controller programming interface.
> 
> For ahci we have a MMIO interface to issue the software reset command.
> 
> For my SAS controller of interest, there is no such MMIO interface. To
> issue the reset we build a h2d fis with a SRST set, and send on the
> controller ring buffer like any other IO.
> 
> As I mentioned, we can set the SRST for the h2d fis on the HW interface
> without issue, and it works fine. The problem for me is that the command
> comes via libsas/driver, and I would like it to come from libata such
> that it has a ATA queued command associated. But then we have the
> problem that the port is frozen at such times that we want to issue this
> command.

Yeah, qc is too high level for this to work. But we could probably do
something generic at TF or FIS level. libata-sata.c has already some
code in that area, something for a "reset TF/FIS" would fit in that file
too. libahci could also use that too.

> 
>> Doesn't this end up being the same as resetting the port directly from
>> the
>> driver? (if we ignore all the callbacks)
>> Or do you actually get stuck on a ata_port_is_frozen() check somewhere?
> 
> 
> Thanks,
> John

-- 
Damien Le Moal
Western Digital Research





[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux