]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] cpqarray.c per-disk gendisks
authorAlexander Viro <viro@math.psu.edu>
Sat, 10 Aug 2002 09:21:54 +0000 (02:21 -0700)
committerLinus Torvalds <torvalds@penguin.transmeta.com>
Sat, 10 Aug 2002 09:21:54 +0000 (02:21 -0700)
cpqarray.c switched to per-disk gendisks

drivers/block/cpqarray.c
fs/partitions/check.c

index 26eee9bafac4d35629f63c3835c56bfcd481a683..b5e79170bb2920b05bc59215e9332b287bfa9732 100644 (file)
@@ -104,7 +104,8 @@ static struct board_type products[] = {
 };
 
 static struct hd_struct * ida;
-static struct gendisk ida_gendisk[MAX_CTLR];
+static char *ida_names;
+static struct gendisk ida_gendisk[MAX_CTLR * NWD];
 
 static struct proc_dir_entry *proc_array;
 
@@ -154,7 +155,6 @@ static inline void complete_command(cmdlist_t *cmd, int timeout);
 static void do_ida_intr(int irq, void *dev_id, struct pt_regs * regs);
 static void ida_timer(unsigned long tdata);
 static int ida_revalidate(kdev_t dev);
-static int revalidate_logvol(kdev_t dev, int maxusage);
 static int revalidate_allvol(kdev_t dev);
 
 #ifdef CONFIG_PROC_FS
@@ -166,23 +166,6 @@ static int ida_proc_get_info(char *buffer, char **start, off_t offset,
                             int length, int *eof, void *data) { return 0;}
 #endif
 
-static void ida_geninit(int ctlr)
-{
-       int i;
-       drv_info_t *drv;
-
-       for(i=0; i<NWD; i++) {
-               drv = &hba[ctlr]->drv[i];
-               if (!drv->nr_blks)
-                       continue;
-               ida[(ctlr<<CTLR_SHIFT) + (i<<NWD_SHIFT)].nr_sects = drv->nr_blks;
-
-               (BLK_DEFAULT_QUEUE(MAJOR_NR + ctlr))->hardsect_size = drv->blk_size;
-               ida_gendisk[ctlr].nr_real++;
-       }
-
-}
-
 static struct block_device_operations ida_fops  = {
        owner:          THIS_MODULE,
        open:           ida_open,
@@ -307,7 +290,7 @@ int __init init_module(void)
 
 void cleanup_module(void)
 {
-       int i;
+       int i, j;
        char buff[4]; 
 
        for(i=0; i<nr_ctlr; i++) {
@@ -331,11 +314,15 @@ void cleanup_module(void)
                        hba[i]->cmd_pool_dhandle);
                kfree(hba[i]->cmd_pool_bits);
 
-               del_gendisk(&ida_gendisk[i]);
+               for (j = 0; j < NWD; j++) {
+                       if (ida_gendisk[i*NWD+j].major_name)
+                               del_gendisk(&ida_gendisk[i*NWD+j]);
+               }
        }
        devfs_find_and_unregister(NULL, "ida", 0, 0, 0, 0);
        remove_proc_entry("cpqarray", proc_root_driver);
        kfree(ida);
+       kfree(ida_names);
 }
 #endif /* MODULE */
 
@@ -349,7 +336,6 @@ int __init cpqarray_init(void)
        request_queue_t *q;
        int i,j;
        int num_cntlrs_reg = 0;
-
        /* detect controllers */
        cpqarray_pci_detect();
        cpqarray_eisa_detect();
@@ -362,16 +348,15 @@ int __init cpqarray_init(void)
 
        /* allocate space for disk structs */
        ida = kmalloc(sizeof(struct hd_struct)*nr_ctlr*NWD*16, GFP_KERNEL);
-       if(ida==NULL)
-       {
+       ida_names = kmalloc(nr_ctlr*NWD*10, GFP_KERNEL);
+       if (!ida || !ida_names) {
                printk( KERN_ERR "cpqarray: out of memory");
+               kfree(ida);
+               kfree(ida_names);
                return(num_cntlrs_reg);
        }
-       
        memset(ida, 0, sizeof(struct hd_struct)*nr_ctlr*NWD*16);
-       memset(ida_gendisk, 0, sizeof(struct gendisk)*MAX_CTLR);
-
-               /* 
+       /* 
         * register block devices
         * Find disks and fill in structs
         * Get an interrupt, set the Q depth and get into /proc
@@ -424,6 +409,7 @@ int __init cpqarray_init(void)
                        if (num_cntlrs_reg == 0) 
                        {
                                kfree(ida);
+                               kfree(ida_names);
                        }
                        return(num_cntlrs_reg);
        
@@ -450,30 +436,34 @@ int __init cpqarray_init(void)
 
                /* This is a driver limit and could be eliminated. */
                blk_queue_max_phys_segments(q, SG_MAX);
-
-               ida_gendisk[i].major = MAJOR_NR + i;
-               ida_gendisk[i].major_name = "ida";
-               ida_gendisk[i].minor_shift = NWD_SHIFT;
-               ida_gendisk[i].part = ida + (i*256);
-               ida_gendisk[i].nr_real = 0; 
-               ida_gendisk[i].de_arr = de_arr[i]; 
-               ida_gendisk[i].fops = &ida_fops; 
        
-               /* Get on the disk list */
-               add_gendisk(&ida_gendisk[i]);
-
                init_timer(&hba[i]->timer);
                hba[i]->timer.expires = jiffies + IDA_TIMER;
                hba[i]->timer.data = (unsigned long)hba[i];
                hba[i]->timer.function = ida_timer;
                add_timer(&hba[i]->timer);
 
-               ida_geninit(i);
-               for(j=0; j<NWD; j++)    
-                       register_disk(&ida_gendisk[i], 
-                               mk_kdev(MAJOR_NR+i,j<<4),
-                               16, &ida_fops, hba[i]->drv[j].nr_blks);
-
+               for(j=0; j<NWD; j++) {
+                       struct gendisk *disk = ida_gendisk + i*NWD + j;
+                       drv_info_t *drv = &hba[i]->drv[j];
+                       sprintf(ida_names + (i*NWD+j)*10, "ida/c%dd%d", i, j);
+                       disk->major = MAJOR_NR + i;
+                       disk->first_minor = j<<NWD_SHIFT;
+                       disk->minor_shift = NWD_SHIFT;
+                       disk->part = ida + i*256 + (j<<NWD_SHIFT);
+                       disk->nr_real = 1; 
+                       disk->de_arr = &de_arr[i][j]; 
+                       disk->fops = &ida_fops; 
+                       if (!drv->nr_blks)
+                               continue;
+                       disk->major_name = ida_names + (i*NWD+j)*10;
+                       (BLK_DEFAULT_QUEUE(MAJOR_NR + i))->hardsect_size = drv->blk_size;
+                       add_gendisk(disk);
+                       register_disk(disk,
+                                     mk_kdev(disk->major,disk->first_minor),
+                                     1<<disk->minor_shift, disk->fops,
+                                     drv->nr_blks);
+               }
        }
        /* done ! */
        return(num_cntlrs_reg);
@@ -755,21 +745,19 @@ static int ida_open(struct inode *inode, struct file *filep)
        if (ctlr > MAX_CTLR || hba[ctlr] == NULL)
                return -ENXIO;
 
-       if (!capable(CAP_SYS_RAWIO) && inode->i_bdev->bd_inode->i_size == 0)
-               return -ENXIO;
-
        /*
         * Root is allowed to open raw volume zero even if its not configured
         * so array config can still work.  I don't think I really like this,
         * but I'm already using way to many device nodes to claim another one
         * for "raw controller".
         */
-       if (capable(CAP_SYS_ADMIN)
-               && inode->i_bdev->bd_inode->i_size == 0
-               && minor(inode->i_rdev) != 0)
-               return -ENXIO;
-
-       hba[ctlr]->drv[dsk].usage_count++;
+       if (!hba[ctlr]->drv[dsk].nr_blks) {
+               if (!capable(CAP_SYS_RAWIO))
+                       return -ENXIO;
+               /* Huh??? */
+               if (capable(CAP_SYS_ADMIN) && minor(inode->i_rdev) != 0)
+                       return -ENXIO;
+       }
        hba[ctlr]->usage_count++;
        return 0;
 }
@@ -780,11 +768,6 @@ static int ida_open(struct inode *inode, struct file *filep)
 static int ida_release(struct inode *inode, struct file *filep)
 {
        int ctlr = major(inode->i_rdev) - MAJOR_NR;
-       int dsk  = minor(inode->i_rdev) >> NWD_SHIFT;
-
-       DBGINFO(printk("ida_release %x (%x:%x)\n", inode->i_rdev, ctlr, dsk) );
-
-       hba[ctlr]->drv[dsk].usage_count--;
        hba[ctlr]->usage_count--;
        return 0;
 }
@@ -1474,9 +1457,16 @@ static int revalidate_allvol(kdev_t dev)
         * Set the partition and block size structures for all volumes
         * on this controller to zero.  We will reread all of this data
         */
+       for (i = 0; i < NWD; i++) {
+               struct gendisk *disk = ida_gendisk + ctlr*NWD + i;
+               if (!disk->major_name)
+                       continue;
+               wipe_partitions(mk_kdev(disk->major, disk->first_minor));
+               del_gendisk(disk);
+               disk->major_name = NULL;
+       }
        memset(ida+(ctlr*256),            0, sizeof(struct hd_struct)*NWD*16);
        memset(hba[ctlr]->drv,            0, sizeof(drv_info_t)*NWD);
-       ida_gendisk[ctlr].nr_real = 0;
 
        /*
         * Tell the array controller not to give us any interrupts while
@@ -1487,11 +1477,17 @@ static int revalidate_allvol(kdev_t dev)
        getgeometry(ctlr);
        hba[ctlr]->access.set_intr_mask(hba[ctlr], FIFO_NOT_EMPTY);
 
-       ida_geninit(ctlr);
        for(i=0; i<NWD; i++) {
-               kdev_t kdev = mk_kdev(major(dev), i << NWD_SHIFT);
-               if (ida[(ctlr<<CTLR_SHIFT) + (i<<NWD_SHIFT)].nr_sects)
-                       revalidate_logvol(kdev, 2);
+               struct gendisk *disk = ida_gendisk + ctlr*NWD + i;
+               drv_info_t *drv = &hba[ctlr]->drv[i];
+               if (!drv->nr_blks)
+                       continue;
+               (BLK_DEFAULT_QUEUE(MAJOR_NR + ctlr))->hardsect_size = drv->blk_size;
+               add_gendisk(disk);
+               register_disk(disk,
+                             mk_kdev(disk->major,disk->first_minor),
+                             1<<disk->minor_shift, disk->fops,
+                             drv->nr_blks);
        }
 
        hba[ctlr]->usage_count--;
@@ -1502,47 +1498,11 @@ static int ida_revalidate(kdev_t dev)
 {
         int ctlr = major(dev) - MAJOR_NR;
        int target = DEVICE_NR(dev);
-        struct gendisk *gdev = &ida_gendisk[ctlr];
-       gdev->part[minor(dev)].nr_sects = hba[ctlr]->drv[target].nr_blocks;
+        struct gendisk *gdev = &ida_gendisk[ctlr*NWD+target];
+       gdev->part[minor(dev)].nr_sects = hba[ctlr]->drv[target].nr_blks;
        return 0;
 }
 
-/* Borrowed and adapted from sd.c */
-/*
- * FIXME: exclusion with ->open()
- */
-static int revalidate_logvol(kdev_t dev, int maxusage)
-{
-       int ctlr, target;
-       struct gendisk *gdev;
-       unsigned long flags;
-       int res;
-
-       target = DEVICE_NR(dev);
-       ctlr = major(dev) - MAJOR_NR;
-       gdev = &ida_gendisk[ctlr];
-       
-       spin_lock_irqsave(IDA_LOCK(ctlr), flags);
-       if (hba[ctlr]->drv[target].usage_count > maxusage) {
-               spin_unlock_irqrestore(IDA_LOCK(ctlr), flags);
-               printk(KERN_WARNING "cpqarray: Device busy for "
-                       "revalidation (usage=%d)\n",
-                       hba[ctlr]->drv[target].usage_count);
-               return -EBUSY;
-       }
-
-       hba[ctlr]->drv[target].usage_count++;
-       spin_unlock_irqrestore(IDA_LOCK(ctlr), flags);
-
-       res = wipe_partitions(dev);
-       if (!res)
-               grok_partitions(dev, hba[ctlr]->drv[target].nr_blks);
-
-       hba[ctlr]->drv[target].usage_count--;
-       return res;
-}
-
-
 /********************************************************************
     name: pollcomplete
     Wait polling for a command to complete.
index 8b2728ef18fddb5592fabfb20b0203e62701a09b..babf84e5f3615126fba960abbcf31c8827494351 100644 (file)
@@ -137,11 +137,6 @@ char *disk_name (struct gendisk *hd, int minor, char *buf)
                        sprintf(s, "%s%d", "md", unit);
                        maj = s;
                        break;
-               case COMPAQ_SMART2_MAJOR ... COMPAQ_SMART2_MAJOR+7:
-                       sprintf(s, "ida/c%dd%d",
-                               hd->major - COMPAQ_SMART2_MAJOR, unit);
-                       maj = s;
-                       break;
                case COMPAQ_CISS_MAJOR ... COMPAQ_CISS_MAJOR+7:
                        sprintf(s, "cciss/c%dd%d",
                                hd->major - COMPAQ_CISS_MAJOR, unit);