drivers/block/cpqarray.c | 110 ++++++++++++++++++++++++----------------------- 1 files changed, 58 insertions(+), 52 deletions(-) diff -puN drivers/block/cpqarray.c~T26-cpqarray-C69 drivers/block/cpqarray.c --- 25/drivers/block/cpqarray.c~T26-cpqarray-C69 2003-05-05 22:37:53.000000000 -0700 +++ 25-akpm/drivers/block/cpqarray.c 2003-05-05 22:37:53.000000000 -0700 @@ -134,7 +134,7 @@ static int sendcmd( static int ida_open(struct inode *inode, struct file *filep); static int ida_release(struct inode *inode, struct file *filep); static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg); -static int ida_ctlr_ioctl(int ctlr, int dsk, ida_ioctl_t *io); +static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io); static void do_ida_request(request_queue_t *q); static void start_io(ctlr_info_t *h); @@ -147,7 +147,7 @@ static inline void complete_command(cmdl static irqreturn_t do_ida_intr(int irq, void *dev_id, struct pt_regs * regs); static void ida_timer(unsigned long tdata); static int ida_revalidate(struct gendisk *disk); -static int revalidate_allvol(kdev_t dev); +static int revalidate_allvol(ctlr_info_t *host); #ifdef CONFIG_PROC_FS static void ida_procinit(int i); @@ -158,6 +158,17 @@ static int ida_proc_get_info(char *buffe int length, int *eof, void *data) { return 0;} #endif +static inline drv_info_t *get_drv(struct gendisk *disk) +{ + return disk->private_data; +} + +static inline ctlr_info_t *get_host(struct gendisk *disk) +{ + return disk->queue->queuedata; +} + + static struct block_device_operations ida_fops = { .owner = THIS_MODULE, .open = ida_open, @@ -401,7 +412,7 @@ static int __init cpqarray_init(void) disk->major = COMPAQ_SMART2_MAJOR + i; disk->first_minor = j<fops = &ida_fops; - if (!drv->nr_blks) + if (j && !drv->nr_blks) continue; hba[i]->queue.hardsect_size = drv->blk_size; set_capacity(disk, drv->nr_blks); @@ -704,27 +715,23 @@ DBGINFO( */ static int ida_open(struct inode *inode, struct file *filep) { - int ctlr = major(inode->i_rdev) - COMPAQ_SMART2_MAJOR; - int dsk = minor(inode->i_rdev) >> NWD_SHIFT; - - DBGINFO(printk("ida_open %x (%x:%x)\n", inode->i_rdev, ctlr, dsk) ); - if (ctlr > MAX_CTLR || hba[ctlr] == NULL) - return -ENXIO; + drv_info_t *drv = get_drv(inode->i_bdev->bd_disk); + ctlr_info_t *host = get_host(inode->i_bdev->bd_disk); + DBGINFO(printk("ida_open %s\n", inode->i_bdev->bd_disk->disk_name)); /* * Root is allowed to open raw volume zero even if it's 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 (!hba[ctlr]->drv[dsk].nr_blks) { + if (!drv->nr_blks) { if (!capable(CAP_SYS_RAWIO)) return -ENXIO; - /* Huh??? */ - if (capable(CAP_SYS_ADMIN) && minor(inode->i_rdev) != 0) + if (!capable(CAP_SYS_ADMIN) && drv != host->drv) return -ENXIO; } - hba[ctlr]->usage_count++; + host->usage_count++; return 0; } @@ -733,8 +740,8 @@ static int ida_open(struct inode *inode, */ static int ida_release(struct inode *inode, struct file *filep) { - int ctlr = major(inode->i_rdev) - COMPAQ_SMART2_MAJOR; - hba[ctlr]->usage_count--; + ctlr_info_t *host = get_host(inode->i_bdev->bd_disk); + host->usage_count--; return 0; } @@ -1015,8 +1022,8 @@ static void ida_timer(unsigned long tdat */ static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg) { - int ctlr = major(inode->i_rdev) - COMPAQ_SMART2_MAJOR; - int dsk = minor(inode->i_rdev) >> NWD_SHIFT; + drv_info_t *drv = get_drv(inode->i_bdev->bd_disk); + ctlr_info_t *host = get_host(inode->i_bdev->bd_disk); int error; int diskinfo[4]; struct hd_geometry *geo = (struct hd_geometry *)arg; @@ -1025,14 +1032,14 @@ static int ida_ioctl(struct inode *inode switch(cmd) { case HDIO_GETGEO: - if (hba[ctlr]->drv[dsk].cylinders) { - diskinfo[0] = hba[ctlr]->drv[dsk].heads; - diskinfo[1] = hba[ctlr]->drv[dsk].sectors; - diskinfo[2] = hba[ctlr]->drv[dsk].cylinders; + if (drv->cylinders) { + diskinfo[0] = drv->heads; + diskinfo[1] = drv->sectors; + diskinfo[2] = drv->cylinders; } else { diskinfo[0] = 0xff; diskinfo[1] = 0x3f; - diskinfo[2] = hba[ctlr]->drv[dsk].nr_blks / (0xff*0x3f); + diskinfo[2] = drv->nr_blks / (0xff*0x3f); } put_user(diskinfo[0], &geo->heads); put_user(diskinfo[1], &geo->sectors); @@ -1040,23 +1047,24 @@ static int ida_ioctl(struct inode *inode put_user(get_start_sect(inode->i_bdev), &geo->start); return 0; case IDAGETDRVINFO: - if (copy_to_user(&io->c.drv, &hba[ctlr]->drv[dsk], - sizeof(drv_info_t))) + if (copy_to_user(&io->c.drv, drv, sizeof(drv_info_t))) return -EFAULT; return 0; case IDAPASSTHRU: if (!capable(CAP_SYS_RAWIO)) return -EPERM; if (copy_from_user(&my_io, io, sizeof(my_io))) return -EFAULT; - error = ida_ctlr_ioctl(ctlr, dsk, &my_io); + error = ida_ctlr_ioctl(host, drv - host->drv, &my_io); if (error) return error; return copy_to_user(io, &my_io, sizeof(my_io)) ? -EFAULT : 0; case IDAGETCTLRSIG: if (!arg) return -EINVAL; - put_user(hba[ctlr]->ctlr_sig, (int*)arg); + put_user(host->ctlr_sig, (int*)arg); return 0; case IDAREVALIDATEVOLS: - return revalidate_allvol(inode->i_rdev); + if (minor(inode->i_rdev) != 0) + return -ENXIO; + return revalidate_allvol(host); case IDADRIVERVERSION: if (!arg) return -EINVAL; put_user(DRIVER_VERSION, (unsigned long*)arg); @@ -1067,9 +1075,9 @@ static int ida_ioctl(struct inode *inode ida_pci_info_struct pciinfo; if (!arg) return -EINVAL; - pciinfo.bus = hba[ctlr]->pci_dev->bus->number; - pciinfo.dev_fn = hba[ctlr]->pci_dev->devfn; - pciinfo.board_id = hba[ctlr]->board_id; + pciinfo.bus = host->pci_dev->bus->number; + pciinfo.dev_fn = host->pci_dev->devfn; + pciinfo.board_id = host->board_id; if(copy_to_user((void *) arg, &pciinfo, sizeof( ida_pci_info_struct))) return -EFAULT; @@ -1091,9 +1099,9 @@ static int ida_ioctl(struct inode *inode * any serious sanity checking on the arguments. Doing an IDA_WRITE_MEDIA and * putting a 64M buffer in the sglist is probably a *bad* idea. */ -static int ida_ctlr_ioctl(int ctlr, int dsk, ida_ioctl_t *io) +static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io) { - ctlr_info_t *h = hba[ctlr]; + int ctlr = h->ctlr; cmdlist_t *c; void *p = NULL; unsigned long flags; @@ -1387,59 +1395,57 @@ DBG( * particualar logical volume (instead of all of them on a particular * controller). */ -static int revalidate_allvol(kdev_t dev) +static int revalidate_allvol(ctlr_info_t *host) { - int ctlr, i; + int ctlr = host->ctlr; + int i; unsigned long flags; - if (minor(dev) != 0) - return -ENXIO; - - ctlr = major(dev) - COMPAQ_SMART2_MAJOR; - spin_lock_irqsave(IDA_LOCK(ctlr), flags); - if (hba[ctlr]->usage_count > 1) { + if (host->usage_count > 1) { spin_unlock_irqrestore(IDA_LOCK(ctlr), flags); printk(KERN_WARNING "cpqarray: Device busy for volume" - " revalidation (usage=%d)\n", hba[ctlr]->usage_count); + " revalidation (usage=%d)\n", host->usage_count); return -EBUSY; } - hba[ctlr]->usage_count++; + host->usage_count++; spin_unlock_irqrestore(IDA_LOCK(ctlr), flags); /* * 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++) { + set_capacity(ida_gendisk[ctlr][0], 0); + for (i = 1; i < NWD; i++) { struct gendisk *disk = ida_gendisk[ctlr][i]; if (disk->flags & GENHD_FL_UP) del_gendisk(disk); } - memset(hba[ctlr]->drv, 0, sizeof(drv_info_t)*NWD); + memset(host->drv, 0, sizeof(drv_info_t)*NWD); /* * Tell the array controller not to give us any interrupts while * we check the new geometry. Then turn interrupts back on when * we're done. */ - hba[ctlr]->access.set_intr_mask(hba[ctlr], 0); + host->access.set_intr_mask(host, 0); getgeometry(ctlr); - hba[ctlr]->access.set_intr_mask(hba[ctlr], FIFO_NOT_EMPTY); + host->access.set_intr_mask(host, FIFO_NOT_EMPTY); for(i=0; idrv[i]; - if (!drv->nr_blks) + drv_info_t *drv = &host->drv[i]; + if (i && !drv->nr_blks) continue; - hba[ctlr]->queue.hardsect_size = drv->blk_size; + host->queue.hardsect_size = drv->blk_size; set_capacity(disk, drv->nr_blks); - disk->queue = &hba[ctlr]->queue; + disk->queue = &host->queue; disk->private_data = drv; - add_disk(disk); + if (i) + add_disk(disk); } - hba[ctlr]->usage_count--; + host->usage_count--; return 0; } _