aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2019-08-28 22:04:04 +0000
committerAlexander Motin <mav@FreeBSD.org>2019-08-28 22:04:04 +0000
commit610defb17cfc8819e312695609cc0750fa5ef43d (patch)
tree9c258267c8576789bcbc18fc8a824c1d26520c7c /sys/dev
parent69ac7c76713a1076708c745652ade69286fb2d00 (diff)
downloadsrc-610defb17cfc8819e312695609cc0750fa5ef43d.tar.gz
src-610defb17cfc8819e312695609cc0750fa5ef43d.zip
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.
Notes
Notes: svn path=/head/; revision=351589
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ahci/ahci.c37
-rw-r--r--sys/dev/ahci/ahci.h7
2 files changed, 24 insertions, 20 deletions
diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index bbd789b1e69e..213292c3b667 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -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 type, int *rid,
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 resource *irq,
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, struct resource *irq,
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, struct resource *irq,
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);
}
diff --git a/sys/dev/ahci/ahci.h b/sys/dev/ahci/ahci.h
index 43e80a05e9a6..127bcb040349 100644
--- a/sys/dev/ahci/ahci.h
+++ b/sys/dev/ahci/ahci.h
@@ -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;