Loading drivers/ata/sata_mv.c +186 −4 Original line number Diff line number Diff line Loading @@ -31,8 +31,6 @@ * * --> Complete a full errata audit for all chipsets to identify others. * * --> ATAPI support (Marvell claims the 60xx/70xx chips can do it). * * --> Develop a low-power-consumption strategy, and implement it. * * --> [Experiment, low priority] Investigate interrupt coalescing. Loading Loading @@ -68,7 +66,7 @@ #include <linux/libata.h> #define DRV_NAME "sata_mv" #define DRV_VERSION "1.25" #define DRV_VERSION "1.26" enum { /* BAR's are enumerated in terms of pci_resource_start() terms */ Loading Loading @@ -126,7 +124,7 @@ enum { MV_GEN_II_FLAGS = MV_COMMON_FLAGS | MV_FLAG_IRQ_COALESCE | ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA | ATA_FLAG_NCQ | ATA_FLAG_NO_ATAPI, ATA_FLAG_NCQ, MV_GEN_IIE_FLAGS = MV_GEN_II_FLAGS | ATA_FLAG_AN, Loading Loading @@ -348,6 +346,12 @@ enum { EDMA_HALTCOND_OFS = 0x60, /* GenIIe halt conditions */ BMDMA_CMD_OFS = 0x224, /* bmdma command register */ BMDMA_STATUS_OFS = 0x228, /* bmdma status register */ BMDMA_PRD_LOW_OFS = 0x22c, /* bmdma PRD addr 31:0 */ BMDMA_PRD_HIGH_OFS = 0x230, /* bmdma PRD addr 63:32 */ /* Host private flags (hp_flags) */ MV_HP_FLAG_MSI = (1 << 0), MV_HP_ERRATA_50XXB0 = (1 << 1), Loading Loading @@ -547,6 +551,15 @@ static void mv_pmp_error_handler(struct ata_port *ap); static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp); static unsigned long mv_mode_filter(struct ata_device *dev, unsigned long xfer_mask); static void mv_sff_irq_clear(struct ata_port *ap); static int mv_check_atapi_dma(struct ata_queued_cmd *qc); static void mv_bmdma_setup(struct ata_queued_cmd *qc); static void mv_bmdma_start(struct ata_queued_cmd *qc); static void mv_bmdma_stop(struct ata_queued_cmd *qc); static u8 mv_bmdma_status(struct ata_port *ap); /* .sg_tablesize is (MV_MAX_SG_CT / 2) in the structures below * because we have to allow room for worst case splitting of * PRDs for 64K boundaries in mv_fill_sg(). Loading Loading @@ -594,6 +607,14 @@ static struct ata_port_operations mv6_ops = { .pmp_softreset = mv_softreset, .softreset = mv_softreset, .error_handler = mv_pmp_error_handler, .sff_irq_clear = mv_sff_irq_clear, .check_atapi_dma = mv_check_atapi_dma, .bmdma_setup = mv_bmdma_setup, .bmdma_start = mv_bmdma_start, .bmdma_stop = mv_bmdma_stop, .bmdma_status = mv_bmdma_status, .mode_filter = mv_mode_filter, }; static struct ata_port_operations mv_iie_ops = { Loading Loading @@ -1392,6 +1413,167 @@ static void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last) *cmdw = cpu_to_le16(tmp); } /** * mv_mode_filter - Allow ATAPI DMA only on GenII chips. * @dev: device whose xfer modes are being configured. * * Only the GenII hardware can use DMA with ATAPI drives. */ static unsigned long mv_mode_filter(struct ata_device *adev, unsigned long xfer_mask) { if (adev->class == ATA_DEV_ATAPI) { struct mv_host_priv *hpriv = adev->link->ap->host->private_data; if (!IS_GEN_II(hpriv)) { xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); ata_dev_printk(adev, KERN_INFO, "ATAPI DMA not supported on this chipset\n"); } } return xfer_mask; } /** * mv_sff_irq_clear - Clear hardware interrupt after DMA. * @ap: Port associated with this ATA transaction. * * We need this only for ATAPI bmdma transactions, * as otherwise we experience spurious interrupts * after libata-sff handles the bmdma interrupts. */ static void mv_sff_irq_clear(struct ata_port *ap) { mv_clear_and_enable_port_irqs(ap, mv_ap_base(ap), ERR_IRQ); } /** * mv_check_atapi_dma - Filter ATAPI cmds which are unsuitable for DMA. * @qc: queued command to check for chipset/DMA compatibility. * * The bmdma engines cannot handle speculative data sizes * (bytecount under/over flow). So only allow DMA for * data transfer commands with known data sizes. * * LOCKING: * Inherited from caller. */ static int mv_check_atapi_dma(struct ata_queued_cmd *qc) { struct scsi_cmnd *scmd = qc->scsicmd; if (scmd) { switch (scmd->cmnd[0]) { case READ_6: case READ_10: case READ_12: case WRITE_6: case WRITE_10: case WRITE_12: case GPCMD_READ_CD: case GPCMD_SEND_DVD_STRUCTURE: case GPCMD_SEND_CUE_SHEET: return 0; /* DMA is safe */ } } return -EOPNOTSUPP; /* use PIO instead */ } /** * mv_bmdma_setup - Set up BMDMA transaction * @qc: queued command to prepare DMA for. * * LOCKING: * Inherited from caller. */ static void mv_bmdma_setup(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; void __iomem *port_mmio = mv_ap_base(ap); struct mv_port_priv *pp = ap->private_data; mv_fill_sg(qc); /* clear all DMA cmd bits */ writel(0, port_mmio + BMDMA_CMD_OFS); /* load PRD table addr. */ writel((pp->sg_tbl_dma[qc->tag] >> 16) >> 16, port_mmio + BMDMA_PRD_HIGH_OFS); writelfl(pp->sg_tbl_dma[qc->tag], port_mmio + BMDMA_PRD_LOW_OFS); /* issue r/w command */ ap->ops->sff_exec_command(ap, &qc->tf); } /** * mv_bmdma_start - Start a BMDMA transaction * @qc: queued command to start DMA on. * * LOCKING: * Inherited from caller. */ static void mv_bmdma_start(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; void __iomem *port_mmio = mv_ap_base(ap); unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE); u32 cmd = (rw ? 0 : ATA_DMA_WR) | ATA_DMA_START; /* start host DMA transaction */ writelfl(cmd, port_mmio + BMDMA_CMD_OFS); } /** * mv_bmdma_stop - Stop BMDMA transfer * @qc: queued command to stop DMA on. * * Clears the ATA_DMA_START flag in the bmdma control register * * LOCKING: * Inherited from caller. */ static void mv_bmdma_stop(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; void __iomem *port_mmio = mv_ap_base(ap); u32 cmd; /* clear start/stop bit */ cmd = readl(port_mmio + BMDMA_CMD_OFS); cmd &= ~ATA_DMA_START; writelfl(cmd, port_mmio + BMDMA_CMD_OFS); /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ ata_sff_dma_pause(ap); } /** * mv_bmdma_status - Read BMDMA status * @ap: port for which to retrieve DMA status. * * Read and return equivalent of the sff BMDMA status register. * * LOCKING: * Inherited from caller. */ static u8 mv_bmdma_status(struct ata_port *ap) { void __iomem *port_mmio = mv_ap_base(ap); u32 reg, status; /* * Other bits are valid only if ATA_DMA_ACTIVE==0, * and the ATA_DMA_INTR bit doesn't exist. */ reg = readl(port_mmio + BMDMA_STATUS_OFS); if (reg & ATA_DMA_ACTIVE) status = ATA_DMA_ACTIVE; else status = (reg & ATA_DMA_ERR) | ATA_DMA_INTR; return status; } /** * mv_qc_prep - Host specific command preparation. * @qc: queued command to prepare Loading Loading
drivers/ata/sata_mv.c +186 −4 Original line number Diff line number Diff line Loading @@ -31,8 +31,6 @@ * * --> Complete a full errata audit for all chipsets to identify others. * * --> ATAPI support (Marvell claims the 60xx/70xx chips can do it). * * --> Develop a low-power-consumption strategy, and implement it. * * --> [Experiment, low priority] Investigate interrupt coalescing. Loading Loading @@ -68,7 +66,7 @@ #include <linux/libata.h> #define DRV_NAME "sata_mv" #define DRV_VERSION "1.25" #define DRV_VERSION "1.26" enum { /* BAR's are enumerated in terms of pci_resource_start() terms */ Loading Loading @@ -126,7 +124,7 @@ enum { MV_GEN_II_FLAGS = MV_COMMON_FLAGS | MV_FLAG_IRQ_COALESCE | ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA | ATA_FLAG_NCQ | ATA_FLAG_NO_ATAPI, ATA_FLAG_NCQ, MV_GEN_IIE_FLAGS = MV_GEN_II_FLAGS | ATA_FLAG_AN, Loading Loading @@ -348,6 +346,12 @@ enum { EDMA_HALTCOND_OFS = 0x60, /* GenIIe halt conditions */ BMDMA_CMD_OFS = 0x224, /* bmdma command register */ BMDMA_STATUS_OFS = 0x228, /* bmdma status register */ BMDMA_PRD_LOW_OFS = 0x22c, /* bmdma PRD addr 31:0 */ BMDMA_PRD_HIGH_OFS = 0x230, /* bmdma PRD addr 63:32 */ /* Host private flags (hp_flags) */ MV_HP_FLAG_MSI = (1 << 0), MV_HP_ERRATA_50XXB0 = (1 << 1), Loading Loading @@ -547,6 +551,15 @@ static void mv_pmp_error_handler(struct ata_port *ap); static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp); static unsigned long mv_mode_filter(struct ata_device *dev, unsigned long xfer_mask); static void mv_sff_irq_clear(struct ata_port *ap); static int mv_check_atapi_dma(struct ata_queued_cmd *qc); static void mv_bmdma_setup(struct ata_queued_cmd *qc); static void mv_bmdma_start(struct ata_queued_cmd *qc); static void mv_bmdma_stop(struct ata_queued_cmd *qc); static u8 mv_bmdma_status(struct ata_port *ap); /* .sg_tablesize is (MV_MAX_SG_CT / 2) in the structures below * because we have to allow room for worst case splitting of * PRDs for 64K boundaries in mv_fill_sg(). Loading Loading @@ -594,6 +607,14 @@ static struct ata_port_operations mv6_ops = { .pmp_softreset = mv_softreset, .softreset = mv_softreset, .error_handler = mv_pmp_error_handler, .sff_irq_clear = mv_sff_irq_clear, .check_atapi_dma = mv_check_atapi_dma, .bmdma_setup = mv_bmdma_setup, .bmdma_start = mv_bmdma_start, .bmdma_stop = mv_bmdma_stop, .bmdma_status = mv_bmdma_status, .mode_filter = mv_mode_filter, }; static struct ata_port_operations mv_iie_ops = { Loading Loading @@ -1392,6 +1413,167 @@ static void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last) *cmdw = cpu_to_le16(tmp); } /** * mv_mode_filter - Allow ATAPI DMA only on GenII chips. * @dev: device whose xfer modes are being configured. * * Only the GenII hardware can use DMA with ATAPI drives. */ static unsigned long mv_mode_filter(struct ata_device *adev, unsigned long xfer_mask) { if (adev->class == ATA_DEV_ATAPI) { struct mv_host_priv *hpriv = adev->link->ap->host->private_data; if (!IS_GEN_II(hpriv)) { xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); ata_dev_printk(adev, KERN_INFO, "ATAPI DMA not supported on this chipset\n"); } } return xfer_mask; } /** * mv_sff_irq_clear - Clear hardware interrupt after DMA. * @ap: Port associated with this ATA transaction. * * We need this only for ATAPI bmdma transactions, * as otherwise we experience spurious interrupts * after libata-sff handles the bmdma interrupts. */ static void mv_sff_irq_clear(struct ata_port *ap) { mv_clear_and_enable_port_irqs(ap, mv_ap_base(ap), ERR_IRQ); } /** * mv_check_atapi_dma - Filter ATAPI cmds which are unsuitable for DMA. * @qc: queued command to check for chipset/DMA compatibility. * * The bmdma engines cannot handle speculative data sizes * (bytecount under/over flow). So only allow DMA for * data transfer commands with known data sizes. * * LOCKING: * Inherited from caller. */ static int mv_check_atapi_dma(struct ata_queued_cmd *qc) { struct scsi_cmnd *scmd = qc->scsicmd; if (scmd) { switch (scmd->cmnd[0]) { case READ_6: case READ_10: case READ_12: case WRITE_6: case WRITE_10: case WRITE_12: case GPCMD_READ_CD: case GPCMD_SEND_DVD_STRUCTURE: case GPCMD_SEND_CUE_SHEET: return 0; /* DMA is safe */ } } return -EOPNOTSUPP; /* use PIO instead */ } /** * mv_bmdma_setup - Set up BMDMA transaction * @qc: queued command to prepare DMA for. * * LOCKING: * Inherited from caller. */ static void mv_bmdma_setup(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; void __iomem *port_mmio = mv_ap_base(ap); struct mv_port_priv *pp = ap->private_data; mv_fill_sg(qc); /* clear all DMA cmd bits */ writel(0, port_mmio + BMDMA_CMD_OFS); /* load PRD table addr. */ writel((pp->sg_tbl_dma[qc->tag] >> 16) >> 16, port_mmio + BMDMA_PRD_HIGH_OFS); writelfl(pp->sg_tbl_dma[qc->tag], port_mmio + BMDMA_PRD_LOW_OFS); /* issue r/w command */ ap->ops->sff_exec_command(ap, &qc->tf); } /** * mv_bmdma_start - Start a BMDMA transaction * @qc: queued command to start DMA on. * * LOCKING: * Inherited from caller. */ static void mv_bmdma_start(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; void __iomem *port_mmio = mv_ap_base(ap); unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE); u32 cmd = (rw ? 0 : ATA_DMA_WR) | ATA_DMA_START; /* start host DMA transaction */ writelfl(cmd, port_mmio + BMDMA_CMD_OFS); } /** * mv_bmdma_stop - Stop BMDMA transfer * @qc: queued command to stop DMA on. * * Clears the ATA_DMA_START flag in the bmdma control register * * LOCKING: * Inherited from caller. */ static void mv_bmdma_stop(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; void __iomem *port_mmio = mv_ap_base(ap); u32 cmd; /* clear start/stop bit */ cmd = readl(port_mmio + BMDMA_CMD_OFS); cmd &= ~ATA_DMA_START; writelfl(cmd, port_mmio + BMDMA_CMD_OFS); /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ ata_sff_dma_pause(ap); } /** * mv_bmdma_status - Read BMDMA status * @ap: port for which to retrieve DMA status. * * Read and return equivalent of the sff BMDMA status register. * * LOCKING: * Inherited from caller. */ static u8 mv_bmdma_status(struct ata_port *ap) { void __iomem *port_mmio = mv_ap_base(ap); u32 reg, status; /* * Other bits are valid only if ATA_DMA_ACTIVE==0, * and the ATA_DMA_INTR bit doesn't exist. */ reg = readl(port_mmio + BMDMA_STATUS_OFS); if (reg & ATA_DMA_ACTIVE) status = ATA_DMA_ACTIVE; else status = (reg & ATA_DMA_ERR) | ATA_DMA_INTR; return status; } /** * mv_qc_prep - Host specific command preparation. * @qc: queued command to prepare Loading