mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 19:29:37 +00:00
[libata] sata_mv: Minor cleanups and renaming, preparing for new EH & NCQ
Minor cleanups, new definitions, and code movement, preparing for upcoming new-EH and NCQ changes. This commit shoult not change behavior at all. Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
parent
814600ee10
commit
c5d3e45a22
1 changed files with 105 additions and 57 deletions
|
@ -108,8 +108,6 @@ enum {
|
|||
MV_SATAHC_ARBTR_REG_SZ = MV_MINOR_REG_AREA_SZ, /* arbiter */
|
||||
MV_PORT_REG_SZ = MV_MINOR_REG_AREA_SZ,
|
||||
|
||||
MV_USE_Q_DEPTH = ATA_DEF_QUEUE,
|
||||
|
||||
MV_MAX_Q_DEPTH = 32,
|
||||
MV_MAX_Q_DEPTH_MASK = MV_MAX_Q_DEPTH - 1,
|
||||
|
||||
|
@ -133,18 +131,22 @@ enum {
|
|||
/* Host Flags */
|
||||
MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */
|
||||
MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */
|
||||
MV_COMMON_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
|
||||
ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING),
|
||||
MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
|
||||
ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING,
|
||||
MV_6XXX_FLAGS = MV_FLAG_IRQ_COALESCE,
|
||||
|
||||
CRQB_FLAG_READ = (1 << 0),
|
||||
CRQB_TAG_SHIFT = 1,
|
||||
CRQB_IOID_SHIFT = 6, /* CRQB Gen-II/IIE IO Id shift */
|
||||
CRQB_HOSTQ_SHIFT = 17, /* CRQB Gen-II/IIE HostQueTag shift */
|
||||
CRQB_CMD_ADDR_SHIFT = 8,
|
||||
CRQB_CMD_CS = (0x2 << 11),
|
||||
CRQB_CMD_LAST = (1 << 15),
|
||||
|
||||
CRPB_FLAG_STATUS_SHIFT = 8,
|
||||
CRPB_IOID_SHIFT_6 = 5, /* CRPB Gen-II IO Id shift */
|
||||
CRPB_IOID_SHIFT_7 = 7, /* CRPB Gen-IIE IO Id shift */
|
||||
|
||||
EPRD_FLAG_END_OF_TBL = (1 << 31),
|
||||
|
||||
|
@ -236,8 +238,10 @@ enum {
|
|||
EDMA_ERR_DEV_DCON = (1 << 3),
|
||||
EDMA_ERR_DEV_CON = (1 << 4),
|
||||
EDMA_ERR_SERR = (1 << 5),
|
||||
EDMA_ERR_SELF_DIS = (1 << 7),
|
||||
EDMA_ERR_SELF_DIS = (1 << 7), /* Gen II/IIE self-disable */
|
||||
EDMA_ERR_SELF_DIS_5 = (1 << 8), /* Gen I self-disable */
|
||||
EDMA_ERR_BIST_ASYNC = (1 << 8),
|
||||
EDMA_ERR_TRANS_IRQ_7 = (1 << 8), /* Gen IIE transprt layer irq */
|
||||
EDMA_ERR_CRBQ_PAR = (1 << 9),
|
||||
EDMA_ERR_CRPB_PAR = (1 << 10),
|
||||
EDMA_ERR_INTRL_PAR = (1 << 11),
|
||||
|
@ -248,6 +252,8 @@ enum {
|
|||
EDMA_ERR_LNK_CTRL_TX = (0x1f << 21),
|
||||
EDMA_ERR_LNK_DATA_TX = (0x1f << 26),
|
||||
EDMA_ERR_TRANS_PROTO = (1 << 31),
|
||||
EDMA_ERR_OVERRUN_5 = (1 << 5),
|
||||
EDMA_ERR_UNDERRUN_5 = (1 << 6),
|
||||
EDMA_ERR_FATAL = (EDMA_ERR_D_PAR | EDMA_ERR_PRD_PAR |
|
||||
EDMA_ERR_DEV_DCON | EDMA_ERR_CRBQ_PAR |
|
||||
EDMA_ERR_CRPB_PAR | EDMA_ERR_INTRL_PAR |
|
||||
|
@ -288,6 +294,7 @@ enum {
|
|||
/* Port private flags (pp_flags) */
|
||||
MV_PP_FLAG_EDMA_EN = (1 << 0),
|
||||
MV_PP_FLAG_EDMA_DS_ACT = (1 << 1),
|
||||
MV_PP_FLAG_HAD_A_RESET = (1 << 2),
|
||||
};
|
||||
|
||||
#define IS_50XX(hpriv) ((hpriv)->hp_flags & MV_HP_50XX)
|
||||
|
@ -417,12 +424,30 @@ static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio,
|
|||
unsigned int port_no);
|
||||
static void mv_stop_and_reset(struct ata_port *ap);
|
||||
|
||||
static struct scsi_host_template mv_sht = {
|
||||
static struct scsi_host_template mv5_sht = {
|
||||
.module = THIS_MODULE,
|
||||
.name = DRV_NAME,
|
||||
.ioctl = ata_scsi_ioctl,
|
||||
.queuecommand = ata_scsi_queuecmd,
|
||||
.can_queue = MV_USE_Q_DEPTH,
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = MV_MAX_SG_CT,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = 1,
|
||||
.proc_name = DRV_NAME,
|
||||
.dma_boundary = MV_DMA_BOUNDARY,
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
};
|
||||
|
||||
static struct scsi_host_template mv6_sht = {
|
||||
.module = THIS_MODULE,
|
||||
.name = DRV_NAME,
|
||||
.ioctl = ata_scsi_ioctl,
|
||||
.queuecommand = ata_scsi_queuecmd,
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = MV_MAX_SG_CT,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
|
@ -530,38 +555,38 @@ static const struct ata_port_info mv_port_info[] = {
|
|||
.port_ops = &mv5_ops,
|
||||
},
|
||||
{ /* chip_508x */
|
||||
.flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
|
||||
.flags = MV_COMMON_FLAGS | MV_FLAG_DUAL_HC,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = ATA_UDMA6,
|
||||
.port_ops = &mv5_ops,
|
||||
},
|
||||
{ /* chip_5080 */
|
||||
.flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
|
||||
.flags = MV_COMMON_FLAGS | MV_FLAG_DUAL_HC,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = ATA_UDMA6,
|
||||
.port_ops = &mv5_ops,
|
||||
},
|
||||
{ /* chip_604x */
|
||||
.flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
|
||||
.flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = ATA_UDMA6,
|
||||
.port_ops = &mv6_ops,
|
||||
},
|
||||
{ /* chip_608x */
|
||||
.flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS |
|
||||
MV_FLAG_DUAL_HC),
|
||||
.flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS |
|
||||
MV_FLAG_DUAL_HC,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = ATA_UDMA6,
|
||||
.port_ops = &mv6_ops,
|
||||
},
|
||||
{ /* chip_6042 */
|
||||
.flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
|
||||
.flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = ATA_UDMA6,
|
||||
.port_ops = &mv_iie_ops,
|
||||
},
|
||||
{ /* chip_7042 */
|
||||
.flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
|
||||
.flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = ATA_UDMA6,
|
||||
.port_ops = &mv_iie_ops,
|
||||
|
@ -709,6 +734,41 @@ static void mv_irq_clear(struct ata_port *ap)
|
|||
{
|
||||
}
|
||||
|
||||
static void mv_set_edma_ptrs(void __iomem *port_mmio,
|
||||
struct mv_host_priv *hpriv,
|
||||
struct mv_port_priv *pp)
|
||||
{
|
||||
/*
|
||||
* initialize request queue
|
||||
*/
|
||||
WARN_ON(pp->crqb_dma & 0x3ff);
|
||||
writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS);
|
||||
writelfl(pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK,
|
||||
port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
|
||||
|
||||
if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0)
|
||||
writelfl(pp->crqb_dma & 0xffffffff,
|
||||
port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
|
||||
else
|
||||
writelfl(0, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
|
||||
|
||||
/*
|
||||
* initialize response queue
|
||||
*/
|
||||
WARN_ON(pp->crpb_dma & 0xff);
|
||||
writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS);
|
||||
|
||||
if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0)
|
||||
writelfl(pp->crpb_dma & 0xffffffff,
|
||||
port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
|
||||
else
|
||||
writelfl(0, port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
|
||||
|
||||
writelfl(pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK,
|
||||
port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* mv_start_dma - Enable eDMA engine
|
||||
* @base: port base address
|
||||
|
@ -720,9 +780,10 @@ static void mv_irq_clear(struct ata_port *ap)
|
|||
* LOCKING:
|
||||
* Inherited from caller.
|
||||
*/
|
||||
static void mv_start_dma(void __iomem *base, struct mv_port_priv *pp)
|
||||
static void mv_start_dma(void __iomem *base, struct mv_host_priv *hpriv,
|
||||
struct mv_port_priv *pp)
|
||||
{
|
||||
if (!(MV_PP_FLAG_EDMA_EN & pp->pp_flags)) {
|
||||
if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) {
|
||||
writelfl(EDMA_EN, base + EDMA_CMD_OFS);
|
||||
pp->pp_flags |= MV_PP_FLAG_EDMA_EN;
|
||||
}
|
||||
|
@ -739,12 +800,12 @@ static void mv_start_dma(void __iomem *base, struct mv_port_priv *pp)
|
|||
* LOCKING:
|
||||
* Inherited from caller.
|
||||
*/
|
||||
static void mv_stop_dma(struct ata_port *ap)
|
||||
static int mv_stop_dma(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *port_mmio = mv_ap_base(ap);
|
||||
struct mv_port_priv *pp = ap->private_data;
|
||||
u32 reg;
|
||||
int i;
|
||||
int i, err = 0;
|
||||
|
||||
if (MV_PP_FLAG_EDMA_EN & pp->pp_flags) {
|
||||
/* Disable EDMA if active. The disable bit auto clears.
|
||||
|
@ -764,10 +825,13 @@ static void mv_stop_dma(struct ata_port *ap)
|
|||
udelay(100);
|
||||
}
|
||||
|
||||
if (EDMA_EN & reg) {
|
||||
if (reg & EDMA_EN) {
|
||||
ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n");
|
||||
/* FIXME: Consider doing a reset here to recover */
|
||||
err = -EIO;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef ATA_DEBUG
|
||||
|
@ -884,12 +948,13 @@ static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
|
|||
writelfl(val, mv_ap_base(ap) + ofs);
|
||||
}
|
||||
|
||||
static void mv_edma_cfg(struct mv_host_priv *hpriv, void __iomem *port_mmio)
|
||||
static void mv_edma_cfg(struct ata_port *ap, struct mv_host_priv *hpriv,
|
||||
void __iomem *port_mmio)
|
||||
{
|
||||
u32 cfg = readl(port_mmio + EDMA_CFG_OFS);
|
||||
|
||||
/* set up non-NCQ EDMA configuration */
|
||||
cfg &= ~(1 << 9); /* disable equeue */
|
||||
cfg &= ~(1 << 9); /* disable eQue */
|
||||
|
||||
if (IS_GEN_I(hpriv)) {
|
||||
cfg &= ~0x1f; /* clear queue depth */
|
||||
|
@ -971,28 +1036,9 @@ static int mv_port_start(struct ata_port *ap)
|
|||
pp->sg_tbl = mem;
|
||||
pp->sg_tbl_dma = mem_dma;
|
||||
|
||||
mv_edma_cfg(hpriv, port_mmio);
|
||||
mv_edma_cfg(ap, hpriv, port_mmio);
|
||||
|
||||
writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS);
|
||||
writelfl(pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK,
|
||||
port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
|
||||
|
||||
if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0)
|
||||
writelfl(pp->crqb_dma & 0xffffffff,
|
||||
port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
|
||||
else
|
||||
writelfl(0, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
|
||||
|
||||
writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS);
|
||||
|
||||
if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0)
|
||||
writelfl(pp->crpb_dma & 0xffffffff,
|
||||
port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
|
||||
else
|
||||
writelfl(0, port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
|
||||
|
||||
writelfl(pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK,
|
||||
port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
|
||||
mv_set_edma_ptrs(port_mmio, hpriv, pp);
|
||||
|
||||
/* Don't turn on EDMA here...do it before DMA commands only. Else
|
||||
* we'll be unable to send non-data, PIO, etc due to restricted access
|
||||
|
@ -1088,7 +1134,7 @@ static void mv_qc_prep(struct ata_queued_cmd *qc)
|
|||
u16 flags = 0;
|
||||
unsigned in_index;
|
||||
|
||||
if (ATA_PROT_DMA != qc->tf.protocol)
|
||||
if (qc->tf.protocol != ATA_PROT_DMA)
|
||||
return;
|
||||
|
||||
/* Fill in command request block
|
||||
|
@ -1180,7 +1226,7 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc)
|
|||
unsigned in_index;
|
||||
u32 flags = 0;
|
||||
|
||||
if (ATA_PROT_DMA != qc->tf.protocol)
|
||||
if (qc->tf.protocol != ATA_PROT_DMA)
|
||||
return;
|
||||
|
||||
/* Fill in Gen IIE command request block
|
||||
|
@ -1241,17 +1287,19 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc)
|
|||
*/
|
||||
static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
|
||||
{
|
||||
void __iomem *port_mmio = mv_ap_base(qc->ap);
|
||||
struct mv_port_priv *pp = qc->ap->private_data;
|
||||
struct ata_port *ap = qc->ap;
|
||||
void __iomem *port_mmio = mv_ap_base(ap);
|
||||
struct mv_port_priv *pp = ap->private_data;
|
||||
struct mv_host_priv *hpriv = ap->host->private_data;
|
||||
unsigned in_index;
|
||||
u32 in_ptr;
|
||||
|
||||
if (ATA_PROT_DMA != qc->tf.protocol) {
|
||||
if (qc->tf.protocol != ATA_PROT_DMA) {
|
||||
/* We're about to send a non-EDMA capable command to the
|
||||
* port. Turn off EDMA so there won't be problems accessing
|
||||
* shadow block, etc registers.
|
||||
*/
|
||||
mv_stop_dma(qc->ap);
|
||||
mv_stop_dma(ap);
|
||||
return ata_qc_issue_prot(qc);
|
||||
}
|
||||
|
||||
|
@ -1264,7 +1312,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
|
|||
|
||||
in_index = mv_inc_q_index(in_index); /* now incr producer index */
|
||||
|
||||
mv_start_dma(port_mmio, pp);
|
||||
mv_start_dma(port_mmio, hpriv, pp);
|
||||
|
||||
/* and write the request in pointer to kick the EDMA to life */
|
||||
in_ptr &= EDMA_REQ_Q_BASE_LO_MASK;
|
||||
|
@ -1379,7 +1427,8 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc)
|
|||
void __iomem *hc_mmio = mv_hc_base(mmio, hc);
|
||||
struct ata_queued_cmd *qc;
|
||||
u32 hc_irq_cause;
|
||||
int shift, port, port0, hard_port, handled;
|
||||
int port, port0;
|
||||
int shift, hard_port, handled;
|
||||
unsigned int err_mask;
|
||||
|
||||
if (hc == 0)
|
||||
|
@ -1458,10 +1507,9 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc)
|
|||
}
|
||||
|
||||
/**
|
||||
* mv_interrupt -
|
||||
* mv_interrupt - Main interrupt event handler
|
||||
* @irq: unused
|
||||
* @dev_instance: private data; in this case the host structure
|
||||
* @regs: unused
|
||||
*
|
||||
* Read the read only register to determine if any host
|
||||
* controllers have pending interrupts. If so, call lower level
|
||||
|
@ -1965,7 +2013,7 @@ static void __mv_phy_reset(struct ata_port *ap, int can_sleep)
|
|||
void __iomem *port_mmio = mv_ap_base(ap);
|
||||
struct ata_taskfile tf;
|
||||
struct ata_device *dev = &ap->device[0];
|
||||
unsigned long timeout;
|
||||
unsigned long deadline;
|
||||
int retry = 5;
|
||||
u32 sstatus;
|
||||
|
||||
|
@ -1983,14 +2031,14 @@ static void __mv_phy_reset(struct ata_port *ap, int can_sleep)
|
|||
sata_scr_write_flush(ap, SCR_CONTROL, 0x300);
|
||||
__msleep(20, can_sleep);
|
||||
|
||||
timeout = jiffies + msecs_to_jiffies(200);
|
||||
deadline = jiffies + msecs_to_jiffies(200);
|
||||
do {
|
||||
sata_scr_read(ap, SCR_STATUS, &sstatus);
|
||||
if (((sstatus & 0x3) == 3) || ((sstatus & 0x3) == 0))
|
||||
break;
|
||||
|
||||
__msleep(1, can_sleep);
|
||||
} while (time_before(jiffies, timeout));
|
||||
} while (time_before(jiffies, deadline));
|
||||
|
||||
/* work around errata */
|
||||
if (IS_60XX(hpriv) &&
|
||||
|
@ -2427,7 +2475,7 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
|
||||
pci_set_master(pdev);
|
||||
return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED,
|
||||
&mv_sht);
|
||||
IS_GEN_I(hpriv) ? &mv5_sht : &mv6_sht);
|
||||
}
|
||||
|
||||
static int __init mv_init(void)
|
||||
|
|
Loading…
Reference in a new issue