Add two latest advisories:
Fix an integer overflow in computing the size of a temporary buffer can result in a buffer which is too small for the requested operation. [13:09] Fix a bug that could lead to kernel memory disclosure with SCTP state cookie. [13:10] Add latest errata notices: Fix a data corruption problem with mfi(4) operating on > 2TB disks in a JBOD. [EN-13:03]
This commit is contained in:
parent
09753ffb21
commit
b735a9d213
Notes:
svn2git
2020-12-08 03:00:23 +00:00
svn path=/head/; revision=42568
11 changed files with 1451 additions and 0 deletions
109
share/security/advisories/FreeBSD-EN-13:03.mfi.asc
Normal file
109
share/security/advisories/FreeBSD-EN-13:03.mfi.asc
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
-----BEGIN PGP SIGNED MESSAGE-----
|
||||||
|
Hash: SHA1
|
||||||
|
|
||||||
|
=============================================================================
|
||||||
|
FreeBSD-EN-13:03.mfi Errata Notice
|
||||||
|
The FreeBSD Project
|
||||||
|
|
||||||
|
Topic: data corruption with mfi(4) JBOD disks > 2TB
|
||||||
|
|
||||||
|
Category: contrib
|
||||||
|
Module: mfi
|
||||||
|
Announced: 2013-08-22
|
||||||
|
Credits: Steven Hartland, Doug Ambrisko
|
||||||
|
Affects: FreeBSD 9.1
|
||||||
|
Corrected: 2012-12-03 18:37:02 UTC (stable/9, 9.1-STABLE)
|
||||||
|
2013-08-22 00:51:48 UTC (releng/9.1, 9.1-RELEASE-p6)
|
||||||
|
|
||||||
|
For general information regarding FreeBSD Errata Notices and Security
|
||||||
|
Advisories, including descriptions of the fields above, security
|
||||||
|
branches, and the following sections, please visit
|
||||||
|
<URL:http://security.freebsd.org/>.
|
||||||
|
|
||||||
|
I. Background
|
||||||
|
|
||||||
|
The mfi(4) driver supports LSI's next generation PCI Express SAS RAID
|
||||||
|
controllers. The driver supports JBOD attachment through /dev/mfisyspd?
|
||||||
|
device nodes.
|
||||||
|
|
||||||
|
Logical block addressing (LBA) is a common scheme used for specifying the
|
||||||
|
location of sectors on hard drives.
|
||||||
|
|
||||||
|
II. Problem Description
|
||||||
|
|
||||||
|
The way mfi(4) implements access of "syspd" or also known as JBOD always
|
||||||
|
uses READ10/WRITE10 commands for underlying disk. When writing over 2^32
|
||||||
|
sectors, the LBA would wrap and starts writing at the beginning of the
|
||||||
|
disk.
|
||||||
|
|
||||||
|
III. Impact
|
||||||
|
|
||||||
|
Writing beyond 2TB to mfi(4) connected JBODs would result in data corruption.
|
||||||
|
|
||||||
|
IV. Workaround
|
||||||
|
|
||||||
|
No workaround is available, but systems that do not use mfi(4) as a JBOD
|
||||||
|
HBA or do not have disks with 2^32 or more sectors (2^41 or more bytes with
|
||||||
|
512-byte logical sector size) are not affected.
|
||||||
|
|
||||||
|
V. Solution
|
||||||
|
|
||||||
|
Perform one of the following:
|
||||||
|
|
||||||
|
1) Upgrade your system to a supported FreeBSD stable or release / security
|
||||||
|
branch (releng) dated after the correction date.
|
||||||
|
|
||||||
|
2) To update your present system via a source code patch:
|
||||||
|
|
||||||
|
The following patches have been verified to apply to the applicable
|
||||||
|
FreeBSD release branches.
|
||||||
|
|
||||||
|
a) Download the relevant patch from the location below, and verify the
|
||||||
|
detached PGP signature using your PGP utility.
|
||||||
|
|
||||||
|
# fetch http://security.FreeBSD.org/patches/EN-13:03/mfi.patch
|
||||||
|
# fetch http://security.FreeBSD.org/patches/EN-13:03/mfi.patch.asc
|
||||||
|
# gpg --verify mfi.patch.asc
|
||||||
|
|
||||||
|
b) Apply the patch.
|
||||||
|
|
||||||
|
# cd /usr/src
|
||||||
|
# patch < /path/to/patch
|
||||||
|
|
||||||
|
c) Recompile your kernel as described in
|
||||||
|
<URL:http://www.FreeBSD.org/handbook/kernelconfig.html> and reboot the
|
||||||
|
system.
|
||||||
|
|
||||||
|
3) To update your system via a binary patch:
|
||||||
|
|
||||||
|
Systems running a RELEASE version of FreeBSD on the i386 or amd64
|
||||||
|
platforms can be updated via the freebsd-update(8) utility:
|
||||||
|
|
||||||
|
# freebsd-update fetch
|
||||||
|
# freebsd-update install
|
||||||
|
|
||||||
|
VI. Correction details
|
||||||
|
|
||||||
|
The following list contains the revision numbers of each file that was
|
||||||
|
corrected in FreeBSD.
|
||||||
|
|
||||||
|
Branch/path Revision
|
||||||
|
- -------------------------------------------------------------------------
|
||||||
|
stable/9/ r243824
|
||||||
|
releng/9.1/ r254631
|
||||||
|
- -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
VII. References
|
||||||
|
|
||||||
|
http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/173291
|
||||||
|
|
||||||
|
The latest revision of this Errata Notice is available at
|
||||||
|
http://security.FreeBSD.org/advisories/FreeBSD-EN-13:03.mfi.asc
|
||||||
|
|
||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
Version: GnuPG v2.0.21 (FreeBSD)
|
||||||
|
|
||||||
|
iEYEARECAAYFAlIVY1YACgkQFdaIBMps37IHmwCfZH+1Gi0u7eYMXYevu0KHaG3a
|
||||||
|
rCwAn2ecdXnLOsaC6D6i2mo4dmI4HLDk
|
||||||
|
=AwdQ
|
||||||
|
-----END PGP SIGNATURE-----
|
121
share/security/advisories/FreeBSD-SA-13:09.ip_multicast.asc
Normal file
121
share/security/advisories/FreeBSD-SA-13:09.ip_multicast.asc
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
-----BEGIN PGP SIGNED MESSAGE-----
|
||||||
|
Hash: SHA1
|
||||||
|
|
||||||
|
FreeBSD-SA-13:09.ip_multicast Security Advisory
|
||||||
|
The FreeBSD Project
|
||||||
|
|
||||||
|
Topic: integer overflow in IP_MSFILTER
|
||||||
|
|
||||||
|
Category: core
|
||||||
|
Module: kernel
|
||||||
|
Announced: 2013-08-22
|
||||||
|
Credits: Clement Lecigne (Google Security Team)
|
||||||
|
Affects: All supported versions of FreeBSD.
|
||||||
|
Corrected: 2013-08-22 00:51:37 UTC (stable/9, 9.2-PRERELEASE)
|
||||||
|
2013-08-22 00:51:43 UTC (releng/9.2, 9.2-RC2-p1)
|
||||||
|
2013-08-22 00:51:48 UTC (releng/9.1, 9.1-RELEASE-p6)
|
||||||
|
2013-08-22 00:51:37 UTC (stable/8, 8.4-STABLE)
|
||||||
|
2013-08-22 00:51:56 UTC (releng/8.4, 8.4-RELEASE-p3)
|
||||||
|
2013-08-22 00:51:56 UTC (releng/8.3, 8.3-RELEASE-p10)
|
||||||
|
CVE Name: CVE-2013-3077
|
||||||
|
|
||||||
|
For general information regarding FreeBSD Security Advisories,
|
||||||
|
including descriptions of the fields above, security branches, and the
|
||||||
|
following sections, please visit <URL:http://security.FreeBSD.org/>.
|
||||||
|
|
||||||
|
I. Background
|
||||||
|
|
||||||
|
IP multicast is a method of sending Internet Protocol (IP) datagrams to a
|
||||||
|
group of interested receivers in a single transmission.
|
||||||
|
|
||||||
|
II. Problem Description
|
||||||
|
|
||||||
|
An integer overflow in computing the size of a temporary buffer can
|
||||||
|
result in a buffer which is too small for the requested operation.
|
||||||
|
|
||||||
|
III. Impact
|
||||||
|
|
||||||
|
An unprivileged process can read or write pages of memory which belong to
|
||||||
|
the kernel. These may lead to exposure of sensitive information or allow
|
||||||
|
privilege escalation.
|
||||||
|
|
||||||
|
IV. Workaround
|
||||||
|
|
||||||
|
No workaround is available.
|
||||||
|
|
||||||
|
V. Solution
|
||||||
|
|
||||||
|
Perform one of the following:
|
||||||
|
|
||||||
|
1) Upgrade your vulnerable system to a supported FreeBSD stable or
|
||||||
|
release / security branch (releng) dated after the correction date.
|
||||||
|
|
||||||
|
2) To update your vulnerable system via a source code patch:
|
||||||
|
|
||||||
|
The following patches have been verified to apply to the applicable
|
||||||
|
FreeBSD release branches.
|
||||||
|
|
||||||
|
a) Download the relevant patch from the location below, and verify the
|
||||||
|
detached PGP signature using your PGP utility.
|
||||||
|
|
||||||
|
# fetch http://security.FreeBSD.org/patches/SA-13:09/ip_multicast.patch
|
||||||
|
# fetch http://security.FreeBSD.org/patches/SA-13:09/ip_multicast.patch.asc
|
||||||
|
# gpg --verify ip_multicast.patch.asc
|
||||||
|
|
||||||
|
b) Apply the patch.
|
||||||
|
|
||||||
|
# cd /usr/src
|
||||||
|
# patch < /path/to/patch
|
||||||
|
|
||||||
|
c) Recompile your kernel as described in
|
||||||
|
<URL:http://www.FreeBSD.org/handbook/kernelconfig.html> and reboot the
|
||||||
|
system.
|
||||||
|
|
||||||
|
3) To update your vulnerable system via a binary patch:
|
||||||
|
|
||||||
|
Systems running a RELEASE version of FreeBSD on the i386 or amd64
|
||||||
|
platforms can be updated via the freebsd-update(8) utility:
|
||||||
|
|
||||||
|
# freebsd-update fetch
|
||||||
|
# freebsd-update install
|
||||||
|
|
||||||
|
VI. Correction details
|
||||||
|
|
||||||
|
The following list contains the correction revision numbers for each
|
||||||
|
affected branch.
|
||||||
|
|
||||||
|
Branch/path Revision
|
||||||
|
- -------------------------------------------------------------------------
|
||||||
|
stable/8/ r254629
|
||||||
|
releng/8.3/ r254632
|
||||||
|
releng/8.4/ r254632
|
||||||
|
stable/9/ r254629
|
||||||
|
releng/9.1/ r254631
|
||||||
|
releng/9.2/ r254630
|
||||||
|
- -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
To see which files were modified by a particular revision, run the
|
||||||
|
following command, replacing XXXXXX with the revision number, on a
|
||||||
|
machine with Subversion installed:
|
||||||
|
|
||||||
|
# svn diff -cXXXXXX --summarize svn://svn.freebsd.org/base
|
||||||
|
|
||||||
|
Or visit the following URL, replacing XXXXXX with the revision number:
|
||||||
|
|
||||||
|
<URL:http://svnweb.freebsd.org/base?view=revision&revision=XXXXXX>
|
||||||
|
|
||||||
|
VII. References
|
||||||
|
|
||||||
|
<other info on vulnerability>
|
||||||
|
|
||||||
|
<URL:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-3077>
|
||||||
|
|
||||||
|
The latest revision of this advisory is available at
|
||||||
|
<URL:http://security.FreeBSD.org/advisories/FreeBSD-SA-13:09.ip_multicast.asc>
|
||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
Version: GnuPG v2.0.21 (FreeBSD)
|
||||||
|
|
||||||
|
iEYEARECAAYFAlIVY1YACgkQFdaIBMps37K1cwCeOwXryun/C0EceD7v1se+z8w1
|
||||||
|
EUYAoJ7Hh/bOjyuD6oR6ZOEqtDVIL5LP
|
||||||
|
=6Ehk
|
||||||
|
-----END PGP SIGNATURE-----
|
133
share/security/advisories/FreeBSD-SA-13:10.sctp.asc
Normal file
133
share/security/advisories/FreeBSD-SA-13:10.sctp.asc
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
-----BEGIN PGP SIGNED MESSAGE-----
|
||||||
|
Hash: SHA1
|
||||||
|
|
||||||
|
=============================================================================
|
||||||
|
FreeBSD-SA-13:10.sctp Security Advisory
|
||||||
|
The FreeBSD Project
|
||||||
|
|
||||||
|
Topic: Kernel memory disclosure in sctp(4)
|
||||||
|
|
||||||
|
Category: core
|
||||||
|
Module: sctp
|
||||||
|
Announced: 2013-08-22
|
||||||
|
Credits: Julian Seward, Michael Tuexen
|
||||||
|
Affects: All supported versions of FreeBSD.
|
||||||
|
Corrected: 2013-08-15 04:25:16 UTC (stable/9, 9.2-PRERELEASE)
|
||||||
|
2013-08-15 05:14:20 UTC (releng/9.2, 9.2-RC2)
|
||||||
|
2013-08-22 00:51:48 UTC (releng/9.1, 9.1-RELEASE-p6)
|
||||||
|
2013-08-15 04:35:25 UTC (stable/8, 8.4-STABLE)
|
||||||
|
2013-08-22 00:51:56 UTC (releng/8.4, 8.4-RELEASE-p3)
|
||||||
|
2013-08-22 00:51:56 UTC (releng/8.3, 8.3-RELEASE-p10)
|
||||||
|
CVE Name: CVE-2013-5209
|
||||||
|
|
||||||
|
For general information regarding FreeBSD Security Advisories,
|
||||||
|
including descriptions of the fields above, security branches, and the
|
||||||
|
following sections, please visit <URL:http://security.FreeBSD.org/>.
|
||||||
|
|
||||||
|
I. Background
|
||||||
|
|
||||||
|
The SCTP protocol provides reliable, flow-controlled, two-way transmission
|
||||||
|
of data. It is a message oriented protocol and can support the SOCK_STREAM
|
||||||
|
and SOCK_SEQPACKET abstractions.
|
||||||
|
|
||||||
|
The SCTP protocol checks the integrity of messages by validating the state
|
||||||
|
cookie information that is returned from the peer.
|
||||||
|
|
||||||
|
II. Problem Description
|
||||||
|
|
||||||
|
When initializing the SCTP state cookie being sent in INIT-ACK chunks,
|
||||||
|
a buffer allocated from the kernel stack is not completely initialized.
|
||||||
|
|
||||||
|
III. Impact
|
||||||
|
|
||||||
|
Fragments of kernel memory may be included in SCTP packets and
|
||||||
|
transmitted over the network. For each SCTP session, there are two
|
||||||
|
separate instances in which a 4-byte fragment may be transmitted.
|
||||||
|
|
||||||
|
This memory might contain sensitive information, such as portions of the
|
||||||
|
file cache or terminal buffers. This information might be directly
|
||||||
|
useful, or it might be leveraged to obtain elevated privileges in
|
||||||
|
some way. For example, a terminal buffer might include an user-entered
|
||||||
|
password.
|
||||||
|
|
||||||
|
IV. Workaround
|
||||||
|
|
||||||
|
No workaround is available, but systems not using the SCTP protocol
|
||||||
|
are not vulnerable.
|
||||||
|
|
||||||
|
V. Solution
|
||||||
|
|
||||||
|
Perform one of the following:
|
||||||
|
|
||||||
|
1) Upgrade your vulnerable system to a supported FreeBSD stable or
|
||||||
|
release / security branch (releng) dated after the correction date.
|
||||||
|
|
||||||
|
2) To update your vulnerable system via a source code patch:
|
||||||
|
|
||||||
|
The following patches have been verified to apply to the applicable
|
||||||
|
FreeBSD release branches.
|
||||||
|
|
||||||
|
a) Download the relevant patch from the location below, and verify the
|
||||||
|
detached PGP signature using your PGP utility.
|
||||||
|
|
||||||
|
# fetch http://security.FreeBSD.org/patches/SA-13:10/sctp.patch
|
||||||
|
# fetch http://security.FreeBSD.org/patches/SA-13:10/sctp.patch.asc
|
||||||
|
# gpg --verify sctp.patch.asc
|
||||||
|
|
||||||
|
b) Apply the patch.
|
||||||
|
|
||||||
|
# cd /usr/src
|
||||||
|
# patch < /path/to/patch
|
||||||
|
|
||||||
|
c) Recompile your kernel as described in
|
||||||
|
<URL:http://www.FreeBSD.org/handbook/kernelconfig.html> and reboot the
|
||||||
|
system.
|
||||||
|
|
||||||
|
3) To update your vulnerable system via a binary patch:
|
||||||
|
|
||||||
|
Systems running a RELEASE version of FreeBSD on the i386 or amd64
|
||||||
|
platforms can be updated via the freebsd-update(8) utility:
|
||||||
|
|
||||||
|
# freebsd-update fetch
|
||||||
|
# freebsd-update install
|
||||||
|
|
||||||
|
VI. Correction details
|
||||||
|
|
||||||
|
The following list contains the correction revision numbers for each
|
||||||
|
affected branch.
|
||||||
|
|
||||||
|
Branch/path Revision
|
||||||
|
- -------------------------------------------------------------------------
|
||||||
|
stable/8/ r254354
|
||||||
|
releng/8.3/ r254632
|
||||||
|
releng/8.4/ r254632
|
||||||
|
stable/9/ r254352
|
||||||
|
releng/9.1/ r254631
|
||||||
|
releng/9.2/ r254355
|
||||||
|
- -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
To see which files were modified by a particular revision, run the
|
||||||
|
following command, replacing XXXXXX with the revision number, on a
|
||||||
|
machine with Subversion installed:
|
||||||
|
|
||||||
|
# svn diff -cXXXXXX --summarize svn://svn.freebsd.org/base
|
||||||
|
|
||||||
|
Or visit the following URL, replacing XXXXXX with the revision number:
|
||||||
|
|
||||||
|
<URL:http://svnweb.freebsd.org/base?view=revision&revision=XXXXXX>
|
||||||
|
|
||||||
|
VII. References
|
||||||
|
|
||||||
|
<other info on vulnerability>
|
||||||
|
|
||||||
|
<URL:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-5209>
|
||||||
|
|
||||||
|
The latest revision of this advisory is available at
|
||||||
|
<URL:http://security.FreeBSD.org/advisories/FreeBSD-SA-13:10.sctp.asc>
|
||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
Version: GnuPG v2.0.21 (FreeBSD)
|
||||||
|
|
||||||
|
iEYEARECAAYFAlIVY1YACgkQFdaIBMps37L0AQCgh30FZd+f+rmzMabRFkTPVEmX
|
||||||
|
tZgAnRuZptKgvlHkqnEhUj30tH6xLDCO
|
||||||
|
=KJ8k
|
||||||
|
-----END PGP SIGNATURE-----
|
994
share/security/patches/EN-13:03/mfi.patch
Normal file
994
share/security/patches/EN-13:03/mfi.patch
Normal file
|
@ -0,0 +1,994 @@
|
||||||
|
Index: sys/dev/mfi/mfi.c
|
||||||
|
===================================================================
|
||||||
|
--- sys/dev/mfi/mfi.c (revision 254079)
|
||||||
|
+++ sys/dev/mfi/mfi.c (working copy)
|
||||||
|
@@ -107,7 +107,7 @@ static void mfi_bio_complete(struct mfi_command *)
|
||||||
|
static struct mfi_command *mfi_build_ldio(struct mfi_softc *,struct bio*);
|
||||||
|
static struct mfi_command *mfi_build_syspdio(struct mfi_softc *,struct bio*);
|
||||||
|
static int mfi_send_frame(struct mfi_softc *, struct mfi_command *);
|
||||||
|
-static int mfi_abort(struct mfi_softc *, struct mfi_command *);
|
||||||
|
+static int mfi_abort(struct mfi_softc *, struct mfi_command **);
|
||||||
|
static int mfi_linux_ioctl_int(struct cdev *, u_long, caddr_t, int, struct thread *);
|
||||||
|
static void mfi_timeout(void *);
|
||||||
|
static int mfi_user_command(struct mfi_softc *,
|
||||||
|
@@ -373,6 +373,8 @@ mfi_attach(struct mfi_softc *sc)
|
||||||
|
sx_init(&sc->mfi_config_lock, "MFI config");
|
||||||
|
TAILQ_INIT(&sc->mfi_ld_tqh);
|
||||||
|
TAILQ_INIT(&sc->mfi_syspd_tqh);
|
||||||
|
+ TAILQ_INIT(&sc->mfi_ld_pend_tqh);
|
||||||
|
+ TAILQ_INIT(&sc->mfi_syspd_pend_tqh);
|
||||||
|
TAILQ_INIT(&sc->mfi_evt_queue);
|
||||||
|
TASK_INIT(&sc->mfi_evt_task, 0, mfi_handle_evt, sc);
|
||||||
|
TASK_INIT(&sc->mfi_map_sync_task, 0, mfi_handle_map_sync, sc);
|
||||||
|
@@ -694,6 +696,7 @@ mfi_attach(struct mfi_softc *sc)
|
||||||
|
device_printf(sc->mfi_dev, "Cannot set up interrupt\n");
|
||||||
|
return (EINVAL);
|
||||||
|
}
|
||||||
|
+ sc->mfi_intr_ptr = mfi_intr_tbolt;
|
||||||
|
sc->mfi_enable_intr(sc);
|
||||||
|
} else {
|
||||||
|
if ((error = mfi_comms_init(sc)) != 0)
|
||||||
|
@@ -704,6 +707,7 @@ mfi_attach(struct mfi_softc *sc)
|
||||||
|
device_printf(sc->mfi_dev, "Cannot set up interrupt\n");
|
||||||
|
return (EINVAL);
|
||||||
|
}
|
||||||
|
+ sc->mfi_intr_ptr = mfi_intr;
|
||||||
|
sc->mfi_enable_intr(sc);
|
||||||
|
}
|
||||||
|
if ((error = mfi_get_controller_info(sc)) != 0)
|
||||||
|
@@ -1278,6 +1282,17 @@ mfi_shutdown(struct mfi_softc *sc)
|
||||||
|
struct mfi_command *cm;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
+
|
||||||
|
+ if (sc->mfi_aen_cm)
|
||||||
|
+ sc->cm_aen_abort = 1;
|
||||||
|
+ if (sc->mfi_aen_cm != NULL)
|
||||||
|
+ mfi_abort(sc, &sc->mfi_aen_cm);
|
||||||
|
+
|
||||||
|
+ if (sc->mfi_map_sync_cm)
|
||||||
|
+ sc->cm_map_abort = 1;
|
||||||
|
+ if (sc->mfi_map_sync_cm != NULL)
|
||||||
|
+ mfi_abort(sc, &sc->mfi_map_sync_cm);
|
||||||
|
+
|
||||||
|
mtx_lock(&sc->mfi_io_lock);
|
||||||
|
error = mfi_dcmd_command(sc, &cm, MFI_DCMD_CTRL_SHUTDOWN, NULL, 0);
|
||||||
|
if (error) {
|
||||||
|
@@ -1285,12 +1300,6 @@ mfi_shutdown(struct mfi_softc *sc)
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (sc->mfi_aen_cm != NULL)
|
||||||
|
- mfi_abort(sc, sc->mfi_aen_cm);
|
||||||
|
-
|
||||||
|
- if (sc->mfi_map_sync_cm != NULL)
|
||||||
|
- mfi_abort(sc, sc->mfi_map_sync_cm);
|
||||||
|
-
|
||||||
|
dcmd = &cm->cm_frame->dcmd;
|
||||||
|
dcmd->header.flags = MFI_FRAME_DIR_NONE;
|
||||||
|
cm->cm_flags = MFI_CMD_POLLED;
|
||||||
|
@@ -1312,6 +1321,7 @@ mfi_syspdprobe(struct mfi_softc *sc)
|
||||||
|
struct mfi_command *cm = NULL;
|
||||||
|
struct mfi_pd_list *pdlist = NULL;
|
||||||
|
struct mfi_system_pd *syspd, *tmp;
|
||||||
|
+ struct mfi_system_pending *syspd_pend;
|
||||||
|
int error, i, found;
|
||||||
|
|
||||||
|
sx_assert(&sc->mfi_config_lock, SA_XLOCKED);
|
||||||
|
@@ -1352,6 +1362,10 @@ mfi_syspdprobe(struct mfi_softc *sc)
|
||||||
|
if (syspd->pd_id == pdlist->addr[i].device_id)
|
||||||
|
found = 1;
|
||||||
|
}
|
||||||
|
+ TAILQ_FOREACH(syspd_pend, &sc->mfi_syspd_pend_tqh, pd_link) {
|
||||||
|
+ if (syspd_pend->pd_id == pdlist->addr[i].device_id)
|
||||||
|
+ found = 1;
|
||||||
|
+ }
|
||||||
|
if (found == 0)
|
||||||
|
mfi_add_sys_pd(sc, pdlist->addr[i].device_id);
|
||||||
|
}
|
||||||
|
@@ -1387,6 +1401,7 @@ mfi_ldprobe(struct mfi_softc *sc)
|
||||||
|
struct mfi_command *cm = NULL;
|
||||||
|
struct mfi_ld_list *list = NULL;
|
||||||
|
struct mfi_disk *ld;
|
||||||
|
+ struct mfi_disk_pending *ld_pend;
|
||||||
|
int error, i;
|
||||||
|
|
||||||
|
sx_assert(&sc->mfi_config_lock, SA_XLOCKED);
|
||||||
|
@@ -1415,6 +1430,10 @@ mfi_ldprobe(struct mfi_softc *sc)
|
||||||
|
if (ld->ld_id == list->ld_list[i].ld.v.target_id)
|
||||||
|
goto skip_add;
|
||||||
|
}
|
||||||
|
+ TAILQ_FOREACH(ld_pend, &sc->mfi_ld_pend_tqh, ld_link) {
|
||||||
|
+ if (ld_pend->ld_id == list->ld_list[i].ld.v.target_id)
|
||||||
|
+ goto skip_add;
|
||||||
|
+ }
|
||||||
|
mfi_add_ld(sc, list->ld_list[i].ld.v.target_id);
|
||||||
|
skip_add:;
|
||||||
|
}
|
||||||
|
@@ -1617,9 +1636,7 @@ mfi_aen_register(struct mfi_softc *sc, int seq, in
|
||||||
|
< current_aen.members.evt_class)
|
||||||
|
current_aen.members.evt_class =
|
||||||
|
prior_aen.members.evt_class;
|
||||||
|
- mtx_lock(&sc->mfi_io_lock);
|
||||||
|
- mfi_abort(sc, sc->mfi_aen_cm);
|
||||||
|
- mtx_unlock(&sc->mfi_io_lock);
|
||||||
|
+ mfi_abort(sc, &sc->mfi_aen_cm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1811,10 +1828,17 @@ mfi_add_ld(struct mfi_softc *sc, int id)
|
||||||
|
struct mfi_command *cm;
|
||||||
|
struct mfi_dcmd_frame *dcmd = NULL;
|
||||||
|
struct mfi_ld_info *ld_info = NULL;
|
||||||
|
+ struct mfi_disk_pending *ld_pend;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
mtx_assert(&sc->mfi_io_lock, MA_OWNED);
|
||||||
|
|
||||||
|
+ ld_pend = malloc(sizeof(*ld_pend), M_MFIBUF, M_NOWAIT | M_ZERO);
|
||||||
|
+ if (ld_pend != NULL) {
|
||||||
|
+ ld_pend->ld_id = id;
|
||||||
|
+ TAILQ_INSERT_TAIL(&sc->mfi_ld_pend_tqh, ld_pend, ld_link);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
error = mfi_dcmd_command(sc, &cm, MFI_DCMD_LD_GET_INFO,
|
||||||
|
(void **)&ld_info, sizeof(*ld_info));
|
||||||
|
if (error) {
|
||||||
|
@@ -1855,11 +1879,13 @@ mfi_add_ld_complete(struct mfi_command *cm)
|
||||||
|
hdr = &cm->cm_frame->header;
|
||||||
|
ld_info = cm->cm_private;
|
||||||
|
|
||||||
|
- if (hdr->cmd_status != MFI_STAT_OK) {
|
||||||
|
+ if (sc->cm_map_abort || hdr->cmd_status != MFI_STAT_OK) {
|
||||||
|
free(ld_info, M_MFIBUF);
|
||||||
|
+ wakeup(&sc->mfi_map_sync_cm);
|
||||||
|
mfi_release_command(cm);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
+ wakeup(&sc->mfi_map_sync_cm);
|
||||||
|
mfi_release_command(cm);
|
||||||
|
|
||||||
|
mtx_unlock(&sc->mfi_io_lock);
|
||||||
|
@@ -1884,10 +1910,17 @@ static int mfi_add_sys_pd(struct mfi_softc *sc, in
|
||||||
|
struct mfi_command *cm;
|
||||||
|
struct mfi_dcmd_frame *dcmd = NULL;
|
||||||
|
struct mfi_pd_info *pd_info = NULL;
|
||||||
|
+ struct mfi_system_pending *syspd_pend;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
mtx_assert(&sc->mfi_io_lock, MA_OWNED);
|
||||||
|
|
||||||
|
+ syspd_pend = malloc(sizeof(*syspd_pend), M_MFIBUF, M_NOWAIT | M_ZERO);
|
||||||
|
+ if (syspd_pend != NULL) {
|
||||||
|
+ syspd_pend->pd_id = id;
|
||||||
|
+ TAILQ_INSERT_TAIL(&sc->mfi_syspd_pend_tqh, syspd_pend, pd_link);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
error = mfi_dcmd_command(sc, &cm, MFI_DCMD_PD_GET_INFO,
|
||||||
|
(void **)&pd_info, sizeof(*pd_info));
|
||||||
|
if (error) {
|
||||||
|
@@ -1981,19 +2014,87 @@ mfi_bio_command(struct mfi_softc *sc)
|
||||||
|
mfi_enqueue_bio(sc, bio);
|
||||||
|
return cm;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * mostly copied from cam/scsi/scsi_all.c:scsi_read_write
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+mfi_build_cdb(int readop, uint8_t byte2, u_int64_t lba, u_int32_t block_count, uint8_t *cdb)
|
||||||
|
+{
|
||||||
|
+ int cdb_len;
|
||||||
|
+
|
||||||
|
+ if (((lba & 0x1fffff) == lba)
|
||||||
|
+ && ((block_count & 0xff) == block_count)
|
||||||
|
+ && (byte2 == 0)) {
|
||||||
|
+ /* We can fit in a 6 byte cdb */
|
||||||
|
+ struct scsi_rw_6 *scsi_cmd;
|
||||||
|
+
|
||||||
|
+ scsi_cmd = (struct scsi_rw_6 *)cdb;
|
||||||
|
+ scsi_cmd->opcode = readop ? READ_6 : WRITE_6;
|
||||||
|
+ scsi_ulto3b(lba, scsi_cmd->addr);
|
||||||
|
+ scsi_cmd->length = block_count & 0xff;
|
||||||
|
+ scsi_cmd->control = 0;
|
||||||
|
+ cdb_len = sizeof(*scsi_cmd);
|
||||||
|
+ } else if (((block_count & 0xffff) == block_count) && ((lba & 0xffffffff) == lba)) {
|
||||||
|
+ /* Need a 10 byte CDB */
|
||||||
|
+ struct scsi_rw_10 *scsi_cmd;
|
||||||
|
+
|
||||||
|
+ scsi_cmd = (struct scsi_rw_10 *)cdb;
|
||||||
|
+ scsi_cmd->opcode = readop ? READ_10 : WRITE_10;
|
||||||
|
+ scsi_cmd->byte2 = byte2;
|
||||||
|
+ scsi_ulto4b(lba, scsi_cmd->addr);
|
||||||
|
+ scsi_cmd->reserved = 0;
|
||||||
|
+ scsi_ulto2b(block_count, scsi_cmd->length);
|
||||||
|
+ scsi_cmd->control = 0;
|
||||||
|
+ cdb_len = sizeof(*scsi_cmd);
|
||||||
|
+ } else if (((block_count & 0xffffffff) == block_count) &&
|
||||||
|
+ ((lba & 0xffffffff) == lba)) {
|
||||||
|
+ /* Block count is too big for 10 byte CDB use a 12 byte CDB */
|
||||||
|
+ struct scsi_rw_12 *scsi_cmd;
|
||||||
|
+
|
||||||
|
+ scsi_cmd = (struct scsi_rw_12 *)cdb;
|
||||||
|
+ scsi_cmd->opcode = readop ? READ_12 : WRITE_12;
|
||||||
|
+ scsi_cmd->byte2 = byte2;
|
||||||
|
+ scsi_ulto4b(lba, scsi_cmd->addr);
|
||||||
|
+ scsi_cmd->reserved = 0;
|
||||||
|
+ scsi_ulto4b(block_count, scsi_cmd->length);
|
||||||
|
+ scsi_cmd->control = 0;
|
||||||
|
+ cdb_len = sizeof(*scsi_cmd);
|
||||||
|
+ } else {
|
||||||
|
+ /*
|
||||||
|
+ * 16 byte CDB. We'll only get here if the LBA is larger
|
||||||
|
+ * than 2^32
|
||||||
|
+ */
|
||||||
|
+ struct scsi_rw_16 *scsi_cmd;
|
||||||
|
+
|
||||||
|
+ scsi_cmd = (struct scsi_rw_16 *)cdb;
|
||||||
|
+ scsi_cmd->opcode = readop ? READ_16 : WRITE_16;
|
||||||
|
+ scsi_cmd->byte2 = byte2;
|
||||||
|
+ scsi_u64to8b(lba, scsi_cmd->addr);
|
||||||
|
+ scsi_cmd->reserved = 0;
|
||||||
|
+ scsi_ulto4b(block_count, scsi_cmd->length);
|
||||||
|
+ scsi_cmd->control = 0;
|
||||||
|
+ cdb_len = sizeof(*scsi_cmd);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return cdb_len;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static struct mfi_command *
|
||||||
|
mfi_build_syspdio(struct mfi_softc *sc, struct bio *bio)
|
||||||
|
{
|
||||||
|
struct mfi_command *cm;
|
||||||
|
struct mfi_pass_frame *pass;
|
||||||
|
- int flags = 0, blkcount = 0;
|
||||||
|
uint32_t context = 0;
|
||||||
|
+ int flags = 0, blkcount = 0, readop;
|
||||||
|
+ uint8_t cdb_len;
|
||||||
|
|
||||||
|
if ((cm = mfi_dequeue_free(sc)) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
/* Zero out the MFI frame */
|
||||||
|
- context = cm->cm_frame->header.context;
|
||||||
|
+ context = cm->cm_frame->header.context;
|
||||||
|
bzero(cm->cm_frame, sizeof(union mfi_frame));
|
||||||
|
cm->cm_frame->header.context = context;
|
||||||
|
pass = &cm->cm_frame->pass;
|
||||||
|
@@ -2001,35 +2102,31 @@ mfi_build_syspdio(struct mfi_softc *sc, struct bio
|
||||||
|
pass->header.cmd = MFI_CMD_PD_SCSI_IO;
|
||||||
|
switch (bio->bio_cmd & 0x03) {
|
||||||
|
case BIO_READ:
|
||||||
|
-#define SCSI_READ 0x28
|
||||||
|
- pass->cdb[0] = SCSI_READ;
|
||||||
|
flags = MFI_CMD_DATAIN;
|
||||||
|
+ readop = 1;
|
||||||
|
break;
|
||||||
|
case BIO_WRITE:
|
||||||
|
-#define SCSI_WRITE 0x2a
|
||||||
|
- pass->cdb[0] = SCSI_WRITE;
|
||||||
|
flags = MFI_CMD_DATAOUT;
|
||||||
|
+ readop = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
- panic("Invalid bio command");
|
||||||
|
+ /* TODO: what about BIO_DELETE??? */
|
||||||
|
+ panic("Unsupported bio command %x\n", bio->bio_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cheat with the sector length to avoid a non-constant division */
|
||||||
|
blkcount = (bio->bio_bcount + MFI_SECTOR_LEN - 1) / MFI_SECTOR_LEN;
|
||||||
|
/* Fill the LBA and Transfer length in CDB */
|
||||||
|
- pass->cdb[2] = (bio->bio_pblkno & 0xff000000) >> 24;
|
||||||
|
- pass->cdb[3] = (bio->bio_pblkno & 0x00ff0000) >> 16;
|
||||||
|
- pass->cdb[4] = (bio->bio_pblkno & 0x0000ff00) >> 8;
|
||||||
|
- pass->cdb[5] = bio->bio_pblkno & 0x000000ff;
|
||||||
|
- pass->cdb[7] = (blkcount & 0xff00) >> 8;
|
||||||
|
- pass->cdb[8] = (blkcount & 0x00ff);
|
||||||
|
+ cdb_len = mfi_build_cdb(readop, 0, bio->bio_pblkno, blkcount,
|
||||||
|
+ pass->cdb);
|
||||||
|
pass->header.target_id = (uintptr_t)bio->bio_driver1;
|
||||||
|
+ pass->header.lun_id = 0;
|
||||||
|
pass->header.timeout = 0;
|
||||||
|
pass->header.flags = 0;
|
||||||
|
pass->header.scsi_status = 0;
|
||||||
|
pass->header.sense_len = MFI_SENSE_LEN;
|
||||||
|
pass->header.data_len = bio->bio_bcount;
|
||||||
|
- pass->header.cdb_len = 10;
|
||||||
|
+ pass->header.cdb_len = cdb_len;
|
||||||
|
pass->sense_addr_lo = (uint32_t)cm->cm_sense_busaddr;
|
||||||
|
pass->sense_addr_hi = (uint32_t)((uint64_t)cm->cm_sense_busaddr >> 32);
|
||||||
|
cm->cm_complete = mfi_bio_complete;
|
||||||
|
@@ -2047,7 +2144,8 @@ mfi_build_ldio(struct mfi_softc *sc, struct bio *b
|
||||||
|
{
|
||||||
|
struct mfi_io_frame *io;
|
||||||
|
struct mfi_command *cm;
|
||||||
|
- int flags, blkcount;
|
||||||
|
+ int flags;
|
||||||
|
+ uint32_t blkcount;
|
||||||
|
uint32_t context = 0;
|
||||||
|
|
||||||
|
if ((cm = mfi_dequeue_free(sc)) == NULL)
|
||||||
|
@@ -2068,7 +2166,8 @@ mfi_build_ldio(struct mfi_softc *sc, struct bio *b
|
||||||
|
flags = MFI_CMD_DATAOUT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
- panic("Invalid bio command");
|
||||||
|
+ /* TODO: what about BIO_DELETE??? */
|
||||||
|
+ panic("Unsupported bio command %x\n", bio->bio_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cheat with the sector length to avoid a non-constant division */
|
||||||
|
@@ -2358,7 +2457,7 @@ mfi_complete(struct mfi_softc *sc, struct mfi_comm
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
-mfi_abort(struct mfi_softc *sc, struct mfi_command *cm_abort)
|
||||||
|
+mfi_abort(struct mfi_softc *sc, struct mfi_command **cm_abort)
|
||||||
|
{
|
||||||
|
struct mfi_command *cm;
|
||||||
|
struct mfi_abort_frame *abort;
|
||||||
|
@@ -2365,8 +2464,7 @@ static int
|
||||||
|
int i = 0;
|
||||||
|
uint32_t context = 0;
|
||||||
|
|
||||||
|
- mtx_assert(&sc->mfi_io_lock, MA_OWNED);
|
||||||
|
-
|
||||||
|
+ mtx_lock(&sc->mfi_io_lock);
|
||||||
|
if ((cm = mfi_dequeue_free(sc)) == NULL) {
|
||||||
|
return (EBUSY);
|
||||||
|
}
|
||||||
|
@@ -2380,29 +2478,27 @@ static int
|
||||||
|
abort->header.cmd = MFI_CMD_ABORT;
|
||||||
|
abort->header.flags = 0;
|
||||||
|
abort->header.scsi_status = 0;
|
||||||
|
- abort->abort_context = cm_abort->cm_frame->header.context;
|
||||||
|
- abort->abort_mfi_addr_lo = (uint32_t)cm_abort->cm_frame_busaddr;
|
||||||
|
+ abort->abort_context = (*cm_abort)->cm_frame->header.context;
|
||||||
|
+ abort->abort_mfi_addr_lo = (uint32_t)(*cm_abort)->cm_frame_busaddr;
|
||||||
|
abort->abort_mfi_addr_hi =
|
||||||
|
- (uint32_t)((uint64_t)cm_abort->cm_frame_busaddr >> 32);
|
||||||
|
+ (uint32_t)((uint64_t)(*cm_abort)->cm_frame_busaddr >> 32);
|
||||||
|
cm->cm_data = NULL;
|
||||||
|
cm->cm_flags = MFI_CMD_POLLED;
|
||||||
|
|
||||||
|
- if (sc->mfi_aen_cm)
|
||||||
|
- sc->cm_aen_abort = 1;
|
||||||
|
- if (sc->mfi_map_sync_cm)
|
||||||
|
- sc->cm_map_abort = 1;
|
||||||
|
mfi_mapcmd(sc, cm);
|
||||||
|
mfi_release_command(cm);
|
||||||
|
|
||||||
|
- while (i < 5 && sc->mfi_aen_cm != NULL) {
|
||||||
|
- msleep(&sc->mfi_aen_cm, &sc->mfi_io_lock, 0, "mfiabort",
|
||||||
|
+ mtx_unlock(&sc->mfi_io_lock);
|
||||||
|
+ while (i < 5 && *cm_abort != NULL) {
|
||||||
|
+ tsleep(cm_abort, 0, "mfiabort",
|
||||||
|
5 * hz);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
- while (i < 5 && sc->mfi_map_sync_cm != NULL) {
|
||||||
|
- msleep(&sc->mfi_map_sync_cm, &sc->mfi_io_lock, 0, "mfiabort",
|
||||||
|
- 5 * hz);
|
||||||
|
- i++;
|
||||||
|
+ if (*cm_abort != NULL) {
|
||||||
|
+ /* Force a complete if command didn't abort */
|
||||||
|
+ mtx_lock(&sc->mfi_io_lock);
|
||||||
|
+ (*cm_abort)->cm_complete(*cm_abort);
|
||||||
|
+ mtx_unlock(&sc->mfi_io_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
@@ -2458,8 +2554,8 @@ mfi_dump_syspd_blocks(struct mfi_softc *sc, int id
|
||||||
|
{
|
||||||
|
struct mfi_command *cm;
|
||||||
|
struct mfi_pass_frame *pass;
|
||||||
|
- int error;
|
||||||
|
- int blkcount = 0;
|
||||||
|
+ int error, readop, cdb_len;
|
||||||
|
+ uint32_t blkcount;
|
||||||
|
|
||||||
|
if ((cm = mfi_dequeue_free(sc)) == NULL)
|
||||||
|
return (EBUSY);
|
||||||
|
@@ -2467,14 +2563,10 @@ mfi_dump_syspd_blocks(struct mfi_softc *sc, int id
|
||||||
|
pass = &cm->cm_frame->pass;
|
||||||
|
bzero(pass->cdb, 16);
|
||||||
|
pass->header.cmd = MFI_CMD_PD_SCSI_IO;
|
||||||
|
- pass->cdb[0] = SCSI_WRITE;
|
||||||
|
- pass->cdb[2] = (lba & 0xff000000) >> 24;
|
||||||
|
- pass->cdb[3] = (lba & 0x00ff0000) >> 16;
|
||||||
|
- pass->cdb[4] = (lba & 0x0000ff00) >> 8;
|
||||||
|
- pass->cdb[5] = (lba & 0x000000ff);
|
||||||
|
+
|
||||||
|
+ readop = 0;
|
||||||
|
blkcount = (len + MFI_SECTOR_LEN - 1) / MFI_SECTOR_LEN;
|
||||||
|
- pass->cdb[7] = (blkcount & 0xff00) >> 8;
|
||||||
|
- pass->cdb[8] = (blkcount & 0x00ff);
|
||||||
|
+ cdb_len = mfi_build_cdb(readop, 0, lba, blkcount, pass->cdb);
|
||||||
|
pass->header.target_id = id;
|
||||||
|
pass->header.timeout = 0;
|
||||||
|
pass->header.flags = 0;
|
||||||
|
@@ -2481,7 +2573,7 @@ mfi_dump_syspd_blocks(struct mfi_softc *sc, int id
|
||||||
|
pass->header.scsi_status = 0;
|
||||||
|
pass->header.sense_len = MFI_SENSE_LEN;
|
||||||
|
pass->header.data_len = len;
|
||||||
|
- pass->header.cdb_len = 10;
|
||||||
|
+ pass->header.cdb_len = cdb_len;
|
||||||
|
pass->sense_addr_lo = (uint32_t)cm->cm_sense_busaddr;
|
||||||
|
pass->sense_addr_hi = (uint32_t)((uint64_t)cm->cm_sense_busaddr >> 32);
|
||||||
|
cm->cm_data = virt;
|
||||||
|
@@ -2488,7 +2580,7 @@ mfi_dump_syspd_blocks(struct mfi_softc *sc, int id
|
||||||
|
cm->cm_len = len;
|
||||||
|
cm->cm_sg = &pass->sgl;
|
||||||
|
cm->cm_total_frame_size = MFI_PASS_FRAME_SIZE;
|
||||||
|
- cm->cm_flags = MFI_CMD_POLLED | MFI_CMD_DATAOUT;
|
||||||
|
+ cm->cm_flags = MFI_CMD_POLLED | MFI_CMD_DATAOUT | MFI_CMD_SCSI;
|
||||||
|
|
||||||
|
error = mfi_mapcmd(sc, cm);
|
||||||
|
bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap,
|
||||||
|
@@ -2687,16 +2779,24 @@ mfi_check_command_post(struct mfi_softc *sc, struc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int mfi_check_for_sscd(struct mfi_softc *sc, struct mfi_command *cm)
|
||||||
|
+static int
|
||||||
|
+mfi_check_for_sscd(struct mfi_softc *sc, struct mfi_command *cm)
|
||||||
|
{
|
||||||
|
- struct mfi_config_data *conf_data=(struct mfi_config_data *)cm->cm_data;
|
||||||
|
+ struct mfi_config_data *conf_data;
|
||||||
|
struct mfi_command *ld_cm = NULL;
|
||||||
|
struct mfi_ld_info *ld_info = NULL;
|
||||||
|
+ struct mfi_ld_config *ld;
|
||||||
|
+ char *p;
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
|
- if ((cm->cm_frame->dcmd.opcode == MFI_DCMD_CFG_ADD) &&
|
||||||
|
- (conf_data->ld[0].params.isSSCD == 1)) {
|
||||||
|
- error = 1;
|
||||||
|
+ conf_data = (struct mfi_config_data *)cm->cm_data;
|
||||||
|
+
|
||||||
|
+ if (cm->cm_frame->dcmd.opcode == MFI_DCMD_CFG_ADD) {
|
||||||
|
+ p = (char *)conf_data->array;
|
||||||
|
+ p += conf_data->array_size * conf_data->array_count;
|
||||||
|
+ ld = (struct mfi_ld_config *)p;
|
||||||
|
+ if (ld->params.isSSCD == 1)
|
||||||
|
+ error = 1;
|
||||||
|
} else if (cm->cm_frame->dcmd.opcode == MFI_DCMD_LD_DELETE) {
|
||||||
|
error = mfi_dcmd_command (sc, &ld_cm, MFI_DCMD_LD_GET_INFO,
|
||||||
|
(void **)&ld_info, sizeof(*ld_info));
|
||||||
|
Index: sys/dev/mfi/mfi_cam.c
|
||||||
|
===================================================================
|
||||||
|
--- sys/dev/mfi/mfi_cam.c (revision 254079)
|
||||||
|
+++ sys/dev/mfi/mfi_cam.c (working copy)
|
||||||
|
@@ -79,6 +79,11 @@ static void mfip_cam_poll(struct cam_sim *);
|
||||||
|
static struct mfi_command * mfip_start(void *);
|
||||||
|
static void mfip_done(struct mfi_command *cm);
|
||||||
|
|
||||||
|
+static int mfi_allow_disks = 0;
|
||||||
|
+TUNABLE_INT("hw.mfi.allow_cam_disk_passthrough", &mfi_allow_disks);
|
||||||
|
+SYSCTL_INT(_hw_mfi, OID_AUTO, allow_cam_disk_passthrough, CTLFLAG_RD,
|
||||||
|
+ &mfi_allow_disks, 0, "event message locale");
|
||||||
|
+
|
||||||
|
static devclass_t mfip_devclass;
|
||||||
|
static device_method_t mfip_methods[] = {
|
||||||
|
DEVMETHOD(device_probe, mfip_probe),
|
||||||
|
@@ -349,7 +354,8 @@ mfip_done(struct mfi_command *cm)
|
||||||
|
command = csio->cdb_io.cdb_bytes[0];
|
||||||
|
if (command == INQUIRY) {
|
||||||
|
device = csio->data_ptr[0] & 0x1f;
|
||||||
|
- if ((device == T_DIRECT) || (device == T_PROCESSOR))
|
||||||
|
+ if ((!mfi_allow_disks && device == T_DIRECT) ||
|
||||||
|
+ (device == T_PROCESSOR))
|
||||||
|
csio->data_ptr[0] =
|
||||||
|
(csio->data_ptr[0] & 0xe0) | T_NODEVICE;
|
||||||
|
}
|
||||||
|
@@ -392,6 +398,9 @@ mfip_done(struct mfi_command *cm)
|
||||||
|
static void
|
||||||
|
mfip_cam_poll(struct cam_sim *sim)
|
||||||
|
{
|
||||||
|
- return;
|
||||||
|
+ struct mfip_softc *sc = cam_sim_softc(sim);
|
||||||
|
+ struct mfi_softc *mfisc = sc->mfi_sc;
|
||||||
|
+
|
||||||
|
+ mfisc->mfi_intr_ptr(mfisc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Index: sys/dev/mfi/mfi_disk.c
|
||||||
|
===================================================================
|
||||||
|
--- sys/dev/mfi/mfi_disk.c (revision 254079)
|
||||||
|
+++ sys/dev/mfi/mfi_disk.c (working copy)
|
||||||
|
@@ -93,6 +93,7 @@ mfi_disk_attach(device_t dev)
|
||||||
|
{
|
||||||
|
struct mfi_disk *sc;
|
||||||
|
struct mfi_ld_info *ld_info;
|
||||||
|
+ struct mfi_disk_pending *ld_pend;
|
||||||
|
uint64_t sectors;
|
||||||
|
uint32_t secsize;
|
||||||
|
char *state;
|
||||||
|
@@ -111,6 +112,13 @@ mfi_disk_attach(device_t dev)
|
||||||
|
secsize = MFI_SECTOR_LEN;
|
||||||
|
mtx_lock(&sc->ld_controller->mfi_io_lock);
|
||||||
|
TAILQ_INSERT_TAIL(&sc->ld_controller->mfi_ld_tqh, sc, ld_link);
|
||||||
|
+ TAILQ_FOREACH(ld_pend, &sc->ld_controller->mfi_ld_pend_tqh,
|
||||||
|
+ ld_link) {
|
||||||
|
+ TAILQ_REMOVE(&sc->ld_controller->mfi_ld_pend_tqh,
|
||||||
|
+ ld_pend, ld_link);
|
||||||
|
+ free(ld_pend, M_MFIBUF);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
mtx_unlock(&sc->ld_controller->mfi_io_lock);
|
||||||
|
|
||||||
|
switch (ld_info->ld_config.params.state) {
|
||||||
|
@@ -131,16 +139,16 @@ mfi_disk_attach(device_t dev)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if ( strlen(ld_info->ld_config.properties.name) == 0 ) {
|
||||||
|
- device_printf(dev,
|
||||||
|
- "%juMB (%ju sectors) RAID volume (no label) is %s\n",
|
||||||
|
- sectors / (1024 * 1024 / secsize), sectors, state);
|
||||||
|
- } else {
|
||||||
|
- device_printf(dev,
|
||||||
|
- "%juMB (%ju sectors) RAID volume '%s' is %s\n",
|
||||||
|
- sectors / (1024 * 1024 / secsize), sectors,
|
||||||
|
- ld_info->ld_config.properties.name, state);
|
||||||
|
- }
|
||||||
|
+ if ( strlen(ld_info->ld_config.properties.name) == 0 ) {
|
||||||
|
+ device_printf(dev,
|
||||||
|
+ "%juMB (%ju sectors) RAID volume (no label) is %s\n",
|
||||||
|
+ sectors / (1024 * 1024 / secsize), sectors, state);
|
||||||
|
+ } else {
|
||||||
|
+ device_printf(dev,
|
||||||
|
+ "%juMB (%ju sectors) RAID volume '%s' is %s\n",
|
||||||
|
+ sectors / (1024 * 1024 / secsize), sectors,
|
||||||
|
+ ld_info->ld_config.properties.name, state);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
sc->ld_disk = disk_alloc();
|
||||||
|
sc->ld_disk->d_drv1 = sc;
|
||||||
|
Index: sys/dev/mfi/mfi_syspd.c
|
||||||
|
===================================================================
|
||||||
|
--- sys/dev/mfi/mfi_syspd.c (revision 254079)
|
||||||
|
+++ sys/dev/mfi/mfi_syspd.c (working copy)
|
||||||
|
@@ -89,7 +89,6 @@ DRIVER_MODULE(mfisyspd, mfi, mfi_syspd_driver, mfi
|
||||||
|
static int
|
||||||
|
mfi_syspd_probe(device_t dev)
|
||||||
|
{
|
||||||
|
-
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -98,12 +97,12 @@ mfi_syspd_attach(device_t dev)
|
||||||
|
{
|
||||||
|
struct mfi_system_pd *sc;
|
||||||
|
struct mfi_pd_info *pd_info;
|
||||||
|
+ struct mfi_system_pending *syspd_pend;
|
||||||
|
uint64_t sectors;
|
||||||
|
uint32_t secsize;
|
||||||
|
|
||||||
|
sc = device_get_softc(dev);
|
||||||
|
pd_info = device_get_ivars(dev);
|
||||||
|
-
|
||||||
|
sc->pd_dev = dev;
|
||||||
|
sc->pd_id = pd_info->ref.v.device_id;
|
||||||
|
sc->pd_unit = device_get_unit(dev);
|
||||||
|
@@ -115,6 +114,13 @@ mfi_syspd_attach(device_t dev)
|
||||||
|
secsize = MFI_SECTOR_LEN;
|
||||||
|
mtx_lock(&sc->pd_controller->mfi_io_lock);
|
||||||
|
TAILQ_INSERT_TAIL(&sc->pd_controller->mfi_syspd_tqh, sc, pd_link);
|
||||||
|
+ TAILQ_FOREACH(syspd_pend, &sc->pd_controller->mfi_syspd_pend_tqh,
|
||||||
|
+ pd_link) {
|
||||||
|
+ TAILQ_REMOVE(&sc->pd_controller->mfi_syspd_pend_tqh,
|
||||||
|
+ syspd_pend, pd_link);
|
||||||
|
+ free(syspd_pend, M_MFIBUF);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
mtx_unlock(&sc->pd_controller->mfi_io_lock);
|
||||||
|
device_printf(dev, "%juMB (%ju sectors) SYSPD volume\n",
|
||||||
|
sectors / (1024 * 1024 / secsize), sectors);
|
||||||
|
@@ -139,6 +145,7 @@ mfi_syspd_attach(device_t dev)
|
||||||
|
disk_create(sc->pd_disk, DISK_VERSION);
|
||||||
|
|
||||||
|
device_printf(dev, " SYSPD volume attached\n");
|
||||||
|
+
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Index: sys/dev/mfi/mfi_tbolt.c
|
||||||
|
===================================================================
|
||||||
|
--- sys/dev/mfi/mfi_tbolt.c (revision 254079)
|
||||||
|
+++ sys/dev/mfi/mfi_tbolt.c (working copy)
|
||||||
|
@@ -69,13 +69,10 @@ uint8_t
|
||||||
|
mfi_build_mpt_pass_thru(struct mfi_softc *sc, struct mfi_command *mfi_cmd);
|
||||||
|
union mfi_mpi2_request_descriptor *mfi_build_and_issue_cmd(struct mfi_softc
|
||||||
|
*sc, struct mfi_command *mfi_cmd);
|
||||||
|
-int mfi_tbolt_is_ldio(struct mfi_command *mfi_cmd);
|
||||||
|
void mfi_tbolt_build_ldio(struct mfi_softc *sc, struct mfi_command *mfi_cmd,
|
||||||
|
struct mfi_cmd_tbolt *cmd);
|
||||||
|
static int mfi_tbolt_make_sgl(struct mfi_softc *sc, struct mfi_command
|
||||||
|
*mfi_cmd, pMpi25IeeeSgeChain64_t sgl_ptr, struct mfi_cmd_tbolt *cmd);
|
||||||
|
-static int mfi_tbolt_build_cdb(struct mfi_softc *sc, struct mfi_command
|
||||||
|
- *mfi_cmd, uint8_t *cdb);
|
||||||
|
void
|
||||||
|
map_tbolt_cmd_status(struct mfi_command *mfi_cmd, uint8_t status,
|
||||||
|
uint8_t ext_status);
|
||||||
|
@@ -502,6 +499,7 @@ mfi_tbolt_alloc_cmd(struct mfi_softc *sc)
|
||||||
|
+ i * MEGASAS_MAX_SZ_CHAIN_FRAME);
|
||||||
|
cmd->sg_frame_phys_addr = sc->sg_frame_busaddr + i
|
||||||
|
* MEGASAS_MAX_SZ_CHAIN_FRAME;
|
||||||
|
+ cmd->sync_cmd_idx = sc->mfi_max_fw_cmds;
|
||||||
|
|
||||||
|
TAILQ_INSERT_TAIL(&(sc->mfi_cmd_tbolt_tqh), cmd, next);
|
||||||
|
}
|
||||||
|
@@ -574,11 +572,11 @@ void
|
||||||
|
map_tbolt_cmd_status(struct mfi_command *mfi_cmd, uint8_t status,
|
||||||
|
uint8_t ext_status)
|
||||||
|
{
|
||||||
|
-
|
||||||
|
switch (status) {
|
||||||
|
case MFI_STAT_OK:
|
||||||
|
- mfi_cmd->cm_frame->header.cmd_status = 0;
|
||||||
|
- mfi_cmd->cm_frame->dcmd.header.cmd_status = 0;
|
||||||
|
+ mfi_cmd->cm_frame->header.cmd_status = MFI_STAT_OK;
|
||||||
|
+ mfi_cmd->cm_frame->dcmd.header.cmd_status = MFI_STAT_OK;
|
||||||
|
+ mfi_cmd->cm_error = MFI_STAT_OK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MFI_STAT_SCSI_IO_FAILED:
|
||||||
|
@@ -618,6 +616,7 @@ mfi_tbolt_return_cmd(struct mfi_softc *sc, struct
|
||||||
|
{
|
||||||
|
mtx_assert(&sc->mfi_io_lock, MA_OWNED);
|
||||||
|
|
||||||
|
+ cmd->sync_cmd_idx = sc->mfi_max_fw_cmds;
|
||||||
|
TAILQ_INSERT_TAIL(&sc->mfi_cmd_tbolt_tqh, cmd, next);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -667,16 +666,26 @@ mfi_tbolt_complete_cmd(struct mfi_softc *sc)
|
||||||
|
extStatus = cmd_mfi->cm_frame->dcmd.header.scsi_status;
|
||||||
|
map_tbolt_cmd_status(cmd_mfi, status, extStatus);
|
||||||
|
|
||||||
|
- /* remove command from busy queue if not polled */
|
||||||
|
- TAILQ_FOREACH(cmd_mfi_check, &sc->mfi_busy, cm_link) {
|
||||||
|
- if (cmd_mfi_check == cmd_mfi) {
|
||||||
|
- mfi_remove_busy(cmd_mfi);
|
||||||
|
- break;
|
||||||
|
+ if (cmd_mfi->cm_flags & MFI_CMD_SCSI &&
|
||||||
|
+ (cmd_mfi->cm_flags & MFI_CMD_POLLED) != 0) {
|
||||||
|
+ /* polled LD/SYSPD IO command */
|
||||||
|
+ mfi_tbolt_return_cmd(sc, cmd_tbolt);
|
||||||
|
+ /* XXX mark okay for now DJA */
|
||||||
|
+ cmd_mfi->cm_frame->header.cmd_status = MFI_STAT_OK;
|
||||||
|
+ } else {
|
||||||
|
+
|
||||||
|
+ /* remove command from busy queue if not polled */
|
||||||
|
+ TAILQ_FOREACH(cmd_mfi_check, &sc->mfi_busy, cm_link) {
|
||||||
|
+ if (cmd_mfi_check == cmd_mfi) {
|
||||||
|
+ mfi_remove_busy(cmd_mfi);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ /* complete the command */
|
||||||
|
+ mfi_complete(sc, cmd_mfi);
|
||||||
|
+ mfi_tbolt_return_cmd(sc, cmd_tbolt);
|
||||||
|
}
|
||||||
|
- cmd_mfi->cm_error = 0;
|
||||||
|
- mfi_complete(sc, cmd_mfi);
|
||||||
|
- mfi_tbolt_return_cmd(sc, cmd_tbolt);
|
||||||
|
|
||||||
|
sc->last_reply_idx++;
|
||||||
|
if (sc->last_reply_idx >= sc->mfi_max_fw_cmds) {
|
||||||
|
@@ -811,13 +820,13 @@ mfi_tbolt_build_ldio(struct mfi_softc *sc, struct
|
||||||
|
MFI_FRAME_DIR_READ)
|
||||||
|
io_info.isRead = 1;
|
||||||
|
|
||||||
|
- io_request->RaidContext.timeoutValue
|
||||||
|
- = MFI_FUSION_FP_DEFAULT_TIMEOUT;
|
||||||
|
- io_request->Function = MPI2_FUNCTION_LD_IO_REQUEST;
|
||||||
|
- io_request->DevHandle = device_id;
|
||||||
|
- cmd->request_desc->header.RequestFlags
|
||||||
|
- = (MFI_REQ_DESCRIPT_FLAGS_LD_IO
|
||||||
|
- << MFI_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
|
||||||
|
+ io_request->RaidContext.timeoutValue
|
||||||
|
+ = MFI_FUSION_FP_DEFAULT_TIMEOUT;
|
||||||
|
+ io_request->Function = MPI2_FUNCTION_LD_IO_REQUEST;
|
||||||
|
+ io_request->DevHandle = device_id;
|
||||||
|
+ cmd->request_desc->header.RequestFlags
|
||||||
|
+ = (MFI_REQ_DESCRIPT_FLAGS_LD_IO
|
||||||
|
+ << MFI_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
|
||||||
|
if ((io_request->IoFlags == 6) && (io_info.numBlocks == 0))
|
||||||
|
io_request->RaidContext.RegLockLength = 0x100;
|
||||||
|
io_request->DataLength = mfi_cmd->cm_frame->io.header.data_len
|
||||||
|
@@ -825,41 +834,37 @@ mfi_tbolt_build_ldio(struct mfi_softc *sc, struct
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
-mfi_tbolt_is_ldio(struct mfi_command *mfi_cmd)
|
||||||
|
-{
|
||||||
|
- if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_READ
|
||||||
|
- || mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE)
|
||||||
|
- return 1;
|
||||||
|
- else
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-int
|
||||||
|
mfi_tbolt_build_io(struct mfi_softc *sc, struct mfi_command *mfi_cmd,
|
||||||
|
struct mfi_cmd_tbolt *cmd)
|
||||||
|
{
|
||||||
|
- uint32_t device_id;
|
||||||
|
+ struct mfi_mpi2_request_raid_scsi_io *io_request;
|
||||||
|
uint32_t sge_count;
|
||||||
|
- uint8_t cdb[32], cdb_len;
|
||||||
|
+ uint8_t cdb_len;
|
||||||
|
+ int readop;
|
||||||
|
+ u_int64_t lba;
|
||||||
|
|
||||||
|
- memset(cdb, 0, 32);
|
||||||
|
- struct mfi_mpi2_request_raid_scsi_io *io_request = cmd->io_request;
|
||||||
|
+ io_request = cmd->io_request;
|
||||||
|
+ if (!(mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_READ
|
||||||
|
+ || mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE))
|
||||||
|
+ return 1;
|
||||||
|
|
||||||
|
- device_id = mfi_cmd->cm_frame->header.target_id;
|
||||||
|
+ mfi_tbolt_build_ldio(sc, mfi_cmd, cmd);
|
||||||
|
|
||||||
|
- /* Have to build CDB here for TB as BSD don't have a scsi layer */
|
||||||
|
- if ((cdb_len = mfi_tbolt_build_cdb(sc, mfi_cmd, cdb)) == 1)
|
||||||
|
- return 1;
|
||||||
|
+ /* Convert to SCSI command CDB */
|
||||||
|
+ bzero(io_request->CDB.CDB32, sizeof(io_request->CDB.CDB32));
|
||||||
|
+ if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE)
|
||||||
|
+ readop = 0;
|
||||||
|
+ else
|
||||||
|
+ readop = 1;
|
||||||
|
|
||||||
|
- /* Just the CDB length,rest of the Flags are zero */
|
||||||
|
+ lba = mfi_cmd->cm_frame->io.lba_hi;
|
||||||
|
+ lba = (lba << 32) + mfi_cmd->cm_frame->io.lba_lo;
|
||||||
|
+ cdb_len = mfi_build_cdb(readop, 0, lba,
|
||||||
|
+ mfi_cmd->cm_frame->io.header.data_len, io_request->CDB.CDB32);
|
||||||
|
+
|
||||||
|
+ /* Just the CDB length, rest of the Flags are zero */
|
||||||
|
io_request->IoFlags = cdb_len;
|
||||||
|
- memcpy(io_request->CDB.CDB32, cdb, 32);
|
||||||
|
|
||||||
|
- if (mfi_tbolt_is_ldio(mfi_cmd))
|
||||||
|
- mfi_tbolt_build_ldio(sc, mfi_cmd , cmd);
|
||||||
|
- else
|
||||||
|
- return 1;
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* Construct SGL
|
||||||
|
*/
|
||||||
|
@@ -883,85 +888,13 @@ mfi_tbolt_build_io(struct mfi_softc *sc, struct mf
|
||||||
|
|
||||||
|
io_request->SenseBufferLowAddress = mfi_cmd->cm_sense_busaddr;
|
||||||
|
io_request->SenseBufferLength = MFI_SENSE_LEN;
|
||||||
|
+ io_request->RaidContext.Status = MFI_STAT_INVALID_STATUS;
|
||||||
|
+ io_request->RaidContext.exStatus = MFI_STAT_INVALID_STATUS;
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int
|
||||||
|
-mfi_tbolt_build_cdb(struct mfi_softc *sc, struct mfi_command *mfi_cmd,
|
||||||
|
- uint8_t *cdb)
|
||||||
|
-{
|
||||||
|
- uint32_t lba_lo, lba_hi, num_lba;
|
||||||
|
- uint8_t cdb_len;
|
||||||
|
|
||||||
|
- if (mfi_cmd == NULL || cdb == NULL)
|
||||||
|
- return 1;
|
||||||
|
- num_lba = mfi_cmd->cm_frame->io.header.data_len;
|
||||||
|
- lba_lo = mfi_cmd->cm_frame->io.lba_lo;
|
||||||
|
- lba_hi = mfi_cmd->cm_frame->io.lba_hi;
|
||||||
|
-
|
||||||
|
- if (lba_hi == 0 && (num_lba <= 0xFF) && (lba_lo <= 0x1FFFFF)) {
|
||||||
|
- if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE)
|
||||||
|
- /* Read 6 or Write 6 */
|
||||||
|
- cdb[0] = (uint8_t) (0x0A);
|
||||||
|
- else
|
||||||
|
- cdb[0] = (uint8_t) (0x08);
|
||||||
|
-
|
||||||
|
- cdb[4] = (uint8_t) num_lba;
|
||||||
|
- cdb[3] = (uint8_t) (lba_lo & 0xFF);
|
||||||
|
- cdb[2] = (uint8_t) (lba_lo >> 8);
|
||||||
|
- cdb[1] = (uint8_t) ((lba_lo >> 16) & 0x1F);
|
||||||
|
- cdb_len = 6;
|
||||||
|
- }
|
||||||
|
- else if (lba_hi == 0 && (num_lba <= 0xFFFF) && (lba_lo <= 0xFFFFFFFF)) {
|
||||||
|
- if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE)
|
||||||
|
- /* Read 10 or Write 10 */
|
||||||
|
- cdb[0] = (uint8_t) (0x2A);
|
||||||
|
- else
|
||||||
|
- cdb[0] = (uint8_t) (0x28);
|
||||||
|
- cdb[8] = (uint8_t) (num_lba & 0xFF);
|
||||||
|
- cdb[7] = (uint8_t) (num_lba >> 8);
|
||||||
|
- cdb[5] = (uint8_t) (lba_lo & 0xFF);
|
||||||
|
- cdb[4] = (uint8_t) (lba_lo >> 8);
|
||||||
|
- cdb[3] = (uint8_t) (lba_lo >> 16);
|
||||||
|
- cdb[2] = (uint8_t) (lba_lo >> 24);
|
||||||
|
- cdb_len = 10;
|
||||||
|
- } else if ((num_lba > 0xFFFF) && (lba_hi == 0)) {
|
||||||
|
- if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE)
|
||||||
|
- /* Read 12 or Write 12 */
|
||||||
|
- cdb[0] = (uint8_t) (0xAA);
|
||||||
|
- else
|
||||||
|
- cdb[0] = (uint8_t) (0xA8);
|
||||||
|
- cdb[9] = (uint8_t) (num_lba & 0xFF);
|
||||||
|
- cdb[8] = (uint8_t) (num_lba >> 8);
|
||||||
|
- cdb[7] = (uint8_t) (num_lba >> 16);
|
||||||
|
- cdb[6] = (uint8_t) (num_lba >> 24);
|
||||||
|
- cdb[5] = (uint8_t) (lba_lo & 0xFF);
|
||||||
|
- cdb[4] = (uint8_t) (lba_lo >> 8);
|
||||||
|
- cdb[3] = (uint8_t) (lba_lo >> 16);
|
||||||
|
- cdb[2] = (uint8_t) (lba_lo >> 24);
|
||||||
|
- cdb_len = 12;
|
||||||
|
- } else {
|
||||||
|
- if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE)
|
||||||
|
- cdb[0] = (uint8_t) (0x8A);
|
||||||
|
- else
|
||||||
|
- cdb[0] = (uint8_t) (0x88);
|
||||||
|
- cdb[13] = (uint8_t) (num_lba & 0xFF);
|
||||||
|
- cdb[12] = (uint8_t) (num_lba >> 8);
|
||||||
|
- cdb[11] = (uint8_t) (num_lba >> 16);
|
||||||
|
- cdb[10] = (uint8_t) (num_lba >> 24);
|
||||||
|
- cdb[9] = (uint8_t) (lba_lo & 0xFF);
|
||||||
|
- cdb[8] = (uint8_t) (lba_lo >> 8);
|
||||||
|
- cdb[7] = (uint8_t) (lba_lo >> 16);
|
||||||
|
- cdb[6] = (uint8_t) (lba_lo >> 24);
|
||||||
|
- cdb[5] = (uint8_t) (lba_hi & 0xFF);
|
||||||
|
- cdb[4] = (uint8_t) (lba_hi >> 8);
|
||||||
|
- cdb[3] = (uint8_t) (lba_hi >> 16);
|
||||||
|
- cdb[2] = (uint8_t) (lba_hi >> 24);
|
||||||
|
- cdb_len = 16;
|
||||||
|
- }
|
||||||
|
- return cdb_len;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static int
|
||||||
|
mfi_tbolt_make_sgl(struct mfi_softc *sc, struct mfi_command *mfi_cmd,
|
||||||
|
pMpi25IeeeSgeChain64_t sgl_ptr, struct mfi_cmd_tbolt *cmd)
|
||||||
|
@@ -1100,8 +1033,7 @@ mfi_tbolt_send_frame(struct mfi_softc *sc, struct
|
||||||
|
if ((cm->cm_flags & MFI_CMD_POLLED) == 0) {
|
||||||
|
cm->cm_timestamp = time_uptime;
|
||||||
|
mfi_enqueue_busy(cm);
|
||||||
|
- }
|
||||||
|
- else { /* still get interrupts for it */
|
||||||
|
+ } else { /* still get interrupts for it */
|
||||||
|
hdr->cmd_status = MFI_STAT_INVALID_STATUS;
|
||||||
|
hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
|
||||||
|
}
|
||||||
|
@@ -1118,19 +1050,28 @@ mfi_tbolt_send_frame(struct mfi_softc *sc, struct
|
||||||
|
}
|
||||||
|
else
|
||||||
|
device_printf(sc->mfi_dev, "DJA NA XXX SYSPDIO\n");
|
||||||
|
- }
|
||||||
|
- else if (hdr->cmd == MFI_CMD_LD_SCSI_IO ||
|
||||||
|
+ } else if (hdr->cmd == MFI_CMD_LD_SCSI_IO ||
|
||||||
|
hdr->cmd == MFI_CMD_LD_READ || hdr->cmd == MFI_CMD_LD_WRITE) {
|
||||||
|
+ cm->cm_flags |= MFI_CMD_SCSI;
|
||||||
|
if ((req_desc = mfi_build_and_issue_cmd(sc, cm)) == NULL) {
|
||||||
|
device_printf(sc->mfi_dev, "LDIO Failed \n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
- } else
|
||||||
|
- if ((req_desc = mfi_tbolt_build_mpt_cmd(sc, cm)) == NULL) {
|
||||||
|
+ } else if ((req_desc = mfi_tbolt_build_mpt_cmd(sc, cm)) == NULL) {
|
||||||
|
device_printf(sc->mfi_dev, "Mapping from MFI to MPT "
|
||||||
|
"Failed\n");
|
||||||
|
return 1;
|
||||||
|
- }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (cm->cm_flags & MFI_CMD_SCSI) {
|
||||||
|
+ /*
|
||||||
|
+ * LD IO needs to be posted since it doesn't get
|
||||||
|
+ * acknowledged via a status update so have the
|
||||||
|
+ * controller reply via mfi_tbolt_complete_cmd.
|
||||||
|
+ */
|
||||||
|
+ hdr->flags &= ~MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
MFI_WRITE4(sc, MFI_ILQP, (req_desc->words & 0xFFFFFFFF));
|
||||||
|
MFI_WRITE4(sc, MFI_IHQP, (req_desc->words >>0x20));
|
||||||
|
|
||||||
|
@@ -1137,12 +1078,21 @@ mfi_tbolt_send_frame(struct mfi_softc *sc, struct
|
||||||
|
if ((cm->cm_flags & MFI_CMD_POLLED) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
+ if (cm->cm_flags & MFI_CMD_SCSI) {
|
||||||
|
+ /* check reply queue */
|
||||||
|
+ mfi_tbolt_complete_cmd(sc);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* This is a polled command, so busy-wait for it to complete. */
|
||||||
|
while (hdr->cmd_status == MFI_STAT_INVALID_STATUS) {
|
||||||
|
DELAY(1000);
|
||||||
|
tm -= 1;
|
||||||
|
if (tm <= 0)
|
||||||
|
- break;
|
||||||
|
+ break;
|
||||||
|
+ if (cm->cm_flags & MFI_CMD_SCSI) {
|
||||||
|
+ /* check reply queue */
|
||||||
|
+ mfi_tbolt_complete_cmd(sc);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hdr->cmd_status == MFI_STAT_INVALID_STATUS) {
|
||||||
|
@@ -1375,7 +1325,7 @@ mfi_tbolt_sync_map_info(struct mfi_softc *sc)
|
||||||
|
free(ld_sync, M_MFIBUF);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
+
|
||||||
|
context = cmd->cm_frame->header.context;
|
||||||
|
bzero(cmd->cm_frame, sizeof(union mfi_frame));
|
||||||
|
cmd->cm_frame->header.context = context;
|
||||||
|
Index: sys/dev/mfi/mfivar.h
|
||||||
|
===================================================================
|
||||||
|
--- sys/dev/mfi/mfivar.h (revision 254079)
|
||||||
|
+++ sys/dev/mfi/mfivar.h (working copy)
|
||||||
|
@@ -105,6 +105,7 @@ struct mfi_command {
|
||||||
|
#define MFI_ON_MFIQ_READY (1<<6)
|
||||||
|
#define MFI_ON_MFIQ_BUSY (1<<7)
|
||||||
|
#define MFI_ON_MFIQ_MASK ((1<<5)|(1<<6)|(1<<7))
|
||||||
|
+#define MFI_CMD_SCSI (1<<8)
|
||||||
|
uint8_t retry_for_fw_reset;
|
||||||
|
void (* cm_complete)(struct mfi_command *cm);
|
||||||
|
void *cm_private;
|
||||||
|
@@ -125,6 +126,11 @@ struct mfi_disk {
|
||||||
|
#define MFI_DISK_FLAGS_DISABLED 0x02
|
||||||
|
};
|
||||||
|
|
||||||
|
+struct mfi_disk_pending {
|
||||||
|
+ TAILQ_ENTRY(mfi_disk_pending) ld_link;
|
||||||
|
+ int ld_id;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
struct mfi_system_pd {
|
||||||
|
TAILQ_ENTRY(mfi_system_pd) pd_link;
|
||||||
|
device_t pd_dev;
|
||||||
|
@@ -136,6 +142,11 @@ struct mfi_system_pd {
|
||||||
|
int pd_flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
+struct mfi_system_pending {
|
||||||
|
+ TAILQ_ENTRY(mfi_system_pending) pd_link;
|
||||||
|
+ int pd_id;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
struct mfi_evt_queue_elm {
|
||||||
|
TAILQ_ENTRY(mfi_evt_queue_elm) link;
|
||||||
|
struct mfi_evt_detail detail;
|
||||||
|
@@ -284,6 +295,8 @@ struct mfi_softc {
|
||||||
|
|
||||||
|
TAILQ_HEAD(,mfi_disk) mfi_ld_tqh;
|
||||||
|
TAILQ_HEAD(,mfi_system_pd) mfi_syspd_tqh;
|
||||||
|
+ TAILQ_HEAD(,mfi_disk_pending) mfi_ld_pend_tqh;
|
||||||
|
+ TAILQ_HEAD(,mfi_system_pending) mfi_syspd_pend_tqh;
|
||||||
|
eventhandler_tag mfi_eh;
|
||||||
|
struct cdev *mfi_cdev;
|
||||||
|
|
||||||
|
@@ -302,6 +315,7 @@ struct mfi_softc {
|
||||||
|
uint32_t frame_cnt);
|
||||||
|
int (*mfi_adp_reset)(struct mfi_softc *sc);
|
||||||
|
int (*mfi_adp_check_reset)(struct mfi_softc *sc);
|
||||||
|
+ void (*mfi_intr_ptr)(void *sc);
|
||||||
|
|
||||||
|
/* ThunderBolt */
|
||||||
|
uint32_t mfi_tbolt;
|
||||||
|
@@ -420,7 +434,8 @@ extern int mfi_tbolt_reset(struct mfi_softc *sc);
|
||||||
|
extern void mfi_tbolt_sync_map_info(struct mfi_softc *sc);
|
||||||
|
extern void mfi_handle_map_sync(void *context, int pending);
|
||||||
|
extern int mfi_dcmd_command(struct mfi_softc *, struct mfi_command **,
|
||||||
|
- uint32_t, void **, size_t);
|
||||||
|
+ uint32_t, void **, size_t);
|
||||||
|
+extern int mfi_build_cdb(int, uint8_t, u_int64_t, u_int32_t, uint8_t *);
|
||||||
|
|
||||||
|
#define MFIQ_ADD(sc, qname) \
|
||||||
|
do { \
|
7
share/security/patches/EN-13:03/mfi.patch.asc
Normal file
7
share/security/patches/EN-13:03/mfi.patch.asc
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
Version: GnuPG v2.0.21 (FreeBSD)
|
||||||
|
|
||||||
|
iEYEABECAAYFAlIVY24ACgkQFdaIBMps37JCXwCfZhVM1OjOQdzZpIxjNN80C1u1
|
||||||
|
JskAoJxlytTc77jV6csrcPfYIFv/oTJD
|
||||||
|
=MxiW
|
||||||
|
-----END PGP SIGNATURE-----
|
26
share/security/patches/SA-13:09/ip_multicast.patch
Normal file
26
share/security/patches/SA-13:09/ip_multicast.patch
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
Index: sys/netinet/in_mcast.c
|
||||||
|
===================================================================
|
||||||
|
--- sys/netinet/in_mcast.c (revision 254252)
|
||||||
|
+++ sys/netinet/in_mcast.c (working copy)
|
||||||
|
@@ -1648,6 +1648,8 @@
|
||||||
|
* has asked for, but we always tell userland how big the
|
||||||
|
* buffer really needs to be.
|
||||||
|
*/
|
||||||
|
+ if (msfr.msfr_nsrcs > in_mcast_maxsocksrc)
|
||||||
|
+ msfr.msfr_nsrcs = in_mcast_maxsocksrc;
|
||||||
|
tss = NULL;
|
||||||
|
if (msfr.msfr_srcs != NULL && msfr.msfr_nsrcs > 0) {
|
||||||
|
tss = malloc(sizeof(struct sockaddr_storage) * msfr.msfr_nsrcs,
|
||||||
|
Index: sys/netinet6/in6_mcast.c
|
||||||
|
===================================================================
|
||||||
|
--- sys/netinet6/in6_mcast.c (revision 254252)
|
||||||
|
+++ sys/netinet6/in6_mcast.c (working copy)
|
||||||
|
@@ -1625,6 +1625,8 @@
|
||||||
|
* has asked for, but we always tell userland how big the
|
||||||
|
* buffer really needs to be.
|
||||||
|
*/
|
||||||
|
+ if (msfr.msfr_nsrcs > in6_mcast_maxsocksrc)
|
||||||
|
+ msfr.msfr_nsrcs = in6_mcast_maxsocksrc;
|
||||||
|
tss = NULL;
|
||||||
|
if (msfr.msfr_srcs != NULL && msfr.msfr_nsrcs > 0) {
|
||||||
|
tss = malloc(sizeof(struct sockaddr_storage) * msfr.msfr_nsrcs,
|
7
share/security/patches/SA-13:09/ip_multicast.patch.asc
Normal file
7
share/security/patches/SA-13:09/ip_multicast.patch.asc
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
Version: GnuPG v2.0.21 (FreeBSD)
|
||||||
|
|
||||||
|
iEYEABECAAYFAlIVY24ACgkQFdaIBMps37KUkgCfU1WO0UwQEQeRo+DcgCFIf6j7
|
||||||
|
R9YAn3m43TNCB0hft+Fmlt7ikftEOCoQ
|
||||||
|
=m93m
|
||||||
|
-----END PGP SIGNATURE-----
|
19
share/security/patches/SA-13:10/sctp.patch
Normal file
19
share/security/patches/SA-13:10/sctp.patch
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
Index: sys/netinet/sctp_output.c
|
||||||
|
===================================================================
|
||||||
|
--- sys/netinet/sctp_output.c (revision 254337)
|
||||||
|
+++ sys/netinet/sctp_output.c (revision 254338)
|
||||||
|
@@ -5406,6 +5406,14 @@
|
||||||
|
}
|
||||||
|
SCTP_BUF_LEN(m) = sizeof(struct sctp_init_chunk);
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * We might not overwrite the identification[] completely and on
|
||||||
|
+ * some platforms time_entered will contain some padding. Therefore
|
||||||
|
+ * zero out the cookie to avoid putting uninitialized memory on the
|
||||||
|
+ * wire.
|
||||||
|
+ */
|
||||||
|
+ memset(&stc, 0, sizeof(struct sctp_state_cookie));
|
||||||
|
+
|
||||||
|
/* the time I built cookie */
|
||||||
|
(void)SCTP_GETTIME_TIMEVAL(&stc.time_entered);
|
||||||
|
|
7
share/security/patches/SA-13:10/sctp.patch.asc
Normal file
7
share/security/patches/SA-13:10/sctp.patch.asc
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
Version: GnuPG v2.0.21 (FreeBSD)
|
||||||
|
|
||||||
|
iEYEABECAAYFAlIVY24ACgkQFdaIBMps37JspQCdHJl2JvDn4fmmqM8xLRJsHghE
|
||||||
|
onAAn1F8HgApNEcBndp/DlnyiSnPyBCw
|
||||||
|
=Qaow
|
||||||
|
-----END PGP SIGNATURE-----
|
|
@ -7,6 +7,22 @@
|
||||||
<year>
|
<year>
|
||||||
<name>2013</name>
|
<name>2013</name>
|
||||||
|
|
||||||
|
<month>
|
||||||
|
<name>8</name>
|
||||||
|
|
||||||
|
<day>
|
||||||
|
<name>22</name>
|
||||||
|
|
||||||
|
<advisory>
|
||||||
|
<name>FreeBSD-SA-13:10.sctp</name>
|
||||||
|
</advisory>
|
||||||
|
|
||||||
|
<advisory>
|
||||||
|
<name>FreeBSD-SA-13:09.ip_multicast</name>
|
||||||
|
</advisory>
|
||||||
|
</day>
|
||||||
|
</month>
|
||||||
|
|
||||||
<month>
|
<month>
|
||||||
<name>7</name>
|
<name>7</name>
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,18 @@
|
||||||
<year>
|
<year>
|
||||||
<name>2013</name>
|
<name>2013</name>
|
||||||
|
|
||||||
|
<month>
|
||||||
|
<name>8</name>
|
||||||
|
|
||||||
|
<day>
|
||||||
|
<name>22</name>
|
||||||
|
|
||||||
|
<notice>
|
||||||
|
<name>FreeBSD-EN-13:03.mfi</name>
|
||||||
|
</notice>
|
||||||
|
</day>
|
||||||
|
</month>
|
||||||
|
|
||||||
<month>
|
<month>
|
||||||
<name>6</name>
|
<name>6</name>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue