/* * Upload the microcode into the SoundScape. The * microcode is 64K of data, and if we try to copy * it into a local variable then we will SMASH THE * KERNEL'S STACK! We therefore leave it in USER * SPACE, and save ourselves from copying it at all. */ static int sscape_upload_microcode(struct soundscape *sscape, const struct sscape_microcode __user *mc) { unsigned long flags; char __user *code; int err; /* * We are going to have to copy this data into a special * DMA-able buffer before we can upload it. We shall therefore * just check that the data pointer is valid for now. * * NOTE: This buffer is 64K long! That's WAY too big to * copy into a stack-temporary anyway. */ if ( get_user(code, &mc->code) || !access_ok(VERIFY_READ, code, SSCAPE_MICROCODE_SIZE) ) return -EFAULT; if ((err = upload_dma_data(sscape, code, SSCAPE_MICROCODE_SIZE)) == 0) { snd_printk(KERN_INFO "sscape: MIDI firmware loaded\n"); } spin_lock_irqsave(&sscape->lock, flags); set_midi_mode_unsafe(sscape->io_base); spin_unlock_irqrestore(&sscape->lock, flags); initialise_mpu401(sscape->mpu); return err; }
/* * Initialse an MPU-401 subdevice for MIDI support on the SoundScape. */ static int __devinit create_mpu401(snd_card_t * card, int devnum, unsigned long port, int irq) { struct soundscape *sscape = get_card_soundscape(card); snd_rawmidi_t *rawmidi; int err; #define MPU401_SHARE_HARDWARE 1 if ((err = snd_mpu401_uart_new(card, devnum, MPU401_HW_MPU401, port, MPU401_SHARE_HARDWARE, irq, SA_INTERRUPT, &rawmidi)) == 0) { mpu401_t *mpu = (mpu401_t *) rawmidi->private_data; mpu->open_input = mpu401_open; mpu->open_output = mpu401_open; mpu->close_input = mpu401_close; mpu->close_output = mpu401_close; mpu->private_data = sscape; sscape->mpu = mpu; initialise_mpu401(mpu); } return err; }
/* * Initialse an MPU-401 subdevice for MIDI support on the SoundScape. */ static int __devinit create_mpu401(struct snd_card *card, int devnum, unsigned long port, int irq) { struct soundscape *sscape = get_card_soundscape(card); struct snd_rawmidi *rawmidi; int err; if ((err = snd_mpu401_uart_new(card, devnum, MPU401_HW_MPU401, port, MPU401_INFO_INTEGRATED, irq, IRQF_DISABLED, &rawmidi)) == 0) { struct snd_mpu401 *mpu = (struct snd_mpu401 *) rawmidi->private_data; mpu->open_input = mpu401_open; mpu->open_output = mpu401_open; mpu->close_input = mpu401_close; mpu->close_output = mpu401_close; mpu->private_data = sscape; sscape->mpu = mpu; initialise_mpu401(mpu); } return err; }