📄 aztcd.c
字号:
#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 MODULEmodule_init(aztcd_init);#endifmodule_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_MODE_2) { sendAztCmd(ACMD_PLAY_READ_RAW, &msf); /*XA disks in raw mode */ } else { sendAztCmd(ACMD_PLAY_READ, &msf); /*others in cooked mode */ } azt_state = AZT_S_DATA; AztTimeout = READ_TIMEOUT; } else { azt_state = AZT_S_STOP; loop_ctl = 1; break; } break; case AZT_S_DATA:#ifdef AZT_TEST3 if (azt_state != azt_state_old) { azt_state_old = azt_state; printk("AZT_S_DATA\n"); }#endif st = inb(STATUS_PORT) & AFL_STATUSorDATA; switch (st) { case AFL_DATA:#ifdef AZT_TEST3 if (st != azt_st_old) { azt_st_old = st; printk("---AFL_DATA st:%x\n", st); }#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; break; } if (CURRENT_VALID) end_request(0); AztTries = 5; } azt_state = AZT_S_START; AztTimeout = READ_TIMEOUT; loop_ctl = 1; break; case AFL_STATUSorDATA:#ifdef AZT_TEST3 if (st != azt_st_old) { azt_st_old = st; printk ("---AFL_STATUSorDATA st:%x\n", st); }#endif break; default:#ifdef AZT_TEST3 if (st != azt_st_old) { azt_st_old = st; printk("---default: st:%x\n", st); }#endif AztTries = 5; if (!CURRENT_VALID && azt_buf_in == azt_buf_out) { azt_state = AZT_S_STOP; loop_ctl = 1; break; } if (azt_read_count <= 0) printk ("aztcd: warning - try to read 0 frames\n"); while (azt_read_count) { /*??? fast read ahead loop */ azt_buf_bn[azt_buf_in] = -1; DTEN_LOW; /*??? unsolved problem, very seldom we get timeouts here, don't now the real reason. With my drive this sometimes also happens with Aztech's original driver under DOS. Is it a hardware bug? I tried to recover from such situations here. Zimmermann */ if (aztTimeOutCount >= AZT_TIMEOUT) { printk ("read_count:%d CURRENT->nr_sectors:%ld azt_buf_in:%d\n", azt_read_count,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -