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);
}
#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)
{
__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 */
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;
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);
}
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 */
#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);
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') ||
(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
{
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;
}
/*
/* 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;
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)
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);
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);
#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);
}