sata_nv times out for BD-ROM iHOS104-08

Submitted by Tejun Heo on Feb. 23, 2010, 2:38 a.m.

Details

Message ID 4B833FA1.8030207@kernel.org
State Not Applicable
Delegated to: David Miller
Headers show

Commit Message

Tejun Heo Feb. 23, 2010, 2:38 a.m.
Hello,

On 02/22/2010 06:28 AM, Cengiz Günay wrote:
> On Sat, Feb 20, 2010 at 8:01 PM, Tejun Heo <tj@kernel.org> wrote:
>> Hmmm... So, DRQ gets cleared?  That's strange.  When then the 18 extra
>> bytes happen?  Can you please try this one?
> 
> It worked!
> 
> $ lsscsi
> ...
> [4:0:0:0]    cd/dvd  ATAPI    iHOS104          WL08  /dev/sr0
> ...
> 
> I was able to read a regular DVD in the drive. According to dmesg the
> negotiated speed was down to UDMA/33, so I am not sure about the
> performance of the drive.

Hmmm.... it could be that the drive is sending more data then
requested and the state machine in the controller doesn't like that
and fails to assert IRQ on the host side.  You're still getting
timeouts on 96 byte dma inquiries.  Can you please this patch?

Comments

Cengiz Günay Feb. 28, 2010, 5:24 p.m.
Hi Tejun,

On Mon, Feb 22, 2010 at 9:38 PM, Tejun Heo <tj@kernel.org> wrote:
> On 02/22/2010 06:28 AM, Cengiz Günay wrote:
>> I was able to read a regular DVD in the drive. According to dmesg the
>> negotiated speed was down to UDMA/33, so I am not sure about the
>> performance of the drive.
>
> Hmmm.... it could be that the drive is sending more data then
> requested and the state machine in the controller doesn't like that
> and fails to assert IRQ on the host side.  You're still getting
> timeouts on 96 byte dma inquiries.  Can you please this patch?

Before and after the swncq-atapi-pio patch I still get awful read
times from the BD-ROM drive:

$ time dd if=/dev/sr0 of=/dev/null bs=64k count=1024
67108864 bytes (67 MB) copied, 106.945 seconds, 628 kB/s
=> real	1m46.977s

Compared to reading the same DVD in my DVD-ROM drive:

$ time dd if=/dev/hda of=/dev/null bs=64k count=1024
67108864 bytes (67 MB) copied, 13.8403 seconds, 4.8 MB/s
=> real	0m13.860s

I attached the full dmesg after the swncq-atapi-pio patch.

-Cengiz

Patch hide | download patch | download mbox

diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 0c82d33..4ad76f1 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -307,6 +307,7 @@  static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
 
 static int nv_hardreset(struct ata_link *link, unsigned int *class,
 			unsigned long deadline);
+static int nv_check_atapi_dma(struct ata_queued_cmd *qc);
 static void nv_nf2_freeze(struct ata_port *ap);
 static void nv_nf2_thaw(struct ata_port *ap);
 static void nv_ck804_freeze(struct ata_port *ap);
@@ -470,6 +471,7 @@  static struct ata_port_operations nv_generic_ops = {
 	.scr_read		= nv_scr_read,
 	.scr_write		= nv_scr_write,
 	.hardreset		= nv_hardreset,
+	.check_atapi_dma	= nv_check_atapi_dma,
 };
 
 static struct ata_port_operations nv_nf2_ops = {
@@ -585,7 +587,7 @@  static const struct ata_port_info nv_port_info[] = {
 	/* SWNCQ */
 	{
 		.flags	        = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-				  ATA_FLAG_NCQ,
+				  ATA_FLAG_NCQ | ATA_FLAG_PIO_POLLING,
 		.pio_mask	= NV_PIO_MASK,
 		.mwdma_mask	= NV_MWDMA_MASK,
 		.udma_mask	= NV_UDMA_MASK,
@@ -1614,6 +1616,24 @@  static int nv_hardreset(struct ata_link *link, unsigned int *class,
 	return -EAGAIN;
 }
 
+#include <scsi/scsi_cmnd.h>
+static int nv_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+	/* Whitelist commands that may use DMA. */
+	switch (qc->scsicmd->cmnd[0]) {
+	case WRITE_12:
+	case WRITE_10:
+	case WRITE_6:
+	case READ_12:
+	case READ_10:
+	case READ_6:
+	case 0xad: /* READ_DVD_STRUCTURE */
+	case 0xbe: /* READ_CD */
+		return 0;
+	}
+	return 1;
+}
+
 static void nv_nf2_freeze(struct ata_port *ap)
 {
 	void __iomem *scr_addr = ap->host->ports[0]->ioaddr.scr_addr;