Print this page
MFV: illumos-gate@bbb9d5d65bf8372aae4b8821c80e218b8b832846
9994 cxgbe t4nex: Handle get_fl_payload() alloc failures
9995 cxgbe t4_devo_attach() should initialize ->sfl
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Approved by: Dan McDonald <danmcd@joyent.com>
Author: John Levon <john.levon@joyent.com>
9484 cxgbe should clean TX descriptors in timely manner
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Reviewed by: Ryan Zezeski <rpz@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Approved by: Dan McDonald <danmcd@joyent.com>

@@ -314,10 +314,11 @@
         sc->dip = dip;
         sc->dev = makedevice(ddi_driver_major(dip), instance);
         mutex_init(&sc->lock, NULL, MUTEX_DRIVER, NULL);
         cv_init(&sc->cv, NULL, CV_DRIVER, NULL);
         mutex_init(&sc->sfl_lock, NULL, MUTEX_DRIVER, NULL);
+        TAILQ_INIT(&sc->sfl);
 
         mutex_enter(&t4_adapter_list_lock);
         SLIST_INSERT_HEAD(&t4_adapter_list, sc, link);
         mutex_exit(&t4_adapter_list_lock);
 

@@ -367,10 +368,24 @@
 
         for (i = 0; i < ARRAY_SIZE(sc->fw_msg_handler); i++) {
                 sc->fw_msg_handler[i] = fw_msg_not_handled;
         }
  
+        for (i = 0; i < NCHAN; i++) {
+                (void) snprintf(name, sizeof (name), "%s-%d",
+                                "reclaim", i);
+                sc->tq[i] = ddi_taskq_create(sc->dip,
+                   name, 1, TASKQ_DEFAULTPRI, 0);
+
+                if (sc->tq[i] == NULL) {
+                        cxgb_printf(dip, CE_WARN,
+                                   "failed to create task queues");
+                        rc = DDI_FAILURE;
+                        goto done;
+                }
+        }
+
         /*
          * Prepare the adapter for operation.
          */
         rc = -t4_prep_adapter(sc, false);
         if (rc != 0) {

@@ -834,10 +849,17 @@
 
         /* Safe to call no matter what */
         ddi_prop_remove_all(dip);
         ddi_remove_minor_node(dip, NULL);
 
+        for (i = 0; i < NCHAN; i++) {
+                if (sc->tq[i]) {
+                        ddi_taskq_wait(sc->tq[i]);
+                        ddi_taskq_destroy(sc->tq[i]);
+                }
+        }
+
         if (sc->ksp != NULL)
                 kstat_delete(sc->ksp);
         if (sc->ksp_stat != NULL)
                 kstat_delete(sc->ksp_stat);