static int ntb_set_mw()

in ntb_transport.c [853:910]


static int ntb_set_mw(struct ntb_transport_ctx *nt, int num_mw,
		      resource_size_t size)
{
	struct ntb_transport_mw *mw = &nt->mw_vec[num_mw];
	struct pci_dev *pdev = nt->ndev->pdev;
	size_t xlat_size, buff_size;
	resource_size_t xlat_align;
	resource_size_t xlat_align_size;
	int rc;

	if (!size)
		return -EINVAL;

	rc = ntb_mw_get_align(nt->ndev, PIDX, num_mw, &xlat_align,
			      &xlat_align_size, NULL);
	if (rc)
		return rc;

	xlat_size = round_up(size, xlat_align_size);
	buff_size = round_up(size, xlat_align);

	/* No need to re-setup */
	if (mw->xlat_size == xlat_size)
		return 0;

	if (mw->buff_size)
		ntb_free_mw(nt, num_mw);

	/* Alloc memory for receiving data.  Must be aligned */
	mw->xlat_size = xlat_size;
	mw->buff_size = buff_size;
	mw->alloc_size = buff_size;

	rc = ntb_alloc_mw_buffer(mw, &pdev->dev, xlat_align);
	if (rc) {
		mw->alloc_size *= 2;
		rc = ntb_alloc_mw_buffer(mw, &pdev->dev, xlat_align);
		if (rc) {
			dev_err(&pdev->dev,
				"Unable to alloc aligned MW buff\n");
			mw->xlat_size = 0;
			mw->buff_size = 0;
			mw->alloc_size = 0;
			return rc;
		}
	}

	/* Notify HW the memory location of the receive buffer */
	rc = ntb_mw_set_trans(nt->ndev, PIDX, num_mw, mw->dma_addr,
			      mw->xlat_size);
	if (rc) {
		dev_err(&pdev->dev, "Unable to set mw%d translation", num_mw);
		ntb_free_mw(nt, num_mw);
		return -EIO;
	}

	return 0;
}