⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aztcd.c

📁 cdrom device drive for linux.
💻 C
📖 第 1 页 / 共 5 页
字号:

#ifdef AZT_SW32			/*CDROM connected to Soundwave32 card */
	if ((0xFF00 & inw(AZT_SW32_ID_REG)) != 0x4500) {
		printk
		    ("aztcd: no Soundwave32 card detected at base:%x init:%x config:%x id:%x\n",
		     AZT_SW32_BASE_ADDR, AZT_SW32_INIT,
		     AZT_SW32_CONFIG_REG, AZT_SW32_ID_REG);
		return -EIO;
	} else {
		printk(KERN_INFO
		       "aztcd: Soundwave32 card detected at %x  Version %x\n",
		       AZT_SW32_BASE_ADDR, inw(AZT_SW32_ID_REG));
		outw(AZT_SW32_INIT, AZT_SW32_CONFIG_REG);
		for (count = 0; count < 10000; count++);	/*delay a bit */
	}
#endif

	/* check for presence of drive */

	if (azt_port == -1) {	/* autoprobing */
		for (i = 0; (azt_port_auto[i] != 0) && (i < 16); i++) {
			azt_port = azt_port_auto[i];
			printk("aztcd: Autoprobing BaseAddress=0x%x \n",
			       azt_port);
			st = check_region(azt_port, 4);	/*proprietary interfaces need 4 bytes */
			if (st)
				continue;

			outb(POLLED, MODE_PORT);
			inb(CMD_PORT);
			inb(CMD_PORT);
			outb(ACMD_GET_VERSION, CMD_PORT);	/*Try to get version info */

			aztTimeOutCount = 0;
			do {
				aztIndatum = inb(STATUS_PORT);
				aztTimeOutCount++;
				if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
					break;
			} while (aztIndatum & AFL_STATUS);
			if (inb(DATA_PORT) == AFL_OP_OK)
				break;
		}
		if ((azt_port_auto[i] == 0) || (i == 16)) {
			printk("aztcd: no AZTECH CD-ROM drive found\n");
			return -EIO;
		}
	} else {		/* no autoprobing */
		if ((azt_port == 0x1f0) || (azt_port == 0x170))
			st = check_region(azt_port, 8);	/*IDE-interfaces need 8 bytes */
		else
			st = check_region(azt_port, 4);	/*proprietary interfaces need 4 bytes */
		if (st) {
			printk
			    ("aztcd: conflict, I/O port (%X) already used\n",
			     azt_port);
			return -EIO;
		}

		if ((azt_port == 0x1f0) || (azt_port == 0x170))
			SWITCH_IDE_SLAVE;	/*switch IDE interface to slave configuration */

		outb(POLLED, MODE_PORT);
		inb(CMD_PORT);
		inb(CMD_PORT);
		outb(ACMD_GET_VERSION, CMD_PORT);	/*Try to get version info */

		aztTimeOutCount = 0;
		do {
			aztIndatum = inb(STATUS_PORT);
			aztTimeOutCount++;
			if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
				break;
		} while (aztIndatum & AFL_STATUS);

		if (inb(DATA_PORT) != AFL_OP_OK) {	/*OP_OK? If not, reset and try again */
#ifndef MODULE
			if (azt_cont != 0x79) {
				printk
				    ("aztcd: no AZTECH CD-ROM drive found-Try boot parameter aztcd=<BaseAddress>,0x79\n");
				return -EIO;
			}
#else
			if (0) {
			}
#endif
			else {
				printk
				    ("aztcd: drive reset - please wait\n");
				for (count = 0; count < 50; count++) {
					inb(STATUS_PORT);	/*removing all data from earlier tries */
					inb(DATA_PORT);
				}
				outb(POLLED, MODE_PORT);
				inb(CMD_PORT);
				inb(CMD_PORT);
				getAztStatus();	/*trap errors */
				outb(ACMD_SOFT_RESET, CMD_PORT);	/*send reset */
				STEN_LOW;
				if (inb(DATA_PORT) != AFL_OP_OK) {	/*OP_OK? */
					printk
					    ("aztcd: no AZTECH CD-ROM drive found\n");
					return -EIO;
				}

				for (count = 0; count < AZT_TIMEOUT;
				     count++)
					barrier();	/* Stop gcc 2.96 being smart */

				if ((st = getAztStatus()) == -1) {
					printk
					    ("aztcd: Drive Status Error Status=%x\n",
					     st);
					return -EIO;
				}
#ifdef AZT_DEBUG
				printk("aztcd: Status = %x\n", st);
#endif
				outb(POLLED, MODE_PORT);
				inb(CMD_PORT);
				inb(CMD_PORT);
				outb(ACMD_GET_VERSION, CMD_PORT);	/*GetVersion */
				STEN_LOW;
				OP_OK;
			}
		}
	}

	azt_init_end = 1;
	STEN_LOW;
	result[0] = inb(DATA_PORT);	/*reading in a null byte??? */
	for (count = 1; count < 50; count++) {	/*Reading version string */
		aztTimeOutCount = 0;	/*here we must implement STEN_LOW differently */
		do {
			aztIndatum = inb(STATUS_PORT);	/*because we want to exit by timeout */
			aztTimeOutCount++;
			if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
				break;
		} while (aztIndatum & AFL_STATUS);
		if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
			break;	/*all chars read? */
		result[count] = inb(DATA_PORT);
	}
	if (count > 30)
		max_count = 30;	/*print max.30 chars of the version string */
	else
		max_count = count;
	printk(KERN_INFO "aztcd: FirmwareVersion=");
	for (count = 1; count < max_count; count++)
		printk("%c", result[count]);
	printk("<<>> ");

	if ((result[1] == 'A') && (result[2] == 'Z') && (result[3] == 'T')) {
		printk("AZTECH drive detected\n");
	/*AZTECH*/}
		else if ((result[2] == 'C') && (result[3] == 'D')
			 && (result[4] == 'D')) {
		printk("ORCHID or WEARNES drive detected\n");	/*ORCHID or WEARNES */
	} else if ((result[1] == 0x03) && (result[2] == '5')) {
		printk("TXC or CyCDROM drive detected\n");	/*Conrad TXC, CyCDROM */
	} else {		/*OTHERS or none */
		printk("\nunknown drive or firmware version detected\n");
		printk
		    ("aztcd may not run stable, if you want to try anyhow,\n");
		printk("boot with: aztcd=<BaseAddress>,0x79\n");
		if ((azt_cont != 0x79)) {
			printk("aztcd: FirmwareVersion=");
			for (count = 1; count < 5; count++)
				printk("%c", result[count]);
			printk("<<>> ");
			printk("Aborted\n");
			return -EIO;
		}
	}
	devfs_register(NULL, "aztcd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
		       S_IFBLK | S_IRUGO | S_IWUGO, &azt_fops, NULL);
	if (devfs_register_blkdev(MAJOR_NR, "aztcd", &azt_fops) != 0) {
		printk("aztcd: Unable to get major %d for Aztech CD-ROM\n",
		       MAJOR_NR);
		return -EIO;
	}
	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
	blksize_size[MAJOR_NR] = aztcd_blocksizes;
	read_ahead[MAJOR_NR] = 4;
	register_disk(NULL, MKDEV(MAJOR_NR, 0), 1, &azt_fops, 0);

	if ((azt_port == 0x1f0) || (azt_port == 0x170))
		request_region(azt_port, 8, "aztcd");	/*IDE-interface */
	else
		request_region(azt_port, 4, "aztcd");	/*proprietary interface */

	azt_invalidate_buffers();
	aztPresent = 1;
	aztCloseDoor();
	return (0);
}

void __exit aztcd_exit(void)
{
	devfs_unregister(devfs_find_handle
			 (NULL, "aztcd", 0, 0, DEVFS_SPECIAL_BLK, 0));
	if ((devfs_unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL)) {
		printk("What's that: can't unregister aztcd\n");
		return;
	}
	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
	if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
		SWITCH_IDE_MASTER;
		release_region(azt_port, 8);	/*IDE-interface */
	} else
		release_region(azt_port, 4);	/*proprietary interface */
	printk(KERN_INFO "aztcd module released.\n");
}

#ifdef MODULE
module_init(aztcd_init);
#endif
module_exit(aztcd_exit);

/*##########################################################################
  Aztcd State Machine: Controls Drive Operating State
  ##########################################################################
*/
static void azt_poll(void)
{
	int st = 0;
	int loop_ctl = 1;
	int skip = 0;

	if (azt_error) {
		if (aztSendCmd(ACMD_GET_ERROR))
			RETURN("azt_poll 1");
		STEN_LOW;
		azt_error = inb(DATA_PORT) & 0xFF;
		printk("aztcd: I/O error 0x%02x\n", azt_error);
		azt_invalidate_buffers();
#ifdef WARN_IF_READ_FAILURE
		if (AztTries == 5)
			printk
			    ("aztcd: Read of Block %d Failed - Maybe Audio Disk?\n",
			     azt_next_bn);
#endif
		if (!AztTries--) {
			printk
			    ("aztcd: Read of Block %d Failed, Maybe Audio Disk? Giving up\n",
			     azt_next_bn);
			if (azt_transfer_is_active) {
				AztTries = 0;
				loop_ctl = 0;
			}
			if (CURRENT_VALID)
				end_request(0);
			AztTries = 5;
		}
		azt_error = 0;
		azt_state = AZT_S_STOP;
	}

	while (loop_ctl) {
		loop_ctl = 0;	/* each case must flip this back to 1 if we want
				   to come back up here */
		switch (azt_state) {

		case AZT_S_IDLE:
#ifdef AZT_TEST3
			if (azt_state != azt_state_old) {
				azt_state_old = azt_state;
				printk("AZT_S_IDLE\n");
			}
#endif
			return;

		case AZT_S_START:
#ifdef AZT_TEST3
			if (azt_state != azt_state_old) {
				azt_state_old = azt_state;
				printk("AZT_S_START\n");
			}
#endif
			if (aztSendCmd(ACMD_GET_STATUS))
				RETURN("azt_poll 2");	/*result will be checked by aztStatus() */
			azt_state =
			    azt_mode == 1 ? AZT_S_READ : AZT_S_MODE;
			AztTimeout = 3000;
			break;

		case AZT_S_MODE:
#ifdef AZT_TEST3
			if (azt_state != azt_state_old) {
				azt_state_old = azt_state;
				printk("AZT_S_MODE\n");
			}
#endif
			if (!skip) {
				if ((st = aztStatus()) != -1) {
					if ((st & AST_DSK_CHG)
					    || (st & AST_NOT_READY)) {
						aztDiskChanged = 1;
						aztTocUpToDate = 0;
						azt_invalidate_buffers();
						end_request(0);
						printk
						    ("aztcd: Disk Changed or Not Ready 1 - Unmount Disk!\n");
					}
				} else
					break;
			}
			skip = 0;

			if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
				aztDiskChanged = 1;
				aztTocUpToDate = 0;
				printk
				    ("aztcd: Disk Changed or Not Ready 2 - Unmount Disk!\n");
				end_request(0);
				printk((st & AST_DOOR_OPEN) ?
				       "aztcd: door open\n" :
				       "aztcd: disk removed\n");
				if (azt_transfer_is_active) {
					azt_state = AZT_S_START;
					loop_ctl = 1;	/* goto immediately */
					break;
				}
				azt_state = AZT_S_IDLE;
				while (CURRENT_VALID)
					end_request(0);
				return;
			}

/*	  if (aztSendCmd(ACMD_SET_MODE)) RETURN("azt_poll 3");
	  outb(0x01, DATA_PORT);          
	  PA_OK;
	  STEN_LOW;
*/
			if (aztSendCmd(ACMD_GET_STATUS))
				RETURN("azt_poll 4");
			STEN_LOW;
			azt_mode = 1;
			azt_state = AZT_S_READ;
			AztTimeout = 3000;

			break;


		case AZT_S_READ:
#ifdef AZT_TEST3
			if (azt_state != azt_state_old) {
				azt_state_old = azt_state;
				printk("AZT_S_READ\n");
			}
#endif
			if (!skip) {
				if ((st = aztStatus()) != -1) {
					if ((st & AST_DSK_CHG)
					    || (st & AST_NOT_READY)) {
						aztDiskChanged = 1;
						aztTocUpToDate = 0;
						azt_invalidate_buffers();
						printk
						    ("aztcd: Disk Changed or Not Ready 3 - Unmount Disk!\n");
						end_request(0);
					}
				} else
					break;
			}

			skip = 0;
			if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
				aztDiskChanged = 1;
				aztTocUpToDate = 0;
				printk((st & AST_DOOR_OPEN) ?
				       "aztcd: door open\n" :
				       "aztcd: disk removed\n");
				if (azt_transfer_is_active) {
					azt_state = AZT_S_START;
					loop_ctl = 1;
					break;
				}
				azt_state = AZT_S_IDLE;
				while (CURRENT_VALID)
					end_request(0);
				return;
			}

			if (CURRENT_VALID) {
				struct azt_Play_msf msf;
				int i;
				azt_next_bn = CURRENT->sector / 4;
				azt_hsg2msf(azt_next_bn, &msf.start);
				i = 0;
				/* find out in which track we are */
				while (azt_msf2hsg(&msf.start) >
				       azt_msf2hsg(&Toc[++i].trackTime)) {
				};
				if (azt_msf2hsg(&msf.start) <
				    azt_msf2hsg(&Toc[i].trackTime) -
				    AZT_BUF_SIZ) {
					azt_read_count = AZT_BUF_SIZ;	/*fast, because we read ahead */
					/*azt_read_count=CURRENT->nr_sectors;    slow, no read ahead */
				} else	/* don't read beyond end of track */
#if AZT_MULTISESSION
				{
					azt_read_count =
					    (azt_msf2hsg(&Toc[i].trackTime)
					     / 4) * 4 -
					    azt_msf2hsg(&msf.start);
					if (azt_read_count < 0)
						azt_read_count = 0;
					if (azt_read_count > AZT_BUF_SIZ)
						azt_read_count =
						    AZT_BUF_SIZ;
					printk
					    ("aztcd: warning - trying to read beyond end of track\n");
/*               printk("%i %i %li %li\n",i,azt_read_count,azt_msf2hsg(&msf.start),azt_msf2hsg(&Toc[i].trackTime));
*/ }
#else
				{
					azt_read_count = AZT_BUF_SIZ;
				}
#endif
				msf.end.min = 0;
				msf.end.sec = 0;
				msf.end.frame = azt_read_count;	/*Mitsumi here reads 0xffffff sectors */
#ifdef AZT_TEST3
				printk
				    ("---reading msf-address %x:%x:%x  %x:%x:%x\n",
				     msf.start.min, msf.start.sec,
				     msf.start.frame, msf.end.min,
				     msf.end.sec, msf.end.frame);
				printk
				    ("azt_next_bn:%x  azt_buf_in:%x azt_buf_out:%x  azt_buf_bn:%x\n",
				     azt_next_bn, azt_buf_in, azt_buf_out,
				     azt_buf_bn[azt_buf_in]);
#endif
				if (azt_read_mode == AZT

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -