All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Rafał Bilski" <rafalbilski@interia.pl>
To: Dave Jones <davej@codemonkey.org.uk>
Cc: cpufreq@lists.linux.org.uk
Subject: Longhaul - infrastructure(?) proposal
Date: Thu, 29 Jun 2006 17:05:19 +0200	[thread overview]
Message-ID: <44A3EC2F.7040909@interia.pl> (raw)

Hello!

In case that flushing and disabling caches will not work.
It is possible that I do above in wrong way.
Would this code below be acceptable as infrastructure?
Is this infrastructure or maybe hack?
This is draft/proposal.
Can I continue in this way or I shouldn't?

Rafa³

---

/*
 * Longhaul "infrastructure" for bus master DMA
 */

struct longhaul_work {
	struct list_head entry;
	struct work_struct work;
	struct longhaul_data *data;
	void (*device_func) (void *data);
	void *device_data;
};

struct longhaul_data {
	struct workqueue_struct *wq;
	spinlock_t lock;
	struct list_head work_unused;
	struct list_head work_inuse;
	struct list_head work_used;
};

/* Access control for PCI bus */
static struct rw_semaphore longhaul_sem;

struct longhaul_data *longhaul_bmdma_register(char *name)
{
	struct longhaul_data *longdata;
	struct longhaul_work *longwork;
	struct workqueue_struct *workqueue;

	longdata = kmalloc(sizeof(struct longhaul_data), GFP_KERNEL);
	if (longdata == NULL)
		return NULL;
	spin_lock_init(&longdata->lock);
	INIT_LIST_HEAD(&longdata->work_unused);
	INIT_LIST_HEAD(&longdata->work_inuse);
	INIT_LIST_HEAD(&longdata->work_used);

	longwork = kmalloc(sizeof(struct longhaul_work), GFP_KERNEL);
	if (longwork == NULL) {
		goto free_longdata;
	}
	INIT_WORK(&longwork->work, &longhaul_bmdma_work, NULL);
	list_add(longwork, &longdata->work_unused);
	longwork->data = longdata;

	workqueue = create_singlethread_workqueue(name);
	if (workqueue == NULL) {
		printk(KERN_ERR PFX "Can't create workqueue \"%s\".\n", name);
		goto free_longwork;
	}
	longdata->wq = workqueue;

	return longdata;

free_longwork:
	kfree(longwork);
free_longdata:
	kfree(longdata);
	return NULL;
}
EXPORT_SYMBOL(longhaul_bmdma_register);


void longhaul_bmdma_unregister(struct longhaul_data *longdata)
{
}
EXPORT_SYMBOL(longhaul_bmdma_unregister);


static void longhaul_bmdma_work(void *data)
{
	struct longhaul_work *longwork = data;
	struct longhaul_data *longdata = longwork->data;
	unsigned long flags;

	down_read(&longhaul_sem);

	longdata->device_func(longdata->device_data);

	spin_lock_irqsave(&longdata->lock, flags);
	list_move(longwork, &longdata->work_used);
	spin_unlock_irqrestore(&longdata->lock, flags);
}

int longhaul_bmdma_begin(struct longhaul_data *longdata,
			void (*device_func) (void *data),
			void *device_data);
{
	struct longhaul_work *longwork;
	unsigned long flags;

	spin_lock_irqsave(&longdata->lock, flags);

	if ( list_empty(&longdata->work_unused) ) {
		longwork = kmalloc(sizeof(struct longhaul_work), GFP_ATOMIC);
		if (longwork == NULL) {
			spin_unlock_irqrestore(&longdata->lock, flags);
			return -ENOMEM;
		}
		INIT_WORK(&longwork->work, &longhaul_bmdma_work, NULL);
		longwork->data = longdata;
		list_add(longwork, &longdata->work_inuse);
	} else {
		longwork = longdata->work_unused->next;
		list_move(longwork, &longdata->work_inuse);
	}

	spin_unlock_irqrestore(&longdata->lock, flags);

	longwork->device_func = device_func;
	longwork->device_data = device_data;
	PREPARE_WORK(longwork, &longhaul_bmdma_work, (void*)longwork);
	queue_work(longdata->wq, longwork);

	return 0;
}
EXPORT_SYMBOL(longhaul_bmdma_begin);


void longhaul_bmdma_end(struct longhaul_data *longdata)
{
	struct list_head pos;
	unsigned long flags;

	spin_lock_irqsave(&longdata->lock, flags);

	if ( !list_empty(&longdata->work_used) ) {
		list_for_each(pos, &longdata->work_used) {
			list_move(longwork, &longdata->work_unused);
		}
	}

	spin_unlock_irqrestore(&longdata->lock, flags);

	up_read(&longhaul_sem);
}
EXPORT_SYMBOL(longhaul_bmdma_end);


----------------------------------------------------------------------
PS. Fajny portal... >>> http://link.interia.pl/f196a

             reply	other threads:[~2006-06-29 15:05 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-06-29 15:05 Rafał Bilski [this message]
2006-06-29 19:28 ` Longhaul - infrastructure(?) proposal Dave Jones
  -- strict thread matches above, loose matches on Subject: below --
2006-06-29 20:26 Rafał Bilski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=44A3EC2F.7040909@interia.pl \
    --to=rafalbilski@interia.pl \
    --cc=cpufreq@lists.linux.org.uk \
    --cc=davej@codemonkey.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.