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 77b2555b52a894a2e39a42e43d993df875c46a6a 634 lines 16 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/version.h> 38#include <linux/config.h> 39#include <linux/init.h> 40#include <linux/module.h> 41#include <linux/string.h> 42#include <linux/errno.h> 43#include <linux/blkdev.h> 44#include <linux/device.h> 45#include <linux/spinlock.h> 46#include <linux/moduleparam.h> 47#include <linux/firmware.h> 48#include <linux/dma-mapping.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("1.0"); 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 int dma_alloc; 63 spinlock_t lock; 64 unsigned long packet_read_count; 65 unsigned long packet_write_count; 66 unsigned long num_packets; 67 unsigned long packetsize; 68} rbu_data; 69 70static char image_type[MAX_IMAGE_LENGTH] = "mono"; 71module_param_string(image_type, image_type, sizeof(image_type), 0); 72MODULE_PARM_DESC(image_type, "BIOS image type. choose- mono or packet"); 73 74struct packet_data { 75 struct list_head list; 76 size_t length; 77 void *data; 78 int ordernum; 79}; 80 81static struct packet_data packet_data_head; 82 83static struct platform_device *rbu_device; 84static int context; 85static dma_addr_t dell_rbu_dmaaddr; 86 87static void init_packet_head(void) 88{ 89 INIT_LIST_HEAD(&packet_data_head.list); 90 rbu_data.packet_write_count = 0; 91 rbu_data.packet_read_count = 0; 92 rbu_data.num_packets = 0; 93 rbu_data.packetsize = 0; 94} 95 96static int fill_last_packet(void *data, size_t length) 97{ 98 struct list_head *ptemp_list; 99 struct packet_data *packet = NULL; 100 int packet_count = 0; 101 102 pr_debug("fill_last_packet: entry \n"); 103 104 if (!rbu_data.num_packets) { 105 pr_debug("fill_last_packet: num_packets=0\n"); 106 return -ENOMEM; 107 } 108 109 packet_count = rbu_data.num_packets; 110 111 ptemp_list = (&packet_data_head.list)->prev; 112 113 packet = list_entry(ptemp_list, struct packet_data, list); 114 115 if ((rbu_data.packet_write_count + length) > rbu_data.packetsize) { 116 pr_debug("dell_rbu:%s: packet size data " 117 "overrun\n", __FUNCTION__); 118 return -EINVAL; 119 } 120 121 pr_debug("fill_last_packet : buffer = %p\n", packet->data); 122 123 memcpy((packet->data + rbu_data.packet_write_count), data, length); 124 125 if ((rbu_data.packet_write_count + length) == rbu_data.packetsize) { 126 /* 127 * this was the last data chunk in the packet 128 * so reinitialize the packet data counter to zero 129 */ 130 rbu_data.packet_write_count = 0; 131 } else 132 rbu_data.packet_write_count += length; 133 134 pr_debug("fill_last_packet: exit \n"); 135 return 0; 136} 137 138static int create_packet(size_t length) 139{ 140 struct packet_data *newpacket; 141 int ordernum = 0; 142 143 pr_debug("create_packet: entry \n"); 144 145 if (!rbu_data.packetsize) { 146 pr_debug("create_packet: packetsize not specified\n"); 147 return -EINVAL; 148 } 149 150 newpacket = kmalloc(sizeof(struct packet_data), GFP_KERNEL); 151 if (!newpacket) { 152 printk(KERN_WARNING 153 "dell_rbu:%s: failed to allocate new " 154 "packet\n", __FUNCTION__); 155 return -ENOMEM; 156 } 157 158 ordernum = get_order(length); 159 /* 160 * there is no upper limit on memory 161 * address for packetized mechanism 162 */ 163 newpacket->data = (unsigned char *)__get_free_pages(GFP_KERNEL, 164 ordernum); 165 166 pr_debug("create_packet: newpacket %p\n", newpacket->data); 167 168 if (!newpacket->data) { 169 printk(KERN_WARNING 170 "dell_rbu:%s: failed to allocate new " 171 "packet\n", __FUNCTION__); 172 kfree(newpacket); 173 return -ENOMEM; 174 } 175 176 newpacket->ordernum = ordernum; 177 ++rbu_data.num_packets; 178 /* 179 * initialize the newly created packet headers 180 */ 181 INIT_LIST_HEAD(&newpacket->list); 182 list_add_tail(&newpacket->list, &packet_data_head.list); 183 /* 184 * packets have fixed size 185 */ 186 newpacket->length = rbu_data.packetsize; 187 188 pr_debug("create_packet: exit \n"); 189 190 return 0; 191} 192 193static int packetize_data(void *data, size_t length) 194{ 195 int rc = 0; 196 197 if (!rbu_data.packet_write_count) { 198 if ((rc = create_packet(length))) 199 return rc; 200 } 201 if ((rc = fill_last_packet(data, length))) 202 return rc; 203 204 return rc; 205} 206 207static int 208do_packet_read(char *data, struct list_head *ptemp_list, 209 int length, int bytes_read, int *list_read_count) 210{ 211 void *ptemp_buf; 212 struct packet_data *newpacket = NULL; 213 int bytes_copied = 0; 214 int j = 0; 215 216 newpacket = list_entry(ptemp_list, struct packet_data, list); 217 *list_read_count += newpacket->length; 218 219 if (*list_read_count > bytes_read) { 220 /* point to the start of unread data */ 221 j = newpacket->length - (*list_read_count - bytes_read); 222 /* point to the offset in the packet buffer */ 223 ptemp_buf = (u8 *) newpacket->data + j; 224 /* 225 * check if there is enough room in 226 * * the incoming buffer 227 */ 228 if (length > (*list_read_count - bytes_read)) 229 /* 230 * copy what ever is there in this 231 * packet and move on 232 */ 233 bytes_copied = (*list_read_count - bytes_read); 234 else 235 /* copy the remaining */ 236 bytes_copied = length; 237 memcpy(data, ptemp_buf, bytes_copied); 238 } 239 return bytes_copied; 240} 241 242static int packet_read_list(char *data, size_t * pread_length) 243{ 244 struct list_head *ptemp_list; 245 int temp_count = 0; 246 int bytes_copied = 0; 247 int bytes_read = 0; 248 int remaining_bytes = 0; 249 char *pdest = data; 250 251 /* check if we have any packets */ 252 if (0 == rbu_data.num_packets) 253 return -ENOMEM; 254 255 remaining_bytes = *pread_length; 256 bytes_read = rbu_data.packet_read_count; 257 258 ptemp_list = (&packet_data_head.list)->next; 259 while (!list_empty(ptemp_list)) { 260 bytes_copied = do_packet_read(pdest, ptemp_list, 261 remaining_bytes, bytes_read, 262 &temp_count); 263 remaining_bytes -= bytes_copied; 264 bytes_read += bytes_copied; 265 pdest += bytes_copied; 266 /* 267 * check if we reached end of buffer before reaching the 268 * last packet 269 */ 270 if (remaining_bytes == 0) 271 break; 272 273 ptemp_list = ptemp_list->next; 274 } 275 /*finally set the bytes read */ 276 *pread_length = bytes_read - rbu_data.packet_read_count; 277 rbu_data.packet_read_count = bytes_read; 278 return 0; 279} 280 281static void packet_empty_list(void) 282{ 283 struct list_head *ptemp_list; 284 struct list_head *pnext_list; 285 struct packet_data *newpacket; 286 287 ptemp_list = (&packet_data_head.list)->next; 288 while (!list_empty(ptemp_list)) { 289 newpacket = 290 list_entry(ptemp_list, struct packet_data, list); 291 pnext_list = ptemp_list->next; 292 list_del(ptemp_list); 293 ptemp_list = pnext_list; 294 /* 295 * zero out the RBU packet memory before freeing 296 * to make sure there are no stale RBU packets left in memory 297 */ 298 memset(newpacket->data, 0, rbu_data.packetsize); 299 free_pages((unsigned long)newpacket->data, 300 newpacket->ordernum); 301 kfree(newpacket); 302 } 303 rbu_data.packet_write_count = 0; 304 rbu_data.packet_read_count = 0; 305 rbu_data.num_packets = 0; 306 rbu_data.packetsize = 0; 307} 308 309/* 310 * img_update_free: Frees the buffer allocated for storing BIOS image 311 * Always called with lock held and returned with lock held 312 */ 313static void img_update_free(void) 314{ 315 if (!rbu_data.image_update_buffer) 316 return; 317 /* 318 * zero out this buffer before freeing it to get rid of any stale 319 * BIOS image copied in memory. 320 */ 321 memset(rbu_data.image_update_buffer, 0, 322 rbu_data.image_update_buffer_size); 323 if (rbu_data.dma_alloc == 1) 324 dma_free_coherent(NULL, rbu_data.bios_image_size, 325 rbu_data.image_update_buffer, 326 dell_rbu_dmaaddr); 327 else 328 free_pages((unsigned long)rbu_data.image_update_buffer, 329 rbu_data.image_update_ordernum); 330 331 /* 332 * Re-initialize the rbu_data variables after a free 333 */ 334 rbu_data.image_update_ordernum = -1; 335 rbu_data.image_update_buffer = NULL; 336 rbu_data.image_update_buffer_size = 0; 337 rbu_data.bios_image_size = 0; 338 rbu_data.dma_alloc = 0; 339} 340 341/* 342 * img_update_realloc: This function allocates the contiguous pages to 343 * accommodate the requested size of data. The memory address and size 344 * values are stored globally and on every call to this function the new 345 * size is checked to see if more data is required than the existing size. 346 * If true the previous memory is freed and new allocation is done to 347 * accommodate the new size. If the incoming size is less then than the 348 * already allocated size, then that memory is reused. This function is 349 * called with lock held and returns with lock held. 350 */ 351static int img_update_realloc(unsigned long size) 352{ 353 unsigned char *image_update_buffer = NULL; 354 unsigned long rc; 355 unsigned long img_buf_phys_addr; 356 int ordernum; 357 int dma_alloc = 0; 358 359 /* 360 * check if the buffer of sufficient size has been 361 * already allocated 362 */ 363 if (rbu_data.image_update_buffer_size >= size) { 364 /* 365 * check for corruption 366 */ 367 if ((size != 0) && (rbu_data.image_update_buffer == NULL)) { 368 printk(KERN_ERR "dell_rbu:%s: corruption " 369 "check failed\n", __FUNCTION__); 370 return -EINVAL; 371 } 372 /* 373 * we have a valid pre-allocated buffer with 374 * sufficient size 375 */ 376 return 0; 377 } 378 379 /* 380 * free any previously allocated buffer 381 */ 382 img_update_free(); 383 384 spin_unlock(&rbu_data.lock); 385 386 ordernum = get_order(size); 387 image_update_buffer = 388 (unsigned char *)__get_free_pages(GFP_KERNEL, ordernum); 389 390 img_buf_phys_addr = 391 (unsigned long)virt_to_phys(image_update_buffer); 392 393 if (img_buf_phys_addr > BIOS_SCAN_LIMIT) { 394 free_pages((unsigned long)image_update_buffer, ordernum); 395 ordernum = -1; 396 image_update_buffer = dma_alloc_coherent(NULL, size, 397 &dell_rbu_dmaaddr, 398 GFP_KERNEL); 399 dma_alloc = 1; 400 } 401 402 spin_lock(&rbu_data.lock); 403 404 if (image_update_buffer != NULL) { 405 rbu_data.image_update_buffer = image_update_buffer; 406 rbu_data.image_update_buffer_size = size; 407 rbu_data.bios_image_size = 408 rbu_data.image_update_buffer_size; 409 rbu_data.image_update_ordernum = ordernum; 410 rbu_data.dma_alloc = dma_alloc; 411 rc = 0; 412 } else { 413 pr_debug("Not enough memory for image update:" 414 "size = %ld\n", size); 415 rc = -ENOMEM; 416 } 417 418 return rc; 419} 420 421static ssize_t read_packet_data(char *buffer, loff_t pos, size_t count) 422{ 423 int retval; 424 size_t bytes_left; 425 size_t data_length; 426 char *ptempBuf = buffer; 427 unsigned long imagesize; 428 429 /* check to see if we have something to return */ 430 if (rbu_data.num_packets == 0) { 431 pr_debug("read_packet_data: no packets written\n"); 432 retval = -ENOMEM; 433 goto read_rbu_data_exit; 434 } 435 436 imagesize = rbu_data.num_packets * rbu_data.packetsize; 437 438 if (pos > imagesize) { 439 retval = 0; 440 printk(KERN_WARNING "dell_rbu:read_packet_data: " 441 "data underrun\n"); 442 goto read_rbu_data_exit; 443 } 444 445 bytes_left = imagesize - pos; 446 data_length = min(bytes_left, count); 447 448 if ((retval = packet_read_list(ptempBuf, &data_length)) < 0) 449 goto read_rbu_data_exit; 450 451 if ((pos + count) > imagesize) { 452 rbu_data.packet_read_count = 0; 453 /* this was the last copy */ 454 retval = bytes_left; 455 } else 456 retval = count; 457 458 read_rbu_data_exit: 459 return retval; 460} 461 462static ssize_t read_rbu_mono_data(char *buffer, loff_t pos, size_t count) 463{ 464 unsigned char *ptemp = NULL; 465 size_t bytes_left = 0; 466 size_t data_length = 0; 467 ssize_t ret_count = 0; 468 469 /* check to see if we have something to return */ 470 if ((rbu_data.image_update_buffer == NULL) || 471 (rbu_data.bios_image_size == 0)) { 472 pr_debug("read_rbu_data_mono: image_update_buffer %p ," 473 "bios_image_size %lu\n", 474 rbu_data.image_update_buffer, 475 rbu_data.bios_image_size); 476 ret_count = -ENOMEM; 477 goto read_rbu_data_exit; 478 } 479 480 if (pos > rbu_data.bios_image_size) { 481 ret_count = 0; 482 goto read_rbu_data_exit; 483 } 484 485 bytes_left = rbu_data.bios_image_size - pos; 486 data_length = min(bytes_left, count); 487 488 ptemp = rbu_data.image_update_buffer; 489 memcpy(buffer, (ptemp + pos), data_length); 490 491 if ((pos + count) > rbu_data.bios_image_size) 492 /* this was the last copy */ 493 ret_count = bytes_left; 494 else 495 ret_count = count; 496 read_rbu_data_exit: 497 return ret_count; 498} 499 500static ssize_t 501read_rbu_data(struct kobject *kobj, char *buffer, loff_t pos, size_t count) 502{ 503 ssize_t ret_count = 0; 504 505 spin_lock(&rbu_data.lock); 506 507 if (!strcmp(image_type, "mono")) 508 ret_count = read_rbu_mono_data(buffer, pos, count); 509 else if (!strcmp(image_type, "packet")) 510 ret_count = read_packet_data(buffer, pos, count); 511 else 512 pr_debug("read_rbu_data: invalid image type specified\n"); 513 514 spin_unlock(&rbu_data.lock); 515 return ret_count; 516} 517 518static ssize_t 519read_rbu_image_type(struct kobject *kobj, char *buffer, loff_t pos, 520 size_t count) 521{ 522 int size = 0; 523 if (!pos) 524 size = sprintf(buffer, "%s\n", image_type); 525 return size; 526} 527 528static ssize_t 529write_rbu_image_type(struct kobject *kobj, char *buffer, loff_t pos, 530 size_t count) 531{ 532 int rc = count; 533 spin_lock(&rbu_data.lock); 534 535 if (strlen(buffer) < MAX_IMAGE_LENGTH) 536 sscanf(buffer, "%s", image_type); 537 else 538 printk(KERN_WARNING "dell_rbu: image_type is invalid" 539 "max chars = %d, \n incoming str--%s-- \n", 540 MAX_IMAGE_LENGTH, buffer); 541 542 /* we must free all previous allocations */ 543 packet_empty_list(); 544 img_update_free(); 545 546 spin_unlock(&rbu_data.lock); 547 return rc; 548 549} 550 551static struct bin_attribute rbu_data_attr = { 552 .attr = {.name = "data",.owner = THIS_MODULE,.mode = 0444}, 553 .read = read_rbu_data, 554}; 555 556static struct bin_attribute rbu_image_type_attr = { 557 .attr = {.name = "image_type",.owner = THIS_MODULE,.mode = 0644}, 558 .read = read_rbu_image_type, 559 .write = write_rbu_image_type, 560}; 561 562static void callbackfn_rbu(const struct firmware *fw, void *context) 563{ 564 int rc = 0; 565 566 if (!fw || !fw->size) 567 return; 568 569 spin_lock(&rbu_data.lock); 570 if (!strcmp(image_type, "mono")) { 571 if (!img_update_realloc(fw->size)) 572 memcpy(rbu_data.image_update_buffer, 573 fw->data, fw->size); 574 } else if (!strcmp(image_type, "packet")) { 575 if (!rbu_data.packetsize) 576 rbu_data.packetsize = fw->size; 577 else if (rbu_data.packetsize != fw->size) { 578 packet_empty_list(); 579 rbu_data.packetsize = fw->size; 580 } 581 packetize_data(fw->data, fw->size); 582 } else 583 pr_debug("invalid image type specified.\n"); 584 spin_unlock(&rbu_data.lock); 585 586 rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, 587 "dell_rbu", &rbu_device->dev, 588 &context, callbackfn_rbu); 589 if (rc) 590 printk(KERN_ERR 591 "dell_rbu:%s request_firmware_nowait failed" 592 " %d\n", __FUNCTION__, rc); 593} 594 595static int __init dcdrbu_init(void) 596{ 597 int rc = 0; 598 spin_lock_init(&rbu_data.lock); 599 600 init_packet_head(); 601 rbu_device = 602 platform_device_register_simple("dell_rbu", -1, NULL, 0); 603 if (!rbu_device) { 604 printk(KERN_ERR 605 "dell_rbu:%s:platform_device_register_simple " 606 "failed\n", __FUNCTION__); 607 return -EIO; 608 } 609 610 sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_data_attr); 611 sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr); 612 613 rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, 614 "dell_rbu", &rbu_device->dev, 615 &context, callbackfn_rbu); 616 if (rc) 617 printk(KERN_ERR "dell_rbu:%s:request_firmware_nowait" 618 " failed %d\n", __FUNCTION__, rc); 619 620 return rc; 621 622} 623 624static __exit void dcdrbu_exit(void) 625{ 626 spin_lock(&rbu_data.lock); 627 packet_empty_list(); 628 img_update_free(); 629 spin_unlock(&rbu_data.lock); 630 platform_device_unregister(rbu_device); 631} 632 633module_exit(dcdrbu_exit); 634module_init(dcdrbu_init);