Commit fee64f65 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] large dev_t - second series (4/15)

	cciss cleanup - instead of playing with device numbers, we add
helper functions that get host and drive structures by gendisk and use
them in open/ioctl/release, same as had been done for cpqarray.
parent 98ba005d
...@@ -120,10 +120,10 @@ static int cciss_release(struct inode *inode, struct file *filep); ...@@ -120,10 +120,10 @@ static int cciss_release(struct inode *inode, struct file *filep);
static int cciss_ioctl(struct inode *inode, struct file *filep, static int cciss_ioctl(struct inode *inode, struct file *filep,
unsigned int cmd, unsigned long arg); unsigned int cmd, unsigned long arg);
static int revalidate_allvol(kdev_t dev); static int revalidate_allvol(ctlr_info_t *host);
static int cciss_revalidate(struct gendisk *disk); static int cciss_revalidate(struct gendisk *disk);
static int deregister_disk(int ctlr, int logvol); static int deregister_disk(struct gendisk *disk);
static int register_new_disk(int cltr); static int register_new_disk(ctlr_info_t *h);
static void cciss_getgeometry(int cntl_num); static void cciss_getgeometry(int cntl_num);
...@@ -351,34 +351,42 @@ static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int got_from_pool) ...@@ -351,34 +351,42 @@ static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int got_from_pool)
} }
} }
static inline ctlr_info_t *get_host(struct gendisk *disk)
{
return disk->queue->queuedata;
}
static inline drive_info_struct *get_drv(struct gendisk *disk)
{
return disk->private_data;
}
/* /*
* Open. Make sure the device is really there. * Open. Make sure the device is really there.
*/ */
static int cciss_open(struct inode *inode, struct file *filep) static int cciss_open(struct inode *inode, struct file *filep)
{ {
int ctlr = imajor(inode) - COMPAQ_CISS_MAJOR; ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
int dsk = iminor(inode) >> NWD_SHIFT; drive_info_struct *drv = get_drv(inode->i_bdev->bd_disk);
#ifdef CCISS_DEBUG #ifdef CCISS_DEBUG
printk(KERN_DEBUG "cciss_open %s (%x:%x)\n", inode->i_bdev->bd_disk->disk_name, ctlr, dsk); printk(KERN_DEBUG "cciss_open %s\n", inode->i_bdev->bd_disk->disk_name);
#endif /* CCISS_DEBUG */ #endif /* CCISS_DEBUG */
if (ctlr >= MAX_CTLR || hba[ctlr] == NULL)
return -ENXIO;
/* /*
* Root is allowed to open raw volume zero even if it's not configured * 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, * 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 * but I'm already using way to many device nodes to claim another one
* for "raw controller". * for "raw controller".
*/ */
if (hba[ctlr]->drv[dsk].nr_blocks == 0) { if (drv->nr_blocks == 0) {
if (iminor(inode) != 0) if (iminor(inode) != 0)
return -ENXIO; return -ENXIO;
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
} }
hba[ctlr]->drv[dsk].usage_count++; drv->usage_count++;
hba[ctlr]->usage_count++; host->usage_count++;
return 0; return 0;
} }
/* /*
...@@ -386,17 +394,15 @@ static int cciss_open(struct inode *inode, struct file *filep) ...@@ -386,17 +394,15 @@ static int cciss_open(struct inode *inode, struct file *filep)
*/ */
static int cciss_release(struct inode *inode, struct file *filep) static int cciss_release(struct inode *inode, struct file *filep)
{ {
int ctlr = imajor(inode) - COMPAQ_CISS_MAJOR; ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
int dsk = iminor(inode) >> NWD_SHIFT; drive_info_struct *drv = get_drv(inode->i_bdev->bd_disk);
#ifdef CCISS_DEBUG #ifdef CCISS_DEBUG
printk(KERN_DEBUG "cciss_release %s (%x:%x)\n", inode->i_bdev->bd_disk->disk_name, ctlr, dsk); printk(KERN_DEBUG "cciss_release %s\n", inode->i_bdev->bd_disk->disk_name);
#endif /* CCISS_DEBUG */ #endif /* CCISS_DEBUG */
/* fsync_dev(inode->i_rdev); */ drv->usage_count--;
host->usage_count--;
hba[ctlr]->drv[dsk].usage_count--;
hba[ctlr]->usage_count--;
return 0; return 0;
} }
...@@ -406,8 +412,11 @@ static int cciss_release(struct inode *inode, struct file *filep) ...@@ -406,8 +412,11 @@ static int cciss_release(struct inode *inode, struct file *filep)
static int cciss_ioctl(struct inode *inode, struct file *filep, static int cciss_ioctl(struct inode *inode, struct file *filep,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
int ctlr = imajor(inode) - COMPAQ_CISS_MAJOR; struct block_device *bdev = inode->i_bdev;
int dsk = iminor(inode) >> NWD_SHIFT; struct gendisk *disk = bdev->bd_disk;
ctlr_info_t *host = get_host(disk);
drive_info_struct *drv = get_drv(disk);
int ctlr = host->ctlr;
#ifdef CCISS_DEBUG #ifdef CCISS_DEBUG
printk(KERN_DEBUG "cciss_ioctl: Called with cmd=%x %lx\n", cmd, arg); printk(KERN_DEBUG "cciss_ioctl: Called with cmd=%x %lx\n", cmd, arg);
...@@ -417,14 +426,14 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -417,14 +426,14 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
case HDIO_GETGEO: case HDIO_GETGEO:
{ {
struct hd_geometry driver_geo; struct hd_geometry driver_geo;
if (hba[ctlr]->drv[dsk].cylinders) { if (drv->cylinders) {
driver_geo.heads = hba[ctlr]->drv[dsk].heads; driver_geo.heads = drv->heads;
driver_geo.sectors = hba[ctlr]->drv[dsk].sectors; driver_geo.sectors = drv->sectors;
driver_geo.cylinders = hba[ctlr]->drv[dsk].cylinders; driver_geo.cylinders = drv->cylinders;
} else { } else {
driver_geo.heads = 0xff; driver_geo.heads = 0xff;
driver_geo.sectors = 0x3f; driver_geo.sectors = 0x3f;
driver_geo.cylinders = (int)hba[ctlr]->drv[dsk].nr_blocks / (0xff*0x3f); driver_geo.cylinders = (int)drv->nr_blocks / (0xff*0x3f);
} }
driver_geo.start= get_start_sect(inode->i_bdev); driver_geo.start= get_start_sect(inode->i_bdev);
if (copy_to_user((void *) arg, &driver_geo, if (copy_to_user((void *) arg, &driver_geo,
...@@ -438,9 +447,9 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -438,9 +447,9 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
cciss_pci_info_struct pciinfo; cciss_pci_info_struct pciinfo;
if (!arg) return -EINVAL; if (!arg) return -EINVAL;
pciinfo.bus = hba[ctlr]->pdev->bus->number; pciinfo.bus = host->pdev->bus->number;
pciinfo.dev_fn = hba[ctlr]->pdev->devfn; pciinfo.dev_fn = host->pdev->devfn;
pciinfo.board_id = hba[ctlr]->board_id; pciinfo.board_id = host->board_id;
if (copy_to_user((void *) arg, &pciinfo, sizeof( cciss_pci_info_struct ))) if (copy_to_user((void *) arg, &pciinfo, sizeof( cciss_pci_info_struct )))
return -EFAULT; return -EFAULT;
return(0); return(0);
...@@ -448,11 +457,9 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -448,11 +457,9 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
case CCISS_GETINTINFO: case CCISS_GETINTINFO:
{ {
cciss_coalint_struct intinfo; cciss_coalint_struct intinfo;
ctlr_info_t *c = hba[ctlr];
if (!arg) return -EINVAL; if (!arg) return -EINVAL;
intinfo.delay = readl(&c->cfgtable->HostWrite.CoalIntDelay); intinfo.delay = readl(&host->cfgtable->HostWrite.CoalIntDelay);
intinfo.count = readl(&c->cfgtable->HostWrite.CoalIntCount); intinfo.count = readl(&host->cfgtable->HostWrite.CoalIntCount);
if (copy_to_user((void *) arg, &intinfo, sizeof( cciss_coalint_struct ))) if (copy_to_user((void *) arg, &intinfo, sizeof( cciss_coalint_struct )))
return -EFAULT; return -EFAULT;
return(0); return(0);
...@@ -460,7 +467,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -460,7 +467,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
case CCISS_SETINTINFO: case CCISS_SETINTINFO:
{ {
cciss_coalint_struct intinfo; cciss_coalint_struct intinfo;
ctlr_info_t *c = hba[ctlr];
unsigned long flags; unsigned long flags;
int i; int i;
...@@ -477,13 +483,13 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -477,13 +483,13 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
spin_lock_irqsave(CCISS_LOCK(ctlr), flags); spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
/* Update the field, and then ring the doorbell */ /* Update the field, and then ring the doorbell */
writel( intinfo.delay, writel( intinfo.delay,
&(c->cfgtable->HostWrite.CoalIntDelay)); &(host->cfgtable->HostWrite.CoalIntDelay));
writel( intinfo.count, writel( intinfo.count,
&(c->cfgtable->HostWrite.CoalIntCount)); &(host->cfgtable->HostWrite.CoalIntCount));
writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL); writel( CFGTBL_ChangeReq, host->vaddr + SA5_DOORBELL);
for(i=0;i<MAX_IOCTL_CONFIG_WAIT;i++) { for(i=0;i<MAX_IOCTL_CONFIG_WAIT;i++) {
if (!(readl(c->vaddr + SA5_DOORBELL) if (!(readl(host->vaddr + SA5_DOORBELL)
& CFGTBL_ChangeReq)) & CFGTBL_ChangeReq))
break; break;
/* delay and try again */ /* delay and try again */
...@@ -497,12 +503,11 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -497,12 +503,11 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
case CCISS_GETNODENAME: case CCISS_GETNODENAME:
{ {
NodeName_type NodeName; NodeName_type NodeName;
ctlr_info_t *c = hba[ctlr];
int i; int i;
if (!arg) return -EINVAL; if (!arg) return -EINVAL;
for(i=0;i<16;i++) for(i=0;i<16;i++)
NodeName[i] = readb(&c->cfgtable->ServerName[i]); NodeName[i] = readb(&host->cfgtable->ServerName[i]);
if (copy_to_user((void *) arg, NodeName, sizeof( NodeName_type))) if (copy_to_user((void *) arg, NodeName, sizeof( NodeName_type)))
return -EFAULT; return -EFAULT;
return(0); return(0);
...@@ -510,7 +515,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -510,7 +515,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
case CCISS_SETNODENAME: case CCISS_SETNODENAME:
{ {
NodeName_type NodeName; NodeName_type NodeName;
ctlr_info_t *c = hba[ctlr];
unsigned long flags; unsigned long flags;
int i; int i;
...@@ -524,12 +528,12 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -524,12 +528,12 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
/* Update the field, and then ring the doorbell */ /* Update the field, and then ring the doorbell */
for(i=0;i<16;i++) for(i=0;i<16;i++)
writeb( NodeName[i], &c->cfgtable->ServerName[i]); writeb( NodeName[i], &host->cfgtable->ServerName[i]);
writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL); writel( CFGTBL_ChangeReq, host->vaddr + SA5_DOORBELL);
for(i=0;i<MAX_IOCTL_CONFIG_WAIT;i++) { for(i=0;i<MAX_IOCTL_CONFIG_WAIT;i++) {
if (!(readl(c->vaddr + SA5_DOORBELL) if (!(readl(host->vaddr + SA5_DOORBELL)
& CFGTBL_ChangeReq)) & CFGTBL_ChangeReq))
break; break;
/* delay and try again */ /* delay and try again */
...@@ -544,10 +548,9 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -544,10 +548,9 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
case CCISS_GETHEARTBEAT: case CCISS_GETHEARTBEAT:
{ {
Heartbeat_type heartbeat; Heartbeat_type heartbeat;
ctlr_info_t *c = hba[ctlr];
if (!arg) return -EINVAL; if (!arg) return -EINVAL;
heartbeat = readl(&c->cfgtable->HeartBeat); heartbeat = readl(&host->cfgtable->HeartBeat);
if (copy_to_user((void *) arg, &heartbeat, sizeof( Heartbeat_type))) if (copy_to_user((void *) arg, &heartbeat, sizeof( Heartbeat_type)))
return -EFAULT; return -EFAULT;
return(0); return(0);
...@@ -555,10 +558,9 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -555,10 +558,9 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
case CCISS_GETBUSTYPES: case CCISS_GETBUSTYPES:
{ {
BusTypes_type BusTypes; BusTypes_type BusTypes;
ctlr_info_t *c = hba[ctlr];
if (!arg) return -EINVAL; if (!arg) return -EINVAL;
BusTypes = readl(&c->cfgtable->BusTypes); BusTypes = readl(&host->cfgtable->BusTypes);
if (copy_to_user((void *) arg, &BusTypes, sizeof( BusTypes_type) )) if (copy_to_user((void *) arg, &BusTypes, sizeof( BusTypes_type) ))
return -EFAULT; return -EFAULT;
return(0); return(0);
...@@ -568,7 +570,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -568,7 +570,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
FirmwareVer_type firmware; FirmwareVer_type firmware;
if (!arg) return -EINVAL; if (!arg) return -EINVAL;
memcpy(firmware, hba[ctlr]->firm_ver, 4); memcpy(firmware, host->firm_ver, 4);
if (copy_to_user((void *) arg, firmware, sizeof( FirmwareVer_type))) if (copy_to_user((void *) arg, firmware, sizeof( FirmwareVer_type)))
return -EFAULT; return -EFAULT;
...@@ -586,12 +588,12 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -586,12 +588,12 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
} }
case CCISS_REVALIDVOLS: case CCISS_REVALIDVOLS:
return( revalidate_allvol(inode->i_rdev)); if (bdev != bdev->bd_contains || drv != host->drv)
return -ENXIO;
return revalidate_allvol(host);
case CCISS_GETLUNINFO: { case CCISS_GETLUNINFO: {
LogvolInfo_struct luninfo; LogvolInfo_struct luninfo;
struct gendisk *disk = hba[ctlr]->gendisk[dsk];
drive_info_struct *drv = &hba[ctlr]->drv[dsk];
int i; int i;
luninfo.LunID = drv->LunID; luninfo.LunID = drv->LunID;
...@@ -610,16 +612,14 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -610,16 +612,14 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
return(0); return(0);
} }
case CCISS_DEREGDISK: case CCISS_DEREGDISK:
return( deregister_disk(ctlr,dsk)); return deregister_disk(disk);
case CCISS_REGNEWD: case CCISS_REGNEWD:
{ return register_new_disk(host);
return(register_new_disk(ctlr));
}
case CCISS_PASSTHRU: case CCISS_PASSTHRU:
{ {
IOCTL_Command_struct iocommand; IOCTL_Command_struct iocommand;
ctlr_info_t *h = hba[ctlr];
CommandList_struct *c; CommandList_struct *c;
char *buff = NULL; char *buff = NULL;
u64bit temp64; u64bit temp64;
...@@ -655,7 +655,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -655,7 +655,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
return -EFAULT; return -EFAULT;
} }
} }
if ((c = cmd_alloc(h , 0)) == NULL) if ((c = cmd_alloc(host , 0)) == NULL)
{ {
kfree(buff); kfree(buff);
return -ENOMEM; return -ENOMEM;
...@@ -682,7 +682,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -682,7 +682,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
// Fill in the scatter gather information // Fill in the scatter gather information
if (iocommand.buf_size > 0 ) if (iocommand.buf_size > 0 )
{ {
temp64.val = pci_map_single( h->pdev, buff, temp64.val = pci_map_single( host->pdev, buff,
iocommand.buf_size, iocommand.buf_size,
PCI_DMA_BIDIRECTIONAL); PCI_DMA_BIDIRECTIONAL);
c->SG[0].Addr.lower = temp64.val32.lower; c->SG[0].Addr.lower = temp64.val32.lower;
...@@ -694,9 +694,9 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -694,9 +694,9 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
/* Put the request on the tail of the request queue */ /* Put the request on the tail of the request queue */
spin_lock_irqsave(CCISS_LOCK(ctlr), flags); spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
addQ(&h->reqQ, c); addQ(&host->reqQ, c);
h->Qdepth++; host->Qdepth++;
start_io(h); start_io(host);
spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
wait_for_completion(&wait); wait_for_completion(&wait);
...@@ -704,7 +704,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -704,7 +704,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
/* unlock the buffers from DMA */ /* unlock the buffers from DMA */
temp64.val32.lower = c->SG[0].Addr.lower; temp64.val32.lower = c->SG[0].Addr.lower;
temp64.val32.upper = c->SG[0].Addr.upper; temp64.val32.upper = c->SG[0].Addr.upper;
pci_unmap_single( h->pdev, (dma_addr_t) temp64.val, pci_unmap_single( host->pdev, (dma_addr_t) temp64.val,
iocommand.buf_size, PCI_DMA_BIDIRECTIONAL); iocommand.buf_size, PCI_DMA_BIDIRECTIONAL);
/* Copy the error information out */ /* Copy the error information out */
...@@ -712,7 +712,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -712,7 +712,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
if ( copy_to_user((void *) arg, &iocommand, sizeof( IOCTL_Command_struct) ) ) if ( copy_to_user((void *) arg, &iocommand, sizeof( IOCTL_Command_struct) ) )
{ {
kfree(buff); kfree(buff);
cmd_free(h, c, 0); cmd_free(host, c, 0);
return( -EFAULT); return( -EFAULT);
} }
...@@ -722,17 +722,16 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -722,17 +722,16 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
if (copy_to_user(iocommand.buf, buff, iocommand.buf_size)) if (copy_to_user(iocommand.buf, buff, iocommand.buf_size))
{ {
kfree(buff); kfree(buff);
cmd_free(h, c, 0); cmd_free(host, c, 0);
return -EFAULT; return -EFAULT;
} }
} }
kfree(buff); kfree(buff);
cmd_free(h, c, 0); cmd_free(host, c, 0);
return(0); return(0);
} }
case CCISS_BIG_PASSTHRU: { case CCISS_BIG_PASSTHRU: {
BIG_IOCTL_Command_struct *ioc; BIG_IOCTL_Command_struct *ioc;
ctlr_info_t *h = hba[ctlr];
CommandList_struct *c; CommandList_struct *c;
unsigned char **buff = NULL; unsigned char **buff = NULL;
int *buff_size = NULL; int *buff_size = NULL;
...@@ -798,7 +797,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -798,7 +797,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
data_ptr += sz; data_ptr += sz;
sg_used++; sg_used++;
} }
if ((c = cmd_alloc(h , 0)) == NULL) { if ((c = cmd_alloc(host , 0)) == NULL) {
status = -ENOMEM; status = -ENOMEM;
goto cleanup1; goto cleanup1;
} }
...@@ -819,7 +818,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -819,7 +818,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
if (ioc->buf_size > 0 ) { if (ioc->buf_size > 0 ) {
int i; int i;
for(i=0; i<sg_used; i++) { for(i=0; i<sg_used; i++) {
temp64.val = pci_map_single( h->pdev, buff[i], temp64.val = pci_map_single( host->pdev, buff[i],
buff_size[i], buff_size[i],
PCI_DMA_BIDIRECTIONAL); PCI_DMA_BIDIRECTIONAL);
c->SG[i].Addr.lower = temp64.val32.lower; c->SG[i].Addr.lower = temp64.val32.lower;
...@@ -831,22 +830,22 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -831,22 +830,22 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
c->waiting = &wait; c->waiting = &wait;
/* Put the request on the tail of the request queue */ /* Put the request on the tail of the request queue */
spin_lock_irqsave(CCISS_LOCK(ctlr), flags); spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
addQ(&h->reqQ, c); addQ(&host->reqQ, c);
h->Qdepth++; host->Qdepth++;
start_io(h); start_io(host);
spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
wait_for_completion(&wait); wait_for_completion(&wait);
/* unlock the buffers from DMA */ /* unlock the buffers from DMA */
for(i=0; i<sg_used; i++) { for(i=0; i<sg_used; i++) {
temp64.val32.lower = c->SG[i].Addr.lower; temp64.val32.lower = c->SG[i].Addr.lower;
temp64.val32.upper = c->SG[i].Addr.upper; temp64.val32.upper = c->SG[i].Addr.upper;
pci_unmap_single( h->pdev, (dma_addr_t) temp64.val, pci_unmap_single( host->pdev, (dma_addr_t) temp64.val,
buff_size[i], PCI_DMA_BIDIRECTIONAL); buff_size[i], PCI_DMA_BIDIRECTIONAL);
} }
/* Copy the error information out */ /* Copy the error information out */
ioc->error_info = *(c->err_info); ioc->error_info = *(c->err_info);
if (copy_to_user((void *) arg, ioc, sizeof(*ioc))) { if (copy_to_user((void *) arg, ioc, sizeof(*ioc))) {
cmd_free(h, c, 0); cmd_free(host, c, 0);
status = -EFAULT; status = -EFAULT;
goto cleanup1; goto cleanup1;
} }
...@@ -855,14 +854,14 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -855,14 +854,14 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
BYTE *ptr = (BYTE *) ioc->buf; BYTE *ptr = (BYTE *) ioc->buf;
for(i=0; i< sg_used; i++) { for(i=0; i< sg_used; i++) {
if (copy_to_user(ptr, buff[i], buff_size[i])) { if (copy_to_user(ptr, buff[i], buff_size[i])) {
cmd_free(h, c, 0); cmd_free(host, c, 0);
status = -EFAULT; status = -EFAULT;
goto cleanup1; goto cleanup1;
} }
ptr += buff_size[i]; ptr += buff_size[i];
} }
} }
cmd_free(h, c, 0); cmd_free(host, c, 0);
status = 0; status = 0;
cleanup1: cleanup1:
if (buff) { if (buff) {
...@@ -901,27 +900,23 @@ static int cciss_revalidate(struct gendisk *disk) ...@@ -901,27 +900,23 @@ static int cciss_revalidate(struct gendisk *disk)
* particualar logical volume (instead of all of them on a particular * particualar logical volume (instead of all of them on a particular
* controller). * controller).
*/ */
static int revalidate_allvol(kdev_t dev) static int revalidate_allvol(ctlr_info_t *host)
{ {
int ctlr, i; int ctlr = host->ctlr, i;
unsigned long flags; unsigned long flags;
ctlr = major(dev) - COMPAQ_CISS_MAJOR;
if (minor(dev) != 0)
return -ENXIO;
spin_lock_irqsave(CCISS_LOCK(ctlr), flags); spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
if (hba[ctlr]->usage_count > 1) { if (host->usage_count > 1) {
spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
printk(KERN_WARNING "cciss: Device busy for volume" printk(KERN_WARNING "cciss: Device busy for volume"
" revalidation (usage=%d)\n", hba[ctlr]->usage_count); " revalidation (usage=%d)\n", host->usage_count);
return -EBUSY; return -EBUSY;
} }
hba[ctlr]->usage_count++; host->usage_count++;
spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
for(i=0; i< NWD; i++) { for(i=0; i< NWD; i++) {
struct gendisk *disk = hba[ctlr]->gendisk[i]; struct gendisk *disk = host->gendisk[i];
if (disk->flags & GENHD_FL_UP) if (disk->flags & GENHD_FL_UP)
del_gendisk(disk); del_gendisk(disk);
} }
...@@ -930,54 +925,55 @@ static int revalidate_allvol(kdev_t dev) ...@@ -930,54 +925,55 @@ static int revalidate_allvol(kdev_t dev)
* Set the partition and block size structures for all volumes * Set the partition and block size structures for all volumes
* on this controller to zero. We will reread all of this data * on this controller to zero. We will reread all of this data
*/ */
memset(hba[ctlr]->drv, 0, sizeof(drive_info_struct) memset(host->drv, 0, sizeof(drive_info_struct)
* CISS_MAX_LUN); * CISS_MAX_LUN);
/* /*
* Tell the array controller not to give us any interrupts while * Tell the array controller not to give us any interrupts while
* we check the new geometry. Then turn interrupts back on when * we check the new geometry. Then turn interrupts back on when
* we're done. * we're done.
*/ */
hba[ctlr]->access.set_intr_mask(hba[ctlr], CCISS_INTR_OFF); host->access.set_intr_mask(host, CCISS_INTR_OFF);
cciss_getgeometry(ctlr); cciss_getgeometry(ctlr);
hba[ctlr]->access.set_intr_mask(hba[ctlr], CCISS_INTR_ON); host->access.set_intr_mask(host, CCISS_INTR_ON);
/* Loop through each real device */ /* Loop through each real device */
for (i = 0; i < NWD; i++) { for (i = 0; i < NWD; i++) {
struct gendisk *disk = hba[ctlr]->gendisk[i]; struct gendisk *disk = host->gendisk[i];
drive_info_struct *drv = &(hba[ctlr]->drv[i]); drive_info_struct *drv = &(host->drv[i]);
if (!drv->nr_blocks) if (!drv->nr_blocks)
continue; continue;
blk_queue_hardsect_size(hba[ctlr]->queue, drv->block_size); blk_queue_hardsect_size(host->queue, drv->block_size);
set_capacity(disk, drv->nr_blocks); set_capacity(disk, drv->nr_blocks);
add_disk(disk); add_disk(disk);
} }
hba[ctlr]->usage_count--; host->usage_count--;
return 0; return 0;
} }
static int deregister_disk(int ctlr, int logvol) static int deregister_disk(struct gendisk *disk)
{ {
unsigned long flags; unsigned long flags;
struct gendisk *disk = hba[ctlr]->gendisk[logvol]; ctlr_info_t *h = get_host(disk);
ctlr_info_t *h = hba[ctlr]; drive_info_struct *drv = get_drv(disk);
int ctlr = h->ctlr;
if (!capable(CAP_SYS_RAWIO)) if (!capable(CAP_SYS_RAWIO))
return -EPERM; return -EPERM;
spin_lock_irqsave(CCISS_LOCK(ctlr), flags); spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
/* make sure logical volume is NOT is use */ /* make sure logical volume is NOT is use */
if( h->drv[logvol].usage_count > 1) { if( drv->usage_count > 1) {
spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
return -EBUSY; return -EBUSY;
} }
h->drv[logvol].usage_count++; drv->usage_count++;
spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
/* invalidate the devices and deregister the disk */ /* invalidate the devices and deregister the disk */
if (disk->flags & GENHD_FL_UP) if (disk->flags & GENHD_FL_UP)
del_gendisk(disk); del_gendisk(disk);
/* check to see if it was the last disk */ /* check to see if it was the last disk */
if (logvol == h->highest_lun) { if (drv == h->drv + h->highest_lun) {
/* if so, find the new hightest lun */ /* if so, find the new hightest lun */
int i, newhighest =-1; int i, newhighest =-1;
for(i=0; i<h->highest_lun; i++) { for(i=0; i<h->highest_lun; i++) {
...@@ -990,10 +986,10 @@ static int deregister_disk(int ctlr, int logvol) ...@@ -990,10 +986,10 @@ static int deregister_disk(int ctlr, int logvol)
} }
--h->num_luns; --h->num_luns;
/* zero out the disk size info */ /* zero out the disk size info */
h->drv[logvol].nr_blocks = 0; drv->nr_blocks = 0;
h->drv[logvol].block_size = 0; drv->block_size = 0;
h->drv[logvol].cylinders = 0; drv->cylinders = 0;
h->drv[logvol].LunID = 0; drv->LunID = 0;
return(0); return(0);
} }
static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff,
...@@ -1304,10 +1300,10 @@ cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf, ...@@ -1304,10 +1300,10 @@ cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf,
*total_size, *block_size); *total_size, *block_size);
return; return;
} }
static int register_new_disk(int ctlr) static int register_new_disk(ctlr_info_t *h)
{ {
struct gendisk *disk; struct gendisk *disk;
ctlr_info_t *h = hba[ctlr]; int ctlr = h->ctlr;
int i; int i;
int num_luns; int num_luns;
int logvol; int logvol;
...@@ -1417,7 +1413,7 @@ static int register_new_disk(int ctlr) ...@@ -1417,7 +1413,7 @@ static int register_new_disk(int ctlr)
#ifdef CCISS_DEBUG #ifdef CCISS_DEBUG
printk("Checking Index %d\n", i); printk("Checking Index %d\n", i);
#endif /* CCISS_DEBUG */ #endif /* CCISS_DEBUG */
if(hba[ctlr]->drv[i].LunID == 0) if(h->drv[i].LunID == 0)
{ {
#ifdef CCISS_DEBUG #ifdef CCISS_DEBUG
printk("free index found at %d\n", i); printk("free index found at %d\n", i);
...@@ -1434,19 +1430,19 @@ static int register_new_disk(int ctlr) ...@@ -1434,19 +1430,19 @@ static int register_new_disk(int ctlr)
} }
logvol = free_index; logvol = free_index;
hba[ctlr]->drv[logvol].LunID = lunid; h->drv[logvol].LunID = lunid;
/* there could be gaps in lun numbers, track hightest */ /* there could be gaps in lun numbers, track hightest */
if(hba[ctlr]->highest_lun < lunid) if(h->highest_lun < lunid)
hba[ctlr]->highest_lun = logvol; h->highest_lun = logvol;
cciss_read_capacity(ctlr, logvol, size_buff, 1, cciss_read_capacity(ctlr, logvol, size_buff, 1,
&total_size, &block_size); &total_size, &block_size);
cciss_geometry_inquiry(ctlr, logvol, 1, total_size, block_size, cciss_geometry_inquiry(ctlr, logvol, 1, total_size, block_size,
inq_buff, &hba[ctlr]->drv[logvol]); inq_buff, &h->drv[logvol]);
hba[ctlr]->drv[logvol].usage_count = 0; h->drv[logvol].usage_count = 0;
++hba[ctlr]->num_luns; ++h->num_luns;
/* setup partitions per disk */ /* setup partitions per disk */
disk = hba[ctlr]->gendisk[logvol]; disk = h->gendisk[logvol];
set_capacity(disk, hba[ctlr]->drv[logvol].nr_blocks); set_capacity(disk, h->drv[logvol].nr_blocks);
add_disk(disk); add_disk(disk);
freeret: freeret:
kfree(ld_buff); kfree(ld_buff);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment