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

📄 mcc4.txt

📁 CCS FAT file system access
💻 TXT
📖 第 1 页 / 共 2 页
字号:
               code = 0;
               break;
            }
            else
            {
               mmc_address += hd_hardsectsizes[0];
               buffer_address += hd_hardsectsizes[0];
            }
         }
         spin_lock_irq(&io_request_lock);
      }
      else
      {
         code = 0;
      }
      end_request(code);
   }
}


static int mmc_open(struct inode *inode, struct file *filp)
{
   int device;
   (void)filp;
   
   if (mmc_media_detect == 0) return -ENODEV;

#if defined(MODULE)
   MOD_INC_USE_COUNT;
#endif
   return 0;
}


static int mmc_release(struct inode *inode, struct file *filp)
{
   (void)filp;
   fsync_dev(inode->i_rdev);
        invalidate_buffers(inode->i_rdev);

#if defined(MODULE)
   MOD_DEC_USE_COUNT;
#endif
   return 0;
}


extern struct gendisk hd_gendisk;
static int mmc_revalidate(kdev_t dev)
{
   int target, max_p, start, i;
   if (mmc_media_detect == 0) return -ENODEV;
   
   target = DEVICE_NR(dev);

   max_p = hd_gendisk.max_p;
   start = target << 6;
   for (i = max_p - 1; i >= 0; i--) {
      int minor = start + i;
      invalidate_device(MKDEV(MAJOR_NR, minor), 1);
      hd_gendisk.part[minor].start_sect = 0;
      hd_gendisk.part[minor].nr_sects = 0;
   }
   
   grok_partitions(&hd_gendisk, target, 1 << 6,
         hd_sizes[0] * 2);

   return 0;
}


static int mmc_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
   if (!inode || !inode->i_rdev)
      return -EINVAL;

   switch(cmd) {
   case BLKGETSIZE:
      return put_user(hd[MINOR(inode->i_rdev)].nr_sects, (unsigned long *)arg);
   case BLKGETSIZE64:
      return put_user((u64)hd[MINOR(inode->i_rdev)].
            nr_sects, (u64 *) arg);
   case BLKRRPART:
      if (!capable(CAP_SYS_ADMIN))
         return -EACCES;
         
      return mmc_revalidate(inode->i_rdev);
   case HDIO_GETGEO:
   {
      struct hd_geometry *loc, g;
      loc = (struct hd_geometry *) arg;
      if (!loc)
         return -EINVAL;
      g.heads = 4;
      g.sectors = 16;
      g.cylinders = hd[0].nr_sects / (4 * 16);
      g.start = hd[MINOR(inode->i_rdev)].start_sect;
      return copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0;
   }
   default:
      return blk_ioctl(inode->i_rdev, cmd, arg);
   }
}


static int mmc_card_init(void)
{
unsigned char r = 0;
short i, j;
unsigned long flags;

save_flags(flags);
cli();

printk("mmc Card init\n");

mmc_spi_cs_high();
for (i = 0; i < 20; i++) mmc_spi_io(0xff);

mmc_spi_cs_low();

mmc_spi_io(0x40);

for (i = 0; i < 4; i++) mmc_spi_io(0x00);

mmc_spi_io(0x95);

for (i = 0; i < 8; i++)
   {
   r = mmc_spi_io(0xff);
   if (r == 0x01)
      {
//      printk("mmc Card init WAS break\n");

      break;
      }
   }

mmc_spi_cs_high();

mmc_spi_io(0xff);

//printk("mmc Card init WAS r=%d\n", r);

if (r != 0x01)
   {
   restore_flags(flags);

   return 1;
   }

printk("mmc Card init *1*\n");

for (j = 0; j < 10000; j++)
   {
   mmc_spi_cs_low();

   mmc_spi_io(0x41);
   for (i = 0; i < 4; i++) mmc_spi_io(0x00);

   mmc_spi_io(0xff);
   for (i = 0; i < 8; i++)
      {
      r = mmc_spi_io(0xff);
      if (r == 0x00) break;
      }

   mmc_spi_cs_high();

   mmc_spi_io(0xff);
   if (r == 0x00)
      {
      restore_flags(flags);
      printk("mmc Card init *2*\n");

      return 0;
      }
   }

restore_flags(flags);

return 2;
} /* end function mmc_card_init */


static int mmc_card_config(void)
{
   unsigned char r = 0;
   short i;
   unsigned char csd[32];
   unsigned int c_size;
   unsigned int c_size_mult;
   unsigned int mult;
   unsigned int read_bl_len;
   unsigned int blocknr = 0;
   unsigned int block_len = 0;
   unsigned int size = 0;

   mmc_spi_cs_low();
   for (i = 0; i < 4; i++) mmc_spi_io(0xff);
   mmc_spi_io(0x49);
   for (i = 0; i < 4; i++) mmc_spi_io(0x00);
   mmc_spi_io(0xff);
   for (i = 0; i < 8; i++)
   {
      r = mmc_spi_io(0xff);
      if (r == 0x00) break;
   }
   if (r != 0x00)
   {
      mmc_spi_cs_high();
      mmc_spi_io(0xff);
      return(1);
   }
   for (i = 0; i < 8; i++)
   {
      r = mmc_spi_io(0xff);
      if (r == 0xfe) break;
   }
   if (r != 0xfe)
   {
      mmc_spi_cs_high();
      mmc_spi_io(0xff);
      return(2);
   }
   for (i = 0; i < 16; i++)
   {
      r = mmc_spi_io(0xff);
      csd[i] = r;
   }
   for (i = 0; i < 2; i++)
   {
      r = mmc_spi_io(0xff);
   }
   mmc_spi_cs_high();
   mmc_spi_io(0xff);
   if (r == 0x00) return(3);

   c_size = csd[8] + csd[7] * 256 + (csd[6] & 0x03) * 256 * 256;
   c_size >>= 6;
   c_size_mult = csd[10] + (csd[9] & 0x03) * 256;
   c_size_mult >>= 7;
   read_bl_len = csd[5] & 0x0f;
   mult = 1;
   mult <<= c_size_mult + 2;
   blocknr = (c_size + 1) * mult;
   block_len = 1;
   block_len <<= read_bl_len;
   size = block_len * blocknr;
   size >>= 10;

   for(i=0; i<(1<<6); i++) {
     hd_blocksizes[i] = 1024;
     hd_hardsectsizes[i] = block_len;
     hd_maxsect[i] = 256;
   }
   hd_sizes[0] = size;
   hd[0].nr_sects = blocknr;


   printk("Size = %d, hardsectsize = %d, sectors = %d\n",
          size, block_len, blocknr);

   return 0;
}


static int mmc_hardware_init(void)
{
unsigned int gpio_outen;
  
// Set inputs/outputs here
printk("mmc Hardware init\n");

gpio_outen = *gpioaddr_enable;
gpio_outen = (gpio_outen | SD_DI | SD_CLK | SD_CS) & ~SD_DO;
*gpioaddr_enable = gpio_outen;
  
port_state = *gpioaddr_input;
// Clock low
// all low
port_state &= ~(SD_CLK | SD_DI | SD_CS);
*gpioaddr_output = port_state;

return 0;
}


static int mmc_check_media_change(kdev_t dev)
{
   (void)dev;
   if (mmc_media_changed == 1)
   {
      mmc_media_changed = 0;
      return 1;
   }
   else return 0;
}


static struct block_device_operations mmc_bdops = 
{
   open: mmc_open,
   release: mmc_release,
   ioctl: mmc_ioctl,
#if 0
   check_media_change: mmc_check_media_change,
   revalidate: mmc_revalidate,
#endif
};


static struct gendisk hd_gendisk = {
   major:      MAJOR_NR,
   major_name:   DEVICE_NAME,
   minor_shift:   6,
   max_p:      1 << 6,
   part:      hd,
   sizes:      hd_sizes,
   fops:      &mmc_bdops,
};


static int mmc_init(void)
{
   int rc;

   rc = mmc_hardware_init(); 

   if ( rc != 0)
   {
      printk("mmc: error in mmc_hardware_init (%d)\n", rc);
      return -1;
   }

   rc = mmc_card_init(); 
   if ( rc != 0)
   {
      // Give it an extra shot
      rc = mmc_card_init(); 
      if ( rc != 0)
      {
         printk("mmc: error in mmc_card_init (%d)\n", rc);
         return -1;
      }
   }

   memset(hd_sizes, 0, sizeof(hd_sizes));
   rc = mmc_card_config(); 
   if ( rc != 0)
   {
      printk("mmc: error in mmc_card_config (%d)\n", rc);
      return -1;
   }
   

   blk_size[MAJOR_NR] = hd_sizes;

   memset(hd, 0, sizeof(hd));
   hd[0].nr_sects = hd_sizes[0]*2;

   blksize_size[MAJOR_NR] = hd_blocksizes;
   hardsect_size[MAJOR_NR] = hd_hardsectsizes;
   max_sectors[MAJOR_NR] = hd_maxsect;

   hd_gendisk.nr_real = 1;

   register_disk(&hd_gendisk, MKDEV(MAJOR_NR,0), 1<<6,
            &mmc_bdops, hd_sizes[0]*2);

   return 0;
}


static void mmc_exit(void)
{
   blk_size[MAJOR_NR] = NULL;
   blksize_size[MAJOR_NR] = NULL;
   hardsect_size[MAJOR_NR] = NULL;
   max_sectors[MAJOR_NR] = NULL;
   hd[0].nr_sects = 0;
}


static void mmc_check_media(void)
{
   int old_state;
   int rc;
   
   old_state = mmc_media_detect; 

   // TODO: Add card detection here
   mmc_media_detect = 1;
   if (old_state != mmc_media_detect) 
   {
      mmc_media_changed = 1;
      if (mmc_media_detect == 1)
      {
         rc = mmc_init();
         if (rc != 0) printk("mmc: error in mmc_init (%d)\n", rc);
      }
      else 
      {
         mmc_exit();
      }
   }

   /* del_timer(&mmc_timer);
   mmc_timer.expires = jiffies + 10*HZ;
   add_timer(&mmc_timer); */
}


static int __init mmc_driver_init(void)
{
   int rc;

   rc = devfs_register_blkdev(MAJOR_NR, DEVICE_NAME, &mmc_bdops);
   if (rc < 0)
   {
      printk(KERN_WARNING "mmc: can't get major %d\n", MAJOR_NR);
      return rc;
   }

   blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), mmc_request);

   read_ahead[MAJOR_NR] = 8;
   add_gendisk(&hd_gendisk);

   mmc_check_media();

   /*init_timer(&mmc_timer);
   mmc_timer.expires = jiffies + HZ;
   mmc_timer.function = (void *)mmc_check_media;
   add_timer(&mmc_timer);*/

   return 0;
}


static void __exit mmc_driver_exit(void)
{
   int i;
   del_timer(&mmc_timer);

   for (i = 0; i < (1 << 6); i++)
      fsync_dev(MKDEV(MAJOR_NR, i));

   blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
   del_gendisk(&hd_gendisk);
   devfs_unregister_blkdev(MAJOR_NR, DEVICE_NAME);
   mmc_exit();
}

module_init(mmc_driver_init);
module_exit(mmc_driver_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -