diff options
Diffstat (limited to 'drivers/platform/x86/dell_rbu.c')
-rw-r--r-- | drivers/platform/x86/dell_rbu.c | 173 |
1 files changed, 65 insertions, 108 deletions
diff --git a/drivers/platform/x86/dell_rbu.c b/drivers/platform/x86/dell_rbu.c index 7d5453326b43..03c3ff34bcf5 100644 --- a/drivers/platform/x86/dell_rbu.c +++ b/drivers/platform/x86/dell_rbu.c @@ -26,6 +26,9 @@ * * See Documentation/admin-guide/dell_rbu.rst for more info. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/init.h> #include <linux/module.h> #include <linux/slab.h> @@ -61,13 +64,11 @@ static struct _rbu_data { static char image_type[MAX_IMAGE_LENGTH + 1] = "mono"; module_param_string(image_type, image_type, sizeof (image_type), 0); -MODULE_PARM_DESC(image_type, - "BIOS image type. choose- mono or packet or init"); +MODULE_PARM_DESC(image_type, "BIOS image type. choose- mono or packet or init"); static unsigned long allocation_floor = 0x100000; module_param(allocation_floor, ulong, 0644); -MODULE_PARM_DESC(allocation_floor, - "Minimum address for allocations when using Packet mode"); +MODULE_PARM_DESC(allocation_floor, "Minimum address for allocations when using Packet mode"); struct packet_data { struct list_head list; @@ -100,10 +101,10 @@ static int create_packet(void *data, size_t length) void *packet_data_temp_buf = NULL; unsigned int idx = 0; - pr_debug("create_packet: entry \n"); + pr_debug("entry\n"); if (!rbu_data.packetsize) { - pr_debug("create_packet: packetsize not specified\n"); + pr_debug("packetsize not specified\n"); retval = -EINVAL; goto out_noalloc; } @@ -113,9 +114,7 @@ static int create_packet(void *data, size_t length) newpacket = kzalloc(sizeof (struct packet_data), GFP_KERNEL); if (!newpacket) { - printk(KERN_WARNING - "dell_rbu:%s: failed to allocate new " - "packet\n", __func__); + pr_warn("failed to allocate new packet\n"); retval = -ENOMEM; spin_lock(&rbu_data.lock); goto out_noalloc; @@ -134,17 +133,12 @@ static int create_packet(void *data, size_t length) * due to BIOS errata. This shouldn't be used for higher floors * or you will run out of mem trying to allocate the array. */ - packet_array_size = max( - (unsigned int)(allocation_floor / rbu_data.packetsize), - (unsigned int)1); + packet_array_size = max_t(unsigned int, allocation_floor / rbu_data.packetsize, 1); invalid_addr_packet_array = kcalloc(packet_array_size, sizeof(void *), GFP_KERNEL); if (!invalid_addr_packet_array) { - printk(KERN_WARNING - "dell_rbu:%s: failed to allocate " - "invalid_addr_packet_array \n", - __func__); + pr_warn("failed to allocate invalid_addr_packet_array\n"); retval = -ENOMEM; spin_lock(&rbu_data.lock); goto out_alloc_packet; @@ -154,9 +148,7 @@ static int create_packet(void *data, size_t length) packet_data_temp_buf = (unsigned char *) __get_free_pages(GFP_KERNEL, ordernum); if (!packet_data_temp_buf) { - printk(KERN_WARNING - "dell_rbu:%s: failed to allocate new " - "packet\n", __func__); + pr_warn("failed to allocate new packet\n"); retval = -ENOMEM; spin_lock(&rbu_data.lock); goto out_alloc_packet_array; @@ -164,7 +156,7 @@ static int create_packet(void *data, size_t length) if ((unsigned long)virt_to_phys(packet_data_temp_buf) < allocation_floor) { - pr_debug("packet 0x%lx below floor at 0x%lx.\n", + pr_debug("packet 0x%lx below floor at 0x%lx\n", (unsigned long)virt_to_phys( packet_data_temp_buf), allocation_floor); @@ -181,7 +173,7 @@ static int create_packet(void *data, size_t length) newpacket->data = packet_data_temp_buf; - pr_debug("create_packet: newpacket at physical addr %lx\n", + pr_debug("newpacket at physical addr %lx\n", (unsigned long)virt_to_phys(newpacket->data)); /* packets may not have fixed size */ @@ -195,16 +187,14 @@ static int create_packet(void *data, size_t length) memcpy(newpacket->data, data, length); - pr_debug("create_packet: exit \n"); + pr_debug("exit\n"); out_alloc_packet_array: /* always free packet array */ - for (;idx>0;idx--) { - pr_debug("freeing unused packet below floor 0x%lx.\n", - (unsigned long)virt_to_phys( - invalid_addr_packet_array[idx-1])); - free_pages((unsigned long)invalid_addr_packet_array[idx-1], - ordernum); + while (idx--) { + pr_debug("freeing unused packet below floor 0x%lx\n", + (unsigned long)virt_to_phys(invalid_addr_packet_array[idx])); + free_pages((unsigned long)invalid_addr_packet_array[idx], ordernum); } kfree(invalid_addr_packet_array); @@ -224,10 +214,9 @@ static int packetize_data(const u8 *data, size_t length) int packet_length; u8 *temp; u8 *end = (u8 *) data + length; - pr_debug("packetize_data: data length %zd\n", length); + pr_debug("data length %zd\n", length); if (!rbu_data.packetsize) { - printk(KERN_WARNING - "dell_rbu: packetsize not specified\n"); + pr_warn("packetsize not specified\n"); return -EIO; } @@ -255,15 +244,13 @@ static int packetize_data(const u8 *data, size_t length) return rc; } -static int do_packet_read(char *data, struct list_head *ptemp_list, +static int do_packet_read(char *data, struct packet_data *newpacket, int length, int bytes_read, int *list_read_count) { void *ptemp_buf; - struct packet_data *newpacket = NULL; int bytes_copied = 0; int j = 0; - newpacket = list_entry(ptemp_list, struct packet_data, list); *list_read_count += newpacket->length; if (*list_read_count > bytes_read) { @@ -291,7 +278,7 @@ static int do_packet_read(char *data, struct list_head *ptemp_list, static int packet_read_list(char *data, size_t * pread_length) { - struct list_head *ptemp_list; + struct packet_data *newpacket; int temp_count = 0; int bytes_copied = 0; int bytes_read = 0; @@ -305,9 +292,8 @@ static int packet_read_list(char *data, size_t * pread_length) remaining_bytes = *pread_length; bytes_read = rbu_data.packet_read_count; - ptemp_list = (&packet_data_head.list)->next; - while (!list_empty(ptemp_list)) { - bytes_copied = do_packet_read(pdest, ptemp_list, + list_for_each_entry(newpacket, (&packet_data_head.list)->next, list) { + bytes_copied = do_packet_read(pdest, newpacket, remaining_bytes, bytes_read, &temp_count); remaining_bytes -= bytes_copied; bytes_read += bytes_copied; @@ -318,8 +304,6 @@ static int packet_read_list(char *data, size_t * pread_length) */ if (remaining_bytes == 0) break; - - ptemp_list = ptemp_list->next; } /*finally set the bytes read */ *pread_length = bytes_read - rbu_data.packet_read_count; @@ -329,17 +313,11 @@ static int packet_read_list(char *data, size_t * pread_length) static void packet_empty_list(void) { - struct list_head *ptemp_list; - struct list_head *pnext_list; - struct packet_data *newpacket; + struct packet_data *newpacket, *tmp; + + list_for_each_entry_safe(newpacket, tmp, (&packet_data_head.list)->next, list) { + list_del(&newpacket->list); - ptemp_list = (&packet_data_head.list)->next; - while (!list_empty(ptemp_list)) { - newpacket = - list_entry(ptemp_list, struct packet_data, list); - pnext_list = ptemp_list->next; - list_del(ptemp_list); - ptemp_list = pnext_list; /* * zero out the RBU packet memory before freeing * to make sure there are no stale RBU packets left in memory @@ -407,8 +385,7 @@ static int img_update_realloc(unsigned long size) * check for corruption */ if ((size != 0) && (rbu_data.image_update_buffer == NULL)) { - printk(KERN_ERR "dell_rbu:%s: corruption " - "check failed\n", __func__); + pr_err("corruption check failed\n"); return -EINVAL; } /* @@ -430,8 +407,7 @@ static int img_update_realloc(unsigned long size) (unsigned char *)__get_free_pages(GFP_DMA32, ordernum); spin_lock(&rbu_data.lock); if (!image_update_buffer) { - pr_debug("Not enough memory for image update:" - "size = %ld\n", size); + pr_debug("Not enough memory for image update: size = %ld\n", size); return -ENOMEM; } @@ -455,15 +431,14 @@ static ssize_t read_packet_data(char *buffer, loff_t pos, size_t count) /* check to see if we have something to return */ if (rbu_data.num_packets == 0) { - pr_debug("read_packet_data: no packets written\n"); + pr_debug("no packets written\n"); retval = -ENOMEM; goto read_rbu_data_exit; } if (pos > rbu_data.imagesize) { retval = 0; - printk(KERN_WARNING "dell_rbu:read_packet_data: " - "data underrun\n"); + pr_warn("data underrun\n"); goto read_rbu_data_exit; } @@ -489,8 +464,7 @@ static ssize_t read_rbu_mono_data(char *buffer, loff_t pos, size_t count) /* check to see if we have something to return */ if ((rbu_data.image_update_buffer == NULL) || (rbu_data.bios_image_size == 0)) { - pr_debug("read_rbu_data_mono: image_update_buffer %p ," - "bios_image_size %lu\n", + pr_debug("image_update_buffer %p, bios_image_size %lu\n", rbu_data.image_update_buffer, rbu_data.bios_image_size); return -ENOMEM; @@ -500,9 +474,9 @@ static ssize_t read_rbu_mono_data(char *buffer, loff_t pos, size_t count) rbu_data.image_update_buffer, rbu_data.bios_image_size); } -static ssize_t read_rbu_data(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buffer, loff_t pos, size_t count) +static ssize_t data_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buffer, loff_t pos, size_t count) { ssize_t ret_count = 0; @@ -513,11 +487,12 @@ static ssize_t read_rbu_data(struct file *filp, struct kobject *kobj, else if (!strcmp(image_type, "packet")) ret_count = read_packet_data(buffer, pos, count); else - pr_debug("read_rbu_data: invalid image type specified\n"); + pr_debug("invalid image type specified\n"); spin_unlock(&rbu_data.lock); return ret_count; } +static BIN_ATTR_RO(data, 0); static void callbackfn_rbu(const struct firmware *fw, void *context) { @@ -548,15 +523,15 @@ static void callbackfn_rbu(const struct firmware *fw, void *context) */ packet_empty_list(); } else - pr_debug("invalid image type specified.\n"); + pr_debug("invalid image type specified\n"); spin_unlock(&rbu_data.lock); out: release_firmware(fw); } -static ssize_t read_rbu_image_type(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buffer, loff_t pos, size_t count) +static ssize_t image_type_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buffer, loff_t pos, size_t count) { int size = 0; if (!pos) @@ -564,9 +539,9 @@ static ssize_t read_rbu_image_type(struct file *filp, struct kobject *kobj, return size; } -static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buffer, loff_t pos, size_t count) +static ssize_t image_type_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buffer, loff_t pos, size_t count) { int rc = count; int req_firm_rc = 0; @@ -602,9 +577,7 @@ static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj, &rbu_device->dev, GFP_KERNEL, &context, callbackfn_rbu); if (req_firm_rc) { - printk(KERN_ERR - "dell_rbu:%s request_firmware_nowait" - " failed %d\n", __func__, rc); + pr_err("request_firmware_nowait failed %d\n", rc); rc = -EIO; } else rbu_data.entry_created = 1; @@ -612,7 +585,7 @@ static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj, spin_lock(&rbu_data.lock); } } else { - printk(KERN_WARNING "dell_rbu: image_type is invalid\n"); + pr_warn("image_type is invalid\n"); spin_unlock(&rbu_data.lock); return -EINVAL; } @@ -624,10 +597,11 @@ static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj, return rc; } +static BIN_ATTR_RW(image_type, 0); -static ssize_t read_rbu_packet_size(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buffer, loff_t pos, size_t count) +static ssize_t packet_size_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buffer, loff_t pos, size_t count) { int size = 0; if (!pos) { @@ -638,9 +612,9 @@ static ssize_t read_rbu_packet_size(struct file *filp, struct kobject *kobj, return size; } -static ssize_t write_rbu_packet_size(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buffer, loff_t pos, size_t count) +static ssize_t packet_size_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buffer, loff_t pos, size_t count) { unsigned long temp; spin_lock(&rbu_data.lock); @@ -652,22 +626,17 @@ static ssize_t write_rbu_packet_size(struct file *filp, struct kobject *kobj, spin_unlock(&rbu_data.lock); return count; } +static BIN_ATTR_RW(packet_size, 0); -static struct bin_attribute rbu_data_attr = { - .attr = {.name = "data", .mode = 0444}, - .read = read_rbu_data, -}; - -static struct bin_attribute rbu_image_type_attr = { - .attr = {.name = "image_type", .mode = 0644}, - .read = read_rbu_image_type, - .write = write_rbu_image_type, +static struct bin_attribute *rbu_bin_attrs[] = { + &bin_attr_data, + &bin_attr_image_type, + &bin_attr_packet_size, + NULL }; -static struct bin_attribute rbu_packet_size_attr = { - .attr = {.name = "packet_size", .mode = 0644}, - .read = read_rbu_packet_size, - .write = write_rbu_packet_size, +static const struct attribute_group rbu_group = { + .bin_attrs = rbu_bin_attrs, }; static int __init dcdrbu_init(void) @@ -678,30 +647,17 @@ static int __init dcdrbu_init(void) init_packet_head(); rbu_device = platform_device_register_simple("dell_rbu", -1, NULL, 0); if (IS_ERR(rbu_device)) { - printk(KERN_ERR - "dell_rbu:%s:platform_device_register_simple " - "failed\n", __func__); + pr_err("platform_device_register_simple failed\n"); return PTR_ERR(rbu_device); } - rc = sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_data_attr); + rc = sysfs_create_group(&rbu_device->dev.kobj, &rbu_group); if (rc) goto out_devreg; - rc = sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr); - if (rc) - goto out_data; - rc = sysfs_create_bin_file(&rbu_device->dev.kobj, - &rbu_packet_size_attr); - if (rc) - goto out_imtype; rbu_data.entry_created = 0; return 0; -out_imtype: - sysfs_remove_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr); -out_data: - sysfs_remove_bin_file(&rbu_device->dev.kobj, &rbu_data_attr); out_devreg: platform_device_unregister(rbu_device); return rc; @@ -713,6 +669,7 @@ static __exit void dcdrbu_exit(void) packet_empty_list(); img_update_free(); spin_unlock(&rbu_data.lock); + sysfs_remove_group(&rbu_device->dev.kobj, &rbu_group); platform_device_unregister(rbu_device); } |