2006-09-14 18:39:50

by Robin H. Johnson

[permalink] [raw]
Subject: 2.6.18-rc7-git1: AHCI not seeing devices on ICH8 mobo (DG965RY)

[Please CC me, I'm not subscribed.]

Recently picked up some new hardware (without sufficiently researching
it), and I have found that the AHCI driver does NOT see my SATA optical
device at all.

CPU: Core 2 Duo E6400
Motherboard: Intel DG965RY
DVD: Plextor PX-755SA, SATA DVD burner

# lspci -s 00:1f.2 -vv
00:1f.2 SATA controller: Intel Corporation 82801HR/HO/HH (ICH8R/DO/DH) SATA AHCI Controller (rev 02) (prog-if 01 [AHCI 1.0])
Subsystem: Intel Corporation Unknown device 514d
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
Status: Cap+ 66MHz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
Latency: 0
Interrupt: pin A routed to IRQ 74
Region 0: I/O ports at 4108 [size=8]
Region 1: I/O ports at 411c [size=4]
Region 2: I/O ports at 4100 [size=8]
Region 3: I/O ports at 4118 [size=4]
Region 4: I/O ports at 4020 [size=32]
Region 5: Memory at 90625000 (32-bit, non-prefetchable) [size=2K]
Capabilities: [80] Message Signalled Interrupts: 64bit- Queue=0/4 Enable+
Address: fee00000 Data: 404a
Capabilities: [70] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot+,D3cold-)
Status: D0 PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [a8] #12 [0010]

Snippets from dmesg (http://www.orbis-terrarum.net/~robbat2/x86_64-mmconfig-failure/dmesg-2.6.18-rc7-git1-pci=nommconf):
libata version 2.00 loaded.
ahci 0000:00:1f.2: version 2.0
ACPI: PCI Interrupt 0000:00:1f.2[A] -> GSI 19 (level, low) -> IRQ 193
PCI: Setting latency timer of device 0000:00:1f.2 to 64
ahci 0000:00:1f.2: AHCI 0001.0100 32 slots 4 ports 3 Gbps 0x33 impl SATA mode
ahci 0000:00:1f.2: flags: 64bit ncq led clo pio slum part
ata1: SATA max UDMA/133 cmd 0xFFFFC20000040100 ctl 0x0 bmdma 0x0 irq 74
ata2: SATA max UDMA/133 cmd 0xFFFFC20000040180 ctl 0x0 bmdma 0x0 irq 74
ata3: SATA max UDMA/133 cmd 0xFFFFC20000040200 ctl 0x0 bmdma 0x0 irq 74
ata4: SATA max UDMA/133 cmd 0xFFFFC20000040280 ctl 0x0 bmdma 0x0 irq 74
scsi1 : ahci
ata1: SATA link down (SStatus 0 SControl 300)
scsi2 : ahci
ata2: SATA link down (SStatus 0 SControl 300)
scsi3 : ahci
ata3: SATA link down (SStatus 0 SControl 0)
scsi4 : ahci
ata4: SATA link down (SStatus 0 SControl 0)

I don't have any SATA hard drives on hand (I'm using a 3ware IDE controller for
storage presently), so I haven't tested with them yet, but I intend to pick
some up this afternoon.

On a separate issue, this board incidently is also the one mentioned in
previous LKML posts that has a presently unsupported Marvell IDE controller.
Jeff Garzik said he was asking Marvell for specs, does anybody know how that
went, or did anybody try to prod around with the controller?

Details as follows:

# lspci -s 02:00.0 -vv
02:00.0 IDE interface: Marvell Technology Group Ltd. Unknown device 6101 (rev b1) (prog-if 8f [Master SecP SecO PriP PriO])
Subsystem: Marvell Technology Group Ltd. Unknown device 6101
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
Latency: 0, Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 10
Region 0: I/O ports at 3018 [size=8]
Region 1: I/O ports at 3024 [size=4]
Region 2: I/O ports at 3010 [size=8]
Region 3: I/O ports at 3020 [size=4]
Region 4: I/O ports at 3000 [size=16]
Region 5: Memory at 90400000 (32-bit, non-prefetchable) [size=512]
Capabilities: [48] Power Management version 2
Flags: PMEClk- DSI- D1+ D2- AuxCurrent=0mA PME(D0+,D1+,D2-,D3hot+,D3cold-)
Status: D0 PME-Enable- DSel=0 DScale=1 PME-
Capabilities: [50] Message Signalled Interrupts: 64bit- Queue=0/0 Enable-
Address: 00000000 Data: 0000
Capabilities: [e0] Express Legacy Endpoint IRQ 0
Device: Supported: MaxPayload 128 bytes, PhantFunc 0, ExtTag-
Device: Latency L0s unlimited, L1 unlimited
Device: AtnBtn- AtnInd- PwrInd-
Device: Errors: Correctable- Non-Fatal- Fatal- Unsupported-
Device: RlxdOrd- ExtTag- PhantFunc- AuxPwr+ NoSnoop-
Device: MaxPayload 128 bytes, MaxReadReq 512 bytes
Link: Supported Speed 2.5Gb/s, Width x1, ASPM L0s, Port 0
Link: Latency L0s <256ns, L1 unlimited
Link: ASPM Disabled RCB 64 bytes CommClk+ ExtSynch-
Link: Speed 2.5Gb/s, Width x1

--
Robin Hugh Johnson
E-Mail : [email protected]
GnuPG FP : 11AC BA4F 4778 E3F6 E4ED F38E B27B 944E 3488 4E85


Attachments:
(No filename) (4.32 kB)
(No filename) (232.00 B)
Download all attachments

2006-09-14 19:19:15

by Jeff Garzik

[permalink] [raw]
Subject: Re: 2.6.18-rc7-git1: AHCI not seeing devices on ICH8 mobo (DG965RY)

Robin H. Johnson wrote:
> [Please CC me, I'm not subscribed.]
>
> Recently picked up some new hardware (without sufficiently researching
> it), and I have found that the AHCI driver does NOT see my SATA optical
> device at all.

> scsi1 : ahci
> ata1: SATA link down (SStatus 0 SControl 300)
> scsi2 : ahci
> ata2: SATA link down (SStatus 0 SControl 300)
> scsi3 : ahci
> ata3: SATA link down (SStatus 0 SControl 0)
> scsi4 : ahci
> ata4: SATA link down (SStatus 0 SControl 0)


Unfortunately the SATA phy isn't showing that a SATA device (hd or cdrom
or anything) is connected. So can't do anything much at all, if that is
the case.

Perhaps re-check all the power connections, cables, etc.

Jeff


2006-09-14 19:25:24

by Robin H. Johnson

[permalink] [raw]
Subject: Re: 2.6.18-rc7-git1: AHCI not seeing devices on ICH8 mobo (DG965RY)

On Thu, Sep 14, 2006 at 03:19:10PM -0400, Jeff Garzik wrote:
> Robin H. Johnson wrote:
> >[Please CC me, I'm not subscribed.]
> >
> >Recently picked up some new hardware (without sufficiently researching
> >it), and I have found that the AHCI driver does NOT see my SATA optical
> >device at all.
>
> >scsi1 : ahci
> >ata1: SATA link down (SStatus 0 SControl 300)
> >scsi2 : ahci
> >ata2: SATA link down (SStatus 0 SControl 300)
> >scsi3 : ahci
> >ata3: SATA link down (SStatus 0 SControl 0)
> >scsi4 : ahci
> >ata4: SATA link down (SStatus 0 SControl 0)
> Unfortunately the SATA phy isn't showing that a SATA device (hd or cdrom
> or anything) is connected. So can't do anything much at all, if that is
> the case.
>
> Perhaps re-check all the power connections, cables, etc.
I neglected to say, that the BIOS sees it perfectly fine, and the
initial boot sequence perfectly with ISOLINUX (everything just falls
over later when the initrd tries to load up a squashfs image from the
CD).

--
Robin Hugh Johnson
E-Mail : [email protected]
GnuPG FP : 11AC BA4F 4778 E3F6 E4ED F38E B27B 944E 3488 4E85


Attachments:
(No filename) (1.09 kB)
(No filename) (232.00 B)
Download all attachments

2006-09-16 20:53:53

by Robin H. Johnson

[permalink] [raw]
Subject: Re: 2.6.18-rc7-git1: AHCI not seeing devices on ICH8 mobo (DG965RY)

On Sat, Sep 16, 2006 at 01:38:12PM -0700, Robin H. Johnson wrote:
> Ok, I picked up some SATA hard drives now, and the AHCI driver DOES see them.
> However, it gets more interesting now.
>
> The board has 4 SATA ports.
>
> In the BIOS, all 4 of them work, and can start the bootloader from any
> of them.
>
> In the kernel, ONLY the first two ports work.
>
> The only thing I see on this, is that in my original dmesg, when the DVD
> drive was connected to the 4th port, and nothing connected on SATA1-3,
> SControl was 300 for 1/2 and 0 for 3/4.

I recompiled libata and AHCI using the ATA_DEBUG and ATA_VERBOSE_DEBUG
defines, and got an interesting trace.

In specific, look at port_idx 2/3, being all zeros in ahci_host_init.

I'm digging into it further now, but something makes me suspect that
base addresses for ports 3/4 are wrong.

Full file at:
http://orbis-terrarum.net/~robbat2/x86_64-mmconfig-failure/2.6.18-rc7-git1-libata-ahci-verbose-failure.dmesg

Initial portion:
libata version 2.00 loaded.
ahci_init_one: ENTER
ahci 0000:00:1f.2: version 2.0
ACPI: PCI Interrupt 0000:00:1f.2[A] -> GSI 19 (level, low) -> IRQ 193
ahci_host_init: cap 0xe320ffc3 port_map 0x33 n_ports 4
ahci_host_init: mmio ffffc20000018000 port_mmio ffffc20000018100
ahci_setup_port: ENTER, base==0xffffc20000018000, port_idx 0
ahci_setup_port: base now==0xffffc20000018100
ahci_setup_port: EXIT
ahci_host_init: PORT_CMD 0x6
ahci_host_init: PORT_SCR_ERR 0x4050000
ahci_host_init: PORT_IRQ_STAT 0x0
ahci_host_init: mmio ffffc20000018000 port_mmio ffffc20000018180
ahci_setup_port: ENTER, base==0xffffc20000018000, port_idx 1
ahci_setup_port: base now==0xffffc20000018180
ahci_setup_port: EXIT
ahci_host_init: PORT_CMD 0x6
ahci_host_init: PORT_SCR_ERR 0x4050000
ahci_host_init: PORT_IRQ_STAT 0x0
ahci_host_init: mmio ffffc20000018000 port_mmio ffffc20000018200
ahci_setup_port: ENTER, base==0xffffc20000018000, port_idx 2
ahci_setup_port: base now==0xffffc20000018200
ahci_setup_port: EXIT
ahci_host_init: PORT_CMD 0x0
ahci_host_init: PORT_SCR_ERR 0x0
ahci_host_init: PORT_IRQ_STAT 0x0
ahci_host_init: mmio ffffc20000018000 port_mmio ffffc20000018280
ahci_setup_port: ENTER, base==0xffffc20000018000, port_idx 3
ahci_setup_port: base now==0xffffc20000018280
ahci_setup_port: EXIT
ahci_host_init: PORT_CMD 0x0
ahci_host_init: PORT_SCR_ERR 0x0
ahci_host_init: PORT_IRQ_STAT 0x0
ahci_host_init: HOST_CTL 0x80000000
ahci_host_init: HOST_CTL 0x80000002
PCI: Setting latency timer of device 0000:00:1f.2 to 64
ahci 0000:00:1f.2: AHCI 0001.0100 32 slots 4 ports 3 Gbps 0x33 impl SATA mode
ahci 0000:00:1f.2: flags: 64bit ncq led clo pio slum part

--
Robin Hugh Johnson
E-Mail : [email protected]
GnuPG FP : 11AC BA4F 4778 E3F6 E4ED F38E B27B 944E 3488 4E85


Attachments:
(No filename) (2.69 kB)
(No filename) (232.00 B)
Download all attachments

2006-09-16 20:23:25

by Robin H. Johnson

[permalink] [raw]
Subject: Re: 2.6.18-rc7-git1: AHCI not seeing devices on ICH8 mobo (DG965RY)

On Thu, Sep 14, 2006 at 01:50:50PM -0700, Robin H. Johnson wrote:
> > Unfortunately the SATA phy isn't showing that a SATA device (hd or cdrom
> > or anything) is connected. So can't do anything much at all, if that is
> > the case.
> >
> > Perhaps re-check all the power connections, cables, etc.
> I neglected to say, that the BIOS sees it perfectly fine, and the
> initial boot sequence perfectly with ISOLINUX (everything just falls
> over later when the initrd tries to load up a squashfs image from the
> CD).
Ok, I picked up some SATA hard drives now, and the AHCI driver DOES see them.
However, it gets more interesting now.

The board has 4 SATA ports.

In the BIOS, all 4 of them work, and can start the bootloader from any
of them.

In the kernel, ONLY the first two ports work.

The only thing I see on this, is that in my original dmesg, when the DVD
drive was connected to the 4th port, and nothing connected on SATA1-3,
SControl was 300 for 1/2 and 0 for 3/4.

libata version 2.00 loaded.
ahci 0000:00:1f.2: version 2.0
ACPI: PCI Interrupt 0000:00:1f.2[A] -> GSI 19 (level, low) -> IRQ 193
PCI: Setting latency timer of device 0000:00:1f.2 to 64
ahci 0000:00:1f.2: AHCI 0001.0100 32 slots 4 ports 3 Gbps 0x33 impl SATA mode
ahci 0000:00:1f.2: flags: 64bit ncq led clo pio slum part
ata1: SATA max UDMA/133 cmd 0xFFFFC20000040100 ctl 0x0 bmdma 0x0 irq 74
ata2: SATA max UDMA/133 cmd 0xFFFFC20000040180 ctl 0x0 bmdma 0x0 irq 74
ata3: SATA max UDMA/133 cmd 0xFFFFC20000040200 ctl 0x0 bmdma 0x0 irq 74
ata4: SATA max UDMA/133 cmd 0xFFFFC20000040280 ctl 0x0 bmdma 0x0 irq 74
scsi1 : ahci
ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
ata1.00: ATA-7, max UDMA/133, 488397168 sectors: LBA48
ata1.00: ata1: dev 0 multi count 0
ata1.00: configured for UDMA/133
scsi2 : ahci
ata2: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
ata2.00: ATA-7, max UDMA/133, 488397168 sectors: LBA48
ata2.00: ata2: dev 0 multi count 0
ata2.00: configured for UDMA/133
scsi3 : ahci
ata3: SATA link down (SStatus 0 SControl 0)
scsi4 : ahci
ata4: SATA link down (SStatus 0 SControl 0)
Vendor: ATA Model: WDC WD2500JS-00M Rev: 02.0
Type: Direct-Access ANSI SCSI revision: 05
...
(picks up the second drive, and continues)

--
Robin Hugh Johnson
E-Mail : [email protected]
GnuPG FP : 11AC BA4F 4778 E3F6 E4ED F38E B27B 944E 3488 4E85


Attachments:
(No filename) (2.32 kB)
(No filename) (232.00 B)
Download all attachments

2006-09-17 07:49:33

by Tejun Heo

[permalink] [raw]
Subject: Re: 2.6.18-rc7-git1: AHCI not seeing devices on ICH8 mobo (DG965RY)

On Sat, Sep 16, 2006 at 02:08:57PM -0700, Robin H. Johnson wrote:
> On Sat, Sep 16, 2006 at 01:38:12PM -0700, Robin H. Johnson wrote:
> > Ok, I picked up some SATA hard drives now, and the AHCI driver DOES see them.
> > However, it gets more interesting now.
> >
> > The board has 4 SATA ports.
> >
> > In the BIOS, all 4 of them work, and can start the bootloader from any
> > of them.
> >
> > In the kernel, ONLY the first two ports work.
> >
> > The only thing I see on this, is that in my original dmesg, when the DVD
> > drive was connected to the 4th port, and nothing connected on SATA1-3,
> > SControl was 300 for 1/2 and 0 for 3/4.
>
> I recompiled libata and AHCI using the ATA_DEBUG and ATA_VERBOSE_DEBUG
> defines, and got an interesting trace.
>
> In specific, look at port_idx 2/3, being all zeros in ahci_host_init.
>
> I'm digging into it further now, but something makes me suspect that
> base addresses for ports 3/4 are wrong.
>
> Full file at:
> http://orbis-terrarum.net/~robbat2/x86_64-mmconfig-failure/2.6.18-rc7-git1-libata-ahci-verbose-failure.dmesg

Can you please try the attached patch?

Thanks.

diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 904c25f..dba99a5 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -53,6 +53,7 @@ #define DRV_VERSION "2.0"

enum {
AHCI_PCI_BAR = 5,
+ AHCI_MAX_PORTS = 32,
AHCI_MAX_SG = 168, /* hardware max is 64K */
AHCI_DMA_BOUNDARY = 0xffffffff,
AHCI_USE_CLUSTERING = 0,
@@ -186,9 +187,11 @@ struct ahci_host_priv {
unsigned long flags;
u32 cap; /* cache of HOST_CAP register */
u32 port_map; /* cache of HOST_PORTS_IMPL reg */
+ int port_tbl[AHCI_MAX_PORTS];
};

struct ahci_port_priv {
+ void __iomem *mmio;
struct ahci_cmd_hdr *cmd_slot;
dma_addr_t cmd_slot_dma;
void *cmd_tbl;
@@ -378,7 +381,8 @@ static int ahci_port_start(struct ata_po
struct ahci_host_priv *hpriv = ap->host_set->private_data;
struct ahci_port_priv *pp;
void __iomem *mmio = ap->host_set->mmio_base;
- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+ void __iomem *port_mmio = ahci_port_base(mmio,
+ hpriv->port_tbl[ap->port_no]);
void *mem;
dma_addr_t mem_dma;
int rc;
@@ -394,6 +398,8 @@ static int ahci_port_start(struct ata_po
return rc;
}

+ pp->mmio = port_mmio;
+
mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL);
if (!mem) {
ata_pad_free(ap, dev);
@@ -453,8 +459,7 @@ static void ahci_port_stop(struct ata_po
{
struct device *dev = ap->host_set->dev;
struct ahci_port_priv *pp = ap->private_data;
- void __iomem *mmio = ap->host_set->mmio_base;
- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+ void __iomem *port_mmio = pp->mmio;
u32 tmp;

tmp = readl(port_mmio + PORT_CMD);
@@ -510,8 +515,8 @@ static void ahci_scr_write (struct ata_p

static int ahci_stop_engine(struct ata_port *ap)
{
- void __iomem *mmio = ap->host_set->mmio_base;
- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+ struct ahci_port_priv *pp = ap->private_data;
+ void __iomem *port_mmio = pp->mmio;
int work;
u32 tmp;

@@ -535,8 +540,8 @@ static int ahci_stop_engine(struct ata_p

static void ahci_start_engine(struct ata_port *ap)
{
- void __iomem *mmio = ap->host_set->mmio_base;
- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+ struct ahci_port_priv *pp = ap->private_data;
+ void __iomem *port_mmio = pp->mmio;
u32 tmp;

tmp = readl(port_mmio + PORT_CMD);
@@ -547,7 +552,8 @@ static void ahci_start_engine(struct ata

static unsigned int ahci_dev_classify(struct ata_port *ap)
{
- void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
+ struct ahci_port_priv *pp = ap->private_data;
+ void __iomem *port_mmio = pp->mmio;
struct ata_taskfile tf;
u32 tmp;

@@ -575,8 +581,9 @@ static void ahci_fill_cmd_slot(struct ah

static int ahci_clo(struct ata_port *ap)
{
- void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
struct ahci_host_priv *hpriv = ap->host_set->private_data;
+ struct ahci_port_priv *pp = ap->private_data;
+ void __iomem *port_mmio = pp->mmio;
u32 tmp;

if (!(hpriv->cap & HOST_CAP_CLO))
@@ -608,8 +615,7 @@ static int ahci_prereset(struct ata_port
static int ahci_softreset(struct ata_port *ap, unsigned int *class)
{
struct ahci_port_priv *pp = ap->private_data;
- void __iomem *mmio = ap->host_set->mmio_base;
- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+ void __iomem *port_mmio = pp->mmio;
const u32 cmd_fis_len = 5; /* five dwords */
const char *reason = NULL;
struct ata_taskfile tf;
@@ -743,7 +749,8 @@ static int ahci_hardreset(struct ata_por

static void ahci_postreset(struct ata_port *ap, unsigned int *class)
{
- void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
+ struct ahci_port_priv *pp = ap->private_data;
+ void __iomem *port_mmio = pp->mmio;
u32 new_tmp, tmp;

ata_std_postreset(ap, class);
@@ -904,9 +911,9 @@ static void ahci_error_intr(struct ata_p

static void ahci_host_intr(struct ata_port *ap)
{
- void __iomem *mmio = ap->host_set->mmio_base;
- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+ struct ahci_port_priv *pp = ap->private_data;
struct ata_eh_info *ehi = &ap->eh_info;
+ void __iomem *port_mmio = pp->mmio;
u32 status, qc_active;
int rc;

@@ -978,7 +985,7 @@ static irqreturn_t ahci_interrupt(int ir
for (i = 0; i < host_set->n_ports; i++) {
struct ata_port *ap;

- if (!(irq_stat & (1 << i)))
+ if (!(irq_stat & (1 << hpriv->port_tbl[i])))
continue;

ap = host_set->ports[i];
@@ -992,7 +999,7 @@ static irqreturn_t ahci_interrupt(int ir
"interrupt on disabled port %u\n", i);
}

- irq_ack |= (1 << i);
+ irq_ack |= (1 << hpriv->port_tbl[i]);
}

if (irq_ack) {
@@ -1010,7 +1017,8 @@ static irqreturn_t ahci_interrupt(int ir
static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
+ struct ahci_port_priv *pp = ap->private_data;
+ void __iomem *port_mmio = pp->mmio;

if (qc->tf.protocol == ATA_PROT_NCQ)
writel(1 << qc->tag, port_mmio + PORT_SCR_ACT);
@@ -1022,8 +1030,8 @@ static unsigned int ahci_qc_issue(struct

static void ahci_freeze(struct ata_port *ap)
{
- void __iomem *mmio = ap->host_set->mmio_base;
- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+ struct ahci_port_priv *pp = ap->private_data;
+ void __iomem *port_mmio = pp->mmio;

/* turn IRQ off */
writel(0, port_mmio + PORT_IRQ_MASK);
@@ -1031,14 +1039,16 @@ static void ahci_freeze(struct ata_port

static void ahci_thaw(struct ata_port *ap)
{
+ struct ahci_host_priv *hpriv = ap->host_set->private_data;
+ struct ahci_port_priv *pp = ap->private_data;
void __iomem *mmio = ap->host_set->mmio_base;
- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+ void __iomem *port_mmio = pp->mmio;
u32 tmp;

/* clear IRQ */
tmp = readl(port_mmio + PORT_IRQ_STAT);
writel(tmp, port_mmio + PORT_IRQ_STAT);
- writel(1 << ap->id, mmio + HOST_IRQ_STAT);
+ writel(1 << hpriv->port_tbl[ap->id], mmio + HOST_IRQ_STAT);

/* turn IRQ back on */
writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK);
@@ -1090,7 +1100,7 @@ static int ahci_host_init(struct ata_pro
struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
void __iomem *mmio = probe_ent->mmio_base;
u32 tmp, cap_save;
- unsigned int i, j, using_dac;
+ unsigned int i, j, n_ports, using_dac;
int rc;
void __iomem *port_mmio;

@@ -1133,7 +1143,27 @@ static int ahci_host_init(struct ata_pro

hpriv->cap = readl(mmio + HOST_CAP);
hpriv->port_map = readl(mmio + HOST_PORTS_IMPL);
- probe_ent->n_ports = (hpriv->cap & 0x1f) + 1;
+
+ /* determine number of ports and port table */
+ n_ports = 0;
+ for (i = 0; i < AHCI_MAX_PORTS; i++)
+ if (hpriv->port_map & (1 << i))
+ hpriv->port_tbl[n_ports++] = i;
+
+ i = (hpriv->cap & 0x1f) + 1;
+ if (n_ports > i) {
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "n_ports in PI (%d) > CAP.NP (%d), using %d\n",
+ n_ports, i, i);
+ n_ports = i;
+ }
+
+ if (n_ports == 0) {
+ dev_printk(KERN_ERR, &pdev->dev, "0 port implemented\n");
+ return -EINVAL;
+ }
+
+ probe_ent->n_ports = n_ports;

VPRINTK("cap 0x%x port_map 0x%x n_ports %d\n",
hpriv->cap, hpriv->port_map, probe_ent->n_ports);
@@ -1166,16 +1196,18 @@ static int ahci_host_init(struct ata_pro
}

for (i = 0; i < probe_ent->n_ports; i++) {
+ int port_idx = hpriv->port_tbl[i];
+
#if 0 /* BIOSen initialize this incorrectly */
if (!(hpriv->port_map & (1 << i)))
continue;
#endif

- port_mmio = ahci_port_base(mmio, i);
+ port_mmio = ahci_port_base(mmio, port_idx);
VPRINTK("mmio %p port_mmio %p\n", mmio, port_mmio);

ahci_setup_port(&probe_ent->port[i],
- (unsigned long) mmio, i);
+ (unsigned long) mmio, port_idx);

/* make sure port is not active */
tmp = readl(port_mmio + PORT_CMD);
@@ -1214,7 +1246,7 @@ #endif
if (tmp)
writel(tmp, port_mmio + PORT_IRQ_STAT);

- writel(1 << i, mmio + HOST_IRQ_STAT);
+ writel(1 << port_idx, mmio + HOST_IRQ_STAT);
}

tmp = readl(mmio + HOST_CTL);
diff --git a/include/linux/libata.h b/include/linux/libata.h


--
tejun

2006-09-18 03:21:25

by Robin H. Johnson

[permalink] [raw]
Subject: Re: 2.6.18-rc7-git1: AHCI not seeing devices on ICH8 mobo (DG965RY)

On Sun, Sep 17, 2006 at 04:49:29PM +0900, Tejun Heo wrote:
> On Sat, Sep 16, 2006 at 02:08:57PM -0700, Robin H. Johnson wrote:
> > I recompiled libata and AHCI using the ATA_DEBUG and ATA_VERBOSE_DEBUG
> > defines, and got an interesting trace.
> >
> > In specific, look at port_idx 2/3, being all zeros in ahci_host_init.
> >
> > I'm digging into it further now, but something makes me suspect that
> > base addresses for ports 3/4 are wrong.
> >
> > Full file at:
> > http://orbis-terrarum.net/~robbat2/x86_64-mmconfig-failure/2.6.18-rc7-git1-libata-ahci-verbose-failure.dmesg
>
> Can you please try the attached patch?
Yes your patch fixes it perfectly - it's a better version of an almost
working fix I hacked up after my previous email.

Some patch review comments below as well.

Signed-off-by: Robin H. Johnson <[email protected]>

> @@ -186,9 +187,11 @@ struct ahci_host_priv {
> unsigned long flags;
> u32 cap; /* cache of HOST_CAP register */
> u32 port_map; /* cache of HOST_PORTS_IMPL reg */
> + int port_tbl[AHCI_MAX_PORTS];
> };
maybe u8 instead of int?
also a comment - /* mapping of port_idx to the implemented port */

> + if (n_ports == 0) {
> + dev_printk(KERN_ERR, &pdev->dev, "0 port implemented\n");
> + return -EINVAL;
> + }
Use plural form (0 ports), or negative (No ports) instead.

--
Robin Hugh Johnson
E-Mail : [email protected]
GnuPG FP : 11AC BA4F 4778 E3F6 E4ED F38E B27B 944E 3488 4E85


Attachments:
(No filename) (1.41 kB)
(No filename) (232.00 B)
Download all attachments

2006-09-18 03:34:51

by Tejun Heo

[permalink] [raw]
Subject: Re: 2.6.18-rc7-git1: AHCI not seeing devices on ICH8 mobo (DG965RY)

Robin H. Johnson wrote:
> Yes your patch fixes it perfectly - it's a better version of an almost
> working fix I hacked up after my previous email.
>
> Some patch review comments below as well.
>
> Signed-off-by: Robin H. Johnson <[email protected]>
>
>> @@ -186,9 +187,11 @@ struct ahci_host_priv {
>> unsigned long flags;
>> u32 cap; /* cache of HOST_CAP register */
>> u32 port_map; /* cache of HOST_PORTS_IMPL reg */
>> + int port_tbl[AHCI_MAX_PORTS];
>> };
> maybe u8 instead of int?

Yeah, I like that.

> also a comment - /* mapping of port_idx to the implemented port */

Okay.

>> + if (n_ports == 0) {
>> + dev_printk(KERN_ERR, &pdev->dev, "0 port implemented\n");
>> + return -EINVAL;
>> + }
> Use plural form (0 ports), or negative (No ports) instead.

And, okay.

Jeff, we've been ignoring PI in ahci_host_init()...

for (i = 0; i < probe_ent->n_ports; i++) {
#if 0 /* BIOSen initialize this incorrectly */
if (!(hpriv->port_map & (1 << i)))
continue;
#endif

The comment suggests that some BIOSen initialize PI incorrectly which
will probably result in undetected ports. Is this true? Would it be
dangerous to honor PI on some controllers? If so, PI should be used
only for controllers which does non-linear port mapping.

Thanks.

--
tejun

2006-09-19 03:53:44

by Jeff Garzik

[permalink] [raw]
Subject: Re: 2.6.18-rc7-git1: AHCI not seeing devices on ICH8 mobo (DG965RY)

Tejun Heo wrote:
> Jeff, we've been ignoring PI in ahci_host_init()...
>
> for (i = 0; i < probe_ent->n_ports; i++) {
> #if 0 /* BIOSen initialize this incorrectly */
> if (!(hpriv->port_map & (1 << i)))
> continue;
> #endif
>
> The comment suggests that some BIOSen initialize PI incorrectly which
> will probably result in undetected ports. Is this true? Would it be
> dangerous to honor PI on some controllers? If so, PI should be used
> only for controllers which does non-linear port mapping.


The core problem is that this register is write-once after reset, i.e.
BIOS-initialized. And my experience with pre-production machines has
been that after reset _by the driver_, the register was useless until
initialized to a value... _by the driver_. Which defeats the purpose of
the register.

So the info contained in the register is quite useful -- when info is
contained in the register. :)

Now, granted, I have only seen this on pre-production machines, hence
the #if 0. But also, since the code has been disabled in production, we
don't know how effective it is across all platforms, and we _do_ know
that it is ineffective if used directly after a reset. The write-once
behavior is documented, and normal.

We can't really know which controllers have a non-linear port mapping,
because that is dependent on both the silicon and whether or not the
chip is connected to port X[0-31]. The BIOS knows this, of course :)

We can try to enable the code, but I worry that it will fail in
situations such as kexec.

Jeff


2006-09-19 04:11:41

by Robin H. Johnson

[permalink] [raw]
Subject: Re: 2.6.18-rc7-git1: AHCI not seeing devices on ICH8 mobo (DG965RY)

On Mon, Sep 18, 2006 at 11:53:39PM -0400, Jeff Garzik wrote:
> We can't really know which controllers have a non-linear port mapping,
> because that is dependent on both the silicon and whether or not the
> chip is connected to port X[0-31]. The BIOS knows this, of course :)
I noticed that in my case, when the wrong ioports were probed (base +
port_idx*offset) for port_idx being 2/3 - all of the return values were
zero, instead of the expected values.

You could probably use this to detect cases where PI claims a port is
not present, but it really is.

--
Robin Hugh Johnson
E-Mail : [email protected]
GnuPG FP : 11AC BA4F 4778 E3F6 E4ED F38E B27B 944E 3488 4E85


Attachments:
(No filename) (681.00 B)
(No filename) (232.00 B)
Download all attachments

2006-09-19 06:06:43

by Jeff Garzik

[permalink] [raw]
Subject: Re: 2.6.18-rc7-git1: AHCI not seeing devices on ICH8 mobo (DG965RY)

I don't really like this port_tbl approach. I think it complicates
things too much.

Direct indexing should be fine. For the non-linear case, just make sure
the non-existent ports are always dummy ports. If the driver directly
references a port we know isn't there, that's just an AHCI bug to be
fixed...




2006-09-19 06:24:53

by Tejun Heo

[permalink] [raw]
Subject: Re: 2.6.18-rc7-git1: AHCI not seeing devices on ICH8 mobo (DG965RY)

Jeff Garzik wrote:
> I don't really like this port_tbl approach. I think it complicates
> things too much.
>
> Direct indexing should be fine. For the non-linear case, just make sure
> the non-existent ports are always dummy ports. If the driver directly
> references a port we know isn't there, that's just an AHCI bug to be
> fixed...

I thought about that too, but it will end up with ata1-6 with dummy 3
and 4 while the BIOS shows continuous 4 ports. I wanted avoid this
discrepancy as it could cause confusion to users.

The other option is adding pp->port_idx to record hw port index. It
does make the code a bit simpler. What do you think about this?

Thanks.

--
tejun

2006-09-19 06:25:23

by Robin H. Johnson

[permalink] [raw]
Subject: Re: 2.6.18-rc7-git1: AHCI not seeing devices on ICH8 mobo (DG965RY)

On Tue, Sep 19, 2006 at 02:06:40AM -0400, Jeff Garzik wrote:
> I don't really like this port_tbl approach. I think it complicates
> things too much.
>
> Direct indexing should be fine. For the non-linear case, just make sure
> the non-existent ports are always dummy ports. If the driver directly
> references a port we know isn't there, that's just an AHCI bug to be
> fixed...
So you think we should ignore CAP.NP and instead set our n_ports to the
position of the left-most 1-bit in PI? That would break in your case of
PI containing invalid data.

I do think a mapping is the way to go, but the implementation can
perhaps be improved a little - so that the table is local to the
probing, and is not used thereafter - because the data is stored in the
ata_ports->private_data instead.

For my hardware, note that CAP.NP was 4, and PI was (binary) 110011. By
my reading of the spec, this is correct - and says there are 4 usable
ports, located at addresses 0, 1, 4, 5.

Looking at the motherboard more closely, I do find two other unpopulated
SATA headers (also lacking the various electrical bits, so not trivial
to hack on).

--
Robin Hugh Johnson
E-Mail : [email protected]
GnuPG FP : 11AC BA4F 4778 E3F6 E4ED F38E B27B 944E 3488 4E85


Attachments:
(No filename) (1.23 kB)
(No filename) (232.00 B)
Download all attachments

2006-09-25 21:39:33

by Robin H. Johnson

[permalink] [raw]
Subject: Re: 2.6.18-rc7-git1: AHCI not seeing devices on ICH8 mobo (DG965RY)

On Tue, Sep 19, 2006 at 03:24:46PM +0900, Tejun Heo wrote:
> Jeff Garzik wrote:
> >I don't really like this port_tbl approach. I think it complicates
> >things too much.
> >
> >Direct indexing should be fine. For the non-linear case, just make sure
> >the non-existent ports are always dummy ports. If the driver directly
> >references a port we know isn't there, that's just an AHCI bug to be
> >fixed...
>
> I thought about that too, but it will end up with ata1-6 with dummy 3
> and 4 while the BIOS shows continuous 4 ports. I wanted avoid this
> discrepancy as it could cause confusion to users.
>
> The other option is adding pp->port_idx to record hw port index. It
> does make the code a bit simpler. What do you think about this?
*bump*

Jeff - any opinions on Tejun's or my last posts on this, or do you want
to see some code for the idea.

--
Robin Hugh Johnson
E-Mail : [email protected]
GnuPG FP : 11AC BA4F 4778 E3F6 E4ED F38E B27B 944E 3488 4E85


Attachments:
(No filename) (985.00 B)
(No filename) (232.00 B)
Download all attachments

2006-12-05 06:21:09

by Kurtis D. Rader

[permalink] [raw]
Subject: Re: 2.6.18-rc7-git1: AHCI not seeing devices on ICH8 mobo (DG965RY)

On Sun, 2006-09-17 16:49:29, Tejun Heo wrote:
> Can you please try the attached patch?

I'm seeing the same problem reported by Robin Johnson: that is, the
first two SATA disks are seen by the Linux kernel but the third is not.
The third drive is seen by the BIOS.

I attempted to apply the patch posted by Tejun Heo on 2006-09-17 but it
won't apply against a 2.6.19 kernel. The patch-2.6.19-git6 diff doesn't
contain the needed changes.

Is there a patch compatible with the current source tree? The reason I
ask is that I installed a Intel DP964LT mainboard in my worksation today
(to resolve a SATA silent data corruption problem with a ASUS nVidia
nForce 4 mainboard). Should I try to adapt the patch from September for
the 2.6.19 kernel source or is there an easier option? I've already spent
nearly a week debugging the silent data corruption problem that caused me
to switch mainboards and CPUs and I'm eager to get back to my real job
of solving my customer's problems rather than mine :-)

--
Kurtis D. Rader, Linux level 3 support email: [email protected]
IBM Integrated Technology Services DID: +1 503-578-3714
15300 SW Koll Pkwy, MS RHE2-O2 service: 800-IBM-SERV
Beaverton, OR 97006-6063 http://www.ibm.com