1*982388eaSZhikang Zhang /* 2*982388eaSZhikang Zhang * Copyright (C) 2017 NXP Semiconductors 3*982388eaSZhikang Zhang * Copyright (C) 2017 Bin Meng <bmeng.cn@gmail.com> 4*982388eaSZhikang Zhang * 5*982388eaSZhikang Zhang * SPDX-License-Identifier: GPL-2.0+ 6*982388eaSZhikang Zhang */ 7*982388eaSZhikang Zhang 8*982388eaSZhikang Zhang #include <common.h> 9*982388eaSZhikang Zhang #include <errno.h> 10*982388eaSZhikang Zhang #include <dm.h> 11*982388eaSZhikang Zhang #include <dm/device.h> 12*982388eaSZhikang Zhang #include "nvme.h" 13*982388eaSZhikang Zhang 14*982388eaSZhikang Zhang static int nvme_info_init(struct uclass *uc) 15*982388eaSZhikang Zhang { 16*982388eaSZhikang Zhang struct nvme_info *info = (struct nvme_info *)uc->priv; 17*982388eaSZhikang Zhang 18*982388eaSZhikang Zhang info->ns_num = 0; 19*982388eaSZhikang Zhang info->ndev_num = 0; 20*982388eaSZhikang Zhang INIT_LIST_HEAD(&info->dev_list); 21*982388eaSZhikang Zhang nvme_info = info; 22*982388eaSZhikang Zhang 23*982388eaSZhikang Zhang return 0; 24*982388eaSZhikang Zhang } 25*982388eaSZhikang Zhang 26*982388eaSZhikang Zhang static int nvme_uclass_post_probe(struct udevice *udev) 27*982388eaSZhikang Zhang { 28*982388eaSZhikang Zhang char name[20]; 29*982388eaSZhikang Zhang char *str; 30*982388eaSZhikang Zhang struct udevice *ns_udev; 31*982388eaSZhikang Zhang int i, ret; 32*982388eaSZhikang Zhang struct nvme_dev *ndev = dev_get_priv(udev); 33*982388eaSZhikang Zhang 34*982388eaSZhikang Zhang /* Create a blk device for each namespace */ 35*982388eaSZhikang Zhang for (i = 0; i < ndev->nn; i++) { 36*982388eaSZhikang Zhang sprintf(name, "nvme-blk#%d", nvme_info->ns_num); 37*982388eaSZhikang Zhang str = strdup(name); 38*982388eaSZhikang Zhang if (!str) 39*982388eaSZhikang Zhang return -ENOMEM; 40*982388eaSZhikang Zhang 41*982388eaSZhikang Zhang /* The real blksz and size will be set by nvme_blk_probe() */ 42*982388eaSZhikang Zhang ret = blk_create_device(udev, "nvme-blk", str, IF_TYPE_NVME, 43*982388eaSZhikang Zhang nvme_info->ns_num++, 512, 0, &ns_udev); 44*982388eaSZhikang Zhang if (ret) { 45*982388eaSZhikang Zhang free(str); 46*982388eaSZhikang Zhang nvme_info->ns_num--; 47*982388eaSZhikang Zhang 48*982388eaSZhikang Zhang return ret; 49*982388eaSZhikang Zhang } 50*982388eaSZhikang Zhang device_set_name_alloced(ns_udev); 51*982388eaSZhikang Zhang } 52*982388eaSZhikang Zhang 53*982388eaSZhikang Zhang return 0; 54*982388eaSZhikang Zhang } 55*982388eaSZhikang Zhang 56*982388eaSZhikang Zhang UCLASS_DRIVER(nvme) = { 57*982388eaSZhikang Zhang .name = "nvme", 58*982388eaSZhikang Zhang .id = UCLASS_NVME, 59*982388eaSZhikang Zhang .init = nvme_info_init, 60*982388eaSZhikang Zhang .post_probe = nvme_uclass_post_probe, 61*982388eaSZhikang Zhang .priv_auto_alloc_size = sizeof(struct nvme_info), 62*982388eaSZhikang Zhang }; 63