]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/infiniband/hw/qib/qib_init.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / drivers / infiniband / hw / qib / qib_init.c
index f3b50393604307a92fd1ee0b4e1f2e9bd706607c..ffefb78b894919e483dac74a3f3df3597434502c 100644 (file)
@@ -80,7 +80,6 @@ unsigned qib_wc_pat = 1; /* default (1) is to use PAT, not MTRR */
 module_param_named(wc_pat, qib_wc_pat, uint, S_IRUGO);
 MODULE_PARM_DESC(wc_pat, "enable write-combining via PAT mechanism");
 
-struct workqueue_struct *qib_wq;
 struct workqueue_struct *qib_cq_wq;
 
 static void verify_interrupt(unsigned long);
@@ -92,9 +91,11 @@ unsigned long *qib_cpulist;
 /* set number of contexts we'll actually use */
 void qib_set_ctxtcnt(struct qib_devdata *dd)
 {
-       if (!qib_cfgctxts)
+       if (!qib_cfgctxts) {
                dd->cfgctxts = dd->first_user_ctxt + num_online_cpus();
-       else if (qib_cfgctxts < dd->num_pports)
+               if (dd->cfgctxts > dd->ctxtcnt)
+                       dd->cfgctxts = dd->ctxtcnt;
+       } else if (qib_cfgctxts < dd->num_pports)
                dd->cfgctxts = dd->ctxtcnt;
        else if (qib_cfgctxts <= dd->ctxtcnt)
                dd->cfgctxts = qib_cfgctxts;
@@ -268,23 +269,20 @@ static void init_shadow_tids(struct qib_devdata *dd)
        struct page **pages;
        dma_addr_t *addrs;
 
-       pages = vmalloc(dd->cfgctxts * dd->rcvtidcnt * sizeof(struct page *));
+       pages = vzalloc(dd->cfgctxts * dd->rcvtidcnt * sizeof(struct page *));
        if (!pages) {
                qib_dev_err(dd, "failed to allocate shadow page * "
                            "array, no expected sends!\n");
                goto bail;
        }
 
-       addrs = vmalloc(dd->cfgctxts * dd->rcvtidcnt * sizeof(dma_addr_t));
+       addrs = vzalloc(dd->cfgctxts * dd->rcvtidcnt * sizeof(dma_addr_t));
        if (!addrs) {
                qib_dev_err(dd, "failed to allocate shadow dma handle "
                            "array, no expected sends!\n");
                goto bail_free;
        }
 
-       memset(pages, 0, dd->cfgctxts * dd->rcvtidcnt * sizeof(struct page *));
-       memset(addrs, 0, dd->cfgctxts * dd->rcvtidcnt * sizeof(dma_addr_t));
-
        dd->pageshadow = pages;
        dd->physshadow = addrs;
        return;
@@ -1045,24 +1043,10 @@ static int __init qlogic_ib_init(void)
        if (ret)
                goto bail;
 
-       /*
-        * We create our own workqueue mainly because we want to be
-        * able to flush it when devices are being removed.  We can't
-        * use schedule_work()/flush_scheduled_work() because both
-        * unregister_netdev() and linkwatch_event take the rtnl lock,
-        * so flush_scheduled_work() can deadlock during device
-        * removal.
-        */
-       qib_wq = create_workqueue("qib");
-       if (!qib_wq) {
-               ret = -ENOMEM;
-               goto bail_dev;
-       }
-
        qib_cq_wq = create_singlethread_workqueue("qib_cq");
        if (!qib_cq_wq) {
                ret = -ENOMEM;
-               goto bail_wq;
+               goto bail_dev;
        }
 
        /*
@@ -1092,8 +1076,6 @@ bail_unit:
        idr_destroy(&qib_unit_table);
 bail_cq_wq:
        destroy_workqueue(qib_cq_wq);
-bail_wq:
-       destroy_workqueue(qib_wq);
 bail_dev:
        qib_dev_cleanup();
 bail:
@@ -1117,7 +1099,6 @@ static void __exit qlogic_ib_cleanup(void)
 
        pci_unregister_driver(&qib_driver);
 
-       destroy_workqueue(qib_wq);
        destroy_workqueue(qib_cq_wq);
 
        qib_cpulist_count = 0;
@@ -1290,7 +1271,7 @@ static int __devinit qib_init_one(struct pci_dev *pdev,
 
        if (qib_mini_init || initfail || ret) {
                qib_stop_timers(dd);
-               flush_scheduled_work();
+               flush_workqueue(ib_wq);
                for (pidx = 0; pidx < dd->num_pports; ++pidx)
                        dd->f_quiet_serdes(dd->pport + pidx);
                if (qib_mini_init)
@@ -1339,8 +1320,8 @@ static void __devexit qib_remove_one(struct pci_dev *pdev)
 
        qib_stop_timers(dd);
 
-       /* wait until all of our (qsfp) schedule_work() calls complete */
-       flush_scheduled_work();
+       /* wait until all of our (qsfp) queue_work() calls complete */
+       flush_workqueue(ib_wq);
 
        ret = qibfs_remove(dd);
        if (ret)