You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
qubes-linux-kernel/patches.suse/scsi-netlink-ml

216 lines
5.6 KiB

Subject: Netlink interface for SCSI sense codes
From: Hannes Reinecke <hare@suse.de>
Date: Fri Nov 21 10:08:01 2008 +0100:
Git: 97746dc5543ef9113c927022dc54ccd26915563d
Patch-mainline: not yet
Inform the userspace about SCSI sense codes; some of them
carry vital information where userspace should react to.
Signed-off-by: Hannes Reinecke <hare@suse.de>
---
drivers/scsi/scsi_error.c | 79 +++++++++++++++++++++++++++++++++++++++++
include/scsi/scsi_netlink.h | 6 ++-
include/scsi/scsi_netlink_ml.h | 64 +++++++++++++++++++++++++++++++++
3 files changed, 147 insertions(+), 2 deletions(-)
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -25,6 +25,8 @@
#include <linux/interrupt.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
+#include <linux/netlink.h>
+#include <net/netlink.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -34,6 +36,7 @@
#include <scsi/scsi_transport.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_ioctl.h>
+#include <scsi/scsi_netlink_ml.h>
#include "scsi_priv.h"
#include "scsi_logging.h"
@@ -218,6 +221,80 @@ static inline void scsi_eh_prt_fail_stat
}
#endif
+#ifdef CONFIG_SCSI_NETLINK
+/**
+ * scsi_post_sense_event - called to post a 'Sense Code' event
+ *
+ * @sdev: SCSI device the sense code occured on
+ * @sshdr: SCSI sense code
+ *
+ * Returns:
+ * 0 on succesful return
+ * otherwise, failing error code
+ *
+ */
+static void scsi_post_sense_event(struct scsi_device *sdev,
+ struct scsi_sense_hdr *sshdr)
+{
+ struct sk_buff *skb;
+ struct nlmsghdr *nlh;
+ struct scsi_nl_sense_msg *msg;
+ u32 len, skblen;
+ int err;
+
+ if (!scsi_nl_sock) {
+ err = -ENOENT;
+ goto send_fail;
+ }
+
+ len = SCSI_NL_MSGALIGN(sizeof(*msg));
+ skblen = NLMSG_SPACE(len);
+
+ skb = alloc_skb(skblen, GFP_ATOMIC);
+ if (!skb) {
+ err = -ENOBUFS;
+ goto send_fail;
+ }
+
+ nlh = nlmsg_put(skb, 0, 0, SCSI_TRANSPORT_MSG,
+ skblen - sizeof(*nlh), 0);
+ if (!nlh) {
+ err = -ENOBUFS;
+ goto send_fail_skb;
+ }
+ msg = NLMSG_DATA(nlh);
+
+ INIT_SCSI_NL_HDR(&msg->snlh, SCSI_NL_TRANSPORT_ML,
+ ML_NL_SCSI_SENSE, len);
+ msg->host_no = sdev->host->host_no;
+ msg->channel = sdev->channel;
+ msg->id = sdev->id;
+ msg->lun = sdev->lun;
+ msg->sense = (sshdr->response_code << 24) | (sshdr->sense_key << 16) |
+ (sshdr->asc << 8) | sshdr->ascq;
+
+ err = nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_ML_EVENTS,
+ GFP_KERNEL);
+ if (err && (err != -ESRCH))
+ /* nlmsg_multicast already kfree_skb'd */
+ goto send_fail;
+
+ return;
+
+send_fail_skb:
+ kfree_skb(skb);
+send_fail:
+ sdev_printk(KERN_WARNING, sdev,
+ "Dropped SCSI Msg %02x/%02x/%02x/%02x: err %d\n",
+ sshdr->response_code, sshdr->sense_key,
+ sshdr->asc, sshdr->ascq, err);
+ return;
+}
+#else
+static inline void scsi_post_sense_event(struct scsi_device *sdev,
+ struct scsi_sense_hdr *sshdr) {}
+#endif
+
/**
* scsi_check_sense - Examine scsi cmd sense
* @scmd: Cmd to have sense checked.
@@ -240,6 +317,8 @@ static int scsi_check_sense(struct scsi_
if (scsi_sense_is_deferred(&sshdr))
return NEEDS_RETRY;
+ scsi_post_sense_event(sdev, &sshdr);
+
if (sdev->scsi_dh_data && sdev->scsi_dh_data->scsi_dh &&
sdev->scsi_dh_data->scsi_dh->check_sense) {
int rc;
--- a/include/scsi/scsi_netlink.h
+++ b/include/scsi/scsi_netlink.h
@@ -35,7 +35,8 @@
/* SCSI Transport Broadcast Groups */
/* leaving groups 0 and 1 unassigned */
#define SCSI_NL_GRP_FC_EVENTS (1<<2) /* Group 2 */
-#define SCSI_NL_GRP_CNT 3
+#define SCSI_NL_GRP_ML_EVENTS (1<<3) /* Group 3 */
+#define SCSI_NL_GRP_CNT 4
/* SCSI_TRANSPORT_MSG event message header */
@@ -56,7 +57,8 @@ struct scsi_nl_hdr {
/* scsi_nl_hdr->transport value */
#define SCSI_NL_TRANSPORT 0
#define SCSI_NL_TRANSPORT_FC 1
-#define SCSI_NL_MAX_TRANSPORTS 2
+#define SCSI_NL_TRANSPORT_ML 2
+#define SCSI_NL_MAX_TRANSPORTS 3
/* Transport-based scsi_nl_hdr->msgtype values are defined in each transport */
--- /dev/null
+++ b/include/scsi/scsi_netlink_ml.h
@@ -0,0 +1,64 @@
+/*
+ * SCSI Midlayer Netlink Interface
+ *
+ * Copyright (C) 2008 Hannes Reinecke, SuSE Linux Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef SCSI_NETLINK_ML_H
+#define SCSI_NETLINK_ML_H
+
+#include <scsi/scsi_netlink.h>
+
+/*
+ * This file intended to be included by both kernel and user space
+ */
+
+/*
+ * FC Transport Message Types
+ */
+ /* kernel -> user */
+#define ML_NL_SCSI_SENSE 0x0100
+ /* user -> kernel */
+/* none */
+
+
+/*
+ * Message Structures :
+ */
+
+/* macro to round up message lengths to 8byte boundary */
+#define SCSI_NL_MSGALIGN(len) (((len) + 7) & ~7)
+
+
+/*
+ * SCSI Midlayer SCSI Sense messages :
+ * SCSI_NL_SCSI_SENSE
+ *
+ */
+struct scsi_nl_sense_msg {
+ struct scsi_nl_hdr snlh; /* must be 1st element ! */
+ uint64_t seconds;
+ u64 id;
+ u64 lun;
+ u16 host_no;
+ u16 channel;
+ u32 sense;
+} __attribute__((aligned(sizeof(uint64_t))));
+
+
+#endif /* SCSI_NETLINK_ML_H */
+