summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorjmatthew <jmatthew@openbsd.org>2014-03-31 11:25:45 +0000
committerjmatthew <jmatthew@openbsd.org>2014-03-31 11:25:45 +0000
commitd10165e5f7def8e8052cca42d08658e8dd4020dd (patch)
treee22467915df75fb5dc606aca85f093cfc73dd071 /sys/dev
parentIf HOST or the host argument starts with a /, treat it as a device name (diff)
downloadwireguard-openbsd-d10165e5f7def8e8052cca42d08658e8dd4020dd.tar.xz
wireguard-openbsd-d10165e5f7def8e8052cca42d08658e8dd4020dd.zip
Rather than scanning local loop ids sequentially, just ask the chip which
local devices it has logged in to. This will also be useful for hotplug later on.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ic/qla.c77
-rw-r--r--sys/dev/ic/qlareg.h7
-rw-r--r--sys/dev/ic/qlavar.h9
3 files changed, 75 insertions, 18 deletions
diff --git a/sys/dev/ic/qla.c b/sys/dev/ic/qla.c
index 6f239a671e0..fcd27d4b20f 100644
--- a/sys/dev/ic/qla.c
+++ b/sys/dev/ic/qla.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: qla.c,v 1.30 2014/02/23 10:40:19 jmatthew Exp $ */
+/* $OpenBSD: qla.c,v 1.31 2014/03/31 11:25:45 jmatthew Exp $ */
/*
* Copyright (c) 2011 David Gwynne <dlg@openbsd.org>
@@ -95,6 +95,7 @@ void qla_put_cmd(struct qla_softc *, void *, struct scsi_xfer *,
struct qla_ccb *qla_handle_resp(struct qla_softc *, u_int16_t);
void qla_put_data_seg(struct qla_iocb_seg *, bus_dmamap_t, int);
+int qla_get_port_name_list(struct qla_softc *, u_int32_t);
struct qla_fc_port *qla_next_fabric_port(struct qla_softc *, u_int32_t *,
u_int32_t *);
int qla_add_port(struct qla_softc *, u_int16_t, u_int32_t,
@@ -311,6 +312,7 @@ qla_attach(struct qla_softc *sc)
TAILQ_INIT(&sc->sc_ports);
TAILQ_INIT(&sc->sc_ports_new);
TAILQ_INIT(&sc->sc_ports_gone);
+ TAILQ_INIT(&sc->sc_ports_found);
switch (sc->sc_isp_gen) {
case QLA_GEN_ISP2100:
@@ -523,37 +525,37 @@ qla_attach(struct qla_softc *sc)
}
if (sc->sc_loop_up) {
- int i;
+ struct qla_fc_port *port;
qla_update_topology(sc);
- for (i = 0; i < sc->sc_loop_max_id; i++) {
- if (i != sc->sc_loop_id) {
- qla_add_port(sc, i, 0,
- QLA_LOCATION_LOOP_ID(i));
- }
+ qla_get_port_name_list(sc, QLA_LOCATION_LOOP);
+ while (!TAILQ_EMPTY(&sc->sc_ports_found)) {
+ port = TAILQ_FIRST(&sc->sc_ports_found);
+ TAILQ_REMOVE(&sc->sc_ports_found, port, update);
+ qla_add_port(sc, port->loopid, port->portid,
+ QLA_LOCATION_LOOP_ID(port->loopid));
+ free(port, M_DEVBUF);
}
if (qla_update_fabric(sc) == 0) {
- TAILQ_HEAD(, qla_fc_port) found;
u_int32_t firstport = 0xffffffff;
u_int32_t lastport = 0;
- struct qla_fc_port *port;
- TAILQ_INIT(&found);
do {
port = qla_next_fabric_port(sc, &firstport,
&lastport);
if (port != NULL)
- TAILQ_INSERT_TAIL(&found, port, update);
+ TAILQ_INSERT_TAIL(&sc->sc_ports_found,
+ port, update);
} while (lastport != 0xffffffff);
- while (!TAILQ_EMPTY(&found)) {
- port = TAILQ_FIRST(&found);
+ while (!TAILQ_EMPTY(&sc->sc_ports_found)) {
+ port = TAILQ_FIRST(&sc->sc_ports_found);
if (qla_fabric_plogi(sc, port) == 0) {
qla_add_port(sc, port->loopid,
port->portid, port->location);
}
- TAILQ_REMOVE(&found, port, update);
+ TAILQ_REMOVE(&sc->sc_ports_found, port, update);
free(port, M_DEVBUF);
}
}
@@ -1385,6 +1387,53 @@ qla_update_fabric(struct qla_softc *sc)
return (0);
}
+int
+qla_get_port_name_list(struct qla_softc *sc, u_int32_t match)
+{
+ int i;
+ struct qla_port_name_list *l;
+ struct qla_fc_port *port;
+
+ sc->sc_mbox[0] = QLA_MBOX_GET_PORT_NAME_LIST;
+ sc->sc_mbox[1] = 0x08; /* include initiators */
+ if (match & QLA_LOCATION_FABRIC)
+ sc->sc_mbox[1] |= 0x02; /* return all loop ids */
+ qla_mbox_putaddr(sc->sc_mbox, sc->sc_scratch);
+ bus_dmamap_sync(sc->sc_dmat, QLA_DMA_MAP(sc->sc_scratch), 0,
+ QLA_DMA_LEN(sc->sc_scratch), BUS_DMASYNC_PREREAD);
+ if (qla_mbox(sc, 0x04f, 0x003)) {
+ DPRINTF(QLA_D_PORT, "%s: get port name list failed: %x\n",
+ DEVNAME(sc), sc->sc_mbox[0]);
+ return (1);
+ }
+ bus_dmamap_sync(sc->sc_dmat, QLA_DMA_MAP(sc->sc_scratch), 0,
+ QLA_DMA_LEN(sc->sc_scratch), BUS_DMASYNC_PREREAD);
+
+ i = 0;
+ l = QLA_DMA_KVA(sc->sc_scratch);
+ while (i * sizeof(*l) < sc->sc_mbox[1]) {
+ u_int16_t loopid;
+ u_int32_t loc;
+
+ loopid = letoh16(l[i].loop_id);
+
+ loc = (loopid < QLA_MIN_HANDLE) ? QLA_LOCATION_LOOP :
+ QLA_LOCATION_FABRIC;
+ if (match & loc) {
+ port = malloc(sizeof(*port), M_DEVBUF, M_ZERO |
+ M_NOWAIT);
+ port->loopid = loopid;
+ port->port_name = letoh64(l[i].port_name);
+ DPRINTF(QLA_D_PORT, "%s: loop id %d, port name %llx\n",
+ DEVNAME(sc), port->loopid, port->port_name);
+ TAILQ_INSERT_TAIL(&sc->sc_ports_found, port, update);
+ }
+ i++;
+ }
+
+ return (0);
+}
+
struct qla_fc_port *
qla_next_fabric_port(struct qla_softc *sc, u_int32_t *firstport,
u_int32_t *lastport)
diff --git a/sys/dev/ic/qlareg.h b/sys/dev/ic/qlareg.h
index 6a3b15c56b7..3078bd61f28 100644
--- a/sys/dev/ic/qlareg.h
+++ b/sys/dev/ic/qlareg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: qlareg.h,v 1.4 2014/02/06 21:05:54 jmatthew Exp $ */
+/* $OpenBSD: qlareg.h,v 1.5 2014/03/31 11:25:45 jmatthew Exp $ */
/*
* Copyright (c) 2013, 2014 Jonathan Matthew <jmatthew@openbsd.org>
@@ -423,6 +423,11 @@ struct qla_get_port_db {
u_int16_t ext_lun_stop_ptr;
} __packed;
+struct qla_port_name_list {
+ u_int64_t port_name;
+ u_int16_t loop_id;
+} __packed;
+
#define QLA_SVC3_TARGET_ROLE 0x0010
/* fabric name server commands */
diff --git a/sys/dev/ic/qlavar.h b/sys/dev/ic/qlavar.h
index 556600df22f..82e793a8805 100644
--- a/sys/dev/ic/qlavar.h
+++ b/sys/dev/ic/qlavar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: qlavar.h,v 1.5 2014/02/20 00:23:00 dlg Exp $ */
+/* $OpenBSD: qlavar.h,v 1.6 2014/03/31 11:25:45 jmatthew Exp $ */
/*
* Copyright (c) 2013, 2014 Jonathan Matthew <jmatthew@openbsd.org>
@@ -73,8 +73,10 @@ enum qla_port_disp {
#define QLA_UPDATE_FABRIC_SCAN 4
#define QLA_UPDATE_FABRIC_RELOGIN 5
-#define QLA_LOCATION_LOOP_ID(l) (l | (1 << 24))
-#define QLA_LOCATION_PORT_ID(p) (p | (2 << 24))
+#define QLA_LOCATION_LOOP (1 << 24)
+#define QLA_LOCATION_FABRIC (2 << 24)
+#define QLA_LOCATION_LOOP_ID(l) (l | QLA_LOCATION_LOOP)
+#define QLA_LOCATION_PORT_ID(p) (p | QLA_LOCATION_FABRIC)
struct qla_fc_port {
TAILQ_ENTRY(qla_fc_port) ports;
@@ -158,6 +160,7 @@ struct qla_softc {
TAILQ_HEAD(, qla_fc_port) sc_ports;
TAILQ_HEAD(, qla_fc_port) sc_ports_new;
TAILQ_HEAD(, qla_fc_port) sc_ports_gone;
+ TAILQ_HEAD(, qla_fc_port) sc_ports_found;
struct qla_fc_port *sc_targets[QLA_MAX_TARGETS];
struct taskq *sc_scan_taskq;