Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[libata] sata_mv: Add a new mv_sff_check_status() function to sata_mv. This is necessary for use with the upcoming "mv_qc_issue_fis()" patch, but is being added separately here for easier code review.

When using command issue via the "mv_qc_issue_fis()" mechanism,
the initial ATA_BUSY bit does not show in the ATA status (shadow) register.
This can confuse libata! So here we add a hook to fake ATA_BUSY
for that situation, until the first time a BUSY, DRQ, or ERR bit is seen.

Signed-off-by: Mark Lord <mlord@pobox.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>

authored by

Mark Lord and committed by
Jeff Garzik
d16ab3f6 42ed893d

+36 -1
+36 -1
drivers/ata/sata_mv.c
··· 370 370 MV_PP_FLAG_NCQ_EN = (1 << 1), /* is EDMA set up for NCQ? */ 371 371 MV_PP_FLAG_FBS_EN = (1 << 2), /* is EDMA set up for FBS? */ 372 372 MV_PP_FLAG_DELAYED_EH = (1 << 3), /* delayed dev err handling */ 373 + MV_PP_FLAG_FAKE_ATA_BUSY = (1 << 4), /* ignore initial ATA_DRDY */ 373 374 }; 374 375 375 376 #define IS_GEN_I(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_I) ··· 571 570 static void mv_bmdma_start(struct ata_queued_cmd *qc); 572 571 static void mv_bmdma_stop(struct ata_queued_cmd *qc); 573 572 static u8 mv_bmdma_status(struct ata_port *ap); 573 + static u8 mv_sff_check_status(struct ata_port *ap); 574 574 575 575 /* .sg_tablesize is (MV_MAX_SG_CT / 2) in the structures below 576 576 * because we have to allow room for worst case splitting of ··· 621 619 .softreset = mv_softreset, 622 620 .error_handler = mv_pmp_error_handler, 623 621 622 + .sff_check_status = mv_sff_check_status, 624 623 .sff_irq_clear = mv_sff_irq_clear, 625 624 .check_atapi_dma = mv_check_atapi_dma, 626 625 .bmdma_setup = mv_bmdma_setup, ··· 1287 1284 1288 1285 /* set up non-NCQ EDMA configuration */ 1289 1286 cfg = EDMA_CFG_Q_DEPTH; /* always 0x1f for *all* chips */ 1290 - pp->pp_flags &= ~(MV_PP_FLAG_FBS_EN | MV_PP_FLAG_NCQ_EN); 1287 + pp->pp_flags &= 1288 + ~(MV_PP_FLAG_FBS_EN | MV_PP_FLAG_NCQ_EN | MV_PP_FLAG_FAKE_ATA_BUSY); 1291 1289 1292 1290 if (IS_GEN_I(hpriv)) 1293 1291 cfg |= (1 << 8); /* enab config burst size mask */ ··· 1795 1791 } 1796 1792 1797 1793 /** 1794 + * mv_sff_check_status - fetch device status, if valid 1795 + * @ap: ATA port to fetch status from 1796 + * 1797 + * When using command issue via mv_qc_issue_fis(), 1798 + * the initial ATA_BUSY state does not show up in the 1799 + * ATA status (shadow) register. This can confuse libata! 1800 + * 1801 + * So we have a hook here to fake ATA_BUSY for that situation, 1802 + * until the first time a BUSY, DRQ, or ERR bit is seen. 1803 + * 1804 + * The rest of the time, it simply returns the ATA status register. 1805 + */ 1806 + static u8 mv_sff_check_status(struct ata_port *ap) 1807 + { 1808 + u8 stat = ioread8(ap->ioaddr.status_addr); 1809 + struct mv_port_priv *pp = ap->private_data; 1810 + 1811 + if (pp->pp_flags & MV_PP_FLAG_FAKE_ATA_BUSY) { 1812 + if (stat & (ATA_BUSY | ATA_DRQ | ATA_ERR)) 1813 + pp->pp_flags &= ~MV_PP_FLAG_FAKE_ATA_BUSY; 1814 + else 1815 + stat = ATA_BUSY; 1816 + } 1817 + return stat; 1818 + } 1819 + 1820 + /** 1798 1821 * mv_qc_issue - Initiate a command to the host 1799 1822 * @qc: queued command to start 1800 1823 * ··· 1841 1810 struct mv_port_priv *pp = ap->private_data; 1842 1811 u32 in_index; 1843 1812 unsigned int port_irqs; 1813 + 1814 + pp->pp_flags &= ~MV_PP_FLAG_FAKE_ATA_BUSY; /* paranoia */ 1844 1815 1845 1816 switch (qc->tf.protocol) { 1846 1817 case ATA_PROT_DMA: ··· 3071 3038 3072 3039 mv_reset_channel(hpriv, mmio, ap->port_no); 3073 3040 pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; 3041 + pp->pp_flags &= 3042 + ~(MV_PP_FLAG_FBS_EN | MV_PP_FLAG_NCQ_EN | MV_PP_FLAG_FAKE_ATA_BUSY); 3074 3043 3075 3044 /* Workaround for errata FEr SATA#10 (part 2) */ 3076 3045 do {