📄 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 MODULE
module_init(init_gscd);
#endif
module_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_WORK
static 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
MODULE_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 + -