00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifdef HAVE_CONFIG_H
00027 # include <config.h>
00028 #endif
00029
00030 #include <ctype.h>
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <getopt.h>
00035 #include <assert.h>
00036 #include <unistd.h>
00037 #include <stdarg.h>
00038
00039 #include "../logger.h"
00040 #include "../device_store.h"
00041 #include "linux_class_scsi.h"
00042
00059 static char* scsi_host_compute_udi(HalDevice* d, int append_num)
00060 {
00061 const char* format;
00062 static char buf[256];
00063
00064 if( append_num==-1 )
00065 format = "/org/freedesktop/Hal/devices/scsi_host_%d";
00066 else
00067 format = "/org/freedesktop/Hal/devices/scsi_host_%d-%d";
00068
00069 snprintf(buf, 256, format,
00070 ds_property_get_int(d, "scsi_host.host"),
00071 append_num);
00072
00073 return buf;
00074 }
00075
00076
00086 static char* scsi_device_compute_udi(HalDevice* d, int append_num)
00087 {
00088 const char* format;
00089 static char buf[256];
00090
00091 if( append_num==-1 )
00092 format = "/org/freedesktop/Hal/devices/scsi_device_%d_%d_%d_%d";
00093 else
00094 format = "/org/freedesktop/Hal/devices/scsi_device_%d_%d_%d_%d-%d";
00095
00096 snprintf(buf, 256, format,
00097 ds_property_get_int(d, "scsi_device.host"),
00098 ds_property_get_int(d, "scsi_device.bus"),
00099 ds_property_get_int(d, "scsi_device.target"),
00100 ds_property_get_int(d, "scsi_device.lun"),
00101 append_num);
00102
00103 return buf;
00104 }
00105
00106
00107
00108 static void visit_class_device_scsi_host_got_parent(HalDevice* parent,
00109 void* data1, void* data2);
00110
00119 void visit_class_device_scsi_host(const char* path,
00120 struct sysfs_class_device* class_device)
00121 {
00122 HalDevice* d;
00123 char* parent_sysfs_path;
00124 const char* last_elem;
00125 int host_num;
00126
00127 if( class_device->sysdevice==NULL )
00128 {
00129 HAL_INFO(("Skipping virtual class device at path %s\n", path));
00130 return;
00131 }
00132
00133 HAL_INFO(("scsi_host: sysdevice_path=%s, path=%s\n", class_device->sysdevice->path, path));
00134
00137 d = ds_device_new();
00138 ds_property_set_string(d, "info.bus", "scsi_host");
00139 ds_property_set_string(d, "linux.sysfs_path", path);
00140 ds_property_set_string(d, "linux.sysfs_path_device",
00141 class_device->sysdevice->path);
00142
00143
00144 last_elem = get_last_element(path);
00145 sscanf(last_elem, "host%d", &host_num);
00146 ds_property_set_int(d, "scsi_host.host", host_num);
00147
00148
00149
00150 ds_property_set_string(d, "info.product", "SCSI Host Interface");
00151
00152 parent_sysfs_path = get_parent_sysfs_path(class_device->sysdevice->path);
00153
00154
00155
00156
00157
00158 ds_device_async_find_by_key_value_string(
00159 "linux.sysfs_path_device",
00160 parent_sysfs_path,
00161 TRUE,
00162 visit_class_device_scsi_host_got_parent,
00163 (void*) d, NULL,
00164 is_probing ? 0 :
00165 HAL_LINUX_HOTPLUG_TIMEOUT);
00166
00167 free(parent_sysfs_path);
00168 }
00169
00177 static void visit_class_device_scsi_host_got_parent(HalDevice* parent,
00178 void* data1, void* data2)
00179 {
00180 char* new_udi = NULL;
00181 HalDevice* new_d = NULL;
00182 HalDevice* d = (HalDevice*) data1;
00183
00184
00185
00186 if( parent!=NULL )
00187 {
00188 ds_property_set_string(d, "info.parent", parent->udi);
00189 find_and_set_physical_device(d);
00190 ds_property_set_bool(d, "info.virtual", TRUE);
00191 }
00192 else
00193 {
00194 HAL_ERROR(("No parent for SCSI device!"));
00195 ds_device_destroy(d);
00196 return;
00197 }
00198
00199
00200
00201
00202 new_udi = rename_and_merge(d, scsi_host_compute_udi, "scsi_host");
00203 if( new_udi!=NULL )
00204 {
00205 new_d = ds_device_find(new_udi);
00206 if( new_d!=NULL )
00207 {
00208 ds_gdl_add(new_d);
00209 }
00210 }
00211 }
00212
00213
00214
00215 static void visit_class_device_scsi_device_got_parent(HalDevice* parent,
00216 void* data1, void* data2);
00217
00226 void visit_class_device_scsi_device(const char* path,
00227 struct sysfs_class_device* class_device)
00228 {
00229 HalDevice* d;
00230 char* parent_sysfs_path;
00231 const char* last_elem;
00232 int host_num, bus_num, target_num, lun_num;
00233
00234 if( class_device->sysdevice==NULL )
00235 {
00236 HAL_INFO(("Skipping virtual class device at path %s\n", path));
00237 return;
00238 }
00239
00240
00241
00244 d = ds_device_new();
00245 ds_property_set_string(d, "info.bus", "scsi_device");
00246 ds_property_set_string(d, "linux.sysfs_path", path);
00247 ds_property_set_string(d, "linux.sysfs_path_device",
00248 class_device->sysdevice->path);
00249
00250
00251 last_elem = get_last_element(path);
00252 sscanf(last_elem, "%d:%d:%d:%d",
00253 &host_num, &bus_num, &target_num, &lun_num);
00254 ds_property_set_int(d, "scsi_device.host", host_num);
00255 ds_property_set_int(d, "scsi_device.bus", bus_num);
00256 ds_property_set_int(d, "scsi_device.target", target_num);
00257 ds_property_set_int(d, "scsi_device.lun", lun_num);
00258
00259
00260
00261 ds_property_set_string(d, "info.product", "SCSI Interface");
00262
00263
00264 parent_sysfs_path = get_parent_sysfs_path(class_device->sysdevice->path);
00265
00266
00267
00268
00269
00270 ds_device_async_find_by_key_value_string(
00271 "linux.sysfs_path_device",
00272 parent_sysfs_path,
00273 TRUE,
00274 visit_class_device_scsi_device_got_parent,
00275 (void*) d, NULL,
00276 is_probing ? 0 :
00277 HAL_LINUX_HOTPLUG_TIMEOUT);
00278
00279 free(parent_sysfs_path);
00280 }
00281
00289 static void visit_class_device_scsi_device_got_parent(HalDevice* parent,
00290 void* data1, void* data2)
00291 {
00292 char* new_udi = NULL;
00293 HalDevice* new_d = NULL;
00294 HalDevice* d = (HalDevice*) data1;
00295
00296 if( parent!=NULL )
00297 {
00298 ds_property_set_string(d, "info.parent", parent->udi);
00299 find_and_set_physical_device(d);
00300 ds_property_set_bool(d, "info.virtual", TRUE);
00301 }
00302 else
00303 {
00304 HAL_ERROR(("No parent for SCSI device!"));
00305 ds_device_destroy(d);
00306 return;
00307 }
00308
00309
00310
00311
00312 new_udi = rename_and_merge(d, scsi_device_compute_udi, "scsi_device");
00313 if( new_udi!=NULL )
00314 {
00315 new_d = ds_device_find(new_udi);
00316 if( new_d!=NULL )
00317 {
00318 ds_gdl_add(new_d);
00319 }
00320 }
00321 }
00322
00326 void linux_class_scsi_init()
00327 {
00328 }
00329
00334 void linux_class_scsi_detection_done()
00335 {
00336 }
00337
00341 void linux_class_scsi_shutdown()
00342 {
00343 }
00344