Author: mav
Date: Thu Aug 18 11:45:02 2016
New Revision: 304420
URL: https://svnweb.freebsd.org/changeset/base/304420

Log:
  MFC r302459: Allow AHCI controller to support up to 32 arbitrary devices.
  
  While old syntax is still supported, new syntax looks like this:
  
  -s 3,ahci,hd:/dev/zvol/XXX,hd:/dev/zvol/YYY,cd:/storage/ZZZ.iso
  
  Sponsored by:   iXsystems, Inc.

Modified:
  stable/10/usr.sbin/bhyve/bhyve.8
  stable/10/usr.sbin/bhyve/pci_ahci.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/usr.sbin/bhyve/bhyve.8
==============================================================================
--- stable/10/usr.sbin/bhyve/bhyve.8    Thu Aug 18 11:41:58 2016        
(r304419)
+++ stable/10/usr.sbin/bhyve/bhyve.8    Thu Aug 18 11:45:02 2016        
(r304420)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd August 7, 2015
+.Dd July 8, 2016
 .Dt BHYVE 8
 .Os
 .Sh NAME
@@ -168,6 +168,8 @@ Virtio network interface.
 Virtio block storage interface.
 .It Li virtio-rnd
 Virtio RNG interface.
+.It Li ahci
+AHCI controller attached to arbitraty devices.
 .It Li ahci-cd
 AHCI controller attached to an ATAPI CD/DVD.
 .It Li ahci-hd
@@ -323,15 +325,11 @@ null-modem device.
 .Bd -literal -offset indent
 bhyve -c 4 \\
   -s 0,amd_hostbridge -s 1,lpc \\
-  -s 1:0,ahci-hd,/images/disk.1 \\
-  -s 1:1,ahci-hd,/images/disk.2 \\
-  -s 1:2,ahci-hd,/images/disk.3 \\
-  -s 1:3,ahci-hd,/images/disk.4 \\
-  -s 1:4,ahci-hd,/images/disk.5 \\
-  -s 1:5,ahci-hd,/images/disk.6 \\
-  -s 1:6,ahci-hd,/images/disk.7 \\
-  -s 1:7,ahci-hd,/images/disk.8 \\
-  -s 2,ahci-cd,/images/install.iso \\
+  -s 1:0,ahci,hd:/images/disk.1,hd:/images/disk.2,\\
+hd:/images/disk.3,hd:/images/disk.4,\\
+hd:/images/disk.5,hd:/images/disk.6,\\
+hd:/images/disk.7,hd:/images/disk.8,\\
+cd:/images/install.iso \\
   -s 3,virtio-net,tap0 \\
   -l com1,/dev/nmdm0A \\
   -A -H -P -m 8G

Modified: stable/10/usr.sbin/bhyve/pci_ahci.c
==============================================================================
--- stable/10/usr.sbin/bhyve/pci_ahci.c Thu Aug 18 11:41:58 2016        
(r304419)
+++ stable/10/usr.sbin/bhyve/pci_ahci.c Thu Aug 18 11:45:02 2016        
(r304420)
@@ -1,5 +1,6 @@
 /*-
  * Copyright (c) 2013  Zhixiang Yu <zc...@freebsd.org>
+ * Copyright (c) 2015-2016 Alexander Motin <m...@freebsd.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -57,7 +58,8 @@ __FBSDID("$FreeBSD$");
 #include "ahci.h"
 #include "block_if.h"
 
-#define        MAX_PORTS       6       /* Intel ICH8 AHCI supports 6 ports */
+#define        DEF_PORTS       6       /* Intel ICH8 AHCI supports 6 ports */
+#define        MAX_PORTS       32      /* AHCI supports 32 ports */
 
 #define        PxSIG_ATA       0x00000101 /* ATA drive */
 #define        PxSIG_ATAPI     0xeb140101 /* ATAPI drive */
@@ -2236,20 +2238,16 @@ pci_ahci_read(struct vmctx *ctx, int vcp
 static int
 pci_ahci_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts, int atapi)
 {
-       char bident[sizeof("XX:X:X")];
+       char bident[sizeof("XX:XX:XX")];
        struct blockif_ctxt *bctxt;
        struct pci_ahci_softc *sc;
-       int ret, slots;
+       int ret, slots, p;
        MD5_CTX mdctx;
        u_char digest[16];
+       char *next, *next2;
 
        ret = 0;
 
-       if (opts == NULL) {
-               fprintf(stderr, "pci_ahci: backing device required\n");
-               return (1);
-       }
-
 #ifdef AHCI_DEBUG
        dbg = fopen("/tmp/log", "w+");
 #endif
@@ -2257,58 +2255,83 @@ pci_ahci_init(struct vmctx *ctx, struct 
        sc = calloc(1, sizeof(struct pci_ahci_softc));
        pi->pi_arg = sc;
        sc->asc_pi = pi;
-       sc->ports = MAX_PORTS;
+       pthread_mutex_init(&sc->mtx, NULL);
+       sc->ports = 0;
+       sc->pi = 0;
+       slots = 32;
+
+       for (p = 0; p < MAX_PORTS && opts != NULL; p++, opts = next) {
+               /* Identify and cut off type of present port. */
+               if (strncmp(opts, "hd:", 3) == 0) {
+                       atapi = 0;
+                       opts += 3;
+               } else if (strncmp(opts, "cd:", 3) == 0) {
+                       atapi = 1;
+                       opts += 3;
+               }
+
+               /* Find and cut off the next port options. */
+               next = strstr(opts, ",hd:");
+               next2 = strstr(opts, ",cd:");
+               if (next == NULL || (next2 != NULL && next2 < next))
+                       next = next2;
+               if (next != NULL) {
+                       next[0] = 0;
+                       next++;
+               }
 
-       /*
-        * Only use port 0 for a backing device. All other ports will be
-        * marked as unused
-        */
-       sc->port[0].atapi = atapi;
+               if (opts[0] == 0)
+                       continue;
 
-       /*
-        * Attempt to open the backing image. Use the PCI
-        * slot/func for the identifier string.
-        */
-       snprintf(bident, sizeof(bident), "%d:%d", pi->pi_slot, pi->pi_func);
-       bctxt = blockif_open(opts, bident);
-       if (bctxt == NULL) {            
-               ret = 1;
-               goto open_fail;
-       }       
-       sc->port[0].bctx = bctxt;
-       sc->port[0].pr_sc = sc;
+               /*
+                * Attempt to open the backing image. Use the PCI slot/func
+                * and the port number for the identifier string.
+                */
+               snprintf(bident, sizeof(bident), "%d:%d:%d", pi->pi_slot,
+                   pi->pi_func, p);
+               bctxt = blockif_open(opts, bident);
+               if (bctxt == NULL) {
+                       sc->ports = p;
+                       ret = 1;
+                       goto open_fail;
+               }       
+               sc->port[p].bctx = bctxt;
+               sc->port[p].pr_sc = sc;
+               sc->port[p].atapi = atapi;
 
-       /*
-        * Create an identifier for the backing file. Use parts of the
-        * md5 sum of the filename
-        */
-       MD5Init(&mdctx);
-       MD5Update(&mdctx, opts, strlen(opts));
-       MD5Final(digest, &mdctx);       
-       sprintf(sc->port[0].ident, "BHYVE-%02X%02X-%02X%02X-%02X%02X",
-           digest[0], digest[1], digest[2], digest[3], digest[4], digest[5]);
+               /*
+                * Create an identifier for the backing file.
+                * Use parts of the md5 sum of the filename
+                */
+               MD5Init(&mdctx);
+               MD5Update(&mdctx, opts, strlen(opts));
+               MD5Final(digest, &mdctx);
+               sprintf(sc->port[p].ident, "BHYVE-%02X%02X-%02X%02X-%02X%02X",
+                   digest[0], digest[1], digest[2], digest[3], digest[4],
+                   digest[5]);
 
-       /*
-        * Allocate blockif request structures and add them
-        * to the free list
-        */
-       pci_ahci_ioreq_init(&sc->port[0]);
+               /*
+                * Allocate blockif request structures and add them
+                * to the free list
+                */
+               pci_ahci_ioreq_init(&sc->port[p]);
 
-       pthread_mutex_init(&sc->mtx, NULL);
+               sc->pi |= (1 << p);
+               if (sc->port[p].ioqsz < slots)
+                       slots = sc->port[p].ioqsz;
+       }
+       sc->ports = p;
 
        /* Intel ICH8 AHCI */
-       slots = sc->port[0].ioqsz;
-       if (slots > 32)
-               slots = 32;
        --slots;
+       if (sc->ports < DEF_PORTS)
+               sc->ports = DEF_PORTS;
        sc->cap = AHCI_CAP_64BIT | AHCI_CAP_SNCQ | AHCI_CAP_SSNTF |
            AHCI_CAP_SMPS | AHCI_CAP_SSS | AHCI_CAP_SALP |
            AHCI_CAP_SAL | AHCI_CAP_SCLO | (0x3 << AHCI_CAP_ISS_SHIFT)|
            AHCI_CAP_PMD | AHCI_CAP_SSC | AHCI_CAP_PSC |
            (slots << AHCI_CAP_NCS_SHIFT) | AHCI_CAP_SXS | (sc->ports - 1);
 
-       /* Only port 0 implemented */
-       sc->pi = 1;
        sc->vs = 0x10300;
        sc->cap2 = AHCI_CAP2_APST;
        ahci_reset(sc);
@@ -2326,8 +2349,10 @@ pci_ahci_init(struct vmctx *ctx, struct 
 
 open_fail:
        if (ret) {
-               if (sc->port[0].bctx != NULL)
-                       blockif_close(sc->port[0].bctx);
+               for (p = 0; p < sc->ports; p++) {
+                       if (sc->port[p].bctx != NULL)
+                               blockif_close(sc->port[p].bctx);
+               }
                free(sc);
        }
 
@@ -2351,6 +2376,14 @@ pci_ahci_atapi_init(struct vmctx *ctx, s
 /*
  * Use separate emulation names to distinguish drive and atapi devices
  */
+struct pci_devemu pci_de_ahci = {
+       .pe_emu =       "ahci",
+       .pe_init =      pci_ahci_hd_init,
+       .pe_barwrite =  pci_ahci_write,
+       .pe_barread =   pci_ahci_read
+};
+PCI_EMUL_SET(pci_de_ahci);
+
 struct pci_devemu pci_de_ahci_hd = {
        .pe_emu =       "ahci-hd",
        .pe_init =      pci_ahci_hd_init,
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to