@@ -21,9 +21,15 @@ extern struct acpi_device *acpi_root;
2121#define ACPI_BUS_DEVICE_NAME "System Bus"
2222
2323static LIST_HEAD (acpi_device_list );
24+ static LIST_HEAD (acpi_bus_id_list );
2425DEFINE_SPINLOCK (acpi_device_lock );
2526LIST_HEAD (acpi_wakeup_device_list );
2627
28+ struct acpi_device_bus_id {
29+ char bus_id [9 ];
30+ unsigned int instance_no ;
31+ struct list_head node ;
32+ };
2733static int acpi_eject_operation (acpi_handle handle , int lockable )
2834{
2935 struct acpi_object_list arg_list ;
@@ -103,18 +109,61 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
103109
104110static DEVICE_ATTR (eject , 0200 , NULL, acpi_eject_store ) ;
105111
106- static void acpi_device_setup_files (struct acpi_device * dev )
112+ static ssize_t
113+ acpi_device_hid_show (struct device * dev , struct device_attribute * attr , char * buf ) {
114+ struct acpi_device * acpi_dev = to_acpi_device (dev );
115+
116+ return sprintf (buf , "%s\n" , acpi_dev -> pnp .hardware_id );
117+ }
118+ static DEVICE_ATTR (hid , 0444 , acpi_device_hid_show , NULL) ;
119+
120+ static ssize_t
121+ acpi_device_path_show (struct device * dev , struct device_attribute * attr , char * buf ) {
122+ struct acpi_device * acpi_dev = to_acpi_device (dev );
123+ struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER , NULL };
124+ int result ;
125+
126+ result = acpi_get_name (acpi_dev -> handle , ACPI_FULL_PATHNAME , & path );
127+ if (result )
128+ goto end ;
129+
130+ result = sprintf (buf , "%s\n" , (char * )path .pointer );
131+ kfree (path .pointer );
132+ end :
133+ return result ;
134+ }
135+ static DEVICE_ATTR (path , 0444 , acpi_device_path_show , NULL) ;
136+
137+ static int acpi_device_setup_files (struct acpi_device * dev )
107138{
108139 acpi_status status ;
109140 acpi_handle temp ;
141+ int result = 0 ;
110142
111143 /*
112- * If device has _EJ0, 'eject' file is created that is used to trigger
113- * hot-removal function from userland.
144+ * Devices gotten from FADT don't have a "path" attribute
114145 */
146+ if (dev -> handle ) {
147+ result = device_create_file (& dev -> dev , & dev_attr_path );
148+ if (result )
149+ goto end ;
150+ }
151+
152+ if (dev -> flags .hardware_id ) {
153+ result = device_create_file (& dev -> dev , & dev_attr_hid );
154+ if (result )
155+ goto end ;
156+ }
157+
158+ /*
159+ * If device has _EJ0, 'eject' file is created that is used to trigger
160+ * hot-removal function from userland.
161+ */
115162 status = acpi_get_handle (dev -> handle , "_EJ0" , & temp );
116163 if (ACPI_SUCCESS (status ))
117- device_create_file (& dev -> dev , & dev_attr_eject );
164+ result = device_create_file (& dev -> dev , & dev_attr_eject );
165+ end :
166+ return result ;
118167}
119168
120169static void acpi_device_remove_files (struct acpi_device * dev )
@@ -129,6 +178,11 @@ static void acpi_device_remove_files(struct acpi_device *dev)
129178 status = acpi_get_handle (dev -> handle , "_EJ0" , & temp );
130179 if (ACPI_SUCCESS (status ))
131180 device_remove_file (& dev -> dev , & dev_attr_eject );
181+
182+ if (dev -> flags .hardware_id )
183+ device_remove_file (& dev -> dev , & dev_attr_hid );
184+ if (dev -> handle )
185+ device_remove_file (& dev -> dev , & dev_attr_path );
132186}
133187/* --------------------------------------------------------------------------
134188 ACPI Bus operations
@@ -260,9 +314,12 @@ static struct bus_type acpi_bus_type = {
260314 .uevent = acpi_device_uevent ,
261315};
262316
263- static void acpi_device_register (struct acpi_device * device ,
317+ static int acpi_device_register (struct acpi_device * device ,
264318 struct acpi_device * parent )
265319{
320+ int result ;
321+ struct acpi_device_bus_id * acpi_device_bus_id , * new_bus_id ;
322+ int found = 0 ;
266323 /*
267324 * Linkage
268325 * -------
@@ -273,7 +330,33 @@ static void acpi_device_register(struct acpi_device *device,
273330 INIT_LIST_HEAD (& device -> g_list );
274331 INIT_LIST_HEAD (& device -> wakeup_list );
275332
333+ new_bus_id = kzalloc (sizeof (struct acpi_device_bus_id ), GFP_KERNEL );
334+ if (!new_bus_id ) {
335+ printk (KERN_ERR PREFIX "Memory allocation error\n" );
336+ return - ENOMEM ;
337+ }
338+
276339 spin_lock (& acpi_device_lock );
340+ /*
341+ * Find suitable bus_id and instance number in acpi_bus_id_list
342+ * If failed, create one and link it into acpi_bus_id_list
343+ */
344+ list_for_each_entry (acpi_device_bus_id , & acpi_bus_id_list , node ) {
345+ if (!strcmp (acpi_device_bus_id -> bus_id , device -> flags .hardware_id ? device -> pnp .hardware_id : "PNPIDNON" )) {
346+ acpi_device_bus_id -> instance_no ++ ;
347+ found = 1 ;
348+ kfree (new_bus_id );
349+ break ;
350+ }
351+ }
352+ if (!found ) {
353+ acpi_device_bus_id = new_bus_id ;
354+ strcpy (acpi_device_bus_id -> bus_id , device -> flags .hardware_id ? device -> pnp .hardware_id : "PNPIDNON" );
355+ acpi_device_bus_id -> instance_no = 0 ;
356+ list_add_tail (& acpi_device_bus_id -> node , & acpi_bus_id_list );
357+ }
358+ sprintf (device -> dev .bus_id , "%s:%02x" , acpi_device_bus_id -> bus_id , acpi_device_bus_id -> instance_no );
359+
277360 if (device -> parent ) {
278361 list_add_tail (& device -> node , & device -> parent -> children );
279362 list_add_tail (& device -> g_list , & device -> parent -> g_list );
@@ -287,12 +370,29 @@ static void acpi_device_register(struct acpi_device *device,
287370 device -> dev .parent = & parent -> dev ;
288371 device -> dev .bus = & acpi_bus_type ;
289372 device_initialize (& device -> dev );
290- sprintf (device -> dev .bus_id , "%s" , device -> pnp .bus_id );
291373 device -> dev .release = & acpi_device_release ;
292- device_add (& device -> dev );
374+ result = device_add (& device -> dev );
375+ if (result ) {
376+ printk ("Error adding device %s" , device -> dev .bus_id );
377+ goto end ;
378+ }
379+
380+ result = acpi_device_setup_files (device );
381+ if (result )
382+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR , "Error creating sysfs interface for device %s\n" , device -> dev .bus_id ));
293383
294- acpi_device_setup_files (device );
295384 device -> removal_type = ACPI_BUS_REMOVAL_NORMAL ;
385+ return 0 ;
386+ end :
387+ spin_lock (& acpi_device_lock );
388+ if (device -> parent ) {
389+ list_del (& device -> node );
390+ list_del (& device -> g_list );
391+ } else
392+ list_del (& device -> g_list );
393+ list_del (& device -> wakeup_list );
394+ spin_unlock (& acpi_device_lock );
395+ return result ;
296396}
297397
298398static void acpi_device_unregister (struct acpi_device * device , int type )
@@ -1035,7 +1135,7 @@ acpi_add_single_object(struct acpi_device **child,
10351135
10361136 acpi_device_get_debug_info (device , handle , type );
10371137
1038- acpi_device_register (device , parent );
1138+ result = acpi_device_register (device , parent );
10391139
10401140 end :
10411141 if (!result )
0 commit comments