or the i.MX6 processor family.
aboutsummaryrefslogblamecommitdiffstats
path: root/drivers/char/ps3flash.c
blob: 6abdde4da2b7834991a8e4e0b3feb52e0e054993 (plain) (tree)





















                                                                          
                       
                          
                         











                                                         


                                                                           



                                               
                                                                      
                                                                   
 


                                                                               

                                                    
                                                                              


                                                                 
                 

 
                                                             
 

                                                                              
 


                                          
                                                             

                           
 

                            

 
                                                                           
 
                                                                              

                
                                      







                                      
                                                                


                           
                                 
                 








                                                                           

                      





                                                                           

                            













                                                      

                                                                   

                                                      
                                                                              
                                 
                
                            
                        

                               

                                                                             











                                                                              
                                                               
                                         


                          

                                                                     
 

                                         
                                                  
                        
                                  
 
                                       



                                                                           
                                              






                                                  




                                           
                               
                                              





                                

                                   

 

                                                                               

                                                      
                                                                              

                                 
                            
                  

                               

                                                                               











                                                                              
                                                               
                                         


                          
                                                                     
                                               
 

                                         
                                          
                                                          



                                                      
 
                                       











                                                                           

                 

                                   



                                           
                               
                                              









                                   



















                                                                             












                                                     

 




                                                           
                                                                                    
 





                                                           
 










                                                                           
                                                                         


                                                           
                                                                        







                                                         


                                                     

                                      

                                 




                                                                 















































                                                                            
                                                    
                                 
                       


                                                         
                                                               














                                                                           

                                                         





                              
                                                    








                                                                            
                                         

                                        

                                                     































                                                         
/*
 * PS3 FLASH ROM Storage Driver
 *
 * Copyright (C) 2007 Sony Computer Entertainment Inc.
 * Copyright 2007 Sony Corp.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published
 * by the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/module.h>

#include <asm/lv1call.h>
#include <asm/ps3stor.h>


#define DEVICE_NAME		"ps3flash"

#define FLASH_BLOCK_SIZE	(256*1024)


struct ps3flash_private {
	struct mutex mutex;	/* Bounce buffer mutex */
	u64 chunk_sectors;
	int tag;		/* Start sector of buffer, -1 if invalid */
	bool dirty;
};

static struct ps3_storage_device *ps3flash_dev;

static int ps3flash_read_write_sectors(struct ps3_storage_device *dev,
				       u64 start_sector, int write)
{
	struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
	u64 res = ps3stor_read_write_sectors(dev, dev->bounce_lpar,
					     start_sector, priv->chunk_sectors,
					     write);
	if (res) {
		dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__,
			__LINE__, write ? "write" : "read", res);
		return -EIO;
	}
	return 0;
}

static int ps3flash_writeback(struct ps3_storage_device *dev)
{
	struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
	int res;

	if (!priv->dirty || priv->tag < 0)
		return 0;

	res = ps3flash_read_write_sectors(dev, priv->tag, 1);
	if (res)
		return res;

	priv->dirty = false;
	return 0;
}

static int ps3flash_fetch(struct ps3_storage_device *dev, u64 start_sector)
{
	struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
	int res;

	if (start_sector == priv->tag)
		return 0;

	res = ps3flash_writeback(dev);
	if (res)
		return res;

	priv->tag = -1;

	res = ps3flash_read_write_sectors(dev, start_sector, 0);
	if (res)
		return res;

	priv->tag = start_sector;
	return 0;
}

static loff_t ps3flash_llseek(struct file *file, loff_t offset, int origin)
{
	struct ps3_storage_device *dev = ps3flash_dev;
	loff_t res;

	mutex_lock(&file->f_mapping->host->i_mutex);
	switch (origin) {
	case 0:
		break;
	case 1: