All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Altobelli <david.altobelli@hp.com>
To: David Altobelli <david.altobelli@hp.com>
Cc: linux-kernel@vger.kernel.org, gregkh@suse.de
Subject: [PATCH 1/3] hpilo: staging for interrupt handling
Date: Mon, 10 Aug 2009 13:58:34 -0600	[thread overview]
Message-ID: <20090810195834.GA29404@ldl.fc.hp.com> (raw)
In-Reply-To: <20090810195735.GA29372@ldl.fc.hp.com>

Refactor some hpilo routines in order to allow for locking changes in
interrupt handling.  Should not be functionally different.

Please CC me on any replies.

Signed-off-by: David Altobelli <david.altobelli@hp.com>
---
 hpilo.c |  120 ++++++++++++++++++++++++++++++++++++++--------------------------
 1 file changed, 73 insertions(+), 47 deletions(-)
--- linux-2.6.30.3/drivers/misc/hpilo.c.orig	2009-08-05 12:53:28.000000000 -0500
+++ linux-2.6.30.3/drivers/misc/hpilo.c	2009-08-05 12:54:13.000000000 -0500
@@ -151,6 +151,7 @@ static inline void doorbell_clr(struct c
 {
 	iowrite8(2, ccb->ccb_u5.db_base);
 }
+
 static inline int ctrl_set(int l2sz, int idxmask, int desclim)
 {
 	int active = 0, go = 1;
@@ -160,6 +161,7 @@ static inline int ctrl_set(int l2sz, int
 	       active << CTRL_BITPOS_A |
 	       go << CTRL_BITPOS_G;
 }
+
 static void ctrl_setup(struct ccb *ccb, int nr_desc, int l2desc_sz)
 {
 	/* for simplicity, use the same parameters for send and recv ctrls */
@@ -192,13 +194,10 @@ static void fifo_setup(void *base_addr,
 
 static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data)
 {
-	struct ccb *driver_ccb;
-	struct ccb __iomem *device_ccb;
+	struct ccb *driver_ccb = &data->driver_ccb;
+	struct ccb __iomem *device_ccb = data->mapped_ccb;
 	int retries;
 
-	driver_ccb = &data->driver_ccb;
-	device_ccb = data->mapped_ccb;
-
 	/* complicated dance to tell the hw we are stopping */
 	doorbell_clr(driver_ccb);
 	iowrite32(ioread32(&device_ccb->send_ctrl) & ~(1 << CTRL_BITPOS_G),
@@ -225,26 +224,22 @@ static void ilo_ccb_close(struct pci_dev
 	pci_free_consistent(pdev, data->dma_size, data->dma_va, data->dma_pa);
 }
 
-static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
+static int ilo_ccb_setup(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
 {
 	char *dma_va, *dma_pa;
-	int pkt_id, pkt_sz, i, error;
 	struct ccb *driver_ccb, *ilo_ccb;
-	struct pci_dev *pdev;
 
 	driver_ccb = &data->driver_ccb;
 	ilo_ccb = &data->ilo_ccb;
-	pdev = hw->ilo_dev;
 
 	data->dma_size = 2 * fifo_sz(NR_QENTRY) +
 			 2 * desc_mem_sz(NR_QENTRY) +
 			 ILO_START_ALIGN + ILO_CACHE_SZ;
 
-	error = -ENOMEM;
-	data->dma_va = pci_alloc_consistent(pdev, data->dma_size,
+	data->dma_va = pci_alloc_consistent(hw->ilo_dev, data->dma_size,
 					    &data->dma_pa);
 	if (!data->dma_va)
-		goto out;
+		return -ENOMEM;
 
 	dma_va = (char *)data->dma_va;
 	dma_pa = (char *)data->dma_pa;
@@ -290,10 +285,18 @@ static int ilo_ccb_open(struct ilo_hwinf
 	driver_ccb->ccb_u5.db_base = hw->db_vaddr + (slot << L2_DB_SIZE);
 	ilo_ccb->ccb_u5.db_base = NULL; /* hw ccb's doorbell is not used */
 
+	return 0;
+}
+
+static void ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
+{
+	int pkt_id, pkt_sz;
+	struct ccb *driver_ccb = &data->driver_ccb;
+
 	/* copy the ccb with physical addrs to device memory */
 	data->mapped_ccb = (struct ccb __iomem *)
 				(hw->ram_vaddr + (slot * ILOHW_CCB_SZ));
-	memcpy_toio(data->mapped_ccb, ilo_ccb, sizeof(struct ccb));
+	memcpy_toio(data->mapped_ccb, &data->ilo_ccb, sizeof(struct ccb));
 
 	/* put packets on the send and receive queues */
 	pkt_sz = 0;
@@ -306,7 +309,14 @@ static int ilo_ccb_open(struct ilo_hwinf
 	for (pkt_id = 0; pkt_id < NR_QENTRY; pkt_id++)
 		ilo_pkt_enqueue(hw, driver_ccb, RECVQ, pkt_id, pkt_sz);
 
+	/* the ccb is ready to use */
 	doorbell_clr(driver_ccb);
+}
+
+static int ilo_ccb_verify(struct ilo_hwinfo *hw, struct ccb_data *data)
+{
+	int pkt_id, i;
+	struct ccb *driver_ccb = &data->driver_ccb;
 
 	/* make sure iLO is really handling requests */
 	for (i = MAX_WAIT; i > 0; i--) {
@@ -315,20 +325,14 @@ static int ilo_ccb_open(struct ilo_hwinf
 		udelay(WAIT_TIME);
 	}
 
-	if (i) {
-		ilo_pkt_enqueue(hw, driver_ccb, SENDQ, pkt_id, 0);
-		doorbell_set(driver_ccb);
-	} else {
-		dev_err(&pdev->dev, "Open could not dequeue a packet\n");
-		error = -EBUSY;
-		goto free;
+	if (i == 0) {
+		dev_err(&hw->ilo_dev->dev, "Open could not dequeue a packet\n");
+		return -EBUSY;
 	}
 
+	ilo_pkt_enqueue(hw, driver_ccb, SENDQ, pkt_id, 0);
+	doorbell_set(driver_ccb);
 	return 0;
-free:
-	ilo_ccb_close(pdev, data);
-out:
-	return error;
 }
 
 static inline int is_channel_reset(struct ccb *ccb)
@@ -343,16 +347,31 @@ static inline void set_channel_reset(str
 	FIFOBARTOHANDLE(ccb->ccb_u1.send_fifobar)->reset = 1;
 }
 
+static inline int get_device_outbound(struct ilo_hwinfo *hw)
+{
+	return ioread32(&hw->mmio_vaddr[DB_OUT]);
+}
+
+static inline int is_db_reset(int db_out)
+{
+	return db_out & (1 << DB_RESET);
+}
+
 static inline int is_device_reset(struct ilo_hwinfo *hw)
 {
 	/* check for global reset condition */
-	return ioread32(&hw->mmio_vaddr[DB_OUT]) & (1 << DB_RESET);
+	return is_db_reset(get_device_outbound(hw));
+}
+
+static inline void clear_pending_db(struct ilo_hwinfo *hw, int clr)
+{
+	iowrite32(clr, &hw->mmio_vaddr[DB_OUT]);
 }
 
 static inline void clear_device(struct ilo_hwinfo *hw)
 {
 	/* clear the device (reset bits, pending channel entries) */
-	iowrite32(-1, &hw->mmio_vaddr[DB_OUT]);
+	clear_pending_db(hw, -1);
 }
 
 static void ilo_locked_reset(struct ilo_hwinfo *hw)
@@ -387,15 +406,11 @@ static ssize_t ilo_read(struct file *fp,
 			size_t len, loff_t *off)
 {
 	int err, found, cnt, pkt_id, pkt_len;
-	struct ccb_data *data;
-	struct ccb *driver_ccb;
-	struct ilo_hwinfo *hw;
+	struct ccb_data *data = fp->private_data;
+	struct ccb *driver_ccb = &data->driver_ccb;
+	struct ilo_hwinfo *hw = data->ilo_hw;
 	void *pkt;
 
-	data = fp->private_data;
-	driver_ccb = &data->driver_ccb;
-	hw = data->ilo_hw;
-
 	if (is_device_reset(hw) || is_channel_reset(driver_ccb)) {
 		/*
 		 * If the device has been reset, applications
@@ -442,15 +457,11 @@ static ssize_t ilo_write(struct file *fp
 			 size_t len, loff_t *off)
 {
 	int err, pkt_id, pkt_len;
-	struct ccb_data *data;
-	struct ccb *driver_ccb;
-	struct ilo_hwinfo *hw;
+	struct ccb_data *data = fp->private_data;
+	struct ccb *driver_ccb = &data->driver_ccb;
+	struct ilo_hwinfo *hw = data->ilo_hw;
 	void *pkt;
 
-	data = fp->private_data;
-	driver_ccb = &data->driver_ccb;
-	hw = data->ilo_hw;
-
 	if (is_device_reset(hw) || is_channel_reset(driver_ccb)) {
 		/*
 		 * If the device has been reset, applications
@@ -532,14 +543,28 @@ static int ilo_open(struct inode *ip, st
 	/* each fd private_data holds sw/hw view of ccb */
 	if (hw->ccb_alloc[slot] == NULL) {
 		/* create a channel control block for this minor */
-		error = ilo_ccb_open(hw, data, slot);
-		if (!error) {
-			hw->ccb_alloc[slot] = data;
-			hw->ccb_alloc[slot]->ccb_cnt = 1;
-			hw->ccb_alloc[slot]->ccb_excl = fp->f_flags & O_EXCL;
-			hw->ccb_alloc[slot]->ilo_hw = hw;
-		} else
+		error = ilo_ccb_setup(hw, data, slot);
+		if (error) {
+			kfree(data);
+			goto out;
+		}
+
+		/* write the ccb to hw */
+		ilo_ccb_open(hw, data, slot);
+
+		/* make sure the channel is functional */
+		error = ilo_ccb_verify(hw, data);
+		if (error) {
+			ilo_ccb_close(hw->ilo_dev, data);
 			kfree(data);
+			goto out;
+		}
+
+		data->ccb_cnt = 1;
+		data->ccb_excl = fp->f_flags & O_EXCL;
+		data->ilo_hw = hw;
+		hw->ccb_alloc[slot] = data;
+
 	} else {
 		kfree(data);
 		if (fp->f_flags & O_EXCL || hw->ccb_alloc[slot]->ccb_excl) {
@@ -554,6 +579,7 @@ static int ilo_open(struct inode *ip, st
 			error = 0;
 		}
 	}
+out:
 	spin_unlock(&hw->alloc_lock);
 
 	if (!error)

  reply	other threads:[~2009-08-10 19:58 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-08-10 19:57 [PATCH 0/3] Enable poll handler in hpilo David Altobelli
2009-08-10 19:58 ` David Altobelli [this message]
2009-08-10 20:00 ` [PATCH 2/3] hpilo: add interrupt handler David Altobelli
2009-08-18 21:30   ` Andrew Morton
2009-08-18 22:25     ` Altobelli, David
2009-08-10 20:00 ` [PATCH 3/3] hpilo: add poll f_op David Altobelli

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=20090810195834.GA29404@ldl.fc.hp.com \
    --to=david.altobelli@hp.com \
    --cc=gregkh@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    /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.