summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/poch/poch.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/drivers/staging/poch/poch.c b/drivers/staging/poch/poch.c
index 52fc3d4b433b..afc9863f34dd 100644
--- a/drivers/staging/poch/poch.c
+++ b/drivers/staging/poch/poch.c
@@ -397,11 +397,38 @@ static int poch_channel_alloc_groups(struct channel_info *channel)
return 0;
}
-static void channel_latch_attr(struct channel_info *channel)
+static int channel_latch_attr(struct channel_info *channel)
{
channel->group_count = atomic_read(&channel->sys_group_count);
channel->group_size = atomic_read(&channel->sys_group_size);
channel->block_size = atomic_read(&channel->sys_block_size);
+
+ if (channel->group_count == 0) {
+ printk(KERN_ERR PFX "invalid group count %lu",
+ channel->group_count);
+ return -EINVAL;
+ }
+
+ if (channel->group_size == 0 ||
+ channel->group_size < channel->block_size) {
+ printk(KERN_ERR PFX "invalid group size %lu",
+ channel->group_size);
+ return -EINVAL;
+ }
+
+ if (channel->block_size == 0 || (channel->block_size % 8) != 0) {
+ printk(KERN_ERR PFX "invalid block size %lu",
+ channel->block_size);
+ return -EINVAL;
+ }
+
+ if (channel->group_size % channel->block_size != 0) {
+ printk(KERN_ERR PFX
+ "group size should be multiple of block size");
+ return -EINVAL;
+ }
+
+ return 0;
}
/*
@@ -547,7 +574,9 @@ static int poch_channel_init(struct channel_info *channel,
printk(KERN_WARNING "channel_latch_attr\n");
- channel_latch_attr(channel);
+ ret = channel_latch_attr(channel);
+ if (ret != 0)
+ goto out;
channel->transfer = 0;
@@ -1359,12 +1388,12 @@ static void poch_pci_remove(struct pci_dev *pdev)
unsigned int minor = MINOR(poch_dev->cdev.dev);
unsigned int id = minor / poch_dev->nchannels;
- /* FIXME: unmap fpga_iomem and bridge_iomem */
-
poch_class_dev_unregister(poch_dev, id);
cdev_del(&poch_dev->cdev);
idr_remove(&poch_ids, id);
free_irq(pdev->irq, poch_dev);
+ iounmap(poch_dev->fpga_iomem);
+ iounmap(poch_dev->bridge_iomem);
uio_unregister_device(uio);
pci_release_regions(pdev);
pci_disable_device(pdev);