Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.2-rc3 731 lines 19 kB view raw
1/* 2 * dell_rbu.c 3 * Bios Update driver for Dell systems 4 * Author: Dell Inc 5 * Abhay Salunke <abhay_salunke@dell.com> 6 * 7 * Copyright (C) 2005 Dell Inc. 8 * 9 * Remote BIOS Update (rbu) driver is used for updating DELL BIOS by 10 * creating entries in the /sys file systems on Linux 2.6 and higher 11 * kernels. The driver supports two mechanism to update the BIOS namely 12 * contiguous and packetized. Both these methods still require having some 13 * application to set the CMOS bit indicating the BIOS to update itself 14 * after a reboot. 15 * 16 * Contiguous method: 17 * This driver writes the incoming data in a monolithic image by allocating 18 * contiguous physical pages large enough to accommodate the incoming BIOS 19 * image size. 20 * 21 * Packetized method: 22 * The driver writes the incoming packet image by allocating a new packet 23 * on every time the packet data is written. This driver requires an 24 * application to break the BIOS image in to fixed sized packet chunks. 25 * 26 * See Documentation/dell_rbu.txt for more info. 27 * 28 * This program is free software; you can redistribute it and/or modify 29 * it under the terms of the GNU General Public License v2.0 as published by 30 * the Free Software Foundation 31 * 32 * This program is distributed in the hope that it will be useful, 33 * but WITHOUT ANY WARRANTY; without even the implied warranty of 34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 35 * GNU General Public License for more details. 36 */ 37#include <linux/init.h> 38#include <linux/module.h> 39#include <linux/slab.h> 40#include <linux/string.h> 41#include <linux/errno.h> 42#include <linux/blkdev.h> 43#include <linux/platform_device.h> 44#include <linux/spinlock.h> 45#include <linux/moduleparam.h> 46#include <linux/firmware.h> 47#include <linux/dma-mapping.h> 48#include <asm/set_memory.h> 49 50MODULE_AUTHOR("Abhay Salunke <abhay_salunke@dell.com>"); 51MODULE_DESCRIPTION("Driver for updating BIOS image on DELL systems"); 52MODULE_LICENSE("GPL"); 53MODULE_VERSION("3.2"); 54 55#define BIOS_SCAN_LIMIT 0xffffffff 56#define MAX_IMAGE_LENGTH 16 57static struct _rbu_data { 58 void *image_update_buffer; 59 unsigned long image_update_buffer_size; 60 unsigned long bios_image_size; 61 int image_update_ordernum; 62 spinlock_t lock; 63 unsigned long packet_read_count; 64 unsigned long num_packets; 65 unsigned long packetsize; 66 unsigned long imagesize; 67 int entry_created; 68} rbu_data; 69 70static char image_type[MAX_IMAGE_LENGTH + 1] = "mono"; 71module_param_string(image_type, image_type, sizeof (image_type), 0); 72MODULE_PARM_DESC(image_type, 73 "BIOS image type. choose- mono or packet or init"); 74 75static unsigned long allocation_floor = 0x100000; 76module_param(allocation_floor, ulong, 0644); 77MODULE_PARM_DESC(allocation_floor, 78 "Minimum address for allocations when using Packet mode"); 79 80struct packet_data { 81 struct list_head list; 82 size_t length; 83 void *data; 84 int ordernum; 85}; 86 87static struct packet_data packet_data_head; 88 89static struct platform_device *rbu_device; 90static int context; 91 92static void init_packet_head(void) 93{ 94 INIT_LIST_HEAD(&packet_data_head.list); 95 rbu_data.packet_read_count = 0; 96 rbu_data.num_packets = 0; 97 rbu_data.packetsize = 0; 98 rbu_data.imagesize = 0; 99} 100 101static int create_packet(void *data, size_t length) 102{ 103 struct packet_data *newpacket; 104 int ordernum = 0; 105 int retval = 0; 106 unsigned int packet_array_size = 0; 107 void **invalid_addr_packet_array = NULL; 108 void *packet_data_temp_buf = NULL; 109 unsigned int idx = 0; 110 111 pr_debug("create_packet: entry \n"); 112 113 if (!rbu_data.packetsize) { 114 pr_debug("create_packet: packetsize not specified\n"); 115 retval = -EINVAL; 116 goto out_noalloc; 117 } 118 119 spin_unlock(&rbu_data.lock); 120 121 newpacket = kzalloc(sizeof (struct packet_data), GFP_KERNEL); 122 123 if (!newpacket) { 124 printk(KERN_WARNING 125 "dell_rbu:%s: failed to allocate new " 126 "packet\n", __func__); 127 retval = -ENOMEM; 128 spin_lock(&rbu_data.lock); 129 goto out_noalloc; 130 } 131 132 ordernum = get_order(length); 133 134 /* 135 * BIOS errata mean we cannot allocate packets below 1MB or they will 136 * be overwritten by BIOS. 137 * 138 * array to temporarily hold packets 139 * that are below the allocation floor 140 * 141 * NOTE: very simplistic because we only need the floor to be at 1MB 142 * due to BIOS errata. This shouldn't be used for higher floors 143 * or you will run out of mem trying to allocate the array. 144 */ 145 packet_array_size = max( 146 (unsigned int)(allocation_floor / rbu_data.packetsize), 147 (unsigned int)1); 148 invalid_addr_packet_array = kcalloc(packet_array_size, sizeof(void *), 149 GFP_KERNEL); 150 151 if (!invalid_addr_packet_array) { 152 printk(KERN_WARNING 153 "dell_rbu:%s: failed to allocate " 154 "invalid_addr_packet_array \n", 155 __func__); 156 retval = -ENOMEM; 157 spin_lock(&rbu_data.lock); 158 goto out_alloc_packet; 159 } 160 161 while (!packet_data_temp_buf) { 162 packet_data_temp_buf = (unsigned char *) 163 __get_free_pages(GFP_KERNEL, ordernum); 164 if (!packet_data_temp_buf) { 165 printk(KERN_WARNING 166 "dell_rbu:%s: failed to allocate new " 167 "packet\n", __func__); 168 retval = -ENOMEM; 169 spin_lock(&rbu_data.lock); 170 goto out_alloc_packet_array; 171 } 172 173 if ((unsigned long)virt_to_phys(packet_data_temp_buf) 174 < allocation_floor) { 175 pr_debug("packet 0x%lx below floor at 0x%lx.\n", 176 (unsigned long)virt_to_phys( 177 packet_data_temp_buf), 178 allocation_floor); 179 invalid_addr_packet_array[idx++] = packet_data_temp_buf; 180 packet_data_temp_buf = NULL; 181 } 182 } 183 /* 184 * set to uncachable or it may never get written back before reboot 185 */ 186 set_memory_uc((unsigned long)packet_data_temp_buf, 1 << ordernum); 187 188 spin_lock(&rbu_data.lock); 189 190 newpacket->data = packet_data_temp_buf; 191 192 pr_debug("create_packet: newpacket at physical addr %lx\n", 193 (unsigned long)virt_to_phys(newpacket->data)); 194 195 /* packets may not have fixed size */ 196 newpacket->length = length; 197 newpacket->ordernum = ordernum; 198 ++rbu_data.num_packets; 199 200 /* initialize the newly created packet headers */ 201 INIT_LIST_HEAD(&newpacket->list); 202 list_add_tail(&newpacket->list, &packet_data_head.list); 203 204 memcpy(newpacket->data, data, length); 205 206 pr_debug("create_packet: exit \n"); 207 208out_alloc_packet_array: 209 /* always free packet array */ 210 for (;idx>0;idx--) { 211 pr_debug("freeing unused packet below floor 0x%lx.\n", 212 (unsigned long)virt_to_phys( 213 invalid_addr_packet_array[idx-1])); 214 free_pages((unsigned long)invalid_addr_packet_array[idx-1], 215 ordernum); 216 } 217 kfree(invalid_addr_packet_array); 218 219out_alloc_packet: 220 /* if error, free data */ 221 if (retval) 222 kfree(newpacket); 223 224out_noalloc: 225 return retval; 226} 227 228static int packetize_data(const u8 *data, size_t length) 229{ 230 int rc = 0; 231 int done = 0; 232 int packet_length; 233 u8 *temp; 234 u8 *end = (u8 *) data + length; 235 pr_debug("packetize_data: data length %zd\n", length); 236 if (!rbu_data.packetsize) { 237 printk(KERN_WARNING 238 "dell_rbu: packetsize not specified\n"); 239 return -EIO; 240 } 241 242 temp = (u8 *) data; 243 244 /* packetize the hunk */ 245 while (!done) { 246 if ((temp + rbu_data.packetsize) < end) 247 packet_length = rbu_data.packetsize; 248 else { 249 /* this is the last packet */ 250 packet_length = end - temp; 251 done = 1; 252 } 253 254 if ((rc = create_packet(temp, packet_length))) 255 return rc; 256 257 pr_debug("%p:%td\n", temp, (end - temp)); 258 temp += packet_length; 259 } 260 261 rbu_data.imagesize = length; 262 263 return rc; 264} 265 266static int do_packet_read(char *data, struct list_head *ptemp_list, 267 int length, int bytes_read, int *list_read_count) 268{ 269 void *ptemp_buf; 270 struct packet_data *newpacket = NULL; 271 int bytes_copied = 0; 272 int j = 0; 273 274 newpacket = list_entry(ptemp_list, struct packet_data, list); 275 *list_read_count += newpacket->length; 276 277 if (*list_read_count > bytes_read) { 278 /* point to the start of unread data */ 279 j = newpacket->length - (*list_read_count - bytes_read); 280 /* point to the offset in the packet buffer */ 281 ptemp_buf = (u8 *) newpacket->data + j; 282 /* 283 * check if there is enough room in 284 * * the incoming buffer 285 */ 286 if (length > (*list_read_count - bytes_read)) 287 /* 288 * copy what ever is there in this 289 * packet and move on 290 */ 291 bytes_copied = (*list_read_count - bytes_read); 292 else 293 /* copy the remaining */ 294 bytes_copied = length; 295 memcpy(data, ptemp_buf, bytes_copied); 296 } 297 return bytes_copied; 298} 299 300static int packet_read_list(char *data, size_t * pread_length) 301{ 302 struct list_head *ptemp_list; 303 int temp_count = 0; 304 int bytes_copied = 0; 305 int bytes_read = 0; 306 int remaining_bytes = 0; 307 char *pdest = data; 308 309 /* check if we have any packets */ 310 if (0 == rbu_data.num_packets) 311 return -ENOMEM; 312 313 remaining_bytes = *pread_length; 314 bytes_read = rbu_data.packet_read_count; 315 316 ptemp_list = (&packet_data_head.list)->next; 317 while (!list_empty(ptemp_list)) { 318 bytes_copied = do_packet_read(pdest, ptemp_list, 319 remaining_bytes, bytes_read, &temp_count); 320 remaining_bytes -= bytes_copied; 321 bytes_read += bytes_copied; 322 pdest += bytes_copied; 323 /* 324 * check if we reached end of buffer before reaching the 325 * last packet 326 */ 327 if (remaining_bytes == 0) 328 break; 329 330 ptemp_list = ptemp_list->next; 331 } 332 /*finally set the bytes read */ 333 *pread_length = bytes_read - rbu_data.packet_read_count; 334 rbu_data.packet_read_count = bytes_read; 335 return 0; 336} 337 338static void packet_empty_list(void) 339{ 340 struct list_head *ptemp_list; 341 struct list_head *pnext_list; 342 struct packet_data *newpacket; 343 344 ptemp_list = (&packet_data_head.list)->next; 345 while (!list_empty(ptemp_list)) { 346 newpacket = 347 list_entry(ptemp_list, struct packet_data, list); 348 pnext_list = ptemp_list->next; 349 list_del(ptemp_list); 350 ptemp_list = pnext_list; 351 /* 352 * zero out the RBU packet memory before freeing 353 * to make sure there are no stale RBU packets left in memory 354 */ 355 memset(newpacket->data, 0, rbu_data.packetsize); 356 set_memory_wb((unsigned long)newpacket->data, 357 1 << newpacket->ordernum); 358 free_pages((unsigned long) newpacket->data, 359 newpacket->ordernum); 360 kfree(newpacket); 361 } 362 rbu_data.packet_read_count = 0; 363 rbu_data.num_packets = 0; 364 rbu_data.imagesize = 0; 365} 366 367/* 368 * img_update_free: Frees the buffer allocated for storing BIOS image 369 * Always called with lock held and returned with lock held 370 */ 371static void img_update_free(void) 372{ 373 if (!rbu_data.image_update_buffer) 374 return; 375 /* 376 * zero out this buffer before freeing it to get rid of any stale 377 * BIOS image copied in memory. 378 */ 379 memset(rbu_data.image_update_buffer, 0, 380 rbu_data.image_update_buffer_size); 381 free_pages((unsigned long) rbu_data.image_update_buffer, 382 rbu_data.image_update_ordernum); 383 384 /* 385 * Re-initialize the rbu_data variables after a free 386 */ 387 rbu_data.image_update_ordernum = -1; 388 rbu_data.image_update_buffer = NULL; 389 rbu_data.image_update_buffer_size = 0; 390 rbu_data.bios_image_size = 0; 391} 392 393/* 394 * img_update_realloc: This function allocates the contiguous pages to 395 * accommodate the requested size of data. The memory address and size 396 * values are stored globally and on every call to this function the new 397 * size is checked to see if more data is required than the existing size. 398 * If true the previous memory is freed and new allocation is done to 399 * accommodate the new size. If the incoming size is less then than the 400 * already allocated size, then that memory is reused. This function is 401 * called with lock held and returns with lock held. 402 */ 403static int img_update_realloc(unsigned long size) 404{ 405 unsigned char *image_update_buffer = NULL; 406 unsigned long img_buf_phys_addr; 407 int ordernum; 408 409 /* 410 * check if the buffer of sufficient size has been 411 * already allocated 412 */ 413 if (rbu_data.image_update_buffer_size >= size) { 414 /* 415 * check for corruption 416 */ 417 if ((size != 0) && (rbu_data.image_update_buffer == NULL)) { 418 printk(KERN_ERR "dell_rbu:%s: corruption " 419 "check failed\n", __func__); 420 return -EINVAL; 421 } 422 /* 423 * we have a valid pre-allocated buffer with 424 * sufficient size 425 */ 426 return 0; 427 } 428 429 /* 430 * free any previously allocated buffer 431 */ 432 img_update_free(); 433 434 spin_unlock(&rbu_data.lock); 435 436 ordernum = get_order(size); 437 image_update_buffer = 438 (unsigned char *)__get_free_pages(GFP_DMA32, ordernum); 439 spin_lock(&rbu_data.lock); 440 if (!image_update_buffer) { 441 pr_debug("Not enough memory for image update:" 442 "size = %ld\n", size); 443 return -ENOMEM; 444 } 445 446 img_buf_phys_addr = (unsigned long)virt_to_phys(image_update_buffer); 447 if (WARN_ON_ONCE(img_buf_phys_addr > BIOS_SCAN_LIMIT)) 448 return -EINVAL; /* can't happen per definition */ 449 450 rbu_data.image_update_buffer = image_update_buffer; 451 rbu_data.image_update_buffer_size = size; 452 rbu_data.bios_image_size = rbu_data.image_update_buffer_size; 453 rbu_data.image_update_ordernum = ordernum; 454 return 0; 455} 456 457static ssize_t read_packet_data(char *buffer, loff_t pos, size_t count) 458{ 459 int retval; 460 size_t bytes_left; 461 size_t data_length; 462 char *ptempBuf = buffer; 463 464 /* check to see if we have something to return */ 465 if (rbu_data.num_packets == 0) { 466 pr_debug("read_packet_data: no packets written\n"); 467 retval = -ENOMEM; 468 goto read_rbu_data_exit; 469 } 470 471 if (pos > rbu_data.imagesize) { 472 retval = 0; 473 printk(KERN_WARNING "dell_rbu:read_packet_data: " 474 "data underrun\n"); 475 goto read_rbu_data_exit; 476 } 477 478 bytes_left = rbu_data.imagesize - pos; 479 data_length = min(bytes_left, count); 480 481 if ((retval = packet_read_list(ptempBuf, &data_length)) < 0) 482 goto read_rbu_data_exit; 483 484 if ((pos + count) > rbu_data.imagesize) { 485 rbu_data.packet_read_count = 0; 486 /* this was the last copy */ 487 retval = bytes_left; 488 } else 489 retval = count; 490 491 read_rbu_data_exit: 492 return retval; 493} 494 495static ssize_t read_rbu_mono_data(char *buffer, loff_t pos, size_t count) 496{ 497 /* check to see if we have something to return */ 498 if ((rbu_data.image_update_buffer == NULL) || 499 (rbu_data.bios_image_size == 0)) { 500 pr_debug("read_rbu_data_mono: image_update_buffer %p ," 501 "bios_image_size %lu\n", 502 rbu_data.image_update_buffer, 503 rbu_data.bios_image_size); 504 return -ENOMEM; 505 } 506 507 return memory_read_from_buffer(buffer, count, &pos, 508 rbu_data.image_update_buffer, rbu_data.bios_image_size); 509} 510 511static ssize_t read_rbu_data(struct file *filp, struct kobject *kobj, 512 struct bin_attribute *bin_attr, 513 char *buffer, loff_t pos, size_t count) 514{ 515 ssize_t ret_count = 0; 516 517 spin_lock(&rbu_data.lock); 518 519 if (!strcmp(image_type, "mono")) 520 ret_count = read_rbu_mono_data(buffer, pos, count); 521 else if (!strcmp(image_type, "packet")) 522 ret_count = read_packet_data(buffer, pos, count); 523 else 524 pr_debug("read_rbu_data: invalid image type specified\n"); 525 526 spin_unlock(&rbu_data.lock); 527 return ret_count; 528} 529 530static void callbackfn_rbu(const struct firmware *fw, void *context) 531{ 532 rbu_data.entry_created = 0; 533 534 if (!fw) 535 return; 536 537 if (!fw->size) 538 goto out; 539 540 spin_lock(&rbu_data.lock); 541 if (!strcmp(image_type, "mono")) { 542 if (!img_update_realloc(fw->size)) 543 memcpy(rbu_data.image_update_buffer, 544 fw->data, fw->size); 545 } else if (!strcmp(image_type, "packet")) { 546 /* 547 * we need to free previous packets if a 548 * new hunk of packets needs to be downloaded 549 */ 550 packet_empty_list(); 551 if (packetize_data(fw->data, fw->size)) 552 /* Incase something goes wrong when we are 553 * in middle of packetizing the data, we 554 * need to free up whatever packets might 555 * have been created before we quit. 556 */ 557 packet_empty_list(); 558 } else 559 pr_debug("invalid image type specified.\n"); 560 spin_unlock(&rbu_data.lock); 561 out: 562 release_firmware(fw); 563} 564 565static ssize_t read_rbu_image_type(struct file *filp, struct kobject *kobj, 566 struct bin_attribute *bin_attr, 567 char *buffer, loff_t pos, size_t count) 568{ 569 int size = 0; 570 if (!pos) 571 size = scnprintf(buffer, count, "%s\n", image_type); 572 return size; 573} 574 575static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj, 576 struct bin_attribute *bin_attr, 577 char *buffer, loff_t pos, size_t count) 578{ 579 int rc = count; 580 int req_firm_rc = 0; 581 int i; 582 spin_lock(&rbu_data.lock); 583 /* 584 * Find the first newline or space 585 */ 586 for (i = 0; i < count; ++i) 587 if (buffer[i] == '\n' || buffer[i] == ' ') { 588 buffer[i] = '\0'; 589 break; 590 } 591 if (i == count) 592 buffer[count] = '\0'; 593 594 if (strstr(buffer, "mono")) 595 strcpy(image_type, "mono"); 596 else if (strstr(buffer, "packet")) 597 strcpy(image_type, "packet"); 598 else if (strstr(buffer, "init")) { 599 /* 600 * If due to the user error the driver gets in a bad 601 * state where even though it is loaded , the 602 * /sys/class/firmware/dell_rbu entries are missing. 603 * to cover this situation the user can recreate entries 604 * by writing init to image_type. 605 */ 606 if (!rbu_data.entry_created) { 607 spin_unlock(&rbu_data.lock); 608 req_firm_rc = request_firmware_nowait(THIS_MODULE, 609 FW_ACTION_NOHOTPLUG, "dell_rbu", 610 &rbu_device->dev, GFP_KERNEL, &context, 611 callbackfn_rbu); 612 if (req_firm_rc) { 613 printk(KERN_ERR 614 "dell_rbu:%s request_firmware_nowait" 615 " failed %d\n", __func__, rc); 616 rc = -EIO; 617 } else 618 rbu_data.entry_created = 1; 619 620 spin_lock(&rbu_data.lock); 621 } 622 } else { 623 printk(KERN_WARNING "dell_rbu: image_type is invalid\n"); 624 spin_unlock(&rbu_data.lock); 625 return -EINVAL; 626 } 627 628 /* we must free all previous allocations */ 629 packet_empty_list(); 630 img_update_free(); 631 spin_unlock(&rbu_data.lock); 632 633 return rc; 634} 635 636static ssize_t read_rbu_packet_size(struct file *filp, struct kobject *kobj, 637 struct bin_attribute *bin_attr, 638 char *buffer, loff_t pos, size_t count) 639{ 640 int size = 0; 641 if (!pos) { 642 spin_lock(&rbu_data.lock); 643 size = scnprintf(buffer, count, "%lu\n", rbu_data.packetsize); 644 spin_unlock(&rbu_data.lock); 645 } 646 return size; 647} 648 649static ssize_t write_rbu_packet_size(struct file *filp, struct kobject *kobj, 650 struct bin_attribute *bin_attr, 651 char *buffer, loff_t pos, size_t count) 652{ 653 unsigned long temp; 654 spin_lock(&rbu_data.lock); 655 packet_empty_list(); 656 sscanf(buffer, "%lu", &temp); 657 if (temp < 0xffffffff) 658 rbu_data.packetsize = temp; 659 660 spin_unlock(&rbu_data.lock); 661 return count; 662} 663 664static struct bin_attribute rbu_data_attr = { 665 .attr = {.name = "data", .mode = 0444}, 666 .read = read_rbu_data, 667}; 668 669static struct bin_attribute rbu_image_type_attr = { 670 .attr = {.name = "image_type", .mode = 0644}, 671 .read = read_rbu_image_type, 672 .write = write_rbu_image_type, 673}; 674 675static struct bin_attribute rbu_packet_size_attr = { 676 .attr = {.name = "packet_size", .mode = 0644}, 677 .read = read_rbu_packet_size, 678 .write = write_rbu_packet_size, 679}; 680 681static int __init dcdrbu_init(void) 682{ 683 int rc; 684 spin_lock_init(&rbu_data.lock); 685 686 init_packet_head(); 687 rbu_device = platform_device_register_simple("dell_rbu", -1, NULL, 0); 688 if (IS_ERR(rbu_device)) { 689 printk(KERN_ERR 690 "dell_rbu:%s:platform_device_register_simple " 691 "failed\n", __func__); 692 return PTR_ERR(rbu_device); 693 } 694 695 rc = sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_data_attr); 696 if (rc) 697 goto out_devreg; 698 rc = sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr); 699 if (rc) 700 goto out_data; 701 rc = sysfs_create_bin_file(&rbu_device->dev.kobj, 702 &rbu_packet_size_attr); 703 if (rc) 704 goto out_imtype; 705 706 rbu_data.entry_created = 0; 707 return 0; 708 709out_imtype: 710 sysfs_remove_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr); 711out_data: 712 sysfs_remove_bin_file(&rbu_device->dev.kobj, &rbu_data_attr); 713out_devreg: 714 platform_device_unregister(rbu_device); 715 return rc; 716} 717 718static __exit void dcdrbu_exit(void) 719{ 720 spin_lock(&rbu_data.lock); 721 packet_empty_list(); 722 img_update_free(); 723 spin_unlock(&rbu_data.lock); 724 platform_device_unregister(rbu_device); 725} 726 727module_exit(dcdrbu_exit); 728module_init(dcdrbu_init); 729 730/* vim:noet:ts=8:sw=8 731*/