📄 gscd.c
字号:
disk_state = ST_x08 | ST_x04 | ST_INVALID; return; } /* ...and waiting */ for (i = 1, dummy = 1; i < 0xFFFF; i++) { dummy *= i; } } /* LOC_172 */ /* 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_DEBUG printk("\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;}int __init 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;}void __init 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/* Init for the Module-Version */int init_gscd(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 __exit exit_gscd(void){ CLEAR_TIMER; devfs_unregister(devfs_find_handle (NULL, "gscd", 0, 0, DEVFS_SPECIAL_BLK, 0)); if ((devfs_unregister_blkdev(MAJOR_NR, "gscd") == -EINVAL)) { printk("What's that: can't unregister GoldStar-module\n"); return; } blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); release_region(gscd_port, 4); printk(KERN_INFO "GoldStar-module released.\n");}#ifdef MODULEmodule_init(init_gscd);#endifmodule_exit(exit_gscd);/* Test for presence of drive and initialize it. Called only at boot time. */int __init 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. */int __init 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 (devfs_register_blkdev(MAJOR_NR, "gscd", &gscd_fops) != 0) { printk ("GSCD: Unable to get major %d for GoldStar CD-ROM\n", MAJOR_NR); return -EIO; } devfs_register(NULL, "gscd", DEVFS_FL_DEFAULT, MAJOR_NR, 0, S_IFBLK | S_IRUGO | S_IWUGO, &gscd_fops, NULL); blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST); blksize_size[MAJOR_NR] = gscd_blocksizes; read_ahead[MAJOR_NR] = 4; disk_state = 0; gscdPresent = 1; request_region(gscd_port, 4, "gscd"); register_disk(NULL, MKDEV(MAJOR_NR, 0), 1, &gscd_fops, 0); 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);}#endifMODULE_AUTHOR("Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>");MODULE_LICENSE("GPL");EXPORT_NO_SYMBOLS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -