static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg) { struct NFTLrecord *nftl; nftl = NFTLs[MINOR(inode->i_rdev) / 16]; if (!nftl) return -EINVAL; switch (cmd) { case HDIO_GETGEO: { struct hd_geometry g; g.heads = nftl->heads; g.sectors = nftl->sectors; g.cylinders = nftl->cylinders; g.start = part_table[MINOR(inode->i_rdev)].start_sect; return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0; } case BLKGETSIZE: /* Return device size */ if (!arg) return -EINVAL; return put_user(part_table[MINOR(inode->i_rdev)].nr_sects, (long *) arg); case BLKFLSBUF: if (!capable(CAP_SYS_ADMIN)) return -EACCES; fsync_dev(inode->i_rdev); invalidate_buffers(inode->i_rdev); if (nftl->mtd->sync) nftl->mtd->sync(nftl->mtd); return 0; case BLKRRPART: if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (nftl->usecount > 1) return -EBUSY; #if LINUX_VERSION_CODE < 0x20328 resetup_one_dev(&nftl_gendisk, MINOR(inode->i_rdev) / 16); #else grok_partitions(&nftl_gendisk, MINOR(inode->i_rdev) / 16, 1<<4, nftl->nr_sects); #endif return 0; #if (LINUX_VERSION_CODE < 0x20303) RO_IOCTLS(inode->i_rdev, arg); /* ref. linux/blk.h */ #else case BLKROSET: case BLKROGET: case BLKSSZGET: return blk_ioctl(inode->i_rdev, cmd, arg); #endif default: return -EINVAL; } }
int init_module(void) { int i, j; cpqarray_init(); if (nr_ctlr == 0) return -EIO; for(i=0; i<nr_ctlr; i++) { ida_geninit(&ida_gendisk[i]); for(j=0; j<NWD; j++) if (ida_sizes[(i<<CTLR_SHIFT) + (j<<NWD_SHIFT)]) resetup_one_dev(&ida_gendisk[i], j); } return 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 }