Corey,

Moving uart_register_ldrv() into uart_add_one_port() seems to be working.  I
can create and deliver a patch for you.  I am unaware of the proper
procedure for posting patches so I have a few questions.

What would you like the patch generated against (stock kernel.org
2.6.18serial_core.c   or   serial_core.c that already has the
serial-allow-in-kernel-users.patch)?

What is the proper way to deliver the patch:  attach to email  or include
text of patch (as large as it may be) in body of email to list?

And I'll throw another thread into the queue here as well.

The version of pigeonpoint I am working with does not implement an event
queue.  It uses the ATTN char and the OEM0 flag bit to indicate that there
are bits of interest in the status register which can be retrieved with the
oem command "get_status".  Among these bits of interest are 'graceful reboot
request', 'diag interrupt request', 'shutdown alert', 'reset alert', 'sensor
alert', and various bus events.

When the OEM0 bit in the flag msg is set I would like to kick off an OEM
based request that sends a get_status command and then responds
appropriately to the bits set in the response message.

It seems like this would be best done in user space (or as much as
possible).  I noticed the 'oem_data_avail_handler' hook in the serial
handle_flags routine.  As well I was experimenting with registering for
commands from user space.  So I added an oem_data_handler to ipmi_serial.c
that creates an alert message and passes it up the stack to ipmi_msghandler
to give to anyone registerd for the specific oem netfn and command.  In user
space I have a daemon that registers for the oem netfn & cmd, waits for the
alert message, does a oem get_status command to the ipmc, and then can take
action when the get_status response comes back.

I will put my patch for this in line below (not that large) for your review
and comments.  Is this a good / appropriate way to do this?  Is there a
better / more appropriate method?

--- linux-2.6.18-ipmi/drivers/char/ipmi/ipmi_serial.c    2007-04-05 17:27:
35.000000000 -0500
+++ linux-2.6.18-new/drivers/char/ipmi/ipmi_serial.c    2007-04-04 18:25:
59.000000000 -0500
@@ -1456,6 +1456,59 @@
                     &info->old_termios);
}

+#define IPMI_EMERSON_PPS_MANUF_ID 0x0080F9
+#define IPMI_OEM_GET_STATUS_CMD 0x00
+#define IPMI_ATCA_PPS_IANA_BYTE0 0x40
+#define IPMI_ATCA_PPS_IANA_BYTE1 0x0A
+#define IPMI_ATCA_PPS_IANA_BYTE2 0x00
+
+static int emrsn_oem_data_handler(struct ipmi_serial_info *info)
+{
+        struct ipmi_smi_msg *msg;
+
+        info->msg_flags = (info->msg_flags & ~(OEM_DATA_AVAIL));
+
+        WARN_ON(info->curr_msg);
+        if (info->curr_msg)
+            return -EBUSY;
+
+        msg = ipmi_alloc_smi_msg();
+        if (!msg)
+            return -ENOMEM;
+
+        msg->data[0] =((IPMI_NETFN_APP_REQUEST | 1) << 2);
+        msg->data[1] = IPMI_GET_MSG_CMD;
+        msg->rsp[0] = ((IPMI_NETFN_APP_REQUEST | 1) << 2);
+        msg->rsp[1] = IPMI_GET_MSG_CMD;
+        msg->rsp[2] = 0;
+        msg->rsp[4] = (IPMI_NETFN_OEM_REQUEST << 2);
+        msg->rsp[8] = IPMI_OEM_GET_STATUS_CMD;
+        msg->rsp[10] = IPMI_ATCA_PPS_IANA_BYTE0;
+        msg->rsp[11] = IPMI_ATCA_PPS_IANA_BYTE1;
+        msg->rsp[12] = IPMI_ATCA_PPS_IANA_BYTE2;
+        msg->data_size = 0;
+        msg->rsp_size = 12;
+
+        queue_async_msg(info, msg);
+
+        return 0;
+}
+
+/*
+ * setup_oem_data_handler
+ * @info - info.device_id must be filled in already
+ *
+ * Fills in info.device_id.oem_data_available_handler
+ * when we know what function to use there.
+ */
+static void setup_oem_data_handler(struct ipmi_serial_info *info)
+{
+    if (info->device_id.manufacturer_id == IPMI_EMERSON_PPS_MANUF_ID) {
+        printk("IPMI:  Attaching EMRSN OEM handler\n");
+        info->oem_data_avail_handler = emrsn_oem_data_handler;
+    }
+}
+
/*
 * Called when the serial layer says it found a serial driver that
 * matches.  We use this to kick things off.
@@ -1528,6 +1581,8 @@
        goto out_err;
    }

+    setup_oem_data_handler(info);
+
    capabilities = info->codec->capabilities(info->codec_data);
    info->do_event_request = (capabilities
                  & IPMI_SERIAL_SUPPORTS_EVENT_BUFFER);
@@ -1545,7 +1600,6 @@
                   info,
                   &info->device_id,
                   port->dev,
-                   sysfs_name,
                   info->slave_addr);
    if (rv) {
        printk(KERN_ERR PFX "Unable to register the "




On 3/30/07, Corey Minyard <[EMAIL PROTECTED]> wrote:

I haven't seen this problem, but it appears to be order related and
that's probably why I missed it.

I think the right answer is to move the call to uart_register_ldrv() out
of uart_configure_port() and move it into uart_add_one_port() after the
mutex->state is  unlocked.  However, I haven't tested it.  If that
works, could you send a patch?

I'm currently completely reworking this, as the kernel developers didn't
like the approach.

Thanks,

-corey



-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Openipmi-developer mailing list
Openipmi-developer@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openipmi-developer

Reply via email to