#define MODIFANNOT(X)  MICRODRIVERS__MODIF_ ## X
#define MODIFIES(var)  MICRODRIVERS__DUMMY((void *) var)
#define READS(var)     MICRODRIVERS__DUMMY((void *) var)
#define MODIFIES_ADDROF(var) MICRODRIVERS__DUMMY((void *) &var)

void MICRODRIVERS__DUMMY(void *x) {
  return;
}

// Does not modify anything.
const char *MODIFANNOT(dev_driver_string) (struct device *dev) {
    return 0;
}

int MODIFANNOT(pci_bus_write_config_word) (struct pci_bus *bus, unsigned int devfn, int where, u16 val) {
    return 0;
}

/* DONE */
void MODIFANNOT(_spin_lock) (spinlock_t *lock) {
    return;
}

/* DONE */
void MODIFANNOT(__spin_lock_init)
  (spinlock_t *lock, const char *name, struct lock_class_key *key) {
  return;
}

// DONE
void MODIFANNOT(_spin_lock_irq) (spinlock_t *lock) {
    return;
}

/* DONE */
void MODIFANNOT(_spin_lock_irqsave) (spinlock_t *lock) {
    return;
}

/* DONE */
void MODIFANNOT(_spin_unlock)
  (spinlock_t *lock) {
  return;
}

void MODIFANNOT(_spin_unlock_irq) (spinlock_t *lock) {
    return;
}

/* DONE */
void MODIFANNOT(_spin_unlock_irqrestore)
  (spinlock_t *lock, unsigned long flags) {
  return;
}

void * MODIFANNOT(dma_alloc_coherent)
    (struct device *dev, size_t size,
     dma_addr_t *dma_handle, gfp_t flag) {
    //MODIFIES(dev->dma_mem);
    MODIFIES(dev->coherent_dma_mask);
    return 0;
}

/* DONE */
void MODIFANNOT(dma_free_coherent)
    (struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle) {
    //MODIFIES(dev->dma_mem);
    return;
}

/* TODO */
void *MODIFANNOT(page_address) (struct page *page) {
    return 0;
}

/* TODO */
int MODIFANNOT(pci_bus_read_config_byte)
    (struct pci_bus *bus,
     unsigned int devfn,
     int where,
     u8 *val)
{
    MODIFIES(val);
    return 0;
}

/* TODO */
int MODIFANNOT(pci_bus_read_config_word)
    (struct pci_bus *bus,
     unsigned int devfn,
     int where,
     u16 *val)
{
    MODIFIES(val);
    return 0;
}

pci_power_t MODIFANNOT(pci_choose_state)
    (struct pci_dev *dev,
     pm_message_t state)
{
    return 0;
}

/* TODO */
void MODIFANNOT(pci_clear_mwi) (struct pci_dev *dev) {
    return;
}

/* DONE */
void MODIFANNOT(pci_disable_device)
    (struct pci_dev *dev) {
    return;
}

/* TODO */
int MODIFANNOT(pci_enable_device)
    (struct pci_dev *dev) {
    return 0;
}

/* TODO */
int MODIFANNOT(pci_enable_wake)
    (struct pci_dev *dev,
     pci_power_t state,
     int enable)
{
    return 0;
}

/* TODO */
int MODIFANNOT(__pci_register_driver)
    (struct pci_driver *drv, struct module *owner) {
    MODIFIES(drv->driver.name);
    MODIFIES(drv->name);
    MODIFIES(drv->driver.bus);
    MODIFIES(drv->driver.owner);
    MODIFIES_ADDROF(drv->dynids.lock);
    MODIFIES_ADDROF(drv->dynids.list);
    MODIFIES_ADDROF(drv->driver);
    MODIFIES(drv->probe);

    return 0;
}

/* TODO */
void MODIFANNOT(pci_release_regions)
    (struct pci_dev *pdev)
{
    return;
}

/* TODO */
int MODIFANNOT(pci_request_regions)
    (struct pci_dev *pdev,
     const char *res_name)
{
    MODIFIES(pdev->resource);
    return 0;
}

/* TODO */
int MODIFANNOT(pci_restore_state)
    (struct pci_dev *dev)
{
    return 0;
}

/* TODO */
int MODIFANNOT(pci_save_state)
    (struct pci_dev *dev)
{
    return 0;
}

/* TODO */
int MODIFANNOT(pci_set_consistent_dma_mask)
    (struct pci_dev *dev, u64 mask)
{
    return 0;
}

/* TODO */
int MODIFANNOT(pci_set_dma_mask)
    (struct pci_dev *dev, u64 mask)
{
    return 0;
}

/* DONE */
void MODIFANNOT(pci_set_master)
    (struct pci_dev *dev) {
    return;
}

/* TODO */
int MODIFANNOT(pci_set_mwi) (struct pci_dev *dev)
{
    return 0;
}

/* TODO */
int  MODIFANNOT(pci_set_power_state)
    (struct pci_dev *dev,
     pci_power_t state)
{
    return 0;
}

/* TODO */
void MODIFANNOT(pci_unregister_driver)
    (struct pci_driver *drv) {
    MODIFIES_ADDROF(drv->driver);
    return;
}

/* DONE */
int MODIFANNOT(request_irq)
    (unsigned int a,
     irqreturn_t (*handler)(int, void *, struct pt_regs *),
     unsigned long b, const char * c, void * d) {
    return 0;
}

void MODIFANNOT(free_irq)
    (unsigned int irq , struct net_device *dev )
{
    return;
}

void MODIFANNOT(cancel_rearming_delayed_work)
    (struct work_struct *work)
{
}

int MODIFANNOT(schedule_delayed_work)
    (struct delayed_work *work,
     unsigned long delay)
{
    MODIFIES(work->work.data.counter);
    MODIFIES(work->work.entry.next);
    MODIFIES(work->work.entry.prev);
    MODIFIES(work->work.func);
    MODIFIES(work->timer.entry.next);
    MODIFIES(work->timer.entry.prev);
    MODIFIES(work->timer.expires);
    MODIFIES(work->timer.function);
    MODIFIES(work->timer.data);
    return 0;
}

void MODIFANNOT(init_timer)(struct timer_list *timer)
{
    // These are marshaled, but it saves modifying timer.h (see e1000)
    /*MODIFIES(timer->entry.next);
      MODIFIES(timer->base);*/
}

void MODIFANNOT(_spin_unlock_bh)(spinlock_t *lock)
{
}

void MODIFANNOT(_spin_lock_bh)(spinlock_t *lock)
{
}

//
// Sound driver specific CA0106
//

// DONE
void *MODIFANNOT(pci_get_drvdata)(struct pci_dev *pdev) {
    MODIFIES(pdev->dev.driver_data);
    return NULL;
}

// TODO
void MODIFANNOT(pci_read_config_dword)() {
    return;
}

// TODO
void MODIFANNOT(pci_read_config_word)() {
    return;
}

// DONE
void MODIFANNOT(pci_set_drvdata)(struct pci_dev *pdev, void *data) {
    MODIFIES(pdev->dev.driver_data);
    return;
}

// DONE
void MODIFANNOT(release_and_free_resource)(struct resource *res) {
    return;
}

// TODO, probably doesn't matter
struct resource *MODIFANNOT(__request_region)(struct resource *parent,
                                              resource_size_t start, resource_size_t n,
                                              const char *name, int flags) {
    
    return NULL;
}

// DONE
int MODIFANNOT(snd_ac97_bus)(struct snd_card *card, int num, struct snd_ac97_bus_ops *ops,
                             void *private_data, struct snd_ac97_bus **rbus) {
    return 0;
}

// DONE
int MODIFANNOT(snd_ac97_mixer)(struct snd_ac97_bus *bus,
                               struct snd_ac97_template *template,
                               struct snd_ac97 **rac97) {
    return 0;
}

int MODIFANNOT(snd_card_free)(struct snd_card * card) {
    return 0;
}

/*
struct snd_card *MODIFANNOT(snd_card_new)(int  idx,
                                          char const   * xid,
                                          struct module * module,
                                          int  extra_size) {
    return NULL;
}
*/
int MODIFANNOT(snd_card_proc_new)(struct snd_card * card, char const   * name, struct snd_info_entry ** entryp) {
    return 0;
}

/*
int MODIFANNOT(snd_card_register)(struct snd_card * card) {
    return 0;
}
*/

/*
int MODIFANNOT(snd_card_register)(struct snd_card * card) {
    return 0;
}
*/

int MODIFANNOT(snd_ctl_add)(struct snd_card * card, struct snd_kcontrol * kcontrol) {
    return 0;
}

int MODIFANNOT(snd_ctl_add_slave)(struct snd_kcontrol * master, struct snd_kcontrol * slave) {
    return 0;
}

struct snd_kcontrol *MODIFANNOT(snd_ctl_find_id)(struct snd_card * card, struct snd_ctl_elem_id * id) {
    return NULL;
}

struct snd_kcontrol *MODIFANNOT(snd_ctl_make_virtual_master)(char * name, unsigned int const   * tlv) {
    return NULL;
}

void MODIFANNOT(snd_ctl_new1)(const struct snd_kcontrol_new *ncontrol,
                              void *private_data) {
    MODIFIES(ncontrol->info);
    MODIFIES(ncontrol->iface);
    MODIFIES(ncontrol->device);
    MODIFIES(ncontrol->subdevice);
    MODIFIES(ncontrol->name);
    MODIFIES(ncontrol->index);
    MODIFIES(ncontrol->count);
    MODIFIES(ncontrol->access);
    MODIFIES(ncontrol->get);
    MODIFIES(ncontrol->put);
    MODIFIES(ncontrol->tlv.p);
    MODIFIES(ncontrol->private_value);
    return;
}

int MODIFANNOT(snd_ctl_remove_id)(struct snd_card * card, struct snd_ctl_elem_id * id) {
    return 0;
}

/*
int MODIFANNOT(snd_device_new)(struct snd_card * card,
                               snd_device_type_t  type,
                               void * device_data,
                               struct snd_device_ops * ops) {
    return 0;
}
*/

int MODIFANNOT(snd_dma_alloc_pages)(int type, struct device *device, size_t size,
                                    struct snd_dma_buffer *dmab) {
    return 0;
}

void MODIFANNOT(snd_dma_free_pages)(struct snd_dma_buffer * dmab) {
    return;
}

int MODIFANNOT(snd_info_get_line)(struct snd_info_buffer * buffer,
                                  char * line,
                                  int  len) {
    return 0;
}

void MODIFANNOT(snd_iprintf)() {
    return;
}

int MODIFANNOT(snd_pcm_hw_constraint_integer)(struct snd_pcm_runtime * runtime,
                                              snd_pcm_hw_param_t  var) {
    return 0;
}

int MODIFANNOT(snd_pcm_hw_constraint_step)(struct snd_pcm_runtime * runtime,
                                           unsigned int  cond,
                                           snd_pcm_hw_param_t  var,
                                           unsigned long  step) {
    return 0;
}

void MODIFANNOT(snd_pcm_lib_free_pages)() {
    return;
}

void MODIFANNOT(snd_pcm_lib_malloc_pages)() {
    return;
}

void MODIFANNOT(snd_pcm_lib_preallocate_pages)() {
    return;
}

int MODIFANNOT(snd_pcm_new)(struct snd_card * card,
                            char * id,
                            int  device,
                            int  playback_count,
                            int  capture_count,
                            struct snd_pcm ** rpcm) {
    return 0;
}

void MODIFANNOT(snd_pcm_period_elapsed)(struct snd_pcm_substream * substream) {
    /* snd_pcm_period_elapsed generated automatically */
    return;
}

void MODIFANNOT(snd_pcm_set_ops)(struct snd_pcm * pcm,
                                 int  direction,
                                 struct snd_pcm_ops * ops) {
    return;
}


void MODIFANNOT(snd_pcm_set_sync)(struct snd_pcm_substream * substream) {
    return;
}

int MODIFANNOT(snd_rawmidi_new)(struct snd_card * card,
                                char * id,
                                int  device,
                                int  output_count,
                                int  input_count,
                                struct snd_rawmidi ** rrawmidi) {

    return 0;
}

int MODIFANNOT(snd_rawmidi_receive)(struct snd_rawmidi_substream * substream,
                                    unsigned char const   * buffer,
                                    int  count) {

    return 0;
}

void MODIFANNOT(snd_rawmidi_set_ops)(struct snd_rawmidi * rmidi,
                                     int  stream,
                                     struct snd_rawmidi_ops * ops___0) {
}

int MODIFANNOT(snd_rawmidi_transmit)(struct snd_rawmidi_substream * substream,
                                     unsigned char * buffer,
                                     int  count) {
    return 0;
}
