Thank you very much sir. That was a good advise. 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 <htmldevelo...@gmail.com> wrote: > On Wed, Apr 7, 2010 at 1:49 PM, Onkar Mahajan <kern.de...@gmail.com> > 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 >