43
43
44
44
#define DEVICE_MTD_NAME "/dev/mtd"
45
45
#define DEVICE_UBI_NAME "/dev/ubi"
46
+ #define DEVICE_UBI_CTRL "/dev/ubi_ctrl"
47
+ #define SYS_UBI "/sys/class/ubi"
48
+ #define SYS_UBI_MTD_NUM "/sys/class/ubi/ubi%d/mtd_num"
46
49
#define SYS_UBI_VOLUME_COUNT "/sys/class/ubi/ubi%d/volumes_count"
47
50
#define SYS_UBI_VOLUME_NAME "/sys/class/ubi/ubi%d/ubi%d_%d/name"
48
51
@@ -196,7 +199,11 @@ static enum device_type get_device_type(char *device)
196
199
enum device_type type = DEVICE_NONE ;
197
200
198
201
if (!strncmp (device , DEVICE_MTD_NAME , strlen (DEVICE_MTD_NAME )))
199
- type = DEVICE_MTD ;
202
+ if (strchr (device , DEVNAME_SEPARATOR )) {
203
+ type = DEVICE_UBI ;
204
+ } else {
205
+ type = DEVICE_MTD ;
206
+ }
200
207
else if (!strncmp (device , DEVICE_UBI_NAME , strlen (DEVICE_UBI_NAME )))
201
208
type = DEVICE_UBI ;
202
209
else if (strlen (device ) > 0 )
@@ -217,6 +224,77 @@ static int ubi_get_dev_id(char *device)
217
224
return dev_id ;
218
225
}
219
226
227
+ static int mtd_get_dev_id (char * device )
228
+ {
229
+ int dev_id = -1 ;
230
+ char * sep ;
231
+
232
+ sep = strrchr (device , 'd' );
233
+ if (sep )
234
+ sscanf (sep + 1 , "%d" , & dev_id );
235
+
236
+ return dev_id ;
237
+ }
238
+
239
+ static int ubi_get_dev_id_from_mtd (char * device )
240
+ {
241
+ DIR * sysfs_ubi ;
242
+ struct dirent * dirent ;
243
+ int mtd_id ;
244
+
245
+ mtd_id = mtd_get_dev_id (device );
246
+ if (mtd_id < 0 )
247
+ return -1 ;
248
+
249
+ sysfs_ubi = opendir (SYS_UBI );
250
+ if (!sysfs_ubi )
251
+ return -1 ;
252
+
253
+ while (1 ) {
254
+ int ubi_num , ret ;
255
+
256
+ dirent = readdir (sysfs_ubi );
257
+ if (!dirent )
258
+ break ;
259
+
260
+ if (strlen (dirent -> d_name ) >= 255 ) {
261
+ closedir (sysfs_ubi );
262
+ return -1 ;
263
+ }
264
+
265
+ ret = sscanf (dirent -> d_name , "ubi%d" , & ubi_num );
266
+ if (ret == 1 ) {
267
+ char filename [DEVNAME_MAX_LENGTH ];
268
+ char data [DEVNAME_MAX_LENGTH ];
269
+ int fd , n , num_mtd = -1 ;
270
+
271
+ snprintf (filename , sizeof (filename ), SYS_UBI_MTD_NUM , ubi_num );
272
+ fd = open (filename , O_RDONLY );
273
+ if (fd < 0 )
274
+ continue ;
275
+
276
+ n = read (fd , data , sizeof (data ));
277
+ close (fd );
278
+ if (n < 0 )
279
+ continue ;
280
+
281
+ if (sscanf (data , "%d" , & num_mtd ) != 1 )
282
+ num_mtd = -1 ;
283
+
284
+ if (num_mtd < 0 )
285
+ continue ;
286
+
287
+ if (num_mtd == mtd_id ) {
288
+ closedir (sysfs_ubi );
289
+ return ubi_num ;
290
+ }
291
+ }
292
+ }
293
+
294
+ closedir (sysfs_ubi );
295
+ return -1 ;
296
+ }
297
+
220
298
static int ubi_get_num_volume (char * device )
221
299
{
222
300
char filename [DEVNAME_MAX_LENGTH ];
@@ -308,9 +386,48 @@ static int ubi_update_name(struct uboot_flash_env *dev)
308
386
{
309
387
char device [DEVNAME_MAX_LENGTH ];
310
388
char volume [DEVNAME_MAX_LENGTH ];
311
- int dev_id , vol_id , ret = - EBADF ;
389
+ int dev_id , vol_id , fd , ret = - EBADF ;
390
+ struct stat st ;
312
391
char * sep ;
313
392
393
+ if (!strncmp (dev -> devname , DEVICE_MTD_NAME , strlen (DEVICE_MTD_NAME )))
394
+ {
395
+ sep = strchr (dev -> devname , DEVNAME_SEPARATOR );
396
+ if (sep )
397
+ {
398
+ memset (device , 0 , DEVNAME_MAX_LENGTH );
399
+ memcpy (device , dev -> devname , sep - dev -> devname );
400
+
401
+ memset (volume , 0 , DEVNAME_MAX_LENGTH );
402
+ sscanf (sep + 1 , "%s" , & volume [0 ]);
403
+
404
+ ret = ubi_get_dev_id_from_mtd (device );
405
+ if (ret < 0 ) {
406
+ struct ubi_attach_req req ;
407
+
408
+ memset (& req , 0 , sizeof (struct ubi_attach_req ));
409
+ req .ubi_num = UBI_DEV_NUM_AUTO ;
410
+ req .mtd_num = mtd_get_dev_id (device );
411
+ req .vid_hdr_offset = 0 ;
412
+
413
+ fd = open (DEVICE_UBI_CTRL , O_RDONLY );
414
+ if (fd == -1 )
415
+ return - EBADF ;
416
+
417
+ ret = ioctl (fd , UBI_IOCATT , & req );
418
+ close (fd );
419
+ if (ret == -1 )
420
+ return - EBADF ;
421
+
422
+ sprintf (dev -> devname , DEVICE_UBI_NAME "%d:%s" , req .ubi_num , volume );
423
+ } else {
424
+ sprintf (dev -> devname , DEVICE_UBI_NAME "%d:%s" , ret , volume );
425
+ }
426
+ } else {
427
+ return - EBADF ;
428
+ }
429
+ }
430
+
314
431
sep = strchr (dev -> devname , DEVNAME_SEPARATOR );
315
432
if (sep )
316
433
{
0 commit comments