vserver 1.9.3
[linux-2.6.git] / drivers / scsi / cpqfcTSinit.c
index 8778aac..58d140c 100644 (file)
@@ -302,10 +302,16 @@ int cpqfcTS_detect(Scsi_Host_Template *ScsiHostTemplate)
                                    cpqfc_boards[i].device_id, PciDev)))
     {
 
+      if (pci_enable_device(PciDev)) {
+       printk(KERN_ERR
+               "cpqfc: can't enable PCI device at %s\n", pci_name(PciDev));
+       goto err_continue;
+      }
+
       if (pci_set_dma_mask(PciDev, CPQFCTS_DMA_MASK) != 0) {
        printk(KERN_WARNING 
                "cpqfc: HBA cannot support required DMA mask, skipping.\n");
-       continue;
+       goto err_disable_dev;
       }
 
       // NOTE: (kernel 2.2.12-32) limits allocation to 128k bytes...
@@ -314,8 +320,11 @@ int cpqfcTS_detect(Scsi_Host_Template *ScsiHostTemplate)
 
       HostAdapter = scsi_register( ScsiHostTemplate, sizeof( CPQFCHBA ) );
       
-      if(HostAdapter == NULL)
-       continue;
+      if(HostAdapter == NULL) {
+       printk(KERN_WARNING
+               "cpqfc: can't register SCSI HBA, skipping.\n");
+       goto err_disable_dev;
+      }
       DEBUG_PCI( printk("  HBA found!\n"));
       DEBUG_PCI( printk("  HostAdapter->PciDev->irq = %u\n", PciDev->irq) );
       DEBUG_PCI(printk("  PciDev->baseaddress[0]= %lx\n", 
@@ -367,9 +376,8 @@ int cpqfcTS_detect(Scsi_Host_Template *ScsiHostTemplate)
                       DEV_NAME,
                       HostAdapter) )
       {
-       printk(" IRQ %u already used\n", HostAdapter->irq);
-        scsi_unregister( HostAdapter);
-       continue;
+       printk(KERN_WARNING "cpqfc: IRQ %u already used\n", HostAdapter->irq);
+       goto err_unregister;
       }
 
       // Since we have two 256-byte I/O port ranges (upper
@@ -377,22 +385,17 @@ int cpqfcTS_detect(Scsi_Host_Template *ScsiHostTemplate)
       if( !request_region( cpqfcHBAdata->fcChip.Registers.IOBaseU,
                           0xff, DEV_NAME ) )
       {
-       printk("  cpqfcTS address in use: %x\n", 
+       printk(KERN_WARNING "cpqfc: address in use: %x\n",
                        cpqfcHBAdata->fcChip.Registers.IOBaseU);
-       free_irq( HostAdapter->irq, HostAdapter);
-        scsi_unregister( HostAdapter);
-       continue;
+       goto err_free_irq;
       }        
       
       if( !request_region( cpqfcHBAdata->fcChip.Registers.IOBaseL,
                           0xff, DEV_NAME ) )
       {
-       printk("  cpqfcTS address in use: %x\n", 
+       printk(KERN_WARNING "cpqfc: address in use: %x\n",
                                cpqfcHBAdata->fcChip.Registers.IOBaseL);
-       release_region( cpqfcHBAdata->fcChip.Registers.IOBaseU, 0xff );
-       free_irq( HostAdapter->irq, HostAdapter);
-        scsi_unregister( HostAdapter);
-       continue;
+       goto err_release_region_U;
       }        
       
       // OK, we have grabbed everything we need now.
@@ -424,7 +427,7 @@ int cpqfcTS_detect(Scsi_Host_Template *ScsiHostTemplate)
       // now initialize our hardware...
       if (cpqfcHBAdata->fcChip.InitializeTachyon( cpqfcHBAdata, 1,1)) {
        printk(KERN_WARNING "cpqfc: initialization of HBA hardware failed.\n");
-       // FIXME: might want to do something better than nothing here.
+       goto err_release_region_L;
       }
 
       cpqfcHBAdata->fcStatsTime = jiffies;  // (for FC Statistics delta)
@@ -455,6 +458,21 @@ int cpqfcTS_detect(Scsi_Host_Template *ScsiHostTemplate)
       spin_lock_irq(HostAdapter->host_lock);
       NumberOfAdapters++; 
       spin_unlock_irq(HostAdapter->host_lock);
+
+      continue;
+
+err_release_region_L:
+      release_region( cpqfcHBAdata->fcChip.Registers.IOBaseL, 0xff );
+err_release_region_U:
+      release_region( cpqfcHBAdata->fcChip.Registers.IOBaseU, 0xff );
+err_free_irq:
+      free_irq( HostAdapter->irq, HostAdapter);
+err_unregister:
+      scsi_unregister( HostAdapter);
+err_disable_dev:
+      pci_disable_device( PciDev );
+err_continue:
+      continue;
     } // end of while()
   }
 
@@ -811,6 +829,7 @@ int cpqfcTS_release(struct Scsi_Host *HostAdapter)
       cpqfcHBAdata->fcChip.Registers.ReMapMemBase)
     vfree( cpqfcHBAdata->fcChip.Registers.ReMapMemBase);
 */
+  pci_disable_device( cpqfcHBAdata->PciDev);
 
   LEAVE("cpqfcTS_release");
   return 0;