1283 0, 0, &txp->xt_dma_handle) != DDI_SUCCESS)
1284 goto failure;
1285
1286 if (ddi_dma_mem_alloc(txp->xt_dma_handle, PAGESIZE, &data_accattr,
1287 DDI_DMA_STREAMING, 0, 0, &txp->xt_buf, &len,
1288 &txp->xt_acc_handle) != DDI_SUCCESS)
1289 goto failure_1;
1290
1291 if (ddi_dma_addr_bind_handle(txp->xt_dma_handle, NULL, txp->xt_buf,
1292 len, DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, 0,
1293 &dma_cookie, &ncookies)
1294 != DDI_DMA_MAPPED)
1295 goto failure_2;
1296 ASSERT(ncookies == 1);
1297
1298 txp->xt_mfn = xnb_btop(dma_cookie.dmac_laddress);
1299 txp->xt_buflen = dma_cookie.dmac_size;
1300
1301 DTRACE_PROBE(txbuf_allocated);
1302
1303 atomic_add_32(&xnbp->xnb_tx_buf_count, 1);
1304 xnbp->xnb_tx_buf_outstanding++;
1305
1306 return (0);
1307
1308 failure_2:
1309 ddi_dma_mem_free(&txp->xt_acc_handle);
1310
1311 failure_1:
1312 ddi_dma_free_handle(&txp->xt_dma_handle);
1313
1314 failure:
1315
1316 return (-1);
1317 }
1318
1319 static void
1320 xnb_txbuf_destructor(void *buf, void *arg)
1321 {
1322 xnb_txbuf_t *txp = buf;
1323 xnb_t *xnbp = arg;
1324
1325 (void) ddi_dma_unbind_handle(txp->xt_dma_handle);
1326 ddi_dma_mem_free(&txp->xt_acc_handle);
1327 ddi_dma_free_handle(&txp->xt_dma_handle);
1328
1329 atomic_add_32(&xnbp->xnb_tx_buf_count, -1);
1330 }
1331
1332 /*
1333 * Take packets from the peer and deliver them onward.
1334 */
1335 static mblk_t *
1336 xnb_from_peer(xnb_t *xnbp)
1337 {
1338 RING_IDX start, end, loop;
1339 gnttab_copy_t *cop;
1340 xnb_txbuf_t **txpp;
1341 netif_tx_request_t *txreq;
1342 boolean_t work_to_do, need_notify = B_FALSE;
1343 mblk_t *head, *tail;
1344 int n_data_req, i;
1345
1346 ASSERT(MUTEX_HELD(&xnbp->xnb_tx_lock));
1347
1348 head = tail = NULL;
1349 around:
|
1283 0, 0, &txp->xt_dma_handle) != DDI_SUCCESS)
1284 goto failure;
1285
1286 if (ddi_dma_mem_alloc(txp->xt_dma_handle, PAGESIZE, &data_accattr,
1287 DDI_DMA_STREAMING, 0, 0, &txp->xt_buf, &len,
1288 &txp->xt_acc_handle) != DDI_SUCCESS)
1289 goto failure_1;
1290
1291 if (ddi_dma_addr_bind_handle(txp->xt_dma_handle, NULL, txp->xt_buf,
1292 len, DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, 0,
1293 &dma_cookie, &ncookies)
1294 != DDI_DMA_MAPPED)
1295 goto failure_2;
1296 ASSERT(ncookies == 1);
1297
1298 txp->xt_mfn = xnb_btop(dma_cookie.dmac_laddress);
1299 txp->xt_buflen = dma_cookie.dmac_size;
1300
1301 DTRACE_PROBE(txbuf_allocated);
1302
1303 atomic_inc_32(&xnbp->xnb_tx_buf_count);
1304 xnbp->xnb_tx_buf_outstanding++;
1305
1306 return (0);
1307
1308 failure_2:
1309 ddi_dma_mem_free(&txp->xt_acc_handle);
1310
1311 failure_1:
1312 ddi_dma_free_handle(&txp->xt_dma_handle);
1313
1314 failure:
1315
1316 return (-1);
1317 }
1318
1319 static void
1320 xnb_txbuf_destructor(void *buf, void *arg)
1321 {
1322 xnb_txbuf_t *txp = buf;
1323 xnb_t *xnbp = arg;
1324
1325 (void) ddi_dma_unbind_handle(txp->xt_dma_handle);
1326 ddi_dma_mem_free(&txp->xt_acc_handle);
1327 ddi_dma_free_handle(&txp->xt_dma_handle);
1328
1329 atomic_dec_32(&xnbp->xnb_tx_buf_count);
1330 }
1331
1332 /*
1333 * Take packets from the peer and deliver them onward.
1334 */
1335 static mblk_t *
1336 xnb_from_peer(xnb_t *xnbp)
1337 {
1338 RING_IDX start, end, loop;
1339 gnttab_copy_t *cop;
1340 xnb_txbuf_t **txpp;
1341 netif_tx_request_t *txreq;
1342 boolean_t work_to_do, need_notify = B_FALSE;
1343 mblk_t *head, *tail;
1344 int n_data_req, i;
1345
1346 ASSERT(MUTEX_HELD(&xnbp->xnb_tx_lock));
1347
1348 head = tail = NULL;
1349 around:
|