diff options
author | Alexander Motin <mav@FreeBSD.org> | 2021-12-17 20:24:56 +0000 |
---|---|---|
committer | Alexander Motin <mav@FreeBSD.org> | 2021-12-17 20:34:43 +0000 |
commit | 9aba757e92aaf0751c83c0ce3f18f65f864f1811 (patch) | |
tree | c2fa5fe2b0f37d155401ca6d65d04179e40a67da /sys | |
parent | 75add59a8ee2e24cb76a2f0fcbf9aa6d740e3bb6 (diff) | |
download | src-9aba757e92aaf0751c83c0ce3f18f65f864f1811.tar.gz src-9aba757e92aaf0751c83c0ce3f18f65f864f1811.zip |
ahci(4): Allow enclosure emulation without hardware.
After 53f5ac1310e allowed SATA device mapping to enclosure slots,
it may have sense to provide enclosure device emulation even without
real hardware interface like SGPIO just for purposes of physical
device location tracking (still assuming straight cabling).
MFC after: 1 week
Sponsored by: iXsystems, Inc.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/ahci/ahci.c | 7 | ||||
-rw-r--r-- | sys/dev/ahci/ahciem.c | 36 |
2 files changed, 28 insertions, 15 deletions
diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 4b13ae3068d5..12e6ee8102da 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -376,7 +376,10 @@ ahci_attach(device_t dev) device_set_ivars(child, (void *)(intptr_t)(unit | AHCI_REMAPPED_UNIT)); } - if (ctlr->caps & AHCI_CAP_EMS) { + int em = (ctlr->caps & AHCI_CAP_EMS) != 0; + resource_int_value(device_get_name(dev), device_get_unit(dev), + "em", &em); + if (em) { child = device_add_child(dev, "ahciem", -1); if (child == NULL) device_printf(dev, "failed to add enclosure device\n"); @@ -602,6 +605,8 @@ ahci_alloc_resource(device_t dev, device_t child, int type, int *rid, } else if (!is_em) { offset = AHCI_OFFSET + (unit << 7); size = 128; + } else if ((ctlr->caps & AHCI_CAP_EMS) == 0) { + break; } else if (*rid == 0) { offset = AHCI_EM_CTL; size = 4; diff --git a/sys/dev/ahci/ahciem.c b/sys/dev/ahci/ahciem.c index b1c3fbf1fdd4..20b36830ce9a 100644 --- a/sys/dev/ahci/ahciem.c +++ b/sys/dev/ahci/ahciem.c @@ -86,17 +86,18 @@ ahci_em_attach(device_t dev) enc->ichannels = ctlr->ichannels; mtx_init(&enc->mtx, "AHCI enclosure lock", NULL, MTX_DEF); rid = 0; - if (!(enc->r_memc = bus_alloc_resource_any(dev, SYS_RES_MEMORY, - &rid, RF_ACTIVE))) { - mtx_destroy(&enc->mtx); - return (ENXIO); - } - enc->capsem = ATA_INL(enc->r_memc, 0); - rid = 1; - if (!(enc->r_memt = bus_alloc_resource_any(dev, SYS_RES_MEMORY, - &rid, RF_ACTIVE))) { - error = ENXIO; - goto err0; + if ((enc->r_memc = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &rid, RF_ACTIVE)) != NULL) { + enc->capsem = ATA_INL(enc->r_memc, 0); + rid = 1; + if (!(enc->r_memt = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &rid, RF_ACTIVE))) { + error = ENXIO; + goto err0; + } + } else { + enc->capsem = AHCI_EM_XMT | AHCI_EM_SMB | AHCI_EM_LED; + enc->r_memt = NULL; } if ((enc->capsem & (AHCI_EM_XMT | AHCI_EM_SMB)) == 0) { rid = 2; @@ -194,7 +195,8 @@ err1: err0: if (enc->r_memt) bus_release_resource(dev, SYS_RES_MEMORY, 1, enc->r_memt); - bus_release_resource(dev, SYS_RES_MEMORY, 0, enc->r_memc); + if (enc->r_memc) + bus_release_resource(dev, SYS_RES_MEMORY, 0, enc->r_memc); mtx_destroy(&enc->mtx); return (error); } @@ -216,8 +218,10 @@ ahci_em_detach(device_t dev) cam_sim_free(enc->sim, /*free_devq*/TRUE); mtx_unlock(&enc->mtx); - bus_release_resource(dev, SYS_RES_MEMORY, 0, enc->r_memc); - bus_release_resource(dev, SYS_RES_MEMORY, 1, enc->r_memt); + if (enc->r_memc) + bus_release_resource(dev, SYS_RES_MEMORY, 0, enc->r_memc); + if (enc->r_memt) + bus_release_resource(dev, SYS_RES_MEMORY, 1, enc->r_memt); if (enc->r_memr) bus_release_resource(dev, SYS_RES_MEMORY, 2, enc->r_memr); mtx_destroy(&enc->mtx); @@ -231,6 +235,8 @@ ahci_em_reset(device_t dev) int i, timeout; enc = device_get_softc(dev); + if (enc->r_memc == NULL) + return (0); ATA_OUTL(enc->r_memc, 0, AHCI_EM_RST); timeout = 1000; while ((ATA_INL(enc->r_memc, 0) & AHCI_EM_RST) && @@ -292,6 +298,8 @@ ahci_em_setleds(device_t dev, int c) int16_t val; enc = device_get_softc(dev); + if (enc->r_memc == NULL) + return; val = 0; if (enc->status[c][2] & SESCTL_RQSACT) /* Activity */ |