From 77b906e591b171f06d505c39e0651779a9c75bea Mon Sep 17 00:00:00 2001 From: Roy Pledge Date: Tue, 13 Aug 2013 11:25:33 -0400 Subject: Add API to allocate specific portals based on index. This allows an application to get back the exact portal it was previously using by specifing the portals index value. Signed-off-by: Roy Pledge Change-Id: I8233816f0519731eb65b3671d68a01266eee42dd Reviewed-on: http://git.am.freescale.net:8181/4002 Tested-by: Review Code-CDREVIEW Reviewed-by: Ladouceur Jeffrey-R11498 Reviewed-by: Wang Haiying-R54964 Reviewed-by: Rivera Jose-B46482 diff --git a/drivers/staging/fsl_qbman/bman_driver.c b/drivers/staging/fsl_qbman/bman_driver.c index 06b77ed..27a5b0f 100644 --- a/drivers/staging/fsl_qbman/bman_driver.c +++ b/drivers/staging/fsl_qbman/bman_driver.c @@ -198,11 +198,34 @@ static struct bm_portal_config *get_pcfg(struct list_head *list) return pcfg; } +static struct bm_portal_config *get_pcfg_idx(struct list_head *list, + uint32_t idx) +{ + struct bm_portal_config *pcfg; + if (list_empty(list)) + return NULL; + list_for_each_entry(pcfg, list, list) { + if (pcfg->public_cfg.index == idx) { + list_del(&pcfg->list); + return pcfg; + } + } + return NULL; +} + struct bm_portal_config *bm_get_unused_portal(void) { + return bm_get_unused_portal_idx(QBMAN_ANY_PORTAL_IDX); +} + +struct bm_portal_config *bm_get_unused_portal_idx(uint32_t idx) +{ struct bm_portal_config *ret; spin_lock(&unused_pcfgs_lock); - ret = get_pcfg(&unused_pcfgs); + if (idx == QBMAN_ANY_PORTAL_IDX) + ret = get_pcfg(&unused_pcfgs); + else + ret = get_pcfg_idx(&unused_pcfgs, idx); spin_unlock(&unused_pcfgs_lock); return ret; } diff --git a/drivers/staging/fsl_qbman/bman_private.h b/drivers/staging/fsl_qbman/bman_private.h index 53aa21b..2df9857 100644 --- a/drivers/staging/fsl_qbman/bman_private.h +++ b/drivers/staging/fsl_qbman/bman_private.h @@ -80,6 +80,7 @@ const struct bm_portal_config *bman_destroy_affine_portal(void); /* Hooks from fsl_usdpaa.c to bman_driver.c */ struct bm_portal_config *bm_get_unused_portal(void); +struct bm_portal_config *bm_get_unused_portal_idx(uint32_t idx); void bm_put_unused_portal(struct bm_portal_config *pcfg); void bm_set_liodns(struct bm_portal_config *pcfg); diff --git a/drivers/staging/fsl_qbman/fsl_usdpaa.c b/drivers/staging/fsl_qbman/fsl_usdpaa.c index 0167b7b..aebbc15 100644 --- a/drivers/staging/fsl_qbman/fsl_usdpaa.c +++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c @@ -1047,7 +1047,8 @@ static long ioctl_portal_map(struct file *fp, struct ctx *ctx, return -ENOMEM; memcpy(&mapping->user, arg, sizeof(mapping->user)); if (mapping->user.type == usdpaa_portal_qman) { - mapping->qportal = qm_get_unused_portal(); + mapping->qportal = + qm_get_unused_portal_idx(mapping->user.index); if (!mapping->qportal) { ret = -ENODEV; goto err_get_portal; @@ -1055,13 +1056,16 @@ static long ioctl_portal_map(struct file *fp, struct ctx *ctx, mapping->phys = &mapping->qportal->addr_phys[0]; mapping->user.channel = mapping->qportal->public_cfg.channel; mapping->user.pools = mapping->qportal->public_cfg.pools; + mapping->user.index = mapping->qportal->public_cfg.index; } else if (mapping->user.type == usdpaa_portal_bman) { - mapping->bportal = bm_get_unused_portal(); + mapping->bportal = + bm_get_unused_portal_idx(mapping->user.index); if (!mapping->bportal) { ret = -ENODEV; goto err_get_portal; } mapping->phys = &mapping->bportal->addr_phys[0]; + mapping->user.index = mapping->bportal->public_cfg.index; } else { ret = -EINVAL; goto err_copy_from_user; @@ -1255,11 +1259,13 @@ static long usdpaa_ioctl_compat(struct file *fp, unsigned int cmd, if (copy_from_user(&input, a, sizeof(input))) return -EFAULT; converted.type = input.type; + converted.index = input.index; ret = ioctl_portal_map(fp, ctx, &converted); input.addr.cinh = ptr_to_compat(converted.addr.cinh); input.addr.cena = ptr_to_compat(converted.addr.cena); input.channel = converted.channel; input.pools = converted.pools; + input.index = converted.index; if (copy_to_user(a, &input, sizeof(input))) return -EFAULT; return ret; diff --git a/drivers/staging/fsl_qbman/qman_driver.c b/drivers/staging/fsl_qbman/qman_driver.c index 875c0df..b2f60d7 100644 --- a/drivers/staging/fsl_qbman/qman_driver.c +++ b/drivers/staging/fsl_qbman/qman_driver.c @@ -454,6 +454,21 @@ static struct qm_portal_config *get_pcfg(struct list_head *list) return pcfg; } +static struct qm_portal_config *get_pcfg_idx(struct list_head *list, u32 idx) +{ + struct qm_portal_config *pcfg; + if (list_empty(list)) + return NULL; + list_for_each_entry(pcfg, list, list) { + if (pcfg->public_cfg.index == idx) { + list_del(&pcfg->list); + return pcfg; + } + } + return NULL; +} + + static void portal_set_cpu(struct qm_portal_config *pcfg, int cpu) { int ret; @@ -530,11 +545,14 @@ _iommu_domain_free: iommu_domain_free(pcfg->iommu_domain); } -struct qm_portal_config *qm_get_unused_portal(void) +struct qm_portal_config *qm_get_unused_portal_idx(u32 idx) { struct qm_portal_config *ret; spin_lock(&unused_pcfgs_lock); - ret = get_pcfg(&unused_pcfgs); + if (idx == QBMAN_ANY_PORTAL_IDX) + ret = get_pcfg(&unused_pcfgs); + else + ret = get_pcfg_idx(&unused_pcfgs, idx); spin_unlock(&unused_pcfgs_lock); /* Bind stashing LIODNs to the CPU we are currently executing on, and * set the portal to use the stashing request queue corresonding to the @@ -549,6 +567,11 @@ struct qm_portal_config *qm_get_unused_portal(void) return ret; } +struct qm_portal_config *qm_get_unused_portal() +{ + return qm_get_unused_portal_idx(QBMAN_ANY_PORTAL_IDX); +} + void qm_put_unused_portal(struct qm_portal_config *pcfg) { spin_lock(&unused_pcfgs_lock); diff --git a/drivers/staging/fsl_qbman/qman_private.h b/drivers/staging/fsl_qbman/qman_private.h index 6179943..a701006 100644 --- a/drivers/staging/fsl_qbman/qman_private.h +++ b/drivers/staging/fsl_qbman/qman_private.h @@ -218,6 +218,8 @@ void qman_destroy_portal(struct qman_portal *qm); /* Hooks from fsl_usdpaa.c to qman_driver.c */ struct qm_portal_config *qm_get_unused_portal(void); +struct qm_portal_config *qm_get_unused_portal_idx(uint32_t idx); + void qm_put_unused_portal(struct qm_portal_config *pcfg); void qm_set_liodns(struct qm_portal_config *pcfg); diff --git a/include/linux/fsl_usdpaa.h b/include/linux/fsl_usdpaa.h index de017a6..fbf9480 100644 --- a/include/linux/fsl_usdpaa.h +++ b/include/linux/fsl_usdpaa.h @@ -165,9 +165,17 @@ enum usdpaa_portal_type { usdpaa_portal_bman, }; +#define QBMAN_ANY_PORTAL_IDX 0xffffffff + struct usdpaa_ioctl_portal_map { /* Input parameter, is a qman or bman portal required. */ + enum usdpaa_portal_type type; + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX + for don't care. The portal index will be populated by the + driver when the ioctl() successfully completes */ + uint32_t index; + /* Return value if the map succeeds, this gives the mapped * cache-inhibited (cinh) and cache-enabled (cena) addresses. */ struct usdpaa_portal_map { @@ -183,6 +191,10 @@ struct usdpaa_ioctl_portal_map { struct compat_usdpaa_ioctl_portal_map { /* Input parameter, is a qman or bman portal required. */ enum usdpaa_portal_type type; + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX + for don't care. The portal index will be populated by the + driver when the ioctl() successfully completes */ + uint32_t index; /* Return value if the map succeeds, this gives the mapped * cache-inhibited (cinh) and cache-enabled (cena) addresses. */ struct usdpaa_portal_map_compat { -- cgit v0.10.2