Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[pb] Basic sysfs skeleton providing a "program" binary attribute
Signed-off-by: Michael Brown <mbrown@fensystems.co.uk>
  • Loading branch information
mcb30 committed Oct 9, 2010
1 parent 29796e8 commit c8f0023
Showing 1 changed file with 92 additions and 3 deletions.
95 changes: 92 additions & 3 deletions pulseblaster.c
Expand Up @@ -6,10 +6,57 @@
/** Pulseblaster driver name */
#define PB_NAME "pulseblaster"

/** Pulseblaster instruction word size */
#define PB_WORDSIZE 10

/** Pulseblaster class */
static struct class *pb_class;

/** A Pulseblaster device */
struct pulseblaster {
/** I/O port base address */
unsigned long iobase;
/** Class device */
struct device *dev;
/** Device access semaphore */
struct semaphore sem;
};

/**
* Program Pulseblaster device
*
*/
static ssize_t pulseblaster_program ( struct kobject *kobj,
struct bin_attribute *attr,
char *buf, loff_t off, size_t size ) {
struct device *dev = container_of ( kobj, struct device, kobj );
struct pulseblaster *pb = dev_get_drvdata ( dev );
int rc;

/* Lock device */
if ( ( rc = down_interruptible ( &pb->sem ) ) != 0 )
goto err_down;

printk ( "%s: program %#04zx bytes at %#04llx\n",
dev_name ( dev ), size, off );

/* Unlock device and return */
up ( &pb->sem );
return size;

up ( &pb->sem );
err_down:
return rc;
}

/** Pulseblaster program device attribute */
static struct bin_attribute dev_attr_program = {
.attr = {
.name = "program",
.mode = ( S_IWUSR | S_IRUGO ),
},
.size = 32768 * PB_WORDSIZE,
.write = pulseblaster_program,
};

/**
Expand All @@ -21,15 +68,17 @@ struct pulseblaster {
*/
static int __devinit pb_probe ( struct pci_dev *pci,
const struct pci_device_id *id ) {
static unsigned int pbidx = 0;
struct pulseblaster *pb;
int rc;

/* Allocate and initialise structure */
pb = kmalloc ( sizeof ( *pb ), GFP_KERNEL );
pb = kzalloc ( sizeof ( *pb ), GFP_KERNEL );
if ( ! pb ) {
rc = -ENOMEM;
goto err_alloc;
}
sema_init ( &pb->sem, 1 );

/* Enable PCI device */
if ( ( rc = pci_enable_device ( pci ) ) != 0 )
Expand All @@ -42,10 +91,28 @@ static int __devinit pb_probe ( struct pci_dev *pci,
/* Set I/O base address */
pb->iobase = pci_resource_start ( pci, 0 );

printk ( PB_NAME " at %04lx\n", pb->iobase );
/* Create class device */
pb->dev = device_create ( pb_class, &pci->dev, 0, pb,
PB_NAME "%d", pbidx++ );
if ( IS_ERR ( pb->dev ) ) {
rc = PTR_ERR ( pb->dev );
goto err_device_create;
}

/* Create program attribute */
if ( ( rc = device_create_bin_file ( pb->dev,
&dev_attr_program ) ) != 0 ) {
goto err_device_create_bin_file;
}

printk ( "%s: I/O at %04lx\n", dev_name ( pb->dev ), pb->iobase );
pci_set_drvdata ( pci, pb );
return 0;

device_remove_bin_file ( pb->dev, &dev_attr_program );
err_device_create_bin_file:
device_unregister ( pb->dev );
err_device_create:
pci_release_regions ( pci );
err_request_regions:
pci_disable_device ( pci );
Expand All @@ -63,6 +130,8 @@ static int __devinit pb_probe ( struct pci_dev *pci,
static void __devexit pb_remove ( struct pci_dev *pci ) {
struct pulseblaster *pb = pci_get_drvdata ( pci );

device_remove_bin_file ( pb->dev, &dev_attr_program );
device_unregister ( pb->dev );
pci_release_regions ( pci );
pci_disable_device ( pci );
kfree ( pb );
Expand All @@ -88,7 +157,26 @@ static struct pci_driver pb_pci_driver = {
* @ret rc Return status code
*/
static int __init pb_module_init ( void ) {
return pci_register_driver ( &pb_pci_driver );
int rc;

/* Register class */
pb_class = class_create ( THIS_MODULE, PB_NAME );
if ( IS_ERR ( pb_class ) ) {
rc = PTR_ERR ( pb_class );
goto err_class_create;
}

/* Register PCI driver */
if ( ( rc = pci_register_driver ( &pb_pci_driver ) ) != 0 )
goto err_pci_register_driver;

return 0;

pci_unregister_driver ( &pb_pci_driver );
err_pci_register_driver:
class_destroy ( pb_class );
err_class_create:
return rc;
}

/**
Expand All @@ -97,6 +185,7 @@ static int __init pb_module_init ( void ) {
*/
static void __exit pb_module_exit ( void ) {
pci_unregister_driver ( &pb_pci_driver );
class_destroy ( pb_class );
}

module_init(pb_module_init);
Expand Down

0 comments on commit c8f0023

Please sign in to comment.