LCOV - code coverage report
Current view: top level - drivers/mtd/chips - fwh_lock.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 30 0.0 %
Date: 2014-02-18 Functions: 0 4 0.0 %
Branches: 0 4 0.0 %

           Branch data     Line data    Source code
       1                 :            : #ifndef FWH_LOCK_H
       2                 :            : #define FWH_LOCK_H
       3                 :            : 
       4                 :            : 
       5                 :            : enum fwh_lock_state {
       6                 :            :         FWH_UNLOCKED   = 0,
       7                 :            :         FWH_DENY_WRITE = 1,
       8                 :            :         FWH_IMMUTABLE  = 2,
       9                 :            :         FWH_DENY_READ  = 4,
      10                 :            : };
      11                 :            : 
      12                 :            : struct fwh_xxlock_thunk {
      13                 :            :         enum fwh_lock_state val;
      14                 :            :         flstate_t state;
      15                 :            : };
      16                 :            : 
      17                 :            : 
      18                 :            : #define FWH_XXLOCK_ONEBLOCK_LOCK   ((struct fwh_xxlock_thunk){ FWH_DENY_WRITE, FL_LOCKING})
      19                 :            : #define FWH_XXLOCK_ONEBLOCK_UNLOCK ((struct fwh_xxlock_thunk){ FWH_UNLOCKED,   FL_UNLOCKING})
      20                 :            : 
      21                 :            : /*
      22                 :            :  * This locking/unlock is specific to firmware hub parts.  Only one
      23                 :            :  * is known that supports the Intel command set.    Firmware
      24                 :            :  * hub parts cannot be interleaved as they are on the LPC bus
      25                 :            :  * so this code has not been tested with interleaved chips,
      26                 :            :  * and will likely fail in that context.
      27                 :            :  */
      28                 :          0 : static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
      29                 :            :         unsigned long adr, int len, void *thunk)
      30                 :            : {
      31                 :          0 :         struct cfi_private *cfi = map->fldrv_priv;
      32                 :            :         struct fwh_xxlock_thunk *xxlt = (struct fwh_xxlock_thunk *)thunk;
      33                 :            :         int ret;
      34                 :            : 
      35                 :            :         /* Refuse the operation if the we cannot look behind the chip */
      36         [ #  # ]:          0 :         if (chip->start < 0x400000) {
      37                 :            :                 pr_debug( "MTD %s(): chip->start: %lx wanted >= 0x400000\n",
      38                 :            :                         __func__, chip->start );
      39                 :            :                 return -EIO;
      40                 :            :         }
      41                 :            :         /*
      42                 :            :          * lock block registers:
      43                 :            :          * - on 64k boundariesand
      44                 :            :          * - bit 1 set high
      45                 :            :          * - block lock registers are 4MiB lower - overflow subtract (danger)
      46                 :            :          *
      47                 :            :          * The address manipulation is first done on the logical address
      48                 :            :          * which is 0 at the start of the chip, and then the offset of
      49                 :            :          * the individual chip is addted to it.  Any other order a weird
      50                 :            :          * map offset could cause problems.
      51                 :            :          */
      52                 :          0 :         adr = (adr & ~0xffffUL) | 0x2;
      53                 :          0 :         adr += chip->start - 0x400000;
      54                 :            : 
      55                 :            :         /*
      56                 :            :          * This is easy because these are writes to registers and not writes
      57                 :            :          * to flash memory - that means that we don't have to check status
      58                 :            :          * and timeout.
      59                 :            :          */
      60                 :          0 :         mutex_lock(&chip->mutex);
      61                 :          0 :         ret = get_chip(map, chip, adr, FL_LOCKING);
      62         [ #  # ]:          0 :         if (ret) {
      63                 :          0 :                 mutex_unlock(&chip->mutex);
      64                 :          0 :                 return ret;
      65                 :            :         }
      66                 :            : 
      67                 :          0 :         chip->oldstate = chip->state;
      68                 :          0 :         chip->state = xxlt->state;
      69                 :          0 :         map_write(map, CMD(xxlt->val), adr);
      70                 :            : 
      71                 :            :         /* Done and happy. */
      72                 :          0 :         chip->state = chip->oldstate;
      73                 :          0 :         put_chip(map, chip, adr);
      74                 :          0 :         mutex_unlock(&chip->mutex);
      75                 :          0 :         return 0;
      76                 :            : }
      77                 :            : 
      78                 :            : 
      79                 :          0 : static int fwh_lock_varsize(struct mtd_info *mtd, loff_t ofs, uint64_t len)
      80                 :            : {
      81                 :            :         int ret;
      82                 :            : 
      83                 :          0 :         ret = cfi_varsize_frob(mtd, fwh_xxlock_oneblock, ofs, len,
      84                 :          0 :                 (void *)&FWH_XXLOCK_ONEBLOCK_LOCK);
      85                 :            : 
      86                 :          0 :         return ret;
      87                 :            : }
      88                 :            : 
      89                 :            : 
      90                 :          0 : static int fwh_unlock_varsize(struct mtd_info *mtd, loff_t ofs, uint64_t len)
      91                 :            : {
      92                 :            :         int ret;
      93                 :            : 
      94                 :          0 :         ret = cfi_varsize_frob(mtd, fwh_xxlock_oneblock, ofs, len,
      95                 :          0 :                 (void *)&FWH_XXLOCK_ONEBLOCK_UNLOCK);
      96                 :            : 
      97                 :          0 :         return ret;
      98                 :            : }
      99                 :            : 
     100                 :          0 : static void fixup_use_fwh_lock(struct mtd_info *mtd)
     101                 :            : {
     102                 :          0 :         printk(KERN_NOTICE "using fwh lock/unlock method\n");
     103                 :            :         /* Setup for the chips with the fwh lock method */
     104                 :          0 :         mtd->_lock   = fwh_lock_varsize;
     105                 :          0 :         mtd->_unlock = fwh_unlock_varsize;
     106                 :          0 : }
     107                 :            : #endif /* FWH_LOCK_H */

Generated by: LCOV version 1.9