offs += (extp->MinorVersion < '4') ? 6 : 5; 
offs += extp->extra[offs+1]+2; 
static int cfi_intelext_partition_fixup(struct mtd_info *mtd,					struct cfi_private **pcfi){	struct map_info *map = mtd->priv;	struct cfi_private *cfi = *pcfi;	struct cfi_pri_intelext *extp = cfi->cmdset_priv;	/*	 * Probing of multi-partition flash ships.	 *	 * To support multiple partitions when available, we simply arrange	 * for each of them to have their own flchip structure even if they	 * are on the same physical chip.  This means completely recreating	 * a new cfi_private structure right here which is a blatent code	 * layering violation, but this is still the least intrusive	 * arrangement at this point. This can be rearranged in the future	 * if someone feels motivated enough.  --nico	 */	if (extp && extp->MajorVersion == '1' && extp->MinorVersion >= '3'	    && extp->FeatureSupport & (1 << 9)) {		struct cfi_private *newcfi;		struct flchip *chip;		struct flchip_shared *shared;		int offs, numregions, numparts, partshift, numvirtchips, i, j;		/* Protection Register info */		offs = (extp->NumProtectionFields - 1) *		       sizeof(struct cfi_intelext_otpinfo);		/* Burst Read info */		offs += (extp->MinorVersion < '4') ? 6 : 5;		/* Number of partition regions */		numregions = extp->extra[offs];		offs += 1;		/* skip the sizeof(partregion) field in CFI 1.4 */		if (extp->MinorVersion >= '4')			offs += 2;		/* Number of hardware partitions */		numparts = 0;		for (i = 0; i < numregions; i++) {			struct cfi_intelext_regioninfo *rinfo;			rinfo = (struct cfi_intelext_regioninfo *)&extp->extra[offs];			numparts += rinfo->NumIdentPartitions;			offs += sizeof(*rinfo)				+ (rinfo->NumBlockTypes - 1) *				  sizeof(struct cfi_intelext_blockinfo);		}		/* Programming Region info */		if (extp->MinorVersion >= '4') {			struct cfi_intelext_programming_regioninfo *prinfo;			prinfo = (struct cfi_intelext_programming_regioninfo *)&extp->extra[offs];			MTD_PROGREGION_SIZE(mtd) = cfi->interleave << prinfo->ProgRegShift;			MTD_PROGREGION_CTRLMODE_VALID(mtd) = cfi->interleave * prinfo->ControlValid;			MTD_PROGREGION_CTRLMODE_INVALID(mtd) = cfi->interleave * prinfo->ControlInvalid;			mtd->flags |= MTD_PROGRAM_REGIONS;			printk(KERN_DEBUG "%s: program region size/ctrl_valid/ctrl_inval = %d/%d/%d\n",			       map->name, MTD_PROGREGION_SIZE(mtd),			       MTD_PROGREGION_CTRLMODE_VALID(mtd),			       MTD_PROGREGION_CTRLMODE_INVALID(mtd));		}		/*		 * All functions below currently rely on all chips having		 * the same geometry so we'll just assume that all hardware		 * partitions are of the same size too.		 */		partshift = cfi->chipshift - __ffs(numparts);		if ((1 << partshift) < mtd->erasesize) {			printk( KERN_ERR				"%s: bad number of hw partitions (%d)\n",				__FUNCTION__, numparts);			return -EINVAL;		}		numvirtchips = cfi->numchips * numparts;		newcfi = kmalloc(sizeof(struct cfi_private) + numvirtchips * sizeof(struct flchip), GFP_KERNEL);		if (!newcfi)			return -ENOMEM;		shared = kmalloc(sizeof(struct flchip_shared) * cfi->numchips, GFP_KERNEL);		if (!shared) {			kfree(newcfi);			return -ENOMEM;		}		memcpy(newcfi, cfi, sizeof(struct cfi_private));		newcfi->numchips = numvirtchips;		newcfi->chipshift = partshift;		chip = &newcfi->chips[0];		for (i = 0; i < cfi->numchips; i++) {			shared[i].writing = shared[i].erasing = NULL;			spin_lock_init(&shared[i].lock);			for (j = 0; j < numparts; j++) {				*chip = cfi->chips[i];				chip->start += j << partshift;				chip->priv = &shared[i];				/* those should be reset too since				   they create memory references. */				init_waitqueue_head(&chip->wq);				spin_lock_init(&chip->_spinlock);				chip->mutex = &chip->_spinlock;				chip++;			}		}		printk(KERN_DEBUG "%s: %d set(s) of %d interleaved chips "				  "--> %d partitions of %d KiB\n",				  map->name, cfi->numchips, cfi->interleave,				  newcfi->numchips, 1<<(newcfi->chipshift-10));		map->fldrv_priv = newcfi;		*pcfi = newcfi;		kfree(cfi);	}	return 0;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/6f6ed056d2d5de7af9f0c14cf5bc73707eeb0a88/cfi_cmdset_0001.c/clean/drivers/mtd/chips/cfi_cmdset_0001.c