Esempio n. 1
0
/*
 * write the device - load patches
 */
long snd_opl3_write(struct snd_hwdep *hw, const char __user *buf, long count,
                    loff_t *offset)
{
    struct snd_opl3 *opl3 = hw->private_data;
    long result = 0;
    int err = 0;
    struct sbi_patch inst;

    while (count >= sizeof(inst)) {
        unsigned char type;
        if (copy_from_user(&inst, buf, sizeof(inst)))
            return -EFAULT;
        if (!memcmp(inst.key, FM_KEY_SBI, 4) ||
                !memcmp(inst.key, FM_KEY_2OP, 4))
            type = FM_PATCH_OPL2;
        else if (!memcmp(inst.key, FM_KEY_4OP, 4))
            type = FM_PATCH_OPL3;
        else /* invalid type */
            break;
        err = snd_opl3_load_patch(opl3, inst.prog, inst.bank, type,
                                  inst.name, inst.extension,
                                  inst.data);
        if (err < 0)
            break;
        result += sizeof(inst);
        count -= sizeof(inst);
    }
    return result > 0 ? result : err;
}
Esempio n. 2
0
static int snd_opl3_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format,
				       const char __user *buf, int offs, int count)
{
	struct snd_opl3 *opl3;
	struct sbi_instrument sbi;
	char name[32];
	int err, type;

	if (snd_BUG_ON(!arg))
		return -ENXIO;
	opl3 = arg->private_data;

	if (format == FM_PATCH)
		type = FM_PATCH_OPL2;
	else if (format == OPL3_PATCH)
		type = FM_PATCH_OPL3;
	else
		return -EINVAL;

	if (count < (int)sizeof(sbi)) {
		snd_printk(KERN_ERR "FM Error: Patch record too short\n");
		return -EINVAL;
	}
	if (copy_from_user(&sbi, buf, sizeof(sbi)))
		return -EFAULT;

	if (sbi.channel < 0 || sbi.channel >= SBFM_MAXINSTR) {
		snd_printk(KERN_ERR "FM Error: Invalid instrument number %d\n",
			   sbi.channel);
		return -EINVAL;
	}

	memset(name, 0, sizeof(name));
	sprintf(name, "Chan%d", sbi.channel);

	err = snd_opl3_load_patch(opl3, sbi.channel, 127, type, name, NULL,
				  sbi.operators);
	if (err < 0)
		return err;

	return sizeof(sbi);
}