Ejemplo n.º 1
0
int ufs_get_device_info(struct ufs_hba *hba, struct ufs_card_info *card_data)
{
	int err;
	u8 model_index;
	u8 str_desc_buf[QUERY_DESC_STRING_MAX_SIZE];
	u8 desc_buf[QUERY_DESC_DEVICE_MAX_SIZE];

	err = ufshcd_read_device_desc(hba, desc_buf,
					QUERY_DESC_DEVICE_MAX_SIZE);
	if (err)
		goto out;

	card_data->vendor = desc_buf[DEVICE_DESC_PARAM_MANF_ID + 1];
	model_index = desc_buf[DEVICE_DESC_PARAM_PRDCT_NAME];

	memset(str_desc_buf, 0, QUERY_DESC_STRING_MAX_SIZE);
	err = ufshcd_read_string_desc(hba, model_index, str_desc_buf,
					QUERY_DESC_STRING_MAX_SIZE, ASCII_STD);
	if (err)
		goto out;

	strlcpy(card_data->model, str_desc_buf, MAX_MODEL_LEN + 1);
out:
	return err;
}
Ejemplo n.º 2
0
int ufs_get_device_info(struct ufs_hba *hba, struct ufs_card_info *card_data)
{
    int err;
    u8 model_index;
    u8 serial_num_index;
    u8 serial_num_buf[6]; /* samsung spec : use only 6 bytes of serial number string descriptor */
    u8 str_desc_buf[QUERY_DESC_STRING_MAX_SIZE + 1];
    u8 desc_buf[QUERY_DESC_DEVICE_MAX_SIZE];
    u8 health_buf[QUERY_DESC_HEALTH_MAX_SIZE];
    bool ascii_type;

    err = ufshcd_read_device_desc(hba, desc_buf,
                                  QUERY_DESC_DEVICE_MAX_SIZE);
    if (err)
        goto out;

    err = ufshcd_read_health_desc(hba, health_buf,
                                  QUERY_DESC_HEALTH_MAX_SIZE);
    if (err)
        printk("%s: DEVICE_HEALTH desc read fail, err  = %d\n", __FUNCTION__, err);

    /* getting Life Time at Device Health DESC*/
    card_data->lifetime = health_buf[HEALTH_DEVICE_DESC_PARAM_LIFETIMEA];

    /*
     * getting vendor (manufacturerID) and Bank Index in big endian
     * format
     */
    card_data->wmanufacturerid = desc_buf[DEVICE_DESC_PARAM_MANF_ID] << 8 |
                                 desc_buf[DEVICE_DESC_PARAM_MANF_ID + 1];

    hba->manufacturer_id = card_data->wmanufacturerid;
    hba->lifetime = card_data->lifetime;

    model_index = desc_buf[DEVICE_DESC_PARAM_PRDCT_NAME];

    memset(str_desc_buf, 0, QUERY_DESC_STRING_MAX_SIZE);
    err = ufshcd_read_string_desc(hba, model_index, str_desc_buf,
                                  QUERY_DESC_STRING_MAX_SIZE, ASCII_STD);
    if (err)
        goto out;

    str_desc_buf[QUERY_DESC_STRING_MAX_SIZE] = '\0';
    strlcpy(card_data->model, (str_desc_buf + QUERY_DESC_HDR_SIZE),
            min_t(u8, str_desc_buf[QUERY_DESC_LENGTH_OFFSET],
                  MAX_MODEL_LEN));
    /* Null terminate the model string */
    card_data->model[MAX_MODEL_LEN] = '\0';

    /* make unique id with MANUFACTURE DATE & SERIAL NUMBER */
    serial_num_index = desc_buf[DEVICE_DESC_PARAM_SN];
    memset(str_desc_buf, 0, QUERY_DESC_STRING_MAX_SIZE);

    /*Samsung device use UTF16*/
    if ((hba->manufacturer_id == UFS_VENDOR_ID_SAMSUNG)  || (hba->manufacturer_id == UFS_VENDOR_ID_TOSHIBA))
        ascii_type = UTF16_STD;
    else
        ascii_type = ASCII_STD;

    err = ufshcd_read_string_desc(hba, serial_num_index, str_desc_buf,
                                  QUERY_DESC_STRING_MAX_SIZE, ascii_type);

    if (err)
        goto out;
    str_desc_buf[QUERY_DESC_STRING_MAX_SIZE] = '\0';

    memset(serial_num_buf, 0, sizeof(serial_num_buf));
    memcpy(serial_num_buf, str_desc_buf + QUERY_DESC_HDR_SIZE, sizeof(serial_num_buf));

    memset(hba->unique_number, 0, sizeof(hba->unique_number));
    sprintf(hba->unique_number, "%02x%02x%02x%02x%02x%02x%02x%02x", desc_buf[DEVICE_DESC_PARAM_MANF_DATE], desc_buf[DEVICE_DESC_PARAM_MANF_DATE+1], serial_num_buf[0], serial_num_buf[1], serial_num_buf[2], serial_num_buf[3], serial_num_buf[4], serial_num_buf[5]);

    /* Null terminate the unique number string */
    hba->unique_number[UFS_UNIQUE_NUMBER_LEN - 1] = '\0';

    printk("%s: UNIQUE NUMBER = %s , Lifetime: 0x%02x \n", __FUNCTION__, hba->unique_number, health_buf[3]<<4|health_buf[4]);

out:
    return err;
}
Ejemplo n.º 3
0
static int ufsdbg_dump_device_desc_show(struct seq_file *file, void *data)
{
	int err = 0;
	int buff_len = QUERY_DESC_DEVICE_MAX_SIZE;
	u8 desc_buf[QUERY_DESC_DEVICE_MAX_SIZE];
	struct ufs_hba *hba = (struct ufs_hba *)file->private;

	struct desc_field_offset device_desc_field_name[] = {
		{"bLength",		0x00, BYTE},
		{"bDescriptorType",	0x01, BYTE},
		{"bDevice",		0x02, BYTE},
		{"bDeviceClass",	0x03, BYTE},
		{"bDeviceSubClass",	0x04, BYTE},
		{"bProtocol",		0x05, BYTE},
		{"bNumberLU",		0x06, BYTE},
		{"bNumberWLU",		0x07, BYTE},
		{"bBootEnable",		0x08, BYTE},
		{"bDescrAccessEn",	0x09, BYTE},
		{"bInitPowerMode",	0x0A, BYTE},
		{"bHighPriorityLUN",	0x0B, BYTE},
		{"bSecureRemovalType",	0x0C, BYTE},
		{"bSecurityLU",		0x0D, BYTE},
		{"Reserved",		0x0E, BYTE},
		{"bInitActiveICCLevel",	0x0F, BYTE},
		{"wSpecVersion",	0x10, WORD},
		{"wManufactureDate",	0x12, WORD},
		{"iManufactureName",	0x14, BYTE},
		{"iProductName",	0x15, BYTE},
		{"iSerialNumber",	0x16, BYTE},
		{"iOemID",		0x17, BYTE},
		{"wManufactureID",	0x18, WORD},
		{"bUD0BaseOffset",	0x1A, BYTE},
		{"bUDConfigPLength",	0x1B, BYTE},
		{"bDeviceRTTCap",	0x1C, BYTE},
		{"wPeriodicRTCUpdate",	0x1D, WORD}
	};

	pm_runtime_get_sync(hba->dev);
	err = ufshcd_read_device_desc(hba, desc_buf, buff_len);
	pm_runtime_put_sync(hba->dev);

	if (!err) {
		int i;
		struct desc_field_offset *tmp;
		for (i = 0; i < ARRAY_SIZE(device_desc_field_name); ++i) {
			tmp = &device_desc_field_name[i];

			if (tmp->width_byte == BYTE) {
				seq_printf(file,
					   "Device Descriptor[Byte offset 0x%x]: %s = 0x%x\n",
					   tmp->offset,
					   tmp->name,
					   (u8)desc_buf[tmp->offset]);
			} else if (tmp->width_byte == WORD) {
				seq_printf(file,
					   "Device Descriptor[Byte offset 0x%x]: %s = 0x%x\n",
					   tmp->offset,
					   tmp->name,
					   *(u16 *)&desc_buf[tmp->offset]);
			} else {
				seq_printf(file,
				"Device Descriptor[offset 0x%x]: %s. Wrong Width = %d",
				tmp->offset, tmp->name, tmp->width_byte);
			}
		}
	} else {
		seq_printf(file, "Reading Device Descriptor failed. err = %d\n",
			   err);
	}

	return err;
}