Re: libata/PATA: GPCMD_SET_STREAMING via SG_IO does nothing

Previous thread: [BUGS][PATCH] Fixes to the BFS filesystem driver by Dmitri Vorobiev on Tuesday, November 13, 2007 - 9:32 am. (2 messages)

Next thread: [PATCH] FRV: Fix the extern declaration of kallsyms_num_syms [try #2] by David Howells on Tuesday, November 13, 2007 - 9:53 am. (3 messages)
From: Sebastian Kemper
Date: Tuesday, November 13, 2007 - 9:43 am

Hi all,

while trying to limit the speed of DVD drives during DVD playback I've
come under the impression that GPCMD_SET_STREAMING via SG_IO doesn't yet
work with libata/PATA (AMD/NVIDIA PATA support). I tested on an NForce2
board (all IDE, no SATA) and kernel 2.6.22.12. When I use the "old" ATA
kernel driver my drive slows down, with libata it doesn't. Is this a
known issue or has this slipped by unnoticed?

I tried with mplayer dvd:// -dvd-device /dev/sr0 -dvd-speed BTW . I get
no errors in syslog/dmesg. Also mplayer doesn't report a problem (so
ioctl(fd, SG_IO, &sghdr) doesn't have a return < 0).

Regards
Sebastian
From: Alan Cox
Date: Tuesday, November 13, 2007 - 2:22 pm

It isn't a known issue, and it suprises me as SG_IO basically passes
commands through to the drive. We don't support speed change via xfermode

Do you have a simple code example that shows the problem ?
-

From: Sebastian Kemper
Date: Tuesday, November 13, 2007 - 4:28 pm

Hi Alan!


http://svn.mplayerhq.hu/mplayer/trunk/stream/stream_dvd.c?view=markup

See dvd_set_speed(). The drive I'm using is an Optiarc DVD RW AD-7170A.
With the "old" ATA driver dvd_set_speed() works, with libata it doesn't.

Regards
Sebastian
-

From: Sebastian Kemper
Date: Wednesday, November 14, 2007 - 5:11 am

Hello Alan,

in the meantime I tried the kernels 2.6.23.1 as well as 2.6.24-rc2. Both
show the same behaviour when using libata with AMD/NVIDIA PATA support:
GPCMD_SET_STREAMING via SG_IO doesn't have any effect. With these two
kernels I didn't try the "old" ATA driver - but I assume it would've
worked out (changing your system from ATA to libata and vice versa
turned out to be quite time consuming ;)).

Regards
Sebastian
-

From: Mark Lord
Date: Wednesday, November 14, 2007 - 8:09 am

..

I think the problem here might be that libata doesn't actually support SG_IO
for ATAPI drives prior to 2.6.24 (ugh).

Try it with a 2.6.24-rc* kernel from kernel.org, or back-patch the ATA_16
SG_IO support into your older kernel.

Cheers
-

From: Sebastian Kemper
Date: Wednesday, November 14, 2007 - 8:38 am

Hi Mark,

I already tried 2.6.24-rc2 and it didn't work, see my last reply:
http://marc.info/?l=linux-kernel&m=119504244805467&w=2

Regards
Sebastian
-

From: Mark Lord
Date: Wednesday, November 14, 2007 - 9:00 am

..
Yeah, I'm a bit drowsy this morning -- the set speed command
doesn't use ATA_16, so it should work with any kernel.

I'll try it here soon-ish, since I need to update "hdparm -E" for libata anyway.

Cheers
-

From: Mark Lord
Date: Wednesday, November 14, 2007 - 10:44 am

Sebastian Kemper reported that issuing CD/DVD commands under libata
is not fully compatible with ide-scsi.  In particular, the GPCMD_SET_STREAMING
was being rejected at the host level in some instances.

The reason is that libata-scsi insists upon the cmd_len field exactly matching
the SCSI opcode being issued, whereas ide-scsi tolerates 12-byte commands
contained within a 16-byte (cmd_len) CDB.

There doesn't seem to be a good reason for us to not be compatible there,
so here is a patch to fix libata-scsi to permit SCSI opcodes so long as
they fit within whatever size CDB is provided.

Signed-off-by: Mark Lord <mlord@pobox.com>
---

Patch is against 2.6.24-rc2-git4.
Sebastian, could you please re-test with this patch
and let us know that it works for you (or not).

--- old/drivers/ata/libata-scsi.c	2007-11-13 23:25:15.000000000 -0500
+++ linux/drivers/ata/libata-scsi.c	2007-11-14 12:32:16.000000000 -0500
@@ -2869,7 +2869,8 @@
 		xlat_func = NULL;
 		if (likely((scsi_op != ATA_16) || !atapi_passthru16)) {
 			/* relay SCSI command to ATAPI device */
-			if (unlikely(scmd->cmd_len > dev->cdb_len))
+			int len = COMMAND_SIZE(scsi_op);
+			if (unlikely(len > scmd->cmd_len || len > dev->cdb_len))
 				goto bad_cdb_len;
 
 			xlat_func = atapi_xlat;
-

From: Alan Cox
Date: Wednesday, November 14, 2007 - 10:50 am

Acked-by: Alan Cox <alan@redhat.com>

-

From: Tejun Heo
Date: Wednesday, November 14, 2007 - 7:26 pm

applied to #tj-upstream-fixes.

-- 
tejun
-

From: Mark Lord
Date: Wednesday, November 14, 2007 - 9:26 am

..

That code is riddled with bugs, by the way.
It fails to close/clean-up on just about every exit path.
But apart from that, it does appear to issue the command.

Another way to the same thing is with "hdparm -E",
which contrary to my earlier posting actually does
..

Can you define "doesn't work" for me?
How can I test this to see if it works one way or another ?

The command issue (ioctl) is not returning -1.

-

From: Mark Lord
Date: Wednesday, November 14, 2007 - 9:41 am

..

Ahh.. got it.  The host_status returned (not checked by that code) was 7,
which means "host error".

In this case, that's because the cmd_len is (16), which is too large for ATAPI.
It needs to be changed to (12) instead.

So this line:  sghdr.cmd_len = 12;
The code (apart from totally mishandling any kinds of errors) works after that.

-ml
-

From: Sebastian Kemper
Date: Wednesday, November 14, 2007 - 10:11 am

Hi Mark!


I don't understand. You seem to use a cmd_len of 16 in hdparm yourself.
And why does it work with the "old" ATA driver and not with libata if

Greetings
Sebastian
-

From: Mark Lord
Date: Wednesday, November 14, 2007 - 10:21 am

..

..

Now that *is* the question.
And the answer appears to be that ide-cd.c ignores the passed-in cmd_len,
and replaces it with:

   cmd_len = COMMAND_SIZE(rq->cmd[0]);

That's a SCSI macro to calculate the correct cmd_len based on the SCSI opcode,
which is very appropriate here.   We should do that too (we don't) in libata.

But not exactly as IDE does it -- that's actually a bug:  the code needs to also
check that the new cmd_len is no larger than the original, or we'll get an Oops.

I'll cook up a patch for that shortly and try it before posting it here.

-ml
-

From: Bartlomiej Zolnierkiewicz
Date: Thursday, November 15, 2007 - 1:55 pm

[Empty message]
From: Sebastian Kemper
Date: Wednesday, November 14, 2007 - 10:16 am

Hi!

There are DVD-ROM drives that don't react to hdparm -E but do react to
SET_STREAMING, for instance some NEC drives.

Regards
Sebastian
-

From: Mark Lord
Date: Wednesday, November 14, 2007 - 10:49 am

..

Mmm.. that's possible.  The NEC drive I have here works with either.

I wonder if an update to sr_select_speed() (inside the SCSI code) is needed?
It currently uses GPCMD_SET_SPEED, with no fallback to GPCMD_SET_STREAMING.

Or I suppose this is best left to userspace.
I may change hdparm to try both opcodes.
-

Previous thread: [BUGS][PATCH] Fixes to the BFS filesystem driver by Dmitri Vorobiev on Tuesday, November 13, 2007 - 9:32 am. (2 messages)

Next thread: [PATCH] FRV: Fix the extern declaration of kallsyms_num_syms [try #2] by David Howells on Tuesday, November 13, 2007 - 9:53 am. (3 messages)