mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-19 17:26:28 +00:00
Update hyperkit vendoring
This includes using ftruncate for speedier disk creation Signed-off-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
This commit is contained in:
parent
a9e6f37958
commit
4b9bf071e5
@ -15,7 +15,7 @@ github.com/gophercloud/gophercloud 2804b72cf099b41d2e25c8afcca786f9f962ddee
|
||||
github.com/jmespath/go-jmespath bd40a432e4c76585ef6b72d3fd96fb9b6dc7b68d
|
||||
github.com/mitchellh/go-ps 4fdf99ab29366514c69ccccddab5dc58b8d84062
|
||||
github.com/moby/datakit 97b3d230535397a813323902c23751e176481a86
|
||||
github.com/moby/hyperkit 3e31617ae866c93925e2b3bc5d8006b60985e920
|
||||
github.com/moby/hyperkit a12cd7250bcd8d689078e3e42ae4a7cf6a0cbaf3
|
||||
github.com/moby/vpnkit 0e4293bb1058598c4b0a406ed171f52573ef414c
|
||||
github.com/packethost/packngo 131798f2804a1b3e895ca98047d56f0d7e094e2a
|
||||
github.com/pmezard/go-difflib v1.0.0
|
||||
|
6
src/cmd/linuxkit/vendor/github.com/moby/hyperkit/go/hyperkit.go
generated
vendored
6
src/cmd/linuxkit/vendor/github.com/moby/hyperkit/go/hyperkit.go
generated
vendored
@ -395,11 +395,7 @@ func CreateDiskImage(location string, sizeMB int) error {
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
buf := make([]byte, 1048676)
|
||||
for i := 0; i < sizeMB; i++ {
|
||||
f.Write(buf)
|
||||
}
|
||||
return nil
|
||||
return f.Truncate(int64(sizeMB) * int64(1024) * int64(1024))
|
||||
}
|
||||
|
||||
func intArrayToString(i []int, sep string) string {
|
||||
|
@ -4,5 +4,6 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
int bootrom_init(const char *bootrom_path);
|
||||
const char *bootrom(void);
|
||||
uint64_t bootrom_load(void);
|
||||
bool bootrom_contains_gpa(uint64_t gpa);
|
||||
|
54
src/cmd/linuxkit/vendor/github.com/moby/hyperkit/src/include/xhyve/fwctl.h
generated
vendored
Normal file
54
src/cmd/linuxkit/vendor/github.com/moby/hyperkit/src/include/xhyve/fwctl.h
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
/*-
|
||||
* Copyright (c) 2015 Peter Grehan <grehan@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _FWCTL_H_
|
||||
#define _FWCTL_H_
|
||||
|
||||
#include <xhyve/support/linker_set.h>
|
||||
|
||||
/*
|
||||
* Linker set api for export of information to guest firmware via
|
||||
* a sysctl-like OID interface
|
||||
*/
|
||||
struct ctl {
|
||||
const char *c_oid;
|
||||
const void *c_data;
|
||||
const int c_len;
|
||||
};
|
||||
|
||||
#define CTL_NODE(oid, data, len) \
|
||||
static struct ctl __CONCAT(__ctl, __LINE__) = { \
|
||||
oid, \
|
||||
(data), \
|
||||
(len), \
|
||||
}; \
|
||||
DATA_SET(ctl_set, __CONCAT(__ctl, __LINE__))
|
||||
|
||||
void fwctl_init(void);
|
||||
|
||||
#endif /* _FWCTL_H_ */
|
100
src/cmd/linuxkit/vendor/github.com/moby/hyperkit/src/lib/block_if.c
generated
vendored
100
src/cmd/linuxkit/vendor/github.com/moby/hyperkit/src/lib/block_if.c
generated
vendored
@ -33,6 +33,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/disk.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
@ -53,6 +54,14 @@
|
||||
|
||||
#define BLOCKIF_SIG 0xb109b109
|
||||
|
||||
#ifndef ALIGNUP
|
||||
#define ALIGNUP(x, a) (((x - 1) & ~(a - 1)) + a)
|
||||
#endif
|
||||
|
||||
#ifndef ALIGNDOWN
|
||||
#define ALIGNDOWN(x, a) (-(a) & (x))
|
||||
#endif
|
||||
|
||||
/* xhyve: FIXME
|
||||
*
|
||||
* // #define BLOCKIF_NUMTHR 8
|
||||
@ -101,6 +110,8 @@ struct blockif_ctxt {
|
||||
off_t bc_size;
|
||||
int bc_sectsz;
|
||||
int bc_psectsz;
|
||||
size_t bc_delete_alignment; /* f_bsize always a power of 2 */
|
||||
void* bc_delete_zero_buf;
|
||||
int bc_psectoff;
|
||||
int bc_closing;
|
||||
pthread_t bc_btid[BLOCKIF_NUMTHR];
|
||||
@ -211,6 +222,7 @@ static int
|
||||
block_delete(struct blockif_ctxt *bc, off_t offset, off_t len)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
off_t arg[2] = { offset, len };
|
||||
#endif
|
||||
@ -221,22 +233,52 @@ block_delete(struct blockif_ctxt *bc, off_t offset, off_t len)
|
||||
errno = EOPNOTSUPP;
|
||||
else if (bc->bc_rdonly)
|
||||
errno = EROFS;
|
||||
if (bc->bc_fd >= 0) {
|
||||
if (bc->bc_ischr) {
|
||||
#ifdef __FreeBSD__
|
||||
ret = ioctl(bc->bc_fd, DIOCGDELETE, arg);
|
||||
#else
|
||||
errno = EOPNOTSUPP;
|
||||
#endif
|
||||
} else
|
||||
errno = EOPNOTSUPP;
|
||||
#ifdef HAVE_OCAML_QCOW
|
||||
} else if (bc->bc_mbh >= 0) {
|
||||
if (bc->bc_mbh >= 0) {
|
||||
ret = mirage_block_delete(bc->bc_mbh, offset, len);
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
} else
|
||||
abort();
|
||||
#ifdef __FreeBSD__
|
||||
if ((bc->bc_fd >= 0) && (bc->bc_ischr)) {
|
||||
ret = ioctl(bc->bc_fd, DIOCGDELETE, arg);
|
||||
errno = EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
#elif __APPLE__
|
||||
if (bc->bc_fd >= 0) {
|
||||
/* PUNCHHOLE lengths and offsets have to be aligned so explicitly write zeroes
|
||||
into the unaligned parts at the beginning and the end. This wouldn't be necessary
|
||||
if the host and guest had the same sector size */
|
||||
assert (offset >= 0);
|
||||
assert (len >= 0);
|
||||
size_t fp_offset = (size_t) offset;
|
||||
size_t fp_length = (size_t) len;
|
||||
|
||||
size_t aligned_offset = ALIGNUP(fp_offset, bc->bc_delete_alignment);
|
||||
if (aligned_offset != fp_offset) {
|
||||
size_t len_to_zero = aligned_offset - fp_offset;
|
||||
assert(len_to_zero <= bc->bc_delete_alignment);
|
||||
ssize_t written = pwrite(bc->bc_fd, bc->bc_delete_zero_buf, len_to_zero, (off_t) fp_offset);
|
||||
if (written == -1) goto out;
|
||||
fp_offset += len_to_zero;
|
||||
fp_length -= len_to_zero;
|
||||
}
|
||||
size_t aligned_length = ALIGNDOWN(fp_length, bc->bc_delete_alignment);
|
||||
if (aligned_length != fp_length) {
|
||||
size_t len_to_zero = fp_length - aligned_length;
|
||||
assert(len_to_zero <= bc->bc_delete_alignment);
|
||||
fp_length -= len_to_zero;
|
||||
ssize_t written = pwrite(bc->bc_fd, bc->bc_delete_zero_buf, len_to_zero, (off_t) (fp_offset + fp_length));
|
||||
if (written == -1) goto out;
|
||||
}
|
||||
struct fpunchhole arg = { .fp_flags = 0, .reserved = 0, .fp_offset = (off_t) fp_offset, .fp_length = (off_t) fp_length };
|
||||
ret = fcntl(bc->bc_fd, F_PUNCHHOLE, &arg);
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
errno = EOPNOTSUPP;
|
||||
out:
|
||||
HYPERKIT_BLOCK_DELETE_DONE(offset, ret);
|
||||
return ret;
|
||||
}
|
||||
@ -554,9 +596,12 @@ blockif_open(const char *optstr, const char *ident)
|
||||
char *nopt, *xopts, *cp;
|
||||
struct blockif_ctxt *bc;
|
||||
struct stat sbuf;
|
||||
struct statfs fsbuf;
|
||||
// struct diocgattr_arg arg;
|
||||
off_t size, psectsz, psectoff, blocks;
|
||||
int extra, fd, i, sectsz;
|
||||
size_t delete_alignment;
|
||||
void *delete_zero_buf;
|
||||
int nocache, sync, ro, candelete, geom, ssopt, pssopt;
|
||||
mirage_block_handle mbh;
|
||||
int use_mirage = 0;
|
||||
@ -621,6 +666,8 @@ blockif_open(const char *optstr, const char *ident)
|
||||
extra |= O_SYNC;
|
||||
|
||||
candelete = 0;
|
||||
sectsz = DEV_BSIZE;
|
||||
delete_alignment = DEV_BSIZE;
|
||||
|
||||
if (use_mirage) {
|
||||
#ifdef HAVE_OCAML_QCOW
|
||||
@ -655,7 +702,33 @@ blockif_open(const char *optstr, const char *ident)
|
||||
perror("Could not stat backing file");
|
||||
goto err;
|
||||
}
|
||||
if (fstatfs(fd, &fsbuf) < 0) {
|
||||
perror("Could not stat backfile file filesystem");
|
||||
goto err;
|
||||
}
|
||||
delete_alignment = (size_t)fsbuf.f_bsize;
|
||||
#ifdef __APPLE__
|
||||
{
|
||||
/* Check to see whether we can use F_PUNCHHOLE on this file */
|
||||
struct fpunchhole arg = { .fp_flags = 0, .reserved = 0, .fp_offset = 0, .fp_length = 0 };
|
||||
if (fcntl(fd, F_PUNCHHOLE, &arg) == 0) {
|
||||
/* Sparse files are supported: enable TRIM */
|
||||
candelete = 1;
|
||||
} else {
|
||||
perror("fcntl(F_PUNCHHOLE) failed: host filesystem does not support sparse files");
|
||||
candelete = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* delete_alignment is a power of 2 allowing us to use ALIGNDOWN for rounding */
|
||||
assert((delete_alignment & (delete_alignment - 1)) == 0);
|
||||
|
||||
if ((delete_zero_buf = malloc(delete_alignment)) == NULL){
|
||||
perror("Failed to allocate zeroed buffer for unaligned deletes");
|
||||
goto err;
|
||||
}
|
||||
bzero(delete_zero_buf, delete_alignment);
|
||||
|
||||
/* One and only one handle */
|
||||
assert(mbh >= 0 || fd >= 0);
|
||||
@ -664,7 +737,6 @@ blockif_open(const char *optstr, const char *ident)
|
||||
* Deal with raw devices
|
||||
*/
|
||||
size = sbuf.st_size;
|
||||
sectsz = DEV_BSIZE;
|
||||
psectsz = psectoff = 0;
|
||||
geom = 0;
|
||||
if (S_ISCHR(sbuf.st_mode)) {
|
||||
@ -749,6 +821,8 @@ blockif_open(const char *optstr, const char *ident)
|
||||
bc->bc_sectsz = sectsz;
|
||||
bc->bc_psectsz = (int)psectsz;
|
||||
bc->bc_psectoff = (int)psectoff;
|
||||
bc->bc_delete_alignment = delete_alignment;
|
||||
bc->bc_delete_zero_buf = delete_zero_buf;
|
||||
pthread_mutex_init(&bc->bc_mtx, NULL);
|
||||
pthread_cond_init(&bc->bc_cond, NULL);
|
||||
TAILQ_INIT(&bc->bc_freeq);
|
||||
|
560
src/cmd/linuxkit/vendor/github.com/moby/hyperkit/src/lib/fwctl.c
generated
vendored
Normal file
560
src/cmd/linuxkit/vendor/github.com/moby/hyperkit/src/lib/fwctl.c
generated
vendored
Normal file
@ -0,0 +1,560 @@
|
||||
/*-
|
||||
* Copyright (c) 2015 Peter Grehan <grehan@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Guest firmware interface. Uses i/o ports x510/x511 as Qemu does,
|
||||
* but with a request/response messaging protocol.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "xhyve/inout.h"
|
||||
#include "xhyve/xhyve.h"
|
||||
#include "xhyve/support/misc.h"
|
||||
#include "xhyve/fwctl.h"
|
||||
|
||||
/*
|
||||
* Messaging protocol base operations
|
||||
*/
|
||||
#define OP_NULL 1
|
||||
#define OP_ECHO 2
|
||||
#define OP_GET 3
|
||||
#define OP_GET_LEN 4
|
||||
#define OP_SET 5
|
||||
#define OP_MAX OP_SET
|
||||
|
||||
/* I/O ports */
|
||||
#define FWCTL_OUT 0x510
|
||||
#define FWCTL_IN 0x511
|
||||
|
||||
/*
|
||||
* Back-end state-machine
|
||||
*/
|
||||
static enum state {
|
||||
DORMANT,
|
||||
IDENT_WAIT,
|
||||
IDENT_SEND,
|
||||
REQ,
|
||||
RESP
|
||||
} be_state = DORMANT;
|
||||
|
||||
static uint8_t sig[] = { 'B', 'H', 'Y', 'V' };
|
||||
static u_int ident_idx;
|
||||
|
||||
struct op_info {
|
||||
int op;
|
||||
int (*op_start)(size_t len);
|
||||
void (*op_data)(uint32_t data, size_t len);
|
||||
int (*op_result)(struct iovec **data);
|
||||
void (*op_done)(struct iovec *data);
|
||||
};
|
||||
static struct op_info *ops[OP_MAX+1];
|
||||
|
||||
/* Return 0-padded uint32_t */
|
||||
static uint32_t
|
||||
fwctl_send_rest(uint8_t *data, size_t len)
|
||||
{
|
||||
union {
|
||||
uint8_t c[4];
|
||||
uint32_t w;
|
||||
} u;
|
||||
size_t i;
|
||||
|
||||
u.w = 0;
|
||||
|
||||
for (i = 0, u.w = 0; i < len; i++)
|
||||
u.c[i] = *data++;
|
||||
|
||||
return (u.w);
|
||||
}
|
||||
|
||||
/*
|
||||
* error op dummy proto - drop all data sent and return an error
|
||||
*/
|
||||
static int errop_code;
|
||||
|
||||
static void
|
||||
errop_set(int err)
|
||||
{
|
||||
|
||||
errop_code = err;
|
||||
}
|
||||
|
||||
static int
|
||||
errop_start(UNUSED size_t len)
|
||||
{
|
||||
errop_code = ENOENT;
|
||||
|
||||
/* accept any length */
|
||||
return (errop_code);
|
||||
}
|
||||
|
||||
static void
|
||||
errop_data(UNUSED uint32_t data, UNUSED size_t len)
|
||||
{
|
||||
|
||||
/* ignore */
|
||||
}
|
||||
|
||||
static int
|
||||
errop_result(struct iovec **data)
|
||||
{
|
||||
|
||||
/* no data to send back; always successful */
|
||||
*data = NULL;
|
||||
return (errop_code);
|
||||
}
|
||||
|
||||
static void
|
||||
errop_done(UNUSED struct iovec *data)
|
||||
{
|
||||
|
||||
/* assert data is NULL */
|
||||
}
|
||||
|
||||
static struct op_info errop_info = {
|
||||
.op_start = errop_start,
|
||||
.op_data = errop_data,
|
||||
.op_result = errop_result,
|
||||
.op_done = errop_done
|
||||
};
|
||||
|
||||
/* OID search */
|
||||
SET_DECLARE(ctl_set, struct ctl);
|
||||
|
||||
CTL_NODE("hw.ncpu", &guest_ncpus, sizeof(guest_ncpus));
|
||||
|
||||
static struct ctl *
|
||||
ctl_locate(const char *str, size_t maxlen)
|
||||
{
|
||||
struct ctl *cp, **cpp;
|
||||
|
||||
SET_FOREACH(cpp, ctl_set) {
|
||||
cp = *cpp;
|
||||
if (!strncmp(str, cp->c_oid, maxlen))
|
||||
return (cp);
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* uefi-sysctl get-len */
|
||||
#define FGET_STRSZ 80
|
||||
static struct iovec fget_biov[2];
|
||||
static char fget_str[FGET_STRSZ];
|
||||
static struct {
|
||||
size_t f_sz;
|
||||
uint32_t f_data[1024];
|
||||
} fget_buf;
|
||||
static size_t fget_cnt;
|
||||
static size_t fget_size;
|
||||
|
||||
static int
|
||||
fget_start(size_t len)
|
||||
{
|
||||
|
||||
if (len > FGET_STRSZ)
|
||||
return(E2BIG);
|
||||
|
||||
fget_cnt = 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
fget_data(uint32_t data, UNUSED size_t len)
|
||||
{
|
||||
memcpy(&fget_str[fget_cnt], &data, sizeof(data));
|
||||
fget_cnt += sizeof(uint32_t);
|
||||
}
|
||||
|
||||
static int
|
||||
fget_result(struct iovec **data, int val)
|
||||
{
|
||||
struct ctl *cp;
|
||||
int err;
|
||||
|
||||
err = 0;
|
||||
|
||||
/* Locate the OID */
|
||||
cp = ctl_locate(fget_str, fget_cnt);
|
||||
if (cp == NULL) {
|
||||
*data = NULL;
|
||||
err = ENOENT;
|
||||
} else {
|
||||
if (val) {
|
||||
/* For now, copy the len/data into a buffer */
|
||||
memset(&fget_buf, 0, sizeof(fget_buf));
|
||||
fget_buf.f_sz = (size_t)cp->c_len;
|
||||
memcpy(fget_buf.f_data, cp->c_data, cp->c_len);
|
||||
fget_biov[0].iov_base = (char *)&fget_buf;
|
||||
fget_biov[0].iov_len = sizeof(fget_buf.f_sz) +
|
||||
(size_t)cp->c_len;
|
||||
} else {
|
||||
fget_size = (size_t)cp->c_len;
|
||||
fget_biov[0].iov_base = (char *)&fget_size;
|
||||
fget_biov[0].iov_len = sizeof(fget_size);
|
||||
}
|
||||
|
||||
fget_biov[1].iov_base = NULL;
|
||||
fget_biov[1].iov_len = 0;
|
||||
*data = fget_biov;
|
||||
}
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static void
|
||||
fget_done(UNUSED struct iovec *data)
|
||||
{
|
||||
|
||||
/* nothing needs to be freed */
|
||||
}
|
||||
|
||||
static int
|
||||
fget_len_result(struct iovec **data)
|
||||
{
|
||||
return (fget_result(data, 0));
|
||||
}
|
||||
|
||||
static int
|
||||
fget_val_result(struct iovec **data)
|
||||
{
|
||||
return (fget_result(data, 1));
|
||||
}
|
||||
|
||||
static struct op_info fgetlen_info = {
|
||||
.op_start = fget_start,
|
||||
.op_data = fget_data,
|
||||
.op_result = fget_len_result,
|
||||
.op_done = fget_done
|
||||
};
|
||||
|
||||
static struct op_info fgetval_info = {
|
||||
.op_start = fget_start,
|
||||
.op_data = fget_data,
|
||||
.op_result = fget_val_result,
|
||||
.op_done = fget_done
|
||||
};
|
||||
|
||||
static struct req_info {
|
||||
int req_error;
|
||||
u_int req_count;
|
||||
uint32_t req_size;
|
||||
uint32_t req_type;
|
||||
uint32_t req_txid;
|
||||
struct op_info *req_op;
|
||||
int resp_error;
|
||||
int resp_count;
|
||||
int resp_size;
|
||||
int resp_off;
|
||||
struct iovec *resp_biov;
|
||||
} rinfo;
|
||||
|
||||
static void
|
||||
fwctl_response_done(void)
|
||||
{
|
||||
|
||||
(*rinfo.req_op->op_done)(rinfo.resp_biov);
|
||||
|
||||
/* reinit the req data struct */
|
||||
memset(&rinfo, 0, sizeof(rinfo));
|
||||
}
|
||||
|
||||
static void
|
||||
fwctl_request_done(void)
|
||||
{
|
||||
|
||||
rinfo.resp_error = (*rinfo.req_op->op_result)(&rinfo.resp_biov);
|
||||
|
||||
/* XXX only a single vector supported at the moment */
|
||||
rinfo.resp_off = 0;
|
||||
if (rinfo.resp_biov == NULL) {
|
||||
rinfo.resp_size = 0;
|
||||
} else {
|
||||
assert(rinfo.resp_biov[0].iov_len < INT_MAX);
|
||||
rinfo.resp_size = (int)rinfo.resp_biov[0].iov_len;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
fwctl_request_start(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Data size doesn't include header */
|
||||
rinfo.req_size -= 12;
|
||||
|
||||
rinfo.req_op = &errop_info;
|
||||
if (rinfo.req_type <= OP_MAX && ops[rinfo.req_type] != NULL)
|
||||
rinfo.req_op = ops[rinfo.req_type];
|
||||
|
||||
err = (*rinfo.req_op->op_start)(rinfo.req_size);
|
||||
|
||||
if (err) {
|
||||
errop_set(err);
|
||||
rinfo.req_op = &errop_info;
|
||||
}
|
||||
|
||||
/* Catch case of zero-length message here */
|
||||
if (rinfo.req_size == 0) {
|
||||
fwctl_request_done();
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
fwctl_request_data(uint32_t value)
|
||||
{
|
||||
size_t remlen;
|
||||
|
||||
/* Make sure remaining size is >= 0 */
|
||||
rinfo.req_size -= sizeof(uint32_t);
|
||||
remlen = MAX(rinfo.req_size, 0);
|
||||
|
||||
(*rinfo.req_op->op_data)(value, remlen);
|
||||
|
||||
if (rinfo.req_size < sizeof(uint32_t)) {
|
||||
fwctl_request_done();
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
fwctl_request(uint32_t value)
|
||||
{
|
||||
|
||||
int ret;
|
||||
|
||||
ret = 0;
|
||||
|
||||
switch (rinfo.req_count) {
|
||||
case 0:
|
||||
/* Verify size */
|
||||
if (value < 12) {
|
||||
printf("msg size error");
|
||||
exit(1);
|
||||
}
|
||||
rinfo.req_size = value;
|
||||
rinfo.req_count = 1;
|
||||
break;
|
||||
case 1:
|
||||
rinfo.req_type = value;
|
||||
rinfo.req_count++;
|
||||
break;
|
||||
case 2:
|
||||
rinfo.req_txid = value;
|
||||
rinfo.req_count++;
|
||||
ret = fwctl_request_start();
|
||||
break;
|
||||
default:
|
||||
ret = fwctl_request_data(value);
|
||||
break;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
fwctl_response(uint32_t *retval)
|
||||
{
|
||||
uint8_t *dp;
|
||||
size_t remlen;
|
||||
|
||||
switch(rinfo.resp_count) {
|
||||
case 0:
|
||||
/* 4 x u32 header len + data */
|
||||
*retval = 4*sizeof(uint32_t) +
|
||||
roundup((uint32_t)rinfo.resp_size, sizeof(uint32_t));
|
||||
rinfo.resp_count++;
|
||||
break;
|
||||
case 1:
|
||||
*retval = rinfo.req_type;
|
||||
rinfo.resp_count++;
|
||||
break;
|
||||
case 2:
|
||||
*retval = rinfo.req_txid;
|
||||
rinfo.resp_count++;
|
||||
break;
|
||||
case 3:
|
||||
*retval = (uint32_t)rinfo.resp_error;
|
||||
rinfo.resp_count++;
|
||||
break;
|
||||
default:
|
||||
remlen = (size_t)rinfo.resp_size - (size_t)rinfo.resp_off;
|
||||
dp = ((uint8_t *)rinfo.resp_biov->iov_base + rinfo.resp_off);
|
||||
if (remlen >= sizeof(uint32_t)) {
|
||||
memcpy(retval, dp, sizeof(*retval));
|
||||
} else if (remlen > 0) {
|
||||
*retval = fwctl_send_rest(dp, remlen);
|
||||
}
|
||||
rinfo.resp_off += sizeof(uint32_t);
|
||||
break;
|
||||
}
|
||||
|
||||
if (rinfo.resp_count > 3 &&
|
||||
rinfo.resp_size - rinfo.resp_off <= 0) {
|
||||
fwctl_response_done();
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* i/o port handling.
|
||||
*/
|
||||
static uint8_t
|
||||
fwctl_inb(void)
|
||||
{
|
||||
uint8_t retval;
|
||||
|
||||
retval = 0xff;
|
||||
|
||||
switch (be_state) {
|
||||
case DORMANT:
|
||||
case IDENT_WAIT:
|
||||
break;
|
||||
case IDENT_SEND:
|
||||
retval = sig[ident_idx++];
|
||||
if (ident_idx >= sizeof(sig))
|
||||
be_state = REQ;
|
||||
break;
|
||||
case REQ:
|
||||
case RESP:
|
||||
break;
|
||||
}
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
static void
|
||||
fwctl_outw(uint16_t val)
|
||||
{
|
||||
switch (be_state) {
|
||||
case DORMANT:
|
||||
break;
|
||||
case IDENT_WAIT:
|
||||
if (val == 0) {
|
||||
be_state = IDENT_SEND;
|
||||
ident_idx = 0;
|
||||
}
|
||||
break;
|
||||
case IDENT_SEND:
|
||||
case REQ:
|
||||
case RESP:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
fwctl_inl(void)
|
||||
{
|
||||
uint32_t retval;
|
||||
|
||||
switch (be_state) {
|
||||
case DORMANT:
|
||||
case IDENT_WAIT:
|
||||
case IDENT_SEND:
|
||||
case REQ:
|
||||
retval = 0xffffffff;
|
||||
break;
|
||||
case RESP:
|
||||
if (fwctl_response(&retval))
|
||||
be_state = REQ;
|
||||
break;
|
||||
}
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
static void
|
||||
fwctl_outl(uint32_t val)
|
||||
{
|
||||
|
||||
switch (be_state) {
|
||||
case DORMANT:
|
||||
case IDENT_WAIT:
|
||||
case IDENT_SEND:
|
||||
break;
|
||||
case REQ:
|
||||
if (fwctl_request(val))
|
||||
be_state = RESP;
|
||||
case RESP:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
fwctl_handler(UNUSED int vcpu, int in, UNUSED int port, int bytes,
|
||||
uint32_t *eax, UNUSED void *arg)
|
||||
{
|
||||
|
||||
if (in) {
|
||||
if (bytes == 1)
|
||||
*eax = fwctl_inb();
|
||||
else if (bytes == 4)
|
||||
*eax = fwctl_inl();
|
||||
else
|
||||
*eax = 0xffff;
|
||||
} else {
|
||||
if (bytes == 2)
|
||||
fwctl_outw((uint16_t)*eax);
|
||||
else if (bytes == 4)
|
||||
fwctl_outl(*eax);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
INOUT_PORT(fwctl_wreg, FWCTL_OUT, IOPORT_F_INOUT, fwctl_handler);
|
||||
INOUT_PORT(fwctl_rreg, FWCTL_IN, IOPORT_F_IN, fwctl_handler);
|
||||
|
||||
void
|
||||
fwctl_init(void)
|
||||
{
|
||||
|
||||
ops[OP_GET_LEN] = &fgetlen_info;
|
||||
ops[OP_GET] = &fgetval_info;
|
||||
|
||||
be_state = IDENT_WAIT;
|
||||
}
|
13
src/cmd/linuxkit/vendor/github.com/moby/hyperkit/src/lib/pci_ahci.c
generated
vendored
13
src/cmd/linuxkit/vendor/github.com/moby/hyperkit/src/lib/pci_ahci.c
generated
vendored
@ -797,7 +797,15 @@ next:
|
||||
done += 8;
|
||||
if (elen == 0) {
|
||||
if (done >= len) {
|
||||
ahci_write_fis_d2h(p, slot, cfis, ATA_S_READY | ATA_S_DSC);
|
||||
if (ncq) {
|
||||
if (first)
|
||||
ahci_write_fis_d2h_ncq(p, slot);
|
||||
ahci_write_fis_sdb(p, slot, cfis,
|
||||
ATA_S_READY | ATA_S_DSC);
|
||||
} else {
|
||||
ahci_write_fis_d2h(p, slot, cfis,
|
||||
ATA_S_READY | ATA_S_DSC);
|
||||
}
|
||||
p->pending &= ~(1 << slot);
|
||||
ahci_check_stopped(p);
|
||||
if (!first)
|
||||
@ -977,6 +985,7 @@ handle_identify(struct ahci_port *p, int slot, uint8_t *cfis)
|
||||
buf[88] = 0x7f;
|
||||
if (p->xfermode & ATA_UDMA0)
|
||||
buf[88] |= (1 << ((p->xfermode & 7) + 8));
|
||||
buf[93] = (1 | 1 <<14);
|
||||
buf[100] = (uint16_t) sectors;
|
||||
buf[101] = (uint16_t) (sectors >> 16);
|
||||
buf[102] = (uint16_t) (sectors >> 32);
|
||||
@ -1725,7 +1734,7 @@ ahci_handle_cmd(struct ahci_port *p, int slot, uint8_t *cfis)
|
||||
case ATA_SEND_FPDMA_QUEUED:
|
||||
if ((cfis[13] & 0x1f) == ATA_SFPDMA_DSM &&
|
||||
cfis[17] == 0 && cfis[16] == ATA_DSM_TRIM &&
|
||||
cfis[11] == 0 && cfis[13] == 1) {
|
||||
cfis[11] == 0 && cfis[3] == 1) {
|
||||
ahci_handle_dsm_trim(p, slot, cfis, 0);
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user