mirror of https://gitee.com/openkylin/linux.git
sata_fsl,mv,nv: prepare for NCQ command completion update
Make the following changes to prepare for NCQ command completion update. Changes made by this patch don't cause any functional difference. * sata_fsl_host_intr(): rename the local variable qc_active to done_mask as that's what it is. * mv_process_crpb_response(): restructure if clause for easier update. * nv_adma_interrupt(): drop unnecessary error variable. * nv_swncq_sdbfis(): drop unnecessary nr_done and return 0 on success. Typo fix. * nv_swncq_dmafis(): drop unused return value and return void. * nv_swncq_host_interrupt(): drop unnecessary return value handling. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Ashish Kalra <ashish.kalra@freescale.com> Cc: Saeed Bishara <saeed@marvell.com> Cc: Mark Lord <liml@rtr.ca> Cc: Robert Hancock <hancockr@shaw.ca> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
This commit is contained in:
parent
af4d6e257d
commit
752e386c24
|
@ -1096,7 +1096,7 @@ static void sata_fsl_host_intr(struct ata_port *ap)
|
||||||
{
|
{
|
||||||
struct sata_fsl_host_priv *host_priv = ap->host->private_data;
|
struct sata_fsl_host_priv *host_priv = ap->host->private_data;
|
||||||
void __iomem *hcr_base = host_priv->hcr_base;
|
void __iomem *hcr_base = host_priv->hcr_base;
|
||||||
u32 hstatus, qc_active = 0;
|
u32 hstatus, done_mask = 0;
|
||||||
struct ata_queued_cmd *qc;
|
struct ata_queued_cmd *qc;
|
||||||
u32 SError;
|
u32 SError;
|
||||||
|
|
||||||
|
@ -1116,28 +1116,28 @@ static void sata_fsl_host_intr(struct ata_port *ap)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read command completed register */
|
/* Read command completed register */
|
||||||
qc_active = ioread32(hcr_base + CC);
|
done_mask = ioread32(hcr_base + CC);
|
||||||
|
|
||||||
VPRINTK("Status of all queues :\n");
|
VPRINTK("Status of all queues :\n");
|
||||||
VPRINTK("qc_active/CC = 0x%x, CA = 0x%x, CE=0x%x,CQ=0x%x,apqa=0x%x\n",
|
VPRINTK("done_mask/CC = 0x%x, CA = 0x%x, CE=0x%x,CQ=0x%x,apqa=0x%x\n",
|
||||||
qc_active,
|
done_mask,
|
||||||
ioread32(hcr_base + CA),
|
ioread32(hcr_base + CA),
|
||||||
ioread32(hcr_base + CE),
|
ioread32(hcr_base + CE),
|
||||||
ioread32(hcr_base + CQ),
|
ioread32(hcr_base + CQ),
|
||||||
ap->qc_active);
|
ap->qc_active);
|
||||||
|
|
||||||
if (qc_active & ap->qc_active) {
|
if (done_mask & ap->qc_active) {
|
||||||
int i;
|
int i;
|
||||||
/* clear CC bit, this will also complete the interrupt */
|
/* clear CC bit, this will also complete the interrupt */
|
||||||
iowrite32(qc_active, hcr_base + CC);
|
iowrite32(done_mask, hcr_base + CC);
|
||||||
|
|
||||||
DPRINTK("Status of all queues :\n");
|
DPRINTK("Status of all queues :\n");
|
||||||
DPRINTK("qc_active/CC = 0x%x, CA = 0x%x, CE=0x%x\n",
|
DPRINTK("done_mask/CC = 0x%x, CA = 0x%x, CE=0x%x\n",
|
||||||
qc_active, ioread32(hcr_base + CA),
|
done_mask, ioread32(hcr_base + CA),
|
||||||
ioread32(hcr_base + CE));
|
ioread32(hcr_base + CE));
|
||||||
|
|
||||||
for (i = 0; i < SATA_FSL_QUEUE_DEPTH; i++) {
|
for (i = 0; i < SATA_FSL_QUEUE_DEPTH; i++) {
|
||||||
if (qc_active & (1 << i)) {
|
if (done_mask & (1 << i)) {
|
||||||
qc = ata_qc_from_tag(ap, i);
|
qc = ata_qc_from_tag(ap, i);
|
||||||
if (qc) {
|
if (qc) {
|
||||||
ata_qc_complete(qc);
|
ata_qc_complete(qc);
|
||||||
|
@ -1164,7 +1164,7 @@ static void sata_fsl_host_intr(struct ata_port *ap)
|
||||||
/* Spurious Interrupt!! */
|
/* Spurious Interrupt!! */
|
||||||
DPRINTK("spurious interrupt!!, CC = 0x%x\n",
|
DPRINTK("spurious interrupt!!, CC = 0x%x\n",
|
||||||
ioread32(hcr_base + CC));
|
ioread32(hcr_base + CC));
|
||||||
iowrite32(qc_active, hcr_base + CC);
|
iowrite32(done_mask, hcr_base + CC);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2716,34 +2716,35 @@ static void mv_err_intr(struct ata_port *ap)
|
||||||
static void mv_process_crpb_response(struct ata_port *ap,
|
static void mv_process_crpb_response(struct ata_port *ap,
|
||||||
struct mv_crpb *response, unsigned int tag, int ncq_enabled)
|
struct mv_crpb *response, unsigned int tag, int ncq_enabled)
|
||||||
{
|
{
|
||||||
|
u8 ata_status;
|
||||||
|
u16 edma_status = le16_to_cpu(response->flags);
|
||||||
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag);
|
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag);
|
||||||
|
|
||||||
if (qc) {
|
if (unlikely(!qc)) {
|
||||||
u8 ata_status;
|
|
||||||
u16 edma_status = le16_to_cpu(response->flags);
|
|
||||||
/*
|
|
||||||
* edma_status from a response queue entry:
|
|
||||||
* LSB is from EDMA_ERR_IRQ_CAUSE (non-NCQ only).
|
|
||||||
* MSB is saved ATA status from command completion.
|
|
||||||
*/
|
|
||||||
if (!ncq_enabled) {
|
|
||||||
u8 err_cause = edma_status & 0xff & ~EDMA_ERR_DEV;
|
|
||||||
if (err_cause) {
|
|
||||||
/*
|
|
||||||
* Error will be seen/handled by mv_err_intr().
|
|
||||||
* So do nothing at all here.
|
|
||||||
*/
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ata_status = edma_status >> CRPB_FLAG_STATUS_SHIFT;
|
|
||||||
if (!ac_err_mask(ata_status))
|
|
||||||
ata_qc_complete(qc);
|
|
||||||
/* else: leave it for mv_err_intr() */
|
|
||||||
} else {
|
|
||||||
ata_port_printk(ap, KERN_ERR, "%s: no qc for tag=%d\n",
|
ata_port_printk(ap, KERN_ERR, "%s: no qc for tag=%d\n",
|
||||||
__func__, tag);
|
__func__, tag);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* edma_status from a response queue entry:
|
||||||
|
* LSB is from EDMA_ERR_IRQ_CAUSE (non-NCQ only).
|
||||||
|
* MSB is saved ATA status from command completion.
|
||||||
|
*/
|
||||||
|
if (!ncq_enabled) {
|
||||||
|
u8 err_cause = edma_status & 0xff & ~EDMA_ERR_DEV;
|
||||||
|
if (err_cause) {
|
||||||
|
/*
|
||||||
|
* Error will be seen/handled by
|
||||||
|
* mv_err_intr(). So do nothing at all here.
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ata_status = edma_status >> CRPB_FLAG_STATUS_SHIFT;
|
||||||
|
if (!ac_err_mask(ata_status))
|
||||||
|
ata_qc_complete(qc);
|
||||||
|
/* else: leave it for mv_err_intr() */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp)
|
static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp)
|
||||||
|
|
|
@ -1018,7 +1018,7 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
|
||||||
NV_ADMA_STAT_CPBERR |
|
NV_ADMA_STAT_CPBERR |
|
||||||
NV_ADMA_STAT_CMD_COMPLETE)) {
|
NV_ADMA_STAT_CMD_COMPLETE)) {
|
||||||
u32 check_commands = notifier_clears[i];
|
u32 check_commands = notifier_clears[i];
|
||||||
int pos, error = 0;
|
int pos, rc;
|
||||||
|
|
||||||
if (status & NV_ADMA_STAT_CPBERR) {
|
if (status & NV_ADMA_STAT_CPBERR) {
|
||||||
/* check all active commands */
|
/* check all active commands */
|
||||||
|
@ -1030,10 +1030,12 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check CPBs for completed commands */
|
/* check CPBs for completed commands */
|
||||||
while ((pos = ffs(check_commands)) && !error) {
|
while ((pos = ffs(check_commands))) {
|
||||||
pos--;
|
pos--;
|
||||||
error = nv_adma_check_cpb(ap, pos,
|
rc = nv_adma_check_cpb(ap, pos,
|
||||||
notifier_error & (1 << pos));
|
notifier_error & (1 << pos));
|
||||||
|
if (unlikely(rc))
|
||||||
|
check_commands = 0;
|
||||||
check_commands &= ~(1 << pos);
|
check_commands &= ~(1 << pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2129,7 +2131,6 @@ static int nv_swncq_sdbfis(struct ata_port *ap)
|
||||||
struct nv_swncq_port_priv *pp = ap->private_data;
|
struct nv_swncq_port_priv *pp = ap->private_data;
|
||||||
struct ata_eh_info *ehi = &ap->link.eh_info;
|
struct ata_eh_info *ehi = &ap->link.eh_info;
|
||||||
u32 sactive;
|
u32 sactive;
|
||||||
int nr_done = 0;
|
|
||||||
u32 done_mask;
|
u32 done_mask;
|
||||||
int i;
|
int i;
|
||||||
u8 host_stat;
|
u8 host_stat;
|
||||||
|
@ -2170,22 +2171,21 @@ static int nv_swncq_sdbfis(struct ata_port *ap)
|
||||||
pp->dhfis_bits &= ~(1 << i);
|
pp->dhfis_bits &= ~(1 << i);
|
||||||
pp->dmafis_bits &= ~(1 << i);
|
pp->dmafis_bits &= ~(1 << i);
|
||||||
pp->sdbfis_bits |= (1 << i);
|
pp->sdbfis_bits |= (1 << i);
|
||||||
nr_done++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ap->qc_active) {
|
if (!ap->qc_active) {
|
||||||
DPRINTK("over\n");
|
DPRINTK("over\n");
|
||||||
nv_swncq_pp_reinit(ap);
|
nv_swncq_pp_reinit(ap);
|
||||||
return nr_done;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pp->qc_active & pp->dhfis_bits)
|
if (pp->qc_active & pp->dhfis_bits)
|
||||||
return nr_done;
|
return 0;
|
||||||
|
|
||||||
if ((pp->ncq_flags & ncq_saw_backout) ||
|
if ((pp->ncq_flags & ncq_saw_backout) ||
|
||||||
(pp->qc_active ^ pp->dhfis_bits))
|
(pp->qc_active ^ pp->dhfis_bits))
|
||||||
/* if the controller cann't get a device to host register FIS,
|
/* if the controller can't get a device to host register FIS,
|
||||||
* The driver needs to reissue the new command.
|
* The driver needs to reissue the new command.
|
||||||
*/
|
*/
|
||||||
lack_dhfis = 1;
|
lack_dhfis = 1;
|
||||||
|
@ -2202,7 +2202,7 @@ static int nv_swncq_sdbfis(struct ata_port *ap)
|
||||||
if (lack_dhfis) {
|
if (lack_dhfis) {
|
||||||
qc = ata_qc_from_tag(ap, pp->last_issue_tag);
|
qc = ata_qc_from_tag(ap, pp->last_issue_tag);
|
||||||
nv_swncq_issue_atacmd(ap, qc);
|
nv_swncq_issue_atacmd(ap, qc);
|
||||||
return nr_done;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pp->defer_queue.defer_bits) {
|
if (pp->defer_queue.defer_bits) {
|
||||||
|
@ -2212,7 +2212,7 @@ static int nv_swncq_sdbfis(struct ata_port *ap)
|
||||||
nv_swncq_issue_atacmd(ap, qc);
|
nv_swncq_issue_atacmd(ap, qc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nr_done;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 nv_swncq_tag(struct ata_port *ap)
|
static inline u32 nv_swncq_tag(struct ata_port *ap)
|
||||||
|
@ -2224,7 +2224,7 @@ static inline u32 nv_swncq_tag(struct ata_port *ap)
|
||||||
return (tag & 0x1f);
|
return (tag & 0x1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nv_swncq_dmafis(struct ata_port *ap)
|
static void nv_swncq_dmafis(struct ata_port *ap)
|
||||||
{
|
{
|
||||||
struct ata_queued_cmd *qc;
|
struct ata_queued_cmd *qc;
|
||||||
unsigned int rw;
|
unsigned int rw;
|
||||||
|
@ -2239,7 +2239,7 @@ static int nv_swncq_dmafis(struct ata_port *ap)
|
||||||
qc = ata_qc_from_tag(ap, tag);
|
qc = ata_qc_from_tag(ap, tag);
|
||||||
|
|
||||||
if (unlikely(!qc))
|
if (unlikely(!qc))
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
rw = qc->tf.flags & ATA_TFLAG_WRITE;
|
rw = qc->tf.flags & ATA_TFLAG_WRITE;
|
||||||
|
|
||||||
|
@ -2254,8 +2254,6 @@ static int nv_swncq_dmafis(struct ata_port *ap)
|
||||||
dmactl |= ATA_DMA_WR;
|
dmactl |= ATA_DMA_WR;
|
||||||
|
|
||||||
iowrite8(dmactl | ATA_DMA_START, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
|
iowrite8(dmactl | ATA_DMA_START, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis)
|
static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis)
|
||||||
|
@ -2265,7 +2263,6 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis)
|
||||||
struct ata_eh_info *ehi = &ap->link.eh_info;
|
struct ata_eh_info *ehi = &ap->link.eh_info;
|
||||||
u32 serror;
|
u32 serror;
|
||||||
u8 ata_stat;
|
u8 ata_stat;
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
ata_stat = ap->ops->sff_check_status(ap);
|
ata_stat = ap->ops->sff_check_status(ap);
|
||||||
nv_swncq_irq_clear(ap, fis);
|
nv_swncq_irq_clear(ap, fis);
|
||||||
|
@ -2310,8 +2307,7 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis)
|
||||||
"dhfis 0x%X dmafis 0x%X sactive 0x%X\n",
|
"dhfis 0x%X dmafis 0x%X sactive 0x%X\n",
|
||||||
ap->print_id, pp->qc_active, pp->dhfis_bits,
|
ap->print_id, pp->qc_active, pp->dhfis_bits,
|
||||||
pp->dmafis_bits, readl(pp->sactive_block));
|
pp->dmafis_bits, readl(pp->sactive_block));
|
||||||
rc = nv_swncq_sdbfis(ap);
|
if (nv_swncq_sdbfis(ap) < 0)
|
||||||
if (rc < 0)
|
|
||||||
goto irq_error;
|
goto irq_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2348,7 +2344,7 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis)
|
||||||
*/
|
*/
|
||||||
pp->dmafis_bits |= (0x1 << nv_swncq_tag(ap));
|
pp->dmafis_bits |= (0x1 << nv_swncq_tag(ap));
|
||||||
pp->ncq_flags |= ncq_saw_dmas;
|
pp->ncq_flags |= ncq_saw_dmas;
|
||||||
rc = nv_swncq_dmafis(ap);
|
nv_swncq_dmafis(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
irq_exit:
|
irq_exit:
|
||||||
|
|
Loading…
Reference in New Issue