The definition of ahci_start_fis_rx() and ahci_stop_fis_rx()
PATCH 2/6 The definition of ahci_start_fis_rx() and ahci_stop_fis_rx()
Put the "start/stop FIS RX" operation into ahci_start_fis_rx() and
ahci_stop_fis_rx().
Signed-off-by Forrest Zhao <[email protected]>
Signed-off-by Hannes Reinecke <[email protected]>
Signed-off-by Jens Axboe <[email protected]>
---
drivers/scsi/ahci.c | 75 ++++++++++++++++++++++++++++++++++++++++++++ +++++++ 1 files changed, 75 insertions(+), 0 deletions(-)
a94f89e6d8fecdbc0b196a69c0c966df9eb5c648
drivers/scsi/ahci.c +75 -0
@@ -207,6 +207,10 @@ static int ahci_port_start(struct ata_postatic void ahci_port_stop (struct ata_port *ap);static int ahci_start_engine (void __iomem *port_mmio);static int ahci_stop_engine (void __iomem *port_mmio); +static void ahci_start_fis_rx (void __iomem *port_mmio, +struct ahci_port_priv *pp, +struct ahci_host_priv *hpriv); +static int ahci_stop_fis_rx (void __iomem *port_mmio);static void ahci_tf_read (struct ata_port *ap,struct ata_taskfile *tf);static void ahci_qc_prep (struct ata_queued_cmd *qc);static u8 ahci_check_status (struct ata_port *ap);
@@ -570,6 +574,77 @@ static int ahci_start_engine(void __iomereturn 0 ; } +static int ahci_stop_fis_rx (void __iomem *port_mmio) +{ +u32 tmp; + +/* +* Get current status +*/ + tmp =readl (port_mmio +PORT_CMD ); + +/* Check if FIS RX is already disabled */ +if ((tmp &PORT_CMD_FIS_RX ) ==0 ) +return 0 ; + +/* +* AHCI Rev 1.1 section 10.3.2 +* Software shall not clear PxCMD.FRE while +* PxCMD.ST or PxCMD.CR is set to '1' +*/ +if (tmp & (PORT_CMD_LIST_ON |PORT_CMD_START )) { +return -EPERM ; + } + +/* +* Disable FIS reception +* +* AHCI Rev 1.1 Section 10.1.2: +* If PxCMD.FRE is set to '1', software should clear it +* to '0' and wait at least 500 milliseconds for PxCMD.FR +* to return '0' when read. If PxCMD.FR does not clear +* '0' correctly, then software may attempt a port reset +* of a full HBA reset to recover. +*/ + tmp &= ~(PORT_CMD_FIS_RX ); +writel (tmp, port_mmio +PORT_CMD ); + + tmp =ata_wait_register (port_mmio +PORT_CMD ,PORT_CMD_FIS_ON , +PORT_CMD_FIS_ON ,1 ,1000 ); +if (tmp &PORT_CMD_FIS_ON ) +return -EBUSY ; + +return 0 ; +} + +static void ahci_start_fis_rx (void __iomem *port_mmio, +struct ahci_port_priv *pp, +struct ahci_host_priv *hpriv) +{ +u32 tmp; + +/* +* Set FIS registers +*/ +if (hpriv->cap &HOST_CAP_64 ) +writel ((pp->cmd_slot_dma >>16 ) >>16 , port_mmio +PORT_LST_ADDR_HI ); +writel (pp->cmd_slot_dma &0xffffffff , port_mmio +PORT_LST_ADDR ); +readl (port_mmio +PORT_LST_ADDR );/* flush */ + +if (hpriv->cap &HOST_CAP_64 ) +writel ((pp->rx_fis_dma >>16 ) >>16 , port_mmio +PORT_FIS_ADDR_HI ); +writel (pp->rx_fis_dma &0xffffffff , port_mmio +PORT_FIS_ADDR ); +readl (port_mmio +PORT_FIS_ADDR );/* flush */ + +/* +* Enable FIS reception +*/ + tmp =readl (port_mmio +PORT_CMD ); + tmp |=PORT_CMD_FIS_RX ; +writel (tmp, port_mmio +PORT_CMD ); +readl (port_mmio +PORT_CMD );/* flush */ +} +static unsigned int ahci_dev_classify (struct ata_port *ap) {void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
Signature · 1 line
1.2.6