xref: /illumos-gate/usr/src/uts/common/io/bnxe/bnxe_workq.c (revision d14abf155341d55053c76eeec58b787a456b753b)
1*d14abf15SRobert Mustacchi /*
2*d14abf15SRobert Mustacchi  * CDDL HEADER START
3*d14abf15SRobert Mustacchi  *
4*d14abf15SRobert Mustacchi  * The contents of this file are subject to the terms of the
5*d14abf15SRobert Mustacchi  * Common Development and Distribution License (the "License").
6*d14abf15SRobert Mustacchi  * You may not use this file except in compliance with the License.
7*d14abf15SRobert Mustacchi  *
8*d14abf15SRobert Mustacchi  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*d14abf15SRobert Mustacchi  * or http://www.opensolaris.org/os/licensing.
10*d14abf15SRobert Mustacchi  * See the License for the specific language governing permissions
11*d14abf15SRobert Mustacchi  * and limitations under the License.
12*d14abf15SRobert Mustacchi  *
13*d14abf15SRobert Mustacchi  * When distributing Covered Code, include this CDDL HEADER in each
14*d14abf15SRobert Mustacchi  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*d14abf15SRobert Mustacchi  * If applicable, add the following below this CDDL HEADER, with the
16*d14abf15SRobert Mustacchi  * fields enclosed by brackets "[]" replaced with your own identifying
17*d14abf15SRobert Mustacchi  * information: Portions Copyright [yyyy] [name of copyright owner]
18*d14abf15SRobert Mustacchi  *
19*d14abf15SRobert Mustacchi  * CDDL HEADER END
20*d14abf15SRobert Mustacchi  */
21*d14abf15SRobert Mustacchi 
22*d14abf15SRobert Mustacchi /*
23*d14abf15SRobert Mustacchi  * Copyright 2014 QLogic Corporation
24*d14abf15SRobert Mustacchi  * The contents of this file are subject to the terms of the
25*d14abf15SRobert Mustacchi  * QLogic End User License (the "License").
26*d14abf15SRobert Mustacchi  * You may not use this file except in compliance with the License.
27*d14abf15SRobert Mustacchi  *
28*d14abf15SRobert Mustacchi  * You can obtain a copy of the License at
29*d14abf15SRobert Mustacchi  * http://www.qlogic.com/Resources/Documents/DriverDownloadHelp/
30*d14abf15SRobert Mustacchi  * QLogic_End_User_Software_License.txt
31*d14abf15SRobert Mustacchi  * See the License for the specific language governing permissions
32*d14abf15SRobert Mustacchi  * and limitations under the License.
33*d14abf15SRobert Mustacchi  */
34*d14abf15SRobert Mustacchi 
35*d14abf15SRobert Mustacchi #include "bnxe.h"
36*d14abf15SRobert Mustacchi 
37*d14abf15SRobert Mustacchi 
38*d14abf15SRobert Mustacchi typedef struct _BnxeWorkItem
39*d14abf15SRobert Mustacchi {
40*d14abf15SRobert Mustacchi     s_list_entry_t link;
41*d14abf15SRobert Mustacchi     void *         pWorkData;
42*d14abf15SRobert Mustacchi     u32_t          workDataLen;
43*d14abf15SRobert Mustacchi     u32_t          delayMs;
44*d14abf15SRobert Mustacchi     void (*pWorkCbkCopy)(um_device_t *, void *, u32_t);
45*d14abf15SRobert Mustacchi     void (*pWorkCbkNoCopy)(um_device_t *, void *);
46*d14abf15SRobert Mustacchi     void (*pWorkCbkGeneric)(um_device_t *);
47*d14abf15SRobert Mustacchi } BnxeWorkItem;
48*d14abf15SRobert Mustacchi 
49*d14abf15SRobert Mustacchi 
BnxeWorkQueueInstanceWaitAndDestroy(BnxeWorkQueueInstance * pWorkq)50*d14abf15SRobert Mustacchi static void BnxeWorkQueueInstanceWaitAndDestroy(BnxeWorkQueueInstance * pWorkq)
51*d14abf15SRobert Mustacchi {
52*d14abf15SRobert Mustacchi     if (pWorkq->pTaskq)
53*d14abf15SRobert Mustacchi     {
54*d14abf15SRobert Mustacchi         ddi_taskq_wait(pWorkq->pTaskq);
55*d14abf15SRobert Mustacchi         ddi_taskq_destroy(pWorkq->pTaskq);
56*d14abf15SRobert Mustacchi         mutex_destroy(&pWorkq->workQueueMutex);
57*d14abf15SRobert Mustacchi     }
58*d14abf15SRobert Mustacchi 
59*d14abf15SRobert Mustacchi     memset(pWorkq, 0, sizeof(BnxeWorkQueueInstance));
60*d14abf15SRobert Mustacchi }
61*d14abf15SRobert Mustacchi 
62*d14abf15SRobert Mustacchi 
BnxeWorkQueueInit(um_device_t * pUM)63*d14abf15SRobert Mustacchi boolean_t BnxeWorkQueueInit(um_device_t * pUM)
64*d14abf15SRobert Mustacchi {
65*d14abf15SRobert Mustacchi     pUM->workqs.instq.pUM = pUM;
66*d14abf15SRobert Mustacchi 
67*d14abf15SRobert Mustacchi     strcpy(pUM->workqs.instq.taskqName, pUM->devName);
68*d14abf15SRobert Mustacchi     strcat(pUM->workqs.instq.taskqName, "_inst_q");
69*d14abf15SRobert Mustacchi 
70*d14abf15SRobert Mustacchi     mutex_init(&pUM->workqs.instq.workQueueMutex, NULL,
71*d14abf15SRobert Mustacchi                MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
72*d14abf15SRobert Mustacchi 
73*d14abf15SRobert Mustacchi     if ((pUM->workqs.instq.pTaskq =
74*d14abf15SRobert Mustacchi          ddi_taskq_create(pUM->pDev,
75*d14abf15SRobert Mustacchi                           pUM->workqs.instq.taskqName,
76*d14abf15SRobert Mustacchi                           1,
77*d14abf15SRobert Mustacchi                           TASKQ_DEFAULTPRI,
78*d14abf15SRobert Mustacchi                           0)) == NULL)
79*d14abf15SRobert Mustacchi     {
80*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to create the workqs instq");
81*d14abf15SRobert Mustacchi         return B_FALSE;
82*d14abf15SRobert Mustacchi     }
83*d14abf15SRobert Mustacchi 
84*d14abf15SRobert Mustacchi     pUM->workqs.instq.pUM = pUM;
85*d14abf15SRobert Mustacchi 
86*d14abf15SRobert Mustacchi     strcpy(pUM->workqs.delayq.taskqName, pUM->devName);
87*d14abf15SRobert Mustacchi     strcat(pUM->workqs.delayq.taskqName, "_delay_q");
88*d14abf15SRobert Mustacchi 
89*d14abf15SRobert Mustacchi     mutex_init(&pUM->workqs.delayq.workQueueMutex, NULL,
90*d14abf15SRobert Mustacchi                MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
91*d14abf15SRobert Mustacchi 
92*d14abf15SRobert Mustacchi     if ((pUM->workqs.delayq.pTaskq =
93*d14abf15SRobert Mustacchi          ddi_taskq_create(pUM->pDev,
94*d14abf15SRobert Mustacchi                           pUM->workqs.delayq.taskqName,
95*d14abf15SRobert Mustacchi                           16, /* XXX Is this enough? */
96*d14abf15SRobert Mustacchi                           TASKQ_DEFAULTPRI,
97*d14abf15SRobert Mustacchi                           0)) == NULL)
98*d14abf15SRobert Mustacchi     {
99*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to create the workqs delayq");
100*d14abf15SRobert Mustacchi         BnxeWorkQueueInstanceWaitAndDestroy(&pUM->workqs.instq);
101*d14abf15SRobert Mustacchi         return B_FALSE;
102*d14abf15SRobert Mustacchi     }
103*d14abf15SRobert Mustacchi 
104*d14abf15SRobert Mustacchi     pUM->workqs.delayq.pUM = pUM;
105*d14abf15SRobert Mustacchi 
106*d14abf15SRobert Mustacchi     return B_TRUE;
107*d14abf15SRobert Mustacchi }
108*d14abf15SRobert Mustacchi 
109*d14abf15SRobert Mustacchi 
BnxeWorkQueueWaitAndDestroy(um_device_t * pUM)110*d14abf15SRobert Mustacchi void BnxeWorkQueueWaitAndDestroy(um_device_t * pUM)
111*d14abf15SRobert Mustacchi {
112*d14abf15SRobert Mustacchi     BnxeWorkQueueInstanceWaitAndDestroy(&pUM->workqs.instq);
113*d14abf15SRobert Mustacchi     BnxeWorkQueueInstanceWaitAndDestroy(&pUM->workqs.delayq);
114*d14abf15SRobert Mustacchi }
115*d14abf15SRobert Mustacchi 
116*d14abf15SRobert Mustacchi 
BnxeWorkQueueDispatch(void * pArg)117*d14abf15SRobert Mustacchi static void BnxeWorkQueueDispatch(void * pArg)
118*d14abf15SRobert Mustacchi {
119*d14abf15SRobert Mustacchi     BnxeWorkQueueInstance * pWorkq = (BnxeWorkQueueInstance *)pArg;
120*d14abf15SRobert Mustacchi     um_device_t * pUM = (um_device_t *)pWorkq->pUM;
121*d14abf15SRobert Mustacchi     BnxeWorkItem * pWorkItem;
122*d14abf15SRobert Mustacchi 
123*d14abf15SRobert Mustacchi     mutex_enter(&pWorkq->workQueueMutex);
124*d14abf15SRobert Mustacchi     pWorkItem = (BnxeWorkItem *)s_list_pop_head(&pWorkq->workQueue);
125*d14abf15SRobert Mustacchi     mutex_exit(&pWorkq->workQueueMutex);
126*d14abf15SRobert Mustacchi 
127*d14abf15SRobert Mustacchi     if (pWorkItem == NULL)
128*d14abf15SRobert Mustacchi     {
129*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Work item is NULL!");
130*d14abf15SRobert Mustacchi         pWorkq->workItemError++;
131*d14abf15SRobert Mustacchi         return;
132*d14abf15SRobert Mustacchi     }
133*d14abf15SRobert Mustacchi 
134*d14abf15SRobert Mustacchi     if ((pWorkItem->pWorkCbkCopy == NULL) &&
135*d14abf15SRobert Mustacchi         (pWorkItem->pWorkCbkNoCopy == NULL) &&
136*d14abf15SRobert Mustacchi         (pWorkItem->pWorkCbkGeneric == NULL))
137*d14abf15SRobert Mustacchi     {
138*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Work item callback is NULL!");
139*d14abf15SRobert Mustacchi         pWorkq->workItemError++;
140*d14abf15SRobert Mustacchi         goto BnxeWorkQueueDispatch_done;
141*d14abf15SRobert Mustacchi     }
142*d14abf15SRobert Mustacchi 
143*d14abf15SRobert Mustacchi     if (pWorkItem->delayMs > 0)
144*d14abf15SRobert Mustacchi     {
145*d14abf15SRobert Mustacchi         /* this only occurs when processing the delayq */
146*d14abf15SRobert Mustacchi         drv_usecwait(pWorkItem->delayMs * 1000);
147*d14abf15SRobert Mustacchi     }
148*d14abf15SRobert Mustacchi 
149*d14abf15SRobert Mustacchi     if (pWorkItem->pWorkCbkCopy)
150*d14abf15SRobert Mustacchi     {
151*d14abf15SRobert Mustacchi         pWorkItem->pWorkCbkCopy(pUM,
152*d14abf15SRobert Mustacchi                                 pWorkItem->pWorkData,
153*d14abf15SRobert Mustacchi                                 pWorkItem->workDataLen);
154*d14abf15SRobert Mustacchi     }
155*d14abf15SRobert Mustacchi     else if (pWorkItem->pWorkCbkNoCopy)
156*d14abf15SRobert Mustacchi     {
157*d14abf15SRobert Mustacchi         pWorkItem->pWorkCbkNoCopy(pUM,
158*d14abf15SRobert Mustacchi                                   pWorkItem->pWorkData);
159*d14abf15SRobert Mustacchi     }
160*d14abf15SRobert Mustacchi     else /* (pWorkItem->pWorkCbkGeneric) */
161*d14abf15SRobert Mustacchi     {
162*d14abf15SRobert Mustacchi         pWorkItem->pWorkCbkGeneric(pUM);
163*d14abf15SRobert Mustacchi     }
164*d14abf15SRobert Mustacchi 
165*d14abf15SRobert Mustacchi     pWorkq->workItemComplete++;
166*d14abf15SRobert Mustacchi 
167*d14abf15SRobert Mustacchi BnxeWorkQueueDispatch_done:
168*d14abf15SRobert Mustacchi 
169*d14abf15SRobert Mustacchi     kmem_free(pWorkItem, (sizeof(BnxeWorkItem) + pWorkItem->workDataLen));
170*d14abf15SRobert Mustacchi }
171*d14abf15SRobert Mustacchi 
172*d14abf15SRobert Mustacchi 
BnxeWorkQueueTrigger(um_device_t * pUM,BnxeWorkQueueInstance * pWorkq)173*d14abf15SRobert Mustacchi static void BnxeWorkQueueTrigger(um_device_t *           pUM,
174*d14abf15SRobert Mustacchi                                  BnxeWorkQueueInstance * pWorkq)
175*d14abf15SRobert Mustacchi {
176*d14abf15SRobert Mustacchi     if (pUM->chipStarted)
177*d14abf15SRobert Mustacchi     {
178*d14abf15SRobert Mustacchi         ddi_taskq_dispatch(pWorkq->pTaskq,
179*d14abf15SRobert Mustacchi                            BnxeWorkQueueDispatch,
180*d14abf15SRobert Mustacchi                            (void *)pWorkq,
181*d14abf15SRobert Mustacchi                            DDI_NOSLEEP);
182*d14abf15SRobert Mustacchi     }
183*d14abf15SRobert Mustacchi     else
184*d14abf15SRobert Mustacchi     {
185*d14abf15SRobert Mustacchi         BnxeLogInfo(pUM, "Delaying WorkQ item since chip not yet started.");
186*d14abf15SRobert Mustacchi     }
187*d14abf15SRobert Mustacchi }
188*d14abf15SRobert Mustacchi 
189*d14abf15SRobert Mustacchi 
BnxeWorkQueueStartPending(um_device_t * pUM)190*d14abf15SRobert Mustacchi void BnxeWorkQueueStartPending(um_device_t * pUM)
191*d14abf15SRobert Mustacchi {
192*d14abf15SRobert Mustacchi     u32_t cnt;
193*d14abf15SRobert Mustacchi 
194*d14abf15SRobert Mustacchi     if (!pUM->chipStarted)
195*d14abf15SRobert Mustacchi     {
196*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Triggering WorkQs and chip not started!");
197*d14abf15SRobert Mustacchi         return;
198*d14abf15SRobert Mustacchi     }
199*d14abf15SRobert Mustacchi 
200*d14abf15SRobert Mustacchi     mutex_enter(&pUM->workqs.instq.workQueueMutex);
201*d14abf15SRobert Mustacchi     cnt = s_list_entry_cnt(&pUM->workqs.instq.workQueue);
202*d14abf15SRobert Mustacchi     mutex_exit(&pUM->workqs.instq.workQueueMutex);
203*d14abf15SRobert Mustacchi 
204*d14abf15SRobert Mustacchi     if (cnt)
205*d14abf15SRobert Mustacchi     {
206*d14abf15SRobert Mustacchi         BnxeWorkQueueTrigger(pUM, &pUM->workqs.instq);
207*d14abf15SRobert Mustacchi     }
208*d14abf15SRobert Mustacchi 
209*d14abf15SRobert Mustacchi     mutex_enter(&pUM->workqs.delayq.workQueueMutex);
210*d14abf15SRobert Mustacchi     cnt = s_list_entry_cnt(&pUM->workqs.delayq.workQueue);
211*d14abf15SRobert Mustacchi     mutex_exit(&pUM->workqs.delayq.workQueueMutex);
212*d14abf15SRobert Mustacchi 
213*d14abf15SRobert Mustacchi     if (cnt)
214*d14abf15SRobert Mustacchi     {
215*d14abf15SRobert Mustacchi         BnxeWorkQueueTrigger(pUM, &pUM->workqs.delayq);
216*d14abf15SRobert Mustacchi     }
217*d14abf15SRobert Mustacchi }
218*d14abf15SRobert Mustacchi 
219*d14abf15SRobert Mustacchi 
BnxeWorkQueueAdd(um_device_t * pUM,void (* pWorkCbkCopy)(um_device_t *,void *,u32_t),void * pWorkData,u32_t workDataLen)220*d14abf15SRobert Mustacchi boolean_t BnxeWorkQueueAdd(um_device_t * pUM,
221*d14abf15SRobert Mustacchi                            void (*pWorkCbkCopy)(um_device_t *, void *, u32_t),
222*d14abf15SRobert Mustacchi                            void * pWorkData,
223*d14abf15SRobert Mustacchi                            u32_t  workDataLen)
224*d14abf15SRobert Mustacchi {
225*d14abf15SRobert Mustacchi     BnxeWorkItem * pWorkItem;
226*d14abf15SRobert Mustacchi 
227*d14abf15SRobert Mustacchi     if ((pWorkItem = kmem_zalloc((sizeof(BnxeWorkItem) + workDataLen),
228*d14abf15SRobert Mustacchi                                  KM_NOSLEEP)) == NULL)
229*d14abf15SRobert Mustacchi     {
230*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to allocate memory for work item!");
231*d14abf15SRobert Mustacchi         return B_FALSE;
232*d14abf15SRobert Mustacchi     }
233*d14abf15SRobert Mustacchi 
234*d14abf15SRobert Mustacchi     pWorkItem->pWorkData       = (pWorkItem + 1);
235*d14abf15SRobert Mustacchi     pWorkItem->workDataLen     = workDataLen;
236*d14abf15SRobert Mustacchi     pWorkItem->pWorkCbkCopy    = pWorkCbkCopy;
237*d14abf15SRobert Mustacchi     pWorkItem->pWorkCbkNoCopy  = NULL;
238*d14abf15SRobert Mustacchi     pWorkItem->pWorkCbkGeneric = NULL;
239*d14abf15SRobert Mustacchi     pWorkItem->delayMs         = 0;
240*d14abf15SRobert Mustacchi 
241*d14abf15SRobert Mustacchi     memcpy(pWorkItem->pWorkData, pWorkData, workDataLen);
242*d14abf15SRobert Mustacchi 
243*d14abf15SRobert Mustacchi     mutex_enter(&pUM->workqs.instq.workQueueMutex);
244*d14abf15SRobert Mustacchi 
245*d14abf15SRobert Mustacchi     s_list_push_tail(&pUM->workqs.instq.workQueue, &pWorkItem->link);
246*d14abf15SRobert Mustacchi     pUM->workqs.instq.workItemQueued++;
247*d14abf15SRobert Mustacchi     if (s_list_entry_cnt(&pUM->workqs.instq.workQueue) >
248*d14abf15SRobert Mustacchi         pUM->workqs.instq.highWater)
249*d14abf15SRobert Mustacchi     {
250*d14abf15SRobert Mustacchi         pUM->workqs.instq.highWater =
251*d14abf15SRobert Mustacchi             s_list_entry_cnt(&pUM->workqs.instq.workQueue);
252*d14abf15SRobert Mustacchi     }
253*d14abf15SRobert Mustacchi 
254*d14abf15SRobert Mustacchi     mutex_exit(&pUM->workqs.instq.workQueueMutex);
255*d14abf15SRobert Mustacchi 
256*d14abf15SRobert Mustacchi     BnxeWorkQueueTrigger(pUM, &pUM->workqs.instq);
257*d14abf15SRobert Mustacchi 
258*d14abf15SRobert Mustacchi     return B_TRUE;
259*d14abf15SRobert Mustacchi }
260*d14abf15SRobert Mustacchi 
261*d14abf15SRobert Mustacchi 
BnxeWorkQueueAddNoCopy(um_device_t * pUM,void (* pWorkCbkNoCopy)(um_device_t *,void *),void * pWorkData)262*d14abf15SRobert Mustacchi boolean_t BnxeWorkQueueAddNoCopy(um_device_t * pUM,
263*d14abf15SRobert Mustacchi                                  void (*pWorkCbkNoCopy)(um_device_t *, void *),
264*d14abf15SRobert Mustacchi                                  void * pWorkData)
265*d14abf15SRobert Mustacchi {
266*d14abf15SRobert Mustacchi     BnxeWorkItem * pWorkItem;
267*d14abf15SRobert Mustacchi 
268*d14abf15SRobert Mustacchi     if ((pWorkItem = kmem_zalloc(sizeof(BnxeWorkItem), KM_NOSLEEP)) == NULL)
269*d14abf15SRobert Mustacchi     {
270*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to allocate memory for work item!");
271*d14abf15SRobert Mustacchi         return B_FALSE;
272*d14abf15SRobert Mustacchi     }
273*d14abf15SRobert Mustacchi 
274*d14abf15SRobert Mustacchi     pWorkItem->pWorkData       = pWorkData;
275*d14abf15SRobert Mustacchi     pWorkItem->workDataLen     = 0;
276*d14abf15SRobert Mustacchi     pWorkItem->pWorkCbkCopy    = NULL;
277*d14abf15SRobert Mustacchi     pWorkItem->pWorkCbkNoCopy  = pWorkCbkNoCopy;
278*d14abf15SRobert Mustacchi     pWorkItem->pWorkCbkGeneric = NULL;
279*d14abf15SRobert Mustacchi     pWorkItem->delayMs         = 0;
280*d14abf15SRobert Mustacchi 
281*d14abf15SRobert Mustacchi     mutex_enter(&pUM->workqs.instq.workQueueMutex);
282*d14abf15SRobert Mustacchi 
283*d14abf15SRobert Mustacchi     s_list_push_tail(&pUM->workqs.instq.workQueue, &pWorkItem->link);
284*d14abf15SRobert Mustacchi     pUM->workqs.instq.workItemQueued++;
285*d14abf15SRobert Mustacchi     if (s_list_entry_cnt(&pUM->workqs.instq.workQueue) >
286*d14abf15SRobert Mustacchi         pUM->workqs.instq.highWater)
287*d14abf15SRobert Mustacchi     {
288*d14abf15SRobert Mustacchi         pUM->workqs.instq.highWater =
289*d14abf15SRobert Mustacchi             s_list_entry_cnt(&pUM->workqs.instq.workQueue);
290*d14abf15SRobert Mustacchi     }
291*d14abf15SRobert Mustacchi 
292*d14abf15SRobert Mustacchi     mutex_exit(&pUM->workqs.instq.workQueueMutex);
293*d14abf15SRobert Mustacchi 
294*d14abf15SRobert Mustacchi     BnxeWorkQueueTrigger(pUM, &pUM->workqs.instq);
295*d14abf15SRobert Mustacchi 
296*d14abf15SRobert Mustacchi     return B_TRUE;
297*d14abf15SRobert Mustacchi }
298*d14abf15SRobert Mustacchi 
299*d14abf15SRobert Mustacchi 
BnxeWorkQueueAddGeneric(um_device_t * pUM,void (* pWorkCbkGeneric)(um_device_t *))300*d14abf15SRobert Mustacchi boolean_t BnxeWorkQueueAddGeneric(um_device_t * pUM,
301*d14abf15SRobert Mustacchi                                   void (*pWorkCbkGeneric)(um_device_t *))
302*d14abf15SRobert Mustacchi {
303*d14abf15SRobert Mustacchi     BnxeWorkItem * pWorkItem;
304*d14abf15SRobert Mustacchi 
305*d14abf15SRobert Mustacchi     if ((pWorkItem = kmem_zalloc(sizeof(BnxeWorkItem), KM_NOSLEEP)) == NULL)
306*d14abf15SRobert Mustacchi     {
307*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to allocate memory for work item!");
308*d14abf15SRobert Mustacchi         return B_FALSE;
309*d14abf15SRobert Mustacchi     }
310*d14abf15SRobert Mustacchi 
311*d14abf15SRobert Mustacchi     pWorkItem->pWorkData       = NULL;
312*d14abf15SRobert Mustacchi     pWorkItem->workDataLen     = 0;
313*d14abf15SRobert Mustacchi     pWorkItem->pWorkCbkCopy    = NULL;
314*d14abf15SRobert Mustacchi     pWorkItem->pWorkCbkNoCopy  = NULL;
315*d14abf15SRobert Mustacchi     pWorkItem->pWorkCbkGeneric = pWorkCbkGeneric;
316*d14abf15SRobert Mustacchi     pWorkItem->delayMs         = 0;
317*d14abf15SRobert Mustacchi 
318*d14abf15SRobert Mustacchi     mutex_enter(&pUM->workqs.instq.workQueueMutex);
319*d14abf15SRobert Mustacchi 
320*d14abf15SRobert Mustacchi     s_list_push_tail(&pUM->workqs.instq.workQueue, &pWorkItem->link);
321*d14abf15SRobert Mustacchi     pUM->workqs.instq.workItemQueued++;
322*d14abf15SRobert Mustacchi     if (s_list_entry_cnt(&pUM->workqs.instq.workQueue) >
323*d14abf15SRobert Mustacchi         pUM->workqs.instq.highWater)
324*d14abf15SRobert Mustacchi     {
325*d14abf15SRobert Mustacchi         pUM->workqs.instq.highWater =
326*d14abf15SRobert Mustacchi             s_list_entry_cnt(&pUM->workqs.instq.workQueue);
327*d14abf15SRobert Mustacchi     }
328*d14abf15SRobert Mustacchi 
329*d14abf15SRobert Mustacchi     mutex_exit(&pUM->workqs.instq.workQueueMutex);
330*d14abf15SRobert Mustacchi 
331*d14abf15SRobert Mustacchi     BnxeWorkQueueTrigger(pUM, &pUM->workqs.instq);
332*d14abf15SRobert Mustacchi 
333*d14abf15SRobert Mustacchi     return B_TRUE;
334*d14abf15SRobert Mustacchi }
335*d14abf15SRobert Mustacchi 
336*d14abf15SRobert Mustacchi 
BnxeWorkQueueAddDelay(um_device_t * pUM,void (* pWorkCbkCopy)(um_device_t *,void *,u32_t),void * pWorkData,u32_t workDataLen,u32_t delayMs)337*d14abf15SRobert Mustacchi boolean_t BnxeWorkQueueAddDelay(um_device_t * pUM,
338*d14abf15SRobert Mustacchi                                 void (*pWorkCbkCopy)(um_device_t *, void *, u32_t),
339*d14abf15SRobert Mustacchi                                 void * pWorkData,
340*d14abf15SRobert Mustacchi                                 u32_t  workDataLen,
341*d14abf15SRobert Mustacchi                                 u32_t  delayMs)
342*d14abf15SRobert Mustacchi {
343*d14abf15SRobert Mustacchi     BnxeWorkItem * pWorkItem;
344*d14abf15SRobert Mustacchi 
345*d14abf15SRobert Mustacchi     if ((pWorkItem = kmem_zalloc((sizeof(BnxeWorkItem) + workDataLen),
346*d14abf15SRobert Mustacchi                                  KM_NOSLEEP)) == NULL)
347*d14abf15SRobert Mustacchi     {
348*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to allocate memory for work item!");
349*d14abf15SRobert Mustacchi         return B_FALSE;
350*d14abf15SRobert Mustacchi     }
351*d14abf15SRobert Mustacchi 
352*d14abf15SRobert Mustacchi     pWorkItem->pWorkData       = (pWorkItem + 1);
353*d14abf15SRobert Mustacchi     pWorkItem->workDataLen     = workDataLen;
354*d14abf15SRobert Mustacchi     pWorkItem->pWorkCbkCopy    = pWorkCbkCopy;
355*d14abf15SRobert Mustacchi     pWorkItem->pWorkCbkNoCopy  = NULL;
356*d14abf15SRobert Mustacchi     pWorkItem->pWorkCbkGeneric = NULL;
357*d14abf15SRobert Mustacchi     pWorkItem->delayMs         = delayMs;
358*d14abf15SRobert Mustacchi 
359*d14abf15SRobert Mustacchi     memcpy(pWorkItem->pWorkData, pWorkData, workDataLen);
360*d14abf15SRobert Mustacchi 
361*d14abf15SRobert Mustacchi     mutex_enter(&pUM->workqs.delayq.workQueueMutex);
362*d14abf15SRobert Mustacchi 
363*d14abf15SRobert Mustacchi     s_list_push_tail(&pUM->workqs.delayq.workQueue, &pWorkItem->link);
364*d14abf15SRobert Mustacchi     pUM->workqs.delayq.workItemQueued++;
365*d14abf15SRobert Mustacchi     if (s_list_entry_cnt(&pUM->workqs.delayq.workQueue) >
366*d14abf15SRobert Mustacchi         pUM->workqs.delayq.highWater)
367*d14abf15SRobert Mustacchi     {
368*d14abf15SRobert Mustacchi         pUM->workqs.delayq.highWater =
369*d14abf15SRobert Mustacchi             s_list_entry_cnt(&pUM->workqs.delayq.workQueue);
370*d14abf15SRobert Mustacchi     }
371*d14abf15SRobert Mustacchi 
372*d14abf15SRobert Mustacchi     mutex_exit(&pUM->workqs.delayq.workQueueMutex);
373*d14abf15SRobert Mustacchi 
374*d14abf15SRobert Mustacchi     BnxeWorkQueueTrigger(pUM, &pUM->workqs.delayq);
375*d14abf15SRobert Mustacchi 
376*d14abf15SRobert Mustacchi     return B_TRUE;
377*d14abf15SRobert Mustacchi }
378*d14abf15SRobert Mustacchi 
379*d14abf15SRobert Mustacchi 
BnxeWorkQueueAddDelayNoCopy(um_device_t * pUM,void (* pWorkCbkNoCopy)(um_device_t *,void *),void * pWorkData,u32_t delayMs)380*d14abf15SRobert Mustacchi boolean_t BnxeWorkQueueAddDelayNoCopy(um_device_t * pUM,
381*d14abf15SRobert Mustacchi                                       void (*pWorkCbkNoCopy)(um_device_t *, void *),
382*d14abf15SRobert Mustacchi                                       void * pWorkData,
383*d14abf15SRobert Mustacchi                                       u32_t  delayMs)
384*d14abf15SRobert Mustacchi {
385*d14abf15SRobert Mustacchi     BnxeWorkItem * pWorkItem;
386*d14abf15SRobert Mustacchi 
387*d14abf15SRobert Mustacchi     if ((pWorkItem = kmem_zalloc(sizeof(BnxeWorkItem), KM_NOSLEEP)) == NULL)
388*d14abf15SRobert Mustacchi     {
389*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to allocate memory for work item!");
390*d14abf15SRobert Mustacchi         return B_FALSE;
391*d14abf15SRobert Mustacchi     }
392*d14abf15SRobert Mustacchi 
393*d14abf15SRobert Mustacchi     pWorkItem->pWorkData       = pWorkData;
394*d14abf15SRobert Mustacchi     pWorkItem->workDataLen     = 0;
395*d14abf15SRobert Mustacchi     pWorkItem->pWorkCbkCopy    = NULL;
396*d14abf15SRobert Mustacchi     pWorkItem->pWorkCbkNoCopy  = pWorkCbkNoCopy;
397*d14abf15SRobert Mustacchi     pWorkItem->pWorkCbkGeneric = NULL;
398*d14abf15SRobert Mustacchi     pWorkItem->delayMs         = delayMs;
399*d14abf15SRobert Mustacchi 
400*d14abf15SRobert Mustacchi     mutex_enter(&pUM->workqs.delayq.workQueueMutex);
401*d14abf15SRobert Mustacchi 
402*d14abf15SRobert Mustacchi     s_list_push_tail(&pUM->workqs.delayq.workQueue, &pWorkItem->link);
403*d14abf15SRobert Mustacchi     pUM->workqs.delayq.workItemQueued++;
404*d14abf15SRobert Mustacchi     if (s_list_entry_cnt(&pUM->workqs.delayq.workQueue) >
405*d14abf15SRobert Mustacchi         pUM->workqs.delayq.highWater)
406*d14abf15SRobert Mustacchi     {
407*d14abf15SRobert Mustacchi         pUM->workqs.delayq.highWater =
408*d14abf15SRobert Mustacchi             s_list_entry_cnt(&pUM->workqs.delayq.workQueue);
409*d14abf15SRobert Mustacchi     }
410*d14abf15SRobert Mustacchi 
411*d14abf15SRobert Mustacchi     mutex_exit(&pUM->workqs.delayq.workQueueMutex);
412*d14abf15SRobert Mustacchi 
413*d14abf15SRobert Mustacchi     BnxeWorkQueueTrigger(pUM, &pUM->workqs.delayq);
414*d14abf15SRobert Mustacchi 
415*d14abf15SRobert Mustacchi     return B_TRUE;
416*d14abf15SRobert Mustacchi }
417*d14abf15SRobert Mustacchi 
418*d14abf15SRobert Mustacchi 
BnxeWorkQueueAddDelayGeneric(um_device_t * pUM,void (* pWorkCbkGeneric)(um_device_t *),u32_t delayMs)419*d14abf15SRobert Mustacchi boolean_t BnxeWorkQueueAddDelayGeneric(um_device_t * pUM,
420*d14abf15SRobert Mustacchi                                        void (*pWorkCbkGeneric)(um_device_t *),
421*d14abf15SRobert Mustacchi                                        u32_t delayMs)
422*d14abf15SRobert Mustacchi {
423*d14abf15SRobert Mustacchi     BnxeWorkItem * pWorkItem;
424*d14abf15SRobert Mustacchi 
425*d14abf15SRobert Mustacchi     if ((pWorkItem = kmem_zalloc(sizeof(BnxeWorkItem), KM_NOSLEEP)) == NULL)
426*d14abf15SRobert Mustacchi     {
427*d14abf15SRobert Mustacchi         BnxeLogWarn(pUM, "Failed to allocate memory for work item!");
428*d14abf15SRobert Mustacchi         return B_FALSE;
429*d14abf15SRobert Mustacchi     }
430*d14abf15SRobert Mustacchi 
431*d14abf15SRobert Mustacchi     pWorkItem->pWorkData       = NULL;
432*d14abf15SRobert Mustacchi     pWorkItem->workDataLen     = 0;
433*d14abf15SRobert Mustacchi     pWorkItem->pWorkCbkCopy    = NULL;
434*d14abf15SRobert Mustacchi     pWorkItem->pWorkCbkNoCopy  = NULL;
435*d14abf15SRobert Mustacchi     pWorkItem->pWorkCbkGeneric = pWorkCbkGeneric;
436*d14abf15SRobert Mustacchi     pWorkItem->delayMs         = delayMs;
437*d14abf15SRobert Mustacchi 
438*d14abf15SRobert Mustacchi     mutex_enter(&pUM->workqs.delayq.workQueueMutex);
439*d14abf15SRobert Mustacchi 
440*d14abf15SRobert Mustacchi     s_list_push_tail(&pUM->workqs.delayq.workQueue, &pWorkItem->link);
441*d14abf15SRobert Mustacchi     pUM->workqs.delayq.workItemQueued++;
442*d14abf15SRobert Mustacchi     if (s_list_entry_cnt(&pUM->workqs.delayq.workQueue) >
443*d14abf15SRobert Mustacchi         pUM->workqs.delayq.highWater)
444*d14abf15SRobert Mustacchi     {
445*d14abf15SRobert Mustacchi         pUM->workqs.delayq.highWater =
446*d14abf15SRobert Mustacchi             s_list_entry_cnt(&pUM->workqs.delayq.workQueue);
447*d14abf15SRobert Mustacchi     }
448*d14abf15SRobert Mustacchi 
449*d14abf15SRobert Mustacchi     mutex_exit(&pUM->workqs.delayq.workQueueMutex);
450*d14abf15SRobert Mustacchi 
451*d14abf15SRobert Mustacchi     BnxeWorkQueueTrigger(pUM, &pUM->workqs.delayq);
452*d14abf15SRobert Mustacchi 
453*d14abf15SRobert Mustacchi     return B_TRUE;
454*d14abf15SRobert Mustacchi }
455*d14abf15SRobert Mustacchi 
456