linux/arch/powerpc/kernel/rtas_flash.c
<<
>>
Prefs
   1/*
   2 *  c 2001 PPC 64 Team, IBM Corp
   3 *
   4 *      This program is free software; you can redistribute it and/or
   5 *      modify it under the terms of the GNU General Public License
   6 *      as published by the Free Software Foundation; either version
   7 *      2 of the License, or (at your option) any later version.
   8 *
   9 * /proc/ppc64/rtas/firmware_flash interface
  10 *
  11 * This file implements a firmware_flash interface to pump a firmware
  12 * image into the kernel.  At reboot time rtas_restart() will see the
  13 * firmware image and flash it as it reboots (see rtas.c).
  14 */
  15
  16#include <linux/module.h>
  17#include <linux/init.h>
  18#include <linux/proc_fs.h>
  19#include <asm/delay.h>
  20#include <asm/uaccess.h>
  21#include <asm/rtas.h>
  22#include <asm/abs_addr.h>
  23
  24#define MODULE_VERS "1.0"
  25#define MODULE_NAME "rtas_flash"
  26
  27#define FIRMWARE_FLASH_NAME "firmware_flash"   
  28#define FIRMWARE_UPDATE_NAME "firmware_update"
  29#define MANAGE_FLASH_NAME "manage_flash"
  30#define VALIDATE_FLASH_NAME "validate_flash"
  31
  32/* General RTAS Status Codes */
  33#define RTAS_RC_SUCCESS  0
  34#define RTAS_RC_HW_ERR  -1
  35#define RTAS_RC_BUSY    -2
  36
  37/* Flash image status values */
  38#define FLASH_AUTH           -9002 /* RTAS Not Service Authority Partition */
  39#define FLASH_NO_OP          -1099 /* No operation initiated by user */ 
  40#define FLASH_IMG_SHORT      -1005 /* Flash image shorter than expected */
  41#define FLASH_IMG_BAD_LEN    -1004 /* Bad length value in flash list block */
  42#define FLASH_IMG_NULL_DATA  -1003 /* Bad data value in flash list block */
  43#define FLASH_IMG_READY      0     /* Firmware img ready for flash on reboot */
  44
  45/* Manage image status values */
  46#define MANAGE_AUTH          -9002 /* RTAS Not Service Authority Partition */
  47#define MANAGE_ACTIVE_ERR    -9001 /* RTAS Cannot Overwrite Active Img */
  48#define MANAGE_NO_OP         -1099 /* No operation initiated by user */
  49#define MANAGE_PARAM_ERR     -3    /* RTAS Parameter Error */
  50#define MANAGE_HW_ERR        -1    /* RTAS Hardware Error */
  51
  52/* Validate image status values */
  53#define VALIDATE_AUTH          -9002 /* RTAS Not Service Authority Partition */
  54#define VALIDATE_NO_OP         -1099 /* No operation initiated by the user */
  55#define VALIDATE_INCOMPLETE    -1002 /* User copied < VALIDATE_BUF_SIZE */
  56#define VALIDATE_READY         -1001 /* Firmware image ready for validation */
  57#define VALIDATE_PARAM_ERR     -3    /* RTAS Parameter Error */
  58#define VALIDATE_HW_ERR        -1    /* RTAS Hardware Error */
  59#define VALIDATE_TMP_UPDATE    0     /* Validate Return Status */
  60#define VALIDATE_FLASH_AUTH    1     /* Validate Return Status */
  61#define VALIDATE_INVALID_IMG   2     /* Validate Return Status */
  62#define VALIDATE_CUR_UNKNOWN   3     /* Validate Return Status */
  63#define VALIDATE_TMP_COMMIT_DL 4     /* Validate Return Status */
  64#define VALIDATE_TMP_COMMIT    5     /* Validate Return Status */
  65#define VALIDATE_TMP_UPDATE_DL 6     /* Validate Return Status */
  66
  67/* ibm,manage-flash-image operation tokens */
  68#define RTAS_REJECT_TMP_IMG   0
  69#define RTAS_COMMIT_TMP_IMG   1
  70
  71/* Array sizes */
  72#define VALIDATE_BUF_SIZE 4096    
  73#define RTAS_MSG_MAXLEN   64
  74
  75/* Quirk - RTAS requires 4k list length and block size */
  76#define RTAS_BLKLIST_LENGTH 4096
  77#define RTAS_BLK_SIZE 4096
  78
  79struct flash_block {
  80        char *data;
  81        unsigned long length;
  82};
  83
  84/* This struct is very similar but not identical to
  85 * that needed by the rtas flash update.
  86 * All we need to do for rtas is rewrite num_blocks
  87 * into a version/length and translate the pointers
  88 * to absolute.
  89 */
  90#define FLASH_BLOCKS_PER_NODE ((RTAS_BLKLIST_LENGTH - 16) / sizeof(struct flash_block))
  91struct flash_block_list {
  92        unsigned long num_blocks;
  93        struct flash_block_list *next;
  94        struct flash_block blocks[FLASH_BLOCKS_PER_NODE];
  95};
  96struct flash_block_list_header { /* just the header of flash_block_list */
  97        unsigned long num_blocks;
  98        struct flash_block_list *next;
  99};
 100
 101static struct flash_block_list_header rtas_firmware_flash_list = {0, NULL};
 102
 103/* Use slab cache to guarantee 4k alignment */
 104static struct kmem_cache *flash_block_cache = NULL;
 105
 106#define FLASH_BLOCK_LIST_VERSION (1UL)
 107
 108/* Local copy of the flash block list.
 109 * We only allow one open of the flash proc file and create this
 110 * list as we go.  This list will be put in the
 111 * rtas_firmware_flash_list var once it is fully read.
 112 *
 113 * For convenience as we build the list we use virtual addrs,
 114 * we do not fill in the version number, and the length field
 115 * is treated as the number of entries currently in the block
 116 * (i.e. not a byte count).  This is all fixed on release.
 117 */
 118
 119/* Status int must be first member of struct */
 120struct rtas_update_flash_t
 121{
 122        int status;                     /* Flash update status */
 123        struct flash_block_list *flist; /* Local copy of flash block list */
 124};
 125
 126/* Status int must be first member of struct */
 127struct rtas_manage_flash_t
 128{
 129        int status;                     /* Returned status */
 130        unsigned int op;                /* Reject or commit image */
 131};
 132
 133/* Status int must be first member of struct */
 134struct rtas_validate_flash_t
 135{
 136        int status;                     /* Returned status */   
 137        char buf[VALIDATE_BUF_SIZE];    /* Candidate image buffer */
 138        unsigned int buf_size;          /* Size of image buf */
 139        unsigned int update_results;    /* Update results token */
 140};
 141
 142static DEFINE_SPINLOCK(flash_file_open_lock);
 143static struct proc_dir_entry *firmware_flash_pde;
 144static struct proc_dir_entry *firmware_update_pde;
 145static struct proc_dir_entry *validate_pde;
 146static struct proc_dir_entry *manage_pde;
 147
 148/* Do simple sanity checks on the flash image. */
 149static int flash_list_valid(struct flash_block_list *flist)
 150{
 151        struct flash_block_list *f;
 152        int i;
 153        unsigned long block_size, image_size;
 154
 155        /* Paranoid self test here.  We also collect the image size. */
 156        image_size = 0;
 157        for (f = flist; f; f = f->next) {
 158                for (i = 0; i < f->num_blocks; i++) {
 159                        if (f->blocks[i].data == NULL) {
 160                                return FLASH_IMG_NULL_DATA;
 161                        }
 162                        block_size = f->blocks[i].length;
 163                        if (block_size <= 0 || block_size > RTAS_BLK_SIZE) {
 164                                return FLASH_IMG_BAD_LEN;
 165                        }
 166                        image_size += block_size;
 167                }
 168        }
 169
 170        if (image_size < (256 << 10)) {
 171                if (image_size < 2) 
 172                        return FLASH_NO_OP;
 173        }
 174
 175        printk(KERN_INFO "FLASH: flash image with %ld bytes stored for hardware flash on reboot\n", image_size);
 176
 177        return FLASH_IMG_READY;
 178}
 179
 180static void free_flash_list(struct flash_block_list *f)
 181{
 182        struct flash_block_list *next;
 183        int i;
 184
 185        while (f) {
 186                for (i = 0; i < f->num_blocks; i++)
 187                        kmem_cache_free(flash_block_cache, f->blocks[i].data);
 188                next = f->next;
 189                kmem_cache_free(flash_block_cache, f);
 190                f = next;
 191        }
 192}
 193
 194static int rtas_flash_release(struct inode *inode, struct file *file)
 195{
 196        struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode);
 197        struct rtas_update_flash_t *uf;
 198        
 199        uf = (struct rtas_update_flash_t *) dp->data;
 200        if (uf->flist) {    
 201                /* File was opened in write mode for a new flash attempt */
 202                /* Clear saved list */
 203                if (rtas_firmware_flash_list.next) {
 204                        free_flash_list(rtas_firmware_flash_list.next);
 205                        rtas_firmware_flash_list.next = NULL;
 206                }
 207
 208                if (uf->status != FLASH_AUTH)  
 209                        uf->status = flash_list_valid(uf->flist);
 210
 211                if (uf->status == FLASH_IMG_READY) 
 212                        rtas_firmware_flash_list.next = uf->flist;
 213                else
 214                        free_flash_list(uf->flist);
 215
 216                uf->flist = NULL;
 217        }
 218
 219        atomic_dec(&dp->count);
 220        return 0;
 221}
 222
 223static void get_flash_status_msg(int status, char *buf)
 224{
 225        char *msg;
 226
 227        switch (status) {
 228        case FLASH_AUTH:
 229                msg = "error: this partition does not have service authority\n";
 230                break;
 231        case FLASH_NO_OP:
 232                msg = "info: no firmware image for flash\n";
 233                break;
 234        case FLASH_IMG_SHORT:
 235                msg = "error: flash image short\n";
 236                break;
 237        case FLASH_IMG_BAD_LEN:
 238                msg = "error: internal error bad length\n";
 239                break;
 240        case FLASH_IMG_NULL_DATA:
 241                msg = "error: internal error null data\n";
 242                break;
 243        case FLASH_IMG_READY:
 244                msg = "ready: firmware image ready for flash on reboot\n";
 245                break;
 246        default:
 247                sprintf(buf, "error: unexpected status value %d\n", status);
 248                return;
 249        }
 250
 251        strcpy(buf, msg);       
 252}
 253
 254/* Reading the proc file will show status (not the firmware contents) */
 255static ssize_t rtas_flash_read(struct file *file, char __user *buf,
 256                               size_t count, loff_t *ppos)
 257{
 258        struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode);
 259        struct rtas_update_flash_t *uf;
 260        char msg[RTAS_MSG_MAXLEN];
 261        int msglen;
 262
 263        uf = (struct rtas_update_flash_t *) dp->data;
 264
 265        if (!strcmp(dp->name, FIRMWARE_FLASH_NAME)) {
 266                get_flash_status_msg(uf->status, msg);
 267        } else {           /* FIRMWARE_UPDATE_NAME */
 268                sprintf(msg, "%d\n", uf->status);
 269        }
 270        msglen = strlen(msg);
 271        if (msglen > count)
 272                msglen = count;
 273
 274        if (ppos && *ppos != 0)
 275                return 0;       /* be cheap */
 276
 277        if (!access_ok(VERIFY_WRITE, buf, msglen))
 278                return -EINVAL;
 279
 280        if (copy_to_user(buf, msg, msglen))
 281                return -EFAULT;
 282
 283        if (ppos)
 284                *ppos = msglen;
 285        return msglen;
 286}
 287
 288/* constructor for flash_block_cache */
 289void rtas_block_ctor(void *ptr)
 290{
 291        memset(ptr, 0, RTAS_BLK_SIZE);
 292}
 293
 294/* We could be much more efficient here.  But to keep this function
 295 * simple we allocate a page to the block list no matter how small the
 296 * count is.  If the system is low on memory it will be just as well
 297 * that we fail....
 298 */
 299static ssize_t rtas_flash_write(struct file *file, const char __user *buffer,
 300                                size_t count, loff_t *off)
 301{
 302        struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode);
 303        struct rtas_update_flash_t *uf;
 304        char *p;
 305        int next_free;
 306        struct flash_block_list *fl;
 307
 308        uf = (struct rtas_update_flash_t *) dp->data;
 309
 310        if (uf->status == FLASH_AUTH || count == 0)
 311                return count;   /* discard data */
 312
 313        /* In the case that the image is not ready for flashing, the memory
 314         * allocated for the block list will be freed upon the release of the 
 315         * proc file
 316         */
 317        if (uf->flist == NULL) {
 318                uf->flist = kmem_cache_alloc(flash_block_cache, GFP_KERNEL);
 319                if (!uf->flist)
 320                        return -ENOMEM;
 321        }
 322
 323        fl = uf->flist;
 324        while (fl->next)
 325                fl = fl->next; /* seek to last block_list for append */
 326        next_free = fl->num_blocks;
 327        if (next_free == FLASH_BLOCKS_PER_NODE) {
 328                /* Need to allocate another block_list */
 329                fl->next = kmem_cache_alloc(flash_block_cache, GFP_KERNEL);
 330                if (!fl->next)
 331                        return -ENOMEM;
 332                fl = fl->next;
 333                next_free = 0;
 334        }
 335
 336        if (count > RTAS_BLK_SIZE)
 337                count = RTAS_BLK_SIZE;
 338        p = kmem_cache_alloc(flash_block_cache, GFP_KERNEL);
 339        if (!p)
 340                return -ENOMEM;
 341        
 342        if(copy_from_user(p, buffer, count)) {
 343                kmem_cache_free(flash_block_cache, p);
 344                return -EFAULT;
 345        }
 346        fl->blocks[next_free].data = p;
 347        fl->blocks[next_free].length = count;
 348        fl->num_blocks++;
 349
 350        return count;
 351}
 352
 353static int rtas_excl_open(struct inode *inode, struct file *file)
 354{
 355        struct proc_dir_entry *dp = PDE(inode);
 356
 357        /* Enforce exclusive open with use count of PDE */
 358        spin_lock(&flash_file_open_lock);
 359        if (atomic_read(&dp->count) > 2) {
 360                spin_unlock(&flash_file_open_lock);
 361                return -EBUSY;
 362        }
 363
 364        atomic_inc(&dp->count);
 365        spin_unlock(&flash_file_open_lock);
 366        
 367        return 0;
 368}
 369
 370static int rtas_excl_release(struct inode *inode, struct file *file)
 371{
 372        struct proc_dir_entry *dp = PDE(inode);
 373
 374        atomic_dec(&dp->count);
 375
 376        return 0;
 377}
 378
 379static void manage_flash(struct rtas_manage_flash_t *args_buf)
 380{
 381        s32 rc;
 382
 383        do {
 384                rc = rtas_call(rtas_token("ibm,manage-flash-image"), 1, 
 385                               1, NULL, args_buf->op);
 386        } while (rtas_busy_delay(rc));
 387
 388        args_buf->status = rc;
 389}
 390
 391static ssize_t manage_flash_read(struct file *file, char __user *buf,
 392                               size_t count, loff_t *ppos)
 393{
 394        struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode);
 395        struct rtas_manage_flash_t *args_buf;
 396        char msg[RTAS_MSG_MAXLEN];
 397        int msglen;
 398
 399        args_buf = (struct rtas_manage_flash_t *) dp->data;
 400        if (args_buf == NULL)
 401                return 0;
 402
 403        msglen = sprintf(msg, "%d\n", args_buf->status);
 404        if (msglen > count)
 405                msglen = count;
 406
 407        if (ppos && *ppos != 0)
 408                return 0;       /* be cheap */
 409
 410        if (!access_ok(VERIFY_WRITE, buf, msglen))
 411                return -EINVAL;
 412
 413        if (copy_to_user(buf, msg, msglen))
 414                return -EFAULT;
 415
 416        if (ppos)
 417                *ppos = msglen;
 418        return msglen;
 419}
 420
 421static ssize_t manage_flash_write(struct file *file, const char __user *buf,
 422                                size_t count, loff_t *off)
 423{
 424        struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode);
 425        struct rtas_manage_flash_t *args_buf;
 426        const char reject_str[] = "0";
 427        const char commit_str[] = "1";
 428        char stkbuf[10];
 429        int op;
 430
 431        args_buf = (struct rtas_manage_flash_t *) dp->data;
 432        if ((args_buf->status == MANAGE_AUTH) || (count == 0))
 433                return count;
 434                
 435        op = -1;
 436        if (buf) {
 437                if (count > 9) count = 9;
 438                if (copy_from_user (stkbuf, buf, count)) {
 439                        return -EFAULT;
 440                }
 441                if (strncmp(stkbuf, reject_str, strlen(reject_str)) == 0) 
 442                        op = RTAS_REJECT_TMP_IMG;
 443                else if (strncmp(stkbuf, commit_str, strlen(commit_str)) == 0) 
 444                        op = RTAS_COMMIT_TMP_IMG;
 445        }
 446        
 447        if (op == -1)   /* buf is empty, or contains invalid string */
 448                return -EINVAL;
 449
 450        args_buf->op = op;
 451        manage_flash(args_buf);
 452
 453        return count;
 454}
 455
 456static void validate_flash(struct rtas_validate_flash_t *args_buf)
 457{
 458        int token = rtas_token("ibm,validate-flash-image");
 459        int update_results;
 460        s32 rc; 
 461
 462        rc = 0;
 463        do {
 464                spin_lock(&rtas_data_buf_lock);
 465                memcpy(rtas_data_buf, args_buf->buf, VALIDATE_BUF_SIZE);
 466                rc = rtas_call(token, 2, 2, &update_results, 
 467                               (u32) __pa(rtas_data_buf), args_buf->buf_size);
 468                memcpy(args_buf->buf, rtas_data_buf, VALIDATE_BUF_SIZE);
 469                spin_unlock(&rtas_data_buf_lock);
 470        } while (rtas_busy_delay(rc));
 471
 472        args_buf->status = rc;
 473        args_buf->update_results = update_results;
 474}
 475
 476static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf, 
 477                                   char *msg)
 478{
 479        int n;
 480
 481        if (args_buf->status >= VALIDATE_TMP_UPDATE) { 
 482                n = sprintf(msg, "%d\n", args_buf->update_results);
 483                if ((args_buf->update_results >= VALIDATE_CUR_UNKNOWN) ||
 484                    (args_buf->update_results == VALIDATE_TMP_UPDATE))
 485                        n += sprintf(msg + n, "%s\n", args_buf->buf);
 486        } else {
 487                n = sprintf(msg, "%d\n", args_buf->status);
 488        }
 489        return n;
 490}
 491
 492static ssize_t validate_flash_read(struct file *file, char __user *buf,
 493                               size_t count, loff_t *ppos)
 494{
 495        struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode);
 496        struct rtas_validate_flash_t *args_buf;
 497        char msg[RTAS_MSG_MAXLEN];
 498        int msglen;
 499
 500        args_buf = (struct rtas_validate_flash_t *) dp->data;
 501
 502        if (ppos && *ppos != 0)
 503                return 0;       /* be cheap */
 504        
 505        msglen = get_validate_flash_msg(args_buf, msg);
 506        if (msglen > count)
 507                msglen = count;
 508
 509        if (!access_ok(VERIFY_WRITE, buf, msglen))
 510                return -EINVAL;
 511
 512        if (copy_to_user(buf, msg, msglen))
 513                return -EFAULT;
 514
 515        if (ppos)
 516                *ppos = msglen;
 517        return msglen;
 518}
 519
 520static ssize_t validate_flash_write(struct file *file, const char __user *buf,
 521                                    size_t count, loff_t *off)
 522{
 523        struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode);
 524        struct rtas_validate_flash_t *args_buf;
 525        int rc;
 526
 527        args_buf = (struct rtas_validate_flash_t *) dp->data;
 528
 529        if (dp->data == NULL) {
 530                dp->data = kmalloc(sizeof(struct rtas_validate_flash_t), 
 531                                GFP_KERNEL);
 532                if (dp->data == NULL) 
 533                        return -ENOMEM;
 534        }
 535
 536        /* We are only interested in the first 4K of the
 537         * candidate image */
 538        if ((*off >= VALIDATE_BUF_SIZE) || 
 539                (args_buf->status == VALIDATE_AUTH)) {
 540                *off += count;
 541                return count;
 542        }
 543
 544        if (*off + count >= VALIDATE_BUF_SIZE)  {
 545                count = VALIDATE_BUF_SIZE - *off;
 546                args_buf->status = VALIDATE_READY;      
 547        } else {
 548                args_buf->status = VALIDATE_INCOMPLETE;
 549        }
 550
 551        if (!access_ok(VERIFY_READ, buf, count)) {
 552                rc = -EFAULT;
 553                goto done;
 554        }
 555        if (copy_from_user(args_buf->buf + *off, buf, count)) {
 556                rc = -EFAULT;
 557                goto done;
 558        }
 559
 560        *off += count;
 561        rc = count;
 562done:
 563        if (rc < 0) {
 564                kfree(dp->data);
 565                dp->data = NULL;
 566        }
 567        return rc;
 568}
 569
 570static int validate_flash_release(struct inode *inode, struct file *file)
 571{
 572        struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode);
 573        struct rtas_validate_flash_t *args_buf;
 574
 575        args_buf = (struct rtas_validate_flash_t *) dp->data;
 576
 577        if (args_buf->status == VALIDATE_READY) {
 578                args_buf->buf_size = VALIDATE_BUF_SIZE;
 579                validate_flash(args_buf);
 580        }
 581
 582        /* The matching atomic_inc was in rtas_excl_open() */
 583        atomic_dec(&dp->count);
 584
 585        return 0;
 586}
 587
 588static void rtas_flash_firmware(int reboot_type)
 589{
 590        unsigned long image_size;
 591        struct flash_block_list *f, *next, *flist;
 592        unsigned long rtas_block_list;
 593        int i, status, update_token;
 594
 595        if (rtas_firmware_flash_list.next == NULL)
 596                return;         /* nothing to do */
 597
 598        if (reboot_type != SYS_RESTART) {
 599                printk(KERN_ALERT "FLASH: firmware flash requires a reboot\n");
 600                printk(KERN_ALERT "FLASH: the firmware image will NOT be flashed\n");
 601                return;
 602        }
 603
 604        update_token = rtas_token("ibm,update-flash-64-and-reboot");
 605        if (update_token == RTAS_UNKNOWN_SERVICE) {
 606                printk(KERN_ALERT "FLASH: ibm,update-flash-64-and-reboot "
 607                       "is not available -- not a service partition?\n");
 608                printk(KERN_ALERT "FLASH: firmware will not be flashed\n");
 609                return;
 610        }
 611
 612        /* NOTE: the "first" block list is a global var with no data
 613         * blocks in the kernel data segment.  We do this because
 614         * we want to ensure this block_list addr is under 4GB.
 615         */
 616        rtas_firmware_flash_list.num_blocks = 0;
 617        flist = (struct flash_block_list *)&rtas_firmware_flash_list;
 618        rtas_block_list = virt_to_abs(flist);
 619        if (rtas_block_list >= 4UL*1024*1024*1024) {
 620                printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n");
 621                return;
 622        }
 623
 624        printk(KERN_ALERT "FLASH: preparing saved firmware image for flash\n");
 625        /* Update the block_list in place. */
 626        image_size = 0;
 627        for (f = flist; f; f = next) {
 628                /* Translate data addrs to absolute */
 629                for (i = 0; i < f->num_blocks; i++) {
 630                        f->blocks[i].data = (char *)virt_to_abs(f->blocks[i].data);
 631                        image_size += f->blocks[i].length;
 632                }
 633                next = f->next;
 634                /* Don't translate NULL pointer for last entry */
 635                if (f->next)
 636                        f->next = (struct flash_block_list *)virt_to_abs(f->next);
 637                else
 638                        f->next = NULL;
 639                /* make num_blocks into the version/length field */
 640                f->num_blocks = (FLASH_BLOCK_LIST_VERSION << 56) | ((f->num_blocks+1)*16);
 641        }
 642
 643        printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size);
 644        printk(KERN_ALERT "FLASH: performing flash and reboot\n");
 645        rtas_progress("Flashing        \n", 0x0);
 646        rtas_progress("Please Wait...  ", 0x0);
 647        printk(KERN_ALERT "FLASH: this will take several minutes.  Do not power off!\n");
 648        status = rtas_call(update_token, 1, 1, NULL, rtas_block_list);
 649        switch (status) {       /* should only get "bad" status */
 650            case 0:
 651                printk(KERN_ALERT "FLASH: success\n");
 652                break;
 653            case -1:
 654                printk(KERN_ALERT "FLASH: hardware error.  Firmware may not be not flashed\n");
 655                break;
 656            case -3:
 657                printk(KERN_ALERT "FLASH: image is corrupt or not correct for this platform.  Firmware not flashed\n");
 658                break;
 659            case -4:
 660                printk(KERN_ALERT "FLASH: flash failed when partially complete.  System may not reboot\n");
 661                break;
 662            default:
 663                printk(KERN_ALERT "FLASH: unknown flash return code %d\n", status);
 664                break;
 665        }
 666}
 667
 668static void remove_flash_pde(struct proc_dir_entry *dp)
 669{
 670        if (dp) {
 671                kfree(dp->data);
 672                dp->owner = NULL;
 673                remove_proc_entry(dp->name, dp->parent);
 674        }
 675}
 676
 677static int initialize_flash_pde_data(const char *rtas_call_name,
 678                                     size_t buf_size,
 679                                     struct proc_dir_entry *dp)
 680{
 681        int *status;
 682        int token;
 683
 684        dp->data = kzalloc(buf_size, GFP_KERNEL);
 685        if (dp->data == NULL) {
 686                remove_flash_pde(dp);
 687                return -ENOMEM;
 688        }
 689
 690        /*
 691         * This code assumes that the status int is the first member of the
 692         * struct 
 693         */
 694        status = (int *) dp->data;
 695        token = rtas_token(rtas_call_name);
 696        if (token == RTAS_UNKNOWN_SERVICE)
 697                *status = FLASH_AUTH;
 698        else
 699                *status = FLASH_NO_OP;
 700
 701        return 0;
 702}
 703
 704static struct proc_dir_entry *create_flash_pde(const char *filename,
 705                                               const struct file_operations *fops)
 706{
 707        return proc_create(filename, S_IRUSR | S_IWUSR, NULL, fops);
 708}
 709
 710static const struct file_operations rtas_flash_operations = {
 711        .owner          = THIS_MODULE,
 712        .read           = rtas_flash_read,
 713        .write          = rtas_flash_write,
 714        .open           = rtas_excl_open,
 715        .release        = rtas_flash_release,
 716};
 717
 718static const struct file_operations manage_flash_operations = {
 719        .owner          = THIS_MODULE,
 720        .read           = manage_flash_read,
 721        .write          = manage_flash_write,
 722        .open           = rtas_excl_open,
 723        .release        = rtas_excl_release,
 724};
 725
 726static const struct file_operations validate_flash_operations = {
 727        .owner          = THIS_MODULE,
 728        .read           = validate_flash_read,
 729        .write          = validate_flash_write,
 730        .open           = rtas_excl_open,
 731        .release        = validate_flash_release,
 732};
 733
 734static int __init rtas_flash_init(void)
 735{
 736        int rc;
 737
 738        if (rtas_token("ibm,update-flash-64-and-reboot") ==
 739                       RTAS_UNKNOWN_SERVICE) {
 740                printk(KERN_ERR "rtas_flash: no firmware flash support\n");
 741                return 1;
 742        }
 743
 744        firmware_flash_pde = create_flash_pde("ppc64/rtas/"
 745                                              FIRMWARE_FLASH_NAME,
 746                                              &rtas_flash_operations);
 747        if (firmware_flash_pde == NULL) {
 748                rc = -ENOMEM;
 749                goto cleanup;
 750        }
 751
 752        rc = initialize_flash_pde_data("ibm,update-flash-64-and-reboot",
 753                                       sizeof(struct rtas_update_flash_t), 
 754                                       firmware_flash_pde);
 755        if (rc != 0)
 756                goto cleanup;
 757
 758        firmware_update_pde = create_flash_pde("ppc64/rtas/"
 759                                               FIRMWARE_UPDATE_NAME,
 760                                               &rtas_flash_operations);
 761        if (firmware_update_pde == NULL) {
 762                rc = -ENOMEM;
 763                goto cleanup;
 764        }
 765
 766        rc = initialize_flash_pde_data("ibm,update-flash-64-and-reboot",
 767                                       sizeof(struct rtas_update_flash_t), 
 768                                       firmware_update_pde);
 769        if (rc != 0)
 770                goto cleanup;
 771
 772        validate_pde = create_flash_pde("ppc64/rtas/" VALIDATE_FLASH_NAME,
 773                                        &validate_flash_operations);
 774        if (validate_pde == NULL) {
 775                rc = -ENOMEM;
 776                goto cleanup;
 777        }
 778
 779        rc = initialize_flash_pde_data("ibm,validate-flash-image",
 780                                       sizeof(struct rtas_validate_flash_t), 
 781                                       validate_pde);
 782        if (rc != 0)
 783                goto cleanup;
 784
 785        manage_pde = create_flash_pde("ppc64/rtas/" MANAGE_FLASH_NAME,
 786                                      &manage_flash_operations);
 787        if (manage_pde == NULL) {
 788                rc = -ENOMEM;
 789                goto cleanup;
 790        }
 791
 792        rc = initialize_flash_pde_data("ibm,manage-flash-image",
 793                                       sizeof(struct rtas_manage_flash_t),
 794                                       manage_pde);
 795        if (rc != 0)
 796                goto cleanup;
 797
 798        rtas_flash_term_hook = rtas_flash_firmware;
 799
 800        flash_block_cache = kmem_cache_create("rtas_flash_cache",
 801                                RTAS_BLK_SIZE, RTAS_BLK_SIZE, 0,
 802                                rtas_block_ctor);
 803        if (!flash_block_cache) {
 804                printk(KERN_ERR "%s: failed to create block cache\n",
 805                                __func__);
 806                rc = -ENOMEM;
 807                goto cleanup;
 808        }
 809        return 0;
 810
 811cleanup:
 812        remove_flash_pde(firmware_flash_pde);
 813        remove_flash_pde(firmware_update_pde);
 814        remove_flash_pde(validate_pde);
 815        remove_flash_pde(manage_pde);
 816
 817        return rc;
 818}
 819
 820static void __exit rtas_flash_cleanup(void)
 821{
 822        rtas_flash_term_hook = NULL;
 823
 824        if (flash_block_cache)
 825                kmem_cache_destroy(flash_block_cache);
 826
 827        remove_flash_pde(firmware_flash_pde);
 828        remove_flash_pde(firmware_update_pde);
 829        remove_flash_pde(validate_pde);
 830        remove_flash_pde(manage_pde);
 831}
 832
 833module_init(rtas_flash_init);
 834module_exit(rtas_flash_cleanup);
 835MODULE_LICENSE("GPL");
 836
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.