Re: data sheet for SATA drive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Apr 7, 2010 at 1:49 PM, Onkar Mahajan <kern.devel@xxxxxxxxx> wrote:
> Greg,
>       My intention is to learn to write a SATA driver with the hardware
> that I have. I have a SATA hard drive from Western Digital (MDL :
> WD800JD-75MSAS)
> and SATA controller (Intel 82801 GB/GR/GH ( ICH7 family ) for which the
> drivers are already
> present. I want to unload the drivers and reverse engineer them and make
> them working.
> Is it a good way to learn SATA/SCSI drivers ?? Please guide me with your
> invaluable experience.
>

Not sure if it is useful to you or not, but the following are
extracted from my emails to my students working on the SATA drivers
right now :-) (sorry I did not have time to edit it...but if u
learning....just absorbed everything :-), and if u have time, find the
differences between the current drivers and those of the datasheet, so
as to add in new functionalities to the drivers.
but....but...but.....this is easier said than done....even for
me!!!!).

Looking up the datasheet (WD u must find for yourself):

http://www.seagate.com/support/disc/manuals/sata/100402371a.pdf

Looking further into page 47:

Supported ATA commands

The following table lists Serial ATA standard commands that the drive
supports. For a detailed description of the ATA commands, refer to the
Serial ATA: High Speed Serialized AT Attachment specification. See
“S.M.A.R.T. commands” on page 44.for details and subcommands used in
the S.M.A.R.T. implementation.

A list of all the command supported is listed:

Identify Device
ECH
Idle
97H or E3H

which is inside drivers/ata/libata-eh.c:

2135 const char *ata_get_cmd_descript(u8 command)
2136 {
2137 #ifdef CONFIG_ATA_VERBOSE_ERROR
2138         static const struct
2139         {
2140                 u8 command;
2141                 const char *text;
2142         } cmd_descr[] = {
2143                 { ATA_CMD_DEV_RESET,            "DEVICE RESET" },
2144                 { ATA_CMD_CHK_POWER,            "CHECK POWER MODE" },
2145                 { ATA_CMD_STANDBY,              "STANDBY" },
2146                 { ATA_CMD_IDLE,                 "IDLE" },
2147                 { ATA_CMD_EDD,                  "EXECUTE DEVICE
DIAGNOSTIC"      },
2148                 { ATA_CMD_DOWNLOAD_MICRO,       "DOWNLOAD MICROCODE" },
2149                 { ATA_CMD_NOP,                  "NOP" },
2150                 { ATA_CMD_FLUSH,                "FLUSH CACHE" },
2151                 { ATA_CMD_FLUSH_EXT,            "FLUSH CACHE EXT" },
2152                 { ATA_CMD_ID_ATA,               "IDENTIFY DEVICE"
},========================>
2153                 { ATA_CMD_ID_ATAPI,             "IDENTIFY PACKET DEVICE" },

and this is called inside libata-acpi.c:

 663 /**
 664  * ata_acpi_run_tf - send taskfile registers to host controller
 665  * @dev: target ATA device
 666  * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7)
 667  *
 668  * Outputs ATA taskfile to standard ATA host controller using MMIO
 669  * or PIO as indicated by the ATA_FLAG_MMIO flag.
 670  * Writes the control, feature, nsect, lbal, lbam, and lbah registers.
 671  * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect,
 672  * hob_lbal, hob_lbam, and hob_lbah.
 673  *
 674  * This function waits for idle (!BUSY and !DRQ) after writing
 675  * registers.  If the control register has a new value, this
 676  * function also waits for idle after writing control and before
 677  * writing the remaining registers.
 678  *
 679  * LOCKING:
 680  * EH context.
 681  *
 682  * RETURNS:
 683  * 1 if command is executed successfully.  0 if ignored, rejected or
 684  * filtered out, -errno on other errors.
 685  */
 686 static int ata_acpi_run_tf(struct ata_device *dev,
 687                            const struct ata_acpi_gtf *gtf,
 688                            const struct ata_acpi_gtf *prev_gtf)
 689 {
 690         struct ata_taskfile *pptf = NULL;
 691         struct ata_taskfile tf, ptf, rtf;
 692         unsigned int err_mask;
 693         const char *level;
 694         const char *descr;
 695         char msg[60];
 696         int rc;
 697
 698         if ((gtf->tf[0] == 0) && (gtf->tf[1] == 0) && (gtf->tf[2] == 0)
 699             && (gtf->tf[3] == 0) && (gtf->tf[4] == 0) && (gtf->tf[5] == 0)
 700             && (gtf->tf[6] == 0))
 701                 return 0;
 702
 703         ata_acpi_gtf_to_tf(dev, gtf, &tf);
 704         if (prev_gtf) {
 705                 ata_acpi_gtf_to_tf(dev, prev_gtf, &ptf);
 706                 pptf = &ptf;
 707         }
 708
 709         if (!ata_acpi_filter_tf(dev, &tf, pptf)) {
 710                 rtf = tf;
 711                 err_mask = ata_exec_internal(dev, &rtf, NULL,
 712                                              DMA_NONE, NULL, 0, 0);
 713
 714                 switch (err_mask) {
 715                 case 0:
 716                         level = KERN_DEBUG;
 717                         snprintf(msg, sizeof(msg), "succeeded");
 718                         rc = 1;
 719                         break;
 720
 721                 case AC_ERR_DEV:
 722                         level = KERN_INFO;
 723                         snprintf(msg, sizeof(msg),
 724                                  "rejected by device (Stat=0x%02x
Err=0x%02x)",
 725                                  rtf.command, rtf.feature);
 726                         rc = 0;
 727                         break;
 728
 729                 default:
 730                         level = KERN_ERR;
 731                         snprintf(msg, sizeof(msg),
 732                                  "failed (Emask=0x%x Stat=0x%02x
Err=0x%02x)",
 733                                  err_mask, rtf.command, rtf.feature);
 734                         rc = -EIO;
 735                         break;
 736                 }
 737         } else {
 738                 level = KERN_INFO;
 739                 snprintf(msg, sizeof(msg), "filtered out");
 740                 rc = 0;
 741         }
 742         descr = ata_get_cmd_descript(tf.command);
 743


And the systemtap tracing:

ata_scsi_queuecmd
 0xffffffff8162c26d : ata_scsi_queuecmd+0x0/0x98 [kernel]
 0xffffffff81515625 : scsi_dispatch_cmd+0x1e1/0x25f [kernel]
 0xffffffff8151b43b : scsi_request_fn+0x3f2/0x53b [kernel]
 0xffffffff813bb641 : __generic_unplug_device+0x35/0x39 [kernel]
 0xffffffff813bb673 : generic_unplug_device+0x2e/0x3e [kernel]
 0xffffffff813b63a6 : blk_unplug+0x48/0x4d [kernel]
 0xffffffff813b63bd : blk_backing_dev_unplug+0x12/0x14 [kernel]
 0xffffffff8114084f : sync_buffer+0x3e/0x47 [kernel]
 0xffffffff81d9b33c : __wait_on_bit+0x4c/0x7e [kernel]
 0xffffffff81d9b3dd : out_of_line_wait_on_bit+0x6f/0x7c [kernel]
 0xffffffff81140774 : __wait_on_buffer+0x24/0x26 [kernel]
 0xffffffff81205523 : wait_on_buffer+0x3d/0x41 [kernel]
 0xffffffff81206138 : journal_commit_transaction+0xb42/0x117a [kernel]
 0xffffffff8120961a : kjournald+0x102/0x25f [kernel]
 0xffffffff81083c43 : kthread+0x9d/0xa5 [kernel]
 0xffffffff81030634 : kernel_thread_helper+0x4/0x10 [kernel]
 0xffffffff81d9d53c : restore_args+0x0/0x30 [kernel] (inexact)
 0xffffffff81083ba6 : kthread+0x0/0xa5 [kernel] (inexact)
 0xffffffff81030630 : kernel_thread_helper+0x0/0x10 [kernel] (inexact)

ata_scsi_find_dev
 0xffffffff816292b1 : ata_scsi_find_dev+0x0/0x39 [kernel]
 0xffffffff8162c2b6 : ata_scsi_queuecmd+0x49/0x98 [kernel]
 0xffffffff81515625 : scsi_dispatch_cmd+0x1e1/0x25f [kernel]
 0xffffffff8151b43b : scsi_request_fn+0x3f2/0x53b [kernel]
 0xffffffff813bb641 : __generic_unplug_device+0x35/0x39 [kernel]
 0xffffffff813bb673 : generic_unplug_device+0x2e/0x3e [kernel]
 0xffffffff813b63a6 : blk_unplug+0x48/0x4d [kernel]
 0xffffffff813b63bd : blk_backing_dev_unplug+0x12/0x14 [kernel]
 0xffffffff8114084f : sync_buffer+0x3e/0x47 [kernel]
 0xffffffff81d9b33c : __wait_on_bit+0x4c/0x7e [kernel]
 0xffffffff81d9b3dd : out_of_line_wait_on_bit+0x6f/0x7c [kernel]
 0xffffffff81140774 : __wait_on_buffer+0x24/0x26 [kernel]
 0xffffffff81205523 : wait_on_buffer+0x3d/0x41 [kernel]
 0xffffffff81206138 : journal_commit_transaction+0xb42/0x117a [kernel]
 0xffffffff8120961a : kjournald+0x102/0x25f [kernel]
 0xffffffff81083c43 : kthread+0x9d/0xa5 [kernel]
 0xffffffff81030634 : kernel_thread_helper+0x4/0x10 [kernel]
 0xffffffff81d9d53c : restore_args+0x0/0x30 [kernel] (inexact)
 0xffffffff81083ba6 : kthread+0x0/0xa5 [kernel] (inexact)
 0xffffffff81030630 : kernel_thread_helper+0x0/0x10 [kernel] (inexact)

__ata_scsi_find_dev
 0xffffffff816291ff : __ata_scsi_find_dev+0x0/0xb2 [kernel]
 0xffffffff816292bf : ata_scsi_find_dev+0xe/0x39 [kernel]
 0xffffffff8162c2b6 : ata_scsi_queuecmd+0x49/0x98 [kernel]
 0xffffffff81515625 : scsi_dispatch_cmd+0x1e1/0x25f [kernel]
 0xffffffff8151b43b : scsi_request_fn+0x3f2/0x53b [kernel]
 0xffffffff813bb641 : __generic_unplug_device+0x35/0x39 [kernel]

which is output by:

probe kernel.function("*@drivers/ata/libata*.c") {
        printf("%s\n", probefunc());
        print_backtrace();
        printf("\n");
}

-- 
Regards,
Peter Teoh

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ



[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux