📄 gscd.c
字号:
/* check the unit */ /* and wake it up */ if ( cmd_unit_alive () != 0x08 ) { /* LOC_174 */ /* game over for this unit */ disk_state = ST_x08 | ST_x04 | ST_INVALID; return; } /* LOC_176 */ #ifdef GSCD_DEBUG printk ("LOC_176 "); #endif if ( drv_mode == 0x09 ) { /* magic... */ printk ("GSCD: magic ...\n"); outb ( result, GSCDPORT(2)); } /* write the command to the drive */ cmd_write_cmd (cmd); /* LOC_178 */ for (;;) { result = wait_drv_ready (); if ( result != drv_mode ) { /* LOC_179 */ if ( result == 0x04 ) /* Mode 4 */ { /* LOC_205 */ #ifdef GSCD_DEBUG printk ("LOC_205 "); #endif disk_state = inb ( GSCDPORT (2)); do { result = wait_drv_ready (); } while ( result != drv_mode ); return; } else { if ( result == 0x06 ) /* Mode 6 */ { /* LOC_181 */ #ifdef GSCD_DEBUG printk ("LOC_181 "); #endif if (cmd_type == TYPE_DATA) { /* read data */ /* LOC_184 */ if ( drv_mode == 9 ) { /* read the data to the buffer (word) */ /* (*(cmd+1))?(CD_FRAMESIZE/2):(CD_FRAMESIZE_RAW/2) */ cmd_read_w ( respo_buf, respo_count, CD_FRAMESIZE/2 ); return; } else { /* read the data to the buffer (byte) */ /* (*(cmd+1))?(CD_FRAMESIZE):(CD_FRAMESIZE_RAW) */ cmd_read_b ( respo_buf, respo_count, CD_FRAMESIZE ); return; } } else { /* read the info to the buffer */ cmd_info_in ( respo_buf, respo_count ); return; } return; } } } else { disk_state = ST_x08 | ST_x04 | ST_INVALID; return; } } /* for (;;) */#ifdef GSCD_DEBUGprintk ("\n"); #endif }static void cmd_write_cmd ( char *pstr ){int i,j; /* LOC_177 */ #ifdef GSCD_DEBUG printk ("LOC_177 "); #endif /* calculate the number of parameter */ j = *pstr & 0x0F; /* shift it out */ for ( i=0 ; i<j ; i++ ) { outb ( *pstr, GSCDPORT(2) ); pstr++; }}static int cmd_unit_alive ( void ){int result;unsigned long max_test_loops; /* LOC_172 */ #ifdef GSCD_DEBUG printk ("LOC_172 "); #endif outb ( curr_drv_state, GSCDPORT(0)); max_test_loops = 0xFFFF; do { result = wait_drv_ready (); max_test_loops--; } while ( (result != 0x08) && (max_test_loops > 0) ); return result;} static void cmd_info_in ( char *pb, int count ){int result;char read; /* read info */ /* LOC_182 */ #ifdef GSCD_DEBUG printk ("LOC_182 "); #endif do { read = inb (GSCDPORT(2)); if ( count > 0 ) { *pb = read; pb++; count--; } /* LOC_183 */ do { result = wait_drv_ready (); } while ( result == 0x0E ); } while ( result == 6 ); cmd_end (); return;}static void cmd_read_b ( char *pb, int count, int size ){int result;int i; /* LOC_188 */ /* LOC_189 */ #ifdef GSCD_DEBUG printk ("LOC_189 "); #endif do { do { result = wait_drv_ready (); } while ( result != 6 || result == 0x0E ); if ( result != 6 ) { cmd_end (); return; } #ifdef GSCD_DEBUG printk ("LOC_191 "); #endif for ( i=0 ; i< size ; i++ ) { *pb = inb (GSCDPORT(2)); pb++; } count--; } while ( count > 0 ); cmd_end (); return;}static void cmd_end (void){int result; /* LOC_204 */ #ifdef GSCD_DEBUG printk ("LOC_204 "); #endif do { result = wait_drv_ready (); if ( result == drv_mode ) { return; } } while ( result != 4 ); /* LOC_205 */ #ifdef GSCD_DEBUG printk ("LOC_205 "); #endif disk_state = inb ( GSCDPORT (2)); do { result = wait_drv_ready (); } while ( result != drv_mode ); return;}static void cmd_read_w ( char *pb, int count, int size ){int result;int i; #ifdef GSCD_DEBUG printk ("LOC_185 "); #endif do { /* LOC_185 */ do { result = wait_drv_ready (); } while ( result != 6 || result == 0x0E ); if ( result != 6 ) { cmd_end (); return; } for ( i=0 ; i<size ; i++ ) { /* na, hier muss ich noch mal drueber nachdenken */ *pb = inw(GSCDPORT(2)); pb++; } count--; } while ( count > 0 ); cmd_end (); return;}__initfunc(int find_drives (void)){int *pdrv;int drvnum;int subdrv;int i; speed = 0; pdrv = (int *)&drv_states; curr_drv_state = 0xFE; subdrv = 0; drvnum = 0; for ( i=0 ; i<8 ; i++ ) { subdrv++; cmd_status (); disk_state &= ST_x08 | ST_x04 | ST_INVALID | ST_x01; if ( disk_state != (ST_x08 | ST_x04 | ST_INVALID) ) { /* LOC_240 */ *pdrv = curr_drv_state; init_cd_drive (drvnum); pdrv++; drvnum++; } else { if ( subdrv < 2 ) { continue; } else { subdrv = 0; } } /* curr_drv_state<<1; <-- das geht irgendwie nicht */ /* muss heissen: curr_drv_state <<= 1; (ist ja Wert-Zuweisung) */ curr_drv_state *= 2; curr_drv_state |= 1;#ifdef GSCD_DEBUG printk ("DriveState: %d\n", curr_drv_state );#endif } ndrives = drvnum; return drvnum;} __initfunc(void init_cd_drive ( int num )){char resp [50];int i; printk ("GSCD: init unit %d\n", num ); cc_Ident ((char *)&resp); printk ("GSCD: identification: "); for ( i=0 ; i<0x1E; i++ ) { printk ( "%c", resp[i] ); } printk ("\n"); cc_SetSpeed (); } #ifdef FUTURE_WORK/* return_done */static void update_state ( void ){unsigned int AX; if ( (disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0 ) { if ( disk_state == (ST_x08 | ST_x04 | ST_INVALID)) { AX = ST_INVALID; } if ( (disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0 ) { invalidate (); f_drv_ok = 0; } AX |= 0x8000; } if ( disk_state & ST_PLAYING ) { AX |= 0x200; } AX |= 0x100; /* pkt_esbx = AX; */ disk_state = 0; }#endif#ifdef MODULE/* Init for the Module-Version */int init_module (void){long err; /* call the GoldStar-init */ err = my_gscd_init ( ); if ( err < 0 ) { return err; } else { printk (KERN_INFO "Happy GoldStar !\n" ); return 0; } }void cleanup_module (void){ if ((unregister_blkdev(MAJOR_NR, "gscd" ) == -EINVAL)) { printk("What's that: can't unregister GoldStar-module\n" ); return; } release_region (gscd_port,4); printk(KERN_INFO "GoldStar-module released.\n" );}#endif/* Test for presence of drive and initialize it. Called only at boot time. */__initfunc(int gscd_init (void)){ return my_gscd_init ();}/* This is the common initialisation for the GoldStar drive. *//* It is called at boot time AND for module init. */__initfunc(int my_gscd_init (void)){int i;int result; printk (KERN_INFO "GSCD: version %s\n", GSCD_VERSION); printk (KERN_INFO "GSCD: Trying to detect a Goldstar R420 CD-ROM drive at 0x%X.\n", gscd_port); if (check_region(gscd_port, 4)) { printk("GSCD: Init failed, I/O port (%X) already in use.\n", gscd_port); return -EIO; } /* check for card */ result = wait_drv_ready (); if ( result == 0x09 ) { printk ("GSCD: DMA kann ich noch nicht!\n" ); return -EIO; } if ( result == 0x0b ) { drv_mode = result; i = find_drives (); if ( i == 0 ) { printk ( "GSCD: GoldStar CD-ROM Drive is not found.\n" ); return -EIO; } } if ( (result != 0x0b) && (result != 0x09) ) { printk ("GSCD: GoldStar Interface Adapter does not exist or H/W error\n" ); return -EIO; } /* reset all drives */ i = 0; while ( drv_states[i] != 0 ) { curr_drv_state = drv_states[i]; printk (KERN_INFO "GSCD: Reset unit %d ... ",i ); cc_Reset (); printk ( "done\n" ); i++; } if (register_blkdev(MAJOR_NR, "gscd", &gscd_fops) != 0) { printk("GSCD: Unable to get major %d for GoldStar CD-ROM\n", MAJOR_NR); return -EIO; } blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST; blksize_size[MAJOR_NR] = gscd_blocksizes; read_ahead[MAJOR_NR] = 4; disk_state = 0; gscdPresent = 1; request_region(gscd_port, 4, "gscd"); printk (KERN_INFO "GSCD: GoldStar CD-ROM Drive found.\n" ); return 0;}static void gscd_hsg2msf (long hsg, struct msf *msf){ hsg += CD_MSF_OFFSET; msf -> min = hsg / (CD_FRAMES*CD_SECS); hsg %= CD_FRAMES*CD_SECS; msf -> sec = hsg / CD_FRAMES; msf -> frame = hsg % CD_FRAMES; gscd_bin2bcd(&msf -> min); /* convert to BCD */ gscd_bin2bcd(&msf -> sec); gscd_bin2bcd(&msf -> frame);} static void gscd_bin2bcd (unsigned char *p){int u, t; u = *p % 10; t = *p / 10; *p = u | (t << 4);}#ifdef FUTURE_WORKstatic long gscd_msf2hsg (struct msf *mp){ return gscd_bcd2bin(mp -> frame) + gscd_bcd2bin(mp -> sec) * CD_FRAMES + gscd_bcd2bin(mp -> min) * CD_FRAMES * CD_SECS - CD_MSF_OFFSET;}static int gscd_bcd2bin (unsigned char bcd){ return (bcd >> 4) * 10 + (bcd & 0xF);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -