Пример #1
0
static void __init attach_maui(struct address_info *hw_config)
{
	int this_dev;

	conf_printf("Maui", hw_config);

	hw_config->irq *= -1;
	hw_config->name = "Maui";
	attach_mpu401(hw_config, THIS_MODULE);

	if (hw_config->slots[1] != -1)	/* The MPU401 driver installed itself */ {
		struct synth_operations *synth;

		this_dev = hw_config->slots[1];

		/*
		 * Intercept patch loading calls so that they can be handled
		 * by the Maui driver.
		 */

		synth = midi_devs[this_dev]->converter;
		synth->id = "MAUI";

		if (synth != NULL) {
			orig_load_patch = synth->load_patch;
			synth->load_patch = &maui_load_patch;
		} else
			printk(KERN_ERR "Maui: Can't install patch loader\n");
	}
}
Пример #2
0
static void __init attach_uart6850(struct address_info *hw_config)
{
	int ok, timeout;
	unsigned long   flags;

	if (!uart6850_detected)
		return;

	if ((my_dev = sound_alloc_mididev()) == -1)
	{
		printk(KERN_INFO "uart6850: Too many midi devices detected\n");
		return;
	}
	uart6850_base = hw_config->io_base;
	uart6850_osp = hw_config->osp;
	uart6850_irq = hw_config->irq;

	spin_lock_irqsave(&lock,flags);

	for (timeout = 30000; timeout > 0 && !output_ready(); timeout--);	/*
										 * Wait
										 */
	uart6850_cmd(UART_MODE_ON);
	ok = 1;
	spin_unlock_irqrestore(&lock,flags);

	conf_printf("6850 Midi Interface", hw_config);

	std_midi_synth.midi_dev = my_dev;
	hw_config->slots[4] = my_dev;
	midi_devs[my_dev] = &uart6850_operations;
	sequencer_init();
}
Пример #3
0
void attach_vidc(struct address_info *hw_config)
{
	char name[32];
	int i;

	sprintf(name, "VIDC %d-bit sound", hw_config->card_subtype);
	conf_printf(name, hw_config);

	for (i = 0; i < 2; i++)
	{
		dma_buf[i] = get_free_page(GFP_KERNEL);
		dma_pbuf[i] = virt_to_phys(dma_buf[i]);
	}

	if (sound_alloc_dma(hw_config->dma, "VIDCsound"))
	{
		printk(KERN_ERR "VIDCsound: can't allocate virtual DMA channel\n");
		return;
	}
	if (request_irq(hw_config->irq, vidc_sound_dma_irq, 0, "VIDCsound", &dma_start))
	{
		printk(KERN_ERR "VIDCsound: can't allocate DMA interrupt\n");
		return;
	}
//	vidc_synth_init(hw_config);
	vidc_audio_init(hw_config);
	vidc_mixer_init(hw_config);
}
Пример #4
0
/*
** Set the DefFiltOpts: line for a group.
*/
int group_deffiltopts_internal(const char *group)
	{
	if(grpopen(group, TRUE, FALSE))
		{
		fprintf(errors, "The group \"%s\" does not exist.\n", group);
		return EXIT_BADDEST;
		}

	{
	void *qobj = NULL;
	const char *p;
	gu_Try {
		qobj = queueinfo_new(QUEUEINFO_GROUP, group);
		queueinfo_set_warnings_file(qobj, errors);
		queueinfo_set_debug_level(qobj, debug_level);
			
		/* Modify the group's configuration file. */
		while(confread())
			{
			if(lmatch(confline, "DefFiltOpts:"))
				continue;

			if((p = lmatchp(confline, "Printer:")))
				queueinfo_add_printer(qobj, p);
	
			conf_printf("%s\n", confline);
			}
	
		if((p = queueinfo_computedDefaultFilterOptions(qobj)))
			conf_printf("DefFiltOpts: %s\n", p);

		confclose();
		}
	gu_Final {
		if(qobj)
			queueinfo_free(qobj);
		}
	gu_Catch {
		confabort();
		fprintf(errors, "%s: %s\n", myname, gu_exception);
		return exception_to_exitcode(gu_exception_code);
		}
	}

	return EXIT_OK;
	} /* end of group_deffiltopts_internal() */
Пример #5
0
/*
** Set a group's rotate setting.
*/
int group_rotate(const char *argv[])
	{
	const char *group = argv[0];
	int newstate;

	if( ! am_administrator() )
		return EXIT_DENIED;

	if(! group || ! argv[1] || ((newstate=gu_torf(argv[1]))==ANSWER_UNKNOWN) )
		{
		fputs(_("You must supply the name of a group and \"true\" or \"false\".\n"), errors);
		return EXIT_SYNTAX;
		}

	/* make sure the group exists */
	if(grpopen(group, TRUE, FALSE))
		{
		fprintf(errors, _("The group \"%s\" does not exist.\n"),group);
		return EXIT_BADDEST;
		}

	/* Modify the group's configuration file. */
	while(confread())
		{
		if(lmatch(confline, "Rotate:"))
			break;
		else
			conf_printf("%s\n", confline);
		}

	conf_printf("Rotate: %s\n", newstate ? "True" : "False");

	while(confread())							/* copy rest of file, */
		{
		if(lmatch(confline, "Rotate:"))			/* discard */
			continue;
		else									/* copy */
			conf_printf("%s\n", confline);
		}
	confclose();

	reread_group(group);						/* pprd must know the rotate setting */
	return EXIT_OK;
	} /* end of group_rotate() */
Пример #6
0
void
attach_sb16midi(struct address_info * hw_config)
{
	int             ok, timeout;
	u_long   flags;

	sb16midi_base = hw_config->io_base;

	if (!sb16midi_detected)
		return;

	flags = splhigh();
	for (timeout = 30000; timeout < 0 && !output_ready(); timeout--);	/* Wait */
	input_byte = 0;
	sb16midi_cmd(UART_MODE_ON);

	ok = 0;
	for (timeout = 50000; timeout > 0 && !ok; timeout--)
		if (input_byte == MPU_ACK)
			ok = 1;
		else if (input_avail())
			if (sb16midi_read() == MPU_ACK)
				ok = 1;

	splx(flags);

	if (num_midis >= MAX_MIDI_DEV) {
		printf("Sound: Too many midi devices detected\n");
		return;
	}
	
	conf_printf("SoundBlaster MPU-401", hw_config);
	std_midi_synth.midi_dev = my_dev = num_midis;
	midi_devs[num_midis++] = &sb16midi_operations;
	return;
}
Пример #7
0
void __init attach_sscape(struct address_info *hw_config)
{
#ifndef SSCAPE_REGS
	/*
	 * Config register values for Spea/V7 Media FX and Ensoniq S-2000.
	 * These values are card
	 * dependent. If you have another SoundScape based card, you have to
	 * find the correct values. Do the following:
	 *  - Compile this driver with SSCAPE_DEBUG1 defined.
	 *  - Shut down and power off your machine.
	 *  - Boot with DOS so that the SSINIT.EXE program is run.
	 *  - Warm boot to {Linux|SYSV|BSD} and write down the lines displayed
	 *    when detecting the SoundScape.
	 *  - Modify the following list to use the values printed during boot.
	 *    Undefine the SSCAPE_DEBUG1
	 */
#define SSCAPE_REGS { \
/* I0 */	0x00, \
/* I1 */	0xf0, /* Note! Ignored. Set always to 0xf0 */ \
/* I2 */	0x20, /* Note! Ignored. Set always to 0x20 */ \
/* I3 */	0x20, /* Note! Ignored. Set always to 0x20 */ \
/* I4 */	0xf5, /* Ignored */ \
/* I5 */	0x10, \
/* I6 */	0x00, \
/* I7 */	0x2e, /* I7 MEM config A. Likely to vary between models */ \
/* I8 */	0x00, /* I8 MEM config B. Likely to vary between models */ \
/* I9 */	0x40 /* Ignored */ \
	}
#endif

	unsigned long   flags;
	static unsigned char regs[10] = SSCAPE_REGS;

	int i, irq_bits = 0xff;

	if (sscape_detected != hw_config->io_base)
		return;

	request_region(devc->base + 2, 6, "SoundScape");
	if (old_hardware)
	{
		valid_interrupts = valid_interrupts_old;
		conf_printf("Ensoniq SoundScape (old)", hw_config);
	}
	else
		conf_printf("Ensoniq SoundScape", hw_config);

	for (i = 0; i < sizeof(valid_interrupts); i++)
	{
		if (hw_config->irq == valid_interrupts[i])
		{
			irq_bits = i;
			break;
		}
	}
	if (hw_config->irq > 15 || ((regs[4] = irq_bits) == 0xff))
	{
		printk(KERN_ERR "Invalid IRQ%d\n", hw_config->irq);
		return;
	}
	
	if (!sscape_is_pnp) {
	
	    save_flags(flags);
	    cli();
	    for (i = 1; i < 10; i++)
	    {
		switch (i)
		{
			case 1:	/* Host interrupt enable */
				sscape_write(devc, i, 0xf0);	/* All interrupts enabled */
				break;

			case 2:	/* DMA A status/trigger register */
			case 3:	/* DMA B status/trigger register */
				sscape_write(devc, i, 0x20);	/* DMA channel disabled */
				break;

			case 4:	/* Host interrupt config reg */
				sscape_write(devc, i, 0xf0 | (irq_bits << 2) | irq_bits);
				break;

			case 5:	/* Don't destroy CD-ROM DMA config bits (0xc0) */
				sscape_write(devc, i, (regs[i] & 0x3f) | (sscape_read(devc, i) & 0xc0));
				break;

			case 6:	/* CD-ROM config (WSS codec actually) */
				sscape_write(devc, i, regs[i]);
				break;

			case 9:	/* Master control reg. Don't modify CR-ROM bits. Disable SB emul */
				sscape_write(devc, i, (sscape_read(devc, i) & 0xf0) | 0x08);
				break;

			default:
				sscape_write(devc, i, regs[i]);
		}
	    }
	    restore_flags(flags);
	}
#ifdef SSCAPE_DEBUG2
	/*
	 * Temporary debugging aid. Print contents of the registers after
	 * changing them.
	 */
	{
		int i;

		for (i = 0; i < 13; i++)
			printk("I%d = %02x (new value)\n", i, sscape_read(devc, i));
	}
#endif

	if (probe_mpu401(hw_config))
		hw_config->always_detect = 1;
	hw_config->name = "SoundScape";

	hw_config->irq *= -1;	/* Negative value signals IRQ sharing */
	attach_mpu401(hw_config, THIS_MODULE);
	hw_config->irq *= -1;	/* Restore it */

	if (hw_config->slots[1] != -1)	/* The MPU driver installed itself */
	{
		sscape_mididev = hw_config->slots[1];
		midi_devs[hw_config->slots[1]]->coproc = &sscape_coproc_operations;
	}
	sscape_write(devc, GA_INTENA_REG, 0x80);	/* Master IRQ enable */
	devc->ok = 1;
	devc->failed = 0;
}
Пример #8
0
int probe_uart401(struct address_info *hw_config, struct module *owner)
{
	uart401_devc *devc;
	char *name = "MPU-401 (UART) MIDI";
	int ok = 0;
	unsigned long flags;

	DDB(printk("Entered probe_uart401()\n"));

	/* Default to "not found" */
	hw_config->slots[4] = -1;

	if (!request_region(hw_config->io_base, 4, "MPU-401 UART")) {
		printk(KERN_INFO "uart401: could not request_region(%d, 4)\n", hw_config->io_base);
		return 0;
	}

	devc = kmalloc(sizeof(uart401_devc), GFP_KERNEL);
	if (!devc) {
		printk(KERN_WARNING "uart401: Can't allocate memory\n");
		goto cleanup_region;
	}

	devc->base = hw_config->io_base;
	devc->irq = hw_config->irq;
	devc->osp = hw_config->osp;
	devc->midi_input_intr = NULL;
	devc->opened = 0;
	devc->input_byte = 0;
	devc->my_dev = 0;
	devc->share_irq = 0;
	spin_lock_init(&devc->lock);

	spin_lock_irqsave(&devc->lock,flags);	
	ok = reset_uart401(devc);
	spin_unlock_irqrestore(&devc->lock,flags);

	if (!ok)
		goto cleanup_devc;

	if (hw_config->name)
		name = hw_config->name;

	if (devc->irq < 0) {
		devc->share_irq = 1;
		devc->irq *= -1;
	} else
		devc->share_irq = 0;

	if (!devc->share_irq)
		if (request_irq(devc->irq, uart401intr, 0, "MPU-401 UART", devc) < 0) {
			printk(KERN_WARNING "uart401: Failed to allocate IRQ%d\n", devc->irq);
			devc->share_irq = 1;
		}
	devc->my_dev = sound_alloc_mididev();
	enter_uart_mode(devc);

	if (devc->my_dev == -1) {
		printk(KERN_INFO "uart401: Too many midi devices detected\n");
		goto cleanup_irq;
	}
	conf_printf(name, hw_config);
	midi_devs[devc->my_dev] = kmemdup(&uart401_operations,
					  sizeof(struct midi_operations),
					  GFP_KERNEL);
	if (!midi_devs[devc->my_dev]) {
		printk(KERN_ERR "uart401: Failed to allocate memory\n");
		goto cleanup_unload_mididev;
	}

	if (owner)
		midi_devs[devc->my_dev]->owner = owner;
	
	midi_devs[devc->my_dev]->devc = devc;
	midi_devs[devc->my_dev]->converter = kmemdup(&std_midi_synth,
						     sizeof(struct synth_operations),
Пример #9
0
static int __init probe_maui(struct address_info *hw_config)
{
	struct resource *ports;
	int this_dev;
	int i;
	int tmp1, tmp2, ret;

	ports = request_region(hw_config->io_base, 2, "mpu401");
	if (!ports)
		return 0;

	if (!request_region(hw_config->io_base + 2, 6, "Maui"))
		goto out;

	maui_base = hw_config->io_base;
	maui_osp = hw_config->osp;

	if (request_irq(hw_config->irq, mauiintr, 0, "Maui", NULL) < 0)
		goto out2;

	/*
	 * Initialize the processor if necessary
	 */

	if (maui_osLen > 0) {
		if (!(inb(HOST_STAT_PORT) & STAT_TX_AVAIL) ||
			!maui_write(0x9F) ||	/* Report firmware version */
			!maui_short_wait(STAT_RX_AVAIL) ||
			maui_read() == -1 || maui_read() == -1)
			if (!maui_init(hw_config->irq))
				goto out3;
	}
	if (!maui_write(0xCF))	/* Report hardware version */ {
		printk(KERN_ERR "No WaveFront firmware detected (card uninitialized?)\n");
		goto out3;
	}
	if ((tmp1 = maui_read()) == -1 || (tmp2 = maui_read()) == -1) {
		printk(KERN_ERR "No WaveFront firmware detected (card uninitialized?)\n");
		goto out3;
	}
	if (tmp1 == 0xff || tmp2 == 0xff)
		goto out3;
	printk(KERN_DEBUG "WaveFront hardware version %d.%d\n", tmp1, tmp2);

	if (!maui_write(0x9F))	/* Report firmware version */
		goto out3;
	if ((tmp1 = maui_read()) == -1 || (tmp2 = maui_read()) == -1)
		goto out3;

	printk(KERN_DEBUG "WaveFront firmware version %d.%d\n", tmp1, tmp2);

	if (!maui_write(0x85))	/* Report free DRAM */
		goto out3;
	tmp1 = 0;
	for (i = 0; i < 4; i++) {
		tmp1 |= maui_read() << (7 * i);
	}
	printk(KERN_DEBUG "Available DRAM %dk\n", tmp1 / 1024);

	for (i = 0; i < 1000; i++)
		if (probe_mpu401(hw_config, ports))
			break;

	ret = probe_mpu401(hw_config, ports);
	if (!ret)
		goto out3;

	conf_printf("Maui", hw_config);

	hw_config->irq *= -1;
	hw_config->name = "Maui";
	attach_mpu401(hw_config, THIS_MODULE);

	if (hw_config->slots[1] != -1)	/* The MPU401 driver installed itself */ {
		struct synth_operations *synth;

		this_dev = hw_config->slots[1];

		/*
		 * Intercept patch loading calls so that they can be handled
		 * by the Maui driver.
		 */

		synth = midi_devs[this_dev]->converter;
		if (synth != NULL) {
			synth->id = "MAUI";
			orig_load_patch = synth->load_patch;
			synth->load_patch = &maui_load_patch;
		} else
			printk(KERN_ERR "Maui: Can't install patch loader\n");
	}
	return 1;

out3:
	free_irq(hw_config->irq, NULL);
out2:
	release_region(hw_config->io_base + 2, 6);
out:
	release_region(hw_config->io_base, 2);
	return 0;
}
Пример #10
0
void
attach_sscape(struct address_info * hw_config)
{
#ifndef SSCAPE_REGS
    /*
     * Config register values for Spea/V7 Media FX and Ensoniq S-2000.
     * These values are card dependent. If you have another SoundScape
     * based card, you have to find the correct values. Do the following:
     * - Compile this driver with SSCAPE_DEBUG1 defined. - Shut down and
     * power off your machine. - Boot with DOS so that the SSINIT.EXE
     * program is run. - Warm boot to {Linux|SYSV|BSD} and write down the
     * lines displayed when detecting the SoundScape. - Modify the
     * following list to use the values printed during boot. Undefine the
     * SSCAPE_DEBUG1
     */
#define SSCAPE_REGS { \
/* I0 */	0x00, \
		0xf0, /* Note! Ignored. Set always to 0xf0 */ \
		0x20, /* Note! Ignored. Set always to 0x20 */ \
		0x20, /* Note! Ignored. Set always to 0x20 */ \
		0xf5, /* Ignored */ \
		0x10, \
		0x00, \
		0x2e, /* I7 MEM config A. Likely to vary between models */ \
		0x00, /* I8 MEM config B. Likely to vary between models */ \
/* I9 */	0x40 /* Ignored */ \
	}
#endif

    u_long   flags;
    static u_char regs[10] = SSCAPE_REGS;

    int             i, irq_bits = 0xff;

    if (sscape_detected != hw_config->io_base)
	return;

    if (old_hardware) {
	valid_interrupts = valid_interrupts_old;
	conf_printf("Ensoniq Soundscape (old)", hw_config);
    } else
	conf_printf("Ensoniq Soundscape", hw_config);

    for (i = 0; i < sizeof(valid_interrupts); i++)
	if (hw_config->irq == valid_interrupts[i]) {
	    irq_bits = i;
	    break;
	}
    if (hw_config->irq > 15 || (regs[4] = irq_bits == 0xff)) {
	printf("Invalid IRQ%d\n", hw_config->irq);
	return;
    }
    flags = splhigh();

    for (i = 1; i < 10; i++)
	switch (i) {
	case 1:	/* Host interrupt enable */
	    sscape_write(devc, i, 0xf0);	/* All interrupts enabled */
	    break;

	case 2:	/* DMA A status/trigger register */
	case 3:	/* DMA B status/trigger register */
	    sscape_write(devc, i, 0x20);	/* DMA channel disabled */
	    break;

	case 4:	/* Host interrupt config reg */
	    sscape_write(devc, i, 0xf0 | (irq_bits << 2) | irq_bits);
	    break;

	case 5:	/* Don't destroy CD-ROM DMA config bits (0xc0) */
	    sscape_write(devc, i, (regs[i] & 0x3f) |
			 (sscape_read(devc, i) & 0xc0));
	    break;

	case 6:	/* CD-ROM config. Don't touch. */
	    break;

	case 9:	/* Master control reg. Don't modify CR-ROM
		 * bits. Disable SB emul */
	    sscape_write(devc, i, (sscape_read(devc, i) & 0xf0) | 0x00);
	    break;

	default:
	    sscape_write(devc, i, regs[i]);
	}

    splx(flags);

#ifdef SSCAPE_DEBUG2
    /*
     * Temporary debugging aid. Print contents of the registers after
     * changing them.
     */
    {
	int             i;

	for (i = 0; i < 13; i++)
	    printf("I%d = %02x (new value)\n", i, sscape_read(devc, i));
    }
#endif

#if defined(CONFIG_MIDI) && defined(CONFIG_MPU_EMU)
    if (probe_mpu401(hw_config))
	hw_config->always_detect = 1;
    {
	int             prev_devs;

	prev_devs = num_midis;
	attach_mpu401(hw_config);

	if (num_midis == (prev_devs + 1))	/* The MPU driver
						 * installed itself */
	    midi_devs[prev_devs]->coproc = &sscape_coproc_operations;
    }
#endif

#ifndef EXCLUDE_NATIVE_PCM
    /* Not supported yet */

#ifdef CONFIG_AUDIO
    if (num_audiodevs < MAX_AUDIO_DEV) {
	int my_dev;

	audio_devs[my_dev = num_audiodevs++] = &sscape_audio_operations;
	audio_devs[my_dev]->dmachan1 = hw_config->dma;
	audio_devs[my_dev]->buffsize = DSP_BUFFSIZE;
	audio_devs[my_dev]->devc = devc;
	devc->my_audiodev = my_dev;
	devc->opened = 0;
	audio_devs[my_dev]->coproc = &sscape_coproc_operations;
	if (snd_set_irq_handler(hw_config->irq, sscapeintr, devc->osp) < 0)
	    printf("Error: Can't allocate IRQ for SoundScape\n");
	sscape_write(devc, GA_INTENA_REG, 0x80);	/* Master IRQ enable */
    } else
	printf("SoundScape: More than enough audio devices detected\n");
#endif
#endif
    devc->ok = 1;
    devc->failed = 0;
    return;
}
Пример #11
0
/*
** Remove a member from a group.  This is a separate function because
** it is called from ppad_printer.c when a printer is deleted and
** it is the member of a group.
**
** sucess:		EXIT_OK
** bad group:	EXIT_BADDEST
** bad member:	EXIT_NOTFOUND
*/
int group_remove_internal(const char *group, const char *member)
	{
	char *ptr;
	int found = FALSE;
	void *qobj = NULL;

	if(grpopen(group, TRUE, FALSE))
		return EXIT_BADDEST;

	gu_Try
		{
		qobj = queueinfo_new(QUEUEINFO_GROUP, group);
		queueinfo_set_warnings_file(qobj, errors);
		queueinfo_set_debug_level(qobj, debug_level);

		/*
		** Copy the configuration file.
		*/
		while(confread())
			{
			if(lmatch(confline, "DefFiltOpts:"))		/* delete old lines */
				continue;
	
			if(lmatch(confline, "Printer:"))			/* if member name, */
				{
				ptr = &confline[8];
				ptr += strspn(ptr, " \t");
	
				if(strcmp(ptr,member)==0)				/* If it is the one we */
					{									/* are deleting, */
					found=TRUE;							/* set a flag */
					continue;							/* and don't copy. */
					}
	
				queueinfo_add_printer(qobj, ptr);		/* Otherwise, add its PPD file, */
				}
	
			conf_printf("%s\n",confline);
			}

		/* Emmit the new "DefFiltOpts:" line. */
		{
		const char *cp = queueinfo_computedDefaultFilterOptions(qobj);
		if(cp)
			conf_printf("DefFiltOpts: %s\n", cp);
		}

		confclose();
		}
	gu_Final
		{
		if(qobj)
			queueinfo_free(qobj);
		}
	gu_Catch
		{
		confabort();
		fprintf(errors, "%s: %s\n", myname, gu_exception);
		return exception_to_exitcode(gu_exception_code);
		}

	if(found)
		{
		reread_group(group);
		return EXIT_OK;
		}
	else
		{
		return EXIT_NOTFOUND;
		}
	} /* end of _group_remove() */
Пример #12
0
/*
** Add a member to a group, creating the group if
** it does not already exist.
*/
int group_members_add(const char *argv[], gu_boolean do_add)
	{
	const char *group = argv[0];
	int x;
	char *ptr;
	int count = 0;
	void *qobj = NULL;

	if( ! am_administrator() )
		return EXIT_DENIED;

	if(do_add)
		{
		if(! group || ! argv[1])
			{
			fputs(_("You must specify a new or existing group and one or more printers\n"
				"to add to it.\n"), errors);
			return EXIT_SYNTAX;
			}
		}
	else
		{
		if(!group)
			{
			fputs(_("You must specify a new or existing group and zero or more printers\n"
				"to be its members.\n"), errors);
			return EXIT_SYNTAX;
			}
		}

	if(strlen(group) > MAX_DESTNAME)
		{
		fputs(_("Group name is too long.\n"), errors);
		return EXIT_SYNTAX;
		}

	if(strpbrk(group, DEST_DISALLOWED))
		{
		fputs(_("Group name contains a disallowed character.\n"), errors);
		return EXIT_SYNTAX;
		}

	if(strchr(DEST_DISALLOWED_LEADING, (int)group[0]))
		{
		fputs(_("Group name begins with a disallowed character.\n"), errors);
		return EXIT_SYNTAX;
		}

	/*
	** Make sure the proposed new members really exist.
	** We do this by trying to open their configuration files
	** with prnopen().
	*/
	for(x=1; argv[x]; x++)
		{
		if(prnopen(argv[x], FALSE))
			{
			fprintf(errors, _("The printer \"%s\" does not exist.\n"), argv[x]);
			return EXIT_BADDEST;
			}
		else
			{
			confclose();
			}
		}

	/*
	** If the group to which we are adding a printer
	** does not exist, create it.
	*/
	if(grpopen(group, TRUE, TRUE))
		return EXIT_INTERNAL;

	/* Copy up to but not including the 1st "Printer:" line. */
	while(confread())
		{
		if(lmatch(confline, "DefFiltOpts:"))		/* discard */
			continue;
		if(lmatch(confline, "Printer:"))			/* stop */
			break;
		conf_printf("%s\n", confline);				/* copy */
		}

	gu_Try
		{
		qobj = queueinfo_new(QUEUEINFO_GROUP, group);
		queueinfo_set_warnings_file(qobj, errors);
		queueinfo_set_debug_level(qobj, debug_level);

		/* Copy all the remaining lines. */
		do	{
			if((ptr = lmatchp(confline, "Printer:")))
				{
				if(!do_add)				/* If we are adding, just delete it. */
					continue;

				for(x=1; argv[x]; x++)	/* Is this the same as one we are adding? */
					{
					if(strcmp(ptr, argv[x]) == 0)
						gu_Throw(_("%d Printer \"%s\" is already a member of \"%s\".\n"), EXIT_ALREADY, argv[x], group);
					queueinfo_add_printer(qobj, ptr);
					count++;
					}
				}

			/* Delete old "DefFiltOpts:" lines as we go. */
			else if(lmatch(confline, "DefFiltOpts:"))
				continue;

			/* Other lines we keep. */
			conf_printf("%s\n", confline);
			} while(confread());

		/* Add a "Printer:" line for each new member. */
		for(x=1; argv[x]; x++)
			{
			conf_printf("Printer: %s\n", argv[x]);
			queueinfo_add_printer(qobj, argv[x]);
			count++;
			}

		/* Emmit the new "DefFiltOpts:" line. */
		{
		const char *cp = queueinfo_computedDefaultFilterOptions(qobj);
		if(cp)
			conf_printf("DefFiltOpts: %s\n", cp);
		}

		/* See if adding our printer will make the group too big. */
		if(count > MAX_GROUPSIZE)
			gu_Throw(_("%d Group \"%s\" would have %d members, only %d are allowed.\n"), EXIT_OVERFLOW, group, count, MAX_GROUPSIZE);

		/* Commit the changes. */
		confclose();
		}
	gu_Final
		{
		if(qobj)
			queueinfo_free(qobj);
		}
	gu_Catch
		{
		confabort();		/* roll back the changes */
		fprintf(errors, "%s: %s\n", myname, gu_exception);
		return exception_to_exitcode(gu_exception_code);
		}

	/* necessary because pprd keeps track of mounted media */
	reread_group(group);

	return EXIT_OK;
	} /* end of group_add() */
Пример #13
0
/*
 * Install OPL3-SA2 based card(s).
 *
 * Need to have ad1848 and mpu401 loaded ready.
 */
static int __init init_opl3sa2(void)
{
        int card;
	int max;

	/* Sanitize isapnp and multiple settings */
	isapnp = isapnp != 0 ? 1 : 0;
	multiple = multiple != 0 ? 1 : 0;
	
	max = (multiple && isapnp) ? OPL3SA2_CARDS_MAX : 1;
	for(card = 0; card < max; card++, opl3sa2_cards_num++) {
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
		/*
		 * Please remember that even with CONFIG_ISAPNP defined one
		 * should still be able to disable PNP support for this 
		 * single driver!
		 */
		if(isapnp && opl3sa2_isapnp_probe(&cfg[card],
						  &cfg_mss[card],
						  &cfg_mpu[card],
						  card) < 0) {
			if(!opl3sa2_cards_num)
				printk(KERN_INFO "opl3sa2: No PnP cards found\n");
			if(io == -1)
				break;
			isapnp=0;
			printk(KERN_INFO "opl3sa2: Search for a card at 0x%d.\n", io);
			/* Fall through */
		}
#endif
		/* If a user wants an I/O then assume they meant it */
		
		if(!isapnp) {
			if(io == -1 || irq == -1 || dma == -1 ||
			   dma2 == -1 || mss_io == -1) {
				printk(KERN_ERR
				       "opl3sa2: io, mss_io, irq, dma, and dma2 must be set\n");
				return -EINVAL;
			}

			/*
			 * Our own config:
			 * (NOTE: IRQ and DMA aren't used, so they're set to
			 *  give pretty output from conf_printf. :)
			 */
			cfg[card].io_base = io;
			cfg[card].irq     = irq;
			cfg[card].dma     = dma;
			cfg[card].dma2    = dma2;
	
			/* The MSS config: */
			cfg_mss[card].io_base      = mss_io;
			cfg_mss[card].irq          = irq;
			cfg_mss[card].dma          = dma;
			cfg_mss[card].dma2         = dma2;
			cfg_mss[card].card_subtype = 1; /* No IRQ or DMA setup */

			cfg_mpu[card].io_base       = mpu_io;
			cfg_mpu[card].irq           = irq;
			cfg_mpu[card].dma           = -1;
			cfg_mpu[card].always_detect = 1; /* Use shared IRQs */

			/* Call me paranoid: */
			opl3sa2_clear_slots(&cfg[card]);
			opl3sa2_clear_slots(&cfg_mss[card]);
			opl3sa2_clear_slots(&cfg_mpu[card]);
		}

		if(!probe_opl3sa2(&cfg[card], card) ||
		   !probe_opl3sa2_mss(&cfg_mss[card])) {
			/*
			 * If one or more cards are already registered, don't
			 * return an error but print a warning.  Note, this
			 * should never really happen unless the hardware or
			 * ISA PnP screwed up.
			 */
			if(opl3sa2_cards_num) {
				printk(KERN_WARNING
				       "opl3sa2: There was a problem probing one "
				       " of the ISA PNP cards, continuing\n");
				opl3sa2_cards_num--;
				continue;
			} else
				return -ENODEV;
		}

		attach_opl3sa2(&cfg[card], card);
		conf_printf(chipset_name[card], &cfg[card]);
		attach_opl3sa2_mss(&cfg_mss[card]);
		attach_opl3sa2_mixer(&cfg[card], card);

		/*
		 * Set the Yamaha 3D enhancement mode (aka Ymersion) if asked to and
		 * it's supported.
		 */
		if(ymode != -1) {
			if(chipset[card] == CHIPSET_OPL3SA2) {
				printk(KERN_ERR
				       "opl3sa2: ymode not supported on OPL3-SA2\n");
			}
			else {
				opl3sa2_set_ymode(&cfg[card], ymode);
			}
		}


		/* Set A/D input to Mono loopback if asked to. */
		if(loopback != -1) {
			opl3sa2_set_loopback(&cfg[card], loopback);
		}
		
		/* Attach MPU if we've been asked to do so */
		if(cfg_mpu[card].io_base != -1) {
			if(probe_opl3sa2_mpu(&cfg_mpu[card])) {
				attach_opl3sa2_mpu(&cfg_mpu[card]);
			}
		}
	}

	if(isapnp) {
		printk(KERN_NOTICE "opl3sa2: %d PnP card(s) found.\n", opl3sa2_cards_num);
	}

	return 0;
}