int scan_sata(int port) { 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; u16 *id; struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv; if (!priv->link) return -ENODEV; id = (u16 *)malloc(ATA_ID_WORDS * 2); if (!id) { printf("Failed to malloc id data\n"); return -ENOMEM; } mv_sata_identify(port, id); ata_swap_buf_le16(id, ATA_ID_WORDS); #ifdef DEBUG ata_dump_id(id); #endif /* Serial number */ ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial)); memcpy(sata_dev_desc[port].product, serial, sizeof(serial)); /* Firmware version */ ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware)); memcpy(sata_dev_desc[port].revision, firmware, sizeof(firmware)); /* Product model */ ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product)); memcpy(sata_dev_desc[port].vendor, product, sizeof(product)); /* Total sectors */ n_sectors = ata_id_n_sectors(id); sata_dev_desc[port].lba = n_sectors; /* Check if support LBA48 */ if (ata_id_has_lba48(id)) { sata_dev_desc[port].lba48 = 1; debug("Device support LBA48\n"); } /* Get the NCQ queue depth from device */ priv->queue_depth = ata_id_queue_depth(id); /* Get the xfer mode from device */ mv_sata_xfer_mode(port, id); /* Set the xfer mode to highest speed */ mv_sata_set_features(port); /* Start up */ mv_start_edma_engine(port); return 0; }
static uint64_t ata_id_n_sectors(uint16_t *id) { if (ata_id_has_lba(id)) { if (ata_id_has_lba48(id)) return ata_id_u64(id, ATA_ID_LBA_CAPACITY_2); else return ata_id_u32(id, ATA_ID_LBA_CAPACITY); } return 0; }
int pio_write_buffer(struct ata_device *dev, struct ata_port *ap, unsigned long sector, const u8* buf, unsigned int size, u32 *csum) { int ret; int writtensects=0; int i; u32 checksum = 0, carry = 0; const u16 *id = dev->id; unsigned long flags; spin_lock_irqsave(ap->lock, flags); while(size > 0) { /* Written according to ATA - 6 specification */ int cnt=0; if (ata_id_has_lba48(id)) { /* LBA 48 addressing */ lba48_address_write(ap, sector); } else if (ata_id_has_lba(id)) { /* LBA 28 addressing */ lba28_address_write(ap, sector); } else { printk("ATA Dead System doesn't do CHS\n"); spin_unlock_irqrestore(ap->lock, flags); return -ENODEV; } udelay(1); if((ret = pio_busy_wait(ap, 100000)) < 0) { spin_unlock_irqrestore(ap->lock, flags); return ret; } for(i=(512/2);i;i--) { u16 data; /* Unaligned access unwise, makes for funky code */ if(size >= 2) { data = *buf++; data |= (*buf++)<<8; size -= 2; } else if (size == 1){ data = *buf++; size = 0; } else { data = 0; } writew(data, (void __iomem *)ap->ioaddr.data_addr); checksum += carry; checksum += data; carry = (data > checksum); cnt++; } mdelay(5); if((ret = pio_wait(ap)) < 0) { spin_unlock_irqrestore(ap->lock, flags); return ret; } sector++; writtensects++; } spin_unlock_irqrestore(ap->lock, flags); checksum += carry; if(csum != NULL) { *csum += checksum; if(checksum > *csum) *csum = (*csum) + 1; } return writtensects; }
int scan_sata(int dev) { fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv; 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]; u16 *id; u64 n_sectors; /* if no detected link */ if (!sata->link) return -1; id = (u16 *)malloc(ATA_ID_WORDS * 2); if (!id) { printf("id malloc failed\n\r"); return -1; } /* Identify device to get information */ fsl_sata_identify(dev, id); /* Serial number */ ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial)); memcpy(sata_dev_desc[dev].product, serial, sizeof(serial)); /* Firmware version */ ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware)); memcpy(sata_dev_desc[dev].revision, firmware, sizeof(firmware)); /* Product model */ ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product)); memcpy(sata_dev_desc[dev].vendor, product, sizeof(product)); /* Totoal sectors */ n_sectors = ata_id_n_sectors(id); sata_dev_desc[dev].lba = (u32)n_sectors; /* Check if support LBA48 */ if (ata_id_has_lba48(id)) { sata_dev_desc[dev].lba48 = 1; debug("Device support LBA48\n\r"); } /* Get the NCQ queue depth from device */ sata->queue_depth = ata_id_queue_depth(id); /* Get the xfer mode from device */ fsl_sata_xfer_mode(dev, id); /* Get the write cache status from device */ fsl_sata_init_wcache(dev, id); /* Set the xfer mode to highest speed */ fsl_sata_set_features(dev); #ifdef DEBUG fsl_sata_identify(dev, id); ata_dump_id(id); #endif free((void *)id); return 0; }