📄 aztcd.c
字号:
#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 + -