version 1.6, 2020/06/28 05:21:39 |
version 1.7, 2021/03/03 10:00:27 |
|
|
void |
void |
dev_sioctl_ondesc(void *arg, struct sioctl_desc *desc, int val) |
dev_sioctl_ondesc(void *arg, struct sioctl_desc *desc, int val) |
{ |
{ |
#define GROUP_PREFIX "hw" |
|
char group_buf[CTL_NAMEMAX], *group; |
|
struct dev *d = arg; |
struct dev *d = arg; |
int addr; |
char *group, group_buf[CTL_NAMEMAX]; |
|
|
if (desc == NULL) { |
if (desc == NULL) { |
dev_ctlsync(d); |
dev_ctlsync(d); |
return; |
return; |
} |
} |
|
|
addr = CTLADDR_END + desc->addr; |
ctl_del(CTL_HW, d, &desc->addr); |
dev_rmctl(d, addr); |
|
|
|
/* |
if (desc->group[0] == 0) |
* prefix with "hw/" group names of controls we expose, to |
group = d->name; |
* ensure that all controls have unique names when multiple |
else { |
* sndiod's are chained |
if (snprintf(group_buf, CTL_NAMEMAX, "%s/%s", |
*/ |
d->name, desc->group) >= CTL_NAMEMAX) |
if (strcmp(desc->group, "app") == 0 || (desc->group[0] == 0 && |
|
strcmp(desc->node0.name, "server") == 0)) { |
|
group = group_buf; |
|
if (snprintf(group_buf, CTL_NAMEMAX, GROUP_PREFIX "/%s", |
|
desc->group) >= CTL_NAMEMAX) |
|
return; |
return; |
} else |
group = group_buf; |
group = desc->group; |
} |
|
|
dev_addctl(d, group, desc->type, addr, |
ctl_new(CTL_HW, d, &desc->addr, |
|
desc->type, group, |
desc->node0.name, desc->node0.unit, desc->func, |
desc->node0.name, desc->node0.unit, desc->func, |
desc->node1.name, desc->node1.unit, desc->maxval, val); |
desc->node1.name, desc->node1.unit, desc->maxval, val); |
} |
} |
|
|
struct dev *d = arg; |
struct dev *d = arg; |
struct ctl *c; |
struct ctl *c; |
|
|
addr += CTLADDR_END; |
|
|
|
dev_log(d); |
dev_log(d); |
log_puts(": onctl: addr = "); |
log_puts(": onctl: addr = "); |
log_putu(addr); |
log_putu(addr); |
|
|
log_putu(val); |
log_putu(val); |
log_puts("\n"); |
log_puts("\n"); |
|
|
for (c = d->ctl_list; c != NULL; c = c->next) { |
for (c = ctl_list; c != NULL; c = c->next) { |
if (c->addr != addr) |
if (c->scope != CTL_HW || c->u.hw.addr != addr) |
continue; |
continue; |
ctl_log(c); |
ctl_log(c); |
log_puts(": new value -> "); |
log_puts(": new value -> "); |
|
|
struct ctl *c, **pc; |
struct ctl *c, **pc; |
|
|
/* remove controls */ |
/* remove controls */ |
pc = &d->ctl_list; |
pc = &ctl_list; |
while ((c = *pc) != NULL) { |
while ((c = *pc) != NULL) { |
if (c->addr >= CTLADDR_END) { |
if (c->scope == CTL_HW && c->u.hw.dev == d) { |
c->refs_mask &= ~CTL_DEVMASK; |
c->refs_mask &= ~CTL_DEVMASK; |
if (c->refs_mask == 0) { |
if (c->refs_mask == 0) { |
*pc = c->next; |
*pc = c->next; |
|
|
struct ctl *c; |
struct ctl *c; |
int events = 0; |
int events = 0; |
|
|
for (c = d->ctl_list; c != NULL; c = c->next) { |
for (c = ctl_list; c != NULL; c = c->next) { |
if (c->dirty) |
if (c->scope == CTL_HW && c->u.hw.dev == d && c->dirty) |
events |= POLLOUT; |
events |= POLLOUT; |
} |
} |
return sioctl_pollfd(d->sioctl.hdl, pfd, events); |
return sioctl_pollfd(d->sioctl.hdl, pfd, events); |
|
|
* we've finished iterating on it. |
* we've finished iterating on it. |
*/ |
*/ |
cnt = 0; |
cnt = 0; |
for (c = d->ctl_list; c != NULL; c = c->next) { |
for (c = ctl_list; c != NULL; c = c->next) { |
if (!c->dirty) |
if (c->scope != CTL_HW || c->u.hw.dev != d || !c->dirty) |
continue; |
continue; |
if (!sioctl_setval(d->sioctl.hdl, |
if (!sioctl_setval(d->sioctl.hdl, c->u.hw.addr, c->curval)) { |
c->addr - CTLADDR_END, c->curval)) { |
|
ctl_log(c); |
ctl_log(c); |
log_puts(": set failed\n"); |
log_puts(": set failed\n"); |
break; |
break; |