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 *
00060 scsi_host_compute_udi (HalDevice * d, int append_num)
00061 {
00062 const char *format;
00063 static char buf[256];
00064
00065 if (append_num == -1)
00066 format = "/org/freedesktop/Hal/devices/scsi_host_%d";
00067 else
00068 format = "/org/freedesktop/Hal/devices/scsi_host_%d-%d";
00069
00070 snprintf (buf, 256, format,
00071 ds_property_get_int (d, "scsi_host.host"), append_num);
00072
00073 return buf;
00074 }
00075
00076
00086 static char *
00087 scsi_device_compute_udi (HalDevice * d, int append_num)
00088 {
00089 const char *format;
00090 static char buf[256];
00091
00092 if (append_num == -1)
00093 format =
00094 "/org/freedesktop/Hal/devices/scsi_device_%d_%d_%d_%d";
00095 else
00096 format =
00097 "/org/freedesktop/Hal/devices/scsi_device_%d_%d_%d_%d-%d";
00098
00099 snprintf (buf, 256, format,
00100 ds_property_get_int (d, "scsi_device.host"),
00101 ds_property_get_int (d, "scsi_device.bus"),
00102 ds_property_get_int (d, "scsi_device.target"),
00103 ds_property_get_int (d, "scsi_device.lun"), append_num);
00104
00105 return buf;
00106 }
00107
00108
00109
00110 static void visit_class_device_scsi_host_got_parent (HalDevice * parent,
00111 void *data1,
00112 void *data2);
00113
00122 void
00123 visit_class_device_scsi_host (const char *path,
00124 struct sysfs_class_device *class_device)
00125 {
00126 HalDevice *d;
00127 char *parent_sysfs_path;
00128 const char *last_elem;
00129 int host_num;
00130
00131 if (class_device->sysdevice == NULL) {
00132 HAL_INFO (("Skipping virtual class device at path %s\n",
00133 path));
00134 return;
00135 }
00136
00137 HAL_INFO (("scsi_host: sysdevice_path=%s, path=%s\n",
00138 class_device->sysdevice->path, path));
00139
00142 d = ds_device_new ();
00143 ds_property_set_string (d, "info.bus", "scsi_host");
00144 ds_property_set_string (d, "linux.sysfs_path", path);
00145 ds_property_set_string (d, "linux.sysfs_path_device",
00146 class_device->sysdevice->path);
00147
00148
00149 last_elem = get_last_element (path);
00150 sscanf (last_elem, "host%d", &host_num);
00151 ds_property_set_int (d, "scsi_host.host", host_num);
00152
00153
00154
00155 ds_property_set_string (d, "info.product", "SCSI Host Interface");
00156
00157 parent_sysfs_path =
00158 get_parent_sysfs_path (class_device->sysdevice->path);
00159
00160
00161
00162
00163
00164 ds_device_async_find_by_key_value_string
00165 ("linux.sysfs_path_device", parent_sysfs_path, TRUE,
00166 visit_class_device_scsi_host_got_parent, (void *) d, NULL,
00167 is_probing ? 0 : HAL_LINUX_HOTPLUG_TIMEOUT);
00168
00169 free (parent_sysfs_path);
00170 }
00171
00179 static void
00180 visit_class_device_scsi_host_got_parent (HalDevice * parent,
00181 void *data1, void *data2)
00182 {
00183 char *new_udi = NULL;
00184 HalDevice *new_d = NULL;
00185 HalDevice *d = (HalDevice *) data1;
00186
00187
00188
00189 if (parent != NULL) {
00190 ds_property_set_string (d, "info.parent", parent->udi);
00191 find_and_set_physical_device (d);
00192 ds_property_set_bool (d, "info.virtual", TRUE);
00193 } else {
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 new_d = ds_device_find (new_udi);
00205 if (new_d != NULL) {
00206 ds_gdl_add (new_d);
00207 }
00208 }
00209 }
00210
00211
00212
00213 static void visit_class_device_scsi_device_got_parent (HalDevice * parent,
00214 void *data1,
00215 void *data2);
00216
00225 void
00226 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 HAL_INFO (("Skipping virtual class device at path %s\n",
00236 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
00252
00253 last_elem = get_last_element (path);
00254 sscanf (last_elem, "%d:%d:%d:%d",
00255 &host_num, &bus_num, &target_num, &lun_num);
00256 ds_property_set_int (d, "scsi_device.host", host_num);
00257 ds_property_set_int (d, "scsi_device.bus", bus_num);
00258 ds_property_set_int (d, "scsi_device.target", target_num);
00259 ds_property_set_int (d, "scsi_device.lun", lun_num);
00260
00261
00262
00263 ds_property_set_string (d, "info.product", "SCSI Interface");
00264
00265
00266 parent_sysfs_path =
00267 get_parent_sysfs_path (class_device->sysdevice->path);
00268
00269
00270
00271
00272
00273 ds_device_async_find_by_key_value_string
00274 ("linux.sysfs_path_device", parent_sysfs_path, TRUE,
00275 visit_class_device_scsi_device_got_parent, (void *) d, NULL,
00276 is_probing ? 0 : HAL_LINUX_HOTPLUG_TIMEOUT);
00277
00278 free (parent_sysfs_path);
00279 }
00280
00288 static void
00289 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 ds_property_set_string (d, "info.parent", parent->udi);
00298 find_and_set_physical_device (d);
00299 ds_property_set_bool (d, "info.virtual", TRUE);
00300 } else {
00301 HAL_ERROR (("No parent for SCSI device!"));
00302 ds_device_destroy (d);
00303 return;
00304 }
00305
00306
00307
00308
00309 new_udi =
00310 rename_and_merge (d, scsi_device_compute_udi, "scsi_device");
00311 if (new_udi != NULL) {
00312 new_d = ds_device_find (new_udi);
00313 if (new_d != NULL) {
00314 ds_gdl_add (new_d);
00315 }
00316 }
00317 }
00318
00322 void
00323 linux_class_scsi_init ()
00324 {
00325 }
00326
00331 void
00332 linux_class_scsi_detection_done ()
00333 {
00334 }
00335
00339 void
00340 linux_class_scsi_shutdown ()
00341 {
00342 }
00343