261 if (behavior == DDI_INTR_ALLOC_STRICT) {
262 DDI_INTR_APIDBG((CE_CONT, "ddi_intr_alloc: "
263 "DDI_INTR_ALLOC_STRICT flag is passed, "
264 "return failure\n"));
265 if (curr_nintrs == 0)
266 i_ddi_intr_devi_fini(dip);
267 else if (i_ddi_irm_supported(dip, type) != DDI_SUCCESS)
268 (void) i_ddi_irm_modify(dip, curr_nintrs);
269 return (DDI_EAGAIN);
270 }
271 count = navail - curr_nintrs;
272 }
273
274 /* Now allocate required number of interrupts */
275 bzero(&tmp_hdl, sizeof (ddi_intr_handle_impl_t));
276 tmp_hdl.ih_type = type;
277 tmp_hdl.ih_inum = inum;
278 tmp_hdl.ih_scratch1 = count;
279 tmp_hdl.ih_scratch2 = (void *)(uintptr_t)behavior;
280 tmp_hdl.ih_dip = dip;
281
282 if (i_ddi_intr_ops(dip, dip, DDI_INTROP_ALLOC,
283 &tmp_hdl, (void *)actualp) != DDI_SUCCESS) {
284 DDI_INTR_APIDBG((CE_CONT, "ddi_intr_alloc: allocation "
285 "failed\n"));
286 i_ddi_intr_devi_fini(dip);
287 return (*actualp ? DDI_EAGAIN : DDI_INTR_NOTFOUND);
288 }
289
290 if ((ret = i_ddi_intr_ops(dip, dip, DDI_INTROP_GETPRI,
291 &tmp_hdl, (void *)&pri)) != DDI_SUCCESS) {
292 DDI_INTR_APIDBG((CE_CONT, "ddi_intr_alloc: get priority "
293 "failed\n"));
294 goto fail;
295 }
296
297 DDI_INTR_APIDBG((CE_CONT, "ddi_intr_alloc: getting capability\n"));
298
299 if ((ret = i_ddi_intr_ops(dip, dip, DDI_INTROP_GETCAP,
300 &tmp_hdl, (void *)&cap)) != DDI_SUCCESS) {
307 * Save current interrupt type, supported and current intr count.
308 */
309 i_ddi_intr_set_current_type(dip, type);
310 i_ddi_intr_set_supported_nintrs(dip, nintrs);
311 i_ddi_intr_set_current_nintrs(dip,
312 i_ddi_intr_get_current_nintrs(dip) + *actualp);
313
314 /* Now, go and handle each "handle" */
315 for (i = inum; i < (inum + *actualp); i++) {
316 hdlp = (ddi_intr_handle_impl_t *)kmem_zalloc(
317 (sizeof (ddi_intr_handle_impl_t)), KM_SLEEP);
318 rw_init(&hdlp->ih_rwlock, NULL, RW_DRIVER, NULL);
319 h_array[i] = (struct __ddi_intr_handle *)hdlp;
320 hdlp->ih_type = type;
321 hdlp->ih_pri = pri;
322 hdlp->ih_cap = cap;
323 hdlp->ih_ver = DDI_INTR_VERSION;
324 hdlp->ih_state = DDI_IHDL_STATE_ALLOC;
325 hdlp->ih_dip = dip;
326 hdlp->ih_inum = i;
327 i_ddi_alloc_intr_phdl(hdlp);
328 if (type & DDI_INTR_TYPE_FIXED)
329 i_ddi_set_intr_handle(dip, hdlp->ih_inum,
330 (ddi_intr_handle_t)hdlp);
331
332 DDI_INTR_APIDBG((CE_CONT, "ddi_intr_alloc: hdlp = 0x%p\n",
333 (void *)h_array[i]));
334 }
335
336 return (DDI_SUCCESS);
337
338 fail:
339 (void) i_ddi_intr_ops(tmp_hdl.ih_dip, tmp_hdl.ih_dip,
340 DDI_INTROP_FREE, &tmp_hdl, NULL);
341 i_ddi_intr_devi_fini(dip);
342
343 return (ret);
344 }
345
346 int
347 ddi_intr_free(ddi_intr_handle_t h)
348 {
349 ddi_intr_handle_impl_t *hdlp = (ddi_intr_handle_impl_t *)h;
350 int ret;
|
261 if (behavior == DDI_INTR_ALLOC_STRICT) {
262 DDI_INTR_APIDBG((CE_CONT, "ddi_intr_alloc: "
263 "DDI_INTR_ALLOC_STRICT flag is passed, "
264 "return failure\n"));
265 if (curr_nintrs == 0)
266 i_ddi_intr_devi_fini(dip);
267 else if (i_ddi_irm_supported(dip, type) != DDI_SUCCESS)
268 (void) i_ddi_irm_modify(dip, curr_nintrs);
269 return (DDI_EAGAIN);
270 }
271 count = navail - curr_nintrs;
272 }
273
274 /* Now allocate required number of interrupts */
275 bzero(&tmp_hdl, sizeof (ddi_intr_handle_impl_t));
276 tmp_hdl.ih_type = type;
277 tmp_hdl.ih_inum = inum;
278 tmp_hdl.ih_scratch1 = count;
279 tmp_hdl.ih_scratch2 = (void *)(uintptr_t)behavior;
280 tmp_hdl.ih_dip = dip;
281 tmp_hdl.ih_irq = -1;
282
283 if (i_ddi_intr_ops(dip, dip, DDI_INTROP_ALLOC,
284 &tmp_hdl, (void *)actualp) != DDI_SUCCESS) {
285 DDI_INTR_APIDBG((CE_CONT, "ddi_intr_alloc: allocation "
286 "failed\n"));
287 i_ddi_intr_devi_fini(dip);
288 return (*actualp ? DDI_EAGAIN : DDI_INTR_NOTFOUND);
289 }
290
291 if ((ret = i_ddi_intr_ops(dip, dip, DDI_INTROP_GETPRI,
292 &tmp_hdl, (void *)&pri)) != DDI_SUCCESS) {
293 DDI_INTR_APIDBG((CE_CONT, "ddi_intr_alloc: get priority "
294 "failed\n"));
295 goto fail;
296 }
297
298 DDI_INTR_APIDBG((CE_CONT, "ddi_intr_alloc: getting capability\n"));
299
300 if ((ret = i_ddi_intr_ops(dip, dip, DDI_INTROP_GETCAP,
301 &tmp_hdl, (void *)&cap)) != DDI_SUCCESS) {
308 * Save current interrupt type, supported and current intr count.
309 */
310 i_ddi_intr_set_current_type(dip, type);
311 i_ddi_intr_set_supported_nintrs(dip, nintrs);
312 i_ddi_intr_set_current_nintrs(dip,
313 i_ddi_intr_get_current_nintrs(dip) + *actualp);
314
315 /* Now, go and handle each "handle" */
316 for (i = inum; i < (inum + *actualp); i++) {
317 hdlp = (ddi_intr_handle_impl_t *)kmem_zalloc(
318 (sizeof (ddi_intr_handle_impl_t)), KM_SLEEP);
319 rw_init(&hdlp->ih_rwlock, NULL, RW_DRIVER, NULL);
320 h_array[i] = (struct __ddi_intr_handle *)hdlp;
321 hdlp->ih_type = type;
322 hdlp->ih_pri = pri;
323 hdlp->ih_cap = cap;
324 hdlp->ih_ver = DDI_INTR_VERSION;
325 hdlp->ih_state = DDI_IHDL_STATE_ALLOC;
326 hdlp->ih_dip = dip;
327 hdlp->ih_inum = i;
328 hdlp->ih_irq = -1;
329 i_ddi_alloc_intr_phdl(hdlp);
330 if (type & DDI_INTR_TYPE_FIXED) {
331 if (tmp_hdl.ih_irq != -1)
332 hdlp->ih_irq = tmp_hdl.ih_irq;
333 i_ddi_set_intr_handle(dip, hdlp->ih_inum,
334 (ddi_intr_handle_t)hdlp);
335 }
336
337 DDI_INTR_APIDBG((CE_CONT, "ddi_intr_alloc: hdlp = 0x%p\n",
338 (void *)h_array[i]));
339 }
340
341 return (DDI_SUCCESS);
342
343 fail:
344 (void) i_ddi_intr_ops(tmp_hdl.ih_dip, tmp_hdl.ih_dip,
345 DDI_INTROP_FREE, &tmp_hdl, NULL);
346 i_ddi_intr_devi_fini(dip);
347
348 return (ret);
349 }
350
351 int
352 ddi_intr_free(ddi_intr_handle_t h)
353 {
354 ddi_intr_handle_impl_t *hdlp = (ddi_intr_handle_impl_t *)h;
355 int ret;
|