2008-10-16 09:04:33 +04:00
/*
2005-04-17 02:20:36 +04:00
* Parallel - port resource manager code .
2015-10-28 12:11:31 +03:00
*
2005-04-17 02:20:36 +04:00
* Authors : David Campbell < campbell @ tirian . che . curtin . edu . au >
* Tim Waugh < tim @ cyberelk . demon . co . uk >
* Jose Renau < renau @ acm . org >
* Philip Blundell < philb @ gnu . org >
* Andrea Arcangeli
*
* based on work by Grant Guenther < grant @ torque . net >
* and Philip Blundell
*
* Any part of this program may be used in documents licensed under
* the GNU Free Documentation License , Version 1.1 or any later version
* published by the Free Software Foundation .
*/
# undef PARPORT_DEBUG_SHARING /* undef for production */
# include <linux/module.h>
# include <linux/string.h>
# include <linux/threads.h>
# include <linux/parport.h>
# include <linux/delay.h>
# include <linux/errno.h>
# include <linux/interrupt.h>
# include <linux/ioport.h>
# include <linux/kernel.h>
# include <linux/slab.h>
# include <linux/sched.h>
# include <linux/kmod.h>
2015-05-20 18:26:57 +03:00
# include <linux/device.h>
2005-04-17 02:20:36 +04:00
# include <linux/spinlock.h>
2006-03-26 13:37:14 +04:00
# include <linux/mutex.h>
2005-04-17 02:20:36 +04:00
# include <asm/irq.h>
# undef PARPORT_PARANOID
# define PARPORT_DEFAULT_TIMESLICE (HZ / 5)
unsigned long parport_default_timeslice = PARPORT_DEFAULT_TIMESLICE ;
int parport_default_spintime = DEFAULT_SPIN_TIME ;
static LIST_HEAD ( portlist ) ;
static DEFINE_SPINLOCK ( parportlist_lock ) ;
/* list of all allocated ports, sorted by ->number */
static LIST_HEAD ( all_ports ) ;
static DEFINE_SPINLOCK ( full_list_lock ) ;
static LIST_HEAD ( drivers ) ;
2006-03-26 13:37:14 +04:00
static DEFINE_MUTEX ( registration_lock ) ;
2005-04-17 02:20:36 +04:00
/* What you can do to a port that's gone away.. */
2015-10-28 12:11:39 +03:00
static void dead_write_lines ( struct parport * p , unsigned char b ) { }
static unsigned char dead_read_lines ( struct parport * p ) { return 0 ; }
static unsigned char dead_frob_lines ( struct parport * p , unsigned char b ,
2005-04-17 02:20:36 +04:00
unsigned char c ) { return 0 ; }
2015-10-28 12:11:39 +03:00
static void dead_onearg ( struct parport * p ) { }
static void dead_initstate ( struct pardevice * d , struct parport_state * s ) { }
static void dead_state ( struct parport * p , struct parport_state * s ) { }
static size_t dead_write ( struct parport * p , const void * b , size_t l , int f )
2005-04-17 02:20:36 +04:00
{ return 0 ; }
2015-10-28 12:11:39 +03:00
static size_t dead_read ( struct parport * p , void * b , size_t l , int f )
2005-04-17 02:20:36 +04:00
{ return 0 ; }
static struct parport_operations dead_ops = {
. write_data = dead_write_lines , /* data */
. read_data = dead_read_lines ,
. write_control = dead_write_lines , /* control */
. read_control = dead_read_lines ,
. frob_control = dead_frob_lines ,
. read_status = dead_read_lines , /* status */
. enable_irq = dead_onearg , /* enable_irq */
. disable_irq = dead_onearg , /* disable_irq */
. data_forward = dead_onearg , /* data_forward */
. data_reverse = dead_onearg , /* data_reverse */
. init_state = dead_initstate , /* init_state */
. save_state = dead_state ,
. restore_state = dead_state ,
. epp_write_data = dead_write , /* epp */
. epp_read_data = dead_read ,
. epp_write_addr = dead_write ,
. epp_read_addr = dead_read ,
. ecp_write_data = dead_write , /* ecp */
. ecp_read_data = dead_read ,
. ecp_write_addr = dead_write ,
2015-10-28 12:11:31 +03:00
2005-04-17 02:20:36 +04:00
. compat_write_data = dead_write , /* compat */
. nibble_read_data = dead_read , /* nibble */
. byte_read_data = dead_read , /* byte */
. owner = NULL ,
} ;
2015-05-20 18:26:57 +03:00
static struct device_type parport_device_type = {
. name = " parport " ,
} ;
static int is_parport ( struct device * dev )
{
return dev - > type = = & parport_device_type ;
}
static int parport_probe ( struct device * dev )
{
struct parport_driver * drv ;
if ( is_parport ( dev ) )
return - ENODEV ;
drv = to_parport_driver ( dev - > driver ) ;
if ( ! drv - > probe ) {
/* if driver has not defined a custom probe */
struct pardevice * par_dev = to_pardevice ( dev ) ;
if ( strcmp ( par_dev - > name , drv - > name ) )
return - ENODEV ;
return 0 ;
}
/* if driver defined its own probe */
return drv - > probe ( to_pardevice ( dev ) ) ;
}
static struct bus_type parport_bus_type = {
. name = " parport " ,
. probe = parport_probe ,
} ;
int parport_bus_init ( void )
{
return bus_register ( & parport_bus_type ) ;
}
void parport_bus_exit ( void )
{
bus_unregister ( & parport_bus_type ) ;
}
/*
* iterates through all the drivers registered with the bus and sends the port
* details to the match_port callback of the driver , so that the driver can
2015-10-28 12:11:30 +03:00
* know about the new port that just registered with the bus and decide if it
2015-05-20 18:26:57 +03:00
* wants to use this new port .
*/
static int driver_check ( struct device_driver * dev_drv , void * _port )
{
struct parport * port = _port ;
struct parport_driver * drv = to_parport_driver ( dev_drv ) ;
if ( drv - > match_port )
drv - > match_port ( port ) ;
return 0 ;
}
2005-04-17 02:20:36 +04:00
/* Call attach(port) for each registered driver. */
static void attach_driver_chain ( struct parport * port )
{
/* caller has exclusive registration_lock */
struct parport_driver * drv ;
2015-05-20 18:26:57 +03:00
2005-04-17 02:20:36 +04:00
list_for_each_entry ( drv , & drivers , list )
drv - > attach ( port ) ;
2015-05-20 18:26:57 +03:00
/*
* call the driver_check function of the drivers registered in
* new device model
*/
bus_for_each_drv ( & parport_bus_type , NULL , port , driver_check ) ;
}
static int driver_detach ( struct device_driver * _drv , void * _port )
{
struct parport * port = _port ;
struct parport_driver * drv = to_parport_driver ( _drv ) ;
if ( drv - > detach )
drv - > detach ( port ) ;
return 0 ;
2005-04-17 02:20:36 +04:00
}
/* Call detach(port) for each registered driver. */
static void detach_driver_chain ( struct parport * port )
{
struct parport_driver * drv ;
/* caller has exclusive registration_lock */
list_for_each_entry ( drv , & drivers , list )
2015-10-28 12:11:39 +03:00
drv - > detach ( port ) ;
2015-05-20 18:26:57 +03:00
/*
* call the detach function of the drivers registered in
* new device model
*/
bus_for_each_drv ( & parport_bus_type , NULL , port , driver_detach ) ;
2005-04-17 02:20:36 +04:00
}
/* Ask kmod for some lowlevel drivers. */
2015-10-28 12:11:39 +03:00
static void get_lowlevel_driver ( void )
2005-04-17 02:20:36 +04:00
{
2015-10-28 12:11:33 +03:00
/*
* There is no actual module called this : you should set
* up an alias for modutils .
*/
2015-10-28 12:11:39 +03:00
request_module ( " parport_lowlevel " ) ;
2005-04-17 02:20:36 +04:00
}
2015-05-20 18:26:57 +03:00
/*
* iterates through all the devices connected to the bus and sends the device
* details to the match_port callback of the driver , so that the driver can
* know what are all the ports that are connected to the bus and choose the
* port to which it wants to register its device .
*/
static int port_check ( struct device * dev , void * dev_drv )
{
struct parport_driver * drv = dev_drv ;
/* only send ports, do not send other devices connected to bus */
if ( is_parport ( dev ) )
drv - > match_port ( to_parport_dev ( dev ) ) ;
return 0 ;
}
2005-04-17 02:20:36 +04:00
/**
* parport_register_driver - register a parallel port device driver
* @ drv : structure describing the driver
2015-05-20 18:26:57 +03:00
* @ owner : owner module of drv
* @ mod_name : module name string
2005-04-17 02:20:36 +04:00
*
* This can be called by a parallel port device driver in order
* to receive notifications about ports being found in the
* system , as well as ports no longer available .
*
2015-05-20 18:26:57 +03:00
* If devmodel is true then the new device model is used
* for registration .
*
2005-04-17 02:20:36 +04:00
* The @ drv structure is allocated by the caller and must not be
* deallocated until after calling parport_unregister_driver ( ) .
*
2015-05-20 18:26:57 +03:00
* If using the non device model :
2005-04-17 02:20:36 +04:00
* The driver ' s attach ( ) function may block . The port that
* attach ( ) is given will be valid for the duration of the
* callback , but if the driver wants to take a copy of the
* pointer it must call parport_get_port ( ) to do so . Calling
* parport_register_device ( ) on that port will do this for you .
*
* The driver ' s detach ( ) function may block . The port that
* detach ( ) is given will be valid for the duration of the
* callback , but if the driver wants to take a copy of the
* pointer it must call parport_get_port ( ) to do so .
*
2015-05-20 18:26:57 +03:00
*
* Returns 0 on success . The non device model will always succeeds .
* but the new device model can fail and will return the error code .
2005-04-17 02:20:36 +04:00
* */
2015-05-20 18:26:57 +03:00
int __parport_register_driver ( struct parport_driver * drv , struct module * owner ,
const char * mod_name )
2005-04-17 02:20:36 +04:00
{
if ( list_empty ( & portlist ) )
2015-10-28 12:11:39 +03:00
get_lowlevel_driver ( ) ;
2005-04-17 02:20:36 +04:00
2015-05-20 18:26:57 +03:00
if ( drv - > devmodel ) {
/* using device model */
int ret ;
/* initialize common driver fields */
drv - > driver . name = drv - > name ;
drv - > driver . bus = & parport_bus_type ;
drv - > driver . owner = owner ;
drv - > driver . mod_name = mod_name ;
ret = driver_register ( & drv - > driver ) ;
if ( ret )
return ret ;
mutex_lock ( & registration_lock ) ;
if ( drv - > match_port )
bus_for_each_dev ( & parport_bus_type , NULL , drv ,
port_check ) ;
mutex_unlock ( & registration_lock ) ;
} else {
struct parport * port ;
drv - > devmodel = false ;
mutex_lock ( & registration_lock ) ;
list_for_each_entry ( port , & portlist , list )
drv - > attach ( port ) ;
list_add ( & drv - > list , & drivers ) ;
mutex_unlock ( & registration_lock ) ;
}
return 0 ;
}
EXPORT_SYMBOL ( __parport_register_driver ) ;
static int port_detach ( struct device * dev , void * _drv )
{
struct parport_driver * drv = _drv ;
if ( is_parport ( dev ) & & drv - > detach )
drv - > detach ( to_parport_dev ( dev ) ) ;
2005-04-17 02:20:36 +04:00
return 0 ;
}
/**
* parport_unregister_driver - deregister a parallel port device driver
* @ drv : structure describing the driver that was given to
* parport_register_driver ( )
*
* This should be called by a parallel port device driver that
* has registered itself using parport_register_driver ( ) when it
* is about to be unloaded .
*
* When it returns , the driver ' s attach ( ) routine will no longer
* be called , and for each port that attach ( ) was called for , the
* detach ( ) routine will have been called .
*
* All the driver ' s attach ( ) and detach ( ) calls are guaranteed to have
* finished by the time this function returns .
* */
2015-10-28 12:11:39 +03:00
void parport_unregister_driver ( struct parport_driver * drv )
2005-04-17 02:20:36 +04:00
{
struct parport * port ;
2006-03-26 13:37:14 +04:00
mutex_lock ( & registration_lock ) ;
2015-05-20 18:26:57 +03:00
if ( drv - > devmodel ) {
bus_for_each_dev ( & parport_bus_type , NULL , drv , port_detach ) ;
driver_unregister ( & drv - > driver ) ;
} else {
list_del_init ( & drv - > list ) ;
list_for_each_entry ( port , & portlist , list )
drv - > detach ( port ) ;
}
2006-03-26 13:37:14 +04:00
mutex_unlock ( & registration_lock ) ;
2005-04-17 02:20:36 +04:00
}
2015-10-28 12:11:32 +03:00
EXPORT_SYMBOL ( parport_unregister_driver ) ;
2005-04-17 02:20:36 +04:00
2015-05-20 18:26:57 +03:00
static void free_port ( struct device * dev )
2005-04-17 02:20:36 +04:00
{
int d ;
2015-05-20 18:26:57 +03:00
struct parport * port = to_parport_dev ( dev ) ;
2005-04-17 02:20:36 +04:00
spin_lock ( & full_list_lock ) ;
list_del ( & port - > full_list ) ;
spin_unlock ( & full_list_lock ) ;
for ( d = 0 ; d < 5 ; d + + ) {
2005-11-07 12:01:32 +03:00
kfree ( port - > probe_info [ d ] . class_name ) ;
kfree ( port - > probe_info [ d ] . mfr ) ;
kfree ( port - > probe_info [ d ] . model ) ;
kfree ( port - > probe_info [ d ] . cmdset ) ;
kfree ( port - > probe_info [ d ] . description ) ;
2005-04-17 02:20:36 +04:00
}
kfree ( port - > name ) ;
kfree ( port ) ;
}
/**
* parport_get_port - increment a port ' s reference count
* @ port : the port
*
2006-06-25 16:49:29 +04:00
* This ensures that a struct parport pointer remains valid
2005-04-17 02:20:36 +04:00
* until the matching parport_put_port ( ) call .
* */
2015-10-28 12:11:39 +03:00
struct parport * parport_get_port ( struct parport * port )
2005-04-17 02:20:36 +04:00
{
2015-05-20 18:26:57 +03:00
struct device * dev = get_device ( & port - > bus_dev ) ;
return to_parport_dev ( dev ) ;
}
2015-10-28 12:11:32 +03:00
EXPORT_SYMBOL ( parport_get_port ) ;
2015-05-20 18:26:57 +03:00
void parport_del_port ( struct parport * port )
{
device_unregister ( & port - > bus_dev ) ;
2005-04-17 02:20:36 +04:00
}
2015-05-20 18:26:57 +03:00
EXPORT_SYMBOL ( parport_del_port ) ;
2005-04-17 02:20:36 +04:00
/**
* parport_put_port - decrement a port ' s reference count
* @ port : the port
*
* This should be called once for each call to parport_get_port ( ) ,
2015-05-20 18:26:57 +03:00
* once the port is no longer needed . When the reference count reaches
* zero ( port is no longer used ) , free_port is called .
2005-04-17 02:20:36 +04:00
* */
2015-10-28 12:11:39 +03:00
void parport_put_port ( struct parport * port )
2005-04-17 02:20:36 +04:00
{
2015-05-20 18:26:57 +03:00
put_device ( & port - > bus_dev ) ;
2005-04-17 02:20:36 +04:00
}
2015-10-28 12:11:32 +03:00
EXPORT_SYMBOL ( parport_put_port ) ;
2005-04-17 02:20:36 +04:00
/**
* parport_register_port - register a parallel port
* @ base : base I / O address
* @ irq : IRQ line
* @ dma : DMA channel
* @ ops : pointer to the port driver ' s port operations structure
*
* When a parallel port ( lowlevel ) driver finds a port that
* should be made available to parallel port device drivers , it
* should call parport_register_port ( ) . The @ base , @ irq , and
* @ dma parameters are for the convenience of port drivers , and
* for ports where they aren ' t meaningful needn ' t be set to
* anything special . They can be altered afterwards by adjusting
* the relevant members of the parport structure that is returned
* and represents the port . They should not be tampered with
* after calling parport_announce_port , however .
*
* If there are parallel port device drivers in the system that
* have registered themselves using parport_register_driver ( ) ,
* they are not told about the port at this time ; that is done by
* parport_announce_port ( ) .
*
* The @ ops structure is allocated by the caller , and must not be
* deallocated before calling parport_remove_port ( ) .
*
* If there is no memory to allocate a new parport structure ,
* this function will return % NULL .
* */
struct parport * parport_register_port ( unsigned long base , int irq , int dma ,
struct parport_operations * ops )
{
struct list_head * l ;
struct parport * tmp ;
int num ;
int device ;
char * name ;
2015-05-20 18:26:57 +03:00
int ret ;
2005-04-17 02:20:36 +04:00
2013-07-04 02:09:09 +04:00
tmp = kzalloc ( sizeof ( struct parport ) , GFP_KERNEL ) ;
2015-10-28 12:11:37 +03:00
if ( ! tmp )
2005-04-17 02:20:36 +04:00
return NULL ;
/* Init our structure */
tmp - > base = base ;
tmp - > irq = irq ;
tmp - > dma = dma ;
tmp - > muxport = tmp - > daisy = tmp - > muxsel = - 1 ;
tmp - > modes = 0 ;
2015-10-28 12:11:34 +03:00
INIT_LIST_HEAD ( & tmp - > list ) ;
2005-04-17 02:20:36 +04:00
tmp - > devices = tmp - > cad = NULL ;
tmp - > flags = 0 ;
tmp - > ops = ops ;
tmp - > physport = tmp ;
2015-10-28 12:11:39 +03:00
memset ( tmp - > probe_info , 0 , 5 * sizeof ( struct parport_device_info ) ) ;
2005-04-17 02:20:36 +04:00
rwlock_init ( & tmp - > cad_lock ) ;
spin_lock_init ( & tmp - > waitlist_lock ) ;
spin_lock_init ( & tmp - > pardevice_lock ) ;
tmp - > ieee1284 . mode = IEEE1284_MODE_COMPAT ;
tmp - > ieee1284 . phase = IEEE1284_PH_FWD_IDLE ;
2010-09-07 18:32:34 +04:00
sema_init ( & tmp - > ieee1284 . irq , 0 ) ;
2005-04-17 02:20:36 +04:00
tmp - > spintime = parport_default_spintime ;
2015-10-28 12:11:39 +03:00
atomic_set ( & tmp - > ref_count , 1 ) ;
2005-04-17 02:20:36 +04:00
INIT_LIST_HEAD ( & tmp - > full_list ) ;
name = kmalloc ( 15 , GFP_KERNEL ) ;
if ( ! name ) {
kfree ( tmp ) ;
return NULL ;
}
/* Search for the lowest free parport number. */
spin_lock ( & full_list_lock ) ;
for ( l = all_ports . next , num = 0 ; l ! = & all_ports ; l = l - > next , num + + ) {
struct parport * p = list_entry ( l , struct parport , full_list ) ;
if ( p - > number ! = num )
break ;
}
tmp - > portnum = tmp - > number = num ;
list_add_tail ( & tmp - > full_list , l ) ;
spin_unlock ( & full_list_lock ) ;
/*
* Now that the portnum is known finish doing the Init .
*/
sprintf ( name , " parport%d " , tmp - > portnum = tmp - > number ) ;
tmp - > name = name ;
2015-05-20 18:26:57 +03:00
tmp - > bus_dev . bus = & parport_bus_type ;
tmp - > bus_dev . release = free_port ;
dev_set_name ( & tmp - > bus_dev , name ) ;
tmp - > bus_dev . type = & parport_device_type ;
2005-04-17 02:20:36 +04:00
for ( device = 0 ; device < 5 ; device + + )
/* assume the worst */
tmp - > probe_info [ device ] . class = PARPORT_CLASS_LEGACY ;
tmp - > waithead = tmp - > waittail = NULL ;
2015-05-20 18:26:57 +03:00
ret = device_register ( & tmp - > bus_dev ) ;
if ( ret ) {
put_device ( & tmp - > bus_dev ) ;
return NULL ;
}
2005-04-17 02:20:36 +04:00
return tmp ;
}
2015-10-28 12:11:32 +03:00
EXPORT_SYMBOL ( parport_register_port ) ;
2005-04-17 02:20:36 +04:00
/**
* parport_announce_port - tell device drivers about a parallel port
* @ port : parallel port to announce
*
* After a port driver has registered a parallel port with
* parport_register_port , and performed any necessary
* initialisation or adjustments , it should call
* parport_announce_port ( ) in order to notify all device drivers
* that have called parport_register_driver ( ) . Their attach ( )
* functions will be called , with @ port as the parameter .
* */
2015-10-28 12:11:39 +03:00
void parport_announce_port ( struct parport * port )
2005-04-17 02:20:36 +04:00
{
int i ;
# ifdef CONFIG_PARPORT_1284
/* Analyse the IEEE1284.3 topology of the port. */
parport_daisy_init ( port ) ;
# endif
2007-05-08 11:27:35 +04:00
if ( ! port - > dev )
2015-10-28 12:11:35 +03:00
printk ( KERN_WARNING " %s: fix this legacy no-device port driver! \n " ,
port - > name ) ;
2007-05-08 11:27:35 +04:00
2005-04-17 02:20:36 +04:00
parport_proc_register ( port ) ;
2006-03-26 13:37:14 +04:00
mutex_lock ( & registration_lock ) ;
2005-04-17 02:20:36 +04:00
spin_lock_irq ( & parportlist_lock ) ;
list_add_tail ( & port - > list , & portlist ) ;
for ( i = 1 ; i < 3 ; i + + ) {
struct parport * slave = port - > slaves [ i - 1 ] ;
if ( slave )
list_add_tail ( & slave - > list , & portlist ) ;
}
spin_unlock_irq ( & parportlist_lock ) ;
/* Let drivers know that new port(s) has arrived. */
2015-10-28 12:11:39 +03:00
attach_driver_chain ( port ) ;
2005-04-17 02:20:36 +04:00
for ( i = 1 ; i < 3 ; i + + ) {
struct parport * slave = port - > slaves [ i - 1 ] ;
if ( slave )
attach_driver_chain ( slave ) ;
}
2006-03-26 13:37:14 +04:00
mutex_unlock ( & registration_lock ) ;
2005-04-17 02:20:36 +04:00
}
2015-10-28 12:11:32 +03:00
EXPORT_SYMBOL ( parport_announce_port ) ;
2005-04-17 02:20:36 +04:00
/**
* parport_remove_port - deregister a parallel port
* @ port : parallel port to deregister
*
* When a parallel port driver is forcibly unloaded , or a
* parallel port becomes inaccessible , the port driver must call
* this function in order to deal with device drivers that still
* want to use it .
*
* The parport structure associated with the port has its
* operations structure replaced with one containing ' null '
* operations that return errors or just don ' t do anything .
*
* Any drivers that have registered themselves using
* parport_register_driver ( ) are notified that the port is no
* longer accessible by having their detach ( ) routines called
* with @ port as the parameter .
* */
void parport_remove_port ( struct parport * port )
{
int i ;
2006-03-26 13:37:14 +04:00
mutex_lock ( & registration_lock ) ;
2005-04-17 02:20:36 +04:00
/* Spread the word. */
2015-10-28 12:11:39 +03:00
detach_driver_chain ( port ) ;
2005-04-17 02:20:36 +04:00
# ifdef CONFIG_PARPORT_1284
/* Forget the IEEE1284.3 topology of the port. */
parport_daisy_fini ( port ) ;
for ( i = 1 ; i < 3 ; i + + ) {
struct parport * slave = port - > slaves [ i - 1 ] ;
if ( ! slave )
continue ;
detach_driver_chain ( slave ) ;
parport_daisy_fini ( slave ) ;
}
# endif
port - > ops = & dead_ops ;
spin_lock ( & parportlist_lock ) ;
list_del_init ( & port - > list ) ;
for ( i = 1 ; i < 3 ; i + + ) {
struct parport * slave = port - > slaves [ i - 1 ] ;
if ( slave )
list_del_init ( & slave - > list ) ;
}
spin_unlock ( & parportlist_lock ) ;
2006-03-26 13:37:14 +04:00
mutex_unlock ( & registration_lock ) ;
2005-04-17 02:20:36 +04:00
parport_proc_unregister ( port ) ;
for ( i = 1 ; i < 3 ; i + + ) {
struct parport * slave = port - > slaves [ i - 1 ] ;
if ( slave )
parport_put_port ( slave ) ;
}
}
2015-10-28 12:11:32 +03:00
EXPORT_SYMBOL ( parport_remove_port ) ;
2005-04-17 02:20:36 +04:00
/**
* parport_register_device - register a device on a parallel port
* @ port : port to which the device is attached
* @ name : a name to refer to the device
* @ pf : preemption callback
* @ kf : kick callback ( wake - up )
* @ irq_func : interrupt handler
* @ flags : registration flags
* @ handle : data for callback functions
*
* This function , called by parallel port device drivers ,
* declares that a device is connected to a port , and tells the
* system all it needs to know .
*
* The @ name is allocated by the caller and must not be
* deallocated until the caller calls @ parport_unregister_device
* for that device .
*
* The preemption callback function , @ pf , is called when this
* device driver has claimed access to the port but another
* device driver wants to use it . It is given @ handle as its
* parameter , and should return zero if it is willing for the
* system to release the port to another driver on its behalf .
* If it wants to keep control of the port it should return
* non - zero , and no action will be taken . It is good manners for
* the driver to try to release the port at the earliest
* opportunity after its preemption callback rejects a preemption
* attempt . Note that if a preemption callback is happy for
* preemption to go ahead , there is no need to release the port ;
* it is done automatically . This function may not block , as it
* may be called from interrupt context . If the device driver
* does not support preemption , @ pf can be % NULL .
*
* The wake - up ( " kick " ) callback function , @ kf , is called when
* the port is available to be claimed for exclusive access ; that
* is , parport_claim ( ) is guaranteed to succeed when called from
* inside the wake - up callback function . If the driver wants to
* claim the port it should do so ; otherwise , it need not take
* any action . This function may not block , as it may be called
* from interrupt context . If the device driver does not want to
* be explicitly invited to claim the port in this way , @ kf can
* be % NULL .
*
* The interrupt handler , @ irq_func , is called when an interrupt
* arrives from the parallel port . Note that if a device driver
* wants to use interrupts it should use parport_enable_irq ( ) ,
* and can also check the irq member of the parport structure
* representing the port .
*
* The parallel port ( lowlevel ) driver is the one that has called
* request_irq ( ) and whose interrupt handler is called first .
* This handler does whatever needs to be done to the hardware to
* acknowledge the interrupt ( for PC - style ports there is nothing
* special to be done ) . It then tells the IEEE 1284 code about
* the interrupt , which may involve reacting to an IEEE 1284
* event depending on the current IEEE 1284 phase . After this ,
* it calls @ irq_func . Needless to say , @ irq_func will be called
* from interrupt context , and may not block .
*
* The % PARPORT_DEV_EXCL flag is for preventing port sharing , and
* so should only be used when sharing the port with other device
* drivers is impossible and would lead to incorrect behaviour .
* Use it sparingly ! Normally , @ flags will be zero .
*
* This function returns a pointer to a structure that represents
* the device on the port , or % NULL if there is not enough memory
* to allocate space for that structure .
* */
struct pardevice *
parport_register_device ( struct parport * port , const char * name ,
int ( * pf ) ( void * ) , void ( * kf ) ( void * ) ,
2015-10-28 12:11:31 +03:00
void ( * irq_func ) ( void * ) ,
2005-04-17 02:20:36 +04:00
int flags , void * handle )
{
struct pardevice * tmp ;
if ( port - > physport - > flags & PARPORT_FLAG_EXCL ) {
/* An exclusive device is registered. */
2015-10-28 12:11:39 +03:00
printk ( KERN_DEBUG " %s: no more devices allowed \n " ,
2005-04-17 02:20:36 +04:00
port - > name ) ;
return NULL ;
}
if ( flags & PARPORT_DEV_LURK ) {
if ( ! pf | | ! kf ) {
printk ( KERN_INFO " %s: refused to register lurking device (%s) without callbacks \n " , port - > name , name ) ;
return NULL ;
}
}
2015-06-12 12:50:20 +03:00
if ( flags & PARPORT_DEV_EXCL ) {
if ( port - > physport - > devices ) {
/*
* If a device is already registered and this new
* device wants exclusive access , then no need to
* continue as we can not grant exclusive access to
* this device .
*/
pr_err ( " %s: cannot grant exclusive access for device %s \n " ,
port - > name , name ) ;
return NULL ;
}
}
2015-10-28 12:11:33 +03:00
/*
* We up our own module reference count , and that of the port
* on which a device is to be registered , to ensure that
* neither of us gets unloaded while we sleep in ( e . g . )
* kmalloc .
*/
2015-10-28 12:11:36 +03:00
if ( ! try_module_get ( port - > ops - > owner ) )
2005-04-17 02:20:36 +04:00
return NULL ;
2015-10-28 12:11:31 +03:00
2015-10-28 12:11:39 +03:00
parport_get_port ( port ) ;
2005-04-17 02:20:36 +04:00
tmp = kmalloc ( sizeof ( struct pardevice ) , GFP_KERNEL ) ;
2015-10-28 12:11:38 +03:00
if ( ! tmp )
2005-04-17 02:20:36 +04:00
goto out ;
tmp - > state = kmalloc ( sizeof ( struct parport_state ) , GFP_KERNEL ) ;
2015-10-28 12:11:38 +03:00
if ( ! tmp - > state )
2005-04-17 02:20:36 +04:00
goto out_free_pardevice ;
tmp - > name = name ;
tmp - > port = port ;
tmp - > daisy = - 1 ;
tmp - > preempt = pf ;
tmp - > wakeup = kf ;
tmp - > private = handle ;
tmp - > flags = flags ;
tmp - > irq_func = irq_func ;
tmp - > waiting = 0 ;
tmp - > timeout = 5 * HZ ;
2015-05-20 18:26:57 +03:00
tmp - > devmodel = false ;
2005-04-17 02:20:36 +04:00
/* Chain this onto the list */
tmp - > prev = NULL ;
/*
* This function must not run from an irq handler so we don ' t need
* to clear irq on the local CPU . - arca
*/
spin_lock ( & port - > physport - > pardevice_lock ) ;
if ( flags & PARPORT_DEV_EXCL ) {
if ( port - > physport - > devices ) {
2015-10-28 12:11:39 +03:00
spin_unlock ( & port - > physport - > pardevice_lock ) ;
printk ( KERN_DEBUG
2015-10-28 12:11:35 +03:00
" %s: cannot grant exclusive access for device %s \n " ,
port - > name , name ) ;
2005-04-17 02:20:36 +04:00
goto out_free_all ;
}
port - > flags | = PARPORT_FLAG_EXCL ;
}
tmp - > next = port - > physport - > devices ;
2015-10-28 12:11:33 +03:00
wmb ( ) ; /*
* Make sure that tmp - > next is written before it ' s
* added to the list ; see comments marked ' no locking
* required '
*/
2005-04-17 02:20:36 +04:00
if ( port - > physport - > devices )
port - > physport - > devices - > prev = tmp ;
port - > physport - > devices = tmp ;
spin_unlock ( & port - > physport - > pardevice_lock ) ;
init_waitqueue_head ( & tmp - > wait_q ) ;
tmp - > timeslice = parport_default_timeslice ;
tmp - > waitnext = tmp - > waitprev = NULL ;
/*
* This has to be run as last thing since init_state may need other
* pardevice fields . - arca
*/
port - > ops - > init_state ( tmp , tmp - > state ) ;
2009-06-02 19:58:10 +04:00
if ( ! test_and_set_bit ( PARPORT_DEVPROC_REGISTERED , & port - > devflags ) ) {
port - > proc_device = tmp ;
parport_device_proc_register ( tmp ) ;
}
2005-04-17 02:20:36 +04:00
return tmp ;
out_free_all :
2005-11-07 12:01:32 +03:00
kfree ( tmp - > state ) ;
2005-04-17 02:20:36 +04:00
out_free_pardevice :
2005-11-07 12:01:32 +03:00
kfree ( tmp ) ;
2005-04-17 02:20:36 +04:00
out :
2015-10-28 12:11:39 +03:00
parport_put_port ( port ) ;
2005-04-17 02:20:36 +04:00
module_put ( port - > ops - > owner ) ;
return NULL ;
}
2015-10-28 12:11:32 +03:00
EXPORT_SYMBOL ( parport_register_device ) ;
2005-04-17 02:20:36 +04:00
2015-05-20 18:26:57 +03:00
static void free_pardevice ( struct device * dev )
{
struct pardevice * par_dev = to_pardevice ( dev ) ;
kfree ( par_dev - > name ) ;
kfree ( par_dev ) ;
}
struct pardevice *
parport_register_dev_model ( struct parport * port , const char * name ,
const struct pardev_cb * par_dev_cb , int id )
{
struct pardevice * par_dev ;
int ret ;
char * devname ;
if ( port - > physport - > flags & PARPORT_FLAG_EXCL ) {
/* An exclusive device is registered. */
pr_err ( " %s: no more devices allowed \n " , port - > name ) ;
return NULL ;
}
if ( par_dev_cb - > flags & PARPORT_DEV_LURK ) {
if ( ! par_dev_cb - > preempt | | ! par_dev_cb - > wakeup ) {
pr_info ( " %s: refused to register lurking device (%s) without callbacks \n " ,
port - > name , name ) ;
return NULL ;
}
}
2015-06-12 12:50:20 +03:00
if ( par_dev_cb - > flags & PARPORT_DEV_EXCL ) {
if ( port - > physport - > devices ) {
/*
* If a device is already registered and this new
* device wants exclusive access , then no need to
* continue as we can not grant exclusive access to
* this device .
*/
pr_err ( " %s: cannot grant exclusive access for device %s \n " ,
port - > name , name ) ;
return NULL ;
}
}
2015-05-20 18:26:57 +03:00
if ( ! try_module_get ( port - > ops - > owner ) )
return NULL ;
parport_get_port ( port ) ;
par_dev = kzalloc ( sizeof ( * par_dev ) , GFP_KERNEL ) ;
if ( ! par_dev )
goto err_put_port ;
par_dev - > state = kzalloc ( sizeof ( * par_dev - > state ) , GFP_KERNEL ) ;
if ( ! par_dev - > state )
goto err_put_par_dev ;
devname = kstrdup ( name , GFP_KERNEL ) ;
if ( ! devname )
goto err_free_par_dev ;
par_dev - > name = devname ;
par_dev - > port = port ;
par_dev - > daisy = - 1 ;
par_dev - > preempt = par_dev_cb - > preempt ;
par_dev - > wakeup = par_dev_cb - > wakeup ;
par_dev - > private = par_dev_cb - > private ;
par_dev - > flags = par_dev_cb - > flags ;
par_dev - > irq_func = par_dev_cb - > irq_func ;
par_dev - > waiting = 0 ;
par_dev - > timeout = 5 * HZ ;
par_dev - > dev . parent = & port - > bus_dev ;
par_dev - > dev . bus = & parport_bus_type ;
ret = dev_set_name ( & par_dev - > dev , " %s.%d " , devname , id ) ;
if ( ret )
goto err_free_devname ;
par_dev - > dev . release = free_pardevice ;
par_dev - > devmodel = true ;
ret = device_register ( & par_dev - > dev ) ;
2015-06-15 17:35:51 +03:00
if ( ret ) {
put_device ( & par_dev - > dev ) ;
goto err_put_port ;
}
2015-05-20 18:26:57 +03:00
/* Chain this onto the list */
par_dev - > prev = NULL ;
/*
* This function must not run from an irq handler so we don ' t need
* to clear irq on the local CPU . - arca
*/
spin_lock ( & port - > physport - > pardevice_lock ) ;
if ( par_dev_cb - > flags & PARPORT_DEV_EXCL ) {
if ( port - > physport - > devices ) {
spin_unlock ( & port - > physport - > pardevice_lock ) ;
pr_debug ( " %s: cannot grant exclusive access for device %s \n " ,
port - > name , name ) ;
2015-06-15 17:35:49 +03:00
device_unregister ( & par_dev - > dev ) ;
goto err_put_port ;
2015-05-20 18:26:57 +03:00
}
port - > flags | = PARPORT_FLAG_EXCL ;
}
par_dev - > next = port - > physport - > devices ;
wmb ( ) ; /*
* Make sure that tmp - > next is written before it ' s
* added to the list ; see comments marked ' no locking
* required '
*/
if ( port - > physport - > devices )
port - > physport - > devices - > prev = par_dev ;
port - > physport - > devices = par_dev ;
spin_unlock ( & port - > physport - > pardevice_lock ) ;
init_waitqueue_head ( & par_dev - > wait_q ) ;
par_dev - > timeslice = parport_default_timeslice ;
par_dev - > waitnext = NULL ;
par_dev - > waitprev = NULL ;
/*
* This has to be run as last thing since init_state may need other
* pardevice fields . - arca
*/
port - > ops - > init_state ( par_dev , par_dev - > state ) ;
port - > proc_device = par_dev ;
parport_device_proc_register ( par_dev ) ;
return par_dev ;
err_free_devname :
kfree ( devname ) ;
err_free_par_dev :
kfree ( par_dev - > state ) ;
err_put_par_dev :
if ( ! par_dev - > devmodel )
kfree ( par_dev ) ;
err_put_port :
parport_put_port ( port ) ;
module_put ( port - > ops - > owner ) ;
return NULL ;
}
EXPORT_SYMBOL ( parport_register_dev_model ) ;
2005-04-17 02:20:36 +04:00
/**
* parport_unregister_device - deregister a device on a parallel port
* @ dev : pointer to structure representing device
*
* This undoes the effect of parport_register_device ( ) .
* */
void parport_unregister_device ( struct pardevice * dev )
{
struct parport * port ;
# ifdef PARPORT_PARANOID
2015-10-28 12:11:38 +03:00
if ( ! dev ) {
2005-04-17 02:20:36 +04:00
printk ( KERN_ERR " parport_unregister_device: passed NULL \n " ) ;
return ;
}
# endif
port = dev - > port - > physport ;
2009-06-02 19:58:10 +04:00
if ( port - > proc_device = = dev ) {
port - > proc_device = NULL ;
clear_bit ( PARPORT_DEVPROC_REGISTERED , & port - > devflags ) ;
parport_device_proc_unregister ( dev ) ;
}
2005-04-17 02:20:36 +04:00
if ( port - > cad = = dev ) {
printk ( KERN_DEBUG " %s: %s forgot to release port \n " ,
port - > name , dev - > name ) ;
2015-10-28 12:11:39 +03:00
parport_release ( dev ) ;
2005-04-17 02:20:36 +04:00
}
spin_lock ( & port - > pardevice_lock ) ;
if ( dev - > next )
dev - > next - > prev = dev - > prev ;
if ( dev - > prev )
dev - > prev - > next = dev - > next ;
else
port - > devices = dev - > next ;
if ( dev - > flags & PARPORT_DEV_EXCL )
port - > flags & = ~ PARPORT_FLAG_EXCL ;
spin_unlock ( & port - > pardevice_lock ) ;
2015-10-28 12:11:33 +03:00
/*
* Make sure we haven ' t left any pointers around in the wait
* list .
*/
2011-01-26 02:07:16 +03:00
spin_lock_irq ( & port - > waitlist_lock ) ;
2005-04-17 02:20:36 +04:00
if ( dev - > waitprev | | dev - > waitnext | | port - > waithead = = dev ) {
if ( dev - > waitprev )
dev - > waitprev - > waitnext = dev - > waitnext ;
else
port - > waithead = dev - > waitnext ;
if ( dev - > waitnext )
dev - > waitnext - > waitprev = dev - > waitprev ;
else
port - > waittail = dev - > waitprev ;
}
2011-01-26 02:07:16 +03:00
spin_unlock_irq ( & port - > waitlist_lock ) ;
2005-04-17 02:20:36 +04:00
kfree ( dev - > state ) ;
2015-05-20 18:26:57 +03:00
if ( dev - > devmodel )
device_unregister ( & dev - > dev ) ;
else
kfree ( dev ) ;
2005-04-17 02:20:36 +04:00
module_put ( port - > ops - > owner ) ;
2015-10-28 12:11:39 +03:00
parport_put_port ( port ) ;
2005-04-17 02:20:36 +04:00
}
2015-10-28 12:11:32 +03:00
EXPORT_SYMBOL ( parport_unregister_device ) ;
2005-04-17 02:20:36 +04:00
/**
* parport_find_number - find a parallel port by number
* @ number : parallel port number
*
* This returns the parallel port with the specified number , or
* % NULL if there is none .
*
* There is an implicit parport_get_port ( ) done already ; to throw
* away the reference to the port that parport_find_number ( )
* gives you , use parport_put_port ( ) .
*/
2015-10-28 12:11:39 +03:00
struct parport * parport_find_number ( int number )
2005-04-17 02:20:36 +04:00
{
struct parport * port , * result = NULL ;
if ( list_empty ( & portlist ) )
2015-10-28 12:11:39 +03:00
get_lowlevel_driver ( ) ;
2005-04-17 02:20:36 +04:00
2015-10-28 12:11:39 +03:00
spin_lock ( & parportlist_lock ) ;
2005-04-17 02:20:36 +04:00
list_for_each_entry ( port , & portlist , list ) {
if ( port - > number = = number ) {
2015-10-28 12:11:39 +03:00
result = parport_get_port ( port ) ;
2005-04-17 02:20:36 +04:00
break ;
}
}
2015-10-28 12:11:39 +03:00
spin_unlock ( & parportlist_lock ) ;
2005-04-17 02:20:36 +04:00
return result ;
}
2015-10-28 12:11:32 +03:00
EXPORT_SYMBOL ( parport_find_number ) ;
2005-04-17 02:20:36 +04:00
/**
* parport_find_base - find a parallel port by base address
* @ base : base I / O address
*
* This returns the parallel port with the specified base
* address , or % NULL if there is none .
*
* There is an implicit parport_get_port ( ) done already ; to throw
* away the reference to the port that parport_find_base ( )
* gives you , use parport_put_port ( ) .
*/
2015-10-28 12:11:39 +03:00
struct parport * parport_find_base ( unsigned long base )
2005-04-17 02:20:36 +04:00
{
struct parport * port , * result = NULL ;
if ( list_empty ( & portlist ) )
2015-10-28 12:11:39 +03:00
get_lowlevel_driver ( ) ;
2005-04-17 02:20:36 +04:00
2015-10-28 12:11:39 +03:00
spin_lock ( & parportlist_lock ) ;
2005-04-17 02:20:36 +04:00
list_for_each_entry ( port , & portlist , list ) {
if ( port - > base = = base ) {
2015-10-28 12:11:39 +03:00
result = parport_get_port ( port ) ;
2005-04-17 02:20:36 +04:00
break ;
}
}
2015-10-28 12:11:39 +03:00
spin_unlock ( & parportlist_lock ) ;
2005-04-17 02:20:36 +04:00
return result ;
}
2015-10-28 12:11:32 +03:00
EXPORT_SYMBOL ( parport_find_base ) ;
2005-04-17 02:20:36 +04:00
/**
* parport_claim - claim access to a parallel port device
* @ dev : pointer to structure representing a device on the port
*
* This function will not block and so can be used from interrupt
* context . If parport_claim ( ) succeeds in claiming access to
* the port it returns zero and the port is available to use . It
* may fail ( returning non - zero ) if the port is in use by another
* driver and that driver is not willing to relinquish control of
* the port .
* */
int parport_claim ( struct pardevice * dev )
{
struct pardevice * oldcad ;
struct parport * port = dev - > port - > physport ;
unsigned long flags ;
if ( port - > cad = = dev ) {
printk ( KERN_INFO " %s: %s already owner \n " ,
dev - > port - > name , dev - > name ) ;
return 0 ;
}
/* Preempt any current device */
2015-10-28 12:11:39 +03:00
write_lock_irqsave ( & port - > cad_lock , flags ) ;
2015-10-28 12:11:40 +03:00
oldcad = port - > cad ;
if ( oldcad ) {
2005-04-17 02:20:36 +04:00
if ( oldcad - > preempt ) {
if ( oldcad - > preempt ( oldcad - > private ) )
goto blocked ;
port - > ops - > save_state ( port , dev - > state ) ;
} else
goto blocked ;
if ( port - > cad ! = oldcad ) {
2015-10-28 12:11:33 +03:00
/*
* I think we ' ll actually deadlock rather than
* get here , but just in case . .
*/
2005-04-17 02:20:36 +04:00
printk ( KERN_WARNING
" %s: %s released port when preempted! \n " ,
port - > name , oldcad - > name ) ;
if ( port - > cad )
goto blocked ;
}
}
/* Can't fail from now on, so mark ourselves as no longer waiting. */
if ( dev - > waiting & 1 ) {
dev - > waiting = 0 ;
/* Take ourselves out of the wait list again. */
2015-10-28 12:11:39 +03:00
spin_lock_irq ( & port - > waitlist_lock ) ;
2005-04-17 02:20:36 +04:00
if ( dev - > waitprev )
dev - > waitprev - > waitnext = dev - > waitnext ;
else
port - > waithead = dev - > waitnext ;
if ( dev - > waitnext )
dev - > waitnext - > waitprev = dev - > waitprev ;
else
port - > waittail = dev - > waitprev ;
2015-10-28 12:11:39 +03:00
spin_unlock_irq ( & port - > waitlist_lock ) ;
2005-04-17 02:20:36 +04:00
dev - > waitprev = dev - > waitnext = NULL ;
}
/* Now we do the change of devices */
port - > cad = dev ;
# ifdef CONFIG_PARPORT_1284
/* If it's a mux port, select it. */
if ( dev - > port - > muxport > = 0 ) {
/* FIXME */
port - > muxsel = dev - > port - > muxport ;
}
/* If it's a daisy chain device, select it. */
if ( dev - > daisy > = 0 ) {
/* This could be lazier. */
2015-10-28 12:11:39 +03:00
if ( ! parport_daisy_select ( port , dev - > daisy ,
2005-04-17 02:20:36 +04:00
IEEE1284_MODE_COMPAT ) )
port - > daisy = dev - > daisy ;
}
# endif /* IEEE1284.3 support */
/* Restore control registers */
port - > ops - > restore_state ( port , dev - > state ) ;
write_unlock_irqrestore ( & port - > cad_lock , flags ) ;
dev - > time = jiffies ;
return 0 ;
blocked :
2015-10-28 12:11:33 +03:00
/*
* If this is the first time we tried to claim the port , register an
* interest . This is only allowed for devices sleeping in
* parport_claim_or_block ( ) , or those with a wakeup function .
*/
2005-04-17 02:20:36 +04:00
/* The cad_lock is still held for writing here */
if ( dev - > waiting & 2 | | dev - > wakeup ) {
2015-10-28 12:11:39 +03:00
spin_lock ( & port - > waitlist_lock ) ;
2005-04-17 02:20:36 +04:00
if ( test_and_set_bit ( 0 , & dev - > waiting ) = = 0 ) {
/* First add ourselves to the end of the wait list. */
dev - > waitnext = NULL ;
dev - > waitprev = port - > waittail ;
if ( port - > waittail ) {
port - > waittail - > waitnext = dev ;
port - > waittail = dev ;
} else
port - > waithead = port - > waittail = dev ;
}
2015-10-28 12:11:39 +03:00
spin_unlock ( & port - > waitlist_lock ) ;
2005-04-17 02:20:36 +04:00
}
2015-10-28 12:11:39 +03:00
write_unlock_irqrestore ( & port - > cad_lock , flags ) ;
2005-04-17 02:20:36 +04:00
return - EAGAIN ;
}
2015-10-28 12:11:32 +03:00
EXPORT_SYMBOL ( parport_claim ) ;
2005-04-17 02:20:36 +04:00
/**
* parport_claim_or_block - claim access to a parallel port device
* @ dev : pointer to structure representing a device on the port
*
* This behaves like parport_claim ( ) , but will block if necessary
* to wait for the port to be free . A return value of 1
* indicates that it slept ; 0 means that it succeeded without
* needing to sleep . A negative error code indicates failure .
* */
int parport_claim_or_block ( struct pardevice * dev )
{
int r ;
2015-10-28 12:11:33 +03:00
/*
* Signal to parport_claim ( ) that we can wait even without a
* wakeup function .
*/
2005-04-17 02:20:36 +04:00
dev - > waiting = 2 ;
/* Try to claim the port. If this fails, we need to sleep. */
r = parport_claim ( dev ) ;
if ( r = = - EAGAIN ) {
# ifdef PARPORT_DEBUG_SHARING
printk ( KERN_DEBUG " %s: parport_claim() returned -EAGAIN \n " , dev - > name ) ;
# endif
/*
* FIXME ! ! ! Use the proper locking for dev - > waiting ,
* and make this use the " wait_event_interruptible() "
* interfaces . The cli / sti that used to be here
* did nothing .
*
* See also parport_release ( )
*/
2015-10-28 12:11:33 +03:00
/*
* If dev - > waiting is clear now , an interrupt
* gave us the port and we would deadlock if we slept .
*/
2005-04-17 02:20:36 +04:00
if ( dev - > waiting ) {
2014-02-26 15:01:49 +04:00
wait_event_interruptible ( dev - > wait_q ,
! dev - > waiting ) ;
2015-10-28 12:11:39 +03:00
if ( signal_pending ( current ) )
2005-04-17 02:20:36 +04:00
return - EINTR ;
r = 1 ;
} else {
r = 0 ;
# ifdef PARPORT_DEBUG_SHARING
printk ( KERN_DEBUG " %s: didn't sleep in parport_claim_or_block() \n " ,
dev - > name ) ;
# endif
}
# ifdef PARPORT_DEBUG_SHARING
if ( dev - > port - > physport - > cad ! = dev )
2015-10-28 12:11:35 +03:00
printk ( KERN_DEBUG " %s: exiting parport_claim_or_block but %s owns port! \n " ,
dev - > name , dev - > port - > physport - > cad ?
2005-04-17 02:20:36 +04:00
dev - > port - > physport - > cad - > name : " nobody " ) ;
# endif
}
dev - > waiting = 0 ;
return r ;
}
2015-10-28 12:11:32 +03:00
EXPORT_SYMBOL ( parport_claim_or_block ) ;
2005-04-17 02:20:36 +04:00
/**
* parport_release - give up access to a parallel port device
* @ dev : pointer to structure representing parallel port device
*
* This function cannot fail , but it should not be called without
* the port claimed . Similarly , if the port is already claimed
* you should not try claiming it again .
* */
void parport_release ( struct pardevice * dev )
{
struct parport * port = dev - > port - > physport ;
struct pardevice * pd ;
unsigned long flags ;
/* Make sure that dev is the current device */
write_lock_irqsave ( & port - > cad_lock , flags ) ;
if ( port - > cad ! = dev ) {
2015-10-28 12:11:39 +03:00
write_unlock_irqrestore ( & port - > cad_lock , flags ) ;
2015-10-28 12:11:35 +03:00
printk ( KERN_WARNING " %s: %s tried to release parport when not owner \n " ,
port - > name , dev - > name ) ;
2005-04-17 02:20:36 +04:00
return ;
}
# ifdef CONFIG_PARPORT_1284
/* If this is on a mux port, deselect it. */
if ( dev - > port - > muxport > = 0 ) {
/* FIXME */
port - > muxsel = - 1 ;
}
/* If this is a daisy device, deselect it. */
if ( dev - > daisy > = 0 ) {
2015-10-28 12:11:39 +03:00
parport_daisy_deselect_all ( port ) ;
2005-04-17 02:20:36 +04:00
port - > daisy = - 1 ;
}
# endif
port - > cad = NULL ;
write_unlock_irqrestore ( & port - > cad_lock , flags ) ;
/* Save control registers */
port - > ops - > save_state ( port , dev - > state ) ;
2015-10-28 12:11:33 +03:00
/*
* If anybody is waiting , find out who ' s been there longest and
* then wake them up . ( Note : no locking required )
*/
2005-04-17 02:20:36 +04:00
/* !!! LOCKING IS NEEDED HERE */
for ( pd = port - > waithead ; pd ; pd = pd - > waitnext ) {
if ( pd - > waiting & 2 ) { /* sleeping in claim_or_block */
parport_claim ( pd ) ;
if ( waitqueue_active ( & pd - > wait_q ) )
wake_up_interruptible ( & pd - > wait_q ) ;
return ;
} else if ( pd - > wakeup ) {
pd - > wakeup ( pd - > private ) ;
if ( dev - > port - > cad ) /* racy but no matter */
return ;
} else {
printk ( KERN_ERR " %s: don't know how to wake %s \n " , port - > name , pd - > name ) ;
}
}
2015-10-28 12:11:33 +03:00
/*
* Nobody was waiting , so walk the list to see if anyone is
* interested in being woken up . ( Note : no locking required )
*/
2005-04-17 02:20:36 +04:00
/* !!! LOCKING IS NEEDED HERE */
2015-10-28 12:11:38 +03:00
for ( pd = port - > devices ; ! port - > cad & & pd ; pd = pd - > next ) {
2005-04-17 02:20:36 +04:00
if ( pd - > wakeup & & pd ! = dev )
pd - > wakeup ( pd - > private ) ;
}
}
2015-10-28 12:11:32 +03:00
EXPORT_SYMBOL ( parport_release ) ;
2005-04-17 02:20:36 +04:00
2007-10-19 09:42:14 +04:00
irqreturn_t parport_irq_handler ( int irq , void * dev_id )
{
struct parport * port = dev_id ;
2007-10-19 09:56:02 +04:00
parport_generic_irq ( port ) ;
2007-10-19 09:42:14 +04:00
return IRQ_HANDLED ;
}
EXPORT_SYMBOL ( parport_irq_handler ) ;
2005-04-17 02:20:36 +04:00
MODULE_LICENSE ( " GPL " ) ;