Пример #1
0
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;
}
Пример #2
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;
}
Пример #3
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;
}
Пример #4
0
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;
}