]> err.no Git - linux-2.6/blobdiff - drivers/block/cciss.c
[PATCH] CCISS: request all PCI resources
[linux-2.6] / drivers / block / cciss.c
index 1319d8f20640505b69ebc6a37c3f9b435910ee0e..45c4c3131c8f6c8d1f3da823f104d93bf6fee8bc 100644 (file)
@@ -1221,6 +1221,7 @@ static void cciss_softirq_done(struct request *rq)
        printk("Done with %p\n", rq);
 #endif /* CCISS_DEBUG */
 
+       add_disk_randomness(rq->rq_disk);
        spin_lock_irqsave(&h->lock, flags);
        end_that_request_last(rq, rq->errors);
        cmd_free(h, cmd,1);
@@ -2637,16 +2638,6 @@ static void print_cfg_table( CfgTable_struct *tb)
 }
 #endif /* CCISS_DEBUG */ 
 
-static void release_io_mem(ctlr_info_t *c)
-{
-       /* if IO mem was not protected do nothing */
-       if( c->io_mem_addr == 0)
-               return;
-       release_region(c->io_mem_addr, c->io_mem_length);
-       c->io_mem_addr = 0;
-       c->io_mem_length = 0;
-}
-
 static int find_PCI_BAR_index(struct pci_dev *pdev,
                                unsigned long pci_bar_addr)
 {
@@ -2743,7 +2734,7 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
        __u64 cfg_offset;
        __u32 cfg_base_addr;
        __u64 cfg_base_addr_index;
-       int i;
+       int i, err;
 
        /* check to see if controller has been disabled */
        /* BEFORE trying to enable it */
@@ -2751,13 +2742,21 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
        if(!(command & 0x02))
        {
                printk(KERN_WARNING "cciss: controller appears to be disabled\n");
-               return(-1);
+               return -ENODEV;
        }
 
-       if (pci_enable_device(pdev))
+       err = pci_enable_device(pdev);
+       if (err)
        {
                printk(KERN_ERR "cciss: Unable to Enable PCI device\n");
-               return( -1);
+               return err;
+       }
+
+       err = pci_request_regions(pdev, "cciss");
+       if (err) {
+               printk(KERN_ERR "cciss: Cannot obtain PCI resources, "
+                       "aborting\n");
+               goto err_out_disable_pdev;
        }
 
        subsystem_vendor_id = pdev->subsystem_vendor;
@@ -2765,31 +2764,6 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
        board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) |
                                        subsystem_vendor_id);
 
-       /* search for our IO range so we can protect it */
-       for(i=0; i<DEVICE_COUNT_RESOURCE; i++)
-       {
-               /* is this an IO range */ 
-               if( pci_resource_flags(pdev, i) & 0x01 ) {
-                       c->io_mem_addr = pci_resource_start(pdev, i);
-                       c->io_mem_length = pci_resource_end(pdev, i) -
-                               pci_resource_start(pdev, i) +1;
-#ifdef CCISS_DEBUG
-                       printk("IO value found base_addr[%d] %lx %lx\n", i,
-                               c->io_mem_addr, c->io_mem_length);
-#endif /* CCISS_DEBUG */
-                       /* register the IO range */ 
-                       if(!request_region( c->io_mem_addr,
-                                        c->io_mem_length, "cciss"))
-                       {
-                               printk(KERN_WARNING "cciss I/O memory range already in use addr=%lx length=%ld\n",
-                               c->io_mem_addr, c->io_mem_length);
-                               c->io_mem_addr= 0;
-                               c->io_mem_length = 0;
-                       } 
-                       break;
-               }
-       }
-
 #ifdef CCISS_DEBUG
        printk("command = %x\n", command);
        printk("irq = %x\n", pdev->irq);
@@ -2823,7 +2797,8 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
        }
        if (scratchpad != CCISS_FIRMWARE_READY) {
                printk(KERN_WARNING "cciss: Board not ready.  Timed out.\n");
-               return -1;
+               err = -ENODEV;
+               goto err_out_free_res;
        }
 
        /* get the address index number */
@@ -2839,8 +2814,8 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
 #endif /* CCISS_DEBUG */
        if (cfg_base_addr_index == -1) {
                printk(KERN_WARNING "cciss: Cannot find cfg_base_addr_index\n");
-               release_io_mem(c);
-               return -1;
+               err = -ENODEV;
+               goto err_out_free_res;
        }
 
        cfg_offset = readl(c->vaddr + SA5_CTMEM_OFFSET);
@@ -2867,7 +2842,8 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
                printk(KERN_WARNING "cciss: Sorry, I don't know how"
                        " to access the Smart Array controller %08lx\n", 
                                (unsigned long)board_id);
-               return -1;
+               err = -ENODEV;
+               goto err_out_free_res;
        }
        if (  (readb(&c->cfgtable->Signature[0]) != 'C') ||
              (readb(&c->cfgtable->Signature[1]) != 'I') ||
@@ -2875,7 +2851,8 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
              (readb(&c->cfgtable->Signature[3]) != 'S') )
        {
                printk("Does not appear to be a valid CISS config table\n");
-               return -1;
+               err = -ENODEV;
+               goto err_out_free_res;
        }
 
 #ifdef CONFIG_X86
@@ -2919,10 +2896,17 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
        {
                printk(KERN_WARNING "cciss: unable to get board into"
                                        " simple mode\n");
-               return -1;
+               err = -ENODEV;
+               goto err_out_free_res;
        }
        return 0;
 
+err_out_free_res:
+       pci_release_regions(pdev);
+
+err_out_disable_pdev:
+       pci_disable_device(pdev);
+       return err;
 }
 
 /* 
@@ -3152,8 +3136,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
        /* make sure the board interrupts are off */
        hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF);
        if( request_irq(hba[i]->intr[SIMPLE_MODE_INT], do_cciss_intr,
-               SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
-                       hba[i]->devname, hba[i])) {
+               SA_INTERRUPT | SA_SHIRQ, hba[i]->devname, hba[i])) {
                printk(KERN_ERR "cciss: Unable to get irq %d for %s\n",
                        hba[i]->intr[SIMPLE_MODE_INT], hba[i]->devname);
                goto clean2;
@@ -3237,6 +3220,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
                disk->fops = &cciss_fops;
                disk->queue = q;
                disk->private_data = drv;
+               disk->driverfs_dev = &pdev->dev;
                /* we must register the controller even if no disks exist */
                /* this is for the online array utilities */
                if(!drv->heads && j)
@@ -3266,7 +3250,6 @@ clean4:
 clean2:
        unregister_blkdev(hba[i]->major, hba[i]->devname);
 clean1:
-       release_io_mem(hba[i]);
        hba[i]->busy_initializing = 0;
        free_hba(i);
        return(-1);
@@ -3312,7 +3295,6 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev)
                 pci_disable_msi(hba[i]->pdev);
 #endif /* CONFIG_PCI_MSI */
 
-       pci_set_drvdata(pdev, NULL);
        iounmap(hba[i]->vaddr);
        cciss_unregister_scsi(i);  /* unhook from SCSI subsystem */
        unregister_blkdev(hba[i]->major, hba[i]->devname);
@@ -3339,7 +3321,9 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev)
 #ifdef CONFIG_CISS_SCSI_TAPE
        kfree(hba[i]->scsi_rejects.complete);
 #endif
-       release_io_mem(hba[i]);
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+       pci_set_drvdata(pdev, NULL);
        free_hba(i);
 }