2007-05-08 04:33:32 +04:00
/*
2006-12-20 03:58:31 +03:00
* Copyright ( C ) 2005 - 2006 Kristian Hoegsberg < krh @ bitplanet . net >
*
* 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 ; either version 2 of the License , or
* ( at your option ) any later version .
*
* 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 . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
# ifndef __fw_device_h
# define __fw_device_h
# include <linux/fs.h>
# include <linux/cdev.h>
2008-11-24 22:40:00 +03:00
# include <linux/idr.h>
2008-03-24 22:54:28 +03:00
# include <linux/rwsem.h>
2007-01-27 12:34:55 +03:00
# include <asm/atomic.h>
2006-12-20 03:58:31 +03:00
enum fw_device_state {
FW_DEVICE_INITIALIZING ,
FW_DEVICE_RUNNING ,
2007-01-21 22:45:32 +03:00
FW_DEVICE_SHUTDOWN ,
2006-12-20 03:58:31 +03:00
} ;
2007-03-28 03:35:13 +04:00
struct fw_attribute_group {
struct attribute_group * groups [ 2 ] ;
struct attribute_group group ;
struct attribute * attrs [ 11 ] ;
} ;
2008-01-25 20:57:41 +03:00
/*
* Note , fw_device . generation always has to be read before fw_device . node_id .
* Use SMP memory barriers to ensure this . Otherwise requests will be sent
* to an outdated node_id if the generation was updated in the meantime due
* to a bus reset .
*
* Likewise , fw - core will take care to update . node_id before . generation so
* that whenever fw_device . generation is current WRT the actual bus generation ,
* fw_device . node_id is guaranteed to be current too .
*
* The same applies to fw_device . card - > node_id vs . fw_device . generation .
2008-03-24 22:54:28 +03:00
*
* fw_device . config_rom and fw_device . config_rom_length may be accessed during
* the lifetime of any fw_unit belonging to the fw_device , before device_del ( )
* was called on the last fw_unit . Alternatively , they may be accessed while
* holding fw_device_rwsem .
2008-01-25 20:57:41 +03:00
*/
2006-12-20 03:58:31 +03:00
struct fw_device {
2007-01-27 12:34:55 +03:00
atomic_t state ;
2006-12-20 03:58:31 +03:00
struct fw_node * node ;
int node_id ;
int generation ;
2007-06-10 23:31:36 +04:00
unsigned max_speed ;
2008-03-24 22:54:28 +03:00
bool cmc ;
2006-12-20 03:58:31 +03:00
struct fw_card * card ;
struct device device ;
2007-03-07 20:12:41 +03:00
struct list_head client_list ;
2007-03-20 21:44:26 +03:00
u32 * config_rom ;
2006-12-20 03:58:31 +03:00
size_t config_rom_length ;
int config_rom_retries ;
struct delayed_work work ;
2007-03-28 03:35:13 +04:00
struct fw_attribute_group attribute_group ;
2006-12-20 03:58:31 +03:00
} ;
2008-02-24 21:01:21 +03:00
static inline struct fw_device * fw_device ( struct device * dev )
2006-12-20 03:58:31 +03:00
{
2007-01-21 22:44:09 +03:00
return container_of ( dev , struct fw_device , device ) ;
2006-12-20 03:58:31 +03:00
}
2008-02-24 21:01:21 +03:00
static inline int fw_device_is_shutdown ( struct fw_device * device )
2007-03-07 20:12:48 +03:00
{
return atomic_read ( & device - > state ) = = FW_DEVICE_SHUTDOWN ;
}
2008-02-24 21:01:21 +03:00
static inline struct fw_device * fw_device_get ( struct fw_device * device )
2008-02-28 00:14:27 +03:00
{
get_device ( & device - > device ) ;
return device ;
}
2008-02-24 21:01:21 +03:00
static inline void fw_device_put ( struct fw_device * device )
2008-02-28 00:14:27 +03:00
{
put_device ( & device - > device ) ;
}
2008-02-02 17:01:09 +03:00
struct fw_device * fw_device_get_by_devt ( dev_t devt ) ;
2006-12-20 03:58:31 +03:00
int fw_device_enable_phys_dma ( struct fw_device * device ) ;
2007-03-07 20:12:41 +03:00
void fw_device_cdev_update ( struct fw_device * device ) ;
2007-03-07 20:12:48 +03:00
void fw_device_cdev_remove ( struct fw_device * device ) ;
2007-03-07 20:12:41 +03:00
2008-03-24 22:54:28 +03:00
extern struct rw_semaphore fw_device_rwsem ;
2008-11-24 22:40:00 +03:00
extern struct idr fw_device_idr ;
2007-03-07 20:12:44 +03:00
extern int fw_cdev_major ;
2008-03-24 22:54:28 +03:00
/*
* fw_unit . directory must not be accessed after device_del ( & fw_unit . device ) .
*/
2006-12-20 03:58:31 +03:00
struct fw_unit {
struct device device ;
u32 * directory ;
2007-03-28 03:35:13 +04:00
struct fw_attribute_group attribute_group ;
2006-12-20 03:58:31 +03:00
} ;
2008-02-24 21:01:21 +03:00
static inline struct fw_unit * fw_unit ( struct device * dev )
2006-12-20 03:58:31 +03:00
{
2007-01-21 22:44:09 +03:00
return container_of ( dev , struct fw_unit , device ) ;
2006-12-20 03:58:31 +03:00
}
2008-02-24 21:01:21 +03:00
static inline struct fw_unit * fw_unit_get ( struct fw_unit * unit )
{
get_device ( & unit - > device ) ;
return unit ;
}
static inline void fw_unit_put ( struct fw_unit * unit )
{
put_device ( & unit - > device ) ;
}
2006-12-20 03:58:31 +03:00
# define CSR_OFFSET 0x40
# define CSR_LEAF 0x80
# define CSR_DIRECTORY 0xc0
# define CSR_DESCRIPTOR 0x01
# define CSR_VENDOR 0x03
# define CSR_HARDWARE_VERSION 0x04
# define CSR_NODE_CAPABILITIES 0x0c
# define CSR_UNIT 0x11
# define CSR_SPECIFIER_ID 0x12
# define CSR_VERSION 0x13
# define CSR_DEPENDENT_INFO 0x14
# define CSR_MODEL 0x17
# define CSR_INSTANCE 0x18
2007-05-27 15:18:27 +04:00
# define CSR_DIRECTORY_ID 0x20
2006-12-20 03:58:31 +03:00
struct fw_csr_iterator {
u32 * p ;
u32 * end ;
} ;
void fw_csr_iterator_init ( struct fw_csr_iterator * ci , u32 * p ) ;
int fw_csr_iterator_next ( struct fw_csr_iterator * ci ,
int * key , int * value ) ;
# define FW_MATCH_VENDOR 0x0001
# define FW_MATCH_MODEL 0x0002
# define FW_MATCH_SPECIFIER_ID 0x0004
# define FW_MATCH_VERSION 0x0008
struct fw_device_id {
u32 match_flags ;
u32 vendor ;
u32 model ;
u32 specifier_id ;
u32 version ;
void * driver_data ;
} ;
struct fw_driver {
struct device_driver driver ;
/* Called when the parent device sits through a bus reset. */
void ( * update ) ( struct fw_unit * unit ) ;
2007-01-14 17:29:07 +03:00
const struct fw_device_id * id_table ;
2006-12-20 03:58:31 +03:00
} ;
static inline struct fw_driver *
fw_driver ( struct device_driver * drv )
{
2007-01-21 22:44:09 +03:00
return container_of ( drv , struct fw_driver , driver ) ;
2006-12-20 03:58:31 +03:00
}
2007-01-14 17:29:07 +03:00
extern const struct file_operations fw_device_ops ;
2006-12-20 03:58:31 +03:00
2006-12-28 18:20:00 +03:00
# endif /* __fw_device_h */