From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tejun Heo Subject: [PATCH 07/10] sata_sil24: separate out sil24_exec_polled_cmd() Date: Fri, 12 May 2006 01:43:42 +0900 Message-ID: <11473658223980-git-send-email-htejun@gmail.com> References: <11473658222012-git-send-email-htejun@gmail.com> Reply-To: Tejun Heo Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7BIT Return-path: Received: from py-out-1112.google.com ([64.233.166.177]:19952 "EHLO py-out-1112.google.com") by vger.kernel.org with ESMTP id S1030344AbWEKQny (ORCPT ); Thu, 11 May 2006 12:43:54 -0400 Received: by py-out-1112.google.com with SMTP id f28so308104pyf for ; Thu, 11 May 2006 09:43:54 -0700 (PDT) In-Reply-To: <11473658222012-git-send-email-htejun@gmail.com> Sender: linux-ide-owner@vger.kernel.org List-Id: linux-ide@vger.kernel.org To: jgarzik@pobox.com, alan@lxorguk.ukuu.org.uk, axboe@suse.de, albertcc@tw.ibm.com, forrest.zhao@intel.com, efalk@google.com, linux-ide@vger.kernel.org Cc: Tejun Heo Separate out sil24_exec_polled_cmd() from sil24_softreset(). This will be used to implement sil24_pm_read/write(). --- drivers/scsi/sata_sil24.c | 75 ++++++++++++++++++++++++++++++++------------- 1 files changed, 54 insertions(+), 21 deletions(-) 4530c25627ea84e1907b94166c8b74a3ade942f4 diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index dfbe750..34f2e67 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c @@ -515,16 +515,59 @@ static int sil24_init_port(struct ata_po return 0; } -static int sil24_softreset(struct ata_link *link, unsigned int *class) +static int sil24_exec_polled_cmd(struct ata_port *ap, u32 ctrl, + const struct ata_taskfile *tf, + int pmp, int is_cmd, + unsigned long timeout_msec) { - struct ata_port *ap = link->ap; void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; struct sil24_port_priv *pp = ap->private_data; struct sil24_prb *prb = &pp->cmd_block[0].ata.prb; dma_addr_t paddr = pp->cmd_block_dma; + u32 irq_enabled, irq_mask, irq_stat; + int rc; + + prb->ctrl = cpu_to_le16(ctrl); + ata_tf_to_fis(tf, pmp, is_cmd, prb->fis); + + /* temporarily plug completion and error interrupts */ + irq_enabled = readl(port + PORT_IRQ_ENABLE_SET); + writel(PORT_IRQ_COMPLETE | PORT_IRQ_ERROR, port + PORT_IRQ_ENABLE_CLR); + + writel((u32)paddr, port + PORT_CMD_ACTIVATE); + writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4); + + irq_mask = (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR) << PORT_IRQ_RAW_SHIFT; + irq_stat = ata_wait_register(port + PORT_IRQ_STAT, irq_mask, 0x0, + 10, timeout_msec); + + writel(irq_mask, port + PORT_IRQ_STAT); /* clear IRQs */ + irq_stat >>= PORT_IRQ_RAW_SHIFT; + + if (irq_stat & PORT_IRQ_COMPLETE) + rc = 0; + else { + /* force port into known state */ + sil24_init_port(ap); + + if (irq_stat & PORT_IRQ_ERROR) + rc = -EIO; + else + rc = -EBUSY; + } + + /* restore IRQ enabled */ + writel(irq_enabled, port + PORT_IRQ_ENABLE_SET); + + return rc; +} + +static int sil24_softreset(struct ata_link *link, unsigned int *class) +{ + struct ata_port *ap = link->ap; struct ata_taskfile tf; - u32 mask, irq_stat; const char *reason; + int rc; DPRINTK("ENTER\n"); @@ -541,24 +584,14 @@ static int sil24_softreset(struct ata_li } /* do SRST */ - prb->ctrl = cpu_to_le16(PRB_CTRL_SRST); - prb->fis[1] = 0; /* no PM yet */ - - writel((u32)paddr, port + PORT_CMD_ACTIVATE); - writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4); - - mask = (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR) << PORT_IRQ_RAW_SHIFT; - irq_stat = ata_wait_register(port + PORT_IRQ_STAT, mask, 0x0, - 100, ATA_TMOUT_BOOT / HZ * 1000); - - writel(irq_stat, port + PORT_IRQ_STAT); /* clear IRQs */ - irq_stat >>= PORT_IRQ_RAW_SHIFT; - - if (!(irq_stat & PORT_IRQ_COMPLETE)) { - if (irq_stat & PORT_IRQ_ERROR) - reason = "SRST command error"; - else - reason = "timeout"; + ata_tf_init(link->device, &tf); /* doesn't really matter */ + rc = sil24_exec_polled_cmd(ap, PRB_CTRL_SRST, &tf, 0, 0, + ATA_TMOUT_BOOT / HZ * 1000); + if (rc == -EBUSY) { + reason = "timeout"; + goto err; + } else if (rc) { + reason = "SRST command error"; goto err; } -- 1.2.4