216 lines
5.6 KiB
Plaintext
216 lines
5.6 KiB
Plaintext
|
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
|
||
|
@@ -24,6 +24,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>
|
||
|
@@ -33,6 +35,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"
|
||
|
@@ -213,6 +216,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.
|
||
|
@@ -235,6 +312,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 */
|
||
|
+
|