示例#1
0
文件: sata_mv.c 项目: OpenNoah/u-boot
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 void fsl_sata_identify(int dev, u16 *id)
{
	fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
	struct sata_fis_h2d h2d, *cfis = &h2d;

	memset(cfis, 0, sizeof(struct sata_fis_h2d));

	cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
	cfis->pm_port_c = 0x80; /* is command */
	cfis->command = ATA_CMD_ID_ATA;

	fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, (u8 *)id, ATA_ID_WORDS * 2);
	ata_swap_buf_le16(id, ATA_ID_WORDS);
}
示例#3
0
static void bfin_ata_identify(struct ata_port *ap, int dev)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	u8 status = 0;
	static u16 iobuf[ATA_SECTOR_WORDS];
	u64 n_sectors = 0;
	hd_driveid_t *iop = (hd_driveid_t *)iobuf;

	memset(iobuf, 0, sizeof(iobuf));

	if (!(ap->dev_mask & (1 << dev)))
		return;

	debug("port=%d dev=%d\n", ap->port_no, dev);

	bfin_dev_select(ap, dev);

	status = 0;
	/* Device Identify Command */
	write_atapi_register(base, ATA_REG_CMD, ATA_CMD_ID_ATA);
	bfin_check_altstatus(ap);
	udelay(10);

	status = bfin_ata_busy_wait(ap, ATA_BUSY, 1000, 0);
	if (status & ATA_ERR) {
		printf("\ndevice not responding\n");
		ap->dev_mask &= ~(1 << dev);
		return;
	}

	read_atapi_data(base, ATA_SECTOR_WORDS, iobuf);

	ata_swap_buf_le16(iobuf, ATA_SECTOR_WORDS);

	/* we require LBA and DMA support (bits 8 & 9 of word 49) */
	if (!ata_id_has_dma(iobuf) || !ata_id_has_lba(iobuf))
		printf("ata%u: no dma/lba\n", ap->port_no);

#ifdef DEBUG
	ata_dump_id(iobuf);
#endif

	n_sectors = ata_id_n_sectors(iobuf);

	if (n_sectors == 0) {
		ap->dev_mask &= ~(1 << dev);
		return;
	}

	ata_id_c_string(iobuf, (unsigned char *)sata_dev_desc[ap->port_no].revision,
			 ATA_ID_FW_REV, sizeof(sata_dev_desc[ap->port_no].revision));
	ata_id_c_string(iobuf, (unsigned char *)sata_dev_desc[ap->port_no].vendor,
			 ATA_ID_PROD, sizeof(sata_dev_desc[ap->port_no].vendor));
	ata_id_c_string(iobuf, (unsigned char *)sata_dev_desc[ap->port_no].product,
			 ATA_ID_SERNO, sizeof(sata_dev_desc[ap->port_no].product));

	if ((iop->config & 0x0080) == 0x0080)
		sata_dev_desc[ap->port_no].removable = 1;
	else
		sata_dev_desc[ap->port_no].removable = 0;

	sata_dev_desc[ap->port_no].lba = (u32) n_sectors;
	debug("lba=0x%lx\n", sata_dev_desc[ap->port_no].lba);

#ifdef CONFIG_LBA48
	if (iop->command_set_2 & 0x0400)
		sata_dev_desc[ap->port_no].lba48 = 1;
	else
		sata_dev_desc[ap->port_no].lba48 = 0;
#endif

	/* assuming HD */
	sata_dev_desc[ap->port_no].type = DEV_TYPE_HARDDISK;
	sata_dev_desc[ap->port_no].blksz = ATA_SECT_SIZE;
	sata_dev_desc[ap->port_no].lun = 0;	/* just to fill something in... */

	printf("PATA device#%d %s is found on ata port#%d.\n",
		ap->port_no%PATA_DEV_NUM_PER_PORT,
		sata_dev_desc[ap->port_no].vendor,
		ap->port_no/PATA_DEV_NUM_PER_PORT);
}