⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gscd.c

📁 powerpc内核 mpc8241芯片 linux系统下cdrom驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
       /* 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 + -