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