public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* Q: how to send ATA cmds to USB drive?
@ 2006-05-24  9:22 Herbert Rosmanith
  2006-05-24 11:22 ` Alan Cox
  0 siblings, 1 reply; 7+ messages in thread
From: Herbert Rosmanith @ 2006-05-24  9:22 UTC (permalink / raw)
  To: linux-kernel


good day,

I have a question concerning sending arbitrary ATA commands to an USB
drive.

Currently, I have a particular application which sends special ATA commands
to an IDE drive using IDE_TASKFILE. So far, this works pretty well.

But now I also have to support USB harddisks from the same company.
The USB harddisk uses the same set of ATA commands as the IDE harddisk,
well, at least that's what I suppose.

How do I send ATA commands to this USB drive? I suppose this would be
done via SG_IO (the drive is recognised by linux as usb-storage, of
course), but how exactly does this have to be done? I have already
used SG_IO before to send some MMC commands to cdvd-drives, but I
don't know how to send ATA (such as those from T13) commands with this
interface.

Do you have any kind of advice?

kind regards,
herbert rosmanith



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Q: how to send ATA cmds to USB drive?
  2006-05-24  9:22 Herbert Rosmanith
@ 2006-05-24 11:22 ` Alan Cox
  2006-06-12  9:22   ` Herbert Rosmanith
  0 siblings, 1 reply; 7+ messages in thread
From: Alan Cox @ 2006-05-24 11:22 UTC (permalink / raw)
  To: Herbert Rosmanith; +Cc: linux-kernel

On Mer, 2006-05-24 at 11:22 +0200, Herbert Rosmanith wrote:
> But now I also have to support USB harddisks from the same company.
> The USB harddisk uses the same set of ATA commands as the IDE harddisk,
> well, at least that's what I suppose.

USB storage is a sort of 'pigdin' SCSI. You send SCSI commands to the
USB storage device but you may find anything too clever breaks.



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Q: how to send ATA cmds to USB drive?
       [not found] <6fXQT-16z-11@gated-at.bofh.it>
@ 2006-05-24 23:15 ` Robert Hancock
  2006-05-24 23:33   ` Jeff Garzik
  0 siblings, 1 reply; 7+ messages in thread
From: Robert Hancock @ 2006-05-24 23:15 UTC (permalink / raw)
  To: linux-kernel; +Cc: robomod

Herbert Rosmanith wrote:
> good day,
> 
> I have a question concerning sending arbitrary ATA commands to an USB
> drive.
> 
> Currently, I have a particular application which sends special ATA commands
> to an IDE drive using IDE_TASKFILE. So far, this works pretty well.
> 
> But now I also have to support USB harddisks from the same company.
> The USB harddisk uses the same set of ATA commands as the IDE harddisk,
> well, at least that's what I suppose.
> 
> How do I send ATA commands to this USB drive? I suppose this would be
> done via SG_IO (the drive is recognised by linux as usb-storage, of
> course), but how exactly does this have to be done? I have already
> used SG_IO before to send some MMC commands to cdvd-drives, but I
> don't know how to send ATA (such as those from T13) commands with this
> interface.

Short answer is you likely can't. The USB-to-IDE bridge pretty much 
entirely hides the fact that it's an IDE drive behind it, from the 
host's viewpoint it looks pretty much like SCSI. Maybe if you sent SCSI 
commands to the device it would translate them into the correct ATA 
commands, depending on what exactly you're doing, but that's entirely 
dependent on the bridge chip in question and I would guess most of them 
don't support such fancy operations.

-- 
Robert Hancock      Saskatoon, SK, Canada
To email, remove "nospam" from hancockr@nospamshaw.ca
Home Page: http://www.roberthancock.com/


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Q: how to send ATA cmds to USB drive?
  2006-05-24 23:15 ` Q: how to send ATA cmds to USB drive? Robert Hancock
@ 2006-05-24 23:33   ` Jeff Garzik
  0 siblings, 0 replies; 7+ messages in thread
From: Jeff Garzik @ 2006-05-24 23:33 UTC (permalink / raw)
  To: Robert Hancock; +Cc: linux-kernel, robomod

Robert Hancock wrote:
> Herbert Rosmanith wrote:
>> good day,
>>
>> I have a question concerning sending arbitrary ATA commands to an USB
>> drive.
>>
>> Currently, I have a particular application which sends special ATA 
>> commands
>> to an IDE drive using IDE_TASKFILE. So far, this works pretty well.
>>
>> But now I also have to support USB harddisks from the same company.
>> The USB harddisk uses the same set of ATA commands as the IDE harddisk,
>> well, at least that's what I suppose.
>>
>> How do I send ATA commands to this USB drive? I suppose this would be
>> done via SG_IO (the drive is recognised by linux as usb-storage, of
>> course), but how exactly does this have to be done? I have already
>> used SG_IO before to send some MMC commands to cdvd-drives, but I
>> don't know how to send ATA (such as those from T13) commands with this
>> interface.
> 
> Short answer is you likely can't. The USB-to-IDE bridge pretty much 
> entirely hides the fact that it's an IDE drive behind it, from the 
> host's viewpoint it looks pretty much like SCSI. Maybe if you sent SCSI 
> commands to the device it would translate them into the correct ATA 
> commands, depending on what exactly you're doing, but that's entirely 
> dependent on the bridge chip in question and I would guess most of them 
> don't support such fancy operations.

AFAIK most are not really pure bridges, but really microcontrollers 
running a tiny firmware.  So there is a non-zero chance of there being 
an 'ata passthrough' SCSI command.

I would try to the official ATA_12 and ATA_16 SCSI commands first, to 
see if they do something useful.

	Jeff




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Q: how to send ATA cmds to USB drive?
  2006-05-24 11:22 ` Alan Cox
@ 2006-06-12  9:22   ` Herbert Rosmanith
  2006-06-12 10:02     ` Herbert Rosmanith
  0 siblings, 1 reply; 7+ messages in thread
From: Herbert Rosmanith @ 2006-06-12  9:22 UTC (permalink / raw)
  To: Alan Cox; +Cc: linux-kernel

> > But now I also have to support USB harddisks from the same company.
> > The USB harddisk uses the same set of ATA commands as the IDE harddisk,
> > well, at least that's what I suppose.
> 
> USB storage is a sort of 'pigdin' SCSI. You send SCSI commands to the
> USB storage device but you may find anything too clever breaks.

hm, that depends 
on where "too much cleverness" is implemented.
I just noticed that scsi-commands I send to
via SG_IO get modified underway.

the userland program looks like this:

        memset(cmd,0,16);
        cmd[0]=0x24;
        cmd[1]=0x24;
        cmd[2]=0x01;
        cmd[3]=0x01;

        memset(&ioh,0,sizeof(ioh));
        ioh.interface_id='S';
        ioh.dxfer_direction=SG_DXFER_FROM_DEV;
        ioh.dxferp = buf;
        ioh.dxfer_len = 8;
        ioh.cmdp=cmd;
        ioh.cmd_len=16;
        ioh.sbp=sbuf;
        ioh.mx_sb_len=SG_MAX_SENSE;
        ioh.timeout = 2000;     // 2 sekunden
        ioh.flags = SG_FLAG_DIRECT_IO;

        if ((i=ioctl(fd,SG_IO,&ioh))==-1)
                die("ioctl");

but what's really sent to the device is:

> usb_stor_Bulk_transport
Bulk Command S 0x43425355 T 0x2a L 8 F 0 Trg 0 LUN 0 CL 16
> usb_stor_bulk_transfer_buf (length=31)
 55
 53
 42
 43
 2a
 00
 00
 00
 08
 00
 00
 00
 00
 00
 10
 24
 04
 01
 01
 00
 00
 00
 00
 00
 00
 00
 00
 00
 00
 00
 00

the data really sent is "0x24 0x04 0x01 0x01", which means that 0x20 gets
cleared in byte 2 (for whatever reason).

the specs I have (CY7C68310.pdf from http://www.rockbox.org/twiki/pub/Main/DataSheets/)
say that this field has to be 0x24 for ATACB commands. this is on page12. with the
ATACB, I want to implement TaskFileRead and TaskFileWrite (page 13).
the device is a "Low-Power USB 2.0 ATA/ATPAI Bridge IC".

do you have any idea why the data is modified and how I can prevent this?

kind regards,
herbert rosmanith


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Q: how to send ATA cmds to USB drive?
  2006-06-12  9:22   ` Herbert Rosmanith
@ 2006-06-12 10:02     ` Herbert Rosmanith
  2006-06-12 10:26       ` Herbert Rosmanith
  0 siblings, 1 reply; 7+ messages in thread
From: Herbert Rosmanith @ 2006-06-12 10:02 UTC (permalink / raw)
  To: linux-kernel; +Cc: Alan Cox

> the userland program looks like this:
> 
>         memset(cmd,0,16);
>         cmd[0]=0x24;
>         cmd[1]=0x24;
>         cmd[2]=0x01;
>         cmd[3]=0x01;
...
>         if ((i=ioctl(fd,SG_IO,&ioh))==-1)
>                 die("ioctl");
> 
...
> the data really sent is "0x24 0x04 0x01 0x01", which means that 0x20 gets
> cleared in byte 2 (for whatever reason).
> 
> do you have any idea why the data is modified and how I can prevent this?

ok, got it:

        int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
        ...
                /*
                 * If SCSI-2 or lower, store the LUN value in cmnd.
                 */
                if (cmd->device->scsi_level <= SCSI_2) {
                        cmd->cmnd[1] = (cmd->cmnd[1] & 0x1f) |
                                       (cmd->device->lun << 5 & 0xe0);
                }

hm. now what .... ? If scsi-2 requires this, and the device is scsi-2 (in fact,
cmd->device->scsi_level equals 3, which means SCSI_2) then the device is a violation
of the scsi-specs. do you have any suggestion how to fix this (beside from commenting
the source)

kind regards,
herbert rosmanith


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Q: how to send ATA cmds to USB drive?
  2006-06-12 10:02     ` Herbert Rosmanith
@ 2006-06-12 10:26       ` Herbert Rosmanith
  0 siblings, 0 replies; 7+ messages in thread
From: Herbert Rosmanith @ 2006-06-12 10:26 UTC (permalink / raw)
  To: linux-kernel; +Cc: alan

>         int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
>         ...
>                 /*
>                  * If SCSI-2 or lower, store the LUN value in cmnd.
>                  */
>                 if (cmd->device->scsi_level <= SCSI_2) {
>                         cmd->cmnd[1] = (cmd->cmnd[1] & 0x1f) |
>                                        (cmd->device->lun << 5 & 0xe0);
>                 }
> 
> hm. now what .... ? If scsi-2 requires this, and the device is scsi-2.

actually, the scsi-level reported by the device is *not* 2.

it is set to 2 by "slave_configure" from drivers/usb/storage/scsiglue.c:

static int slave_configure(struct scsi_device *sdev)
{
...
        /* Set the SCSI level to at least 2.  We'll leave it at 3 if that's
         * what is originally reported.  We need this to avoid confusing
         * the SCSI layer with devices that report 0 or 1, but need 10-byte
         * commands (ala ATAPI devices behind certain bridges, or devices
                                              ^^^^^^^^^^^^^^^

the CY7C68310 is exactly that.

         * which simply have broken INQUIRY data).
...

        if (sdev->scsi_level < SCSI_2)
                sdev->scsi_level = sdev->sdev_target->scsi_level = SCSI_2;


kind regards,
h.rosmanith

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2006-06-12 10:31 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <6fXQT-16z-11@gated-at.bofh.it>
2006-05-24 23:15 ` Q: how to send ATA cmds to USB drive? Robert Hancock
2006-05-24 23:33   ` Jeff Garzik
2006-05-24  9:22 Herbert Rosmanith
2006-05-24 11:22 ` Alan Cox
2006-06-12  9:22   ` Herbert Rosmanith
2006-06-12 10:02     ` Herbert Rosmanith
2006-06-12 10:26       ` Herbert Rosmanith

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox