@@ -463,8 +463,11 @@ static int execute_steps(struct opal_dev *dev,
463
463
return error ;
464
464
}
465
465
466
- static int opal_discovery0_end (struct opal_dev * dev )
466
+ static int opal_discovery0_end (struct opal_dev * dev , void * data )
467
467
{
468
+ struct opal_discovery * discv_out = data ; /* may be NULL */
469
+ u8 __user * buf_out ;
470
+ u64 len_out ;
468
471
bool found_com_id = false, supported = true, single_user = false;
469
472
const struct d0_header * hdr = (struct d0_header * )dev -> resp ;
470
473
const u8 * epos = dev -> resp , * cpos = dev -> resp ;
@@ -480,6 +483,15 @@ static int opal_discovery0_end(struct opal_dev *dev)
480
483
return - EFAULT ;
481
484
}
482
485
486
+ if (discv_out ) {
487
+ buf_out = (u8 __user * )(uintptr_t )discv_out -> data ;
488
+ len_out = min_t (u64 , discv_out -> size , hlen );
489
+ if (buf_out && copy_to_user (buf_out , dev -> resp , len_out ))
490
+ return - EFAULT ;
491
+
492
+ discv_out -> size = hlen ; /* actual size of data */
493
+ }
494
+
483
495
epos += hlen ; /* end of buffer */
484
496
cpos += sizeof (* hdr ); /* current position on buffer */
485
497
@@ -565,13 +577,13 @@ static int opal_discovery0(struct opal_dev *dev, void *data)
565
577
if (ret )
566
578
return ret ;
567
579
568
- return opal_discovery0_end (dev );
580
+ return opal_discovery0_end (dev , data );
569
581
}
570
582
571
583
static int opal_discovery0_step (struct opal_dev * dev )
572
584
{
573
585
const struct opal_step discovery0_step = {
574
- opal_discovery0 ,
586
+ opal_discovery0 , NULL
575
587
};
576
588
577
589
return execute_step (dev , & discovery0_step , 0 );
@@ -2435,6 +2447,22 @@ static int opal_secure_erase_locking_range(struct opal_dev *dev,
2435
2447
return ret ;
2436
2448
}
2437
2449
2450
+ static int opal_get_discv (struct opal_dev * dev , struct opal_discovery * discv )
2451
+ {
2452
+ const struct opal_step discovery0_step = {
2453
+ opal_discovery0 , discv
2454
+ };
2455
+ int ret = 0 ;
2456
+
2457
+ mutex_lock (& dev -> dev_lock );
2458
+ setup_opal_dev (dev );
2459
+ ret = execute_step (dev , & discovery0_step , 0 );
2460
+ mutex_unlock (& dev -> dev_lock );
2461
+ if (ret )
2462
+ return ret ;
2463
+ return discv -> size ; /* modified to actual length of data */
2464
+ }
2465
+
2438
2466
static int opal_erase_locking_range (struct opal_dev * dev ,
2439
2467
struct opal_session_info * opal_session )
2440
2468
{
@@ -3056,6 +3084,10 @@ int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg)
3056
3084
case IOC_OPAL_GET_GEOMETRY :
3057
3085
ret = opal_get_geometry (dev , arg );
3058
3086
break ;
3087
+ case IOC_OPAL_DISCOVERY :
3088
+ ret = opal_get_discv (dev , p );
3089
+ break ;
3090
+
3059
3091
default :
3060
3092
break ;
3061
3093
}
0 commit comments