I will try to do that. But , If I face difficulties is there
any mailing list wherein I can post SATA related questions.
Thanks & regards,
Onkar
On Fri, Apr 9, 2010 at 8:59 AM, Peter Teoh <htmldeveloper@xxxxxxxxx> wrote:
On Wed, Apr 7, 2010 at 1:49 PM, Onkar Mahajan <kern.devel@xxxxxxxxx> wrote:Not sure if it is useful to you or not, but the following are
> 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.
>
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