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.
This commit is contained in:
mav 2019-08-28 22:04:04 +00:00
parent c17eb3d289
commit 6f90b5061a
2 changed files with 24 additions and 20 deletions

View File

@ -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);
}

View File

@ -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;