From 95099d4622f8cb224d94e314c7a8e0df60b13f87 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 09 Dec 2023 08:38:01 +0000
Subject: [PATCH] enable docker ppp
---
kernel/drivers/scsi/scsi_transport_fc.c | 210 +++++++++++++++++++++++++---------------------------
1 files changed, 102 insertions(+), 108 deletions(-)
diff --git a/kernel/drivers/scsi/scsi_transport_fc.c b/kernel/drivers/scsi/scsi_transport_fc.c
index 381668f..2ff7f06 100644
--- a/kernel/drivers/scsi/scsi_transport_fc.c
+++ b/kernel/drivers/scsi/scsi_transport_fc.c
@@ -1,29 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* FiberChannel transport specific attributes exported to sysfs.
*
* Copyright (c) 2003 Silicon Graphics, Inc. All rights reserved.
- *
- * 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
- *
- * ========
- *
* Copyright (C) 2004-2007 James Smart, Emulex Corporation
* Rewrite for host, target, device, and remote port attributes,
* statistics, and service functions...
* Add vports, etc
- *
*/
#include <linux/module.h>
#include <linux/init.h>
@@ -147,6 +130,7 @@
{ FCH_EVT_PORT_OFFLINE, "port_offline" },
{ FCH_EVT_PORT_FABRIC, "port_fabric" },
{ FCH_EVT_LINK_UNKNOWN, "link_unknown" },
+ { FCH_EVT_LINK_FPIN, "link_FPIN" },
{ FCH_EVT_VENDOR_UNIQUE, "vendor_unique" },
};
fc_enum_name_search(host_event_code, fc_host_event_code,
@@ -269,6 +253,7 @@
{ FC_PORTSPEED_25GBIT, "25 Gbit" },
{ FC_PORTSPEED_64GBIT, "64 Gbit" },
{ FC_PORTSPEED_128GBIT, "128 Gbit" },
+ { FC_PORTSPEED_256GBIT, "256 Gbit" },
{ FC_PORTSPEED_NOT_NEGOTIATED, "Not Negotiated" },
};
fc_bitfield_name_search(port_speed, fc_port_speed_names)
@@ -295,6 +280,9 @@
{ FC_PORT_ROLE_FCP_INITIATOR, "FCP Initiator" },
{ FC_PORT_ROLE_IP_PORT, "IP Port" },
{ FC_PORT_ROLE_FCP_DUMMY_INITIATOR, "FCP Dummy Initiator" },
+ { FC_PORT_ROLE_NVME_INITIATOR, "NVMe Initiator" },
+ { FC_PORT_ROLE_NVME_TARGET, "NVMe Target" },
+ { FC_PORT_ROLE_NVME_DISCOVERY, "NVMe Discovery" },
};
fc_bitfield_name_search(port_roles, fc_port_role_names)
@@ -523,20 +511,23 @@
}
EXPORT_SYMBOL(fc_get_event_number);
-
/**
- * fc_host_post_event - called to post an even on an fc_host.
+ * fc_host_post_fc_event - routine to do the work of posting an event
+ * on an fc_host.
* @shost: host the event occurred on
* @event_number: fc event number obtained from get_fc_event_number()
* @event_code: fc_host event being posted
- * @event_data: 32bits of data for the event being posted
+ * @data_len: amount, in bytes, of event data
+ * @data_buf: pointer to event data
+ * @vendor_id: value for Vendor id
*
* Notes:
* This routine assumes no locks are held on entry.
*/
void
-fc_host_post_event(struct Scsi_Host *shost, u32 event_number,
- enum fc_host_event_code event_code, u32 event_data)
+fc_host_post_fc_event(struct Scsi_Host *shost, u32 event_number,
+ enum fc_host_event_code event_code,
+ u32 data_len, char *data_buf, u64 vendor_id)
{
struct sk_buff *skb;
struct nlmsghdr *nlh;
@@ -545,12 +536,15 @@
u32 len;
int err;
+ if (!data_buf || data_len < 4)
+ data_len = 0;
+
if (!scsi_nl_sock) {
err = -ENOENT;
goto send_fail;
}
- len = FC_NL_MSGALIGN(sizeof(*event));
+ len = FC_NL_MSGALIGN(sizeof(*event) + data_len);
skb = nlmsg_new(len, GFP_KERNEL);
if (!skb) {
@@ -568,12 +562,13 @@
INIT_SCSI_NL_HDR(&event->snlh, SCSI_NL_TRANSPORT_FC,
FC_NL_ASYNC_EVENT, len);
event->seconds = ktime_get_real_seconds();
- event->vendor_id = 0;
+ event->vendor_id = vendor_id;
event->host_no = shost->host_no;
- event->event_datalen = sizeof(u32); /* bytes */
+ event->event_datalen = data_len; /* bytes */
event->event_num = event_number;
event->event_code = event_code;
- event->event_data = event_data;
+ if (data_len)
+ memcpy(&event->event_data, data_buf, data_len);
nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS,
GFP_KERNEL);
@@ -586,14 +581,35 @@
printk(KERN_WARNING
"%s: Dropped Event : host %d %s data 0x%08x - err %d\n",
__func__, shost->host_no,
- (name) ? name : "<unknown>", event_data, err);
+ (name) ? name : "<unknown>",
+ (data_len) ? *((u32 *)data_buf) : 0xFFFFFFFF, err);
return;
+}
+EXPORT_SYMBOL(fc_host_post_fc_event);
+
+/**
+ * fc_host_post_event - called to post an even on an fc_host.
+ * @shost: host the event occurred on
+ * @event_number: fc event number obtained from get_fc_event_number()
+ * @event_code: fc_host event being posted
+ * @event_data: 32bits of data for the event being posted
+ *
+ * Notes:
+ * This routine assumes no locks are held on entry.
+ */
+void
+fc_host_post_event(struct Scsi_Host *shost, u32 event_number,
+ enum fc_host_event_code event_code, u32 event_data)
+{
+ fc_host_post_fc_event(shost, event_number, event_code,
+ (u32)sizeof(u32), (char *)&event_data, 0);
}
EXPORT_SYMBOL(fc_host_post_event);
/**
- * fc_host_post_vendor_event - called to post a vendor unique event on an fc_host
+ * fc_host_post_vendor_event - called to post a vendor unique event
+ * on an fc_host
* @shost: host the event occurred on
* @event_number: fc event number obtained from get_fc_event_number()
* @data_len: amount, in bytes, of vendor unique data
@@ -607,56 +623,27 @@
fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number,
u32 data_len, char * data_buf, u64 vendor_id)
{
- struct sk_buff *skb;
- struct nlmsghdr *nlh;
- struct fc_nl_event *event;
- u32 len;
- int err;
-
- if (!scsi_nl_sock) {
- err = -ENOENT;
- goto send_vendor_fail;
- }
-
- len = FC_NL_MSGALIGN(sizeof(*event) + data_len);
-
- skb = nlmsg_new(len, GFP_KERNEL);
- if (!skb) {
- err = -ENOBUFS;
- goto send_vendor_fail;
- }
-
- nlh = nlmsg_put(skb, 0, 0, SCSI_TRANSPORT_MSG, len, 0);
- if (!nlh) {
- err = -ENOBUFS;
- goto send_vendor_fail_skb;
- }
- event = nlmsg_data(nlh);
-
- INIT_SCSI_NL_HDR(&event->snlh, SCSI_NL_TRANSPORT_FC,
- FC_NL_ASYNC_EVENT, len);
- event->seconds = ktime_get_real_seconds();
- event->vendor_id = vendor_id;
- event->host_no = shost->host_no;
- event->event_datalen = data_len; /* bytes */
- event->event_num = event_number;
- event->event_code = FCH_EVT_VENDOR_UNIQUE;
- memcpy(&event->event_data, data_buf, data_len);
-
- nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS,
- GFP_KERNEL);
- return;
-
-send_vendor_fail_skb:
- kfree_skb(skb);
-send_vendor_fail:
- printk(KERN_WARNING
- "%s: Dropped Event : host %d vendor_unique - err %d\n",
- __func__, shost->host_no, err);
- return;
+ fc_host_post_fc_event(shost, event_number, FCH_EVT_VENDOR_UNIQUE,
+ data_len, data_buf, vendor_id);
}
EXPORT_SYMBOL(fc_host_post_vendor_event);
+/**
+ * fc_host_rcv_fpin - routine to process a received FPIN.
+ * @shost: host the FPIN was received on
+ * @fpin_len: length of FPIN payload, in bytes
+ * @fpin_buf: pointer to FPIN payload
+ *
+ * Notes:
+ * This routine assumes no locks are held on entry.
+ */
+void
+fc_host_fpin_rcv(struct Scsi_Host *shost, u32 fpin_len, char *fpin_buf)
+{
+ fc_host_post_fc_event(shost, fc_get_event_number(),
+ FCH_EVT_LINK_FPIN, fpin_len, fpin_buf, 0);
+}
+EXPORT_SYMBOL(fc_host_fpin_rcv);
static __init int fc_transport_init(void)
@@ -3592,7 +3579,7 @@
/* the blk_end_sync_io() doesn't check the error */
if (inflight)
- __blk_complete_request(req);
+ blk_mq_end_request(req, BLK_STS_IOERR);
return BLK_EH_DONE;
}
@@ -3684,14 +3671,9 @@
fc_bsg_goose_queue(struct fc_rport *rport)
{
struct request_queue *q = rport->rqst_q;
- unsigned long flags;
- if (!q)
- return;
-
- spin_lock_irqsave(q->queue_lock, flags);
- blk_run_queue_async(q);
- spin_unlock_irqrestore(q->queue_lock, flags);
+ if (q)
+ blk_mq_run_hw_queues(q, true);
}
/**
@@ -3759,6 +3741,37 @@
return fc_bsg_host_dispatch(shost, job);
}
+static blk_status_t fc_bsg_rport_prep(struct fc_rport *rport)
+{
+ if (rport->port_state == FC_PORTSTATE_BLOCKED &&
+ !(rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT))
+ return BLK_STS_RESOURCE;
+
+ if (rport->port_state != FC_PORTSTATE_ONLINE)
+ return BLK_STS_IOERR;
+
+ return BLK_STS_OK;
+}
+
+
+static int fc_bsg_dispatch_prep(struct bsg_job *job)
+{
+ struct fc_rport *rport = fc_bsg_to_rport(job);
+ blk_status_t ret;
+
+ ret = fc_bsg_rport_prep(rport);
+ switch (ret) {
+ case BLK_STS_OK:
+ break;
+ case BLK_STS_RESOURCE:
+ return -EAGAIN;
+ default:
+ return -EIO;
+ }
+
+ return fc_bsg_dispatch(job);
+}
+
/**
* fc_bsg_hostadd - Create and add the bsg hooks so we can receive requests
* @shost: shost for fc_host
@@ -3780,7 +3793,8 @@
snprintf(bsg_name, sizeof(bsg_name),
"fc_host%d", shost->host_no);
- q = bsg_setup_queue(dev, bsg_name, fc_bsg_dispatch, i->f->dd_bsg_size);
+ q = bsg_setup_queue(dev, bsg_name, fc_bsg_dispatch, fc_bsg_job_timeout,
+ i->f->dd_bsg_size);
if (IS_ERR(q)) {
dev_err(dev,
"fc_host%d: bsg interface failed to initialize - setup queue\n",
@@ -3788,24 +3802,9 @@
return PTR_ERR(q);
}
__scsi_init_queue(shost, q);
- blk_queue_rq_timed_out(q, fc_bsg_job_timeout);
blk_queue_rq_timeout(q, FC_DEFAULT_BSG_TIMEOUT);
fc_host->rqst_q = q;
return 0;
-}
-
-static int fc_bsg_rport_prep(struct request_queue *q, struct request *req)
-{
- struct fc_rport *rport = dev_to_rport(q->queuedata);
-
- if (rport->port_state == FC_PORTSTATE_BLOCKED &&
- !(rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT))
- return BLKPREP_DEFER;
-
- if (rport->port_state != FC_PORTSTATE_ONLINE)
- return BLKPREP_KILL;
-
- return BLKPREP_OK;
}
/**
@@ -3825,15 +3824,13 @@
if (!i->f->bsg_request)
return -ENOTSUPP;
- q = bsg_setup_queue(dev, dev_name(dev), fc_bsg_dispatch,
- i->f->dd_bsg_size);
+ q = bsg_setup_queue(dev, dev_name(dev), fc_bsg_dispatch_prep,
+ fc_bsg_job_timeout, i->f->dd_bsg_size);
if (IS_ERR(q)) {
dev_err(dev, "failed to setup bsg queue\n");
return PTR_ERR(q);
}
__scsi_init_queue(shost, q);
- blk_queue_prep_rq(q, fc_bsg_rport_prep);
- blk_queue_rq_timed_out(q, fc_bsg_job_timeout);
blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT);
rport->rqst_q = q;
return 0;
@@ -3852,10 +3849,7 @@
static void
fc_bsg_remove(struct request_queue *q)
{
- if (q) {
- bsg_unregister_queue(q);
- blk_cleanup_queue(q);
- }
+ bsg_remove_queue(q);
}
--
Gitblit v1.6.2