Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/scsipi Add sedetach() and also use it to remove dupl...
details: https://anonhg.NetBSD.org/src/rev/a11443b14fd2
branches: trunk
changeset: 973170:a11443b14fd2
user: jdc <jdc%NetBSD.org@localhost>
date: Mon Jun 22 17:38:27 2020 +0000
description:
Add sedetach() and also use it to remove duplicate code from seattach().
Correct a comment about sedone().
diffstat:
sys/dev/scsipi/if_se.c | 78 ++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 60 insertions(+), 18 deletions(-)
diffs (154 lines):
diff -r 425c73e0b632 -r a11443b14fd2 sys/dev/scsipi/if_se.c
--- a/sys/dev/scsipi/if_se.c Mon Jun 22 16:39:56 2020 +0000
+++ b/sys/dev/scsipi/if_se.c Mon Jun 22 17:38:27 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_se.c,v 1.106 2020/06/22 16:05:20 jdc Exp $ */
+/* $NetBSD: if_se.c,v 1.107 2020/06/22 17:38:27 jdc Exp $ */
/*
* Copyright (c) 1997 Ian W. Dall <ian.dall%dsto.defence.gov.au@localhost>
@@ -59,7 +59,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_se.c,v 1.106 2020/06/22 16:05:20 jdc Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_se.c,v 1.107 2020/06/22 17:38:27 jdc Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -198,10 +198,12 @@
int sc_flags;
int sc_last_timeout;
int sc_enabled;
+ int sc_attach_state;
};
static int sematch(device_t, cfdata_t, void *);
static void seattach(device_t, device_t, void *);
+static int sedetach(device_t, int);
static void se_ifstart(struct ifnet *);
@@ -240,7 +242,7 @@
void se_disable(struct se_softc *);
CFATTACH_DECL_NEW(se, sizeof(struct se_softc),
- sematch, seattach, NULL, NULL);
+ sematch, seattach, sedetach, NULL);
extern struct cfdriver se_cd;
@@ -267,7 +269,7 @@
NULL, /* Use default error handler */
NULL, /* have no queue */
NULL, /* have no async handler */
- sedone, /* deal with stats at interrupt time */
+ sedone, /* deal with send/recv completion */
};
const struct scsipi_inquiry_pattern se_patterns[] = {
@@ -330,6 +332,7 @@
printf("\n");
SC_DEBUG(periph, SCSIPI_DB2, ("seattach: "));
+ sc->sc_attach_state = 0;
callout_init(&sc->sc_recv_ch, CALLOUT_MPSAFE);
mutex_init(&sc->sc_iflock, MUTEX_DEFAULT, IPL_SOFTNET);
@@ -363,43 +366,82 @@
IFQ_SET_READY(&ifp->if_snd);
se_get_addr(sc, myaddr);
+ sc->sc_attach_state = 1;
/* Attach the interface. */
rv = if_initialize(ifp);
if (rv != 0) {
- free(sc->sc_tbuf, M_DEVBUF);
- callout_destroy(&sc->sc_recv_ch);
- mutex_destroy(&sc->sc_iflock);
+ sedetach(sc->sc_dev, 0);
return; /* Error */
}
+
snprintf(wqname, sizeof(wqname), "%sRx", device_xname(sc->sc_dev));
rv = workqueue_create(&sc->sc_recv_wq, wqname, se_recv_worker, sc,
PRI_SOFTNET, IPL_NET, WQ_MPSAFE);
if (rv != 0) {
aprint_error_dev(sc->sc_dev,
- "unable to create recv workqueue\n");
- free(sc->sc_tbuf, M_DEVBUF);
- callout_destroy(&sc->sc_recv_ch);
- mutex_destroy(&sc->sc_iflock);
+ "unable to create recv Rx workqueue\n");
+ sedetach(sc->sc_dev, 0);
return; /* Error */
}
sc->sc_recv_work_pending = false;
+ sc->sc_attach_state = 2;
+
snprintf(wqname, sizeof(wqname), "%sTx", device_xname(sc->sc_dev));
rv = workqueue_create(&sc->sc_send_wq, wqname, se_send_worker, ifp,
PRI_SOFTNET, IPL_NET, WQ_MPSAFE);
if (rv != 0) {
aprint_error_dev(sc->sc_dev,
- "unable to create send workqueue\n");
+ "unable to create send Tx workqueue\n");
+ sedetach(sc->sc_dev, 0);
+ return; /* Error */
+ }
+ sc->sc_send_work_pending = false;
+ sc->sc_attach_state = 3;
+
+ sc->sc_ipq = if_percpuq_create(&sc->sc_ethercom.ec_if);
+ ether_ifattach(ifp, myaddr);
+ if_register(ifp);
+ sc->sc_attach_state = 4;
+}
+
+static int
+sedetach(device_t self, int flags)
+{
+ struct se_softc *sc = device_private(self);
+ struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+
+ switch(sc->sc_attach_state) {
+ case 4:
+ se_stop(sc);
+ mutex_enter(&sc->sc_iflock);
+ ifp->if_flags &= ~IFF_RUNNING;
+ se_disable(sc);
+ callout_halt(&sc->sc_recv_ch, NULL);
+ ether_ifdetach(ifp);
+ if_detach(ifp);
+ mutex_exit(&sc->sc_iflock);
+ if_percpuq_destroy(sc->sc_ipq);
+ /*FALLTHROUGH*/
+ case 3:
+ workqueue_destroy(sc->sc_send_wq);
+ /*FALLTHROUGH*/
+ case 2:
+ workqueue_destroy(sc->sc_recv_wq);
+ /*FALLTHROUGH*/
+ case 1:
+ free(sc->sc_rbuf, M_DEVBUF);
free(sc->sc_tbuf, M_DEVBUF);
callout_destroy(&sc->sc_recv_ch);
mutex_destroy(&sc->sc_iflock);
- workqueue_destroy(sc->sc_send_wq);
- return; /* Error */
+ break;
+ default:
+ aprint_error_dev(sc->sc_dev, "detach failed (state %d)\n",
+ sc->sc_attach_state);
+ return 1;
+ break;
}
- sc->sc_send_work_pending = false;
- sc->sc_ipq = if_percpuq_create(&sc->sc_ethercom.ec_if);
- ether_ifattach(ifp, myaddr);
- if_register(ifp);
+ return 0;
}
/*
Home |
Main Index |
Thread Index |
Old Index