int smapi_set_DSP_cfg()

in mwave/smapi.c [204:495]


int smapi_set_DSP_cfg(void)
{
	int bRC = -EIO;
	int i;
	unsigned short usAX, usBX, usCX, usDX, usDI, usSI;
	static const unsigned short ausDspBases[] = {
		0x0030, 0x4E30, 0x8E30, 0xCE30,
		0x0130, 0x0350, 0x0070, 0x0DB0 };
	static const unsigned short ausUartBases[] = {
		0x03F8, 0x02F8, 0x03E8, 0x02E8 };
	static const unsigned short ausDspIrqs[] = {
		5, 7, 10, 11, 15 };
	static const unsigned short ausUartIrqs[] = {
		3, 4 };

	unsigned short dspio_index = 0, uartio_index = 0;

	PRINTK_5(TRACE_SMAPI,
		"smapi::smapi_set_DSP_cfg entry mwave_3780i_irq %x mwave_3780i_io %x mwave_uart_irq %x mwave_uart_io %x\n",
		mwave_3780i_irq, mwave_3780i_io, mwave_uart_irq, mwave_uart_io);

	if (mwave_3780i_io) {
		for (i = 0; i < ARRAY_SIZE(ausDspBases); i++) {
			if (mwave_3780i_io == ausDspBases[i])
				break;
		}
		if (i == ARRAY_SIZE(ausDspBases)) {
			PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_3780i_io address %x. Aborting.\n", mwave_3780i_io);
			return bRC;
		}
		dspio_index = i;
	}

	if (mwave_3780i_irq) {
		for (i = 0; i < ARRAY_SIZE(ausDspIrqs); i++) {
			if (mwave_3780i_irq == ausDspIrqs[i])
				break;
		}
		if (i == ARRAY_SIZE(ausDspIrqs)) {
			PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_3780i_irq %x. Aborting.\n", mwave_3780i_irq);
			return bRC;
		}
	}

	if (mwave_uart_io) {
		for (i = 0; i < ARRAY_SIZE(ausUartBases); i++) {
			if (mwave_uart_io == ausUartBases[i])
				break;
		}
		if (i == ARRAY_SIZE(ausUartBases)) {
			PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_uart_io address %x. Aborting.\n", mwave_uart_io);
			return bRC;
		}
		uartio_index = i;
	}


	if (mwave_uart_irq) {
		for (i = 0; i < ARRAY_SIZE(ausUartIrqs); i++) {
			if (mwave_uart_irq == ausUartIrqs[i])
				break;
		}
		if (i == ARRAY_SIZE(ausUartIrqs)) {
			PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_uart_irq %x. Aborting.\n", mwave_uart_irq);
			return bRC;
		}
	}

	if (mwave_uart_irq || mwave_uart_io) {

		/* Check serial port A */
		bRC = smapi_request(0x1402, 0x0000, 0, 0,
			&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
		if (bRC) goto exit_smapi_request_error;
		/* bRC == 0 */
		if (usBX & 0x0100) {	/* serial port A is present */
			if (usCX & 1) {	/* serial port is enabled */
				if ((usSI & 0xFF) == mwave_uart_irq) {
#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
					PRINTK_ERROR(KERN_ERR_MWAVE
						"smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
#else
					PRINTK_3(TRACE_SMAPI,
						"smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
#endif
#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
					PRINTK_1(TRACE_SMAPI,
						"smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n");
					bRC = smapi_request(0x1403, 0x0100, 0, usSI,
						&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
					if (bRC) goto exit_smapi_request_error;
					bRC = smapi_request(0x1402, 0x0000, 0, 0,
						&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
					if (bRC) goto exit_smapi_request_error;
#else
					goto exit_conflict;
#endif
				} else {
					if ((usSI >> 8) == uartio_index) {
#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
						PRINTK_ERROR(KERN_ERR_MWAVE
							"smapi::smapi_set_DSP_cfg: Serial port A base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI >> 8], ausUartBases[uartio_index]);
#else
						PRINTK_3(TRACE_SMAPI,
							"smapi::smapi_set_DSP_cfg: Serial port A base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI >> 8], ausUartBases[uartio_index]);
#endif
#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
						PRINTK_1(TRACE_SMAPI,
							"smapi::smapi_set_DSP_cfg Disabling conflicting serial port A\n");
						bRC = smapi_request (0x1403, 0x0100, 0, usSI,
							&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
						if (bRC) goto exit_smapi_request_error;
						bRC = smapi_request (0x1402, 0x0000, 0, 0,
							&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
						if (bRC) goto exit_smapi_request_error;
#else
						goto exit_conflict;
#endif
					}
				}
			}
		}

		/* Check serial port B */
		bRC = smapi_request(0x1404, 0x0000, 0, 0,
			&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
		if (bRC) goto exit_smapi_request_error;
		/* bRC == 0 */
		if (usBX & 0x0100) {	/* serial port B is present */
			if (usCX & 1) {	/* serial port is enabled */
				if ((usSI & 0xFF) == mwave_uart_irq) {
#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
					PRINTK_ERROR(KERN_ERR_MWAVE
						"smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
#else
					PRINTK_3(TRACE_SMAPI,
						"smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
#endif
#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
					PRINTK_1(TRACE_SMAPI,
						"smapi::smapi_set_DSP_cfg Disabling conflicting serial port B\n");
					bRC = smapi_request(0x1405, 0x0100, 0, usSI,
						&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
					if (bRC) goto exit_smapi_request_error;
					bRC = smapi_request(0x1404, 0x0000, 0, 0,
						&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
					if (bRC) goto exit_smapi_request_error;
#else
					goto exit_conflict;
#endif
				} else {
					if ((usSI >> 8) == uartio_index) {
#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
						PRINTK_ERROR(KERN_ERR_MWAVE
							"smapi::smapi_set_DSP_cfg: Serial port B base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI >> 8], ausUartBases[uartio_index]);
#else
						PRINTK_3(TRACE_SMAPI,
							"smapi::smapi_set_DSP_cfg: Serial port B base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI >> 8], ausUartBases[uartio_index]);
#endif
#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
						PRINTK_1 (TRACE_SMAPI,
						    "smapi::smapi_set_DSP_cfg Disabling conflicting serial port B\n");
						bRC = smapi_request (0x1405, 0x0100, 0, usSI,
							&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
						if (bRC) goto exit_smapi_request_error;
						bRC = smapi_request (0x1404, 0x0000, 0, 0,
							&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
						if (bRC) goto exit_smapi_request_error;
#else
						goto exit_conflict;
#endif
					}
				}
			}
		}

		/* Check IR port */
		bRC = smapi_request(0x1700, 0x0000, 0, 0,
			&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
		if (bRC) goto exit_smapi_request_error;
		bRC = smapi_request(0x1704, 0x0000, 0, 0,
			&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
		if (bRC) goto exit_smapi_request_error;
		/* bRC == 0 */
		if ((usCX & 0xff) != 0xff) { /* IR port not disabled */
			if ((usCX & 0xff) == mwave_uart_irq) {
#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
				PRINTK_ERROR(KERN_ERR_MWAVE
					"smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usCX & 0xff, mwave_uart_irq);
#else
				PRINTK_3(TRACE_SMAPI,
					"smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usCX & 0xff, mwave_uart_irq);
#endif
#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
				PRINTK_1(TRACE_SMAPI,
					"smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n");
				bRC = smapi_request(0x1701, 0x0100, 0, 0,
					&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
				if (bRC) goto exit_smapi_request_error;
				bRC = smapi_request(0x1700, 0, 0, 0,
					&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
				if (bRC) goto exit_smapi_request_error;
				bRC = smapi_request(0x1705, 0x01ff, 0, usSI,
					&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
				if (bRC) goto exit_smapi_request_error;
				bRC = smapi_request(0x1704, 0x0000, 0, 0,
					&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
				if (bRC) goto exit_smapi_request_error;
#else
				goto exit_conflict;
#endif
			} else {
				if ((usSI & 0xff) == uartio_index) {
#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
					PRINTK_ERROR(KERN_ERR_MWAVE
						"smapi::smapi_set_DSP_cfg: IR port base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI & 0xff], ausUartBases[uartio_index]);
#else
					PRINTK_3(TRACE_SMAPI,
						"smapi::smapi_set_DSP_cfg: IR port base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI & 0xff], ausUartBases[uartio_index]);
#endif
#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
					PRINTK_1(TRACE_SMAPI,
						"smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n");
					bRC = smapi_request(0x1701, 0x0100, 0, 0,
						&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
					if (bRC) goto exit_smapi_request_error;
					bRC = smapi_request(0x1700, 0, 0, 0,
						&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
					if (bRC) goto exit_smapi_request_error;
					bRC = smapi_request(0x1705, 0x01ff, 0, usSI,
						&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
					if (bRC) goto exit_smapi_request_error;
					bRC = smapi_request(0x1704, 0x0000, 0, 0,
						&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
					if (bRC) goto exit_smapi_request_error;
#else
					goto exit_conflict;
#endif
				}
			}
		}
	}

	bRC = smapi_request(0x1802, 0x0000, 0, 0,
		&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
	if (bRC) goto exit_smapi_request_error;

	if (mwave_3780i_io) {
		usDI = dspio_index;
	}
	if (mwave_3780i_irq) {
		usSI = (usSI & 0xff00) | mwave_3780i_irq;
	}

	bRC = smapi_request(0x1803, 0x0101, usDI, usSI,
		&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
	if (bRC) goto exit_smapi_request_error;

	bRC = smapi_request(0x1804, 0x0000, 0, 0,
		&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
	if (bRC) goto exit_smapi_request_error;

	if (mwave_uart_io) {
		usSI = (usSI & 0x00ff) | (uartio_index << 8);
	}
	if (mwave_uart_irq) {
		usSI = (usSI & 0xff00) | mwave_uart_irq;
	}
	bRC = smapi_request(0x1805, 0x0101, 0, usSI,
		&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
	if (bRC) goto exit_smapi_request_error;

	bRC = smapi_request(0x1802, 0x0000, 0, 0,
		&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
	if (bRC) goto exit_smapi_request_error;

	bRC = smapi_request(0x1804, 0x0000, 0, 0,
		&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
	if (bRC) goto exit_smapi_request_error;

/* normal exit: */
	PRINTK_1(TRACE_SMAPI, "smapi::smapi_set_DSP_cfg exit\n");
	return 0;

exit_conflict:
	/* Message has already been printed */
	return -EIO;

exit_smapi_request_error:
	PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg exit on smapi_request error bRC %x\n", bRC);
	return bRC;
}