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