[PATCH v2] [SCSI] dpt_i2o: use proper pci driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a pci device but was not done in the usual way a pci driver is
done. Convert the driver into a proper pci driver.

Signed-off-by: Sudip Mukherjee <sudip@xxxxxxxxxxxxxxx>
---

v1: only build warning related to "dptids defined but not used" was
fixed using #ifdef

 drivers/scsi/dpt_i2o.c | 269 ++++++++++++++++++++++---------------------------
 drivers/scsi/dpti.h    |   5 +-
 2 files changed, 120 insertions(+), 154 deletions(-)

diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index d4cda5e..9f50d1ae 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -111,6 +111,7 @@ static int sys_tbl_len;
 
 static adpt_hba* hba_chain = NULL;
 static int hba_count = 0;
+static bool control_reg;
 
 static struct class *adpt_sysfs_class;
 
@@ -187,118 +188,6 @@ static struct pci_device_id dptids[] = {
 };
 MODULE_DEVICE_TABLE(pci,dptids);
 
-static int adpt_detect(struct scsi_host_template* sht)
-{
-	struct pci_dev *pDev = NULL;
-	adpt_hba *pHba;
-	adpt_hba *next;
-
-	PINFO("Detecting Adaptec I2O RAID controllers...\n");
-
-        /* search for all Adatpec I2O RAID cards */
-	while ((pDev = pci_get_device( PCI_DPT_VENDOR_ID, PCI_ANY_ID, pDev))) {
-		if(pDev->device == PCI_DPT_DEVICE_ID ||
-		   pDev->device == PCI_DPT_RAPTOR_DEVICE_ID){
-			if(adpt_install_hba(sht, pDev) ){
-				PERROR("Could not Init an I2O RAID device\n");
-				PERROR("Will not try to detect others.\n");
-				return hba_count-1;
-			}
-			pci_dev_get(pDev);
-		}
-	}
-
-	/* In INIT state, Activate IOPs */
-	for (pHba = hba_chain; pHba; pHba = next) {
-		next = pHba->next;
-		// Activate does get status , init outbound, and get hrt
-		if (adpt_i2o_activate_hba(pHba) < 0) {
-			adpt_i2o_delete_hba(pHba);
-		}
-	}
-
-
-	/* Active IOPs in HOLD state */
-
-rebuild_sys_tab:
-	if (hba_chain == NULL) 
-		return 0;
-
-	/*
-	 * If build_sys_table fails, we kill everything and bail
-	 * as we can't init the IOPs w/o a system table
-	 */	
-	if (adpt_i2o_build_sys_table() < 0) {
-		adpt_i2o_sys_shutdown();
-		return 0;
-	}
-
-	PDEBUG("HBA's in HOLD state\n");
-
-	/* If IOP don't get online, we need to rebuild the System table */
-	for (pHba = hba_chain; pHba; pHba = pHba->next) {
-		if (adpt_i2o_online_hba(pHba) < 0) {
-			adpt_i2o_delete_hba(pHba);	
-			goto rebuild_sys_tab;
-		}
-	}
-
-	/* Active IOPs now in OPERATIONAL state */
-	PDEBUG("HBA's in OPERATIONAL state\n");
-
-	printk("dpti: If you have a lot of devices this could take a few minutes.\n");
-	for (pHba = hba_chain; pHba; pHba = next) {
-		next = pHba->next;
-		printk(KERN_INFO"%s: Reading the hardware resource table.\n", pHba->name);
-		if (adpt_i2o_lct_get(pHba) < 0){
-			adpt_i2o_delete_hba(pHba);
-			continue;
-		}
-
-		if (adpt_i2o_parse_lct(pHba) < 0){
-			adpt_i2o_delete_hba(pHba);
-			continue;
-		}
-		adpt_inquiry(pHba);
-	}
-
-	adpt_sysfs_class = class_create(THIS_MODULE, "dpt_i2o");
-	if (IS_ERR(adpt_sysfs_class)) {
-		printk(KERN_WARNING"dpti: unable to create dpt_i2o class\n");
-		adpt_sysfs_class = NULL;
-	}
-
-	for (pHba = hba_chain; pHba; pHba = next) {
-		next = pHba->next;
-		if (adpt_scsi_host_alloc(pHba, sht) < 0){
-			adpt_i2o_delete_hba(pHba);
-			continue;
-		}
-		pHba->initialized = TRUE;
-		pHba->state &= ~DPTI_STATE_RESET;
-		if (adpt_sysfs_class) {
-			struct device *dev = device_create(adpt_sysfs_class,
-				NULL, MKDEV(DPTI_I2O_MAJOR, pHba->unit), NULL,
-				"dpti%d", pHba->unit);
-			if (IS_ERR(dev)) {
-				printk(KERN_WARNING"dpti%d: unable to "
-					"create device in dpt_i2o class\n",
-					pHba->unit);
-			}
-		}
-	}
-
-	// Register our control device node
-	// nodes will need to be created in /dev to access this
-	// the nodes can not be created from within the driver
-	if (hba_count && register_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER, &adpt_fops)) {
-		adpt_i2o_sys_shutdown();
-		return 0;
-	}
-	return hba_count;
-}
-
-
 /*
  * scsi_unregister will be called AFTER we return.
  */
@@ -901,7 +790,8 @@ static void adpt_i2o_sys_shutdown(void)
 	 printk(KERN_INFO "Adaptec I2O controllers down.\n");
 }
 
-static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev)
+static adpt_hba *adpt_install_hba(struct scsi_host_template *sht,
+				  struct pci_dev *pDev)
 {
 
 	adpt_hba* pHba = NULL;
@@ -917,12 +807,12 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
 	int raptorFlag = FALSE;
 
 	if(pci_enable_device(pDev)) {
-		return -EINVAL;
+		return ERR_PTR(-EINVAL);
 	}
 
 	if (pci_request_regions(pDev, "dpt_i2o")) {
 		PERROR("dpti: adpt_config_hba: pci request region failed\n");
-		return -EINVAL;
+		return ERR_PTR(-EINVAL);
 	}
 
 	pci_set_master(pDev);
@@ -936,7 +826,7 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
 			dma64 = 1;
 	}
 	if (!dma64 && pci_set_dma_mask(pDev, DMA_BIT_MASK(32)) != 0)
-		return -EINVAL;
+		return ERR_PTR(-EINVAL);
 
 	/* adapter only supports message blocks below 4GB */
 	pci_set_consistent_dma_mask(pDev, DMA_BIT_MASK(32));
@@ -984,7 +874,7 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
 	if (!base_addr_virt) {
 		pci_release_regions(pDev);
 		PERROR("dpti: adpt_config_hba: io remap failed\n");
-		return -EINVAL;
+		return ERR_PTR(-EINVAL);
 	}
 
         if(raptorFlag == TRUE) {
@@ -993,7 +883,7 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
 			PERROR("dpti: adpt_config_hba: io remap failed on BAR1\n");
 			iounmap(base_addr_virt);
 			pci_release_regions(pDev);
-			return -EINVAL;
+			return ERR_PTR(-EINVAL);
 		}
 	} else {
 		msg_addr_virt = base_addr_virt;
@@ -1006,7 +896,7 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
 			iounmap(msg_addr_virt);
 		iounmap(base_addr_virt);
 		pci_release_regions(pDev);
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 	}
 
 	mutex_lock(&adpt_configuration_lock);
@@ -1065,10 +955,10 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
 	if (request_irq (pDev->irq, adpt_isr, IRQF_SHARED, pHba->name, pHba)) {
 		printk(KERN_ERR"%s: Couldn't register IRQ %d\n", pHba->name, pDev->irq);
 		adpt_i2o_delete_hba(pHba);
-		return -EINVAL;
+		return ERR_PTR(-EINVAL);
 	}
 
-	return 0;
+	return pHba;
 }
 
 
@@ -3568,47 +3458,124 @@ static struct scsi_host_template driver_template = {
 	.use_clustering		= ENABLE_CLUSTERING,
 };
 
-static int __init adpt_init(void)
+static int adpt_pci_probe(struct pci_dev *pdev,
+			  const struct pci_device_id *ent)
 {
-	int		error;
-	adpt_hba	*pHba, *next;
+	struct scsi_host_template *sht = &driver_template;
+	adpt_hba *pHba, *pHba_temp;
+	int err;
 
-	printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n");
+	pHba = adpt_install_hba(sht, pdev);
+	if (IS_ERR(pHba)) {
+		PERROR("Could not Init an I2O RAID device\n");
+		return PTR_ERR(pHba);
+	}
 
-	error = adpt_detect(&driver_template);
-	if (error < 0)
-		return error;
-	if (hba_chain == NULL)
-		return -ENODEV;
+	/*
+	 * In INIT state, Activate IOPs
+	 * Activate does get status , init outbound, and get hrt
+	 */
+	if (adpt_i2o_activate_hba(pHba) < 0)
+		adpt_i2o_delete_hba(pHba);
 
-	for (pHba = hba_chain; pHba; pHba = pHba->next) {
-		error = scsi_add_host(pHba->host, &pHba->pDev->dev);
-		if (error)
-			goto fail;
-		scsi_scan_host(pHba->host);
+	/* Active IOPs in HOLD state */
+
+rebuild_sys_tab:
+	/*
+	 * If build_sys_table fails, we kill everything and bail
+	 * as we can't init the IOPs w/o a system table
+	 */
+	if (adpt_i2o_build_sys_table() < 0) {
+		adpt_i2o_sys_shutdown();
+		return -EIO;
 	}
-	return 0;
-fail:
-	for (pHba = hba_chain; pHba; pHba = next) {
-		next = pHba->next;
-		scsi_remove_host(pHba->host);
+
+	PDEBUG("HBA's in HOLD state\n");
+
+	/* If IOP don't get online, we need to rebuild the System table */
+	for (pHba_temp = hba_chain; pHba_temp; pHba_temp = pHba_temp->next) {
+		if (adpt_i2o_online_hba(pHba_temp) < 0) {
+			adpt_i2o_delete_hba(pHba_temp);
+			goto rebuild_sys_tab;
+		}
 	}
-	return error;
+
+	/* Active IOPs now in OPERATIONAL state */
+	PDEBUG("%s: HBA in OPERATIONAL state\n", pHba->name);
+
+	if (adpt_i2o_lct_get(pHba) < 0) {
+		adpt_i2o_delete_hba(pHba);
+		return -EIO;
+	}
+	if (adpt_i2o_parse_lct(pHba) < 0) {
+		adpt_i2o_delete_hba(pHba);
+		return -EIO;
+	}
+	adpt_inquiry(pHba);
+
+	if (!adpt_sysfs_class) {
+		adpt_sysfs_class = class_create(THIS_MODULE, "dpt_i2o");
+		if (IS_ERR(adpt_sysfs_class)) {
+			printk(KERN_WARNING
+			       "dpti: unable to create dpt_i2o class\n");
+			adpt_sysfs_class = NULL;
+		}
+	}
+	if (adpt_scsi_host_alloc(pHba, sht) < 0) {
+		adpt_i2o_delete_hba(pHba);
+		return -EIO;
+	}
+
+	pHba->initialized = TRUE;
+	pHba->state &= ~DPTI_STATE_RESET;
+	if (adpt_sysfs_class) {
+		struct device *dev = device_create(adpt_sysfs_class,
+			NULL, MKDEV(DPTI_I2O_MAJOR, pHba->unit), NULL,
+			"dpti%d", pHba->unit);
+		if (IS_ERR(dev)) {
+			printk(KERN_WARNING
+			       "dpti%d: unable to create device in dpt_i2o class\n",
+			       pHba->unit);
+		}
+	}
+
+	/*
+	 * Register our control device node
+	 * nodes will need to be created in /dev to access this
+	 * the nodes can not be created from within the driver
+	 */
+	if (!control_reg && hba_count) {
+		if (register_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER, &adpt_fops)) {
+		adpt_i2o_sys_shutdown();
+		return -EIO;
+		}
+		control_reg = true;
+	}
+
+	err = scsi_add_host(pHba->host, &pHba->pDev->dev);
+	if (err)
+		return err;
+
+	scsi_scan_host(pHba->host);
+	pci_set_drvdata(pdev, pHba);
+
+	return 0;
 }
 
-static void __exit adpt_exit(void)
+static void adpt_pci_remove(struct pci_dev *pdev)
 {
-	adpt_hba	*pHba, *next;
+	adpt_hba *pHba = pci_get_drvdata(pdev);
 
-	for (pHba = hba_chain; pHba; pHba = pHba->next)
-		scsi_remove_host(pHba->host);
-	for (pHba = hba_chain; pHba; pHba = next) {
-		next = pHba->next;
-		adpt_release(pHba->host);
-	}
+	scsi_remove_host(pHba->host);
+	adpt_release(pHba->host);
 }
 
-module_init(adpt_init);
-module_exit(adpt_exit);
+static struct pci_driver adpt_driver = {
+	.name = "adpt",
+	.id_table = dptids,
+	.probe = adpt_pci_probe,
+	.remove = adpt_pci_remove,
+};
 
+module_pci_driver(adpt_driver);
 MODULE_LICENSE("GPL");
diff --git a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h
index 1fa345a..e3481a4 100644
--- a/drivers/scsi/dpti.h
+++ b/drivers/scsi/dpti.h
@@ -28,7 +28,6 @@
  * SCSI interface function Prototypes
  */
 
-static int adpt_detect(struct scsi_host_template * sht);
 static int adpt_queue(struct Scsi_Host *h, struct scsi_cmnd * cmd);
 static int adpt_abort(struct scsi_cmnd * cmd);
 static int adpt_reset(struct scsi_cmnd* cmd);
@@ -265,7 +264,6 @@ struct sg_simple_element {
  */
 
 static void adpt_i2o_sys_shutdown(void);
-static int adpt_init(void);
 static int adpt_i2o_build_sys_table(void);
 static irqreturn_t adpt_isr(int irq, void *dev_id);
 
@@ -301,7 +299,8 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba);
 static void adpt_inquiry(adpt_hba* pHba);
 static void adpt_fail_posted_scbs(adpt_hba* pHba);
 static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u64 lun);
-static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) ;
+static adpt_hba *adpt_install_hba(struct scsi_host_template *sht,
+				  struct pci_dev *pDev);
 static int adpt_i2o_online_hba(adpt_hba* pHba);
 static void adpt_i2o_post_wait_complete(u32, int);
 static int adpt_i2o_systab_send(adpt_hba* pHba);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux