📄 aztcd.c
字号:
aztSendCmd(ACMD_EJECT); CLEAR_TIMER; }#ifdef AZT_KERNEL_PRIOR_2_1 return;#else return 0;#endif}/* * Test for presence of drive and initialize it. Called at boot time. */#ifdef AZT_KERNEL_PRIOR_2_1int aztcd_init(void)#else__initfunc(int aztcd_init(void))#endif{ long int count, max_count; unsigned char result[50]; int st; int i = 0; if (azt_port == 0) { printk("aztcd: no Aztech CD-ROM Initialization"); return -EIO; } printk("aztcd: AZTECH, ORCHID, OKANO, WEARNES, TXC, CyDROM CD-ROM Driver\n"); printk("aztcd: (C) 1994-98 W.Zimmermann\n"); if (azt_port == -1) { printk("aztcd: KernelVersion=%s DriverVersion=%s For IDE/ATAPI-drives use ide-cd.c\n",UTS_RELEASE,AZT_VERSION); } else printk("aztcd: DriverVersion=%s BaseAddress=0x%x For IDE/ATAPI-drives use ide-cd.c\n",AZT_VERSION,azt_port); printk("aztcd: If you have problems, read /usr/src/linux/Documentation/cdrom/aztcd\n"); #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++); { count=count*2; /* delay a bit */ count=count/2; } 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; } } if (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_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;#ifndef AZT_KERNEL_PRIOR_2_1 blksize_size[MAJOR_NR] = aztcd_blocksizes;#endif read_ahead[MAJOR_NR] = 4; 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);}#ifdef MODULEint init_module(void){ return aztcd_init();}void cleanup_module(void){ if ((unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL)) { printk("What's that: can't unregister aztcd\n"); return; } 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");} #endif MODULE/*########################################################################## 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*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -