IFC @r273214

This commit is contained in:
Neel Natu 2014-10-20 02:57:30 +00:00
commit e1a172e1c2
11 changed files with 272 additions and 100 deletions

View File

@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd May 5, 2013
.Dd September 22, 2014
.Dt PING6 8
.Os
.Sh NAME
@ -65,6 +65,12 @@ packets to network hosts
.Op Fl i Ar wait
.Ek
.Bk -words
.Op Fl x Ar waittime
.Ek
.Bk -words
.Op Fl X Ar timeout
.Ek
.Bk -words
.Op Fl l Ar preload
.Ek
.Bk -words
@ -191,6 +197,15 @@ The default is to wait for one second between each packet.
This option is incompatible with the
.Fl f
option.
.It Fl x Ar waittime
Time in milliseconds to wait for a reply for each packet sent.
If a reply arrives later,
the packet is not printed as replied,
but considered as replied when calculating statistics.
.It Fl X Ar timeout
Specify a timeout,
in seconds,
before ping exits regardless of how many packets have been received.
.It Fl l Ar preload
If
.Ar preload

View File

@ -152,6 +152,8 @@ struct tv32 {
#define DEFDATALEN ICMP6ECHOTMLEN
#define MAXDATALEN MAXPACKETLEN - IP6LEN - ICMP6ECHOLEN
#define NROUTES 9 /* number of record route slots */
#define MAXWAIT 10000 /* max ms to wait for response */
#define MAXALARM (60 * 60) /* max seconds for alarm timeout */
#define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */
#define B(bit) (1 << ((bit) & 0x07)) /* identify bit in byte */
@ -188,6 +190,7 @@ struct tv32 {
#define F_MISSED 0x800000
#define F_DONTFRAG 0x1000000
#define F_NOUSERDATA (F_NODEADDR | F_FQDN | F_FQDNOLD | F_SUPTYPES)
#define F_WAITTIME 0x2000000
u_int options;
#define IN6LEN sizeof(struct in6_addr)
@ -228,6 +231,8 @@ long nreceived; /* # of packets we got back */
long nrepeats; /* number of duplicates */
long ntransmitted; /* sequence # for outbound packets = #sent */
int interval = 1000; /* interval between packets in ms */
int waittime = MAXWAIT; /* timeout for each packet */
long nrcvtimeout = 0; /* # of packets we got back after waittime */
/* timing */
int timing; /* flag to do timing */
@ -312,6 +317,7 @@ main(int argc, char *argv[])
char *policy_out = NULL;
#endif
double t;
u_long alarmtimeout;
size_t rthlen;
#ifdef IPV6_USE_MIN_MTU
int mflag = 0;
@ -321,7 +327,7 @@ main(int argc, char *argv[])
memset(&smsghdr, 0, sizeof(smsghdr));
memset(&smsgiov, 0, sizeof(smsgiov));
preload = 0;
alarmtimeout = preload = 0;
datap = &outpack[ICMP6ECHOLEN + ICMP6ECHOTMLEN];
#ifndef IPSEC
#define ADDOPTS
@ -333,7 +339,7 @@ main(int argc, char *argv[])
#endif /*IPSEC_POLICY_IPSEC*/
#endif
while ((ch = getopt(argc, argv,
"a:b:c:DdfHg:h:I:i:l:mnNop:qrRS:s:tvwW" ADDOPTS)) != -1) {
"a:b:c:DdfHg:h:I:i:l:mnNop:qrRS:s:tvwWx:X:" ADDOPTS)) != -1) {
#undef ADDOPTS
switch (ch) {
case 'a':
@ -541,6 +547,24 @@ main(int argc, char *argv[])
options &= ~F_NOUSERDATA;
options |= F_FQDNOLD;
break;
case 'x':
t = strtod(optarg, &e);
if (*e || e == optarg || t > (double)INT_MAX)
err(EX_USAGE, "invalid timing interval: `%s'",
optarg);
options |= F_WAITTIME;
waittime = (int)t;
break;
case 'X':
alarmtimeout = strtoul(optarg, &e, 0);
if ((alarmtimeout < 1) || (alarmtimeout == ULONG_MAX))
errx(EX_USAGE, "invalid timeout: `%s'",
optarg);
if (alarmtimeout > MAXALARM)
errx(EX_USAGE, "invalid timeout: `%s' > %d",
optarg, MAXALARM);
alarm((int)alarmtimeout);
break;
#ifdef IPSEC
#ifdef IPSEC_POLICY_IPSEC
case 'P':
@ -1057,6 +1081,10 @@ main(int argc, char *argv[])
err(EX_OSERR, "sigaction SIGINFO");
seeninfo = 0;
#endif
if (alarmtimeout > 0) {
if (sigaction(SIGALRM, &si_sa, 0) == -1)
err(EX_OSERR, "sigaction SIGALRM");
}
if (options & F_FLOOD) {
intvl.tv_sec = 0;
intvl.tv_usec = 10000;
@ -1157,17 +1185,18 @@ main(int argc, char *argv[])
/*
* If we're not transmitting any more packets,
* change the timer to wait two round-trip times
* if we've received any packets or ten seconds
* if we haven't.
* if we've received any packets or (waittime)
* milliseconds if we haven't.
*/
#define MAXWAIT 10
intvl.tv_usec = 0;
if (nreceived) {
intvl.tv_sec = 2 * tmax / 1000;
if (intvl.tv_sec == 0)
intvl.tv_sec = 1;
} else
intvl.tv_sec = MAXWAIT;
} else {
intvl.tv_sec = waittime / 1000;
intvl.tv_usec = waittime % 1000 * 1000;
}
}
gettimeofday(&last, NULL);
if (ntransmitted - nreceived - 1 > nmissedmax) {
@ -1181,6 +1210,7 @@ main(int argc, char *argv[])
si_sa.sa_flags = 0;
si_sa.sa_handler = SIG_IGN;
sigaction(SIGINT, &si_sa, 0);
sigaction(SIGALRM, &si_sa, 0);
summary();
if (res != NULL)
@ -1198,6 +1228,7 @@ onsignal(int sig)
switch (sig) {
case SIGINT:
case SIGALRM:
seenint++;
break;
#ifdef SIGINFO
@ -1521,6 +1552,11 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
if (options & F_QUIET)
return;
if (options & F_WAITTIME && triptime > waittime) {
++nrcvtimeout;
return;
}
if (options & F_FLOOD)
(void)write(STDOUT_FILENO, &BSPACE, 1);
else {
@ -2216,6 +2252,8 @@ summary(void)
((((double)ntransmitted - nreceived) * 100.0) /
ntransmitted));
}
if (nrcvtimeout)
printf(", %ld packets out of wait time", nrcvtimeout);
(void)putchar('\n');
if (nreceived && timing) {
/* Only display average to microseconds */
@ -2741,6 +2779,7 @@ usage(void)
#endif
"\n"
" [-p pattern] [-S sourceaddr] [-s packetsize] "
"[hops ...] host\n");
"[-x waittime]\n"
" [-X timeout] [hops ...] host\n");
exit(1);
}

View File

@ -25,7 +25,7 @@
*/
#include <machine/asmacros.h>
#include "svm_assym.s"
#include "svm_assym.h"
/*
* Be friendly to DTrace FBT's prologue/epilogue pattern matching.

View File

@ -29,7 +29,7 @@
#include <machine/asmacros.h>
#include "vmx_assym.s"
#include "vmx_assym.h"
#ifdef SMP
#define LK lock ;

View File

@ -3231,7 +3231,8 @@ net/if_ethersubr.c optional ether
net/if_faith.c optional faith
net/if_fddisubr.c optional fddi
net/if_fwsubr.c optional fwip
net/if_gif.c optional gif inet | gif inet6 | netgraph_gif
net/if_gif.c optional gif inet | gif inet6 | \
netgraph_gif inet | netgraph_gif inet6
net/if_gre.c optional gre inet
net/if_iso88025subr.c optional token
net/if_lagg.c optional lagg
@ -3357,7 +3358,7 @@ netgraph/ng_eiface.c optional netgraph_eiface
netgraph/ng_ether.c optional netgraph_ether
netgraph/ng_ether_echo.c optional netgraph_ether_echo
netgraph/ng_frame_relay.c optional netgraph_frame_relay
netgraph/ng_gif.c optional netgraph_gif
netgraph/ng_gif.c optional netgraph_gif inet6 | netgraph_gif inet
netgraph/ng_gif_demux.c optional netgraph_gif_demux
netgraph/ng_hole.c optional netgraph_hole
netgraph/ng_iface.c optional netgraph_iface

View File

@ -550,7 +550,6 @@ autofs_ioctl_request(struct autofs_daemon_request *adr)
&autofs_softc->sc_lock);
if (error != 0) {
sx_xunlock(&autofs_softc->sc_lock);
AUTOFS_DEBUG("failed with error %d", error);
return (error);
}
}

View File

@ -61,8 +61,9 @@ static void
g_confdot_provider(struct sbuf *sb, struct g_provider *pp)
{
sbuf_printf(sb, "z%p [shape=hexagon,label=\"%s\\nr%dw%de%d\\nerr#%d\"];\n",
pp, pp->name, pp->acr, pp->acw, pp->ace, pp->error);
sbuf_printf(sb, "z%p [shape=hexagon,label=\"%s\\nr%dw%de%d\\nerr#%d\\n"
"sector=%u\\nstripe=%u\"];\n", pp, pp->name, pp->acr, pp->acw,
pp->ace, pp->error, pp->sectorsize, pp->stripesize);
}
static void

View File

@ -3,6 +3,7 @@
KMOD= vmm
SRCS= opt_acpi.h opt_ddb.h device_if.h bus_if.h pci_if.h
SRCS+= vmx_assym.h svm_assym.h
CFLAGS+= -DVMM_KEEP_STATS -DSMP
CFLAGS+= -I${.CURDIR}/../../amd64/vmm
@ -39,6 +40,7 @@ SRCS+= iommu.c \
SRCS+= ept.c \
vmcs.c \
vmx_msr.c \
vmx_support.S \
vmx.c \
vtd.c
@ -46,37 +48,37 @@ SRCS+= ept.c \
.PATH: ${.CURDIR}/../../amd64/vmm/amd
SRCS+= vmcb.c \
svm.c \
svm_support.S \
npt.c \
amdv.c \
svm_msr.c
OBJS= vmx_support.o svm_support.o
CLEANFILES= vmx_assym.h vmx_genassym.o svm_assym.h svm_genassym.o
CLEANFILES= vmx_assym.s vmx_genassym.o svm_assym.s svm_genassym.o
vmx_assym.s: vmx_genassym.o
vmx_assym.h: vmx_genassym.o
.if exists(@)
vmx_assym.s: @/kern/genassym.sh
vmx_assym.h: @/kern/genassym.sh
.endif
sh @/kern/genassym.sh vmx_genassym.o > ${.TARGET}
svm_assym.s: svm_genassym.o
svm_assym.h: svm_genassym.o
.if exists(@)
svm_assym.s: @/kern/genassym.sh
svm_assym.h: @/kern/genassym.sh
.endif
sh @/kern/genassym.sh svm_genassym.o > ${.TARGET}
vmx_support.o: vmx_support.S vmx_assym.s
vmx_support.o:
${CC} -c -x assembler-with-cpp -DLOCORE ${CFLAGS} \
${.IMPSRC} -o ${.TARGET}
svm_support.o: svm_support.S svm_assym.s
svm_support.o:
${CC} -c -x assembler-with-cpp -DLOCORE ${CFLAGS} \
${.IMPSRC} -o ${.TARGET}
vmx_genassym.o: vmx_genassym.c @ machine x86
vmx_genassym.o:
${CC} -c ${CFLAGS:N-fno-common} ${.IMPSRC}
svm_genassym.o: svm_genassym.c @ machine x86
svm_genassym.o:
${CC} -c ${CFLAGS:N-fno-common} ${.IMPSRC}
.include <bsd.kmod.mk>

View File

@ -569,9 +569,22 @@ lagg_clone_destroy(struct ifnet *ifp)
static void
lagg_lladdr(struct lagg_softc *sc, uint8_t *lladdr)
{
struct ifnet *ifp = sc->sc_ifp;
struct lagg_port lp;
if (memcmp(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN) == 0)
return;
LAGG_WLOCK_ASSERT(sc);
/*
* Set the link layer address on the lagg interface.
* lagg_proto_lladdr() notifies the MAC change to
* the aggregation protocol. iflladdr_event handler which
* may trigger gratuitous ARPs for INET will be handled in
* a taskqueue.
*/
bcopy(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN);
lagg_proto_lladdr(sc);
bzero(&lp, sizeof(lp));
lp.lp_ifp = sc->sc_ifp;
@ -625,11 +638,13 @@ lagg_port_lladdr(struct lagg_port *lp, uint8_t *lladdr)
struct ifnet *ifp = lp->lp_ifp;
struct lagg_llq *llq;
int pending = 0;
int primary;
LAGG_WLOCK_ASSERT(sc);
if (lp->lp_detaching ||
memcmp(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN) == 0)
primary = (sc->sc_primary->lp_ifp == ifp) ? 1 : 0;
if (primary == 0 && (lp->lp_detaching ||
memcmp(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN) == 0))
return;
/* Check to make sure its not already queued to be changed */
@ -648,7 +663,7 @@ lagg_port_lladdr(struct lagg_port *lp, uint8_t *lladdr)
/* Update the lladdr even if pending, it may have changed */
llq->llq_ifp = ifp;
llq->llq_primary = (sc->sc_primary->lp_ifp == ifp) ? 1 : 0;
llq->llq_primary = primary;
bcopy(lladdr, llq->llq_lladdr, ETHER_ADDR_LEN);
if (!pending)
@ -692,23 +707,8 @@ lagg_port_setlladdr(void *arg, int pending)
if (error)
printf("%s: setlladdr failed on %s\n", __func__,
ifp->if_xname);
} else {
/*
* Set the link layer address on the lagg interface.
* lagg_proto_lladdr() notifies the MAC change to
* the aggregation protocol. iflladdr_event handler
* may trigger gratuitous ARPs for INET.
*/
if (memcmp(llq->llq_lladdr, IF_LLADDR(ifp),
ETHER_ADDR_LEN) != 0) {
bcopy(llq->llq_lladdr, IF_LLADDR(ifp),
ETHER_ADDR_LEN);
LAGG_WLOCK(sc);
lagg_proto_lladdr(sc);
LAGG_WUNLOCK(sc);
EVENTHANDLER_INVOKE(iflladdr_event, ifp);
}
}
} else
EVENTHANDLER_INVOKE(iflladdr_event, ifp);
CURVNET_RESTORE();
head = SLIST_NEXT(llq, llq_entries);
free(llq, M_DEVBUF);
@ -742,34 +742,6 @@ lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp)
if (ifp->if_type != IFT_ETHER)
return (EPROTONOSUPPORT);
#ifdef INET6
/*
* The member interface should not have inet6 address because
* two interfaces with a valid link-local scope zone must not be
* merged in any form. This restriction is needed to
* prevent violation of link-local scope zone. Attempts to
* add a member interface which has inet6 addresses triggers
* removal of all inet6 addresses on the member interface.
*/
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
if (in6ifa_llaonifp(lp->lp_ifp)) {
in6_ifdetach(lp->lp_ifp);
if_printf(sc->sc_ifp,
"IPv6 addresses on %s have been removed "
"before adding it as a member to prevent "
"IPv6 address scope violation.\n",
lp->lp_ifp->if_xname);
}
}
if (in6ifa_llaonifp(ifp)) {
in6_ifdetach(ifp);
if_printf(sc->sc_ifp,
"IPv6 addresses on %s have been removed "
"before adding it as a member to prevent "
"IPv6 address scope violation.\n",
ifp->if_xname);
}
#endif
/* Allow the first Ethernet member to define the MTU */
if (SLIST_EMPTY(&sc->sc_ports))
sc->sc_ifp->if_mtu = ifp->if_mtu;
@ -1414,6 +1386,26 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
error = EINVAL;
break;
}
#ifdef INET6
/*
* A laggport interface should not have inet6 address
* because two interfaces with a valid link-local
* scope zone must not be merged in any form. This
* restriction is needed to prevent violation of
* link-local scope zone. Attempts to add a laggport
* interface which has inet6 addresses triggers
* removal of all inet6 addresses on the member
* interface.
*/
if (in6ifa_llaonifp(tpif)) {
in6_ifdetach(tpif);
if_printf(sc->sc_ifp,
"IPv6 addresses on %s have been removed "
"before adding it as a member to prevent "
"IPv6 address scope violation.\n",
tpif->if_xname);
}
#endif
LAGG_WLOCK(sc);
error = lagg_port_create(sc, tpif);
LAGG_WUNLOCK(sc);

View File

@ -55,8 +55,7 @@ __FBSDID("$FreeBSD$");
enum blockop {
BOP_READ,
BOP_WRITE,
BOP_FLUSH,
BOP_CANCEL
BOP_FLUSH
};
enum blockstat {
@ -159,9 +158,6 @@ blockif_proc(struct blockif_ctxt *bc, struct blockif_elem *be)
break;
case BOP_FLUSH:
break;
case BOP_CANCEL:
err = EINTR;
break;
default:
err = EINVAL;
break;
@ -356,9 +352,28 @@ blockif_flush(struct blockif_ctxt *bc, struct blockif_req *breq)
int
blockif_cancel(struct blockif_ctxt *bc, struct blockif_req *breq)
{
struct blockif_elem *be;
assert(bc->bc_magic == BLOCKIF_SIG);
return (blockif_request(bc, breq, BOP_CANCEL));
pthread_mutex_lock(&bc->bc_mtx);
TAILQ_FOREACH(be, &bc->bc_inuseq, be_link) {
if (be->be_req == breq)
break;
}
if (be == NULL) {
pthread_mutex_unlock(&bc->bc_mtx);
return (EINVAL);
}
TAILQ_REMOVE(&bc->bc_inuseq, be, be_link);
be->be_status = BST_FREE;
be->be_req = NULL;
TAILQ_INSERT_TAIL(&bc->bc_freeq, be, be_link);
bc->bc_req_count--;
pthread_mutex_unlock(&bc->bc_mtx);
return (0);
}
int

View File

@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <unistd.h>
#include <assert.h>
#include <pthread.h>
#include <pthread_np.h>
#include <inttypes.h>
#include "bhyverun.h"
@ -115,7 +116,8 @@ static FILE *dbg;
struct ahci_ioreq {
struct blockif_req io_req;
struct ahci_port *io_pr;
STAILQ_ENTRY(ahci_ioreq) io_list;
STAILQ_ENTRY(ahci_ioreq) io_flist;
TAILQ_ENTRY(ahci_ioreq) io_blist;
uint8_t *cfis;
uint32_t len;
uint32_t done;
@ -160,6 +162,7 @@ struct ahci_port {
struct ahci_ioreq *ioreq;
int ioqsz;
STAILQ_HEAD(ahci_fhead, ahci_ioreq) iofhd;
TAILQ_HEAD(ahci_bhead, ahci_ioreq) iobhd;
};
struct ahci_cmd_hdr {
@ -359,6 +362,68 @@ ahci_write_reset_fis_d2h(struct ahci_port *p)
ahci_write_fis(p, FIS_TYPE_REGD2H, fis);
}
static void
ahci_check_stopped(struct ahci_port *p)
{
/*
* If we are no longer processing the command list and nothing
* is in-flight, clear the running bit.
*/
if (!(p->cmd & AHCI_P_CMD_ST)) {
if (p->pending == 0)
p->cmd &= ~(AHCI_P_CMD_CR | AHCI_P_CMD_CCS_MASK);
}
}
static void
ahci_port_stop(struct ahci_port *p)
{
struct ahci_ioreq *aior;
uint8_t *cfis;
int slot;
int ncq;
int error;
assert(pthread_mutex_isowned_np(&p->pr_sc->mtx));
TAILQ_FOREACH(aior, &p->iobhd, io_blist) {
/*
* Try to cancel the outstanding blockif request.
*/
error = blockif_cancel(p->bctx, &aior->io_req);
if (error != 0)
continue;
slot = aior->slot;
cfis = aior->cfis;
if (cfis[2] == ATA_WRITE_FPDMA_QUEUED ||
cfis[2] == ATA_READ_FPDMA_QUEUED)
ncq = 1;
if (ncq)
p->sact &= ~(1 << slot);
else
p->ci &= ~(1 << slot);
/*
* This command is now done.
*/
p->pending &= ~(1 << slot);
/*
* Delete the blockif request from the busy list
*/
TAILQ_REMOVE(&p->iobhd, aior, io_blist);
/*
* Move the blockif request back to the free list
*/
STAILQ_INSERT_TAIL(&p->iofhd, aior, io_flist);
}
ahci_check_stopped(p);
}
static void
ahci_port_reset(struct ahci_port *pr)
{
@ -492,7 +557,7 @@ ahci_handle_dma(struct ahci_port *p, int slot, uint8_t *cfis, uint32_t done,
*/
aior = STAILQ_FIRST(&p->iofhd);
assert(aior != NULL);
STAILQ_REMOVE_HEAD(&p->iofhd, io_list);
STAILQ_REMOVE_HEAD(&p->iofhd, io_flist);
aior->cfis = cfis;
aior->slot = slot;
aior->len = len;
@ -503,14 +568,20 @@ ahci_handle_dma(struct ahci_port *p, int slot, uint8_t *cfis, uint32_t done,
if (iovcnt > BLOCKIF_IOV_MAX) {
aior->prdtl = iovcnt - BLOCKIF_IOV_MAX;
iovcnt = BLOCKIF_IOV_MAX;
/*
* Mark this command in-flight.
*/
p->pending |= 1 << slot;
} else
aior->prdtl = 0;
breq->br_iovcnt = iovcnt;
/*
* Mark this command in-flight.
*/
p->pending |= 1 << slot;
/*
* Stuff request onto busy list
*/
TAILQ_INSERT_HEAD(&p->iobhd, aior, io_blist);
/*
* Build up the iovec based on the prdt
*/
@ -546,7 +617,7 @@ ahci_handle_flush(struct ahci_port *p, int slot, uint8_t *cfis)
*/
aior = STAILQ_FIRST(&p->iofhd);
assert(aior != NULL);
STAILQ_REMOVE_HEAD(&p->iofhd, io_list);
STAILQ_REMOVE_HEAD(&p->iofhd, io_flist);
aior->cfis = cfis;
aior->slot = slot;
aior->len = 0;
@ -554,6 +625,16 @@ ahci_handle_flush(struct ahci_port *p, int slot, uint8_t *cfis)
aior->prdtl = 0;
breq = &aior->io_req;
/*
* Mark this command in-flight.
*/
p->pending |= 1 << slot;
/*
* Stuff request onto busy list
*/
TAILQ_INSERT_HEAD(&p->iobhd, aior, io_blist);
err = blockif_flush(p->bctx, breq);
assert(err == 0);
}
@ -961,7 +1042,7 @@ atapi_read(struct ahci_port *p, int slot, uint8_t *cfis,
*/
aior = STAILQ_FIRST(&p->iofhd);
assert(aior != NULL);
STAILQ_REMOVE_HEAD(&p->iofhd, io_list);
STAILQ_REMOVE_HEAD(&p->iofhd, io_flist);
aior->cfis = cfis;
aior->slot = slot;
aior->len = len;
@ -976,6 +1057,16 @@ atapi_read(struct ahci_port *p, int slot, uint8_t *cfis,
aior->prdtl = 0;
breq->br_iovcnt = iovcnt;
/*
* Mark this command in-flight.
*/
p->pending |= 1 << slot;
/*
* Stuff request onto busy list
*/
TAILQ_INSERT_HEAD(&p->iobhd, aior, io_blist);
/*
* Build up the iovec based on the prdt
*/
@ -1414,10 +1505,15 @@ ata_ioreq_cb(struct blockif_req *br, int err)
pthread_mutex_lock(&sc->mtx);
/*
* Delete the blockif request from the busy list
*/
TAILQ_REMOVE(&p->iobhd, aior, io_blist);
/*
* Move the blockif request back to the free list
*/
STAILQ_INSERT_TAIL(&p->iofhd, aior, io_list);
STAILQ_INSERT_TAIL(&p->iofhd, aior, io_flist);
if (pending && !err) {
ahci_handle_dma(p, slot, cfis, aior->done,
@ -1438,17 +1534,18 @@ ata_ioreq_cb(struct blockif_req *br, int err)
p->serr |= (1 << slot);
}
/*
* This command is now complete.
*/
p->pending &= ~(1 << slot);
if (ncq) {
p->sact &= ~(1 << slot);
ahci_write_fis_sdb(p, slot, tfd);
} else
ahci_write_fis_d2h(p, slot, cfis, tfd);
/*
* This command is now complete.
*/
p->pending &= ~(1 << slot);
ahci_check_stopped(p);
out:
pthread_mutex_unlock(&sc->mtx);
DPRINTF("%s exit\n", __func__);
@ -1477,10 +1574,15 @@ atapi_ioreq_cb(struct blockif_req *br, int err)
pthread_mutex_lock(&sc->mtx);
/*
* Delete the blockif request from the busy list
*/
TAILQ_REMOVE(&p->iobhd, aior, io_blist);
/*
* Move the blockif request back to the free list
*/
STAILQ_INSERT_TAIL(&p->iofhd, aior, io_list);
STAILQ_INSERT_TAIL(&p->iofhd, aior, io_flist);
if (pending && !err) {
atapi_read(p, slot, cfis, aior->done, hdr->prdtl - pending);
@ -1500,6 +1602,12 @@ atapi_ioreq_cb(struct blockif_req *br, int err)
cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN;
ahci_write_fis_d2h(p, slot, cfis, tfd);
/*
* This command is now complete.
*/
p->pending &= ~(1 << slot);
ahci_check_stopped(p);
out:
pthread_mutex_unlock(&sc->mtx);
DPRINTF("%s exit\n", __func__);
@ -1526,8 +1634,10 @@ pci_ahci_ioreq_init(struct ahci_port *pr)
else
vr->io_req.br_callback = atapi_ioreq_cb;
vr->io_req.br_param = vr;
STAILQ_INSERT_TAIL(&pr->iofhd, vr, io_list);
STAILQ_INSERT_TAIL(&pr->iofhd, vr, io_flist);
}
TAILQ_INIT(&pr->iobhd);
}
static void
@ -1565,9 +1675,7 @@ pci_ahci_port_write(struct pci_ahci_softc *sc, uint64_t offset, uint64_t value)
p->cmd = value;
if (!(value & AHCI_P_CMD_ST)) {
p->cmd &= ~(AHCI_P_CMD_CR | AHCI_P_CMD_CCS_MASK);
p->ci = 0;
p->sact = 0;
ahci_port_stop(p);
} else {
uint64_t clb;