Esempio n. 1
0
static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
{
    struct NFTLrecord *nftl;
    unsigned long temp;

    if (mtd->type != MTD_NANDFLASH)
        return;
    /* OK, this is moderately ugly.  But probably safe.  Alternatives? */
    if (memcmp(mtd->name, "DiskOnChip", 10))
        return;

    if (!mtd->block_isbad) {
        printk(KERN_ERR
               "NFTL no longer supports the old DiskOnChip drivers loaded via docprobe.\n"
               "Please use the new diskonchip driver under the NAND subsystem.\n");
        return;
    }

    DEBUG(MTD_DEBUG_LEVEL1, "NFTL: add_mtd for %s\n", mtd->name);

    nftl = kmalloc(sizeof(struct NFTLrecord), GFP_KERNEL);

    if (!nftl) {
        printk(KERN_WARNING "NFTL: out of memory for data structures\n");
        return;
    }
    memset(nftl, 0, sizeof(*nftl));

    nftl->mbd.mtd = mtd;
    nftl->mbd.devnum = -1;
    nftl->mbd.blksize = 512;
    nftl->mbd.tr = tr;
    memcpy(&nftl->oobinfo, &mtd->oobinfo, sizeof(struct nand_oobinfo));
    nftl->oobinfo.useecc = MTD_NANDECC_PLACEONLY;

    if (NFTL_mount(nftl) < 0) {
        printk(KERN_WARNING "NFTL: could not mount device\n");
        kfree(nftl);
        return;
    }

    /* OK, it's a new one. Set up all the data structures. */

    /* Calculate geometry */
    nftl->cylinders = 1024;
    nftl->heads = 16;

    temp = nftl->cylinders * nftl->heads;
    nftl->sectors = nftl->mbd.size / temp;
    if (nftl->mbd.size % temp) {
        nftl->sectors++;
        temp = nftl->cylinders * nftl->sectors;
        nftl->heads = nftl->mbd.size / temp;

        if (nftl->mbd.size % temp) {
            nftl->heads++;
            temp = nftl->heads * nftl->sectors;
            nftl->cylinders = nftl->mbd.size / temp;
        }
    }

    if (nftl->mbd.size != nftl->heads * nftl->cylinders * nftl->sectors) {
        /*
          Oh no we don't have
           mbd.size == heads * cylinders * sectors
        */
        printk(KERN_WARNING "NFTL: cannot calculate a geometry to "
               "match size of 0x%lx.\n", nftl->mbd.size);
        printk(KERN_WARNING "NFTL: using C:%d H:%d S:%d "
               "(== 0x%lx sects)\n",
               nftl->cylinders, nftl->heads , nftl->sectors,
               (long)nftl->cylinders * (long)nftl->heads *
               (long)nftl->sectors );
    }

    if (add_mtd_blktrans_dev(&nftl->mbd)) {
        if (nftl->ReplUnitTable)
            kfree(nftl->ReplUnitTable);
        if (nftl->EUNtable)
            kfree(nftl->EUNtable);
        kfree(nftl);
        return;
    }
#ifdef PSYCHO_DEBUG
    printk(KERN_INFO "NFTL: Found new nftl%c\n", nftl->mbd.devnum + 'a');
#endif
}
static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
{
	struct NFTLrecord *nftl;
	unsigned long temp;

	if (mtd->ecctype != MTD_ECC_RS_DiskOnChip)
		return;

	DEBUG(MTD_DEBUG_LEVEL1, "NFTL: add_mtd for %s\n", mtd->name);

	nftl = kmalloc(sizeof(struct NFTLrecord), GFP_KERNEL);

	if (!nftl) {
		printk(KERN_WARNING "NFTL: out of memory for data structures\n");
		return;
	}
	memset(nftl, 0, sizeof(*nftl));

	nftl->mbd.mtd = mtd;
	nftl->mbd.devnum = -1;
	nftl->mbd.blksize = 512;
	nftl->mbd.tr = tr;

        if (NFTL_mount(nftl) < 0) {
		printk(KERN_WARNING "NFTL: could not mount device\n");
		kfree(nftl);
		return;
        }

	/* OK, it's a new one. Set up all the data structures. */

	/* Calculate geometry */
	nftl->cylinders = 1024;
	nftl->heads = 16;

	temp = nftl->cylinders * nftl->heads;
	nftl->sectors = nftl->mbd.size / temp;
	if (nftl->mbd.size % temp) {
		nftl->sectors++;
		temp = nftl->cylinders * nftl->sectors;
		nftl->heads = nftl->mbd.size / temp;

		if (nftl->mbd.size % temp) {
			nftl->heads++;
			temp = nftl->heads * nftl->sectors;
			nftl->cylinders = nftl->mbd.size / temp;
		}
	}

	if (nftl->mbd.size != nftl->heads * nftl->cylinders * nftl->sectors) {
		/*
		  Oh no we don't have 
		   mbd.size == heads * cylinders * sectors
		*/
		printk(KERN_WARNING "NFTL: cannot calculate a geometry to "
		       "match size of 0x%lx.\n", nftl->mbd.size);
		printk(KERN_WARNING "NFTL: using C:%d H:%d S:%d "
			"(== 0x%lx sects)\n",
			nftl->cylinders, nftl->heads , nftl->sectors, 
			(long)nftl->cylinders * (long)nftl->heads *
			(long)nftl->sectors );
	}

	if (add_mtd_blktrans_dev(&nftl->mbd)) {
		if (nftl->ReplUnitTable)
			kfree(nftl->ReplUnitTable);
		if (nftl->EUNtable)
			kfree(nftl->EUNtable);
		kfree(nftl);
		return;
	}
#ifdef PSYCHO_DEBUG
	printk(KERN_INFO "NFTL: Found new nftl%c\n", nftl->mbd.devnum + 'a');
#endif
}
Esempio n. 3
0
static void NFTL_setup(struct mtd_info *mtd)
{
	int i;
	struct NFTLrecord *nftl;
	unsigned long temp;
	int firstfree = -1;

	DEBUG(MTD_DEBUG_LEVEL1,"NFTL_setup\n");

	for (i = 0; i < MAX_NFTLS; i++) {
		if (!NFTLs[i] && firstfree == -1)
			firstfree = i;
		else if (NFTLs[i] && NFTLs[i]->mtd == mtd) {
			/* This is a Spare Media Header for an NFTL we've already found */
			DEBUG(MTD_DEBUG_LEVEL1, "MTD already mounted as NFTL\n");
			return;
		}
	}
        if (firstfree == -1) {
		printk(KERN_WARNING "No more NFTL slot available\n");
		return;
        }

	nftl = kmalloc(sizeof(struct NFTLrecord), GFP_KERNEL);
	if (!nftl) {
		printk(KERN_WARNING "Out of memory for NFTL data structures\n");
		return;
	}

	init_MUTEX(&nftl->mutex);

	nftl->mtd = mtd;

        if (NFTL_mount(nftl) < 0) {
		printk(KERN_WARNING "Could not mount NFTL device\n");
		kfree(nftl);
		return;
        }

	/* OK, it's a new one. Set up all the data structures. */
#ifdef PSYCHO_DEBUG
	printk("Found new NFTL nftl%c\n", firstfree + 'a');
#endif

        /* linux stuff */
	nftl->usecount = 0;
	nftl->cylinders = 1024;
	nftl->heads = 16;

	temp = nftl->cylinders * nftl->heads;
	nftl->sectors = nftl->nr_sects / temp;
	if (nftl->nr_sects % temp) {
		nftl->sectors++;
		temp = nftl->cylinders * nftl->sectors;
		nftl->heads = nftl->nr_sects / temp;

		if (nftl->nr_sects % temp) {
			nftl->heads++;
			temp = nftl->heads * nftl->sectors;
			nftl->cylinders = nftl->nr_sects / temp;
		}
	}

	if (nftl->nr_sects != nftl->heads * nftl->cylinders * nftl->sectors) {
		printk(KERN_WARNING "Cannot calculate an NFTL geometry to "
		       "match size of 0x%x.\n", nftl->nr_sects);
		printk(KERN_WARNING "Using C:%d H:%d S:%d (== 0x%lx sects)\n", 
		       nftl->cylinders, nftl->heads , nftl->sectors, 
		       (long)nftl->cylinders * (long)nftl->heads * (long)nftl->sectors );

		/* Oh no we don't have nftl->nr_sects = nftl->heads * nftl->cylinders * nftl->sectors; */
	}
	NFTLs[firstfree] = nftl;
	/* Finally, set up the block device sizes */
	nftl_sizes[firstfree * 16] = nftl->nr_sects;
	//nftl_blocksizes[firstfree*16] = 512;
	part_table[firstfree * 16].nr_sects = nftl->nr_sects;

	nftl_gendisk.nr_real++;

	/* partition check ... */
#if LINUX_VERSION_CODE < 0x20328
	resetup_one_dev(&nftl_gendisk, firstfree);
#else
	grok_partitions(&nftl_gendisk, firstfree, 1<<NFTL_PARTN_BITS, nftl->nr_sects);
#endif
}
Esempio n. 4
0
static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
{
	struct NFTLrecord *nftl;
	unsigned long temp;

	if (mtd->type != MTD_NANDFLASH || mtd->size > UINT_MAX)
		return;
	/* OK, this is moderately ugly.  But probably safe.  Alternatives? */
	if (memcmp(mtd->name, "DiskOnChip", 10))
		return;

	pr_debug("NFTL: add_mtd for %s\n", mtd->name);

	nftl = kzalloc(sizeof(struct NFTLrecord), GFP_KERNEL);

	if (!nftl)
		return;

	nftl->mbd.mtd = mtd;
	nftl->mbd.devnum = -1;

	nftl->mbd.tr = tr;

        if (NFTL_mount(nftl) < 0) {
		printk(KERN_WARNING "NFTL: could not mount device\n");
		kfree(nftl);
		return;
        }

	/* OK, it's a new one. Set up all the data structures. */

	/* Calculate geometry */
	nftl->cylinders = 1024;
	nftl->heads = 16;

	temp = nftl->cylinders * nftl->heads;
	nftl->sectors = nftl->mbd.size / temp;
	if (nftl->mbd.size % temp) {
		nftl->sectors++;
		temp = nftl->cylinders * nftl->sectors;
		nftl->heads = nftl->mbd.size / temp;

		if (nftl->mbd.size % temp) {
			nftl->heads++;
			temp = nftl->heads * nftl->sectors;
			nftl->cylinders = nftl->mbd.size / temp;
		}
	}

	if (nftl->mbd.size != nftl->heads * nftl->cylinders * nftl->sectors) {
		/*
		  Oh no we don't have
		   mbd.size == heads * cylinders * sectors
		*/
		printk(KERN_WARNING "NFTL: cannot calculate a geometry to "
		       "match size of 0x%lx.\n", nftl->mbd.size);
		printk(KERN_WARNING "NFTL: using C:%d H:%d S:%d "
			"(== 0x%lx sects)\n",
			nftl->cylinders, nftl->heads , nftl->sectors,
			(long)nftl->cylinders * (long)nftl->heads *
			(long)nftl->sectors );
	}

	if (add_mtd_blktrans_dev(&nftl->mbd)) {
		kfree(nftl->ReplUnitTable);
		kfree(nftl->EUNtable);
		kfree(nftl);
		return;
	}
#ifdef PSYCHO_DEBUG
	printk(KERN_INFO "NFTL: Found new nftl%c\n", nftl->mbd.devnum + 'a');
#endif
}