Subject: Netlink interface for SCSI sense codes From: Hannes Reinecke 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 --- 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 #include #include +#include +#include #include #include @@ -34,6 +36,7 @@ #include #include #include +#include #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 + +/* + * 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 */ +