aztcd.c
字号:
printk(KERN_WARNING "aztcd: no AZTECH " "CD-ROM drive found\n"); ret = -EIO; goto err_out; } for (count = 0; count < AZT_TIMEOUT; count++) barrier(); /* Stop gcc 2.96 being smart */ /* use udelay(), damnit -- AV */ if ((st = getAztStatus()) == -1) { printk(KERN_WARNING "aztcd: Drive Status" " Error Status=%x\n", st); ret = -EIO; goto err_out; }#ifdef AZT_DEBUG printk(KERN_DEBUG "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"); ret = -EIO; goto err_out; } } azt_disk = alloc_disk(1); if (!azt_disk) goto err_out; if (register_blkdev(MAJOR_NR, "aztcd")) { ret = -EIO; goto err_out2; } azt_queue = blk_init_queue(do_aztcd_request, &aztSpin); if (!azt_queue) { ret = -ENOMEM; goto err_out3; } blk_queue_hardsect_size(azt_queue, 2048); azt_disk->major = MAJOR_NR; azt_disk->first_minor = 0; azt_disk->fops = &azt_fops; sprintf(azt_disk->disk_name, "aztcd"); sprintf(azt_disk->devfs_name, "aztcd"); azt_disk->queue = azt_queue; add_disk(azt_disk); azt_invalidate_buffers(); aztPresent = 1; aztCloseDoor(); return 0;err_out3: unregister_blkdev(MAJOR_NR, "aztcd");err_out2: put_disk(azt_disk);err_out: 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 */ return ret;}static void __exit aztcd_exit(void){ del_gendisk(azt_disk); put_disk(azt_disk); if ((unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL)) { printk("What's that: can't unregister aztcd\n"); return; } blk_cleanup_queue(azt_queue); 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");}module_init(aztcd_init);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(CURRENT, 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(CURRENT, 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(CURRENT, 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(CURRENT, 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(CURRENT, 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(CURRENT, 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(CURRENT, 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, CURRENT->nr_sectors, azt_buf_in); printk ("azt_transfer_is_active:%x\n", azt_transfer_is_active); azt_read_count =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -