Author: mav
Date: Wed Nov 20 23:49:47 2019
New Revision: 354923
URL: https://svnweb.freebsd.org/changeset/base/354923

Log:
  MFC r351589: Fix AHCI Enclosure Management, broken by r351356.
  
  ivars value of -1 was used to distinguish EM device, and r351356 left some
  wrong checks for it.  Give EM device separate flag there instead.

Modified:
  stable/12/sys/dev/ahci/ahci.c
  stable/12/sys/dev/ahci/ahci.h
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/dev/ahci/ahci.c
==============================================================================
--- stable/12/sys/dev/ahci/ahci.c       Wed Nov 20 23:45:31 2019        
(r354922)
+++ stable/12/sys/dev/ahci/ahci.c       Wed Nov 20 23:49:47 2019        
(r354923)
@@ -362,7 +362,7 @@ ahci_attach(device_t dev)
                if (child == NULL)
                        device_printf(dev, "failed to add enclosure device\n");
                else
-                       device_set_ivars(child, (void *)(intptr_t)-1);
+                       device_set_ivars(child, (void *)(intptr_t)AHCI_EM_UNIT);
        }
        bus_generic_attach(dev);
        return (0);
@@ -562,23 +562,25 @@ ahci_alloc_resource(device_t dev, device_t child, int 
        struct resource *res;
        rman_res_t st;
        int offset, size, unit;
-       bool is_remapped;
+       bool is_em, is_remapped;
 
        unit = (intptr_t)device_get_ivars(child);
+       is_em = is_remapped = false;
        if (unit & AHCI_REMAPPED_UNIT) {
-               unit &= ~AHCI_REMAPPED_UNIT;
+               unit &= AHCI_UNIT;
                unit -= ctlr->channels;
                is_remapped = true;
-       } else
-               is_remapped = false;
+       } else if (unit & AHCI_EM_UNIT) {
+               unit &= AHCI_UNIT;
+               is_em = true;
+       }
        res = NULL;
        switch (type) {
        case SYS_RES_MEMORY:
                if (is_remapped) {
                        offset = ctlr->remap_offset + unit * ctlr->remap_size;
                        size = ctlr->remap_size;
-               }
-               else if (unit >= 0) {
+               } else if (!is_em) {
                        offset = AHCI_OFFSET + (unit << 7);
                        size = 128;
                } else if (*rid == 0) {
@@ -639,7 +641,7 @@ ahci_setup_intr(device_t dev, device_t child, struct r
     void *argument, void **cookiep)
 {
        struct ahci_controller *ctlr = device_get_softc(dev);
-       int unit = (intptr_t)device_get_ivars(child) & ~AHCI_REMAPPED_UNIT;
+       int unit = (intptr_t)device_get_ivars(child) & AHCI_UNIT;
 
        if (filter != NULL) {
                printf("ahci.c: we cannot use a filter here\n");
@@ -655,7 +657,7 @@ ahci_teardown_intr(device_t dev, device_t child, struc
     void *cookie)
 {
        struct ahci_controller *ctlr = device_get_softc(dev);
-       int unit = (intptr_t)device_get_ivars(child) & ~AHCI_REMAPPED_UNIT;
+       int unit = (intptr_t)device_get_ivars(child) & AHCI_UNIT;
 
        ctlr->interrupt[unit].function = NULL;
        ctlr->interrupt[unit].argument = NULL;
@@ -665,12 +667,13 @@ ahci_teardown_intr(device_t dev, device_t child, struc
 int
 ahci_print_child(device_t dev, device_t child)
 {
-       int retval, channel;
+       intptr_t ivars;
+       int retval;
 
        retval = bus_print_child_header(dev, child);
-       channel = (int)(intptr_t)device_get_ivars(child) & ~AHCI_REMAPPED_UNIT;
-       if (channel >= 0)
-               retval += printf(" at channel %d", channel);
+       ivars = (intptr_t)device_get_ivars(child);
+       if ((ivars & AHCI_EM_UNIT) == 0)
+               retval += printf(" at channel %d", (int)ivars & AHCI_UNIT);
        retval += bus_print_child_footer(dev, child);
        return (retval);
 }
@@ -679,11 +682,11 @@ int
 ahci_child_location_str(device_t dev, device_t child, char *buf,
     size_t buflen)
 {
-       int channel;
+       intptr_t ivars;
 
-       channel = (int)(intptr_t)device_get_ivars(child) & ~AHCI_REMAPPED_UNIT;
-       if (channel >= 0)
-               snprintf(buf, buflen, "channel=%d", channel);
+       ivars = (intptr_t)device_get_ivars(child);
+       if ((ivars & AHCI_EM_UNIT) == 0)
+               snprintf(buf, buflen, "channel=%d", (int)ivars & AHCI_UNIT);
        return (0);
 }
 

Modified: stable/12/sys/dev/ahci/ahci.h
==============================================================================
--- stable/12/sys/dev/ahci/ahci.h       Wed Nov 20 23:45:31 2019        
(r354922)
+++ stable/12/sys/dev/ahci/ahci.h       Wed Nov 20 23:49:47 2019        
(r354923)
@@ -319,9 +319,10 @@
 /* Total main work area. */
 #define AHCI_WORK_SIZE              (AHCI_CT_OFFSET + AHCI_CT_SIZE * 
ch->numslots)
 
-
-/* NVMe remapped device */
-#define AHCI_REMAPPED_UNIT     (1 << 31)
+/* ivars value fields */
+#define AHCI_REMAPPED_UNIT     (1 << 31)       /* NVMe remapped device. */
+#define AHCI_EM_UNIT           (1 << 30)       /* Enclosure Mgmt device. */
+#define AHCI_UNIT              0xff            /* Channel number. */
 
 struct ahci_dma_prd {
     u_int64_t                   dba;
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to