From mboxrd@z Thu Jan 1 00:00:00 1970 From: Justin Seitz Subject: Re: Output Date: Fri, 13 Jan 2006 13:13:08 -0800 Message-ID: <43C817E4.3090804@crossflux.com> References: <18a8ddb18a33a6.18a33a618a8ddb@shaw.ca> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Return-path: Received: from shawidc-mo1.cg.shawcable.net ([24.71.223.10]:55163 "EHLO pd5mo3so.prod.shaw.ca") by vger.kernel.org with ESMTP id S1422971AbWAMVIc (ORCPT ); Fri, 13 Jan 2006 16:08:32 -0500 Received: from pd3mr6so.prod.shaw.ca (pd3mr6so-qfe3.prod.shaw.ca [10.0.141.21]) by l-daemon (Sun ONE Messaging Server 6.0 HotFix 1.01 (built Mar 15 2004)) with ESMTP id <0IT100CYSUPX7E90@l-daemon> for linux-ide@vger.kernel.org; Fri, 13 Jan 2006 14:08:22 -0700 (MST) Received: from pn2ml8so.prod.shaw.ca ([10.0.121.152]) by pd3mr6so.prod.shaw.ca (Sun ONE Messaging Server 6.0 HotFix 1.01 (built Mar 15 2004)) with ESMTP id <0IT100CVPUPX3I10@pd3mr6so.prod.shaw.ca> for linux-ide@vger.kernel.org; Fri, 13 Jan 2006 14:08:21 -0700 (MST) Received: from [192.168.7.77] ([24.67.66.120]) by l-daemon (Sun ONE Messaging Server 6.0 HotFix 1.01 (built Mar 15 2004)) with ESMTP id <0IT1007YBUPXUMN0@l-daemon> for linux-ide@vger.kernel.org; Fri, 13 Jan 2006 14:08:21 -0700 (MST) In-reply-to: <18a8ddb18a33a6.18a33a618a8ddb@shaw.ca> Sender: linux-ide-owner@vger.kernel.org List-Id: linux-ide@vger.kernel.org To: linux-ide@vger.kernel.org >I am having problems getting the VIA VT8251 southbridge SATA (AHCI) support running on Fedora Core 4. Here is all the information i could possibly give you. > > >Ok I am trying to apply the patch found at >http://seclists.org/lists/linux-kernel/2005/Dec/3220.html > > > >So here is the patch code: >--- ahci.c.orig 2005-11-21 14:24:48.000000000 +0800 >+++ ahci.c 2005-11-21 14:25:35.000000000 +0800 >@@ -59,6 +59,7 @@ > RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */ > > board_ahci = 0, >+ board_via_ahci = 1, > > /* global controller registers */ > HOST_CAP = 0x00, /* host capabilities */ >@@ -126,6 +127,7 @@ > PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */ > PORT_CMD_FIS_ON = (1 << 14), /* FIS DMA engine running */ > PORT_CMD_FIS_RX = (1 << 4), /* Enable FIS receive DMA engine */ >+ PORT_CMD_CLO = (1 << 3), /* CLO */ > PORT_CMD_POWER_ON = (1 << 2), /* Power up device */ > PORT_CMD_SPIN_UP = (1 << 1), /* Spin up device */ > PORT_CMD_START = (1 << 0), /* Enable port DMA engine */ >@@ -183,6 +185,14 @@ > static u8 ahci_check_err(struct ata_port *ap); > static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); > >+static int via_ahci_qc_issue(struct ata_queued_cmd *qc); >+static void via_ahci_phy_reset(struct ata_port *ap); >+static void via_ahci_port_stop(struct ata_port *ap); >+static int via_ahci_softreset(struct ata_port *ap); >+static unsigned int via_ata_busy_sleep (struct ata_port *ap, >+ unsigned long tmout_pat, >+ unsigned long tmout); >+ > static Scsi_Host_Template ahci_sht = { > .module = THIS_MODULE, > .name = DRV_NAME, >@@ -231,6 +241,35 @@ > .host_stop = ahci_host_stop, > }; > >+static struct ata_port_operations via_ahci_ops = { >+ .port_disable = ata_port_disable, >+ >+ .check_status = ahci_check_status, >+ .check_altstatus = ahci_check_status, >+ .check_err = ahci_check_err, >+ .dev_select = ata_noop_dev_select, >+ >+ .tf_read = ahci_tf_read, >+ >+ >+ .qc_prep = ahci_qc_prep, >+ >+ .eng_timeout = ahci_eng_timeout, >+ >+ .irq_handler = ahci_interrupt, >+ .irq_clear = ahci_irq_clear, >+ >+ .scr_read = ahci_scr_read, >+ .scr_write = ahci_scr_write, >+ >+ .port_start = ahci_port_start, >+ .host_stop = ahci_host_stop, >+ >+ .phy_reset = via_ahci_phy_reset, >+ .qc_issue = via_ahci_qc_issue, >+ .port_stop = via_ahci_port_stop, >+}; >+ > static struct ata_port_info ahci_port_info[] = { > /* board_ahci */ > { >@@ -242,6 +281,16 @@ > .udma_mask = 0x7f, /* udma0-6 ; FIXME */ > .port_ops = &ahci_ops, > }, >+ /* board_via_ahci */ >+ { >+ .sht = &ahci_sht, >+ .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | >+ ATA_FLAG_SRST | ATA_FLAG_MMIO | >+ ATA_FLAG_PIO_DMA, >+ .pio_mask = 0x03, /* pio3-4 */ >+ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ >+ .port_ops = &via_ahci_ops, >+ }, > }; > > static struct pci_device_id ahci_pci_tbl[] = { >@@ -263,6 +312,8 @@ > board_ahci }, /* ESB2 */ > { PCI_VENDOR_ID_INTEL, 0x2683, PCI_ANY_ID, PCI_ANY_ID, 0, 0, > board_ahci }, /* ESB2 */ >+ { PCI_VENDOR_ID_VIA, 0x3349, PCI_ANY_ID, PCI_ANY_ID, 0, 0, >+ board_via_ahci }, /* VT8251*/ > { } /* terminate list */ > }; > >@@ -1049,6 +1100,244 @@ > return rc; > } > >+/* START: patch code for VIA VT8251 ahci controller */ >+ >+static int via_ahci_softreset(struct ata_port *ap) >+{ >+ void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; >+ struct ahci_port_priv *pp = ap->private_data; >+ u32 tmp,i; >+ u8 *fisbuf; >+ >+ VPRINTK("ENTER\n"); >+ >+ writel(0x00000000, port_mmio + PORT_IRQ_MASK); /*disable interrupt */ >+ readl (port_mmio + PORT_IRQ_MASK); /* flush */ >+ >+ /* prepare the software-reset commands */ >+ >+ /* prepare first command header */ >+ memset(pp->cmd_slot, 0, 32); >+ pp->cmd_slot[0].opts = 0x00000505; >+ pp->cmd_slot[0].status = 0; >+ pp->cmd_slot[0].tbl_addr = cpu_to_le32(pp->cmd_tbl_dma & 0xffffffff); >+ pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16); >+ >+ /* prepare CMDFIS struct */ >+ fisbuf = pp->cmd_tbl; >+ memset(fisbuf, 0, 64); >+ fisbuf[0] = 0x27; >+ fisbuf[7] = 0xa0; >+ fisbuf[15] = 0x04; >+ >+ /* trigger the commands */ >+ writel(0x1, port_mmio + PORT_CMD_ISSUE); >+ readl (port_mmio + PORT_CMD_ISSUE); /* flush */ >+ >+ udelay(20); >+ /* wait command complete */ >+ for (i = 0; i < 2000; i++) { >+ tmp = readl(port_mmio + PORT_CMD_ISSUE); >+ if ((tmp & 1) == 0) break; >+ msleep(20); >+ } >+ >+ if (i == 2000) { >+ printk(KERN_WARNING "TimeOut for Wait Command complete\n"); >+ return 1; >+ } >+ >+ /* prepare second command header */ >+ pp->cmd_slot[0].opts = 0x00000005; >+ pp->cmd_slot[0].status = 0; >+ pp->cmd_slot[0].tbl_addr = cpu_to_le32(pp->cmd_tbl_dma & 0xffffffff); >+ pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16); >+ >+ fisbuf = pp->cmd_tbl; >+ memset(fisbuf, 0, 64); >+ fisbuf[0] = 0x27; >+ fisbuf[7] = 0xa0; >+ fisbuf[15] = 0x00; >+ >+ /* trigger the commands */ >+ writel(0x1, port_mmio + PORT_CMD_ISSUE); >+ readl (port_mmio + PORT_CMD_ISSUE); /* flush */ >+ >+ udelay(20); >+ /* wait command complete */ >+ for (i = 0; i < 2000; i++) { >+ tmp = readl(port_mmio + PORT_CMD_ISSUE); >+ if ((tmp & 1) == 0) break; >+ msleep(20); >+ } >+ >+ if (i == 2000) { >+ printk(KERN_WARNING "TimeOut for Wait Command complete\n"); >+ return 1; >+ } >+ >+ // enable port interrupt >+ writel(0xffffffff, port_mmio + PORT_IRQ_MASK); >+ readl (port_mmio + PORT_IRQ_MASK); /* flush */ >+ >+ return 0; >+} >+ >+static unsigned int via_ata_busy_sleep (struct ata_port *ap, >+ unsigned long tmout_pat, >+ unsigned long tmout) >+{ >+ unsigned long timer_start, timeout; >+ u8 status; >+ >+ status = ata_busy_wait(ap, ATA_BUSY, 300); >+ timer_start = jiffies; >+ timeout = timer_start + tmout_pat; >+ while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) { >+ msleep(50); >+ status = ata_busy_wait(ap, ATA_BUSY, 3); >+ } >+ >+ if (status & ATA_BUSY) >+ printk(KERN_WARNING "ata%u is slow to respond, " >+ "please be patient\n", ap->id); >+ >+ timeout = timer_start + tmout; >+ while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) { >+ msleep(50); >+ status = ata_chk_status(ap); >+ } >+ >+ if (status & ATA_BUSY) { >+ printk(KERN_ERR "ata%u failed to respond (%lu secs)\n", >+ ap->id, tmout / HZ); >+ return 1; >+ } >+ >+ return 0; >+} >+ >+static void via_ahci_phy_reset(struct ata_port *ap) >+{ >+ void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; >+ struct ata_taskfile tf; >+ struct ata_device *dev = &ap->device[0]; >+ u32 tmp; >+ >+ u32 sstatus,i; >+ unsigned long timeout = jiffies + (HZ * 5); >+ u8 tmp_status; >+ >+ if (ap->flags & ATA_FLAG_SATA_RESET) { >+ /* issue phy wake/reset */ >+ scr_write_flush(ap, SCR_CONTROL, 0x301); >+ udelay(400); /* FIXME: a guess */ >+ } >+ scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */ >+ >+ /* wait for phy to become ready, if necessary */ >+ do { >+ msleep(200); >+ sstatus = scr_read(ap, SCR_STATUS); >+ if ((sstatus & 0xf) != 1) >+ break; >+ } while (time_before(jiffies, timeout)); >+ >+ /* TODO: phy layer with polling, timeouts, etc. */ >+ if (sata_dev_present(ap)) >+ ata_port_probe(ap); >+ else { >+ sstatus = scr_read(ap, SCR_STATUS); >+ printk(KERN_INFO "ata%u: no device found (phy stat %08x)\n", >+ ap->id, sstatus); >+ ata_port_disable(ap); >+ } >+ >+ if (ap->flags & ATA_FLAG_PORT_DISABLED) >+ return; >+ >+ /*Fix the VIA busy bug by a software reset*/ >+ for (i = 0; i < 100; i++) { >+ tmp_status = ap->ops->check_status(ap); >+ if ((tmp_status & ATA_BUSY) == 0) break; >+ msleep(10); >+ } >+ >+ if ((tmp_status & ATA_BUSY)) { >+ DPRINTK("Busy after CommReset, do softreset...\n"); >+ /*set the PxCMD.CLO bit to clear BUSY and DRQ, to make the reset command sent out*/ >+ tmp = readl(port_mmio + PORT_CMD); >+ tmp |= PORT_CMD_CLO; >+ writel(tmp, port_mmio + PORT_CMD); >+ readl(port_mmio + PORT_CMD); /* flush */ >+ >+ if (via_ahci_softreset(ap)) { >+ printk(KERN_WARNING "softreset failed\n"); >+ return; >+ } >+ } >+ >+ if (via_ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) { >+ ata_port_disable(ap); >+ return; >+ } >+ >+ ap->cbl = ATA_CBL_SATA; >+ >+ if (ap->flags & ATA_FLAG_PORT_DISABLED) >+ return; >+ >+ tmp = readl(port_mmio + PORT_SIG); >+ tf.lbah = (tmp >> 24) & 0xff; >+ tf.lbam = (tmp >> 16) & 0xff; >+ tf.lbal = (tmp >> 8) & 0xff; >+ tf.nsect = (tmp) & 0xff; >+ >+ dev->class = ata_dev_classify(&tf); >+ if (!ata_dev_present(dev)) >+ ata_port_disable(ap); >+ >+} >+ >+static int via_ahci_qc_issue(struct ata_queued_cmd *qc) >+{ >+ struct ata_port *ap = qc->ap; >+ void *port_mmio = (void *) ap->ioaddr.cmd_addr; >+ >+ if (qc && >+ qc->tf.command == ATA_CMD_SET_FEATURES && >+ qc->tf.feature == SETFEATURES_XFER) { >+ /* skip set xfer mode process */ >+ >+ ata_qc_complete(qc, 0); >+ qc = NULL; >+ return 0; >+ } >+ >+ writel(1, port_mmio + PORT_CMD_ISSUE); >+ readl(port_mmio + PORT_CMD_ISSUE); /* flush */ >+ >+ return 0; >+} >+ >+static void via_ahci_port_stop(struct ata_port *ap) >+{ >+ struct device *dev = ap->host_set->dev; >+ struct ahci_port_priv *pp = ap->private_data; >+ >+ /* spec says 500 msecs for each PORT_CMD_{START,FIS_RX} bit, so >+ * this is slightly incorrect. >+ */ >+ msleep(500); >+ >+ ap->private_data = NULL; >+ dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, >+ pp->cmd_slot, pp->cmd_slot_dma); >+ kfree(pp); >+ ata_port_stop(ap); >+} >+ >+/* END: patch code for VIA VT8251 ahci controller */ > > static int __init ahci_init(void) > { > > > > >Now when I run: > >patch -p1 ahci.c < ahci-patch > >I get the following output: > >missing header for unified diff at line 3 of patch >patching file ahci.c >Hunk #1 FAILED at 59. >Hunk #2 FAILED at 127. >Hunk #3 succeeded at 198 with fuzz 2 (offset 13 lines). >Hunk #4 succeeded at 240 with fuzz 2 (offset -1 lines). >Hunk #5 FAILED at 280. >Hunk #6 FAILED at 311. >Hunk #7 succeeded at 1140 with fuzz 2 (offset 40 lines). >4 out of 7 hunks FAILED -- saving rejects to file ahci.c.rej > > >*I really need to get this SATA controller working on this VIA VT8251 board on Fedora Core 4. What am I doing wrong to get this patch installed correclty? Does anyone have a fully patched ahci.c that compiles into the kernel properly? > >JS > >ps Here is the output from ahci.c.rej:* > >*************** >*** 59,64 **** > RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */ > > board_ahci = 0, > > /* global controller registers */ > HOST_CAP = 0x00, /* host capabilities */ >--- 59,65 ---- > RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */ > > board_ahci = 0, >+ board_via_ahci = 1, > > /* global controller registers */ > HOST_CAP = 0x00, /* host capabilities */ >*************** >*** 126,131 **** > PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */ >*** 126,131 **** > PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */ > PORT_CMD_FIS_ON = (1 << 14), /* FIS DMA engine running */ > PORT_CMD_FIS_RX = (1 << 4), /* Enable FIS receive DMA engine */ > PORT_CMD_POWER_ON = (1 << 2), /* Power up device */ > PORT_CMD_SPIN_UP = (1 << 1), /* Spin up device */ > PORT_CMD_START = (1 << 0), /* Enable port DMA engine */ >--- 127,133 ---- > PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */ > PORT_CMD_FIS_ON = (1 << 14), /* FIS DMA engine running */ > PORT_CMD_FIS_RX = (1 << 4), /* Enable FIS receive DMA engine */ >+ PORT_CMD_CLO = (1 << 3), /* CLO */ > PORT_CMD_POWER_ON = (1 << 2), /* Power up device */ > PORT_CMD_SPIN_UP = (1 << 1), /* Spin up device */ > PORT_CMD_START = (1 << 0), /* Enable port DMA engine */ >*************** >*** 241,246 **** > .udma_mask = 0x7f, /* udma0-6 ; FIXME */ > .port_ops = &ahci_ops, > .udma_mask = 0x7f, /* udma0-6 ; FIXME */ > .port_ops = &ahci_ops, > }, > }; > > static struct pci_device_id ahci_pci_tbl[] = { >--- 280,295 ---- > .udma_mask = 0x7f, /* udma0-6 ; FIXME */ > .port_ops = &ahci_ops, > }, >+ /* board_via_ahci */ >+ { >+ .sht = &ahci_sht, >+ .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | >+ ATA_FLAG_SRST | ATA_FLAG_MMIO | >+ ATA_FLAG_PIO_DMA, >+ .pio_mask = 0x03, /* pio3-4 */ >+ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ >+ .port_ops = &via_ahci_ops, >+ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ >+ .port_ops = &via_ahci_ops, >+ }, > }; > > static struct pci_device_id ahci_pci_tbl[] = { >*************** >*** 262,267 **** > board_ahci }, /* ESB2 */ > { PCI_VENDOR_ID_INTEL, 0x2683, PCI_ANY_ID, PCI_ANY_ID, 0, 0, > board_ahci }, /* ESB2 */ > { } /* terminate list */ > }; > >--- 311,318 ---- > board_ahci }, /* ESB2 */ > { PCI_VENDOR_ID_INTEL, 0x2683, PCI_ANY_ID, PCI_ANY_ID, 0, 0, > board_ahci }, /* ESB2 */ >+ { PCI_VENDOR_ID_VIA, 0x3349, PCI_ANY_ID, PCI_ANY_ID, 0, 0, > GNU nano 1.3.5-cvs File: ahci.c.rej Modified > > board_ahci }, /* ESB2 */ >+ { PCI_VENDOR_ID_VIA, 0x3349, PCI_ANY_ID, PCI_ANY_ID, 0, 0, >+ board_via_ahci }, /* VT8251*/ > { } /* terminate list */ > }; > > > > > > > > > > >