From patchwork Wed Feb 17 12:20:14 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudip Mukherjee X-Patchwork-Id: 8338091 Return-Path: X-Original-To: patchwork-linux-scsi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 37BB9C02AA for ; Wed, 17 Feb 2016 12:25:53 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id EC8CF2013D for ; Wed, 17 Feb 2016 12:25:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8F56F2017D for ; Wed, 17 Feb 2016 12:25:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1161604AbcBQMUa (ORCPT ); Wed, 17 Feb 2016 07:20:30 -0500 Received: from mail-pa0-f41.google.com ([209.85.220.41]:36077 "EHLO mail-pa0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1161349AbcBQMU0 (ORCPT ); Wed, 17 Feb 2016 07:20:26 -0500 Received: by mail-pa0-f41.google.com with SMTP id yy13so10568721pab.3; Wed, 17 Feb 2016 04:20:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=z2/3zOv6NdF/lxuKmboJsEowMUBnWgNIQLYvuz83ImA=; b=PImZ1uu7UfJ+GNMm5O0XttN7UIDlvsS3z3Z9fYUeqjVD5UOktFkr3JLYIYgIeC3Ho8 Dr3e/I7iZIT0WB3WnAfS+mUW/j/6p/N4rsxFmRKTilzeuEuouv8E5VBkTvP6A1fvXf8P /+6jBX7Y+8Nf1hcNLtQOq4gXyUnAESxmmuQ/Gynj7VdRhi5dgoRfrJ3tz3krxmoSASco dWYKi9QIED3AXOOiG5W00mJosA2/IQ0tCPhWvho8doAlm3JAUs48G7kLtDl1isVYzIsn oLYaCHVX5ZCeeGznLjCXcOEG6FHfN6BL8yasJ5kx0J4Zx2aN5DdobCJ2dcGOZwAGSHFJ 4fKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=z2/3zOv6NdF/lxuKmboJsEowMUBnWgNIQLYvuz83ImA=; b=Df/TeccOJdwFHiJJ4fY06pvt5Spug1+/l4dnglY5MblzcPeo896OOXiFnJ8BQ6SOd7 bUq2FnXCFvLOQnB6qlTIUUmfeMdBu7TfryMI3tYbbOuwx49toE7ZdxsGMgcoWcxEXhj0 x56d2myqGw5SeN71JSPC2QUCLMbkwfjouSFfrV86LDJ4Rhx6vPRfVUCAFrEfRHmEOW57 5A9uNJXMtSL2fOE2nKzdy7zJoDQHWtYUlcQv1+rR7StyLNNmn2uWOBVs4jDfy4puAI0S CjAhnPP5qXAFI6hqh9bf1lIveAXKMu0WEukSKFNTOB7E2xhIx30QvnpOTqTzU22USuh4 QZng== X-Gm-Message-State: AG10YOSJxXUQ2HDtkdwKBAMnQHlsPzjmj6eHNuE6HMTKND3klo5N/OgR8cudSwT8pOlb2A== X-Received: by 10.66.62.162 with SMTP id z2mr1599680par.39.1455711625868; Wed, 17 Feb 2016 04:20:25 -0800 (PST) Received: from sudip-pc.vectortproxy.org ([49.206.197.43]) by smtp.gmail.com with ESMTPSA id g25sm2477014pfg.35.2016.02.17.04.20.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 17 Feb 2016 04:20:25 -0800 (PST) From: Sudip Mukherjee To: Adaptec OEM Raid Solutions , "Martin K. Petersen" Cc: linux-kernel@vger.kernel.org, linux-scsi@vger.kernel.org, Johannes Thumshirn , Sudip Mukherjee Subject: [PATCH v2] [SCSI] dpt_i2o: use proper pci driver Date: Wed, 17 Feb 2016 17:50:14 +0530 Message-Id: <1455711614-5185-1-git-send-email-sudipm.mukherjee@gmail.com> X-Mailer: git-send-email 1.9.1 Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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);