Skip to contentSkip to conversation

sata_nv: fix ATAPI issues with memory over 4GB (v3)

PATCH Applied Robert Hancock 3 participants 8 messages Nov 14, 2007 – Nov 20, 2007 libata

lore
Share & tools
lore
#0 lore raw

PATCH 2/2 sata_nv: fix ATAPI issues with memory over 4GB (v3)

This fixes some problems with ATAPI devices on nForce4 controllers in ADMA mode on systems with memory located above 4GB. We need to delay setting the 64-bit DMA mask until the PRD table and padding buffer are allocated so that they don't get allocated above 4GB and break legacy mode (which is needed for ATAPI devices).

drivers/ata/sata_nv.c renamed from drivers/ata/sata_nv.c.before +16 -7
@@ -247,6 +247,7 @@
 	void __iomem		*ctl_block;
 	void __iomem		*gen_block;
 	void __iomem		*notifier_clear_block;
+	u64			adma_dma_mask;
 	u8			flags;
 	int			last_issue_ncq;
 };
@@ -748,7 +749,7 @@
 		adma_enable = 0;
 		nv_adma_register_mode(ap);
 	} else {
-		bounce_limit = *ap->dev->dma_mask;
+		bounce_limit = pp->adma_dma_mask;
 		segment_boundary = NV_ADMA_DMA_BOUNDARY;
 		sg_tablesize = NV_ADMA_SGTBL_TOTAL_LEN;
 		adma_enable = 1;
@@ -763,6 +764,11 @@
 		config_mask = NV_MCP_SATA_CFG_20_PORT0_EN |
 			      NV_MCP_SATA_CFG_20_PORT0_PWB_EN;
 
+	/* Set appropriate DMA mask. */
+	rc = pci_set_dma_mask(pdev, bounce_limit);
+	if (rc)
+		return rc;
+
 	if (adma_enable) {
 		new_reg = current_reg | config_mask;
 		pp->flags &= ~NV_ADMA_ATAPI_SETUP_COMPLETE;
@@ -1134,6 +1140,7 @@
 	void *mem;
 	dma_addr_t mem_dma;
 	void __iomem *mmio;
+	struct pci_dev *pdev = to_pci_dev(dev);
 	u16 tmp;
 
 	VPRINTK("ENTER\n");
@@ -1153,6 +1160,14 @@
 	pp->notifier_clear_block = pp->gen_block +
 	       NV_ADMA_NOTIFIER_CLEAR + (4 * ap->port_no);
 
+	/* Now that the legacy PRD and padding buffer are allocated we can
+	   safely raise the DMA mask to allocate the CPB/APRD table. */
+	pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+	pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+	/* Store the mask that was actually used so we can restore it later
+	   if needed */
+	pp->adma_dma_mask = *dev->dma_mask;
+
 	mem = dmam_alloc_coherent(dev, NV_ADMA_PORT_PRIV_DMA_SZ,
 				  &mem_dma, GFP_KERNEL);
 	if (!mem)
@@ -2408,12 +2423,6 @@
 	hpriv->type = type;
 	host->private_data = hpriv;
 
-	/* set 64bit dma masks, may fail */
-	if (type == ADMA) {
-		if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0)
-			pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
-	}
-
 	/* request and iomap NV_MMIO_BAR */
 	rc = pcim_iomap_regions(pdev, 1 << NV_MMIO_BAR, DRV_NAME);
 	if (rc)
Acked-by on v1 2/2
#1 lore raw
Quoted 7 lines · On Tue, 13 Nov 2007 22:15:51 -0600 Robert Hancock <[email protected]> wrote:

This fixes some problems with ATAPI devices on nForce4 controllers in ADMA mode on systems with memory located above 4GB. We need to delay setting the 64-bit DMA mask until the PRD table and padding buffer are allocated so that they don't get allocated above 4GB and break legacy mode (which is needed for ATAPI devices).

Applied
#2 lore raw
In reply to Robert Hancock
Quoted 7 lines · Robert Hancock

This fixes some problems with ATAPI devices on nForce4 controllers in ADMA mode on systems with memory located above 4GB. We need to delay setting the 64-bit DMA mask until the PRD table and padding buffer are allocated so that they don't get allocated above 4GB and break legacy mode (which is needed for ATAPI devices).

applied to #tj-upstream-fixes.

Signature · 1 line
tejun
#3 lore raw
Quoted 11 lines · Tejun Heo
Quoted 7 lines · Robert Hancock

This fixes some problems with ATAPI devices on nForce4 controllers in ADMA mode on systems with memory located above 4GB. We need to delay setting the 64-bit DMA mask until the PRD table and padding buffer are allocated so that they don't get allocated above 4GB and break legacy mode (which is needed for ATAPI devices).

applied to #tj-upstream-fixes.

I have a report that these patches crashed but the previous patch worked:

https://bugzilla.redhat.com/show_bug.cgi?id=351451

So there may still be a problem here.

#4 lore raw
Quoted 13 lines · Robert Hancock
Quoted 12 lines · Tejun Heo
Quoted 10 lines · Robert Hancock

This fixes some problems with ATAPI devices on nForce4 controllers in ADMA mode
on systems with memory located above 4GB. We need to delay setting the 64-bit
DMA mask until the PRD table and padding buffer are allocated so that they don't
get allocated above 4GB and break legacy mode (which is needed for ATAPI devices).

Quoted 8 lines
Quoted 2 lines

applied to #tj-upstream-fixes.

I have a report that these patches crashed but the previous patch worked:

https://bugzilla.redhat.com/show_bug.cgi?id=351451

So there may still be a problem here.

Hmmm... The change seemed safe to me. Anyways, dropping the patch for now. Please re-send later. Also, please format patch description such that it fits in 80c.

Thanks.

Signature · 1 line
tejun
#5 lore raw
In reply to Robert Hancock
Quoted 13 lines · Robert Hancock
Quoted 12 lines · Tejun Heo
Quoted 10 lines · Robert Hancock

This fixes some problems with ATAPI devices on nForce4 controllers in ADMA mode
on systems with memory located above 4GB. We need to delay setting the 64-bit
DMA mask until the PRD table and padding buffer are allocated so that they don't
get allocated above 4GB and break legacy mode (which is needed for ATAPI devices).

Quoted 8 lines
Quoted 2 lines

applied to #tj-upstream-fixes.

I have a report that these patches crashed but the previous patch worked:

https://bugzilla.redhat.com/show_bug.cgi?id=351451

So there may still be a problem here.

Any progress?

Signature · 1 line
tejun
#6 lore raw
Quoted 15 lines · Tejun Heo
Quoted 14 lines · Robert Hancock
Quoted 13 lines · Tejun Heo
Quoted 10 lines · Robert Hancock

This fixes some problems with ATAPI devices on nForce4 controllers in ADMA mode
on systems with memory located above 4GB. We need to delay setting the 64-bit
DMA mask until the PRD table and padding buffer are allocated so that they don't
get allocated above 4GB and break legacy mode (which is needed for ATAPI devices).

applied to #tj-upstream-fixes.

Quoted 7 lines
Quoted 5 lines

I have a report that these patches crashed but the previous patch worked:

https://bugzilla.redhat.com/show_bug.cgi?id=351451

So there may still be a problem here.

Any progress?

It looks like the problem is that even though we set the DMA mask after we allocate the PRD and pad buffers, when the other port is set up, the DMA mask is already over 64-bit and so it allocates its buffers over 4GB and fails. I think we just need to explicitly set to 32-bit first, getting the reporter to try that one now.

Signature · 3 lines
Robert Hancock      Saskatoon, SK, Canada
To email, remove "nospam" from [email protected]
Home Page: http://www.roberthancock.com/
#7 lore raw
Quoted 5 lines · Robert Hancock

It looks like the problem is that even though we set the DMA mask after we allocate the PRD and pad buffers, when the other port is set up, the DMA mask is already over 64-bit and so it allocates its buffers over 4GB and fails. I think we just need to explicitly set to 32-bit first, getting the reporter to try that one now.

Ah.. right. That makes sense. Thanks.

Signature · 1 line
tejun