| /* |
| * Copyright (C) 2008 Freescale Semiconductor, Inc. |
| * Dave Liu <daveliu@freescale.com> |
| * port from the libata of linux kernel |
| * |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU General Public License as |
| * published by the Free Software Foundation; either version 2 of |
| * the License, or (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
| * MA 02111-1307 USA |
| * |
| */ |
| |
| #include <libata.h> |
| |
| u64 ata_id_n_sectors(u16 *id) |
| { |
| if (ata_id_has_lba(id)) { |
| if (ata_id_has_lba48(id)) |
| return ata_id_u64(id, ATA_ID_LBA48_SECTORS); |
| else |
| return ata_id_u32(id, ATA_ID_LBA_SECTORS); |
| } else { |
| return 0; |
| } |
| } |
| |
| u32 ata_dev_classify(u32 sig) |
| { |
| u8 lbam, lbah; |
| |
| lbam = (sig >> 16) & 0xff; |
| lbah = (sig >> 24) & 0xff; |
| |
| if (((lbam == 0) && (lbah == 0)) || |
| ((lbam == 0x3c) && (lbah == 0xc3))) |
| return ATA_DEV_ATA; |
| |
| if ((lbam == 0x14) && (lbah == 0xeb)) |
| return ATA_DEV_ATAPI; |
| |
| if ((lbam == 0x69) && (lbah == 0x96)) |
| return ATA_DEV_PMP; |
| |
| return ATA_DEV_UNKNOWN; |
| } |
| |
| static void ata_id_string(const u16 *id, unsigned char *s, |
| unsigned int ofs, unsigned int len) |
| { |
| unsigned int c; |
| |
| while (len > 0) { |
| c = id[ofs] >> 8; |
| *s = c; |
| s++; |
| |
| c = id[ofs] & 0xff; |
| *s = c; |
| s++; |
| |
| ofs++; |
| len -= 2; |
| } |
| } |
| |
| void ata_id_c_string(const u16 *id, unsigned char *s, |
| unsigned int ofs, unsigned int len) |
| { |
| unsigned char *p; |
| |
| ata_id_string(id, s, ofs, len - 1); |
| |
| p = s + strnlen((char *)s, len - 1); |
| while (p > s && p[-1] == ' ') |
| p--; |
| *p = '\0'; |
| } |
| |
| void ata_dump_id(u16 *id) |
| { |
| unsigned char serial[ATA_ID_SERNO_LEN + 1]; |
| unsigned char firmware[ATA_ID_FW_REV_LEN + 1]; |
| unsigned char product[ATA_ID_PROD_LEN + 1]; |
| u64 n_sectors; |
| |
| /* Serial number */ |
| ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial)); |
| printf("S/N: %s\n\r", serial); |
| |
| /* Firmware version */ |
| ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware)); |
| printf("Firmware version: %s\n\r", firmware); |
| |
| /* Product model */ |
| ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product)); |
| printf("Product model number: %s\n\r", product); |
| |
| /* Total sectors of device */ |
| n_sectors = ata_id_n_sectors(id); |
| printf("Capablity: %lld sectors\n\r", n_sectors); |
| |
| printf ("id[49]: capabilities = 0x%04x\n" |
| "id[53]: field valid = 0x%04x\n" |
| "id[63]: mwdma = 0x%04x\n" |
| "id[64]: pio = 0x%04x\n" |
| "id[75]: queue depth = 0x%04x\n", |
| id[49], |
| id[53], |
| id[63], |
| id[64], |
| id[75]); |
| |
| printf ("id[76]: sata capablity = 0x%04x\n" |
| "id[78]: sata features supported = 0x%04x\n" |
| "id[79]: sata features enable = 0x%04x\n", |
| id[76], |
| id[78], |
| id[79]); |
| |
| printf ("id[80]: major version = 0x%04x\n" |
| "id[81]: minor version = 0x%04x\n" |
| "id[82]: command set supported 1 = 0x%04x\n" |
| "id[83]: command set supported 2 = 0x%04x\n" |
| "id[84]: command set extension = 0x%04x\n", |
| id[80], |
| id[81], |
| id[82], |
| id[83], |
| id[84]); |
| printf ("id[85]: command set enable 1 = 0x%04x\n" |
| "id[86]: command set enable 2 = 0x%04x\n" |
| "id[87]: command set default = 0x%04x\n" |
| "id[88]: udma = 0x%04x\n" |
| "id[93]: hardware reset result = 0x%04x\n", |
| id[85], |
| id[86], |
| id[87], |
| id[88], |
| id[93]); |
| } |
| |
| void ata_swap_buf_le16(u16 *buf, unsigned int buf_words) |
| { |
| unsigned int i; |
| |
| for (i = 0; i < buf_words; i++) |
| buf[i] = le16_to_cpu(buf[i]); |
| } |