@@ -109,33 +109,13 @@ static const char * const allow_duplicates[] = {
109
109
NULL
110
110
};
111
111
112
+ #define dev_to_wblock (__dev ) container_of_const(__dev, struct wmi_block, dev.dev)
113
+ #define dev_to_wdev (__dev ) container_of_const(__dev, struct wmi_device, dev)
114
+
112
115
/*
113
116
* GUID parsing functions
114
117
*/
115
118
116
- static acpi_status find_guid (const char * guid_string , struct wmi_block * * out )
117
- {
118
- guid_t guid_input ;
119
- struct wmi_block * wblock ;
120
-
121
- if (!guid_string )
122
- return AE_BAD_PARAMETER ;
123
-
124
- if (guid_parse (guid_string , & guid_input ))
125
- return AE_BAD_PARAMETER ;
126
-
127
- list_for_each_entry (wblock , & wmi_block_list , list ) {
128
- if (guid_equal (& wblock -> gblock .guid , & guid_input )) {
129
- if (out )
130
- * out = wblock ;
131
-
132
- return AE_OK ;
133
- }
134
- }
135
-
136
- return AE_NOT_FOUND ;
137
- }
138
-
139
119
static bool guid_parse_and_compare (const char * string , const guid_t * guid )
140
120
{
141
121
guid_t guid_input ;
@@ -245,6 +225,41 @@ static acpi_status get_event_data(const struct wmi_block *wblock, struct acpi_bu
245
225
return acpi_evaluate_object (wblock -> acpi_device -> handle , "_WED" , & input , out );
246
226
}
247
227
228
+ static int wmidev_match_guid (struct device * dev , const void * data )
229
+ {
230
+ struct wmi_block * wblock = dev_to_wblock (dev );
231
+ const guid_t * guid = data ;
232
+
233
+ if (guid_equal (guid , & wblock -> gblock .guid ))
234
+ return 1 ;
235
+
236
+ return 0 ;
237
+ }
238
+
239
+ static struct bus_type wmi_bus_type ;
240
+
241
+ static struct wmi_device * wmi_find_device_by_guid (const char * guid_string )
242
+ {
243
+ struct device * dev ;
244
+ guid_t guid ;
245
+ int ret ;
246
+
247
+ ret = guid_parse (guid_string , & guid );
248
+ if (ret < 0 )
249
+ return ERR_PTR (ret );
250
+
251
+ dev = bus_find_device (& wmi_bus_type , NULL , & guid , wmidev_match_guid );
252
+ if (!dev )
253
+ return ERR_PTR (- ENODEV );
254
+
255
+ return dev_to_wdev (dev );
256
+ }
257
+
258
+ static void wmi_device_put (struct wmi_device * wdev )
259
+ {
260
+ put_device (& wdev -> dev );
261
+ }
262
+
248
263
/*
249
264
* Exported WMI functions
250
265
*/
@@ -279,18 +294,17 @@ EXPORT_SYMBOL_GPL(set_required_buffer_size);
279
294
*/
280
295
int wmi_instance_count (const char * guid_string )
281
296
{
282
- struct wmi_block * wblock ;
283
- acpi_status status ;
297
+ struct wmi_device * wdev ;
298
+ int ret ;
284
299
285
- status = find_guid (guid_string , & wblock );
286
- if (ACPI_FAILURE (status )) {
287
- if (status == AE_BAD_PARAMETER )
288
- return - EINVAL ;
300
+ wdev = wmi_find_device_by_guid (guid_string );
301
+ if (IS_ERR (wdev ))
302
+ return PTR_ERR (wdev );
289
303
290
- return - ENODEV ;
291
- }
304
+ ret = wmidev_instance_count ( wdev ) ;
305
+ wmi_device_put ( wdev );
292
306
293
- return wmidev_instance_count ( & wblock -> dev ) ;
307
+ return ret ;
294
308
}
295
309
EXPORT_SYMBOL_GPL (wmi_instance_count );
296
310
@@ -325,15 +339,18 @@ EXPORT_SYMBOL_GPL(wmidev_instance_count);
325
339
acpi_status wmi_evaluate_method (const char * guid_string , u8 instance , u32 method_id ,
326
340
const struct acpi_buffer * in , struct acpi_buffer * out )
327
341
{
328
- struct wmi_block * wblock = NULL ;
342
+ struct wmi_device * wdev ;
329
343
acpi_status status ;
330
344
331
- status = find_guid (guid_string , & wblock );
332
- if (ACPI_FAILURE (status ))
333
- return status ;
345
+ wdev = wmi_find_device_by_guid (guid_string );
346
+ if (IS_ERR (wdev ))
347
+ return AE_ERROR ;
348
+
349
+ status = wmidev_evaluate_method (wdev , instance , method_id , in , out );
334
350
335
- return wmidev_evaluate_method (& wblock -> dev , instance , method_id ,
336
- in , out );
351
+ wmi_device_put (wdev );
352
+
353
+ return status ;
337
354
}
338
355
EXPORT_SYMBOL_GPL (wmi_evaluate_method );
339
356
@@ -472,13 +489,19 @@ acpi_status wmi_query_block(const char *guid_string, u8 instance,
472
489
struct acpi_buffer * out )
473
490
{
474
491
struct wmi_block * wblock ;
492
+ struct wmi_device * wdev ;
475
493
acpi_status status ;
476
494
477
- status = find_guid (guid_string , & wblock );
478
- if (ACPI_FAILURE ( status ))
479
- return status ;
495
+ wdev = wmi_find_device_by_guid (guid_string );
496
+ if (IS_ERR ( wdev ))
497
+ return AE_ERROR ;
480
498
481
- return __query_block (wblock , instance , out );
499
+ wblock = container_of (wdev , struct wmi_block , dev );
500
+ status = __query_block (wblock , instance , out );
501
+
502
+ wmi_device_put (wdev );
503
+
504
+ return status ;
482
505
}
483
506
EXPORT_SYMBOL_GPL (wmi_query_block );
484
507
@@ -516,8 +539,9 @@ EXPORT_SYMBOL_GPL(wmidev_block_query);
516
539
acpi_status wmi_set_block (const char * guid_string , u8 instance ,
517
540
const struct acpi_buffer * in )
518
541
{
519
- struct wmi_block * wblock = NULL ;
542
+ struct wmi_block * wblock ;
520
543
struct guid_block * block ;
544
+ struct wmi_device * wdev ;
521
545
acpi_handle handle ;
522
546
struct acpi_object_list input ;
523
547
union acpi_object params [2 ];
@@ -527,19 +551,26 @@ acpi_status wmi_set_block(const char *guid_string, u8 instance,
527
551
if (!in )
528
552
return AE_BAD_DATA ;
529
553
530
- status = find_guid (guid_string , & wblock );
531
- if (ACPI_FAILURE ( status ))
532
- return status ;
554
+ wdev = wmi_find_device_by_guid (guid_string );
555
+ if (IS_ERR ( wdev ))
556
+ return AE_ERROR ;
533
557
558
+ wblock = container_of (wdev , struct wmi_block , dev );
534
559
block = & wblock -> gblock ;
535
560
handle = wblock -> acpi_device -> handle ;
536
561
537
- if (block -> instance_count <= instance )
538
- return AE_BAD_PARAMETER ;
562
+ if (block -> instance_count <= instance ) {
563
+ status = AE_BAD_PARAMETER ;
564
+
565
+ goto err_wdev_put ;
566
+ }
539
567
540
568
/* Check GUID is a data block */
541
- if (block -> flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD ))
542
- return AE_ERROR ;
569
+ if (block -> flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD )) {
570
+ status = AE_ERROR ;
571
+
572
+ goto err_wdev_put ;
573
+ }
543
574
544
575
input .count = 2 ;
545
576
input .pointer = params ;
@@ -551,7 +582,12 @@ acpi_status wmi_set_block(const char *guid_string, u8 instance,
551
582
552
583
get_acpi_method_name (wblock , 'S' , method );
553
584
554
- return acpi_evaluate_object (handle , method , & input , NULL );
585
+ status = acpi_evaluate_object (handle , method , & input , NULL );
586
+
587
+ err_wdev_put :
588
+ wmi_device_put (wdev );
589
+
590
+ return status ;
555
591
}
556
592
EXPORT_SYMBOL_GPL (wmi_set_block );
557
593
@@ -742,7 +778,15 @@ EXPORT_SYMBOL_GPL(wmi_get_event_data);
742
778
*/
743
779
bool wmi_has_guid (const char * guid_string )
744
780
{
745
- return ACPI_SUCCESS (find_guid (guid_string , NULL ));
781
+ struct wmi_device * wdev ;
782
+
783
+ wdev = wmi_find_device_by_guid (guid_string );
784
+ if (IS_ERR (wdev ))
785
+ return false;
786
+
787
+ wmi_device_put (wdev );
788
+
789
+ return true;
746
790
}
747
791
EXPORT_SYMBOL_GPL (wmi_has_guid );
748
792
@@ -756,20 +800,23 @@ EXPORT_SYMBOL_GPL(wmi_has_guid);
756
800
*/
757
801
char * wmi_get_acpi_device_uid (const char * guid_string )
758
802
{
759
- struct wmi_block * wblock = NULL ;
760
- acpi_status status ;
803
+ struct wmi_block * wblock ;
804
+ struct wmi_device * wdev ;
805
+ char * uid ;
761
806
762
- status = find_guid (guid_string , & wblock );
763
- if (ACPI_FAILURE ( status ))
807
+ wdev = wmi_find_device_by_guid (guid_string );
808
+ if (IS_ERR ( wdev ))
764
809
return NULL ;
765
810
766
- return acpi_device_uid (wblock -> acpi_device );
811
+ wblock = container_of (wdev , struct wmi_block , dev );
812
+ uid = acpi_device_uid (wblock -> acpi_device );
813
+
814
+ wmi_device_put (wdev );
815
+
816
+ return uid ;
767
817
}
768
818
EXPORT_SYMBOL_GPL (wmi_get_acpi_device_uid );
769
819
770
- #define dev_to_wblock (__dev ) container_of_const(__dev, struct wmi_block, dev.dev)
771
- #define dev_to_wdev (__dev ) container_of_const(__dev, struct wmi_device, dev)
772
-
773
820
static inline struct wmi_driver * drv_to_wdrv (struct device_driver * drv )
774
821
{
775
822
return container_of (drv , struct wmi_driver , driver );
0 commit comments