/* This is the beginning of hotplug even handling */ void hotplug_event_begin_add_devinfo (HalDevice *d, HalDevice *parent, DevinfoDevHandler *handler, void *end_token) { HotplugEvent *hotplug_event = (HotplugEvent *)end_token; HAL_INFO(("Preprobing udi=%s", hal_device_get_udi (d))); if (parent == NULL && (strcmp(hotplug_event->un.devfs.devfs_path, "/") != 0)) { HAL_ERROR (("Parent is NULL, devfs_path=%s", hotplug_event->un.devfs.devfs_path)); goto skip; } if (parent != NULL && hal_device_property_get_bool (parent, "info.ignore")) { HAL_INFO (("Ignoring device since parent has info.ignore==TRUE")); goto skip; } if (hal_device_store_find (hald_get_tdl (), hal_device_get_udi (d)) == NULL) { /* add to TDL so preprobing callouts and prober can access it */ hal_device_store_add (hald_get_tdl (), d); } /* Process preprobe fdi files */ di_search_and_merge (d, DEVICE_INFO_TYPE_PREPROBE); /* Run preprobe callouts */ hal_util_callout_device_preprobe (d, devinfo_callouts_preprobing_done, end_token, handler); return; skip: if (hal_device_store_find (hald_get_tdl (), hal_device_get_udi (d))) hal_device_store_remove (hald_get_tdl (), d); g_object_unref (d); hotplug_event_end (end_token); return; }
HalDevice * devinfo_mass_add(HalDevice *parent, const char *devnode, char *devfs_path, char *device_type) { HalDevice *d = NULL, *gparent = NULL; prop_dictionary_t dict; struct disklabel label; struct stat st; const char *driver; char *rdevpath, *devpath; char *childnode; char *parent_devnode, *gparent_devnode = NULL; char *gparent_udi; int16_t unit; int i, fd; struct scsipi_inquiry_data inqbuf; struct scsipi_inquiry cmd; bool scsiinq_status; char *storage_model = NULL, *storage_vendor = NULL; if (drvctl_find_device (devnode, &dict) == FALSE || dict == NULL) return NULL; if (prop_dictionary_get_int16 (dict, "device-unit", &unit) == false || prop_dictionary_get_cstring_nocopy (dict, "device-driver", &driver) == false) { prop_object_release (dict); return NULL; } if (strcmp (driver, "wd") != 0 && strcmp (driver, "sd") != 0 && strcmp (driver, "ld") != 0) { prop_object_release (dict); return NULL; } sleep (1); devpath = g_strdup_printf ("/dev/%s%c", devnode, RAW_PART + 'a'); rdevpath = g_strdup_printf ("/dev/r%s%c", devnode, RAW_PART + 'a'); HAL_INFO ((" going to open %s", rdevpath)); fd = open (rdevpath, O_RDONLY); if (fd < 0) { HAL_WARNING (("couldn't open %s: %s", rdevpath, strerror (errno))); g_free (rdevpath); g_free (devpath); return NULL; } HAL_INFO ((" going to DIOCGDINFO %s", rdevpath)); if (ioctl (fd, DIOCGDINFO, &label) == -1) { HAL_WARNING (("DIOCGDINFO failed on %s: %s", rdevpath, strerror (errno))); g_free (rdevpath); g_free (devpath); close (fd); return NULL; } if (strcmp (driver, "sd") == 0) { memset(&cmd, 0, sizeof (cmd)); memset(&inqbuf, 0, sizeof (inqbuf)); cmd.opcode = INQUIRY; cmd.length = sizeof (inqbuf); scsiinq_status = scsi_command (fd, &cmd, sizeof (cmd), &inqbuf, sizeof (inqbuf), 10000, SCCMD_READ); } else scsiinq_status = false; close (fd); d = hal_device_new (); devinfo_set_default_properties (d, parent, devnode, devfs_path); hal_device_add_capability (d, "block"); hal_device_property_set_string (d, "info.subsystem", "block"); hal_device_property_set_string (d, "block.device", devpath); if (stat (devpath, &st) == 0) { hal_device_property_set_int (d, "block.major", major (st.st_rdev)); hal_device_property_set_int (d, "block.minor", minor (st.st_rdev)); } hal_device_property_set_bool (d, "block.is_volume", FALSE); hal_device_property_set_bool (d, "block.no_partitions", FALSE); hal_device_property_set_bool (d, "block.have_scanned", TRUE); hal_device_add_capability (d, "storage"); hal_device_property_set_string (d, "info.category", "storage"); parent_devnode = hal_device_property_get_string (parent, "netbsd.device"); gparent_udi = hal_device_property_get_string (parent, "info.parent"); if (gparent_udi) { gparent = hal_device_store_find (hald_get_gdl (), gparent_udi); if (gparent) gparent_devnode = hal_device_property_get_string (gparent, "netbsd.device"); } if (gparent_devnode && strstr (gparent_devnode, "umass") == gparent_devnode) hal_device_property_set_string (d, "storage.bus", "usb"); else if (parent_devnode && strstr (parent_devnode, "atabus") == parent_devnode) hal_device_property_set_string (d, "storage.bus", "ide"); else hal_device_property_set_string (d, "storage.bus", "scsi"); hal_device_property_set_string (d, "storage.device_type", "disk"); hal_device_property_set_bool (d, "storage.removable", label.d_flags & D_REMOVABLE ? TRUE : FALSE); if (label.d_flags & D_REMOVABLE) { hal_device_property_set_bool (d, "storage.removable.media_available", TRUE); hal_device_property_set_uint64 (d, "storage.removable.media_size", (uint64_t)label.d_secsize * (uint64_t)label.d_secperunit); hal_device_property_set_uint64 (d, "storage.size", 0); hal_device_property_set_bool (d, "storage.hotpluggable", TRUE); hal_device_property_set_bool (d, "storage.automount_enabled_hint", TRUE); } else { hal_device_property_set_bool (d, "storage.removable.media_available", FALSE); hal_device_property_set_uint64 (d, "storage.removable.media_size", 0); hal_device_property_set_uint64 (d, "storage.size", (uint64_t)label.d_secsize * (uint64_t)label.d_secperunit); hal_device_property_set_bool (d, "storage.hotpluggable", FALSE); hal_device_property_set_bool (d, "storage.automount_enabled_hint", FALSE); } hal_device_property_set_bool (d, "storage.no_partitions_hint", FALSE); hal_device_property_set_bool (d, "storage.requires_eject", FALSE); hal_device_property_set_bool (d, "storage.removable.support_async_notification", FALSE); hal_device_property_set_string (d, "storage.partitioning_scheme", "mbr"); hal_device_property_set_string (d, "storage.originating_device", hal_device_property_get_string (d, "info.udi")); if (scsiinq_status == true) { storage_model = rtrim_copy(inqbuf.product, sizeof (inqbuf.product)); storage_vendor = rtrim_copy(inqbuf.vendor, sizeof (inqbuf.vendor)); } if (storage_model) { hal_device_property_set_string (d, "storage.model", storage_model); free (storage_model); } else hal_device_property_set_string (d, "storage.model", label.d_packname); if (storage_vendor) { hal_device_property_set_string (d, "storage.vendor", storage_vendor); free (storage_vendor); } else hal_device_property_set_string (d, "storage.vendor", label.d_typename); devinfo_add_enqueue (d, devfs_path, &devinfo_mass_handler); for (i = 0; i < MAXPARTITIONS; i++) { const char *fstype; fstype = devinfo_mass_get_fstype(label.d_partitions[i].p_fstype); if (fstype == NULL) continue; childnode = g_strdup_printf ("%s%c", devnode, 'a' + i); HAL_INFO ((" adding %s on %s", childnode, rdevpath)); devinfo_mass_disklabel_add (d, childnode, childnode, childnode); g_free (childnode); } HAL_INFO ((" returning")); g_free (rdevpath); g_free (devpath); done: prop_object_release (dict); return d; }