/* * If fmt contains no % (or is exactly %s), use kstrdup_const. If fmt * (or the sole vararg) points to rodata, we will then save a memory * allocation and string copy. In any case, the return value should be * freed using kfree_const(). */ const char *kvasprintf_const(gfp_t gfp, const char *fmt, va_list ap) { if (!strchr(fmt, '%')) return kstrdup_const(fmt, gfp); if (!strcmp(fmt, "%s")) return kstrdup_const(va_arg(ap, const char*), gfp); return kvasprintf(gfp, fmt, ap); }
char *kasprintf(gfp_t gfp, const char *fmt, ...) { va_list ap; char *p; va_start(ap, fmt); p = kvasprintf(gfp, fmt, ap); va_end(ap); return p; }
char * kmem_vasprintf(const char *fmt, va_list ap) { va_list aq; char *ptr; do { va_copy(aq, ap); ptr = kvasprintf(kmem_flags_convert(KM_SLEEP), fmt, aq); va_end(aq); } while (ptr == NULL); return (ptr); }
char * kmem_asprintf(const char *fmt, ...) { va_list ap; char *ptr; do { va_start(ap, fmt); ptr = kvasprintf(kmem_flags_convert(KM_SLEEP), fmt, ap); va_end(ap); } while (ptr == NULL); return (ptr); }
char * kasprintf( int level, const char * fmt, ... ) { va_list ap; char *p; va_start(ap, fmt); p = kvasprintf(level, fmt, ap); va_end(ap); return p; }
/** * pci_request_irq - allocate an interrupt line for a PCI device * @dev: PCI device to operate on * @nr: device-relative interrupt vector index (0-based). * @handler: Function to be called when the IRQ occurs. * Primary handler for threaded interrupts. * If NULL and thread_fn != NULL the default primary handler is * installed. * @thread_fn: Function called from the IRQ handler thread * If NULL, no IRQ thread is created * @dev_id: Cookie passed back to the handler function * @fmt: Printf-like format string naming the handler * * This call allocates interrupt resources and enables the interrupt line and * IRQ handling. From the point this call is made @handler and @thread_fn may * be invoked. All interrupts requested using this function might be shared. * * @dev_id must not be NULL and must be globally unique. */ int pci_request_irq(struct pci_dev *dev, unsigned int nr, irq_handler_t handler, irq_handler_t thread_fn, void *dev_id, const char *fmt, ...) { va_list ap; int ret; char *devname; va_start(ap, fmt); devname = kvasprintf(GFP_KERNEL, fmt, ap); va_end(ap); ret = request_threaded_irq(pci_irq_vector(dev, nr), handler, thread_fn, IRQF_SHARED, devname, dev_id); if (ret) kfree(devname); return ret; }
/** * driver_add_kobj - add a kobject below the specified driver * @drv: requesting device driver * @kobj: kobject to add below this driver * @fmt: format string that names the kobject * * You really don't want to do this, this is only here due to one looney * iseries driver, go poke those developers if you are annoyed about * this... */ int driver_add_kobj(struct device_driver *drv, struct kobject *kobj, const char *fmt, ...) { va_list args; char *name; int ret; va_start(args, fmt); name = kvasprintf(GFP_KERNEL, fmt, args); va_end(args); if (!name) return -ENOMEM; ret = kobject_add(kobj, &drv->p->kobj, "%s", name); kfree(name); return ret; }
/** * drm_encoder_init - Init a preallocated encoder * @dev: drm device * @encoder: the encoder to init * @funcs: callbacks for this encoder * @encoder_type: user visible type of the encoder * @name: printf style format string for the encoder name, or NULL for default name * * Initialises a preallocated encoder. Encoder should be subclassed as part of * driver encoder objects. At driver unload time drm_encoder_cleanup() should be * called from the driver's destroy hook in &drm_encoder_funcs. * * Returns: * Zero on success, error code on failure. */ int drm_encoder_init(struct drm_device *dev, struct drm_encoder *encoder, const struct drm_encoder_funcs *funcs, int encoder_type, const char *name, ...) { int ret; drm_modeset_lock_all(dev); ret = drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER); if (ret) goto out_unlock; encoder->dev = dev; encoder->encoder_type = encoder_type; encoder->funcs = funcs; if (name) { va_list ap; va_start(ap, name); encoder->name = kvasprintf(GFP_KERNEL, name, ap); va_end(ap); } else { encoder->name = kasprintf(GFP_KERNEL, "%s-%d", drm_encoder_enum_list[encoder_type].name, encoder->base.id); } if (!encoder->name) { ret = -ENOMEM; goto out_put; } list_add_tail(&encoder->head, &dev->mode_config.encoder_list); encoder->index = dev->mode_config.num_encoder++; out_put: if (ret) drm_mode_object_unregister(dev, &encoder->base); out_unlock: drm_modeset_unlock_all(dev); return ret; }
/* * kobject_init_and_add (and its helper kobject_set_name_vargs) are * lifted here from 2.6.25, for the case of 2.6.24 compilation */ static int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, va_list vargs) { va_list aq; char *name; va_copy(aq, vargs); name = kvasprintf(GFP_KERNEL, fmt, vargs); va_end(aq); if (!name) return -ENOMEM; /* Free the old name, if necessary. */ kfree(kobj->k_name); /* Now, set the new name */ kobj->k_name = name; return 0; }
/** * kobject_set_name_vargs - Set the name of an kobject * @kobj: struct kobject to set the name of * @fmt: format string used to build the name * @vargs: vargs to format the string. */ static int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, va_list vargs) { const char *old_name = kobj->name; char *s; if (kobj->name && !fmt) return 0; kobj->name = kvasprintf(GFP_KERNEL, fmt, vargs); if (!kobj->name) return -ENOMEM; /* ewww... some of these buggers have '/' in the name ... */ while ((s = strchr(kobj->name, '/'))) s[0] = '!'; kfree(old_name); return 0; }
static void __printf(3, 4) __init __test(const char *expect, int elen, const char *fmt, ...) { va_list ap; int rand; char *p; if (elen >= BUF_SIZE) { pr_err("error in test suite: expected output length %d too long. Format was '%s'.\n", elen, fmt); failed_tests++; return; } va_start(ap, fmt); /* * Every fmt+args is subjected to four tests: Three where we * tell vsnprintf varying buffer sizes (plenty, not quite * enough and 0), and then we also test that kvasprintf would * be able to print it as expected. */ failed_tests += do_test(BUF_SIZE, expect, elen, fmt, ap); rand = 1 + prandom_u32_max(elen+1); /* Since elen < BUF_SIZE, we have 1 <= rand <= BUF_SIZE. */ failed_tests += do_test(rand, expect, elen, fmt, ap); failed_tests += do_test(0, expect, elen, fmt, ap); p = kvasprintf(GFP_KERNEL, fmt, ap); if (p) { total_tests++; if (memcmp(p, expect, elen+1)) { pr_warn("kvasprintf(..., \"%s\", ...) returned '%s', expected '%s'\n", fmt, p, expect); failed_tests++; } kfree(p); } va_end(ap); }
/** * xenbus_watch_pathfmt - register a watch on a sprintf-formatted path * @dev: xenbus device * @watch: watch to register * @callback: callback to register * @pathfmt: format of path to watch * * Register a watch on the given @path, using the given xenbus_watch * structure for storage, and the given @callback function as the callback. * Return 0 on success, or -errno on error. On success, the watched path * (@path/@path2) will be saved as @watch->node, and becomes the caller's to * kfree(). On error, watch->node will be NULL, so the caller has nothing to * free, the device will switch to %XenbusStateClosing, and the error will be * saved in the store. */ int xenbus_watch_pathfmt(struct xenbus_device *dev, struct xenbus_watch *watch, void (*callback)(struct xenbus_watch *, const char **, unsigned int), const char *pathfmt, ...) { int err; va_list ap; char *path; va_start(ap, pathfmt); path = kvasprintf(GFP_NOIO | __GFP_HIGH, pathfmt, ap); va_end(ap); if (!path) { xenbus_dev_fatal(dev, -ENOMEM, "allocating path for watch"); return -ENOMEM; } err = xenbus_watch_path(dev, path, watch, callback); if (err) kfree(path); return err; }
static char *__get_chkpt_filebase(long app_id, unsigned int chkpt_sn, const char *format, va_list args) { char *full_path; char *rel_path; full_path = get_chkpt_dir(app_id, chkpt_sn); if (IS_ERR(full_path)) goto err; rel_path = kvasprintf(GFP_KERNEL, format, args); if (!rel_path) { kfree(full_path); full_path = ERR_PTR(-ENOMEM); goto err; } strncat(full_path, rel_path, PATH_MAX); err: return full_path; }
int logger_write(const enum logidx index, const unsigned char prio, const char __kernel * const tag, const char __kernel * const fmt, ...) { int ret = 0; va_list vargs; struct file *filp = (struct file *)-ENOENT; mm_segment_t oldfs; struct iovec vec[3]; int tag_bytes = strlen(tag) + 1, msg_bytes; char *msg; va_start(vargs, fmt); msg = kvasprintf(GFP_ATOMIC, fmt, vargs); va_end(vargs); if (!msg) return -ENOMEM; if (in_interrupt()) { /* we have no choice since aio_write may be blocked */ printk(KERN_ALERT "%s", msg); goto out_free_message; } msg_bytes = strlen(msg) + 1; if (msg_bytes <= 1) /* empty message? */ goto out_free_message; /* don't bother, then */ if ((msg_bytes + tag_bytes + 1) > 2048) { ret = -E2BIG; goto out_free_message; } vec[0].iov_base = (unsigned char *) &prio; vec[0].iov_len = 1; vec[1].iov_base = (void *) tag; vec[1].iov_len = strlen(tag) + 1; vec[2].iov_base = (void *) msg; vec[2].iov_len = strlen(msg) + 1; oldfs = get_fs(); set_fs(KERNEL_DS); do { filp = filp_open("/dev/log/main", O_WRONLY, S_IRUSR); if (IS_ERR(filp) || !filp->f_op) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: filp_open /dev/log/main error\n", __FUNCTION__)); ret = -ENOENT; break; } if (filp->f_op->aio_write) { int nr_segs = sizeof(vec) / sizeof(vec[0]); int len = vec[0].iov_len + vec[1].iov_len + vec[2].iov_len; struct kiocb kiocb; init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = 0; kiocb.ki_left = len; kiocb.ki_nbytes = len; ret = filp->f_op->aio_write(&kiocb, vec, nr_segs, kiocb.ki_pos); } } while (0); if (!IS_ERR(filp)) { filp_close(filp, NULL); } set_fs(oldfs); out_free_message: if (msg) { kfree(msg); } return ret; }
/** * drm_universal_plane_init - Initialize a new universal plane object * @dev: DRM device * @plane: plane object to init * @possible_crtcs: bitmask of possible CRTCs * @funcs: callbacks for the new plane * @formats: array of supported formats (DRM_FORMAT\_\*) * @format_count: number of elements in @formats * @type: type of plane (overlay, primary, cursor) * @name: printf style format string for the plane name, or NULL for default name * * Initializes a plane object of type @type. * * Returns: * Zero on success, error code on failure. */ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, uint32_t possible_crtcs, const struct drm_plane_funcs *funcs, const uint32_t *formats, unsigned int format_count, enum drm_plane_type type, const char *name, ...) { struct drm_mode_config *config = &dev->mode_config; int ret; ret = drm_mode_object_add(dev, &plane->base, DRM_MODE_OBJECT_PLANE); if (ret) return ret; drm_modeset_lock_init(&plane->mutex); plane->base.properties = &plane->properties; plane->dev = dev; plane->funcs = funcs; plane->format_types = kmalloc_array(format_count, sizeof(uint32_t), GFP_KERNEL); if (!plane->format_types) { DRM_DEBUG_KMS("out of memory when allocating plane\n"); drm_mode_object_unregister(dev, &plane->base); return -ENOMEM; } if (name) { va_list ap; va_start(ap, name); plane->name = kvasprintf(GFP_KERNEL, name, ap); va_end(ap); } else { plane->name = kasprintf(GFP_KERNEL, "plane-%d", drm_num_planes(dev)); } if (!plane->name) { kfree(plane->format_types); drm_mode_object_unregister(dev, &plane->base); return -ENOMEM; } memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); plane->format_count = format_count; plane->possible_crtcs = possible_crtcs; plane->type = type; list_add_tail(&plane->head, &config->plane_list); plane->index = config->num_total_plane++; if (plane->type == DRM_PLANE_TYPE_OVERLAY) config->num_overlay_plane++; drm_object_attach_property(&plane->base, config->plane_type_property, plane->type); if (drm_core_check_feature(dev, DRIVER_ATOMIC)) { drm_object_attach_property(&plane->base, config->prop_fb_id, 0); drm_object_attach_property(&plane->base, config->prop_in_fence_fd, -1); drm_object_attach_property(&plane->base, config->prop_crtc_id, 0); drm_object_attach_property(&plane->base, config->prop_crtc_x, 0); drm_object_attach_property(&plane->base, config->prop_crtc_y, 0); drm_object_attach_property(&plane->base, config->prop_crtc_w, 0); drm_object_attach_property(&plane->base, config->prop_crtc_h, 0); drm_object_attach_property(&plane->base, config->prop_src_x, 0); drm_object_attach_property(&plane->base, config->prop_src_y, 0); drm_object_attach_property(&plane->base, config->prop_src_w, 0); drm_object_attach_property(&plane->base, config->prop_src_h, 0); } return 0; }
/** * drm_crtc_init_with_planes - Initialise a new CRTC object with * specified primary and cursor planes. * @dev: DRM device * @crtc: CRTC object to init * @primary: Primary plane for CRTC * @cursor: Cursor plane for CRTC * @funcs: callbacks for the new CRTC * @name: printf style format string for the CRTC name, or NULL for default name * * Inits a new object created as base part of a driver crtc object. Drivers * should use this function instead of drm_crtc_init(), which is only provided * for backwards compatibility with drivers which do not yet support universal * planes). For really simple hardware which has only 1 plane look at * drm_simple_display_pipe_init() instead. * * Returns: * Zero on success, error code on failure. */ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, struct drm_plane *primary, struct drm_plane *cursor, const struct drm_crtc_funcs *funcs, const char *name, ...) { struct drm_mode_config *config = &dev->mode_config; int ret; WARN_ON(primary && primary->type != DRM_PLANE_TYPE_PRIMARY); WARN_ON(cursor && cursor->type != DRM_PLANE_TYPE_CURSOR); /* crtc index is used with 32bit bitmasks */ if (WARN_ON(config->num_crtc >= 32)) return -EINVAL; WARN_ON(drm_drv_uses_atomic_modeset(dev) && (!funcs->atomic_destroy_state || !funcs->atomic_duplicate_state)); crtc->dev = dev; crtc->funcs = funcs; INIT_LIST_HEAD(&crtc->commit_list); spin_lock_init(&crtc->commit_lock); drm_modeset_lock_init(&crtc->mutex); ret = drm_mode_object_add(dev, &crtc->base, DRM_MODE_OBJECT_CRTC); if (ret) return ret; if (name) { va_list ap; va_start(ap, name); crtc->name = kvasprintf(GFP_KERNEL, name, ap); va_end(ap); } else { crtc->name = kasprintf(GFP_KERNEL, "crtc-%d", drm_num_crtcs(dev)); } if (!crtc->name) { drm_mode_object_unregister(dev, &crtc->base); return -ENOMEM; } crtc->fence_context = dma_fence_context_alloc(1); spin_lock_init(&crtc->fence_lock); snprintf(crtc->timeline_name, sizeof(crtc->timeline_name), "CRTC:%d-%s", crtc->base.id, crtc->name); crtc->base.properties = &crtc->properties; list_add_tail(&crtc->head, &config->crtc_list); crtc->index = config->num_crtc++; crtc->primary = primary; crtc->cursor = cursor; if (primary && !primary->possible_crtcs) primary->possible_crtcs = drm_crtc_mask(crtc); if (cursor && !cursor->possible_crtcs) cursor->possible_crtcs = drm_crtc_mask(crtc); ret = drm_crtc_crc_init(crtc); if (ret) { drm_mode_object_unregister(dev, &crtc->base); return ret; } if (drm_core_check_feature(dev, DRIVER_ATOMIC)) { drm_object_attach_property(&crtc->base, config->prop_active, 0); drm_object_attach_property(&crtc->base, config->prop_mode_id, 0); drm_object_attach_property(&crtc->base, config->prop_out_fence_ptr, 0); drm_object_attach_property(&crtc->base, config->prop_vrr_enabled, 0); } return 0; }
/** * drm_universal_plane_init - Initialize a new universal plane object * @dev: DRM device * @plane: plane object to init * @possible_crtcs: bitmask of possible CRTCs * @funcs: callbacks for the new plane * @formats: array of supported formats (DRM_FORMAT\_\*) * @format_count: number of elements in @formats * @format_modifiers: array of struct drm_format modifiers terminated by * DRM_FORMAT_MOD_INVALID * @type: type of plane (overlay, primary, cursor) * @name: printf style format string for the plane name, or NULL for default name * * Initializes a plane object of type @type. * * Returns: * Zero on success, error code on failure. */ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, uint32_t possible_crtcs, const struct drm_plane_funcs *funcs, const uint32_t *formats, unsigned int format_count, const uint64_t *format_modifiers, enum drm_plane_type type, const char *name, ...) { struct drm_mode_config *config = &dev->mode_config; unsigned int format_modifier_count = 0; int ret; /* plane index is used with 32bit bitmasks */ if (WARN_ON(config->num_total_plane >= 32)) return -EINVAL; WARN_ON(drm_drv_uses_atomic_modeset(dev) && (!funcs->atomic_destroy_state || !funcs->atomic_duplicate_state)); ret = drm_mode_object_add(dev, &plane->base, DRM_MODE_OBJECT_PLANE); if (ret) return ret; drm_modeset_lock_init(&plane->mutex); plane->base.properties = &plane->properties; plane->dev = dev; plane->funcs = funcs; plane->format_types = kmalloc_array(format_count, sizeof(uint32_t), GFP_KERNEL); if (!plane->format_types) { DRM_DEBUG_KMS("out of memory when allocating plane\n"); drm_mode_object_unregister(dev, &plane->base); return -ENOMEM; } /* * First driver to need more than 64 formats needs to fix this. Each * format is encoded as a bit and the current code only supports a u64. */ if (WARN_ON(format_count > 64)) return -EINVAL; if (format_modifiers) { const uint64_t *temp_modifiers = format_modifiers; while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID) format_modifier_count++; } plane->modifier_count = format_modifier_count; plane->modifiers = kmalloc_array(format_modifier_count, sizeof(format_modifiers[0]), GFP_KERNEL); if (format_modifier_count && !plane->modifiers) { DRM_DEBUG_KMS("out of memory when allocating plane\n"); kfree(plane->format_types); drm_mode_object_unregister(dev, &plane->base); return -ENOMEM; } if (name) { va_list ap; va_start(ap, name); plane->name = kvasprintf(GFP_KERNEL, name, ap); va_end(ap); } else { plane->name = kasprintf(GFP_KERNEL, "plane-%d", drm_num_planes(dev)); } if (!plane->name) { kfree(plane->format_types); kfree(plane->modifiers); drm_mode_object_unregister(dev, &plane->base); return -ENOMEM; } memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); plane->format_count = format_count; memcpy(plane->modifiers, format_modifiers, format_modifier_count * sizeof(format_modifiers[0])); plane->possible_crtcs = possible_crtcs; plane->type = type; list_add_tail(&plane->head, &config->plane_list); plane->index = config->num_total_plane++; drm_object_attach_property(&plane->base, config->plane_type_property, plane->type); if (drm_core_check_feature(dev, DRIVER_ATOMIC)) { drm_object_attach_property(&plane->base, config->prop_fb_id, 0); drm_object_attach_property(&plane->base, config->prop_in_fence_fd, -1); drm_object_attach_property(&plane->base, config->prop_crtc_id, 0); drm_object_attach_property(&plane->base, config->prop_crtc_x, 0); drm_object_attach_property(&plane->base, config->prop_crtc_y, 0); drm_object_attach_property(&plane->base, config->prop_crtc_w, 0); drm_object_attach_property(&plane->base, config->prop_crtc_h, 0); drm_object_attach_property(&plane->base, config->prop_src_x, 0); drm_object_attach_property(&plane->base, config->prop_src_y, 0); drm_object_attach_property(&plane->base, config->prop_src_w, 0); drm_object_attach_property(&plane->base, config->prop_src_h, 0); } if (config->allow_fb_modifiers) create_in_format_blob(dev, plane); return 0; }
const char *p; va_list va; char *q; u8 freeable; va_start(va, fmt); if (!strchr(fmt, '%')) { p = fmt; goto unformatted_string; } if (strcmp(fmt, "%s") == 0) { p = va_arg(va, const char *); goto unformatted_string; } q = kvasprintf(GFP_KERNEL, fmt, va); copied_string: if (!q) goto store_failure; freeable = 1; goto store_string; unformatted_string: if ((unsigned long)p >= (unsigned long)__start_rodata && (unsigned long)p < (unsigned long)__end_rodata) goto const_string; if (log && within_module_core((unsigned long)p, log->owner)) goto const_string; q = kstrdup(p, GFP_KERNEL); goto copied_string;