| 130 | |
| 131 | |
| 132 | int nvm_ctrl_init(nvm_ctrl_t** ctrl, int filedes) |
| 133 | { |
| 134 | int err; |
| 135 | struct device* dev; |
| 136 | const struct device_ops ops = { |
| 137 | .release_device = &release_device, |
| 138 | .map_range = &ioctl_map, |
| 139 | .unmap_range = &ioctl_unmap, |
| 140 | }; |
| 141 | |
| 142 | *ctrl = NULL; |
| 143 | dev = (struct device*) malloc(sizeof(struct device)); |
| 144 | if (dev == NULL) |
| 145 | { |
| 146 | dprintf("Failed to allocate device handle: %s\n", strerror(errno)); |
| 147 | return ENOMEM; |
| 148 | } |
| 149 | |
| 150 | dev->fd = dup(filedes); |
| 151 | if (dev->fd < 0) |
| 152 | { |
| 153 | free(dev); |
| 154 | dprintf("Could not duplicate file descriptor: %s\n", strerror(errno)); |
| 155 | return errno; |
| 156 | } |
| 157 | |
| 158 | err = fcntl(dev->fd, F_SETFD, O_RDWR); |
| 159 | if (err == -1) |
| 160 | { |
| 161 | close(dev->fd); |
| 162 | free(dev); |
| 163 | dprintf("Failed to set file descriptor control: %s\n", strerror(errno)); |
| 164 | return errno; |
| 165 | } |
| 166 | |
| 167 | const size_t mm_size = NVM_CTRL_MEM_MINSIZE; |
| 168 | void* mm_ptr = mmap(NULL, mm_size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FILE|MAP_LOCKED, dev->fd, 0); |
| 169 | if (mm_ptr == NULL) |
| 170 | { |
| 171 | close(dev->fd); |
| 172 | free(dev); |
| 173 | dprintf("Failed to map device memory: %s\n", strerror(errno)); |
| 174 | return errno; |
| 175 | } |
| 176 | |
| 177 | err = _nvm_ctrl_init(ctrl, dev, &ops, DEVICE_TYPE_IOCTL, mm_ptr, mm_size); |
| 178 | if (err != 0) |
| 179 | { |
| 180 | release_device(dev, mm_ptr, mm_size); |
| 181 | return err; |
| 182 | } |
| 183 | |
| 184 | return 0; |
| 185 | } |
no test coverage detected